Newest 'ffmpeg' Questions - Stack Overflow

http://stackoverflow.com/questions/tagged/ffmpeg

Les articles publiés sur le site

  • 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(&avDecPkt);
    avDecPkt.data = inbuf_ptr;
    avDecPkt.size = esBufSize;
    
    len = avcodec_decode_video2(mpDecoderContext, mpFrameDec, &got_picture, &avDecPkt);
    if (len < 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 &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) < 0)
        {
            printf("Cannot open decoder context\n");
            exit(1);
        }
    
        mpDecodedFrame = av_frame_alloc();
    }
    
    bool
    VideoDecoder::rcvTsPacket(AVPacket &inTsPkt)
    {
        bool ret = true;
    
        if ((av_read_frame(mpFmtContext, &inTsPkt)) < 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, &got, &inTsPkt);
            if (len < 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(&tsPkt);
    
        VideoDecoder vDecoder;
    
        while (!feof(tsInFile))
        {
            tsPktNum++;
    
            tsPkt.size = 188;
            tsPkt.data = tsBuffer;
            fread(tsPkt.data, 188, 1, tsInFile);
    
            vDecoder.rcvTsPacket(tsPkt);
        }
    }
    
  • ffmpeg AVPixelFormat and manager C++ System::Drawing::Imaging::PixelFormat conflict

    29 novembre 2016, par H S T

    There is #define PixelFormat AVPixelFormat inffmpeg. You can not use System::Drawing::Imaging::PixelFormat in a header file containing this. How can I usePixelFormat in C #?

    .h

    using namespace System::Drawing::Imaging;
    public ref class CTest{
        static Imaging::PixelFormat Format24bppRGB = Imaging::PixelFormat::Format24bppRgb
    };
    

    .cpp

    #include"ffmpeg head file"
    ...
    
  • How to specify multiple inputs to ffmpeg amix filter

    29 novembre 2016, par user3847630

    I am working on mixing more audios with ffmpeg amix filter.I am able to achieve this using command line ,but I want to achieve the same with ffmpeg APIs.I have gone through the examples filtering_audio but it only takes one input . Can anyone tell me how to use multiple inputs for a filter? My purpose is to replace main audio with some other audio whenever there is data on second input.If there is no data on second input ,the filter should go on with one input.

  • FFMPEG : closing RTSP stream cleanly — av_read_frame crash on avformat_close_input

    29 novembre 2016, par braden

    I'm using KxMovie: https://github.com/kolyvan/kxmovie

    It appears to stop a stream and close the view controller one should use [pause]; However, I'm trying to receive a stream from a version of gstreamer that has a memory leak if a stream isn't closed properly (it's just left hanging).

    So, just [pause]ing isn't an option for me.

    I'm trying to use [closeFile] in the KxMovie decoder:

    -(void) closeFile
    {
    
    [self closeAudioStream];
    [self closeVideoStream];
    [self closeSubtitleStream];
    
    _videoStreams = nil;
    _audioStreams = nil;
    _subtitleStreams = nil;
    
         if (_formatCtx) {
             _formatCtx->interrupt_callback.opaque = NULL;
             _formatCtx->interrupt_callback.callback = NULL;
             avformat_close_input(&_formatCtx);
             _formatCtx = NULL;
         }
    }
    

    However, I usually get a EXC_BAD_ACCESS from av_read_frame after [closeFile] issues avformat_close_input.

    Can anyone give me some advice on how to cleanly shutdown an RTSP stream using ffmpeg?

    Thanks!

  • Executing bash shell command and extract output —> invalid file error

    29 novembre 2016, par Ingeborg

    I want to extract the framesize of a video from a file. For this purpose, I have launched an ffmpeg command via bash shell, and I want to extract the output. This command is working well in the bash shell, and returns the output as wanted.

    ffprobe -v error -count_frames -of flat=s=_ -select_streams v:0 -show_entries stream=nb_read_frames /home/peter/DA/videos/IMG-2014-1-10-10-4-37.avi
    

    I want to call it via C++ and read out the result. I use the IDE Qt 4.8.6 with GCC 4.8 compiler.

    For my code, I use this template:

    executing shell command with popen

    and changed it for my demands to

    #include 
    #include 
    #include 
    
    using namespace std;
    
    
    int main()
    {
       FILE* pipe = popen("echo $(ffprobe -v error -count_frames -of flat=s=_ -select_streams v:0 -show_entries stream=nb_read_frames /home/peter/DA/videos/IMG-2014-1-10-10-4-37.avi)", "r");
     if(!pipe)
     {
         cout << "error" << endl;
         return 1;
     }
     char* buffer = new char[512];
    
    string result;
    fgets(buffer, sizeof(buffer), pipe) ;
    while(!feof(pipe))
    {
        if(fgets(buffer, sizeof(buffer), pipe) != NULL)
        {
            cout << buffer << endl;
            result += buffer;
        }
    }
    pclose(pipe);
    cout << result<< endl;
    return 0;   
    }
    

    The Qt console returned me this warning, and it is rending with return 0:

    /home/peter/DA/videos/IMG-2014-1-10-10-4-37.avi: Invalid data found when processing input
    

    and "pipe" is empty.

    When I compile the main.cpp file above with g++ in the shell it works nice too.