Commit a8e6ff47 authored by Martin Storsjö's avatar Martin Storsjö Committed by Jean-Baptiste Kempf

omxil: Pass extradata for WMV3 according to OMX specs

Some OMX decoders that can handle WMV3 (such as the broadcom one
in raspberry pi) can handle the WMV3 extradata both in the original
form as in ASF, and in this format, while the one in Samsung Galaxy
S3 requires it to be in this format (as the OMX IL 1.2 specs specify).

This makes HW-accelerated WMV3 decoding work on Galaxy S3.

The code can be split out to a reusable function if/when the same
needs to be done elsewhere.
Signed-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
parent 8e79d242
...@@ -1081,6 +1081,37 @@ loaded: ...@@ -1081,6 +1081,37 @@ loaded:
p_header->pOutputPortPrivate = p_header->pBuffer; p_header->pOutputPortPrivate = p_header->pBuffer;
p_header->pBuffer = p_dec->fmt_in.p_extra; p_header->pBuffer = p_dec->fmt_in.p_extra;
} }
else if (p_dec->fmt_in.i_codec == VLC_CODEC_WMV3 &&
p_dec->fmt_in.i_extra >= 4 &&
p_header->nAllocLen >= 36)
{
int profile;
// According to OMX IL 1.2.0 spec (4.3.33.2), the codec config
// data for VC-1 Main/Simple (aka WMV3) is according to table 265
// in the VC-1 spec. Most of the fields are just set with placeholders
// (like framerate, hrd_buffer/rate).
static const uint8_t wmv3seq[] = {
0xff, 0xff, 0xff, 0xc5, // numframes=ffffff, marker byte
0x04, 0x00, 0x00, 0x00, // marker byte
0x00, 0x00, 0x00, 0x00, // struct C, almost equal to p_extra
0x00, 0x00, 0x00, 0x00, // struct A, vert size
0x00, 0x00, 0x00, 0x00, // struct A, horiz size
0x0c, 0x00, 0x00, 0x00, // marker byte
0xff, 0xff, 0x00, 0x80, // struct B, level=4, cbr=0, hrd_buffer=ffff
0xff, 0xff, 0x00, 0x00, // struct B, hrd_rate=ffff
0xff, 0xff, 0xff, 0xff, // struct B, framerate=ffffffff
};
p_header->nFilledLen = sizeof(wmv3seq);
memcpy(p_header->pBuffer, wmv3seq, p_header->nFilledLen);
// Struct C - almost equal to the extradata
memcpy(&p_header->pBuffer[8], p_dec->fmt_in.p_extra, 4);
// Expand profile from the highest 2 bits to the highest 4 bits
profile = p_header->pBuffer[8] >> 6;
p_header->pBuffer[8] = (p_header->pBuffer[8] & 0x0f) | (profile << 4);
// Fill in the height/width for struct A
SetDWLE(&p_header->pBuffer[12], p_dec->fmt_in.video.i_height);
SetDWLE(&p_header->pBuffer[16], p_dec->fmt_in.video.i_width);
}
else else
{ {
if(p_header->nFilledLen > p_header->nAllocLen) if(p_header->nFilledLen > p_header->nAllocLen)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment