多码流RM文件的解析

单码流与多码流分析

       VOD4.6客户端不支持rm10的播放,通过分析发现rm10文件是多码流的,它的各条数据流按块分布,与以前的单码流音视频交错分布不同。而有些rm9的文件也是多码流的,所以不能播放的原因是单、多码流的不同。

       单码流和多码流不只是数据分布的不同,它们的头部也有很大的不同。

       MDPR部分:在单码流中每一个流对应一个MDPR,在多码流中也是如此,但是所不同的是,多码流多了LogicalStream,音视频各拥有一个LogicalStream,可以凭借这一点分辨单、多码流,LogicalStream中主要记录了音频或视频所包含实际的物理流以及每条流的起始地址等等。数据结构如下:

class LogicalStream

{

    UINT32  size;

    UINT16  object_version;

    UINT16  num_physical_streams;

    UINT16  *physical_stream_numbers;

    UINT32  *data_offsets;

    UINT16  num_rules;

    UINT16  *rule_to_physical_stream_number_map;

    UINT16  num_properties;

    NameValueProperty       *properties;

};

       DATA部分:单码流一般只有一个DATA,而多码流每对应一个流就有一个DATA,但这也不是一定的,个别的流可能只有MDPR,但是没有DATA。多DATA与多码流的按块分布是很一致的。

class DataHeader

{

   UINT32  object_id;

   UINT32  size;

   UINT16  object_version;

   UINT32  num_interleave_packets;

   UINT32  next_data_header;

};

class PacketHeader

{

   UINT16  object_version;

   UINT16  length;

   UINT16  stream_number;

   UINT32  timestamp;

   UINT16  flags;

};

 

typedef PacketHeader * PacketHeaderPtr;

class PacketHeader1

{

   UINT16  object_version;

   UINT16  length;

   UINT16  stream_number;

   UINT32  timestamp;

   UINT16  asm_rule;

   UINT8    asm_flags;

};

       以上是DATA部分的数据结构,DataHeader部分是相同的,而PacketHeader是用于单码流的,PacketHeader1是用于多码流的,注意:两者的大小相差一个字节。就是这点造成的VOD4.6一点图像都显示不出来。后来通过试验证明了PacketHeader后两者的实际数据部分结构是完全相同的。

       在DATA部分还有一点要注意的是,上面的asm_flags用来判断是否关键帧。对于Video

,在单码中flag值为2代表是关键帧,而多码流2或3都为关键帧;对于Audio,多码流与单码流不同的是,flag总为3,是否关键帧由asm_rule来决定,asm_rule为00是关键帧,01则是非关键帧。

      

VOD4.8中对于多码流的支持

       单码流跟多码流的区别还不止于此,但是要支持多码流的播放,知道以上的区别就足够了。

       首先,根据是否有LogicalStream,可以判断是否多码流。如果是的话,就要解析出LogicalStream结构中有用的字段,如 num_physical_streams     physical_stream_numbersdata_offsets

       然后按照一定的规则为音视频各选择一条流用于播放,接着就引发了一个问题,在以前的文件中,音频与视频是按照一定得比例交错分布的,那时我们不用考虑何时读音频何时读视频,只有一个DATA,从头到尾读就行了,但是由于多码流的音频与视频不是交错分布的,这样的话,如果还是按照这个模式,那就读完视频,才读音频,这样显然不行,解决的办法是再增加一个线程用于接收数据,原来的接收线程我们可以让它只接受视频数据,增加的线程用来接收音频数据。我们再对两个接收线程加以控制,让它们按照一定的条件去读,保持音视频的同步就可以了。

       还有要注意的是,PacketHeader、关键帧和Seek的问题。PacketHeader、关键帧照前面的分析改写,进行兼容性操作,对于Seek,以前是以视频流为主流,由于交错分布,音频跟着就读出来了,但是现在不行了,要音视频分别Seek,注意要以视频的timestamp为准,否则拖拽时就要出现画面迟钝。

       最后,由于音视频分别读取,要注意,每个接收线程都要有一个dataOffset,而两个线程都要完成才能表示文件结束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值