=====================================================
FFmpeg简单使用:过滤器 ---- h264_mp4toannexb
FFmpeg简单使用:解封装h264 ---- 提取SPS PPS
=====================================================
解封装流程
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
编码:
#include <stdio.h> #include <libavformat/avformat.h> int main(int argc, char **argv) { // 1. 打开文件 const char *ifilename = "believe.flv"; printf("in_filename = %s ", ifilename); // AVFormatContext是描述一个媒体文件或媒体流的构成和基本信息的结构体 AVFormatContext *ifmt_ctx = NULL; // 输入文件的demux // 打开文件,主要是探测协议类型,如果是网络文件则创建网络链接 int ret = avformat_open_input(&ifmt_ctx, ifilename, NULL, NULL); if (ret < 0) { char buf[1024] = {0}; av_strerror(ret, buf, sizeof (buf) - 1); printf("open %s failed: %s ", ifilename, buf); return -1; } // 2. 读取码流信息 ret = avformat_find_stream_info(ifmt_ctx, NULL); if (ret < 0) //如果打开媒体文件失败,打印失败原因 { char buf[1024] = { 0 }; av_strerror(ret, buf, sizeof(buf) - 1); printf("avformat_find_stream_info %s failed:%s ", ifilename, buf); avformat_close_input(&ifmt_ctx); return -1; } // 3.打印总体信息 printf_s(" ==== av_dump_format in_filename:%s === ", ifilename); av_dump_format(ifmt_ctx, 0, ifilename, 0); printf_s(" ==== av_dump_format finish ======= "); printf("media name:%s ", ifmt_ctx->url); printf("stream number:%d ", ifmt_ctx->nb_streams); // nb_streams媒体流数量 printf("media average ratio:%lldkbps ",(int64_t)(ifmt_ctx->bit_rate/1024)); // 媒体文件的码率,单位为bps // duration: 媒体文件时长,单位微妙 int total_seconds = (ifmt_ctx->duration) / AV_TIME_BASE; // 1000us = 1ms, 1000ms = 1秒 printf("audio duration: %02d:%02d:%02d ", total_seconds / 3600, (total_seconds % 3600) / 60, (total_seconds % 60)); printf(" "); // 4.读取码流信息 // 音频 int audioindex = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0); if (audioindex < 0) { printf("av_find_best_stream %s eror.", av_get_media_type_string(AVMEDIA_TYPE_AUDIO)); return -1; } AVStream *audio_stream = ifmt_ctx->streams[audioindex]; printf("----- Audio info: "); printf("index: %d ", audio_stream->index); // 序列号 printf("samplarate: %d Hz ", audio_stream->codecpar->sample_rate); // 采样率 printf("sampleformat: %d ", audio_stream->codecpar->format); // 采样格式 AV_SAMPLE_FMT_FLTP:8 printf("audio codec: %d ", audio_stream->codecpar->codec_id); // 编码格式 AV_CODEC_ID_MP3:86017 AV_CODEC_ID_AAC:86018 if (audio_stream->duration != AV_NOPTS_VALUE) { int audio_duration = audio_stream->duration * av_q2d(audio_stream->time_base); printf("audio duration: %02d:%02d:%02d ", audio_duration / 3600, (audio_duration % 3600) / 60, (audio_duration % 60)); } // 视频 int videoindex = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0); if (videoindex < 0) { printf("av_find_best_stream %s eror.", av_get_media_type_string(AVMEDIA_TYPE_VIDEO)); return -1; } AVStream *video_stream = ifmt_ctx->streams[videoindex]; printf("----- Video info: "); printf("index: %d ", video_stream->index); // 序列号 printf("fps: %lf ", av_q2d(video_stream->avg_frame_rate)); // 帧率 printf(" %d, height:%d ", video_stream->codecpar->width, video_stream->codecpar->height); printf("video codec: %d ", video_stream->codecpar->codec_id); // 编码格式 AV_CODEC_ID_H264: 27 if (video_stream->duration != AV_NOPTS_VALUE) { int video_duration = video_stream->duration * av_q2d(video_stream->time_base); printf("audio duration: %02d:%02d:%02d ", video_duration / 3600, (video_duration % 3600) / 60, (video_duration % 60)); } // 5.提取码流 AVPacket *pkt = av_packet_alloc(); int pkt_count = 0; int print_max_count = 10; printf(" -----av_read_frame start "); while (1) { ret = av_read_frame(ifmt_ctx, pkt); if (ret < 0) { printf("av_read_frame end "); break; } if(pkt_count++ < print_max_count) { if (pkt->stream_index == audioindex) { printf("audio pts: %lld ", pkt->pts); printf("audio dts: %lld ", pkt->dts); printf("audio size: %d ", pkt->size); printf("audio pos: %lld ", pkt->pos); printf("audio duration: %lf ", pkt->duration * av_q2d(ifmt_ctx->streams[audioindex]->time_base)); } else if (pkt->stream_index == videoindex) { printf("video pts: %lld ", pkt->pts); printf("video dts: %lld ", pkt->dts); printf("video size: %d ", pkt->size); printf("video pos: %lld ", pkt->pos); printf("video duration: %lf ", pkt->duration * av_q2d(ifmt_ctx->streams[videoindex]->time_base)); } else { printf("unknown stream_index: ", pkt->stream_index); } } av_packet_unref(pkt); } // 6.结束 if(pkt) av_packet_free(&pkt); if(ifmt_ctx) avformat_close_input(&ifmt_ctx); getchar(); //加上这一句,防止程序打印完信息马上退出 return 0; }
输出:
in_filename = believe.flv ==== av_dump_format in_filename:believe.flv === Input #0, flv, from 'believe.flv': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 comment : www.ieway.cn encoder : Lavf58.29.100 Duration: 00:03:42.53, start: 0.000000, bitrate: 286 kb/s Stream #0:0: Video: h264 (Constrained Baseline), yuv420p(progressive), 1920x1080, 150 kb/s, 14.46 fps, 15 tbr, 1k tbn, 30 tbc Stream #0:1: Audio: aac (LC), 48000 Hz, stereo, fltp, 128 kb/s ==== av_dump_format finish ======= media name:believe.flv stream number:2 media average ratio:279kbps audio duration: 00:03:42 ----- Audio info: index: 1 samplarate: 48000 Hz sampleformat: 8 audio codec: 86018 ----- Video info: index: 0 fps: 14.464286 1920, height:1080 video codec: 27 -----av_read_frame start audio pts: 0 audio dts: 0 audio size: 341 audio pos: 502 audio duration: 0.021000 video pts: 14 video dts: 14 video size: 66736 video pos: 860 video duration: 0.066000 audio pts: 21 audio dts: 21 audio size: 341 audio pos: 67616 audio duration: 0.021000 audio pts: 43 audio dts: 43 audio size: 342 audio pos: 67974 audio duration: 0.021000 audio pts: 64 audio dts: 64 audio size: 341 audio pos: 68333 audio duration: 0.021000 video pts: 81 video dts: 81 video size: 580 video pos: 68691 video duration: 0.066000 audio pts: 85 audio dts: 85 audio size: 341 audio pos: 69291 audio duration: 0.021000 audio pts: 107 audio dts: 107 audio size: 342 audio pos: 69649 audio duration: 0.021000 audio pts: 128 audio dts: 128 audio size: 341 audio pos: 70008 audio duration: 0.021000 video pts: 147 video dts: 147 video size: 11289 video pos: 70366 video duration: 0.066000 av_read_frame end