v4l 経由でカメラからビデオ フレームを取得しています。RTP 経由で連続してストリーミングするには、それらを mpeg4 形式でトランスコードする必要があります。
すべてが実際に「機能」しますが、再エンコード中にはできないことがあります。入力ストリームは 15 fps を生成し、出力は 25 fps であり、すべての入力フレームは 1 つのビデオ オブジェクト シーケンスに変換されます (簡単なチェックでこれを確認しました)。出力ビットストリームで)。受信者は mpeg4 ビットストリームを正しく解析していると思いますが、RTP パケット化は何らかの形で間違っています。エンコードされたビットストリームを 1 つ以上の AVPacket に分割するにはどうすればよいですか? たぶん、私は明らかなことを見逃していて、B/P フレーム マーカーを探すだけでよいのですが、エンコード API を正しく使用していないと思います。
これは、利用可能な ffmpeg サンプルに基づく私のコードの抜粋です。
// input frame
AVFrame *picture;
// input frame color-space converted
AVFrame *planar;
// input format context, video4linux2
AVFormatContext *iFmtCtx;
// output codec context, mpeg4
AVCodecContext *oCtx;
// [ init everything ]
// ...
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(;;)
{
// read frame
rdRes = av_read_frame( iFmtCtx, &pkt );
if ( rdRes >= 0 && pkt.size > 0 )
{
// decode it
iCdcCtx->reordered_opaque = pkt.pts;
int decodeRes = avcodec_decode_video2( iCdcCtx, picture, &gotPicture, &pkt );
if ( decodeRes >= 0 && gotPicture )
{
// scale / convert color space
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);
// encode
ByteArray encBuf( 65536 );
int encSize = avcodec_encode_video( oCtx, encBuf.get(), encBuf.size(), planar );
// this happens every GOP end
while( encSize == 0 )
encSize = avcodec_encode_video( oCtx, encBuf.get(), encBuf.size(), 0 );
// send the transcoded bitstream with the result PTS
if ( encSize > 0 )
enqueueFrame( oCtx->coded_frame->pts, encBuf.get(), encSize );
}
}
}