ffmpeg avcodec_open2改变了AVCodecContext中的音频格式

时间:2016-05-15 06:32:55

标签: c++ ffmpeg

我有一个带有DTS轨道的mkv文件。

调用avcodec_open2后,AVCodexContext中的sample_fmt发生了变化。是预期的吗?

AVCodecContext* avAudioCodecCtx = avFormatCtx->streams[audioStreamIndex]->codec;

AVSampleFormat f = avAudioCodecCtx->sample_fmt; // AV_SAMPLE_FMT_FLTP
avcodec_open2(avAudioCodecCtx, avAudioCodec, NULL);
AVSampleFormat f2 = avAudioCodecCtx->sample_fmt; // AV_SAMPLE_FMT_S32P

ffprobe

ffprobe version N-79143-g8ff0f6a Copyright (c) 2007-2016 the FFmpeg developers
  built with gcc 5.3.0 (GCC)
  configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libdcadec --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmfx --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-lzma --enable-decklink --enable-zlib
  libavutil      55. 19.100 / 55. 19.100
  libavcodec     57. 30.100 / 57. 30.100
  libavformat    57. 29.101 / 57. 29.101
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 40.102 /  6. 40.102
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
  libpostproc    54.  0.100 / 54.  0.100

Stream #0:1(eng): Audio: dts (DTS), 48000 Hz, 5.1(side), fltp, 768 kb/s (default)

解码

avcodec_decode_audio4(avAudioCodecCtx, frame, &frameComplete, avPacket);
frame->format // contains AV_SAMPLE_FMT_FLTP

1 个答案:

答案 0 :(得分:2)

是的,这是预料之中的。因此,这可能有些烦人,但avcodec_open2()只是在打开编解码器时根据sample_fmt中存储的信息将AVCodecContext设置为“最可能”的格式。对于某些格式,所有这些信息都在比特流数据包中,所以他们只是不知道。

实际格式在AVFrame->format中为每个解码数据包设置(或解码数据包后AVCodecContext->sample_fmt)。这在整个流中通常是不变的,但这不能保证。 调用AVCodecContext->format之前格式与avcodec_open2() 中的格式相同的原因是,分路器(或更具体地,avformat_find_stream_info())可能会打开解码器并尝试解码一个帧;发生这种情况时,AVCodecContext->sample_fmt设置为与AVFrame->format相同的值,但是当您调用avcodec_open2()以启动实际比特流解码时,此值会再次被覆盖...

结论:使用AVCodecContext->sample_fmt作为信息,并依赖AVFrame->format进行任何实际用途。