-
Notifications
You must be signed in to change notification settings - Fork 25.2k
Closed
Labels
caffe2module: dependency bugProblem is not caused by us, but caused by an upstream library we useProblem is not caused by us, but caused by an upstream library we usetriagedThis issue has been looked at a team member, and triaged and prioritized into an appropriate moduleThis issue has been looked at a team member, and triaged and prioritized into an appropriate module
Description
Describe the bug
caffe2/video/video_decoder.cc
use several parts of the FFMPEG API that have been deprecated for a while, and that have been removed in the recent FFMPEG 5.0 release. This naturally makes the Caffe2 part of PyTorch unbuildable with FFMPEG 5.0.
See also this Debian bug.
Partial fix
Many of the changes are very mechanical to implement. As an example, this patch against an older PyTorch (but representative of the changes needed in git HEAD too)
---
caffe2/video/video_decoder.cc | 30 ++++++++++++++++++------------
1 file changed, 18 insertions(+), 12 deletions(-)
diff --git a/caffe2/video/video_decoder.cc b/caffe2/video/video_decoder.cc
index d40bc05..a496380 100644
--- a/caffe2/video/video_decoder.cc
+++ b/caffe2/video/video_decoder.cc
@@ -12,8 +12,10 @@ VideoDecoder::VideoDecoder() {
static std::mutex gMutex;
std::unique_lock<std::mutex> lock(gMutex);
if (!gInitialized) {
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 10, 100)
av_register_all();
avcodec_register_all();
+#endif
avformat_network_init();
gInitialized = true;
}
@@ -185,12 +187,12 @@ void VideoDecoder::decodeLoop(
if (params.streamIndex_ == -1) {
for (int i = 0; i < inputContext->nb_streams; i++) {
auto stream = inputContext->streams[i];
- if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
+ if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
videoStreamIndex_ == -1) {
videoStreamIndex_ = i;
videoStream_ = stream;
} else if (
- stream->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
+ stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
audioStreamIndex_ == -1) {
audioStreamIndex_ = i;
}
@@ -207,7 +209,11 @@ void VideoDecoder::decodeLoop(
// Initialize codec
AVDictionary* opts = nullptr;
- videoCodecContext_ = videoStream_->codec;
+ ret = avcodec_parameters_to_context(videoCodecContext_, videoStream_->codecpar);
+ if (ret < 0) {
+ LOG(ERROR) << "Cannot get codec context from parameters";
+ return;
+ }
try {
ret = avcodec_open2(
videoCodecContext_,
@@ -452,12 +458,12 @@ void VideoDecoder::decodeLoop(
ret = av_read_frame(inputContext, &packet);
if (ret == AVERROR_EOF) {
eof = 1;
- av_free_packet(&packet);
+ av_packet_unref(&packet);
packet.data = nullptr;
packet.size = 0;
// stay in the while loop to flush frames
} else if (ret == AVERROR(EAGAIN)) {
- av_free_packet(&packet);
+ av_packet_unref(&packet);
continue;
} else if (ret < 0) {
LOG(ERROR) << "Error reading packet : " << ffmpegErrorStr(ret);
@@ -483,7 +489,7 @@ void VideoDecoder::decodeLoop(
}
if (si != videoStreamIndex_) {
- av_free_packet(&packet);
+ av_packet_unref(&packet);
continue;
}
}
@@ -497,7 +503,7 @@ void VideoDecoder::decodeLoop(
try {
// Nothing to do without a picture
if (!gotPicture) {
- av_free_packet(&packet);
+ av_packet_unref(&packet);
continue;
}
frameIndex++;
@@ -534,7 +540,7 @@ void VideoDecoder::decodeLoop(
if (!keyFrame) {
// if fps == SpecialFps::SAMPLE_NO_FRAME (0), don't sample at all
if (currFps == SpecialFps::SAMPLE_NO_FRAME) {
- av_free_packet(&packet);
+ av_packet_unref(&packet);
continue;
}
@@ -560,7 +566,7 @@ void VideoDecoder::decodeLoop(
timestamp >= lastFrameTimestamp + (1 / currFps));
if (!fpsReached) {
- av_free_packet(&packet);
+ av_packet_unref(&packet);
continue;
}
}
@@ -571,7 +577,7 @@ void VideoDecoder::decodeLoop(
if (params.maximumOutputFrames_ != -1 &&
outputFrameIndex >= params.maximumOutputFrames_) {
// enough frames
- av_free_packet(&packet);
+ av_packet_unref(&packet);
break;
}
@@ -628,9 +634,9 @@ void VideoDecoder::decodeLoop(
av_frame_unref(audioStreamFrame_);
}
- av_free_packet(&packet);
+ av_packet_unref(&packet);
} catch (const std::exception&) {
- av_free_packet(&packet);
+ av_packet_unref(&packet);
}
} // of while loop
callback.videoDecodingEnded(timestamp);
seems to take care of a lot of them. However, replacing avcodec_decode_video2
and friends with the newer avcodec_receive_frame
probably takes some care and thought.
Versions
This behavior is present in the current master HEAD at the time of writing, although the partial patch above is for an older version.
rien333 and brlin-tw
Metadata
Metadata
Assignees
Labels
caffe2module: dependency bugProblem is not caused by us, but caused by an upstream library we useProblem is not caused by us, but caused by an upstream library we usetriagedThis issue has been looked at a team member, and triaged and prioritized into an appropriate moduleThis issue has been looked at a team member, and triaged and prioritized into an appropriate module