3

最初にマルチメディア ファイル (test.mp4 ファイル、ビデオ コーデック ID は H264 など) をデコードし、ビデオ ストリームとオーディオ ストリームを取得し、次にオーディオ ストリームをいくつか変更し、最後にエンコードするアプリケーションを実現したいと考えています。ビデオ ストリーム (libx264 を使用) とオーディオ ストリームを結果ファイル (result.mp4) に変換します。効率を高めるために、ビデオ ストリームのデコードとエンコードを省略し、関数「av_read_frame」でビデオ パケットを取得し、関数「av_write_frame」で結果ファイルに直接出力しました。ただし、出力ファイルには画像がなく、出力ファイルのサイズはかなり小さいです。

ffmpeg コードを追跡したところ、関数 "av_write_frame->mov_write_packet->ff_mov_write_packet" で、関数 "ff_avc_parse_nal_units" を呼び出して nal ユニットのサイズを取得することがわかりましたが、戻り値は非常に小さい (208 バイトなど)。

MP4 ファイルの H264 ストリームが Annex-B 形式で保存されていないため、開始コード (0x000001) が見つかりません。H264 ストリームを Annex-B 形式に変更して、すべてのフレームの先頭に手動で開始コードを追加しましたが、まだ機能しません。

誰でもヒントを教えてもらえますか? どうもありがとう。以下は、私のものと同様のコードです:

    // write the stream header, if any
    av_write_header(pFormatCtxEnc);

    .........
    /**
    * Init of Encoder and Decoder
    */

    bool KeyFlag = false;
    bool KeyFlagEx = false;
    // Read frames and save frames to disk
    int iPts = 1;
    av_init_packet(&packet);
    while(av_read_frame(pFormatCtxDec, &packet)>=0)
    {
            if (packet.flags == 1)
                    KeyFlag = true;

            if (!KeyFlag)
                    continue;

            if (m_bStop)
            {
                    break;
            }

            // Is this a packet from the video stream?
            if(packet.stream_index == videoStream)
            {
                    currentframeNum ++;
                    if (progressCB != NULL && currentframeNum%20 == 0)
                    {
                            float fpercent = (float)currentframeNum/frameNum;
                            progressCB(fpercent,m_pUser);
                    }

                    if (currentframeNum >= beginFrame && currentframeNum <= endFrane)
                    {
                            if (packet.flags == 1)
                                    KeyFlagEx = true;

                            if (!KeyFlagEx)
                                    continue;
                            packet.dts = iPts ++;
                            av_write_frame(pFormatCtxEnc, &packet);

                    }
            }
            // Free the packet that was allocated by av_read_frame
    }

    // write the trailer, if any
    av_write_trailer(pFormatCtxEnc);

    /**
    * Release of encoder and decoder
    */

    return true;
4

1 に答える 1

0

libavcodec/h264_mp4toannexb_bsf.cを試してみてください。スタート コードのないビットストリームをスタート コードのあるビットストリームに変換します。

ソースファイルを使用してffmpeg -i src.mp4 -vcodec copy -an dst.mp4動作しますか? を追加すると機能します-bsf h264_mp4toannexbか?(もちろん、プログラムで使用しようとしているのと同じバージョン/ビルドのffmpegを使用しています)

于 2013-01-06T04:05:56.283 に答える