本篇文章目标是给定一个ts封装格式的文件,从中分离出h264视频码流。
void demux(void)
{
const char *src_filename = "/Users/zhw/Desktop/sintel.ts";
const char *video_dst_filename = "/Users/zhw/Desktop/sintel.h264";
int video_index;
AVFormatContext *ifmt_ctx = NULL;
AVPacket pkt;
/* open input file, and allocate format context */
if (avformat_open_input(&ifmt_ctx, src_filename, NULL, NULL) < 0) {
fprintf(stderr, "Could not open source file %s\n", src_filename);
exit(1);
}
/* retrieve stream information */
if (avformat_find_stream_info(ifmt_ctx, NULL) < 0) {
fprintf(stderr, "Could not find stream information\n");
exit(1);
}
video_index = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
if (video_index < 0) {
fprintf(stderr, "Could not find %s stream\n",
av_get_media_type_string(AVMEDIA_TYPE_VIDEO));
return;
}
FILE *out_file = fopen(video_dst_filename, "wb");
if (!out_file) {
fprintf(stderr, "open out_file error");
return;
}
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
while (av_read_frame(ifmt_ctx, &pkt) >= 0) {
if (pkt.stream_index == video_index) {
fwrite(pkt.data, 1, pkt.size, out_file);
}
av_packet_unref(&pkt);
}
printf("finish\n");
h264_parser(video_dst_filename);
}
解析后可以看到已经可以分离出h264视频码流,可以在命令行执行:ffplay sintel.h264 进行播放。
代码的最后一行,是调用的上一篇文章的代码,以此观察NALU header信息,如下:
下图是h264文件的16进制形式