解密硬件解码关键技术

通过上一篇文章,我们用ffmpeg分离出一个多媒体容器中的音视频数据,但是很可能这些数据是不能被正确解码的。为什么呢?因为在解码这些数据之前,需要对解码器做一些配置,典型的就是目前流行的高清编码“黄金搭档”组合H264 + AAC的搭配。本文将讲述H264和AAC的关键解码配置参数的解析,如果没有这些配置信息,数据帧往往不完整,导致了解码器不能解码。

  • H264的配置信息解析

    前面我们知道,ffmpeg的avformat_find_stream_info函数可以取得音视频媒体多种,比如播放持续时间、音视频压缩格式、音轨信息、字幕信息、帧率、采样率等。在信息结果中有一项扩展数据描述(avcodec.h文件中):

AVCodecContext定义如下:

如果视频流是H264,这个extradate里面就包含了H264的配置信息,这个扩展数据有如下定义:

详细解释可以参考“ISO-14496-15 AVC file format”文档。里面最重要的就是NAL长度和SPS,PPS数据和对应的长度信息。对该数据的解析在ffmpeg里面有现成的函数:ff_h264_decode_extradata,在我的项目里面是自己写的扩展数据解析。

  • AAC的配置信息解析及设置

    如果音频数据是AAC流,在解码时需要ADTS(Audio Data Transport Stream)头部,不管是容器封装还是流媒体,没有这个,一般都是不能播放的。很多朋友在做AAC流播放时遇到播不出声音,很可能就是这个原因导致。

    ADTS所需的数据仍然是放在上面的扩展数据extradata中,我们需要先解码这个扩展数据,然后再从解码后的数据信息里面重新封装成ADTS头信息,加到每一帧AAC数据之前再送解码器,这样就可以正常解码了。

    extradate数据定义如下:

    详细信息及说明请参考“ISO-IEC-14496-3 (Audio)”的AudioSpecificConfig部分。里面最重要的部分有采样频率、通道配置和音频对象类型,这几个一般都是AAC解码器需要的配置参数。

    这个数据在ffmpeg中也有相应的解码函数:avpriv_aac_parse_header。在我的项目中,我没有使用这个函数,而是自己实现的:


  • 1

    2

    3

    4

    5

    6

    7

    typedef struct

    {

          int write_adts;

          int objecttype;

          int sample_rate_index;

          int channel_conf;

    }ADTSContext;

      


    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    int aac_decode_extradata(ADTSContext *adts, unsigned char *pbuf, int bufsize)

    {

          int aot, aotext, samfreindex;

          int i, channelconfig;

          unsigned char *p = pbuf;

       

          if (!adts || !pbuf || bufsize<2)

          {

                return -1;

          }

          aot = (p[0]>>3)&0x1f;

          if (aot == 31)

          {

                aotext = (p[0]<<3 | (p[1]>>5)) & 0x3f;

                aot = 32 + aotext;

                samfreindex = (p[1]>>1) & 0x0f;

                 

                if (samfreindex == 0x0f)

                {

                      channelconfig = ((p[4]<<3) | (p[5]>>5)) & 0x0f;

                }

                else

                {

                      channelconfig = ((p[1]<<3)|(p[2]>>5)) & 0x0f;

                }

          }

          else

          {

                samfreindex = ((p[0]<<1)|p[1]>>7) & 0x0f;

                if (samfreindex == 0x0f)

                {

                      channelconfig = (p[4]>>3) & 0x0f;

                }

                else

                {

                      channelconfig = (p[1]>>3) & 0x0f;

                }

          }

       

    #ifdef AOT_PROFILE_CTRL

          if (aot < 2) aot = 2;

    #endif

          adts->objecttype = aot-1;

          adts->sample_rate_index = samfreindex;

          adts->channel_conf = channelconfig;

          adts->write_adts = 1;

       

          return 0;

    }

      

    上面的pbuf就是extradata。

    接下来,再用ADTSContext数据编码为ADTS头信息插入每一个AAC帧前面:


  • 1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    int aac_set_adts_head(ADTSContext *acfg, unsigned char *buf, int size)

    {      

          unsigned char byte;

       

          if (size < ADTS_HEADER_SIZE)

          {

                return -1;

          }

           

          buf[0] = 0xff;

          buf[1] = 0xf1;

          byte = 0;

          byte |= (acfg->objecttype & 0x03) << 6;

          byte |= (acfg->sample_rate_index & 0x0f) << 2;

          byte |= (acfg->channel_conf & 0x07) >> 2;

          buf[2] = byte;

          byte = 0;

          byte |= (acfg->channel_conf & 0x07) << 6;

          byte |= (ADTS_HEADER_SIZE + size) >> 11;

          buf[3] = byte;

          byte = 0;

          byte |= (ADTS_HEADER_SIZE + size) >> 3;

          buf[4] = byte;

          byte = 0;

          byte |= ((ADTS_HEADER_SIZE + size) & 0x7) << 5;

          byte |= (0x7ff >> 6) & 0x1f;

          buf[5] = byte;

          byte = 0;

          byte |= (0x7ff & 0x3f) << 2;

          buf[6] = byte;

       

          return 0;

    }

      

    这个头部是固定的7字节长度,所以可提前空出这7个字节供ADTS占用。

    通过以上对H264和AAC的扩展数据处理,播放各种“黄金搭档”的多媒体文件、流媒体、视频点播等都应该没有问题了。

      想第一时间获得更多原创文章,请关注个人微信公众平台:程序员互动联盟(coder_online),扫一扫下方二维码或者搜索微信号coder_online即可关注,里面有大量Android,Chromium,Linux等相关文章等着您,我们还可以在线交流。

    摘自:http://my.oschina.net/u/2336532/blog/400790

