最初にマルチメディア ファイル (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;