@@ -54,7 +54,8 @@ class DeviceInterface {
5454 // Initialize the device with parameters generic to all kinds of decoding.
5555 virtual void initialize (
5656 const AVStream* avStream,
57- const UniqueDecodingAVFormatContext& avFormatCtx) = 0;
57+ const UniqueDecodingAVFormatContext& avFormatCtx,
58+ const SharedAVCodecContext& codecContext) = 0;
5859
5960 // Initialize the device with parameters specific to video decoding. There is
6061 // a default empty implementation.
@@ -80,52 +81,47 @@ class DeviceInterface {
8081 // Extension points for custom decoding paths
8182 // ------------------------------------------
8283
83- // Override to return true if this device interface can decode packets
84- // directly. This means that the following two member functions can both
85- // be called:
86- //
87- // 1. sendPacket()
88- // 2. receiveFrame()
89- virtual bool canDecodePacketDirectly () const {
90- return false ;
91- }
92-
93- // Moral equivalent of avcodec_send_packet()
9484 // Returns AVSUCCESS on success, AVERROR(EAGAIN) if decoder queue full, or
9585 // other AVERROR on failure
96- virtual int sendPacket ([[maybe_unused]] ReferenceAVPacket& avPacket) {
86+ // Default implementation uses FFmpeg directly
87+ virtual int sendPacket (ReferenceAVPacket& avPacket) {
9788 TORCH_CHECK (
98- false ,
99- " Send/receive packet decoding not implemented for this device interface " );
100- return AVERROR (ENOSYS );
89+ codecContext_ != nullptr ,
90+ " Codec context not available for default packet sending " );
91+ return avcodec_send_packet (codecContext_. get (), avPacket. get () );
10192 }
10293
10394 // Send an EOF packet to flush the decoder
10495 // Returns AVSUCCESS on success, or other AVERROR on failure
96+ // Default implementation uses FFmpeg directly
10597 virtual int sendEOFPacket () {
10698 TORCH_CHECK (
107- false , " Send EOF packet not implemented for this device interface" );
108- return AVERROR (ENOSYS);
99+ codecContext_ != nullptr ,
100+ " Codec context not available for default EOF packet sending" );
101+ return avcodec_send_packet (codecContext_.get (), nullptr );
109102 }
110103
111- // Moral equivalent of avcodec_receive_frame()
112104 // Returns AVSUCCESS on success, AVERROR(EAGAIN) if no frame ready,
113105 // AVERROR_EOF if end of stream, or other AVERROR on failure
114- virtual int receiveFrame ([[maybe_unused]] UniqueAVFrame& avFrame) {
106+ // Default implementation uses FFmpeg directly
107+ virtual int receiveFrame (UniqueAVFrame& avFrame) {
115108 TORCH_CHECK (
116- false ,
117- " Send/receive packet decoding not implemented for this device interface " );
118- return AVERROR (ENOSYS );
109+ codecContext_ != nullptr ,
110+ " Codec context not available for default frame receiving " );
111+ return avcodec_receive_frame (codecContext_. get (), avFrame. get () );
119112 }
120113
121114 // Flush remaining frames from decoder
122115 virtual void flush () {
123- // Default implementation is no-op for standard decoders
124- // Custom decoders can override this method
116+ TORCH_CHECK (
117+ codecContext_ != nullptr ,
118+ " Codec context not available for default flushing" );
119+ avcodec_flush_buffers (codecContext_.get ());
125120 }
126121
127122 protected:
128123 torch::Device device_;
124+ SharedAVCodecContext codecContext_;
129125};
130126
131127using CreateDeviceInterfaceFn =
0 commit comments