1*3f982cf4SFabien Sanglard // Copyright 2019 The Chromium Authors. All rights reserved. 2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be 3*3f982cf4SFabien Sanglard // found in the LICENSE file. 4*3f982cf4SFabien Sanglard 5*3f982cf4SFabien Sanglard #ifndef CAST_STANDALONE_RECEIVER_DECODER_H_ 6*3f982cf4SFabien Sanglard #define CAST_STANDALONE_RECEIVER_DECODER_H_ 7*3f982cf4SFabien Sanglard 8*3f982cf4SFabien Sanglard #include <stdint.h> 9*3f982cf4SFabien Sanglard 10*3f982cf4SFabien Sanglard #include <string> 11*3f982cf4SFabien Sanglard #include <vector> 12*3f982cf4SFabien Sanglard 13*3f982cf4SFabien Sanglard #include "absl/types/span.h" 14*3f982cf4SFabien Sanglard #include "cast/standalone_receiver/avcodec_glue.h" 15*3f982cf4SFabien Sanglard #include "cast/streaming/frame_id.h" 16*3f982cf4SFabien Sanglard 17*3f982cf4SFabien Sanglard namespace openscreen { 18*3f982cf4SFabien Sanglard namespace cast { 19*3f982cf4SFabien Sanglard 20*3f982cf4SFabien Sanglard // Wraps libavcodec to decode audio or video. 21*3f982cf4SFabien Sanglard class Decoder { 22*3f982cf4SFabien Sanglard public: 23*3f982cf4SFabien Sanglard // A buffer backed by storage that is compatible with FFMPEG (i.e., includes 24*3f982cf4SFabien Sanglard // the required zero-padding). 25*3f982cf4SFabien Sanglard class Buffer { 26*3f982cf4SFabien Sanglard public: 27*3f982cf4SFabien Sanglard Buffer(); 28*3f982cf4SFabien Sanglard ~Buffer(); 29*3f982cf4SFabien Sanglard 30*3f982cf4SFabien Sanglard void Resize(int new_size); 31*3f982cf4SFabien Sanglard absl::Span<const uint8_t> GetSpan() const; 32*3f982cf4SFabien Sanglard absl::Span<uint8_t> GetSpan(); 33*3f982cf4SFabien Sanglard 34*3f982cf4SFabien Sanglard private: 35*3f982cf4SFabien Sanglard std::vector<uint8_t> buffer_; 36*3f982cf4SFabien Sanglard }; 37*3f982cf4SFabien Sanglard 38*3f982cf4SFabien Sanglard // Interface for receiving decoded frames and/or errors. 39*3f982cf4SFabien Sanglard class Client { 40*3f982cf4SFabien Sanglard public: 41*3f982cf4SFabien Sanglard 42*3f982cf4SFabien Sanglard virtual void OnFrameDecoded(FrameId frame_id, const AVFrame& frame) = 0; 43*3f982cf4SFabien Sanglard virtual void OnDecodeError(FrameId frame_id, std::string message) = 0; 44*3f982cf4SFabien Sanglard virtual void OnFatalError(std::string message) = 0; 45*3f982cf4SFabien Sanglard 46*3f982cf4SFabien Sanglard protected: 47*3f982cf4SFabien Sanglard Client(); 48*3f982cf4SFabien Sanglard virtual ~Client(); 49*3f982cf4SFabien Sanglard }; 50*3f982cf4SFabien Sanglard 51*3f982cf4SFabien Sanglard // |codec_name| should be the codec_name field from an OFFER message. 52*3f982cf4SFabien Sanglard explicit Decoder(const std::string& codec_name); 53*3f982cf4SFabien Sanglard ~Decoder(); 54*3f982cf4SFabien Sanglard client()55*3f982cf4SFabien Sanglard Client* client() const { return client_; } set_client(Client * client)56*3f982cf4SFabien Sanglard void set_client(Client* client) { client_ = client; } 57*3f982cf4SFabien Sanglard 58*3f982cf4SFabien Sanglard // Starts decoding the data in |buffer|, which should be associated with the 59*3f982cf4SFabien Sanglard // given |frame_id|. This will synchronously call Client::OnFrameDecoded() 60*3f982cf4SFabien Sanglard // and/or Client::OnDecodeError() zero or more times with results. Note that 61*3f982cf4SFabien Sanglard // some codecs will have data dependencies that require multiple encoded 62*3f982cf4SFabien Sanglard // frame's data before the first decoded frame can be generated. 63*3f982cf4SFabien Sanglard void Decode(FrameId frame_id, const Buffer& buffer); 64*3f982cf4SFabien Sanglard 65*3f982cf4SFabien Sanglard private: 66*3f982cf4SFabien Sanglard // Helper to initialize the FFMPEG decoder and supporting objects. Returns 67*3f982cf4SFabien Sanglard // false if this failed (and the Client was notified). 68*3f982cf4SFabien Sanglard bool Initialize(); 69*3f982cf4SFabien Sanglard 70*3f982cf4SFabien Sanglard // Helper to get the FrameId that is associated with the next frame coming out 71*3f982cf4SFabien Sanglard // of the FFMPEG decoder. 72*3f982cf4SFabien Sanglard FrameId DidReceiveFrameFromDecoder(); 73*3f982cf4SFabien Sanglard 74*3f982cf4SFabien Sanglard // Helper to handle a codec initialization error and notify the Client of the 75*3f982cf4SFabien Sanglard // fatal error. 76*3f982cf4SFabien Sanglard void HandleInitializationError(const char* what, int av_errnum); 77*3f982cf4SFabien Sanglard 78*3f982cf4SFabien Sanglard // Called when any transient or fatal error occurs, generating an Error and 79*3f982cf4SFabien Sanglard // notifying the Client of it. 80*3f982cf4SFabien Sanglard void OnError(const char* what, int av_errnum, FrameId frame_id); 81*3f982cf4SFabien Sanglard 82*3f982cf4SFabien Sanglard const std::string codec_name_; 83*3f982cf4SFabien Sanglard AVCodec* codec_ = nullptr; 84*3f982cf4SFabien Sanglard AVCodecParserContextUniquePtr parser_; 85*3f982cf4SFabien Sanglard AVCodecContextUniquePtr context_; 86*3f982cf4SFabien Sanglard AVPacketUniquePtr packet_; 87*3f982cf4SFabien Sanglard AVFrameUniquePtr decoded_frame_; 88*3f982cf4SFabien Sanglard 89*3f982cf4SFabien Sanglard Client* client_ = nullptr; 90*3f982cf4SFabien Sanglard 91*3f982cf4SFabien Sanglard // Queue of frames that have been input to the libavcodec decoder, but which 92*3f982cf4SFabien Sanglard // have not yet had output generated by it. 93*3f982cf4SFabien Sanglard std::vector<FrameId> frames_decoding_; 94*3f982cf4SFabien Sanglard }; 95*3f982cf4SFabien Sanglard 96*3f982cf4SFabien Sanglard } // namespace cast 97*3f982cf4SFabien Sanglard } // namespace openscreen 98*3f982cf4SFabien Sanglard 99*3f982cf4SFabien Sanglard #endif // CAST_STANDALONE_RECEIVER_DECODER_H_ 100