Recherche avancée

Médias (10)

Mot : - Tags -/wav

Sur d’autres sites (2172)

  • How to extract key-frames closest to given frame numbers from H264 video with ffmpeg

    16 décembre 2016, par John Allard

    I know how to extract a set of frames as jpg files from a video using ffmpeg if you know the frame numbers (given below)

    Extracting Frames: [40, 59, 73, 110]
    /usr/bin/ffmpeg -y -hide_banner -nostats -loglevel error -i /home/pi/movie.mp4 -vf select='eq(n\,40)+eq(n\,59)+eq(n\,73)+eq(n\,110)',scale=640:-1 -vsync 0 /tmp/%04d.jpg

    That will extract frames [40, 59, 73, 110] as files /tmp/0000.jpg, /tmp/0001.jpg, etc.

    I also know how to extract all key frames for a given time interval :

    ffmpeg -ss  -i video.mp4 -t <duration> -q:v 2 -vf select="eq(pict_type\,PICT_TYPE_I)" -vsync 0 frame%03d.jpg
    </duration>

    That will get all I-frames from start_time through start_time+duration.

    But what I would like to do is give a list of frame numbers and have ffmpeg extract the closest key-frames to each frame-number. Is there a way to do this with ffmpeg or would I have to write my own program ontop of libavcodec to do this ?

  • What to pass to avcodec_decode_video2 for H.264 Transport Stream ?

    29 novembre 2016, par Danny

    I want to decode H.264 video from a collection of MPEG-2 Transport Stream packets but I am not clear what to pass to avcodec_decode_video2

    The documentation says to pass "the input AVPacket containing the input buffer."

    But what should be in the input buffer ?

    A PES packet will be spread across the payload portion of several TS packets, with NALU(s) inside the PES. So pass a TS fragment ? The entire PES ? PES payload only ?

    This Sample Code mentions :

    BUT some other codecs (msmpeg4, mpeg4) are inherently frame based, so
    you must call them with all the data for one frame exactly. You must
    also initialize ’width’ and ’height’ before initializing them.

    But I can find no info on what "all the data" means...

    Passing a fragment of a TS packet payload is not working :

    AVPacket avDecPkt;
    av_init_packet(&amp;avDecPkt);
    avDecPkt.data = inbuf_ptr;
    avDecPkt.size = esBufSize;

    len = avcodec_decode_video2(mpDecoderContext, mpFrameDec, &amp;got_picture, &amp;avDecPkt);
    if (len &lt; 0)
    {
       printf("  TS PKT #%.0f. Error decoding frame #%04d [rc=%d '%s']\n",
           tsPacket.pktNum, mDecodedFrameNum, len, av_make_error_string(errMsg, 128, len));
       return;
    }

    output

    [h264 @ 0x81cd2a0] no frame!
    TS PKT #2973. Error decoding frame #0001 [rc=-1094995529 'Invalid data found when processing input']

    EDIT

    Using the excellent hits from WLGfx, I made this simple program to try decoding TS packets. As input, I prepared a file containing only TS packets from the Video PID.

    It feels close but I don’t know how to set up the FormatContext. The code below segfaults at av_read_frame() (and internally at ret = s->iformat->read_packet(s, pkt)). s->iformat is zero.

    Suggestions ?

    EDIT II - Sorry, for got post source code **
    **EDIT III - Sample code updated to simulate reading TS PKT Queue

    /*
    * Test program for video decoder
    */

    #include
    #include
    #include
    #include

    extern "C" {

    #ifdef __cplusplus
       #define __STDC_CONSTANT_MACROS
       #ifdef _STDINT_H
           #undef _STDINT_H
       #endif
       #include
    #endif
    }

    extern "C" {
    #include "libavcodec/avcodec.h"
    #include "libavformat/avformat.h"
    #include "libswscale/swscale.h"
    #include "libavutil/imgutils.h"
    #include "libavutil/opt.h"
    }


    class VideoDecoder
    {
    public:
       VideoDecoder();
       bool rcvTsPacket(AVPacket &amp;inTsPacket);

    private:
       AVCodec         *mpDecoder;
       AVCodecContext  *mpDecoderContext;
       AVFrame         *mpDecodedFrame;
       AVFormatContext *mpFmtContext;

    };

    VideoDecoder::VideoDecoder()
    {
       av_register_all();

       // FORMAT CONTEXT SETUP
       mpFmtContext = avformat_alloc_context();
       mpFmtContext->flags = AVFMT_NOFILE;
       // ????? WHAT ELSE ???? //

       // DECODER SETUP
       mpDecoder = avcodec_find_decoder(AV_CODEC_ID_H264);
       if (!mpDecoder)
       {
           printf("Could not load decoder\n");
           exit(11);
       }

       mpDecoderContext = avcodec_alloc_context3(NULL);
       if (avcodec_open2(mpDecoderContext, mpDecoder, NULL) &lt; 0)
       {
           printf("Cannot open decoder context\n");
           exit(1);
       }

       mpDecodedFrame = av_frame_alloc();
    }

    bool
    VideoDecoder::rcvTsPacket(AVPacket &amp;inTsPkt)
    {
       bool ret = true;

       if ((av_read_frame(mpFmtContext, &amp;inTsPkt)) &lt; 0)
       {
           printf("Error in av_read_frame()\n");
           ret = false;
       }
       else
       {
           // success.  Decode the TS packet
           int got;
           int len = avcodec_decode_video2(mpDecoderContext, mpDecodedFrame, &amp;got, &amp;inTsPkt);
           if (len &lt; 0)
               ret = false;

           if (got)
               printf("GOT A DECODED FRAME\n");
       }

       return ret;
    }

    int
    main(int argc, char **argv)
    {
       if (argc != 2)
       {
           printf("Usage: %s tsInFile\n", argv[0]);
           exit(1);
       }

       FILE *tsInFile = fopen(argv[1], "r");
       if (!tsInFile)
       {
           perror("Could not open TS input file");
           exit(2);
       }

       unsigned int tsPktNum = 0;
       uint8_t      tsBuffer[256];
       AVPacket     tsPkt;
       av_init_packet(&amp;tsPkt);

       VideoDecoder vDecoder;

       while (!feof(tsInFile))
       {
           tsPktNum++;

           tsPkt.size = 188;
           tsPkt.data = tsBuffer;
           fread(tsPkt.data, 188, 1, tsInFile);

           vDecoder.rcvTsPacket(tsPkt);
       }
    }
  • How to preserve transparency when using png to make video with ffmpeg

    27 septembre 2016, par Ryan James

    I have a series of png’s that have an alpha channel as a background. Each file is named like file_name.0001.png and so on, in subsequent order. I’d like to join these png’s into a video with ffmpeg and maintain the transparency.

    I’ve tried a couple of things but I suspect I’m running into a codec issue. When I run ffmpeg, the video is created but the background is black.

    If it makes a difference, I’m wanting to use the video in Microsoft Powerpoint. Thanks !

    Edit
    The suggested duplicate is very close to what I was looking for, thank you ! The only reason it’s not a complete solution is none of the options presented in the other thread work well with Microsoft Powerpoint. None of the codecs used in the suggested solution play well with Powerpoint. This is not the fault of ffmpeg, but of Powerpoint.

    Though ffmpeg doesn’t seem to be able to do what I need, I found that imagemagick did the trick. I was able to create a gif from the images and the alpha channel was preserved. I used the following :

    convert -dispose 3 -coalesce images.*.png gif_file_name.gif

    The -dispose 3 is critical as it tells imagemagick to clear the image prior to overlay, otherwise, you can see each image overlaid on each other (since they have the transparent background).