[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