@@ -429,7 +429,6 @@ void SingleStreamDecoder::addStream(
429429 TORCH_CHECK (
430430 deviceInterface_ != nullptr ,
431431 " Failed to create device interface. This should never happen, please report." );
432- deviceInterface_->initialize (streamInfo.stream , formatContext_);
433432
434433 // TODO_CODE_QUALITY it's pretty meh to have a video-specific logic within
435434 // addStream() which is supposed to be generic
@@ -441,7 +440,7 @@ void SingleStreamDecoder::addStream(
441440
442441 AVCodecContext* codecContext = avcodec_alloc_context3 (avCodec);
443442 TORCH_CHECK (codecContext != nullptr );
444- streamInfo.codecContext . reset (codecContext);
443+ streamInfo.codecContext = makeSharedAVCodecContext (codecContext);
445444
446445 int retVal = avcodec_parameters_to_context (
447446 streamInfo.codecContext .get (), streamInfo.stream ->codecpar );
@@ -453,14 +452,19 @@ void SingleStreamDecoder::addStream(
453452 // Note that we must make sure to register the harware device context
454453 // with the codec context before calling avcodec_open2(). Otherwise, decoding
455454 // will happen on the CPU and not the hardware device.
456- deviceInterface_->registerHardwareDeviceWithCodec (codecContext);
455+ deviceInterface_->registerHardwareDeviceWithCodec (
456+ streamInfo.codecContext .get ());
457457 retVal = avcodec_open2 (streamInfo.codecContext .get (), avCodec, nullptr );
458458 TORCH_CHECK (retVal >= AVSUCCESS, getFFMPEGErrorStringFromErrorCode (retVal));
459459
460- codecContext->time_base = streamInfo.stream ->time_base ;
460+ streamInfo.codecContext ->time_base = streamInfo.stream ->time_base ;
461+
462+ // Initialize the device interface with the codec context
463+ deviceInterface_->initialize (
464+ streamInfo.stream , formatContext_, streamInfo.codecContext );
461465
462466 containerMetadata_.allStreamMetadata [activeStreamIndex_].codecName =
463- std::string (avcodec_get_name (codecContext->codec_id ));
467+ std::string (avcodec_get_name (streamInfo. codecContext ->codec_id ));
464468
465469 // We will only need packets from the active stream, so we tell FFmpeg to
466470 // discard packets from the other streams. Note that av_read_frame() may still
@@ -1149,8 +1153,6 @@ void SingleStreamDecoder::maybeSeekToBeforeDesiredPts() {
11491153 getFFMPEGErrorStringFromErrorCode (status));
11501154
11511155 decodeStats_.numFlushes ++;
1152- avcodec_flush_buffers (streamInfo.codecContext .get ());
1153-
11541156 deviceInterface_->flush ();
11551157}
11561158
@@ -1169,24 +1171,16 @@ UniqueAVFrame SingleStreamDecoder::decodeAVFrame(
11691171 cursorWasJustSet_ = false ;
11701172 }
11711173
1172- StreamInfo& streamInfo = streamInfos_[activeStreamIndex_];
11731174 UniqueAVFrame avFrame (av_frame_alloc ());
11741175 AutoAVPacket autoAVPacket;
11751176 int status = AVSUCCESS;
11761177 bool reachedEOF = false ;
11771178
1178- // TODONVDEC P2: Instead of calling canDecodePacketDirectly() and rely on
1179- // if/else blocks to dispatch to the interface or to FFmpeg, consider *always*
1180- // dispatching to the interface. The default implementation of the interface's
1181- // receiveFrame and sendPacket could just be calling avcodec_receive_frame and
1182- // avcodec_send_packet. This would make the decoding loop even more generic.
1179+ // The default implementation uses avcodec_receive_frame and
1180+ // avcodec_send_packet, while specialized interfaces can override for
1181+ // hardware-specific optimizations.
11831182 while (true ) {
1184- if (deviceInterface_->canDecodePacketDirectly ()) {
1185- status = deviceInterface_->receiveFrame (avFrame);
1186- } else {
1187- status =
1188- avcodec_receive_frame (streamInfo.codecContext .get (), avFrame.get ());
1189- }
1183+ status = deviceInterface_->receiveFrame (avFrame);
11901184
11911185 if (status != AVSUCCESS && status != AVERROR (EAGAIN)) {
11921186 // Non-retriable error
@@ -1222,13 +1216,7 @@ UniqueAVFrame SingleStreamDecoder::decodeAVFrame(
12221216
12231217 if (status == AVERROR_EOF) {
12241218 // End of file reached. We must drain the decoder
1225- if (deviceInterface_->canDecodePacketDirectly ()) {
1226- status = deviceInterface_->sendEOFPacket ();
1227- } else {
1228- status = avcodec_send_packet (
1229- streamInfo.codecContext .get (),
1230- /* avpkt=*/ nullptr );
1231- }
1219+ status = deviceInterface_->sendEOFPacket ();
12321220 TORCH_CHECK (
12331221 status >= AVSUCCESS,
12341222 " Could not flush decoder: " ,
@@ -1253,11 +1241,7 @@ UniqueAVFrame SingleStreamDecoder::decodeAVFrame(
12531241
12541242 // We got a valid packet. Send it to the decoder, and we'll receive it in
12551243 // the next iteration.
1256- if (deviceInterface_->canDecodePacketDirectly ()) {
1257- status = deviceInterface_->sendPacket (packet);
1258- } else {
1259- status = avcodec_send_packet (streamInfo.codecContext .get (), packet.get ());
1260- }
1244+ status = deviceInterface_->sendPacket (packet);
12611245 TORCH_CHECK (
12621246 status >= AVSUCCESS,
12631247 " Could not push packet to decoder: " ,
0 commit comments