How to get stream info from opened file in ffmpeg?

2019-05-05 12:21发布

问题:

I am trying to read video file using ffmpeg. I had working code that corresponded to somewhat old version of it, and started to try and upgrade to latest build version, exchanging all those deprecated functions for their actual analogues.

However i have run into a problem. No streams seem to be retrieved and the load of video stops dead in tracks.

here is the code i am using:

   // Open video file
   if(avformat_open_input(&pFormatCtx, filename.toStdString().c_str(), NULL, NULL)!=0)
       return FILE_NOT_OPENED; // Couldn't open file

   // Retrieve stream information
   if(avformat_find_stream_info(pFormatCtx,NULL)<0)
       return NO_STREAM_INFO; // Couldn't find stream information

   // Dump information about file onto standard error
   av_dump_format(pFormatCtx, 0, filename.toStdString().c_str(), false);

   // Find the first video stream
   videoStream=-1;
   for(unsigned i=0; i<pFormatCtx->nb_streams; i++)
       if(pFormatCtx->streams[i]->codec->codec_type==ffmpeg::AVMEDIA_TYPE_VIDEO)
       {
           videoStream=i;
           break;
       }
   if(videoStream==-1)
       return OTHER; // Didn't find a video stream

   // Get a pointer to the codec context for the video stream
   pCodecCtx=pFormatCtx->streams[videoStream]->codec;

   // Find the decoder for the video stream
   pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
   if(pCodec==NULL)
       return CODEC_NOT_FOUND; // Codec not found

   // Open codec
   if(avcodec_open2(pCodecCtx, pCodec,NULL)<0)
       return CODEC_NOT_OPENED; // Could not open codec

The problem arises in the cycle through video streams in ffmpeg::AVFormatContext *pFormatCtx. nb_streams field is 0, and i never actually enter the cycle, and codec is not loaded etc. Strange thing is, av_dump_format gives following output:

License: GPL version 3 or later
AVCodec version 3606372
AVFormat configuration: --disable-static --enable-shared --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libcaca --enable-libfreetype --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxavs --enable-libxvid --enable-zlib
[asf @ 004e9540] Stream #0: not enough frames to estimate rate; consider increasing probesize
Input #0, asf, from 'C:/Users/Public/Videos/Sample Videos/Wildlife.wmv':
  Metadata:
    SfOriginalFPS   : 299700
    WMFSDKVersion   : 11.0.6001.7000
    WMFSDKNeeded    : 0.0.0.0000
    comment         : Footage: Small World Productions, Inc; Tourism New Zealand | Producer: Gary F. Spradling | Music: Steve Ball
    title           : Wildlife in HD
    copyright       : В© 2008 Microsoft Corporation
    IsVBR           : 0
    DeviceConformanceTemplate: AP@L3
  Duration: 00:00:30.09, start: 0.000000, bitrate: 6977 kb/s
    Stream #0:0(eng): Audio: wmav2 (a[1][0][0] / 0x0161), 44100 Hz, 2 channels, fltp, 192 kb/s
    Stream #0:1(eng): Video: vc1 (Advanced) (WVC1 / 0x31435657), yuv420p, 1280x720, 5942 kb/s, 29.97 tbr, 1k tbn, 1k tbc

and there are 2 streams, clear as day.

I am utterly baffled. Please help.

回答1:

If av_dump_format works, but nb_streams is zero in your code, you have mismatching libraries and headers I guess.

av_dump_format relies on nb_streams too, as can bee seen in its source. So the binary code you used for av_dump_format can read nb_streams. It is likely that you are using a precompiled static or dynamic avformat library, which does not match your avformat.h header version. Thus your code may look for nb_streams at an wrong location or type, for example.

Make sure you use the header files exactly matching the ones used for making the binaries of the libraries used.