這篇文章將介紹
Stagefright
中是如何和
OMX video decoder
傳遞
buffer
。
(1) OMXCodec
會在一開始的時候透過
read
函式來傳送未解碼的
data
給
decoder
,並且要求
decoder
將解碼後的
data
傳回來
status_t OMXCodec:
:
read
(
.
.
.
)
{
if
(
mInitialBufferSubmit)
{
mInitialBufferSubmit =
false
;
drainInputBuffers(
)
;
<----- OMX_EmptyThisBuffer
fillOutputBuffers(
)
;
<----- OMX_FillThisBuffer
}
.
.
.
}
void
OMXCodec:
:
drainInputBuffers(
)
{
Vector
<
BufferInfo>
*
buffers =
&
mPortBuffers[
kPortIndexInput]
;
for
(
i =
0;
i <
buffers-
>
size(
)
;
+
+
i)
{
drainInputBuffer(
&
buffers-
>
editItemAt(
i)
)
;
}
}
void
OMXCodec:
:
drainInputBuffer(
BufferInfo *
info)
{
mOMX-
>
emptyBuffer(
.
.
.
)
;
}
void
OMXCodec:
:
fillOutputBuffers(
)
{
Vector
<
BufferInfo>
*
buffers =
&
mPortBuffers[
kPortIndexOutput]
;
for
(
i =
0;
i <
buffers-
>
size(
)
;
+
+
i)
{
fillOutputBuffer(
&
buffers-
>
editItemAt(
i)
)
;
}
}
void
OMXCodec:
:
fillOutputBuffer(
BufferInfo *
info)
{
mOMX-
>
fillBuffer(
.
.
.
)
;
}
|
(2) Decoder
從
input port
讀取資料後,開始進行解碼,並且回傳
EmptyBufferDone
通知
OMXCodec
void
OMXCodec:
:
on_message(
const
omx_message &
msg)
{
switch
(
msg.
type)
{
case
omx_message:
:
EMPTY_BUFFER_DONE:
{
IOMX:
:
buffer_id buffer =
msg.
u.
extended_buffer_data.
buffer;
drainInputBuffer(
&
buffers-
>
editItemAt(
i)
)
;
}
}
}
|
OMXCodec
收到
EMPTY_BUFFER_DONE
之後,繼續傳送下一個未解碼的資料給
decoder
。
(3) Decoder
將解碼完的資料送到
output port
,並回傳
FillBufferDone
通知
OMXCodec
void
OMXCodec:
:
on_message(
const
omx_message &
msg)
{
switch
(
msg.
type)
{
case
omx_message:
:
FILL_BUFFER_DONE:
{
IOMX:
:
buffer_id buffer =
msg.
u.
extended_buffer_data.
buffer;
fillOutputBuffer(
info)
;
mFilledBuffers.
push_back(
i)
;
mBufferFilled.
signal
(
)
;
}
}
}
|
OMXCodec
收到
FILL_BUFFER_DONE
之後,將解碼後的資料放入
mFilledBuffers
,發出
mBufferFilled
信號,並且要求
decoder
繼續送出資料。
(4) read
函式在後段等待
mBufferFilled
信號。當
mFilledBuffers
被填入資料後,
read
函式將其指定給
buffer
指標,並回傳給
AwesomePlayer
status_t OMXCodec:
:
read
(
MediaBuffer *
*
buffer,
.
.
.
)
{
.
.
.
while
(
mFilledBuffers.
empty(
)
)
{
mBufferFilled.
wait(
mLock)
;
}
BufferInfo *
info =
&
mPortBuffers[
kPortIndexOutput]
.
editItemAt(
index)
;
info-
>
mMediaBuffer-
>
add_ref(
)
;
*
buffer =
info-
>
mMediaBuffer;
}