次の問題について助けていただければ幸いです。
H264 圧縮ビデオ フレームを生成するカメラ付きのガジェットがあり、これらのフレームはアプリケーションに送信されています。これらのフレームはコンテナーではなく、生データのみです。
ffmpeg 関数と libav 関数を使用して、後で使用できるビデオ ファイルを作成したいと考えています。
フレームをデコードしてからエンコードすると、すべて正常に動作し、有効なビデオ ファイルが得られます。(デコード/エンコードの手順は通常のlibavコマンドです。ここでは特別なことは何もありません。万能のインターネットから取得しました。それらは堅実です)...ただし、デコードとエンコードで多くの時間を無駄にしているので、この手順をスキップして、フレームを出力ストリームに直接配置します。さて、問題が発生します。
エンコーディングを生成するために思いついたコードは次のとおりです。
AVFrame* picture;
avpicture_fill((AVPicture*) picture, (uint8_t*)frameData,
codecContext->pix_fmt, codecContext->width,
codecContext->height);
int outSize = avcodec_encode_video(codecContext, videoOutBuf,
sizeof(videoOutBuf), picture);
if (outSize > 0)
{
AVPacket packet;
av_init_packet(&packet);
packet.pts = av_rescale_q(codecContext->coded_frame->pts,
codecContext->time_base, videoStream->time_base);
if (codecContext->coded_frame->key_frame)
{
packet.flags |= PKT_FLAG_KEY;
}
packet.stream_index = videoStream->index;
packet.data = videoOutBuf;
packet.size = outSize;
av_interleaved_write_frame(context, &packet);
put_flush_packet(context->pb);
}
変数は次のようになります。
frameData
カメラから送信されたデコード済みフレーム データで、前のステップでデコードされvideoOutBuf
、データを保持するためのプレーンな uint8_t バッファーです。
フレームをデコードせずに、次のようなデータを単純に通過させるようにアプリケーションを変更しました。
AVPacket packet;
av_init_packet(&packet);
packet.stream_index = videoStream->index;
packet.data = (uint8_t*)frameData;
packet.size = currentFrameSize;
av_interleaved_write_frame(context, &packet);
put_flush_packet(context->pb);
どこ
frameData
は生の H264 フレームで、生の H264 フレームcurrentFrameSize
のサイズです。フレームごとにガジェットから取得するバイト数。
そして突然、アプリケーションが正しく動作しなくなり、生成されたビデオが再生できなくなります。パケットに正しい PTS を設定していなかったので、これは明らかです。私がしたことは次のとおりです(私は必死です、このアプローチからそれを見ることができます:))
packet.pts = timestamps[timestamp_counter ++];
ここtimestamps
で実際には、上記の作業コードによって生成され、ファイルに書き込まれた PTS のリストです (はい、正しく読んでください。10 分間のセッションですべての PTS をログに記録し、それらを使用したかったのです)。
アプリケーションはまだ機能しません。
さて、ここで私は何をすべきか見当もつかないので、ここに質問があります:
libav 関数を使用して「mpegts」ビデオ ストリームを作成し、既にエンコードされたビデオ フレームをストリームに挿入し、それを使用してビデオ ファイルを作成したいと考えています。どうすればいいのですか?
ありがとう。