时间: 2024-10-01 03:35:32

解密硬件解码关键技术的相关文章

硬件解码关键技术剖析

通过上一篇文章,我们用ffmpeg分离出一个多媒体容器中的音视频数据,但是很可能这些数据是不能被正确解码的.为什么呢?因为在解码这些数据之前,需要对解码器做一些配置,典型的就是目前流行的高清编码"黄金搭档"组合H264 + AAC的搭配.本文将讲述H264和AAC的关键解码配置参数的解析,如果没有这些配置信息,数据帧往往不完整,导致了解码器不能解码. H264的配置信息解析 前面我们知道,ffmpeg的avformat_find_stream_info函数可以取得音视频媒体多种,比如播

(1)RGB-D SLAM系列- 工具篇(硬件+关键技术)

/*********************************************************************************************************** .....从前,一种叫WALL-E的小机器人被送往地球清除垃圾,但WALL-E并不适合地球的环境,大批量地来也大批量地坏,最后只剩下WALL Tang还在日复一日的按照程序收拾废品.就这么过了几百年,仅存的WALL Tang还在垃圾堆里淘到不少人造宝贝,它也开始有了自我意识,懂得什

聊聊推送的架构及关键技术实现

推送是在日常终端使用场景中经常碰到,特别是移动互联网普及之后,手机终端成为了消息推送的主战场,例如生活服务类的优惠券推送,咨询类的新闻推送,电商类的购物推送等等,在业务用户触达上起到了至关重要的作用,那我们今天就来揭开一下推送这个隐藏在业务背景之下的技术实现 系统架构及模块介绍 这是一个比较完整的推送业务架构图,分为三个部分:业务层.通道层和客户端常驻服务,一般来说客户端常驻服务和通道层维持一个长连接通道实现数据的双向传递,而业务层实现的是基于推送业务形态的展示,例如推送的定时任务推送,接口推送

Android应用程序UI硬件加速渲染技术简要介绍和学习计划

Android系统的流畅性一直被拿来与iOS比较,并且认为不如后者.这一方面与Android设备硬件质量参差不齐有关,另一方面也与Android系统的实现有关.例如在3.0前,Android应用程序UI绘制不支持硬件加速.不过从4.0开始,Android系统一直以"run fast, smooth, and responsively"为目标对UI进行优化.本文对这些优化进行简要介绍和制定学习计划. 老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注!

c++实现加密和解密算法以及JNI技术的应用实例

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

实时视频应用之QoS关键技术分析

转自:http://www.aiweibang.com/m/detail/104476372.html?from=p 随着WebRTC标准的逐步推广,实时音视频通讯技术受到越来越多公司和技术人员的关注.对于交互式音视频应用而言,稳定.低延时.通话质量清晰可靠是其基本需求.在互联网环境下,音视频的通话质量与以下因素有关:一是编码码率.帧率和分辨率等编码因素:二是网络的接入类型和接入设备性能:三是对丢包.抖动.乱序以及网络拥塞的自适应调整能力,即QoS(Quality of Service,服务质量

大数据流式计算:关键技术及系统实例

孙大为1, 张广艳1,2, 郑纬民1 摘要:大数据计算主要有批量计算和流式计算两种形态,目前,关于大数据批量计算系统的研究和讨论相对充分,而如何构建低延迟.高吞吐且持续可靠运行的大数据流式计算系统是当前亟待解决的问题且研究成果和实践经验相对较少.总结了典型应用领域中流式大数据所呈现出的实时性.易失性.突发性.无序性.无限性等特征,给出了理想的大数据流式计算系统在系统结构.数据传输.应用接口.高可用技术等方面应该具有的关键技术特征,论述并对比了已有的大数据流式计算系统的典型实例,最后阐述了大数据流

ARM流水线关键技术分析与代码优化

引 言    流水线技术通 过多个功能部件并行工作来缩短程序执行时间,提高处理器核的效率和吞吐率,从而成为微处理器设计中最为重要的技术之一.ARM7处理器核使用了典型三级流 水线的冯·诺伊曼结构,ARM9系列则采用了基于五级流水线的哈佛结构.通过增加流水线级数简化了流水线各级的逻辑,进一步提高了处理器的性能. ARM7的三级流水线在执行单元完成了大量的工作,包括与操作数相关的寄存器和存储器读写操作.ALU操作以及相关器件之间的数据传输.执行单元的工作往 往占用多个时钟周期,从而成为系统性能的瓶颈

大数据引发混合云井喷,了解四大场景与三大关键技术

进入2018年,我国大数据应用产业正在迎来爆发式增长的一年.作为第五次进入政府工作报告的关键词,大数据已经从国家战略高度到产业发展规划再到具体的发展行动,形成了系统布局.全面扩散.整体爆发之势.2017年底,在"大数据是信息化发展新阶段"的论断下,作为底层技术平台的混合云即将在2018年迎来井喷式发展. 赛迪顾问在"2018中国IT市场年会"上预测,混合云.Docker等技术在2018年将进入规模化部署期.而混合云技术的灵活性可极大提高工作负载,很多大型企业希望私有