ffmpeg封装H246为MP4文档格式.docx
- 文档编号:20344589
- 上传时间:2023-01-22
- 格式:DOCX
- 页数:17
- 大小:20.57KB
ffmpeg封装H246为MP4文档格式.docx
《ffmpeg封装H246为MP4文档格式.docx》由会员分享,可在线阅读,更多相关《ffmpeg封装H246为MP4文档格式.docx(17页珍藏版)》请在冰豆网上搜索。
intmain(intargc,char*argv[])
{
AVOutputFormat*ofmt=NULL;
//InputAVFormatContextandOutputAVFormatContext
AVFormatContext*ifmt_ctx_v=NULL,*ifmt_ctx_a=NULL,*ofmt_ctx=NULL;
AVPacketpkt;
intret,i;
intvideoindex_v=0,videoindex_out=0;
intframe_index=0;
int64_tcur_pts_v=0,cur_pts_a=0;
//constchar*in_filename_v="
cuc_ieschool.ts"
;
//InputfileURL
constchar*in_filename_v="
vpu.h264"
//constchar*in_filename_a="
cuc_ieschool.mp3"
gowest.m4a"
gowest.aac"
constchar*in_filename_a="
huoyuanjia.mp3"
constchar*out_filename="
vpu.mp4"
//OutputfileURL
av_register_all();
//Input
if((ret=avformat_open_input(&
ifmt_ctx_v,in_filename_v,0,0))<
0){
printf("
Couldnotopeninputfile."
);
gotoend;
}
if((ret=avformat_find_stream_info(ifmt_ctx_v,0))<
Failedtoretrieveinputstreaminformation"
/*if((ret=avformat_open_input(&
ifmt_ctx_a,in_filename_a,0,0))<
if((ret=avformat_find_stream_info(ifmt_ctx_a,0))<
}*/
printf("
===========InputInformation==========\n"
av_dump_format(ifmt_ctx_v,0,in_filename_v,0);
//av_dump_format(ifmt_ctx_a,0,in_filename_a,0);
======================================\n"
//Output
avformat_alloc_output_context2(&
ofmt_ctx,NULL,NULL,out_filename);
if(!
ofmt_ctx){
Couldnotcreateoutputcontext\n"
ret=AVERROR_UNKNOWN;
ofmt=ofmt_ctx->
oformat;
ifmt_ctx_v->
nb_streams=%d\n"
ifmt_ctx_v->
nb_streams);
for(i=0;
i<
ifmt_ctx_v->
nb_streams;
i++){
//CreateoutputAVStreamaccordingtoinputAVStream
//if(ifmt_ctx_v->
streams[i]->
codec->
codec_type==AVMEDIA_TYPE_VIDEO)
{
AVStream*in_stream=ifmt_ctx_v->
streams[i];
AVStream*out_stream=avformat_new_stream(ofmt_ctx,in_stream->
codec);
videoindex_v=i;
if(!
out_stream){
printf("
Failedallocatingoutputstream\n"
ret=AVERROR_UNKNOWN;
gotoend;
}
videoindex_out=out_stream->
index;
//CopythesettingsofAVCodecContext
if(avcodec_copy_context(out_stream->
codec,in_stream->
codec)<
Failedtocopycontextfrominputtooutputstreamcodeccontext\n"
out_stream->
codec_tag=0;
if(ofmt_ctx->
oformat->
flags&
AVFMT_GLOBALHEADER)
out_stream->
flags|=CODEC_FLAG_GLOBAL_HEADER;
//break;
}
ifmt_ctx_a->
if(ifmt_ctx_a->
codec_type==AVMEDIA_TYPE_AUDIO){
AVStream*in_stream=ifmt_ctx_a->
audioindex_a=i;
audioindex_out=out_stream->
break;
==========OutputInformation==========\n"
av_dump_format(ofmt_ctx,0,out_filename,1);
//Openoutputfile
(ofmt->
AVFMT_NOFILE)){
if(avio_open(&
ofmt_ctx->
pb,out_filename,AVIO_FLAG_WRITE)<
printf("
Couldnotopenoutputfile'
%s'
out_filename);
gotoend;
//Writefileheader
if(avformat_write_header(ofmt_ctx,NULL)<
Erroroccurredwhenopeningoutputfile\n"
//FIX
#ifUSE_H264BSF
AVBitStreamFilterContext*h264bsfc=av_bitstream_filter_init("
#endif
#ifUSE_AACBSF
AVBitStreamFilterContext*aacbsfc=av_bitstream_filter_init("
while
(1){
AVFormatContext*ifmt_ctx;
intstream_index=0;
AVStream*in_stream,*out_stream;
//GetanAVPacket
//if(av_compare_ts(cur_pts_v,ifmt_ctx_v->
streams[videoindex_v]->
time_base,cur_pts_a,ifmt_ctx_a->
streams[audioindex_a]->
time_base)<
=0)
ifmt_ctx=ifmt_ctx_v;
stream_index=videoindex_out;
if(av_read_frame(ifmt_ctx,&
pkt)>
=0){
do{
in_stream=ifmt_ctx->
streams[pkt.stream_index];
out_stream=ofmt_ctx->
streams[stream_index];
printf("
stream_index==%d,pkt.stream_index==%d,videoindex_v=%d\n"
stream_index,pkt.stream_index,videoindex_v);
if(pkt.stream_index==videoindex_v){
//FIX:
NoPTS(Example:
RawH.264)
//SimpleWritePTS
if(pkt.pts==AV_NOPTS_VALUE){
printf("
frame_index==%d\n"
frame_index);
//WritePTS
AVRationaltime_base1=in_stream->
time_base;
//Durationbetween2frames(us)
int64_tcalc_duration=(double)AV_TIME_BASE/av_q2d(in_stream->
r_frame_rate);
//Parameters
pkt.pts=(double)(frame_index*calc_duration)/(double)(av_q2d(time_base1)*AV_TIME_BASE);
pkt.dts=pkt.pts;
pkt.duration=(double)calc_duration/(double)(av_q2d(time_base1)*AV_TIME_BASE);
frame_index++;
}
cur_pts_v=pkt.pts;
break;
}
}while(av_read_frame(ifmt_ctx,&
=0);
}else{
break;
/*else
ifmt_ctx=ifmt_ctx_a;
stream_index=audioindex_out;
if(pkt.stream_index==audioindex_a){
NoPTS
cur_pts_a=pkt.pts;
}*/
//FIX:
BitstreamFilter
av_bitstream_filter_filter(h264bsfc,in_stream->
codec,NULL,&
pkt.data,&
pkt.size,pkt.data,pkt.size,0);
av_bitstream_filter_filter(aacbsfc,out_stream->
//ConvertPTS/DTS
pkt.pts=av_rescale_q_rnd(pkt.pts,in_stream->
time_base,out_stream->
time_base,(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
pkt.dts=av_rescale_q_rnd(pkt.dts,in_stream->
pkt.duration=av_rescale_q(pkt.duration,in_stream->
time_base);
pkt.pos=-1;
pkt.stream_index=stream_index;
printf("
Write1Packet.size:
%5d\tpts:
%lld\n"
pkt.size,pkt.pts);
//Write
if(av_interleaved_write_frame(ofmt_ctx,&
pkt)<
Errormuxingpacket\n"
av_free_packet(&
pkt);
//Writefiletrailer
av_write_trailer(ofmt_ctx);
av_bitstream_filter_close(h264bsfc);
av_bitstream_filter_close(aacbsfc);
end:
avformat_close_input(&
ifmt_ctx_v);
//avformat_close_input(&
ifmt_ctx_a);
/*closeoutput*/
if(ofmt_ctx&
&
!
AVFMT_NOFILE))
avio_close(ofmt_ctx->
pb);
avformat_free_context(ofmt_ctx);
if(ret<
0&
ret!
=AVERROR_EOF){
Erroroccurred.\n"
return-1;
return0;
}
二、h264视频实时流的封装
大体思路和上面文件操作是差不多的,区别在于不能像上面一样可以获取文件中视频流的信息,这样你就得自己去设置这些参数,下面程序是根据我自己的视频流设置的,如果你的不同,需要修改;
具体参数如下:
(1)AVCodecContext的配置参数
enumAVMediaTypecodec_type:
编解码器的类型(视频,音频...)
structAVCodec
*codec:
采用的解码器AVCodec(H.264,MPEG2...)
intbit_rate:
平均比特率
uint8_t*extradata;
intextradata_size:
针对特定编码器包含的附加信息(例如对于H.264解码器来说,存储SPS,PPS等)
AVRationaltime_base:
根据该参数,可以把PTS转化为实际的时间(单位为秒s)
intwidth,height:
如果是视频的话,代表宽和高
intrefs:
运动估计参考帧的个数(H.264的话会有多帧,MPEG2这类的一般就没有了)
intsample_rate:
采样率(音频)
intchannels:
声道数(音频)
enumAVSampleFormatsample_fmt:
采样格式
intprofile:
型(H.264里面就有,其他编码标准应该也有)
intlevel:
级(和profile差不太多)
(2)还有一个结构体参数也需要去设置,在AVPacket结构体中,重要的变量有以下几个:
uint8_t*data:
压缩编码的数据。
例如对于H.264来说。
1个AVPacket的data通常对应一个NAL。
注意:
在这里只是对应,而不是一模一样。
他们之间有微小的差别:
使用FFMPEG类库分离出多媒体文件中的H.264码流
因此在使用FFMPEG进行视音频处理的时候,常常可以将得到的AVPacket的data数据直接写成文件,从而得到视音频的码流文件。
int
size:
data的大小
int64_tpts:
显示时间戳
int64_tdts:
解码时间戳
stream_index:
标识该AVPacket所属的视频/音频流。
总体代码如下:
#include"
ffmpeg_mp4.h"
intgetVopType(constvoid*p,intlen)
if(!
p||6>
=len)
return-1;
unsignedchar*b=(unsignedchar*)p;
//VerifyNALmarker
if(b[0]||b[1
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ffmpeg 封装 H246 MP4