瀏覽代碼

ffmpeg: Use AVStream.codecpar

AVStream.codec is deprecated as of libavformat version 57.41.100,
so if this version is detected, we switch to AVStream.codecpar instead.

Note this also makes it necessary to construct and use our own codec
context - but doing that is a cleaner approach anyway.
Sam Edwards 7 年之前
父節點
當前提交
9596095294
共有 2 個文件被更改,包括 91 次插入17 次删除
  1. 42 7
      panda/src/ffmpeg/ffmpegAudioCursor.cxx
  2. 49 10
      panda/src/ffmpeg/ffmpegVideoCursor.cxx

+ 42 - 7
panda/src/ffmpeg/ffmpegAudioCursor.cxx

@@ -68,28 +68,58 @@ FfmpegAudioCursor(FfmpegAudio *src) :
     return;
     return;
   }
   }
 
 
+  // As of libavformat version 57.41.100, AVStream.codec is deprecated in favor
+  // of AVStream.codecpar.  Fortunately, the two structures have
+  // similarly-named members, so we can just switch out the declaration.
+#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 41, 100)
+  AVCodecParameters *codecpar;
+#else
+  AVCodecContext *codecpar;
+#endif
+
   // Find the audio stream
   // Find the audio stream
+  AVStream *stream = nullptr;
   for (int i = 0; i < (int)_format_ctx->nb_streams; i++) {
   for (int i = 0; i < (int)_format_ctx->nb_streams; i++) {
-    if (_format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 41, 100)
+    codecpar = _format_ctx->streams[i]->codecpar;
+#else
+    codecpar = _format_ctx->streams[i]->codec;
+#endif
+    if (codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
       _audio_index = i;
       _audio_index = i;
-      _audio_ctx = _format_ctx->streams[i]->codec;
-      _audio_timebase = av_q2d(_format_ctx->streams[i]->time_base);
-      _audio_rate = _audio_ctx->sample_rate;
-      _audio_channels = _audio_ctx->channels;
+      stream = _format_ctx->streams[i];
+      break;
     }
     }
   }
   }
 
 
-  if (_audio_ctx == 0) {
+  if (stream == nullptr) {
     cleanup();
     cleanup();
     return;
     return;
   }
   }
 
 
-  AVCodec *pAudioCodec = avcodec_find_decoder(_audio_ctx->codec_id);
+  _audio_timebase = av_q2d(stream->time_base);
+  _audio_rate = codecpar->sample_rate;
+  _audio_channels = codecpar->channels;
+
+  AVCodec *pAudioCodec = avcodec_find_decoder(codecpar->codec_id);
   if (pAudioCodec == 0) {
   if (pAudioCodec == 0) {
     cleanup();
     cleanup();
     return;
     return;
   }
   }
 
 
+  _audio_ctx = avcodec_alloc_context3(pAudioCodec);
+
+  if (_audio_ctx == nullptr) {
+    cleanup();
+    return;
+  }
+
+#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 41, 100)
+  avcodec_parameters_to_context(_audio_ctx, codecpar);
+#else
+  avcodec_copy_context(_audio_ctx, codecpar);
+#endif
+
   AVDictionary *opts = NULL;
   AVDictionary *opts = NULL;
   av_dict_set(&opts, "request_sample_fmt", "s16", 0);
   av_dict_set(&opts, "request_sample_fmt", "s16", 0);
   if (avcodec_open2(_audio_ctx, pAudioCodec, NULL) < 0) {
   if (avcodec_open2(_audio_ctx, pAudioCodec, NULL) < 0) {
@@ -202,6 +232,11 @@ cleanup() {
 
 
   if ((_audio_ctx)&&(_audio_ctx->codec)) {
   if ((_audio_ctx)&&(_audio_ctx->codec)) {
     avcodec_close(_audio_ctx);
     avcodec_close(_audio_ctx);
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 52, 0)
+    avcodec_free_context(&_audio_ctx);
+#else
+    delete _audio_ctx;
+#endif
   }
   }
   _audio_ctx = NULL;
   _audio_ctx = NULL;
 
 

+ 49 - 10
panda/src/ffmpeg/ffmpegVideoCursor.cxx

@@ -482,37 +482,55 @@ open_stream() {
     return false;
     return false;
   }
   }
 
 
-  // Find the video stream
   nassertr(_video_ctx == NULL, false);
   nassertr(_video_ctx == NULL, false);
+
+  // As of libavformat version 57.41.100, AVStream.codec is deprecated in favor
+  // of AVStream.codecpar.  Fortunately, the two structures have
+  // similarly-named members, so we can just switch out the declaration.
+#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 41, 100)
+  AVCodecParameters *codecpar;
+#else
+  AVCodecContext *codecpar;
+#endif
+
+  // Find the video stream
+  AVStream *stream = nullptr;
   for (int i = 0; i < (int)_format_ctx->nb_streams; ++i) {
   for (int i = 0; i < (int)_format_ctx->nb_streams; ++i) {
-    if (_format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 41, 100)
+    codecpar = _format_ctx->streams[i]->codecpar;
+#else
+    codecpar = _format_ctx->streams[i]->codec;
+#endif
+    if (codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
       _video_index = i;
       _video_index = i;
-      _video_ctx = _format_ctx->streams[i]->codec;
-      _video_timebase = av_q2d(_format_ctx->streams[i]->time_base);
-      _min_fseek = (int)(3.0 / _video_timebase);
+      stream = _format_ctx->streams[i];
+      break;
     }
     }
   }
   }
 
 
