I had a simular problem and I solved it by not putting the ffmpeg code in a class. I don't know weather this is a good or acceptable solution.

greetings fencer
Christoph John schrieb:
Hello,
I am trying to capture a live stream from a webcam. I have used the 
output_example.c code as an example. But when I call 
av_interleaved_write_frame() I always get an buffer underflow error. Has 
somebody an idea what I am doing wrong here?

The following methods I use for capture initialization and writing the frames. 
Thanks for your help

Christoph

/***************************************************************************/
bool FFMPEG_VideoWriter::initCapture(const QString &strFileName, float 
fFrameRate,
                                                                         const 
Vec2D<double> &v2dImageRes, bool bColor)
{
        QString strFile = strCapturePath + strFileName;
        // start from clean state
        deinitCapture();

        // create container format description
        m_pOutputFormat = guess_format(NULL, (const char*)strFile.toLatin1(), 
NULL);
if (!m_pOutputFormat) {
                cout<<"FFMPEG_VideoWriter: Could not deduce output format from file 
extension: using MPEG"<<endl;
        m_pOutputFormat = guess_format("mpeg", NULL, NULL);
                if (!m_pOutputFormat)
                        cout<<"FFMPEG_VideoWriter: Could not find mpeg output 
format"<<endl;
    }

        // FIXME codec choice
        m_pOutputFormat->video_codec = CODEC_ID_RAWVIDEO;

        // select appropriate pixel format
        if(bColor)
        m_iInputPixFormat = PIX_FMT_RGB32_1;
        else
                m_iInputPixFormat = PIX_FMT_GRAY8;

// allocate the output media context m_pFormatContext = av_alloc_format_context();
    if (!m_pFormatContext)
        {
                cout<<"FFMPEG_VideoWriter: Memory error"<<endl;
                return false;
        }
m_pFormatContext->oformat = m_pOutputFormat;
        _snprintf(m_pFormatContext->filename, sizeof(m_pFormatContext->filename), 
"%s", (const char*)strFile.toLatin1());

        ///////////////////// create stream and configure the codec context 
//////////////////////////
     m_pVideoStreamFFMPEG =  av_new_stream(m_pFormatContext, 0);
         if(!m_pVideoStreamFFMPEG)
         {
                 cout<<"FFMPEG_VideoWriter: Could not alloc video stream"<<endl;
         }
        AVCodecContext* pCodecContext = m_pVideoStreamFFMPEG->codec;
        pCodecContext->codec_id = m_pOutputFormat->video_codec;
        pCodecContext->codec_type = CODEC_TYPE_VIDEO;
        
        pCodecContext->bit_rate = v2dImageRes.m_x * v2dImageRes.m_y * 4 * 
fFrameRate * 8;
        pCodecContext->width = (int)v2dImageRes.m_x;
        pCodecContext->height = (int)v2dImageRes.m_y;

        pCodecContext->time_base.num = 1;
        pCodecContext->time_base.den = fFrameRate;
pCodecContext->pix_fmt = (PixelFormat)m_iInputPixFormat;
        
        // some formats want stream headers to be separate
    if(m_pFormatContext->oformat->flags & AVFMT_GLOBALHEADER)
        pCodecContext->flags |= CODEC_FLAG_GLOBAL_HEADER;

        //init output params
        av_set_parameters(m_pFormatContext,NULL);

        //dump_format(m_pFormatContext,0,(const char*)strFile.toLatin1(),1);

        /////////////////////// open video file 
/////////////////////////////////////////
    // find encoder
    AVCodec *pCodec = avcodec_find_encoder(pCodecContext->codec_id);
    if (!pCodec)
        {
                cout<<"FFMPEG_VideoWriter: Codec not found"<<endl;
        return false;
    }

    // open the codec
if (avcodec_open(pCodecContext, pCodec) < 0) {
                cout<<"FFMPEG_VideoWriter: Could not open codec"<<endl;
        return false;
    }

        // create data structure for source picture
    m_pInputPicture = allocPicture(pCodecContext->pix_fmt, pCodecContext->width, 
pCodecContext->height, false);
    if (!m_pInputPicture)
        {
                return false;
                cout<<"FFMPEG_VideoWriter: Could not allocate picture"<<endl;
        }
        // create memory for compressed image, assume 32 bit pixel maximum
        m_uiCompressedImageBufSize = v2dImageRes.m_x*v2dImageRes.m_y*4;
        m_pCompressedImageBuf = (uint8_t *) 
av_malloc(m_uiCompressedImageBufSize);

        // open the output file
        if(url_fopen(&m_pFormatContext->pb, m_pFormatContext->filename, 
URL_WRONLY) < 0)
        {
                cout<<"FFMPEG_VideoWriter: Could not open file"<<endl;
                return false;
        }

        // write stream header
        av_write_header(m_pFormatContext);

        return true;
}

/***************************************************************************/
bool FFMPEG_VideoWriter::writeImage(vil_image_resource_sptr pImg)
{
        if(m_pFormatContext)
        {
                AVCodecContext* pCodecContext = m_pVideoStreamFFMPEG->codec;
                // set rgba input image
if(pCodecContext->pix_fmt == PIX_FMT_RGB32_1 && pImg->nplanes() == 4 && pCodecContext->width == pImg->ni() &&
                        pCodecContext->height == pImg->nj())
                {
                        avpicture_fill((AVPicture*)m_pInputPicture,
                                           
(uint8_t*)((vil_image_view<vxl_byte>)pImg->get_view()).top_left_ptr(),
                                                   PIX_FMT_RGB32_1,
                                                   pImg->ni(), pImg->nj());

                }
                // set monochrome input image
                else if(pCodecContext->pix_fmt == PIX_FMT_GRAY8 && pImg->nplanes() == 1 
&&
                            pCodecContext->width == pImg->ni() &&
                            pCodecContext->height == pImg->nj())
                {
                        avpicture_fill((AVPicture*)m_pInputPicture,
                                           
(uint8_t*)((vil_image_view<vxl_byte>)pImg->get_view()).top_left_ptr(),
                                                   PIX_FMT_GRAY8,
                                                   pImg->ni(), pImg->nj());
                }
                else
                        return false;

                // compress image
                int iOutSize = avcodec_encode_video(pCodecContext, 
m_pCompressedImageBuf,
                                                                                
        m_uiCompressedImageBufSize, m_pInputPicture);
                // serialize data
                if(iOutSize > 0)
                {
                        // create data package
            AVPacket pkt;
            av_init_packet(&pkt);

            if (pCodecContext->coded_frame->pts != AV_NOPTS_VALUE)
pkt.pts= av_rescale_q(pCodecContext->coded_frame->pts, pCodecContext->time_base, m_pVideoStreamFFMPEG->time_base);

            if(pCodecContext->coded_frame->key_frame)
                pkt.flags |= PKT_FLAG_KEY;
pkt.stream_index= m_pVideoStreamFFMPEG->index;
            pkt.data= m_pCompressedImageBuf;
            pkt.size= iOutSize;

            // write the package into file
            av_interleaved_write_frame(m_pFormatContext, &pkt);
                }
        }// end format context

        return true;
}



_______________________________________________
libav-user mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/libav-user

Reply via email to