ffmpeg はフレーム損失の問題を解決します。デコーダにはまだ数フレームのデータがキャッシュされているため、取り出す必要があります。

序文
       

最近、ffmpeg を使ってビデオを解析する方法を学んでいます。インターネットでの検索方法は似ています。デコード関数 avcodec_send_packet と avcodec_receive_frame について直接話します。これら 2 つは一緒であり、同時に出現する必要があります。ビデオ ファイルを読み込みます。抽出されたパケットを videoQueue または audioQueue に配置し、SDL を使用して videoThread を作成し、ビデオ キューから継続的にパケットを取り出してデコーダに送信します。つまり、avcodec_send_packet を使用してパケットをデコーダに送信します。デコーダを起動し、avcodec_receive_frame を使用して ffmpeg からフレームを解析します。それを取り出しますが、プログレス バーで現在のフレームの時間を確認するか、デコードされた Frame->pts を直接出力します。最後には常に数フレーム少なくなります。 、とても憂鬱です

1. フレーム損失の原因
デコーダ内部にはキャッシュキューがあり、最初に数フレームのデータを保存し、その後有効なフレームの出力を開始するため、最終的には数フレームのデータが残ります。ビデオのサイズによってはデコーダ内にフレームが残っているため、パケット数が一定ではないため、最後に出力されないフレームが残り、フレームロスが発生します。

2. 解決策
最初のアイデアは、フレーム損失を解決する方法をインターネットで検索することですが、数が少なく、ソース コードもありません。特に ffmpeg の avcodec_send_packet と avcodec_receive_frame のフレーム損失解決策は少ないため、公式ドキュメントがついに見つかりました。ちょっとした手掛かりとして、次の図が avcode.h にあります。これは、これら 2 つの関数によって宣言されたヘッダー ファイルでもあります。

上記は、必要に応じて、またはパフォーマンスを向上させるために、コーデックが最後に数フレームのデータをキャッシュする場合があり、コーデックを更新する必要があることを示しています。また、アイデアも提供します。

1. 空のパケットを avcodec_send_packet に送信します。
上記の公式ドキュメントで提供されているアイデアに従って、空のパケットをデコーダーに送信する必要があります。コードは次のとおりです。

packet->data = nullptr;
packet->size = 0;
avcodec_send_packet(pVideoCodecCtx, packet);


2. avcodec_receive_frame を呼び出して
空のパケットを送信した後、avcodec_receive_frame が AVERROR_EOF を返すまで、avcodec_receive_frame を呼び出してデコードされたフレームを取り出します。

/**队列里取数据**/
        if (packet_queue_get(&pVideosState->videoQueue, packet, 0) <= 0)
        {
 
            if (pVideosState->readFinished)
            {
                /**队列里面没有数据了且读取完毕了**/
                while(1)
                {
                    packet->data = nullptr;
                    packet->size = 0;
                    avcodec_send_packet(pVideoCodecCtx, packet);
                    
                    ret = avcodec_receive_frame(pVideoCodecCtx, pFrame);
                    if(ret == AVERROR_EOF)
                        break;
                    
                    //进行你所需的一系列操作
                }
                //这个循环跳出后就全部取出解码器缓存的数据了
            }

おすすめ

転載: blog.csdn.net/xionglifei2014/article/details/124951833