FFmpeg简单学习:解封装基本流程
解封装流程
1.分配解复用器上下文avformat_alloc_context
2.根据url打开本地文件或网络流avformat_open_input
3.读取媒体的部分数据包以获取码流信息avformat_find_stream_info
4.读取码流信息:循环处理
4.1 从文件中读取数据包av_read_frame
4.2 定位文件avformat_seek_file或av_seek_frame
5.关闭解复用器avformat_close_input
代码基本流程如下:
1 #include <stdio.h> 2 #include ”libavformat/avformat.h” 3 4 int main(int argc, char **argv) 5 { 6 7 // 1. 打开文件 8 const char *ifilename = "1234.flv"; 9 printf("in_filename = %s\n", ifilename); 10 // AVFormatContext是描述一个媒体文件或媒体流的构成和基本信息的结构体 11 AVFormatContext *ifmt_ctx = NULL; // 输入文件的demux 12 // 打开文件,主要是探测协议类型,如果是网络文件则创建网络链接 13 int ret = avformat_open_input(&ifmt_ctx, ifilename, NULL, NULL); 14 if (ret < 0) { 15 char buf[1024] = {0}; 16 av_strerror(ret, buf, sizeof (buf) - 1); 17 printf("open %s failed: %s\n", ifilename, buf); 18 return -1; 19 } 20 21 // 2. 读取码流信息 22 ret = avformat_find_stream_info(ifmt_ctx, NULL); 23 if (ret < 0) //如果打开媒体文件失败,打印失败原因 24 { 25 char buf[1024] = { 0 }; 26 av_strerror(ret, buf, sizeof(buf) - 1); 27 printf("avformat_find_stream_info %s failed:%s\n", ifilename, buf); 28 avformat_close_input(&ifmt_ctx); 29 return -1; 30 } 31 32 33 // 3.打印总体信息 34 printf_s("\n==== av_dump_format in_filename:%s ===\n", ifilename); 35 av_dump_format(ifmt_ctx, 0, ifilename, 0); 36 printf_s("\n==== av_dump_format finish =======\n\n"); 37 printf("media name:%s\n", ifmt_ctx->url); 38 printf("stream number:%d\n", ifmt_ctx->nb_streams); // nb_streams媒体流数量 39 printf("media average ratio:%lldkbps\n",(int64_t)(ifmt_ctx->bit_rate/1024)); // 媒体文件的码率,单位为bps 40 // duration: 媒体文件时长,单位微妙 41 int total_seconds = (ifmt_ctx->duration) / AV_TIME_BASE; // 1000us = 1ms, 1000ms = 1秒 42 printf("audio duration: %02d:%02d:%02d\n", 43 total_seconds / 3600, (total_seconds % 3600) / 60, (total_seconds % 60)); 44 printf("\n"); 45 46 // 4.读取码流信息 47 // 音频 48 int audioindex = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0); 49 if (audioindex < 0) { 50 printf("av_find_best_stream %s eror.", av_get_media_type_string(AVMEDIA_TYPE_AUDIO)); 51 return -1; 52 } 53 AVStream *audio_stream = ifmt_ctx->streams[audioindex]; 54 printf("----- Audio info:\n"); 55 printf("index: %d\n", audio_stream->index); // 序列号 56 printf("samplarate: %d Hz\n", audio_stream->codecpar->sample_rate); // 采样率 57 printf("sampleformat: %d\n", audio_stream->codecpar->format); // 采样格式 AV_SAMPLE_FMT_FLTP:8 58 printf("audio codec: %d\n", audio_stream->codecpar->codec_id); // 编码格式 AV_CODEC_ID_MP3:86017 AV_CODEC_ID_AAC:86018 59 if (audio_stream->duration != AV_NOPTS_VALUE) { 60 int audio_duration = audio_stream->duration * av_q2d(audio_stream->time_base); 61 printf("audio duration: %02d:%02d:%02d\n", 62 audio_duration / 3600, (audio_duration % 3600) / 60, (audio_duration % 60)); 63 } 64 65 // 视频 66 int videoindex = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0); 67 if (videoindex < 0) { 68 printf("av_find_best_stream %s eror.", av_get_media_type_string(AVMEDIA_TYPE_VIDEO)); 69 return -1; 70 } 71 AVStream *video_stream = ifmt_ctx->streams[videoindex]; 72 printf("----- Video info:\n"); 73 printf("index: %d\n", video_stream->index); // 序列号 74 printf("fps: %lf\n", av_q2d(video_stream->avg_frame_rate)); // 帧率 75 printf("width: %d, height:%d \n", video_stream->codecpar->width, video_stream->codecpar->height); 76 printf("video codec: %d\n", video_stream->codecpar->codec_id); // 编码格式 AV_CODEC_ID_H264: 27 77 if (video_stream->duration != AV_NOPTS_VALUE) { 78 int video_duration = video_stream->duration * av_q2d(video_stream->time_base); 79 printf("audio duration: %02d:%02d:%02d\n", 80 video_duration / 3600, (video_duration % 3600) / 60, (video_duration % 60)); 81 } 82 83 // 5.提取码流 84 AVPacket *pkt = av_packet_alloc(); 85 int pkt_count = 0; 86 int print_max_count = 10; 87 printf("\n-----av_read_frame start\n"); 88 while (1) 89 { 90 ret = av_read_frame(ifmt_ctx, pkt); 91 if (ret < 0) { 92 printf("av_read_frame end\n"); 93 break; 94 } 95 96 if(pkt_count++ < print_max_count) 97 { 98 if (pkt->stream_index == audioindex) 99 { 100 printf("audio pts: %lld\n", pkt->pts); 101 printf("audio dts: %lld\n", pkt->dts); 102 printf("audio size: %d\n", pkt->size); 103 printf("audio pos: %lld\n", pkt->pos); 104 printf("audio duration: %lf\n\n", 105 pkt->duration * av_q2d(ifmt_ctx->streams[audioindex]->time_base)); 106 } 107 else if (pkt->stream_index == videoindex) 108 { 109 printf("video pts: %lld\n", pkt->pts); 110 printf("video dts: %lld\n", pkt->dts); 111 printf("video size: %d\n", pkt->size); 112 printf("video pos: %lld\n", pkt->pos); 113 printf("video duration: %lf\n\n", 114 pkt->duration * av_q2d(ifmt_ctx->streams[videoindex]->time_base)); 115 } 116 else 117 { 118 printf("unknown stream_index:\n", pkt->stream_index); 119 } 120 } 121 av_packet_unref(pkt); 122 } 123 124 // 6.结束 125 if(pkt) 126 av_packet_free(&pkt); 127 if(ifmt_ctx) 128 avformat_close_input(&ifmt_ctx); 129 130 131 getchar(); //加上这一句,防止程序打印完信息马上退出 132 return 0; 133 }
在linux环境中编译执行如下:
输出如下:
1 in_filename = 1234.flv 2 3 ==== av_dump_format in_filename:believe.flv === 4 Input #0, flv, from '1234.flv': 5 Metadata: 6 major_brand : isom 7 minor_version : 512 8 compatible_brands: isomiso2avc1mp41 9 comment : www.ieway.cn 10 encoder : Lavf58.29.100 11 Duration: 00:03:42.53, start: 0.000000, bitrate: 286 kb/s 12 Stream #0:0: Video: h264 (Constrained Baseline), yuv420p(progressive), 1920x1080, 150 kb/s, 14.46 fps, 15 tbr, 1k tbn, 30 tbc 13 Stream #0:1: Audio: aac (LC), 48000 Hz, stereo, fltp, 128 kb/s 14 15 ==== av_dump_format finish ======= 16 17 media name:believe.flv 18 stream number:2 19 media average ratio:279kbps 20 audio duration: 00:03:42 21 22 ----- Audio info: 23 index: 1 24 samplarate: 48000 Hz 25 sampleformat: 8 26 audio codec: 86018 27 ----- Video info: 28 index: 0 29 fps: 14.464286 30 width: 1920, height:1080 31 video codec: 27 32 33 -----av_read_frame start 34 audio pts: 0 35 audio dts: 0 36 audio size: 341 37 audio pos: 502 38 audio duration: 0.021000 39 40 video pts: 14 41 video dts: 14 42 video size: 66736 43 video pos: 860 44 video duration: 0.066000 45 46 audio pts: 21 47 audio dts: 21 48 audio size: 341 49 audio pos: 67616 50 audio duration: 0.021000 51 52 audio pts: 43 53 audio dts: 43 54 audio size: 342 55 audio pos: 67974 56 audio duration: 0.021000 57 58 audio pts: 64 59 audio dts: 64 60 audio size: 341 61 audio pos: 68333 62 audio duration: 0.021000 63 64 video pts: 81 65 video dts: 81 66 video size: 580 67 video pos: 68691 68 video duration: 0.066000 69 70 audio pts: 85 71 audio dts: 85 72 audio size: 341 73 audio pos: 69291 74 audio duration: 0.021000 75 76 audio pts: 107 77 audio dts: 107 78 audio size: 342 79 audio pos: 69649 80 audio duration: 0.021000 81 82 audio pts: 128 83 audio dts: 128 84 audio size: 341 85 audio pos: 70008 86 audio duration: 0.021000 87 88 video pts: 147 89 video dts: 147 90 video size: 11289 91 video pos: 70366 92 video duration: 0.066000 93 av_read_frame end

浙公网安备 33010602011771号