出自: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. javascript基础拾遗(十三)

    1.jQuery的特点 jQuery是目前非常流行的javascript库,理念是"Write Less,Do More" 1)消除浏览器差异 2)简洁的操作DOM方法 3)轻松实 ...

  2. ksoap2调用webservice传递参数丢失

    参数有顺序要求,顺序设置正确即可.

  3. vs2015配置OpenGL开发环境

    先吐槽下,不知道微软怎么整的,从win7开始,OpenGL的头文件更改到windows SDK中,不安装就不能用. 更搞笑的是,在win10下,vs2015安装还报win sdk安装失败,这典型的自己 ...

  4. TNS-12518,TNS-12536,TNS-00506,Linux Error: 11: Resource temporarily unavailable

    TNS-12518: TNS:listener could not hand off client connection TNS-12536: TNS:operation would block  T ...

  5. python 使用pillow将图片转换为webp格式

    1.webp格式 webp格式是谷歌开发的一种旨在加快图片加载速度的格式,将图片转为webp格式后,体积约为原来的2/3,这可以节省大量的服务器带宽,微信公众号文章里的图片就是这种格式的. 2.使用p ...

  6. 2. EM算法-原理详解

    1. EM算法-数学基础 2. EM算法-原理详解 3. EM算法-高斯混合模型GMM 4. EM算法-高斯混合模型GMM详细代码实现 5. EM算法-高斯混合模型GMM+Lasso 1. 前言 概率 ...

  7. iis下php 500错误

      很不想用iis,然而客户不想增加机器,只好按客户的意思了.可是没想到发送短信以在本地 机器上是好的,在iis下直接500.   一开始以为是防火墙问题,后来检查了一下没有,再后来换了一个短信接口, ...

  8. DB2安装过程中可能遇到的错误

    WARNING:DBT3534W  The db2prereqcheck utility determined that ASLR is set to ON and that this could c ...

  9. flume 多chanel配置

    #配置文 a1.sources= r1 a1.sinks= k1 k2 a1.channels= c1 c2 #Describe/configure the source a1.sources.r1. ...

  10. JedisConnectionPool scala

    /** * Created by lq on 2017/8/29. */ object JedisConnectionPool { val config = new JedisPoolConfig() ...