ffmpeg h264 aac 裸数据 保存到文件 avpacket pts 计算
时间: 2023-07-30 10:07:32 浏览: 239
将H.264视频和AAC音频的裸数据保存到文件中,需要使用FFmpeg的AVFormatContext、AVStream、AVCodecContext和AVPacket等结构体进行编码和封装。以下是保存H.264视频和AAC音频的步骤:
1. 初始化AVFormatContext结构体,设置输出文件的格式和文件名等参数。
```
AVFormatContext *out_fmt_ctx = NULL;
avformat_alloc_output_context2(&out_fmt_ctx, NULL, NULL, output_file);
```
2. 初始化视频流和音频流的AVStream结构体,并将其添加到AVFormatContext中。
```
AVStream *video_stream = avformat_new_stream(out_fmt_ctx, NULL);
AVStream *audio_stream = avformat_new_stream(out_fmt_ctx, NULL);
```
3. 初始化视频流和音频流的AVCodecContext结构体,设置编码器参数。
```
AVCodecContext *video_codec_ctx = video_stream->codec;
AVCodecContext *audio_codec_ctx = audio_stream->codec;
// 设置视频编码器参数
video_codec_ctx->codec_id = AV_CODEC_ID_H264;
video_codec_ctx->codec_type = AVMEDIA_TYPE_VIDEO;
video_codec_ctx->width = width;
video_codec_ctx->height = height;
video_codec_ctx->time_base = (AVRational){1, fps};
// 设置音频编码器参数
audio_codec_ctx->codec_id = AV_CODEC_ID_AAC;
audio_codec_ctx->codec_type = AVMEDIA_TYPE_AUDIO;
audio_codec_ctx->sample_rate = sample_rate;
audio_codec_ctx->channels = channels;
audio_codec_ctx->channel_layout = av_get_default_channel_layout(channels);
audio_codec_ctx->time_base = (AVRational){1, sample_rate};
```
4. 初始化视频编码器和音频编码器,并将其打开。
```
AVCodec *video_codec = avcodec_find_encoder(video_codec_ctx->codec_id);
AVCodec *audio_codec = avcodec_find_encoder(audio_codec_ctx->codec_id);
avcodec_open2(video_codec_ctx, video_codec, NULL);
avcodec_open2(audio_codec_ctx, audio_codec, NULL);
```
5. 打开输出文件并写入文件头。
```
avio_open(&out_fmt_ctx->pb, output_file, AVIO_FLAG_WRITE);
avformat_write_header(out_fmt_ctx, NULL);
```
6. 读入H.264视频和AAC音频的裸数据,用AVPacket结构体封装后写入输出文件中。
```
AVPacket video_pkt, audio_pkt;
av_init_packet(&video_pkt);
av_init_packet(&audio_pkt);
video_pkt.data = video_data;
video_pkt.size = video_size;
video_pkt.pts = video_pts;
video_pkt.stream_index = video_stream->index;
audio_pkt.data = audio_data;
audio_pkt.size = audio_size;
audio_pkt.pts = audio_pts;
audio_pkt.stream_index = audio_stream->index;
av_interleaved_write_frame(out_fmt_ctx, &video_pkt);
av_interleaved_write_frame(out_fmt_ctx, &audio_pkt);
```
7. 在读入完所有数据后,写入文件尾。
```
av_write_trailer(out_fmt_ctx);
```
需要注意的是,对于AVPacket的pts值计算,可以参考前面的回答进行计算。在写入AVPacket时,需要使用函数av_interleaved_write_frame进行交错写入,确保音频和视频的AVPacket按时间戳顺序交错写入。同时,需要使用函数av_init_packet对AVPacket进行初始化,保证每个AVPacket的字段都正确设置。
阅读全文