Recherche avancée

Médias (0)

Mot : - Tags -/content

Aucun média correspondant à vos critères n’est disponible sur le site.

Autres articles (65)

Sur d’autres sites (13447)

  • Slightly different number of total frames between my program (using libav) and ffprobe

    16 juin 2022, par Alvein

    For learning purposes, I made a routine that decodes each frame for each stream inside a given container.

    


    I noticed that for some videos, the amount of frames returned by my code differs the one calculated by the tool ffprobe (which comes with ffmpeg).

    


    I'm using ffprobe like this :

    


    ffprobe <media file="file"> -v error -select_streams v:0 -count_frames -show_entries stream=nb_read_frames&#xA;</media>

    &#xA;

    Replacing "v:0" with "a:0" for audio, etc.

    &#xA;

    And this is my source code :

    &#xA;

    void showFrames(char *szFilename) {&#xA;    int               iError;&#xA;    char              szError[AV_ERROR_MAX_STRING_SIZE];&#xA;    AVFormatContext   *fcFormatCtx;&#xA;    AVCodec           *cdCodec;&#xA;    AVCodecParameters *cdpCodecParams;&#xA;    AVCodecContext    *ccCodecCtx;&#xA;    AVPacket          *pkPacket;&#xA;    AVFrame           *frFrame;&#xA;    fcFormatCtx=avformat_alloc_context();&#xA;    iError=avformat_open_input(&amp;fcFormatCtx,szFilename,NULL,NULL);&#xA;    if(0>iError) {&#xA;        av_strerror(iError,szError,sizeof(szError));&#xA;        fprintf(stderr,"avformat_open_input() failed: %s\n",szError);&#xA;        return;&#xA;    }&#xA;    iError=avformat_find_stream_info(fcFormatCtx,NULL);&#xA;    if(0>iError) {&#xA;        av_strerror(iError,szError,sizeof(szError));&#xA;        fprintf(stderr,"avformat_find_stream_info() failed: %s\n",szError);&#xA;        avformat_close_input(&amp;fcFormatCtx);&#xA;        return;&#xA;    }&#xA;    for(uint uiSt=0;uiStnb_streams;uiSt&#x2B;&#x2B;) {&#xA;        cdpCodecParams=fcFormatCtx->streams[uiSt]->codecpar;&#xA;        cdCodec=avcodec_find_decoder(cdpCodecParams->codec_id);&#xA;        if(NULL==cdCodec) {&#xA;            fprintf(stderr,"no codec found for stream %u\n",uiSt);&#xA;            continue;&#xA;        }&#xA;        fprintf(stderr,"stream %u\n",uiSt);&#xA;        if(AVMEDIA_TYPE_VIDEO==cdpCodecParams->codec_type)&#xA;            fprintf(stderr,"video codec id=%d name=&#x27;%s&#x27;\n",&#xA;                    cdCodec->id,cdCodec->long_name);&#xA;        else if(AVMEDIA_TYPE_AUDIO==cdpCodecParams->codec_type)&#xA;            fprintf(stderr,"audio codec id=%d name=&#x27;%s&#x27;\n",&#xA;                    cdCodec->id,cdCodec->long_name);&#xA;        else {&#xA;            fprintf(stderr,"unsupported codec id=%d name=&#x27;%s&#x27;\n",&#xA;                    cdCodec->id,cdCodec->long_name);&#xA;            continue;&#xA;        }&#xA;        ccCodecCtx=avcodec_alloc_context3(cdCodec);&#xA;        avcodec_parameters_to_context(ccCodecCtx,cdpCodecParams);&#xA;        iError=avcodec_open2(ccCodecCtx,cdCodec,NULL);&#xA;        if(0>iError) {&#xA;            av_strerror(iError,szError,sizeof(szError));&#xA;            fprintf(stderr,"avcodec_open2() failed: %s\n",szError);&#xA;            avcodec_free_context(&amp;ccCodecCtx);&#xA;            continue;&#xA;        }&#xA;        pkPacket=av_packet_alloc();&#xA;        frFrame=av_frame_alloc();&#xA;        av_seek_frame(fcFormatCtx,uiSt,0,AVSEEK_FLAG_FRAME);&#xA;        while(0==av_read_frame(fcFormatCtx,pkPacket)) {&#xA;            if(uiSt==pkPacket->stream_index) {&#xA;                iError=avcodec_send_packet(ccCodecCtx,pkPacket);&#xA;                if(0>iError) {&#xA;                    av_strerror(iError,szError,sizeof(szError));&#xA;                    fprintf(stderr,"avcodec_send_packet() failed: %s\n",szError);&#xA;                    break;&#xA;                }&#xA;                while(true) {&#xA;                    iError=avcodec_receive_frame(ccCodecCtx,frFrame);&#xA;                    if(0>iError)&#xA;                        break;&#xA;                    fprintf(stderr,"stream %u, frame %d\n",&#xA;                            uiSt,ccCodecCtx->frame_number);&#xA;                    av_frame_unref(frFrame);&#xA;                }&#xA;                if(AVERROR(EAGAIN)!=iError&amp;&amp;AVERROR_EOF!=iError) {&#xA;                    av_strerror(iError,szError,sizeof(szError));&#xA;                    fprintf(stderr,"avcodec_receive_frame() failed: %s\n",szError);&#xA;                    break;&#xA;                }&#xA;            }&#xA;            av_packet_unref(pkPacket);&#xA;        }&#xA;        av_packet_free(&amp;pkPacket);&#xA;        av_frame_free(&amp;frFrame);&#xA;        avcodec_free_context(&amp;ccCodecCtx);&#xA;    }&#xA;    avformat_close_input(&amp;fcFormatCtx);&#xA;}&#xA;

    &#xA;

    It's pretty much self contained but you may ignore all the initializations and go directly to the while after the call to av_seek_frame(). This is where the actual frames are being read.

    &#xA;

    BTW, I'm using av_seek_frame() because this program goes stream by stream, separating the frames, so I need to rewind with every stream found.

    &#xA;

    Anyway, I've tested the previous code with the following files :

    &#xA;

    #1. sample-10s.mp4 from https://samplelib.com/sample-mp4.html ...

    &#xA;

    &#xA;

    My program : 301 video frames ; 440 audio frames

    &#xA;

    ffprobe : 303 video frames ; 440 audio frames

    &#xA;

    &#xA;

    #2. production ID_3997798.mp4 from https://www.pexels.com/video/hands-hand-table-colorful-3997798/ ...

    &#xA;

    &#xA;

    My program : 736 video frames ; no audio frames

    &#xA;

    ffprobe : 738 video frames ; no audio frames

    &#xA;

    &#xA;

    I found more videos with this difference, but it ONLY happens in the video streams.

    &#xA;

    Is there something I am forgetting ? There seem to be always 2 frames behind what ffprobe shows.

    &#xA;

    Thank you.

    &#xA;

  • Get displaymatrix and change it using ffmpeg C API [closed]

    24 février 2023, par VioGL

    Due to how phones are oriented if a phone takes a picture with portrait mode, the video seems to have an aspect ratio where height is greater than width, but the buffer inside it is rotated.

    &#xA;

    Here is what I'm trying to mean, originally, when displayed through "Videos" on debian 11 the video looks like this :

    &#xA;

    Source video

    &#xA;

    But when I normally use it with ffmpeg (I write the data I got from decoder to an opengl texture and display it) and view it on firefox it looks like this (Ignore the background being green it's intentional) :

    &#xA;

    Ffmpeg displayed video

    &#xA;

    As you can see even though the aspect ratios are the same (roughly 500x1000), for some reason ffmpeg and firefox displays the video like that.

    &#xA;

    I've deduced that there is a metadata called display matrix that show's me a rotation value. This rotation value is in fact there because the video is shot from an Iphone which does add a rotation data depending on how you are holding the phone while recording (in this case it's held vertically)

    &#xA;

    I can see the rotation metadata using this ffprobe command :

    &#xA;

    ffprobe phone_video.mp4&#xA;

    &#xA;

    Along the lines of the output I can see this :

    &#xA;

        Side data:&#xA;      displaymatrix: rotation of -90.00 degrees&#xA;

    &#xA;

    Which is exactly what I need. It is indeed rotated 90 degrees. However I can't access this inside my C/C++ code, here is what I've tried so far :

    &#xA;

    for (int j = 0; j &lt; av_frame->nb_side_data; j&#x2B;&#x2B;) &#xA;{&#xA;    AVFrameSideData *sd = av_frame->side_data[j];&#xA;&#xA;    if(sd->type == AV_FRAME_DATA_DISPLAYMATRIX) &#xA;    {&#xA;        float a =  av_display_rotation_get((int32_t *)sd->data);&#xA;        PRINT_INFO("=> displaymatrix: rotation of {} degrees",a );&#xA;    }&#xA;}&#xA;

    &#xA;

    This results in no output so far.

    &#xA;

    Also I've noticed that on firefox, the video is displayed as rotated but chrome manages to display the video correctly.

    &#xA;

    I have two questions :

    &#xA;

      &#xA;
    • How can I get the metadata information of the videos displaymatrix rotation with the C API ?
    • &#xA;

    • How can I flip the video to be displayed correctly, preferably inside the C API ?
    • &#xA;

    &#xA;

    Note that I want to change the data inside the buffer so the aspect ratio remains the same. So I want the bottom video to look like the top one.

    &#xA;

  • can't record docker selenium with ffmpeg and ubuntu 18

    1er janvier 2019, par Alex028502

    I have a script that starts a selenium/standalone-chrome container, starts recording with ffmpeg, and runs the selenium tests. However, it is not working with ubuntu 18, possibly because of the ffmpeg version (3.4.4 instead of 2.8.15).

    I have broken down the problem into a couple commands which work fine in ubuntu 16 but not ubuntu 18 :

    start selenium container in terminal #1

    docker run --network=host --shm-size=2g -e SCREEN_WIDTH=1920 -e SCREEN_HEIGHT=1080 selenium/standalone-chrome:3.141.59-antimony

    start recording in terminal #2

    rm -f test.mp4
    # :99 seems to be the default for the selenium container
    ffmpeg -f x11grab -video_size 1920x1080 -i :99 -codec:v libx264 -r 4 test.mp4

    and I get something that looks like this

    frame=    2 fps=0.1 q=-1.0 Lsize=       2kB time=00:00:00.25 bitrate=  75.9kbits/s dup=0 drop=413 speed=0.0165

    the time stays at 0, and then goes up to 25msec when I stop it.

    On the other hand, if I just start regular screen buffer in terminal #1

    Xvfb :99 -screen 0 1920x1080x24

    and run the same thing as above in terminal #2, everything works

    Also, I am pretty sure that the above ffmpeg command worked in ubuntu 16, with ffmpeg-3.

    So to summarise when the above ffmpeg command seems to work :

                      | ubuntu 16 (ffmpeg 3) | ubuntu 18 (ffmpeg 4)
    just start Xvfb    | works                | works
    selenium container | works                | DOES NOT WORK

    Any ideas ?