[英]How can i mux H264 stream into MP4 file via libavformat
I want to realize an application that firstly decode a multi-media file(such as test.mp4 file, video codec id is H264), get a video stream and an audio stream, then make some different in the audio stream, at last encode the video stream(use libx264) and audio stream into a result file(result.mp4).我想实现一个应用程序,首先解码一个多媒体文件(例如test.mp4文件,视频编解码器id是H264),得到一个视频流和一个音频流,然后在音频流中做一些不同,最后编码视频流(使用 libx264)和音频流到结果文件(result.mp4)。 To promote the efficiency, i omitted the decode and encode of video stream, i get the video packet via function "av_read_frame", then output it directly into the result file via function "av_write_frame".
为了提高效率,我省略了视频流的解码和编码,我通过函数“av_read_frame”得到视频包,然后通过函数“av_write_frame”直接输出到结果文件中。 But there is no picture in the output file, and the size of output file is fairly small.
但是输出文件中没有图片,输出文件的大小相当小。
I tracked the ffmpeg code and found that in the function "av_write_frame->mov_write_packet->ff_mov_write_packet", it will call function "ff_avc_parse_nal_units" to obtain the size of nal unit, but the return value is very small(such as 208 bytes).我跟踪了ffmpeg的代码,发现在函数“av_write_frame->mov_write_packet->ff_mov_write_packet”中,会调用函数“ff_avc_parse_nal_units”来获取nal单元的大小,但是返回值很小(比如208字节)。
I find that the H264 stream in the MP4 file is not stored in Annex-B format, so it can't find start code(0x000001), now my problem is how can I change the H264 stream to Annex-B format, and make it work? I added start code at the beginning of every frame manually, but it still not work.我发现MP4文件中的H264码流没有以Annex-B格式存储,所以找不到起始码(0x000001),现在我的问题是如何将H264码流改成Annex-B格式,并制作行得通吗?我在每一帧的开头手动添加了启动代码,但它仍然无法正常工作。
Anyone can give me any hint?Thanks very much.任何人都可以给我任何提示吗?非常感谢。 Following is the codes similar with my:
以下是与我类似的代码:
// 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;
You might try this: libavcodec/h264_mp4toannexb_bsf.c .你可以试试这个: libavcodec/h264_mp4toannexb_bsf.c 。 It converts bitstream without start codes to bitstream with start codes.
它将不带起始码的比特流转换为带起始码的比特流。
Using your source file, does ffmpeg -i src.mp4 -vcodec copy -an dst.mp4
work?使用您的源文件,是否
ffmpeg -i src.mp4 -vcodec copy -an dst.mp4
工作? Does it work if you add -bsf h264_mp4toannexb
?如果添加
-bsf h264_mp4toannexb
是否有效? (all using the same version/build of ffmpeg as you are trying to use programmatically of course) (当然,都使用与您尝试以编程方式使用的相同版本/构建的ffmpeg)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.