vlc | branch: master | Duncan McNamara <[email protected]> | Mon May 23 09:34:43 2016 +0200| [a34c4303e95b4f4cf94c3f1e01581cc40bd3429a] | committer: Thomas Guillem
mediacodec: add vc1/wmv3 support Signed-off-by: Thomas Guillem <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=a34c4303e95b4f4cf94c3f1e01581cc40bd3429a --- modules/codec/omxil/mediacodec.c | 106 ++++++++++++++++++++++++++++++++++++-- modules/codec/omxil/utils.c | 5 -- 2 files changed, 102 insertions(+), 9 deletions(-) diff --git a/modules/codec/omxil/mediacodec.c b/modules/codec/omxil/mediacodec.c index 81ba449..47292aa 100644 --- a/modules/codec/omxil/mediacodec.c +++ b/modules/codec/omxil/mediacodec.c @@ -332,6 +332,70 @@ static int H264SetCSD(decoder_t *p_dec, void *p_buf, size_t i_size, return VLC_EGENERIC; } +static int ParseVideoExtraVc1(decoder_t *p_dec, uint8_t *p_extra, int i_extra) +{ + int offset = 0; + struct csd csd; + + if (i_extra < 4) + return VLC_EGENERIC; + + /* Initialisation data starts with : 0x00 0x00 0x01 0x0f */ + /* Skipping unecessary data */ + static const uint8_t vc1_start_code[4] = {0x00, 0x00, 0x01, 0x0f}; + for (; offset < i_extra - 4 ; ++offset) + { + if (!memcmp(&p_extra[offset], vc1_start_code, 4)) + break; + } + + /* Could not find the sequence header start code */ + if (offset >= i_extra - 4) + return VLC_EGENERIC; + + csd.i_size = i_extra - offset; + csd.p_buf = p_extra + offset; + + return CSDDup(p_dec, &csd, 1); +} + +static int ParseVideoExtraWmv3(decoder_t *p_dec, uint8_t *p_extra, int i_extra) +{ + /* WMV3 initialisation data : + * 8 fixed bytes + * 4 extradata bytes + * 4 height bytes (little endian) + * 4 width bytes (little endian) + * 16 fixed bytes */ + + if (i_extra < 4) + return VLC_EGENERIC; + + uint8_t p_data[36] = { + 0x8e, 0x01, 0x00, 0xc5, /* Fixed bytes values */ + 0x04, 0x00, 0x00, 0x00, /* Same */ + 0x00, 0x00, 0x00, 0x00, /* extradata emplacement */ + 0x00, 0x00, 0x00, 0x00, /* height emplacement (little endian) */ + 0x00, 0x00, 0x00, 0x00, /* width emplacement (little endian) */ + 0x0c, 0x00, 0x00, 0x00, /* Fixed byte pattern */ + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + + struct csd csd; + + csd.i_size = sizeof(p_data); + /* Adding extradata */ + memcpy(&p_data[8], p_extra, 4); + /* Adding height and width, little endian */ + SetDWLE(&(p_data[12]), p_dec->fmt_in.video.i_height); + SetDWLE(&(p_data[16]), p_dec->fmt_in.video.i_width); + + csd.p_buf = p_data; + return CSDDup(p_dec, &csd, 1); +} + static int ParseVideoExtra(decoder_t *p_dec, uint8_t *p_extra, int i_extra) { decoder_sys_t *p_sys = p_dec->p_sys; @@ -371,6 +435,14 @@ static int ParseVideoExtra(decoder_t *p_dec, uint8_t *p_extra, int i_extra) /* FIXME: what to do with AnnexB ? */ } } + else if (p_dec->fmt_in.i_codec == VLC_CODEC_WMV3) + { + return ParseVideoExtraWmv3(p_dec, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra); + } + else if (p_dec->fmt_in.i_codec == VLC_CODEC_VC1) + { + return ParseVideoExtraVc1(p_dec, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra); + } return VLC_SUCCESS; } @@ -518,7 +590,8 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init) { if (!p_dec->fmt_in.video.i_width || !p_dec->fmt_in.video.i_height) { - /* We can handle h264 without a valid video size */ + /* We can handle h264 without a valid video size + * TODO handle VC1 with no size */ if (p_dec->fmt_in.i_codec != VLC_CODEC_H264) { msg_Dbg(p_dec, "resolution (%dx%d) not supported", @@ -586,9 +659,24 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init) } if (api->configure(api, i_h264_profile) != 0) { - api->clean(api); - free(api); - return VLC_EGENERIC; + /* If the device can't handle video/wvc1, + * it can probably handle video/x-ms-wmv */ + if (!strcmp(mime, "video/wvc1") && p_dec->fmt_in.i_codec == VLC_CODEC_VC1) + { + api->psz_mime = "video/x-ms-wmv"; + if (api->configure(api, i_h264_profile) != 0) + { + api->clean(api); + free(api); + return (VLC_EGENERIC); + } + } + else + { + api->clean(api); + free(api); + return VLC_EGENERIC; + } } /* Allocate the memory needed to store the decoder's structure */ @@ -1486,6 +1574,16 @@ static int Video_OnNewBlock(decoder_t *p_dec, block_t *p_block, int *p_flags) else return 0; /* Drop current block */ } + else if (p_dec->fmt_in.i_codec == VLC_CODEC_VC1) + { + /* Adding frame start code */ + if (!block_Realloc(p_block, 4, p_block->i_buffer)) + return VLC_ENOMEM; + p_block->p_buffer[0] = 0x00; + p_block->p_buffer[1] = 0x00; + p_block->p_buffer[2] = 0x01; + p_block->p_buffer[3] = 0x0d; + } if (b_csd_changed) { diff --git a/modules/codec/omxil/utils.c b/modules/codec/omxil/utils.c index e9d3945..37e8546 100644 --- a/modules/codec/omxil/utils.c +++ b/modules/codec/omxil/utils.c @@ -301,11 +301,6 @@ bool OMXCodec_IsBlacklisted( const char *p_name, unsigned int i_name_len ) * sensible latency. (Also, even if that one isn't found, in general, * using SW codecs is usually more than fast enough for MP3.) */ "OMX.SEC.MP3.Decoder", - /* This codec should be able to handle both VC1 and WMV3, but - * for VC1 it doesn't output any buffers at all (in the way we use - * it) and for WMV3 it outputs plain black buffers. Thus ignore - * it until we can make it work properly. */ - "OMX.Nvidia.vc1.decode", /* black screen */ "OMX.MTK.VIDEO.DECODER.VC1", /* Not working or crashing (Samsung) */ _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
