[Libav-user] Reading correct frame rate (fps) of input video

Taha Ansari mtaha.ansari at gmail.com
Wed May 22 11:03:56 CEST 2013


Hi guys,

I have come up with a quick patch:

//------------------------------
AVStream *st = pFormatCtx->streams[this->videoStream ];
        if ( st->codec->codec_id == AV_CODEC_ID_H264 )//mp4
        {
            video_frame_rate    = st->avg_frame_rate.num /
(double)st->avg_frame_rate.den;
        }
        else if ( st->codec->codec_id == AV_CODEC_ID_MJPEG )
        {
            video_frame_rate    = st->r_frame_rate.num /
(double)st->r_frame_rate.den;
        }
        else if ( st->codec->codec_id == AV_CODEC_ID_FLV1 )
        {
            video_frame_rate    = st->r_frame_rate.num /
(double)st->r_frame_rate.den;
        }
        else if ( st->codec->codec_id == AV_CODEC_ID_WMV3 )
        {
            video_frame_rate    = st->r_frame_rate.num /
(double)st->r_frame_rate.den;
        }
        else if ( st->codec->codec_id == AV_CODEC_ID_MPEG4 )//3gp
        {
            video_frame_rate    = st->r_frame_rate.num /
(double)st->r_frame_rate.den;
        }
        else
        {
            video_frame_rate    = st->r_frame_rate.num /
(double)st->r_frame_rate.den;
        }
//---------------------------
This way I can add up more files as I encounter them. Question now: is this
solution elegant? I would love to know if there is any generic/proper
implementation for this.

Thanks again for your time,



On Wed, May 22, 2013 at 12:28 PM, Taha Ansari <mtaha.ansari at gmail.com>wrote:

