I capture video frames from the camera via v4l, and I need to transcode them in mpeg4 format in order to transfer them sequentially via RTP.
Everything actually “works”, but something doesn’t happen there when re-encoding: the input stream creates 15 frames per second, and the output 25 frames per second, and each input frame is converted into one sequence of video objects (I checked this with using a simple check of the output bitstream). I assume the receiver correctly parses the mpeg4 bitstream, but RTP packetization is somehow wrong. How should I split an encoded bitstream in one or more AVPackets? Maybe I'm missing the obvious, and I just need to look for B / P frame markers, but I think I'm using the encoding API incorrectly.
Here is a snippet of my code based on available ffmpeg samples:
AVFrame *picture;
AVFrame *planar;
AVFormatContext *iFmtCtx;
AVCodecContext *oCtx;
oCtx->time_base.num = 1;
oCtx->time_base.den = 25;
oCtx->gop_size = 10;
oCtx->max_b_frames = 1;
oCtx->bit_rate = 384000;
oCtx->pix_fmt = PIX_FMT_YUV420P;
for(;;)
{
rdRes = av_read_frame( iFmtCtx, &pkt );
if ( rdRes >= 0 && pkt.size > 0 )
{
iCdcCtx->reordered_opaque = pkt.pts;
int decodeRes = avcodec_decode_video2( iCdcCtx, picture, &gotPicture, &pkt );
if ( decodeRes >= 0 && gotPicture )
{
avpicture_fill((AVPicture *)planar, planarBuf.get(), oCtx->pix_fmt, oCtx->width, oCtx->height);
sws_scale(sws, picture->data, picture->linesize, 0, iCdcCtx->height, planar->data, planar->linesize);
ByteArray encBuf( 65536 );
int encSize = avcodec_encode_video( oCtx, encBuf.get(), encBuf.size(), planar );
while( encSize == 0 )
encSize = avcodec_encode_video( oCtx, encBuf.get(), encBuf.size(), 0 );
if ( encSize > 0 )
enqueueFrame( oCtx->coded_frame->pts, encBuf.get(), encSize );
}
}
}