-  if (_video_ctx == NULL) {
+  if (stream == nullptr) {
     ffmpeg_cat.info()
     ffmpeg_cat.info()
-      << "Couldn't find video_ctx\n";
+      << "Couldn't find stream\n";
     close_stream();
     close_stream();
     return false;
     return false;
   }
   }
 
 
+  _video_timebase = av_q2d(stream->time_base);
+  _min_fseek = (int)(3.0 / _video_timebase);
+
   AVCodec *pVideoCodec = NULL;
   AVCodec *pVideoCodec = NULL;
   if (ffmpeg_prefer_libvpx) {
   if (ffmpeg_prefer_libvpx) {
 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 0, 0)
 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 0, 0)
-    if (_video_ctx->codec_id == AV_CODEC_ID_VP9) {
+    if (codecpar->codec_id == AV_CODEC_ID_VP9) {
       pVideoCodec = avcodec_find_decoder_by_name("libvpx-vp9");
       pVideoCodec = avcodec_find_decoder_by_name("libvpx-vp9");
     } else
     } else
 #endif
 #endif
-    if (_video_ctx->codec_id == AV_CODEC_ID_VP8) {
+    if (codecpar->codec_id == AV_CODEC_ID_VP8) {
       pVideoCodec = avcodec_find_decoder_by_name("libvpx");
       pVideoCodec = avcodec_find_decoder_by_name("libvpx");
     }
     }
   }
   }
   if (pVideoCodec == NULL) {
   if (pVideoCodec == NULL) {
-    pVideoCodec = avcodec_find_decoder(_video_ctx->codec_id);
+    pVideoCodec = avcodec_find_decoder(codecpar->codec_id);
   }
   }
   if (pVideoCodec == NULL) {
   if (pVideoCodec == NULL) {
     ffmpeg_cat.info()
     ffmpeg_cat.info()
@@ -520,6 +538,22 @@ open_stream() {
     close_stream();
     close_stream();
     return false;
     return false;
   }
   }
+
+  _video_ctx = avcodec_alloc_context3(pVideoCodec);
+
+  if (_video_ctx == nullptr) {
+    ffmpeg_cat.info()
+      << "Couldn't allocate _video_ctx\n";
+    close_stream();
+    return false;
+  }
+
+#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 41, 100)
+  avcodec_parameters_to_context(_video_ctx, codecpar);
+#else
+  avcodec_copy_context(_video_ctx, codecpar);
+#endif
+
   if (avcodec_open2(_video_ctx, pVideoCodec, NULL) < 0) {
   if (avcodec_open2(_video_ctx, pVideoCodec, NULL) < 0) {
     ffmpeg_cat.info()
     ffmpeg_cat.info()
       << "Couldn't open codec\n";
       << "Couldn't open codec\n";
@@ -547,6 +581,11 @@ close_stream() {
 
 
   if ((_video_ctx)&&(_video_ctx->codec)) {
   if ((_video_ctx)&&(_video_ctx->codec)) {
     avcodec_close(_video_ctx);
     avcodec_close(_video_ctx);
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 52, 0)
+    avcodec_free_context(&_video_ctx);
+#else
+    delete _video_ctx;
+#endif
   }
   }
   _video_ctx = NULL;
   _video_ctx = NULL;