函数omx_maddec_component_BufferMgmtCallback

此函数是bellagio中mad组件的MP3解码函数。其参数是:

OMX_COMPONENTTYPE *openmaxStandComp,指向OpenMax的标准类型;

OMX_BUFFERHEADERTYPE* inputbuffer, 输入huffer,包含要解码的MP3数据;

OMX_BUFFERHEADERTYPE* outputbuffer,输出buffer,包含pcm内容。

1)首先是通过传入的参数读取组件私有数据结构:omx_maddec_component_Private = openmaxStandComp->pComponentPrivate,接下来的操作仅是对此私有类型的处理,这个私有类型很关键,属于内部数据不能被Client使用,这也是用户自己实现的部分,其实现不属于OpenMax的标准内容,在Bellagio中使用c写的,但是采用了面向对象的思想,存在一个继承关系;

image

2)isNewBuffer指示新的buffer的到达,如果一个输入buffer处理完了,需要重新获取一个新的buffer则需要将此参数值设为1,反之,为0,need_mad_stream指示是否需要新的mad stream,就是是否需要从输入输入buffer中获取数据到临时buffer;

3)这个私有类型有个成员为temporary_buffer,在组件初始化时,为其分配了一个OMX_BUFFERHEADERTYPE类型空间。

如果isNewBuffer和need_mad_stream的值都不为1,则进入12);

4)tocopy是MAD_BUFFER_MDLEN(mad.h里定义的),inputbuffer->nFilledLen(输入buffer中的字节数),MAD_BUFFER_MDLEN * 3 - temporary_buffer->nFilledLen,三者的最小值;

注意:结构体OMX_BUFFERHEADERTYPE中的几个成员的意义:

OMX_U8* pBuffer; 指向buffer中的数据块;

OMX_U32 nAllocLen; 此buffer分配的大小,即buffer得最大容量;

OMX_U32 nFilledLen;当前buffer中保存的数据大小;

OMX_U32 nOffset;已经处理的数据的大小,对于输入buffer也就是已经解码了的数据大小;

5)如果need_mad_stream数值不为1,跳到10);

6)参数temp_input_buffer也是私有类型的成员,在组件初始化时将其保存temporary_buffer->pBuffer的值;

7)memmove将temporary_buffer->pBuffer复制到temp_input_buffer,长度为temporary_buffer->nFilledLen;复制完成后又将temp_input_buffer赋给temporary_buffer->pBuffer,将need_mad_stream值设为0;

在此temp_input_buffer相当于一个中转站,memmove,是转移,原先的不保留。

8)又调用memcpy(很有意思啊):(复制,原先的还是要保留的)

memcpy(temporary_buffer->pBuffer+temporary_buffer->nFilledLen,inputbuffer->pBuffer + inputbuffer->nOffset, tocopy)

完成复制后要接着更新temporary_buffer->nFilledLen的数值加上tocopy;

inputbuffer->nFilledLen -= tocopy;也将输入buffer中数据长度更新。 现存的减少,
inputbuffer->nOffset += tocopy;已经处理的增加。

9)isNewBuffer设置为0;

调用mad的函数mad_stream_buffer,无返回值,此函数的参数:

stream指向mad.h的结构体mad_stream;

temporary_buffer->pBuffer,临时buffer中的存储数据的buffer指针;

temporary_buffer->nFilledLen,长度。

这个函数是将temporary_buffer->pBuffer的数据保存到mad_stream中,供后面的解码处理(?觉得是这样,具体以后再看)

10) 如果inputbuffer->nFilledLen为0,说明当前输入buffer已经处理完了,下次需要新的输入buffer,将isNewBuffer设置为1;inputbuffer->nOffset置为0;

11) 调用mad_header_decode,解码头,返回值类型是int,属于libmad中的API函数,

参数:

&(frame->header):header(mad_header)的地址;

stream:指向mad_stream的指针。如果返回出错则调用相应的错误处理函数mad_stream_errorstr

12) 调用mad_frame_decode,返回值类型是int,解码mad_stream中的数据,属于libmad中的API函数;

参数:

frame和stream,想要移植libmad,必须实现这两个并正确配置参数;

13) 如果没出错(返回值不为-1),跳到14),错误类型是在libmad中定义的:

13.1

如果错误代码是MAD_ERROR_BUFLEN,说明输入的buffer太小,

A:判断temporary_buffer->pBuffer和stream->next_frame是否相等,如果相等,将need_mad_stream置为1,函数返回(return);

B:如果不相等,检查consumed的值(stream->next_frame-temporary_buffer->pBuffer),(怎么理解consumed?目前是已经解码的字节数)并更新数目,函数返回(return);

13.2

如果错误代码是MAD_ERROR_LOSTSYNC,说明同步丢失了,

调用函数id3_tag_query(stream->this_frame, stream->bufend - stream->this_frame),返回tagsize(signed long);

再调用mad_stream_skip(stream, tagsize)貌似是跳过擦长度为tagsize部分啊

14) 获取nsamples(采样率)和nchannels(声道),并判断是否与私有类型中的pAudioMp3和pAudioPcmMode对应值是否相等,如果不等,则更新pAudioMp3和pAudioPcmMode中的对应值;

15) mad_synth_frame,libmad的API函数,函数参数是:

Ø synth

Ø frame

此函数是将解码后的音频数据合成为PCM采样;

16) 根据声道数,对输出buffer进行赋值;

17) 计算解码的字节数,并更新临时buffer中的长度量,函数结束。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值