[Libav-user] A very mysterious question about FFMpeg encoding.

Denis info at denisgottardello.it
Sat Sep 24 22:14:33 CEST 2011


> 
> You need to show the source of your data. How do you get the frames from a
> webcam, does it come in packets? RGB data? that's the code you should show.
> The problem that I'm seeing is that you're using an avio context when you
> don't actually intend to write data with it to a file. Just take the webcam
> frame data call avcodec_encode_video and that function writes it to a
> buffer. I'm not sure why you're making the all these avio calls. I suggest
> you also look at the headers for avcodec_encode_video.


Well, now I am sending my function. I have made a small step forward.
I remember that this function produces h264, theora and vp8 videos correctly.
The small step forward is about the use of "avio_open_dyn_buf, avio_close_dyn_buf" functions. Now I can read the buffer at the end of the encoding correctly. I can put the buffer in a file and 
the file is played correctly. The problem is that I can read the buffer only at the end of the encoding!
The question is: how can I read the buffer (and empy it) during the encoding?





void QThCamera::run() {
    qDebug() << "QThCamera::run() start";
    QString MPGFileName= "a.mp4";

    CvCapture *Capture= NULL;
    Capture= cvCreateCameraCapture(Index, Width, Height);
    if (!Capture) qDebug() << "cvCreateCameraCapture Error!";
    else {
        if (ExternalFrame) cvNamedWindow("Frame", CV_WINDOW_AUTOSIZE);
        IplImage *frame= 0;
        CvFont font;
        cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.5f, 0.5f);

        AVOutputFormat *pOutputFormat= av_guess_format("mp4", NULL, NULL); // CODEC_ID_H264 -> mp4, rawvideo; CODEC_ID_THEORA -> ogg; CODEC_ID_MPEG4 -> mpegts, rawvideo; 
CODEC_ID_VP8 -> webm
        if (!pOutputFormat) {
            qDebug() << "Could not set output format, using MPEG.";
            pOutputFormat= av_guess_format("mpeg", NULL, NULL);
        }
        if (!pOutputFormat) qDebug() << "av_guess_format Error!";
        else {
            AVFormatContext *pFormatCtx;
            if (avformat_alloc_output_context2(&pFormatCtx, pOutputFormat, NULL, NULL)< 0) qDebug() << "avformat_alloc_output_context2 Error!";
            else {
                AVStream *pVideoStream= av_new_stream(pFormatCtx, 0);
                if (!pVideoStream) qDebug() << "av_new_stream Error!";
                else {
                    AVCodecContext *pCodecCtx= pVideoStream->codec;
                    pCodecCtx->codec_id= CODEC_ID_H264;
                    pCodecCtx->codec_type= AVMEDIA_TYPE_VIDEO;
                    pCodecCtx->bit_rate= 40000;
                    pCodecCtx->width= Width;
                    pCodecCtx->height= Height;
                    pCodecCtx->time_base.den= 25;
                    pCodecCtx->time_base.num= 1;
                    pCodecCtx->gop_size= 10;
                    pCodecCtx->pix_fmt= PIX_FMT_YUV420P;
                    if (pFormatCtx->oformat->flags & AVFMT_GLOBALHEADER) pCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
                    av_dump_format(pFormatCtx, 0, NULL, 1);
                    AVCodec *pCodec= avcodec_find_encoder(pCodecCtx->codec_id);
                    if (!pCodec) qDebug() << "avcodec_find_encoder Error!";
                    else {
                        if (avcodec_open(pCodecCtx, pCodec)< 0) qDebug() << "avcodec_open Error!";
                        else {
                            QFile QFMPGFileOut;
                            QFMPGFileOut.setFileName(MPGFileName);
                            if (QFMPGFileOut.open(QIODevice::WriteOnly)) {

                                if (avio_open_dyn_buf(&pFormatCtx->pb)< 0) qDebug() << "avio_open Error!";
                                else {
                                    if (avformat_write_header(pFormatCtx, NULL)!= 0) qDebug() << "av_write_header Error!";

                                    int BYTEPIC= Width * Height * 3;
                                    uint8_t *pOutBuffer= (uint8_t*)malloc(BYTEPIC); {
                                        int Frames= 0;
                                        QDateTime QDTStart= QDateTime::currentDateTime();
                                        while (DoStart) {
                                            if (!cvSetChannel(Capture, Channel)) qDebug() << "cvSetChannel Error!";
                                            frame= cvQueryFrame(Capture);
                                            if (frame) {


                                                AVFrame *pAVFrame= avcodec_alloc_frame();
                                                uint8_t *pBuffer= (uint8_t*)malloc(avpicture_get_size(PIX_FMT_YUV420P, Width, Height)); {
                                                    avpicture_fill((AVPicture*)pAVFrame, pBuffer, PIX_FMT_YUV420P, Width, Height);
                                                    IplImageToAVFrame(frame, pAVFrame, Width, Height, PIX_FMT_YUV420P);
                                                    pAVFrame->pts= Frames;
                                                    int OutSize= avcodec_encode_video(pCodecCtx, pOutBuffer, BYTEPIC, pAVFrame);
                                                    if (OutSize> 0) {
                                                        AVPacket Packet;
                                                        av_init_packet(&Packet);
                                                        //Packet.pts= Frames;
                                                        if (pCodecCtx->coded_frame->pts != AV_NOPTS_VALUE) {
                                                            Packet.pts= av_rescale_q(pCodecCtx->coded_frame->pts, pCodecCtx->time_base, pVideoStream->time_base);
                                                        }
                                                        if (pCodecCtx->coded_frame->key_frame) Packet.flags |= AV_PKT_FLAG_KEY;
                                                        Packet.stream_index= pVideoStream->index;
                                                        Packet.data= pOutBuffer;
                                                        Packet.size= OutSize;
                                                        if (av_interleaved_write_frame(pFormatCtx, &Packet)!= 0) qDebug() << "av_interleaved_write_frame Error!";


                                                    }
                                                    Frames++;
                                                    if (Frames> pCodecCtx->time_base.den / pCodecCtx->time_base.num * 10) break;
                                                }{
                                                    av_free(pAVFrame);
                                                    free(pBuffer);
                                                }




                                            } else qDebug() << "QThCamera::run() frame= false";
                                        }
                                        qDebug() << Frames / QDTStart.secsTo(QDateTime::currentDateTime());
                                    }{
                                        free(pOutBuffer);
                                    }
                                    if (av_write_trailer(pFormatCtx)!= 0) qDebug() << "av_write_trailer Error!"; // Crash with H264!!!
                                    uint8_t *pDynBuffer; {
                                        int pDynBufferLen= avio_close_dyn_buf(pFormatCtx->pb, &pDynBuffer);
                                        QByteArray QBAByteIn((const char*)pDynBuffer, pDynBufferLen);
                                        QFMPGFileOut.write(QBAByteIn);
                                    }{
                                        av_free(pDynBuffer);
                                    }
                                }
                                QFMPGFileOut.close();
                            } else qDebug() << "QFMPGFileOut.open() Error!";
                            avcodec_close(pVideoStream->codec);
                        }
                    }
                    for (int count= 0; (unsigned)count< pFormatCtx->nb_streams; count++) {
                        av_freep(&pFormatCtx->streams[count]->codec);
                        av_freep(&pFormatCtx->streams[count]);
                    }
                }
                av_free(pFormatCtx);
            }
        }
        cvReleaseCapture(&Capture);
        if (ExternalFrame) cvDestroyWindow("Frame");
    }
    qDebug() << "QThCamera::run() stop";
}


-- 
www.denisgottardello.it
Skype: mrdebug
Videosurveillance and home automation! 
http://www.denisgottardello.it/DomusBoss/DomusBossIndice.php
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20110924/3fe9f2ee/attachment.html>


More information about the Libav-user mailing list