[Libav-user] avio_alloc_context custom I/O read_packet issue

John Locke scdmusic at gmail.com
Wed Mar 6 21:42:54 CET 2013


I am trying to set up a custom I/O read callback to read from a std::list
of frames I transmitted via TCP.  In each std::list<item> contains a frame
buffer that was written using a custom I/O write_packet, with an associated
frame size and some other information about each frame that I need.  I have
verified I am getting all of the information by writing out my frame
buffers to disk and opening them up in mplayer or vlc.  The below appears
to work, but after
avformat_open_input(&m_FormatCtx,"fake.h264",NULL,NULL);  None of the
necessary AVContextCodec information appears to be there.  It does find the
codec based on the fake filename, fake.h264, but does not read anything in
from my header, like height or width... Which makes me think it's just
reading the fake filename to determine codec info and not reading in my I/O
buffer...

In my Read_Packet callback I write out the first 32K (all that is read when
avformat_open_input is called) and write that out to disk.  mplayer cannot
play anything (obviously, it's only 32K), but it is able to parse the
header and get height and width:

VIDEO:  [H264]  696x556  0bpp  25.000 fps    0.0 kbps ( 0.0 kbyte/s)

I know the buffer has the correct information in it!

It should be known that the frame size is larger than 32K, so I manage the
position in the buffer with my opaque pointer.  Once finished with the
frame, I pop it off.

static int Read_Packet(void *opaque, uint8_t *buf, int size)
{
    FrameList *l = (FrameList *)opaque;

    if(l->empty())
        return 0;

    Frame_ptr p = l->front();
    int ret;

    if(p->H264_frameSize - p->H264_framePos < size)
    {
        memcpy(buf,p->H264_frameData + p->H264_framePos,p->H264_frameSize -
p->H264_framePos);
        l->pop_front();
        ret=p->H264_frameSize - p->H264_framePos;
    }else
    {
        memcpy(buf,p->H264_frameData + p->H264_framePos,size);
        p->H264_framePos+=size;
        ret=size;
    }

    fwrite(buf, ret, 1, fo); //for debugging... Save out 32K, in which
mplayer can read the header

    return ret;
}

int main()
..... snip
    AVIOContext *avioctx;
    m_BufferCallBack= (unsigned char*)av_malloc(BUFFERSIZE *
sizeof(uint8_t));
    avioctx = avio_alloc_context( m_BufferCallBack, //IOBuffer
                                  BUFFERSIZE,       //Buffer Size
                                  0,                //Write flag, only
reading, so 0
                                  m_H264FrameList,  //H264 Frame pointer
(opaque)
                                  Read_Packet,      //Read callback
                                  NULL,             //Write callback
                                  NULL);            //file_seek... not
using buffer again so 0 is ok


    m_FormatCtx->pb=avioctx;

    int ret = avformat_open_input(&m_FormatCtx,"fake.h264",NULL,NULL);
    if (ret < 0)
        printf("Cannot open buffer in libavformat\n");

    videoStream=-1;
    videoStream =
av_find_best_stream(m_FormatCtx,AVMEDIA_TYPE_VIDEO,-1,-1,&m_avCodec,0);

    // Get a pointer to the codec context for the video stream
    m_CodecCtx=m_FormatCtx->streams[videoStream]->codec;

    m_avCodec=avcodec_find_decoder(m_CodecCtx->codec_id);
    if(m_avCodec==NULL)
        return false; // Codec not found

    // Open codec
    if(avcodec_open2(m_CodecCtx, m_avCodec,NULL)<0)
        return false; // Could not open codec

    // Allocate video frame
    m_avFrame=avcodec_alloc_frame();

    // Allocate an AVFrame structure
    m_avFrameRGB=avcodec_alloc_frame();
    if(m_avFrameRGB==NULL)
        return false;

    av_log(NULL, AV_LOG_INFO, "Width %i | Height %i
\n",m_CodecCtx->width,m_CodecCtx->height);

    // Determine required buffer size and allocate buffer
    //m_numBytes=avpicture_get_size(PIX_FMT_RGB24,
m_CodecCtx->width,m_CodecCtx->height);
    m_numBytes=avpicture_get_size(PIX_FMT_YUYV422,
m_CodecCtx->width,m_CodecCtx->height);
    m_buffer=new uint8_t[m_numBytes];

    // Assign appropriate parts of buffer to image planes in m_avFrameRGB
    avpicture_fill((AVPicture *)m_avFrameRGB, m_buffer, PIX_FMT_YUYV422,
                   m_CodecCtx->width, m_CodecCtx->height);
..... snip
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20130306/9fea1c12/attachment.html>


More information about the Libav-user mailing list