返回
FFmpeg 视频流编码流程:从小白到进阶
见解分享
2024-01-29 10:39:58
图像编码:从 H.264 到 MP4
图像编码概述
视频编码是将原始视频帧压缩成更小文件大小的过程,从而减少传输和存储需求,同时保持视频质量。H.264 和 MP4 都是广泛使用的视频编码格式。H.264 是一种高度压缩的编解码器,而 MP4 是一种容器格式,通常包含 H.264 编码的视频流。
从图像到 H.264 的编码
准备阶段
- 使用 FFmpeg 打开图像文件。
- 检索视频流信息。
- 创建输出视频文件。
- 添加视频流并设置 H.264 编解码器。
编码阶段
- 初始化 H.264 编解码器。
- 分配编码帧缓冲区。
- 读取图像帧。
- 编码图像帧为 H.264 码流。
- 将编码帧写入输出视频文件。
结束阶段
- 释放 H.264 编解码器。
- 关闭输出视频文件。
从图像到 MP4 的编码
准备阶段
- 创建 MP4 容器。
- 添加视频流并设置 H.264 编解码器。
- 添加音频流(可选)。
编码阶段
- 编码视频流为 H.264 码流。
- 将编码后的 H.264 码流封装到 MP4 容器。
- 编码音频流并封装到 MP4 容器(如果需要)。
结束阶段
- 关闭 MP4 容器。
代码示例(C++)
// 编码图像为 H.264
int encode_image_to_h264(const char* input_file, const char* output_file) {
AVFormatContext* input_context = avformat_alloc_context();
avformat_open_input(&input_context, input_file, NULL, NULL);
AVFormatContext* output_context = avformat_alloc_context();
avformat_alloc_output_context2(&output_context, NULL, "mp4", output_file);
AVStream* video_stream = avformat_new_stream(output_context, NULL);
AVCodec* video_codec = avcodec_find_encoder(AV_CODEC_ID_H264);
avcodec_open2(video_codec, NULL, NULL);
AVFrame* frame = av_frame_alloc();
AVPacket pkt;
while (av_read_frame(input_context, &pkt) >= 0) {
if (pkt.stream_index == video_stream->index) {
avcodec_encode_video2(video_codec, &pkt, frame, &got_packet);
if (got_packet) {
av_interleaved_write_frame(output_context, &pkt);
av_packet_unref(&pkt);
}
}
}
avcodec_close(video_codec);
avformat_close_input(&input_context);
avformat_free_context(output_context);
return 0;
}
// 编码图像为 MP4
int encode_image_to_mp4(const char* input_file, const char* output_file) {
AVFormatContext* input_context = avformat_alloc_context();
avformat_open_input(&input_context, input_file, NULL, NULL);
AVFormatContext* output_context = avformat_alloc_context();
avformat_alloc_output_context2(&output_context, NULL, "mp4", output_file);
AVStream* video_stream = avformat_new_stream(output_context, NULL);
AVCodec* video_codec = avcodec_find_encoder(AV_CODEC_ID_H264);
avcodec_open2(video_codec, NULL, NULL);
AVStream* audio_stream = NULL;
AVCodec* audio_codec = NULL;
AVFrame* video_frame = av_frame_alloc();
AVPacket video_pkt;
while (av_read_frame(input_context, &video_pkt) >= 0) {
if (video_pkt.stream_index == video_stream->index) {
avcodec_encode_video2(video_codec, &video_pkt, video_frame, &got_packet);
if (got_packet) {
av_interleaved_write_frame(output_context, &video_pkt);
av_packet_unref(&video_pkt);
}
}
}
avcodec_close(video_codec);
if (audio_stream) {
avcodec_close(audio_codec);
}
avformat_close_input(&input_context);
avformat_free_context(output_context);
return 0;
}
常见问题解答
1. 我可以使用 H.264 编码其他类型的文件吗?
是的,H.264 是一种通用编解码器,可用于编码各种视频格式,包括 MOV、AVI 和 MKV。
2. MP4 和 H.264 之间的区别是什么?
MP4 是一个容器格式,可以包含视频、音频和字幕等多种数据流。H.264 是一种视频编解码器,用于压缩和解压缩视频数据。
3. 我需要使用什么软件来编码图像?
可以使用多种软件来编码图像,包括 FFmpeg、HandBrake 和 VLC Media Player。
4. 如何优化我的编码设置?
编码设置会影响输出视频的质量和文件大小。您需要根据您的特定需求调整这些设置,例如比特率、帧率和分辨率。
5. 我的编码视频为什么会失真或有噪音?
编码视频失真或噪音可能是由多种因素造成的,包括比特率不足、编码器设置不当或源文件质量差。