出自:http://www.mworkbox.com/wp/work/314.html

2013-05-04

MP4的视频H264封装有2种格式:h264和avc1,对于这个细节,很容易被忽略。笔者也是在改编LIVE555流媒体时,增加mp4文件类型支持时遇到了该问题。

(一)首先,从原理上了解一下这2种格式的区别:
AVC1 描述:H.264 bitstream without start codes.一般通过ffmpeg转码生成的视频,是不带起始码0×00000001的。
H264 描述:H.264 bitstream with start codes.一般对于一下HDVD等电影的压制格式,是带有起始码0×00000001的。
来源文档:http://msdn.microsoft.com/zh-cn/library/dd757808(v=vs.85).aspx
(二)其次,通过VLC播放器,可以查看到具体的格式。打开视频后,通过菜单【工具】/【编解码信息】可以查看到【编解码器】具体格式,举例如下,编解码器信息:
编码: H264 – MPEG-4 AVC (part 10) (avc1)
编码: H264 – MPEG-4 AVC (part 10) (h264)

(三)最后,分享一下ffmpeg demux MP4文件后,转换视频流为live555可直接使用的h264 ES流的经验和方法:
针对(avc1),av_read_frame后,取前四个字节为长度,把前四字节直接替换为0×00,0×00,0×00,0×01即可,但注意每个frame可以有多个NAUL:

  AVPacket pkt;
    AVPacket* packet = &pkt;
    av_init_packet(packet);
    av_read_frame(ctx, packet);
    
    
    if(packet->stream_index == 0)
    {//is video stream
    
       const char start_code[4] = { 0, 0, 0, 1 };
            if(is_avc_ || memcmp(start_code, packet->data, 4) != 0)
            {//is avc1 code, have no start code of H264
                int len = 0;
                uint8_t *p = packet->data;

is_avc_ = True;
                do 
                {//add start_code for each NAL, one frame may have multi NALs.
                    len = ntohl(*((long*)p));
                    memcpy(p, start_code, 4);

p += 4;
                    p += len;
                    if(p >= packet->data + packet->size)
                    {
                        break;
                    }
                } while (1);
            }
        }