> Like I spoke too soon, (I have also included time_base structure):
>
> when tried on:
>
> - FLV file: for r_frame_rate: {num=15 den=1 }, for avg_frame_rate: {num=0
> den=0 }, for time_base: {num=1 den=1000 }
>
> - WMV file: for r_frame_rate: {num=15 den=1 }, for avg_frame_rate: {num=0
> den=0 }, for time_base: {num=1 den=1000 }
>
> - AVI file: for r_frame_rate: {num=15 den=1 }, for avg_frame_rate:{num=0
> den=0 }, for time_base: {num=1 den=15 }
>
> - 3gp file: for r_frame_rate: {num=361 den=12 }, for avg_frame_rate:
> {num=64350000 den=2139391 }, for time_base: {num=1 den=90000 } (30.08,
> 30.078 fps respectively)
>
> - MP4 file: for r_frame_rate: {num=599 den=12 }, for avg_frame_rate:
> {num=25 den=1 }, for time_base:  {num=1 den=90000 } (49.9, 25 fps
> respectively - first figure is wrong).
>
>
> So, is there any way to know for sure which structure I could surely rely
> on?
>
> Thanks again for your time..
>
>
> On Wed, May 22, 2013 at 12:12 PM, Taha Ansari <mtaha.ansari at gmail.com>wrote:
>
>> I just noticed one more thing:
>>
>> using:
>>
>>
>> AVStream *st = pFormatCtx->streams[your_video_index];
>> double frame_rate = st->r_frame_rate.num / (double)st->r_frame_rate.den;
>>
>> gives me correct values for 3gp files. When I tried this code on an MP4
>> file, I got about 49.9 value, which was incorrect (actual was 25); looking
>> at other values, I tried following:
>>
>>
>> AVStream *st = pFormatCtx->streams[your_video_index ];
>> double frame_rate    = st->avg_frame_rate.num /
>> (double)st->avg_frame_rate.den;
>>
>> It worked fine for MP4: {num=25 den=1 }, and for 3gp, I get:
>> {num=64350000 den=2139391 } (30.078 FPS), which is also correct.
>>
>> So I assume this might be better structure to refer to, until it breaks
>> again on another video...?
>>
>>
>> On Wed, May 22, 2013 at 8:48 AM, Taha Ansari <mtaha.ansari at gmail.com>wrote:
>>
>>> Hi Guohui Huan!
>>>
>>> Many thanks for your guidance, I have got it working now!
>>>
>>> Thanks once again...
>>>
>>>
>>> On Wed, May 22, 2013 at 5:58 AM, Guohui Huang <huanggh0108 at sina.com>wrote:
>>>
>>>> **
>>>> You can get frame rate as follow:
>>>> AVStream *st = pFormatCtx->streams[your_video_index];
>>>> double frame_rate = st->r_frame_rate.num / (double)st->r_frame_rate.den;
>>>>
>>>> 2013-05-22
>>>>  ------------------------------
>>>>  Guohui Huang
>>>>  ------------------------------
>>>>  *发件人:*Taha Ansari <mtaha.ansari at gmail.com>
>>>> *发送时间:*2013-05-21 23:04
>>>> *主题:*[Libav-user] Reading correct frame rate (fps) of input video
>>>> *收件人:*"This list is about using libavcodec, libavformat, libavutil,
>>>> libavdevice and libavfilter."<libav-user at ffmpeg.org>
>>>> *抄送:*
>>>>
>>>>  Hi!
>>>>
>>>> I am trying to read exact values for frame rate (fps) from any input
>>>> video file. I have been trying to debug different structures like
>>>> AVFormatCtx, etc. but cannot seem to figure it out. For a test case, here
>>>> is the code I have managed (just the source snippet, include files etc. are
>>>> all understandable):
>>>>
>>>>
>>>> //---------------------------------------------------------------------------------------------------------------------------------------------------
>>>>     // ++ test code begins ++//
>>>>     av_register_all();
>>>>     avcodec_register_all();
>>>>     avformat_network_init();
>>>>     avdevice_register_all();
>>>>     AVFormatContext *pFormatCtx = NULL;
>>>>     pFormatCtx = avformat_alloc_context();
>>>>     string finalInputName = "test_input.3gp";
>>>>     avformat_open_input(&pFormatCtx, finalInputName.c_str(), NULL,
>>>> NULL);
>>>>     if ( pFormatCtx == NULL            ||
>>>>         pFormatCtx->iformat == NULL    )
>>>>     {
>>>>         return -1;
>>>>     }
>>>>     // Retrieve stream information
>>>>     if(avformat_find_stream_info(pFormatCtx, NULL)<0)
>>>>         return -1; // Couldn't find stream information
>>>>
>>>>     // Dump information about file onto standard error
>>>>     av_dump_format(pFormatCtx, 0, finalInputName.c_str(), 0);
>>>>     // -- test code ends --//
>>>>
>>>> //---------------------------------------------------------------------------------------------------------------------------------------------------
>>>>
>>>> The output it gives me is (in debug console):
>>>>
>>>>
>>>> //---------------------------------------------------------------------------------------------------------------------------------------------------
>>>> Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test_input.3gp':
>>>>   Metadata:
>>>>     major_brand     : 3gp4
>>>>     minor_version   : 0
>>>>     compatible_brands: isom3gp4
>>>>     creation_time   : 2013-05-20 11:54:39
>>>>   Duration: 00:00:23.77, start: 0.000000, bitrate: 5882 kb/s
>>>>     Stream #0:0(eng): Video: mpeg4 (Advanced Simple Profile) (mp4v /
>>>> 0x7634706D)
>>>> , yuv420p, 640x480 [SAR 1:1 DAR 4:3], 5752 kb/s, 30.08 fps, 30.08 tbr,
>>>> 90k tbn,
>>>> 300 tbc
>>>>     Metadata:
>>>>       creation_time   : 2013-05-20 11:54:39
>>>>       handler_name    : VideoHandle
>>>>     Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 16000 Hz, stereo,
>>>> s16, 127
>>>>  kb/s
>>>>     Metadata:
>>>>       creation_time   : 2013-05-20 11:54:39
>>>>       handler_name    : SoundHandle
>>>>
>>>> //---------------------------------------------------------------------------------------------------------------------------------------------------
>>>>
>>>> Like in above example, I can read that video is recorded at 30.08 fps,
>>>> question is: it is apparently very simple for FFmpeg to figure this out,
>>>> but how can I use this information from my own program? I was trying to
>>>> follow code from FFmpeg source file (utils.c): [void
>>>> av_dump_format(AVFormatContext *ic,  int index, const char *url, int
>>>> is_output)], but was easily lost there.
>>>>
>>>> Can anyone kindly guide me how to intercept this problem?
>>>>
>>>> Thanks in advance for your time...
>>>>
>>>> _______________________________________________
>>>> Libav-user mailing list
>>>> Libav-user at ffmpeg.org
>>>> http://ffmpeg.org/mailman/listinfo/libav-user
>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20130522/09c102db/attachment.html>


More information about the Libav-user mailing list