Skip to content

Commit

Permalink
Avoid unnecessary calls to avcodec_receive_frame in decoding loop (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
NicolasHug authored Feb 7, 2025
1 parent 79c3934 commit b87f00d
Showing 1 changed file with 26 additions and 25 deletions.
51 changes: 26 additions & 25 deletions src/torchcodec/decoders/_core/VideoDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -971,43 +971,44 @@ VideoDecoder::AVFrameStream VideoDecoder::decodeAVFrame(
}

if (reachedEOF) {
// We don't have any more packets to send to the decoder. So keep on
// pulling frames from its internal buffers.
// We don't have any more packets to receive. So keep on pulling frames
// from its internal buffers.
continue;
}

// We still haven't found the frame we're looking for. So let's read more
// packets and send them to the decoder.
ReferenceAVPacket packet(autoAVPacket);
ffmpegStatus = av_read_frame(formatContext_.get(), packet.get());
decodeStats_.numPacketsRead++;
do {
ffmpegStatus = av_read_frame(formatContext_.get(), packet.get());
decodeStats_.numPacketsRead++;

if (ffmpegStatus == AVERROR_EOF) {
// End of file reached. We must drain the codec by sending a nullptr
// packet.
ffmpegStatus = avcodec_send_packet(
streamInfo.codecContext.get(),
/*avpkt=*/nullptr);
if (ffmpegStatus < AVSUCCESS) {
throw std::runtime_error(
"Could not flush decoder: " +
getFFMPEGErrorStringFromErrorCode(ffmpegStatus));
}

reachedEOF = true;
break;
}

if (ffmpegStatus == AVERROR_EOF) {
// End of file reached. We must drain the codec by sending a nullptr
// packet.
ffmpegStatus = avcodec_send_packet(
streamInfo.codecContext.get(),
/*avpkt=*/nullptr);
if (ffmpegStatus < AVSUCCESS) {
throw std::runtime_error(
"Could not flush decoder: " +
"Could not read frame from input file: " +
getFFMPEGErrorStringFromErrorCode(ffmpegStatus));
}
} while (packet->stream_index != activeStreamIndex_);

// We've reached the end of file so we can't read any more packets from
// it, but the decoder may still have frames to read in its buffer.
// Continue iterating to try reading frames.
reachedEOF = true;
continue;
}

if (ffmpegStatus < AVSUCCESS) {
throw std::runtime_error(
"Could not read frame from input file: " +
getFFMPEGErrorStringFromErrorCode(ffmpegStatus));
}

if (packet->stream_index != activeStreamIndex_) {
if (reachedEOF) {
// We don't have any more packets to send to the decoder. So keep on
// pulling frames from its internal buffers.
continue;
}

Expand Down

0 comments on commit b87f00d

Please sign in to comment.