对于另外一种格式,(h264), 则直接对每个packet调用av_bitstream_filter_filter处理每个packet即可:

  bsfc_ = av_bitstream_filter_init("h264_mp4toannexb");
  
   if(pkt->stream_index == 0)
   {//is video stream
    
      AVBitStreamFilterContext* bsfc = bsfc_;
        int a;
        while (bsfc) {
            AVPacket new_pkt = *pkt;
            a = av_bitstream_filter_filter(bsfc, encode_ctx_, NULL,
                &new_pkt.data, &new_pkt.size,
                pkt->data, pkt->size,
                pkt->flags & AV_PKT_FLAG_KEY);
            if(a == 0 && new_pkt.data != pkt->data && new_pkt.destruct) {
                uint8_t *t = (uint8_t*)(new_pkt.size + FF_INPUT_BUFFER_PADDING_SIZE); //the new should be a subset of the old so cannot overflow
                if(t) {
                    memcpy(t, new_pkt.data, new_pkt.size);
                    memset(t + new_pkt.size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
                    new_pkt.data = t;
                    a = 1;
                } else
                    a = AVERROR(ENOMEM);
            }
            if (a > 0 && pkt->data != new_pkt.data) {
                av_free_packet(pkt);
                new_pkt.destruct = av_destruct_packet;
            } else if (a < 0) {
                envir() << "!!!!!!!!!!av_bitstream_filter_filter failed" << ",res=" << a << "\n";
            }
            *pkt = new_pkt;
    
            bsfc = bsfc->next;
        }
    }

(转)MP4文件两种格式AVC1和H264的区别及利用FFMPEG demux为h264码流事项的更多相关文章

  1. Python第十四天 序列化 pickle模块 cPickle模块 JSON模块 API的两种格式

    Python第十四天 序列化  pickle模块  cPickle模块  JSON模块  API的两种格式 目录 Pycharm使用技巧(转载) Python第一天  安装  shell  文件 Py ...

  2. apache用户认证、域名跳转、Apache访问日志(两种格式)

    1.apache 设置,用户访问时 目录或文件的认证: 对目录的认证: <Directory /var/www/222> //指定认证的目录AllowOverride AuthConfig ...

  3. CTF-源码泄露-PHP备份文件的两种格式

    参考大佬文章: https://www.cnblogs.com/yunqian2017/p/11515443.html https://blog.csdn.net/xy_sunny/article/d ...

  4. CASE WHEN的两种格式

    CASE WHEN的两种格式 1.简单Case函数 CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ELSE '其他' END 2.Case搜索函数 CASE ...

  5. Java 解析Excel(xls、xlsx两种格式)

    Java 解析Excel(xls.xlsx两种格式) 一.环境 JDK 1.8 二.JAR 1.commons-collections4-4.1.jar 2.poi-3.9-20121203.jar ...

  6. 返回Json和XML两种格式

    由于项目需要,同一接口支持根据参数不同返回XML和Json两种格式的数据,在网上看了很多大多是加后缀的方式来实现返回不同格式数据的,后来看了一篇http://www.importnew.com/276 ...

  7. Android 两种注册、发送广播的区别

    前言:前面文章记录了Service的使用,这次来记录另一个四个组件之一的BroadcastReceiver.主要介绍两种发送和注册广播的区别. BroadcastReceiver广播接收者用于接收系统 ...

  8. 【Swfit】Swift与OC两种语法写单例的区别

    Swift与OC两种语法写单例的区别 例如写一个NetworkTools的单例 (1)OC写单例 + (instancetype)sharedNetworkTools { static id inst ...

  9. C# 用Serializer.ToXml()方法转换成两种格式的XML

    常见XML格式两种: 这种是属性的格式,实体的Model属性上面加上这个特性 [XmlAttribute] <AAA aa="/> 这种是标签的格式,实体的Model属性上面加上 ...

随机推荐

  1. 每日英语:Making the Most of Your Lunch Hour

    More Americans are eating lunch at their desks or even forgoing it altogether. Is passing up a prope ...

  2. NGUI的UISprite动态染色的一种方法

    本文主要参考iwinterice 的 NGUI的UISprite动态染色的一种解决方案 文章. 参考参考,就是既参详又拷贝,-,-||| 相关理论依据,还请去移步 NGUI的UISprite动态染色的 ...

  3. EntityFramework安装和EF升级方法

    例如:如何在vs2010上安装EntityFramework5.0? 首先,需要安装一个vs插件,名称为NuGet Package Manager,微软官方发布的,其作用就是为vs工程项目自动下载.安 ...

  4. 解决问题:swiper动态加载图片后无法滑动

    原因:swiper在初始化的时候会扫描swiper-wrapper下面的swiper-slide的个数,从而完成初始化,但是由于动态加载时在初始化之后的动作,所以导致无法滑动. 解决方案 1:在动态获 ...

  5. 结合order by 解CTF某题

    真tmd不容易 <?php error_reporting(0); if (!isset($_POST['uname']) || !isset($_POST['pwd'])) { echo '& ...

  6. iis部署wcf服务

    win8的如下 . 打开iis新建一个应用程序MyWcfTest 检查iis中的处理程序映射,含有svc说明激活了. 然后把svc文件和webconfig放入到指定的目录上. 使用地址http://l ...

  7. Linux nginx目录设置

    上一节记录了nginx的安装,这里来试着修改下配置文件. #user nobody; worker_processes 1; #error_log logs/error.log; #error_log ...

  8. centos7永久更改主机名

    操作环境: [root@bogon ~]# uname -a Linux #localhost.localdomain 3.10.0-514.el7.centos.plus.i686 #1 SMP W ...

  9. Spring security 用户,角色,权限,资源

    转自:http://blog.csdn.net/wybqq/article/details/52940194 关于Spring security对用户请求的处理过程 体现在这两个过程的体现. 关于用户 ...

  10. Unicode Character Set and UTF-8, UTF-16, UTF-32 Encoding

    在计算机内存中,统一使用unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为utf-8编码. 用记事本编辑的时候,从文件读取的utf-8字符被转换为unicode字符到内存里,编码完成保存 ...