Nal 数据通过av_interleaved_write_frame 输出ts格式
时间: 2023-08-05 13:09:15 浏览: 98
将 NAL 数据输出到 TS 格式文件中,可以按照以下步骤进行:
1. 初始化 AVFormatContext 和 AVOutputFormat,设置输出文件名和格式参数。
```c
AVFormatContext *ofmt_ctx = NULL;
avformat_alloc_output_context2(&ofmt_ctx, NULL, "mpegts", out_filename);
AVOutputFormat *ofmt = ofmt_ctx->oformat;
```
2. 打开输出文件。
```c
if (!(ofmt->flags & AVFMT_NOFILE)) {
if (avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE) < 0) {
printf("Could not open output file '%s'", out_filename);
return -1;
}
}
```
3. 添加视频流到输出文件中,设置编码参数,打开编码器。
```c
AVStream *out_stream = avformat_new_stream(ofmt_ctx, NULL);
AVCodecParameters *codecpar = out_stream->codecpar;
codecpar->codec_id = AV_CODEC_ID_H264;
codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
codecpar->format = AV_PIX_FMT_YUV420P;
codecpar->width = width;
codecpar->height = height;
codecpar->extradata_size = sps_len + pps_len;
codecpar->extradata = av_mallocz(sps_len + pps_len + AV_INPUT_BUFFER_PADDING_SIZE);
memcpy(codecpar->extradata, sps_pps_data, sps_len + pps_len);
out_stream->time_base = (AVRational){1, fps};
AVCodec *codec = avcodec_find_encoder(codecpar->codec_id);
AVCodecContext *codec_ctx = avcodec_alloc_context3(codec);
avcodec_parameters_to_context(codec_ctx, codecpar);
codec_ctx->time_base = out_stream->time_base;
codec_ctx->gop_size = 10;
codec_ctx->max_b_frames = 1;
codec_ctx->bit_rate = bitrate;
codec_ctx->rc_min_rate = bitrate;
codec_ctx->rc_max_rate = bitrate;
codec_ctx->rc_buffer_size = bitrate;
avcodec_open2(codec_ctx, codec, NULL);
```
4. 循环读取 NAL 数据,将数据写入 AVPacket 中,并设置时间戳和时长。
```c
while (read_len > 0) {
AVPacket pkt;
av_init_packet(&pkt);
pkt.data = buf;
pkt.size = read_len;
pkt.pts = pts++;
pkt.dts = pkt.pts;
pkt.duration = 1;
pkt.stream_index = out_stream->index;
av_interleaved_write_frame(ofmt_ctx, &pkt);
av_packet_unref(&pkt);
read_len = fread(buf, 1, buf_size, fp);
}
```
5. 写入文件尾,并释放资源。
```c
av_write_trailer(ofmt_ctx);
avcodec_close(codec_ctx);
avcodec_free_context(&codec_ctx);
av_freep(&codecpar->extradata);
avio_close(ofmt_ctx->pb);
avformat_free_context(ofmt_ctx);
```
完整代码示例可以参考以下链接:https://gist.github.com/mstorsjo/012b5861e1fca20f1b2b961d853e49ec
阅读全文