Android FFMPEG程序员

ffmpeg muxer 成 mp4 文件的duration 是

2017-11-01  本文已影响83人  爱玩保龄球

问题描述:

最近在研究短视频功能,发现编码出来的mp4文件的duration 比 原始文件的 时间大一倍

ffmpeg 命令行查看并不是stream 里面的时间出了问题,问题应该是最后计算填写头里面的封装信息出错了,详细如下:

ffprobe -print_format json -show_format -show_streams -i output_cut.mp4


通过二进制比较  为“elst” 的字段出了问题

比较结果如图红色部分,详细如下

正确的时间为 00 00 24 48     错误的时间字段 为  00 00 48 62


mp4  封装 “elst ” 字段对应数据结构如下:

aligned(8) class EditListBox extends FullBox(‘elst’, version, 0) {

unsigned int(32) entry_count;

for (i=1; i <= entry_count; i++) {

if (version==1) {

unsigned int(64) segment_duration;

int(64) media_time;

} else { // version==0

unsigned int(32) segment_duration;

int(32) media_time;

}

int(16) media_rate_integer;

int(16) media_rate_fraction = 0;

}

}

解决方案:

参考了 ffmpeg/libavformat/tests/movenc.c  里面的代码 ,由于目前资源无法设置0分,只能最低分了,资源如下

http://download.csdn.net/download/gavin_liang/10049224 

也可以下载源码查看;

关键代码标注

发现由于在 encoder  之后code timebase -> stream timebase 转化的时候 pkt->duration 要同样做处理

自身代码处理方法如下:

intFFMPEGFileOutputImp::write_frame(AVFormatContext*fmt_ctx,AVRational*time_base,AVStream*st,AVPacket*pkt,intstream_type)

{

/* rescale output packet timestamp values from codec to stream timebase */

av_packet_rescale_ts(pkt, *time_base, st->time_base);

pkt->stream_index= st->index;

int64_ttmp = st->time_base.den;

switch(stream_type) {

caseAVMEDIA_TYPE_AUDIO:

pkt->duration=1024LL * ((st->time_base.den/ st->time_base.num) /44100);

break;

caseAVMEDIA_TYPE_VIDEO:

pkt->duration= (st->time_base.den/ st->time_base.num) /STREAM_FRAME_RATE;

break;

default:

break;

}

/* Write the compressed frame to the media file. */

// log_packet(fmt_ctx, pkt);

returnav_interleaved_write_frame(fmt_ctx, pkt);

}

目前看问题得到解决,以上方式仅供参考,有更好的办法欢迎讨论


上一篇 下一篇

猜你喜欢

热点阅读