h264 裸流打包成mp4 注意事项

192 篇文章 4 订阅 ¥19.90 ¥99.00
本文介绍了如何将Android设备上网络摄像头的H264裸流转换并保存为MP4文件,重点讨论了在转换过程中遇到的三个关键问题:dts和pts的设置、sps的重要性以及fps的正确设定。通过设置dts等于pts,正确包含sps信息,并确保fps的准确计算,成功解决了打包MP4时的识别问题。
摘要由CSDN通过智能技术生成

需求: Android 端把网络摄像头的一段正在播放的视频流,截取保存成mp4(按录像按钮时开始录像)。

实现: ffmpeg + x264 + sdl;

h264 裸流 打包成MP4,在网上也有一大堆文章,ffmpeg 也有一个muxing 的 example,大致流程都是一样的,参考ffmpeg的muxing.c 就可以写一个。我这里把我在这个过程中遇到的问题写出来,这些问题困扰了我很久才解决,谁叫我是视频方面的小白呢。

这三个问题其实很简单,但如果对这方面不了解的话,耗掉的时间还是很多的。

 

1,dts,pts:

     在write_frame()之前,每一个avpacket 数据都要设置 dts,pts,因为我的视频没有B帧,所以dts = pts 便可;pts 一开始我也不知道要怎么设, 参考muxing.c,设置成写入的帧数量便可(结合问题3);

2,sps,pps;

     我接受到的裸流里面 sps  +pps + i帧 是放在一个NALU 里面的,在保存成mp4时这个sps 非常重要,我一开始没有设置,打包后的Mp4 普通的播放器就不能识别;

     sps 在创建 编码器时候传递给编码器;     sps 是 00 00 00 01 后面的,不包含这个00 00 00 01 这个码;pps 我还没用到。  

[plain]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. case AVMEDIA_TYPE_VIDEO:  
  2.     c->codec_id = codec_id;  
  3.     LOGE("add_stream AVMEDIA_TYPE_VIDEO c->time_base.num = %d",ost->st->codec->time_base.num);  
  4.     c->bit_rate = 400000;  
  5.     /* Resolution must be a multiple of two. */  
  6.     c->width    = 352;  
  7.     c->height   = 288;  
  8.     /* timebase: This is the fundamental unit of time (in seconds) in terms  
  9.      * of which frame timestamps are represented. For fixed-fps content,  
  10.      * timebase should be 1/framerate and timestamp increments should be  
  11.      * identical to 1. */  
  12.     ost->st->time_base = (AVRational){ 1, STREAM_FRAME_RATE};//STREAM_FRAME_RATE };  
  13.     c->time_base       =ost->st->time_base;  
  14.   
  15.     c->gop_size      = 12; /* emit one intra frame every twelve frames at most */  
  16.     c->pix_fmt       = STREAM_PIX_FMT;  
  17.     if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {  
  18.         /* just for testing, we also add B frames */  
  19.         c->max_b_frames = 2;  
  20.     }  
  21.     if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {  
  22.         /* Needed to avoid using macroblocks in which some coeffs overflow.  
  23.          * This does not happen with normal video, it just happens here as  
  24.          * the motion of the chroma plane does not match the luma plane. */  
  25.         c->mb_decision = 2;  
  26.     }  
  27.    c->extradata = spsinfo;  
  28.    c->extradata_size = 10;  
  29. break;  


3,fps:

    在保存成mp4后,调试过程中各种fps都出来了,最后仔细看muxing.c ,发现其实要设置正确很简单:在pts 按1递增后,用一个很简单的函数就解决了这个问题。

   c->time_base : 输入的帧率fps = 25 :{1,25},ost->st->time_base : 输出的帧率; 我这里设置和输入的一样就好了。

 

[plain]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1.  packet->pts = (ptsInc++);;// * (90000/STREAM_FRAME_RATE);  
  2.   packet->dts = packet->pts;  
  3. // packet->duration = 8/1000000;  
  4.  // packet->pos = -1;//ptsInc;  
  5.   
  6.   
  7.   av_packet_rescale_ts(packet, c->time_base, ost->st->time_base);  




http://blog.csdn.net/xqt8888/article/details/43152529


muxing.c
http://ffmpeg.org/doxygen/trunk/doc_2examples_2muxing_8c-example.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值