ffmpeg中,硬解码VP8 时,如何将 AVPacket拆解,按照OMX_BUFFERFLAG_ENDOFSUBFRAME ,将数据多次送给硬解解码器,OMXIL 例子
时间: 2024-06-12 12:04:26 浏览: 137
1. 首先需要设置解码器的输入格式和输出格式,可以使用OMX_SetParameter函数来设置参数。
2. 接着需要创建一个OMX_BUFFERHEADERTYPE类型的缓冲区结构体,用于存储输入数据。
3. 将AVPacket中的数据按照OMX_BUFFERFLAG_ENDOFSUBFRAME进行拆分,每次拆分后将数据填充到缓冲区中,并设置OMX_BUFFERFLAG_ENDOFSUBFRAME标记。
4. 调用OMX_EmptyThisBuffer函数将缓冲区中的数据送给解码器。
5. 解码器将解码后的数据存储到另外一个OMX_BUFFERHEADERTYPE类型的缓冲区结构体中,可以使用OMX_FillThisBuffer函数将该缓冲区发送给解码器。
6. 循环执行上述步骤,直到AVPacket中的所有数据都被解码。
以下是一个简单的示例代码:
```
OMX_BUFFERHEADERTYPE* pBufferIn = NULL;
OMX_BUFFERHEADERTYPE* pBufferOut = NULL;
// 设置解码器输入格式和输出格式
OMX_VIDEO_PARAM_PORTFORMATTYPE formatIn;
OMX_INIT_STRUCTURE(formatIn);
formatIn.eCompressionFormat = OMX_VIDEO_CodingVP8;
formatIn.eColorFormat = OMX_COLOR_FormatUnused;
OMX_SetParameter(hDecoder, OMX_IndexParamVideoPortFormat, &formatIn);
OMX_VIDEO_PARAM_PORTFORMATTYPE formatOut;
OMX_INIT_STRUCTURE(formatOut);
formatOut.eCompressionFormat = OMX_VIDEO_CodingUnused;
formatOut.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
OMX_SetParameter(hDecoder, OMX_IndexParamVideoPortFormat, &formatOut);
// 创建输入缓冲区
OMX_ALLOCATE_BUFFER(hDecoder, &pBufferIn, OMX_VIDEO_PORT_INPUT, pAppData, nInputBufferSize);
// 创建输出缓冲区
OMX_ALLOCATE_BUFFER(hDecoder, &pBufferOut, OMX_VIDEO_PORT_OUTPUT, pAppData, nOutputBufferSize);
AVPacket packet;
// 将AVPacket中的数据按照OMX_BUFFERFLAG_ENDOFSUBFRAME进行拆分
while (av_read_frame(formatCtx, &packet) >= 0) {
uint8_t* pData = packet.data;
int nDataSize = packet.size;
int nPos = 0;
while (nPos < nDataSize) {
int nCopySize = nDataSize - nPos;
if (nCopySize > nInputBufferSize) {
nCopySize = nInputBufferSize;
}
memcpy(pBufferIn->pBuffer, pData + nPos, nCopySize);
pBufferIn->nOffset = 0;
pBufferIn->nFilledLen = nCopySize;
if (nPos + nCopySize == nDataSize) {
// 最后一帧数据
pBufferIn->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS;
} else {
pBufferIn->nFlags |= OMX_BUFFERFLAG_ENDOFSUBFRAME;
}
nPos += nCopySize;
OMX_EmptyThisBuffer(hDecoder, pBufferIn);
}
av_packet_unref(&packet);
}
// 发送解码器结束标记
pBufferIn->nFlags = OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS;
OMX_EmptyThisBuffer(hDecoder, pBufferIn);
// 读取解码后的数据
OMX_BUFFERHEADERTYPE* pOutputBuf = NULL;
OMX_ERRORTYPE err = OMX_GetOutput(hDecoder, OMX_VIDEO_PORT_OUTPUT, &pOutputBuf, 0);
while (err == OMX_ErrorNone && pOutputBuf) {
// 处理解码后的数据
...
OMX_FillThisBuffer(hDecoder, pOutputBuf);
err = OMX_GetOutput(hDecoder, OMX_VIDEO_PORT_OUTPUT, &pOutputBuf, 0);
}
// 销毁缓冲区
OMX_FreeBuffer(hDecoder, OMX_VIDEO_PORT_INPUT, pBufferIn);
OMX_FreeBuffer(hDecoder, OMX_VIDEO_PORT_OUTPUT, pBufferOut);
```
阅读全文