Commit 20df8f9c authored by Thomas Guillem's avatar Thomas Guillem

omx: add OMXCodec_GetQuirks

This function returns of list of hacks that are needed for codec
initialization, and also include IgnoreOmxDecoderPadding hack.

Remove OMX.MTK.VIDEO.DECODER.MPEG4 from blacklist since it only need a valid
CSD.
parent 9258870f
...@@ -100,6 +100,7 @@ struct decoder_sys_t ...@@ -100,6 +100,7 @@ struct decoder_sys_t
bool error_state; bool error_state;
bool b_new_block; bool b_new_block;
int64_t i_preroll_end; int64_t i_preroll_end;
int i_quirks;
/* Specific Audio/Video callbacks */ /* Specific Audio/Video callbacks */
dec_on_new_block_cb pf_on_new_block; dec_on_new_block_cb pf_on_new_block;
...@@ -585,24 +586,17 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init) ...@@ -585,24 +586,17 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init)
if (!p_sys->psz_name) if (!p_sys->psz_name)
goto bailout; goto bailout;
/* Check if we need late opening */ p_sys->i_quirks = OMXCodec_GetQuirks( VIDEO_ES,
switch (p_dec->fmt_in.i_codec) p_dec->fmt_in.i_codec,
p_sys->psz_name,
strlen(p_sys->psz_name) );
if ((p_sys->i_quirks & OMXCODEC_VIDEO_QUIRKS_NEED_SIZE)
&& (!p_sys->u.video.i_width || !p_sys->u.video.i_height))
{ {
case VLC_CODEC_H264: msg_Warn(p_dec, "waiting for a valid video size for codec %4.4s",
if (!p_sys->u.video.i_width || !p_sys->u.video.i_height) (const char *)&p_dec->fmt_in.i_codec);
{ return VLC_SUCCESS;
msg_Warn(p_dec, "waiting for sps/pps for codec %4.4s",
(const char *)&p_dec->fmt_in.i_codec);
return VLC_SUCCESS;
}
case VLC_CODEC_VC1:
if (!p_dec->fmt_in.i_extra)
{
msg_Warn(p_dec, "waiting for extra data for codec %4.4s",
(const char *)&p_dec->fmt_in.i_codec);
return VLC_SUCCESS;
}
break;
} }
} }
else else
...@@ -616,30 +610,24 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init) ...@@ -616,30 +610,24 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init)
if (!p_sys->psz_name) if (!p_sys->psz_name)
goto bailout; goto bailout;
/* Marvel ACodec assert if channel count is 0 */ p_sys->i_quirks = OMXCodec_GetQuirks( AUDIO_ES,
if (!strncmp(p_sys->psz_name, "OMX.Marvell", p_dec->fmt_in.i_codec,
__MIN(strlen(p_sys->psz_name), strlen("OMX.Marvell")))) p_sys->psz_name,
p_sys->u.audio.b_need_channels = true; strlen(p_sys->psz_name) );
if ((p_sys->i_quirks & OMXCODEC_AUDIO_QUIRKS_NEED_CHANNELS)
/* Check if we need late opening */ && !p_sys->u.audio.i_channels)
switch (p_dec->fmt_in.i_codec)
{
case VLC_CODEC_VORBIS:
case VLC_CODEC_MP4A:
if (!p_dec->fmt_in.i_extra)
{
msg_Warn(p_dec, "waiting for extra data for codec %4.4s",
(const char *)&p_dec->fmt_in.i_codec);
return VLC_SUCCESS;
}
break;
}
if (!p_sys->u.audio.i_channels && p_sys->u.audio.b_need_channels)
{ {
msg_Warn(p_dec, "waiting for valid channel count"); msg_Warn(p_dec, "waiting for valid channel count");
return VLC_SUCCESS; return VLC_SUCCESS;
} }
} }
if ((p_sys->i_quirks & OMXCODEC_QUIRKS_NEED_CSD)
&& !p_dec->fmt_in.i_extra)
{
msg_Warn(p_dec, "waiting for extra data for codec %4.4s",
(const char *)&p_dec->fmt_in.i_codec);
return VLC_SUCCESS;
}
if (StartMediaCodec(p_dec) == VLC_SUCCESS) if (StartMediaCodec(p_dec) == VLC_SUCCESS)
return VLC_SUCCESS; return VLC_SUCCESS;
...@@ -899,7 +887,8 @@ static int Video_ProcessOutput(decoder_t *p_dec, mc_api_out *p_out, ...@@ -899,7 +887,8 @@ static int Video_ProcessOutput(decoder_t *p_dec, mc_api_out *p_out,
p_sys->u.video.i_stride, &p_sys->u.video.ascd); p_sys->u.video.i_stride, &p_sys->u.video.ascd);
if (p_sys->u.video.i_pixel_format == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) if (p_sys->u.video.i_pixel_format == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar)
p_sys->u.video.i_slice_height -= p_out->u.conf.video.crop_top/2; p_sys->u.video.i_slice_height -= p_out->u.conf.video.crop_top/2;
if (IgnoreOmxDecoderPadding(p_sys->psz_name)) { if ((p_sys->i_quirks & OMXCODEC_VIDEO_QUIRKS_IGNORE_PADDING))
{
p_sys->u.video.i_slice_height = 0; p_sys->u.video.i_slice_height = 0;
p_sys->u.video.i_stride = p_dec->fmt_out.video.i_width; p_sys->u.video.i_stride = p_dec->fmt_out.video.i_width;
} }
...@@ -1304,17 +1293,19 @@ static int Video_OnNewBlock(decoder_t *p_dec, block_t *p_block, int *p_flags) ...@@ -1304,17 +1293,19 @@ static int Video_OnNewBlock(decoder_t *p_dec, block_t *p_block, int *p_flags)
} }
} }
/* try delayed opening if there is a new extra data */
if (!p_sys->api->b_started) if (!p_sys->api->b_started)
{ {
switch (p_dec->fmt_in.i_codec) *p_flags |= NEWBLOCK_FLAG_RESTART;
{
case VLC_CODEC_VC1: /* Don't start if we don't have any csd */
if (p_dec->fmt_in.i_extra) if ((p_sys->i_quirks & OMXCODEC_QUIRKS_NEED_CSD)
*p_flags |= NEWBLOCK_FLAG_RESTART; && !p_dec->fmt_in.i_extra && !p_sys->pp_csd)
default: *p_flags &= ~NEWBLOCK_FLAG_RESTART;
break;
} /* Don't start if we don't have a valid video size */
if ((p_sys->i_quirks & OMXCODEC_VIDEO_QUIRKS_NEED_SIZE)
&& (!p_sys->u.video.i_width || !p_sys->u.video.i_height))
*p_flags &= ~NEWBLOCK_FLAG_RESTART;
} }
timestamp_FifoPut(p_sys->u.video.timestamp_fifo, timestamp_FifoPut(p_sys->u.video.timestamp_fifo,
...@@ -1359,22 +1350,18 @@ static int Audio_OnNewBlock(decoder_t *p_dec, block_t *p_block, int *p_flags) ...@@ -1359,22 +1350,18 @@ static int Audio_OnNewBlock(decoder_t *p_dec, block_t *p_block, int *p_flags)
/* try delayed opening if there is a new extra data */ /* try delayed opening if there is a new extra data */
if (!p_sys->api->b_started) if (!p_sys->api->b_started)
{ {
switch (p_dec->fmt_in.i_codec) p_dec->p_sys->u.audio.i_channels = p_dec->fmt_in.audio.i_channels;
{
case VLC_CODEC_VORBIS: *p_flags |= NEWBLOCK_FLAG_RESTART;
case VLC_CODEC_MP4A:
if (p_dec->fmt_in.i_extra) /* Don't start if we don't have any csd */
*p_flags |= NEWBLOCK_FLAG_RESTART; if ((p_sys->i_quirks & OMXCODEC_QUIRKS_NEED_CSD)
default: && !p_dec->fmt_in.i_extra)
break; *p_flags &= ~NEWBLOCK_FLAG_RESTART;
}
if (!p_dec->p_sys->u.audio.i_channels && p_dec->fmt_in.audio.i_channels)
{
p_dec->p_sys->u.audio.i_channels = p_dec->fmt_in.audio.i_channels;
*p_flags |= NEWBLOCK_FLAG_RESTART;
}
if (!p_dec->p_sys->u.audio.i_channels && p_sys->u.audio.b_need_channels) /* Don't start if we don't have a valid channels count */
if ((p_sys->i_quirks & OMXCODEC_AUDIO_QUIRKS_NEED_CHANNELS)
&& !p_dec->p_sys->u.audio.i_channels)
*p_flags &= ~NEWBLOCK_FLAG_RESTART; *p_flags &= ~NEWBLOCK_FLAG_RESTART;
} }
return 1; return 1;
......
...@@ -635,7 +635,7 @@ static OMX_ERRORTYPE GetPortDefinition(decoder_t *p_dec, OmxPort *p_port, ...@@ -635,7 +635,7 @@ static OMX_ERRORTYPE GetPortDefinition(decoder_t *p_dec, OmxPort *p_port,
strlen("OMX.qcom.video.decoder"))) strlen("OMX.qcom.video.decoder")))
def->format.video.eColorFormat = OMX_QCOM_COLOR_FormatYVU420SemiPlanar; def->format.video.eColorFormat = OMX_QCOM_COLOR_FormatYVU420SemiPlanar;
if (IgnoreOmxDecoderPadding(p_sys->psz_component)) { if ((p_sys->i_quirks & OMXCODEC_VIDEO_QUIRKS_IGNORE_PADDING)) {
def->format.video.nSliceHeight = 0; def->format.video.nSliceHeight = 0;
def->format.video.nStride = p_fmt->video.i_width; def->format.video.nStride = p_fmt->video.i_width;
} }
...@@ -821,6 +821,7 @@ static OMX_ERRORTYPE InitialiseComponent(decoder_t *p_dec, ...@@ -821,6 +821,7 @@ static OMX_ERRORTYPE InitialiseComponent(decoder_t *p_dec,
OMX_HANDLETYPE omx_handle; OMX_HANDLETYPE omx_handle;
OMX_ERRORTYPE omx_error; OMX_ERRORTYPE omx_error;
unsigned int i; unsigned int i;
int i_quirks;
OMX_U8 psz_role[OMX_MAX_STRINGNAME_SIZE]; OMX_U8 psz_role[OMX_MAX_STRINGNAME_SIZE];
OMX_PARAM_COMPONENTROLETYPE role; OMX_PARAM_COMPONENTROLETYPE role;
OMX_PARAM_PORTDEFINITIONTYPE definition; OMX_PARAM_PORTDEFINITIONTYPE definition;
...@@ -835,6 +836,10 @@ static OMX_ERRORTYPE InitialiseComponent(decoder_t *p_dec, ...@@ -835,6 +836,10 @@ static OMX_ERRORTYPE InitialiseComponent(decoder_t *p_dec,
return omx_error; return omx_error;
} }
strncpy(p_sys->psz_component, psz_component, OMX_MAX_STRINGNAME_SIZE-1); strncpy(p_sys->psz_component, psz_component, OMX_MAX_STRINGNAME_SIZE-1);
i_quirks = OMXCodec_GetQuirks(p_dec->fmt_in.i_cat,
p_sys->b_enc ? p_dec->fmt_out.i_codec : p_dec->fmt_in.i_codec,
p_sys->psz_component,
strlen(p_sys->psz_component));
omx_error = OMX_ComponentRoleEnum(omx_handle, psz_role, 0); omx_error = OMX_ComponentRoleEnum(omx_handle, psz_role, 0);
if(omx_error == OMX_ErrorNone) if(omx_error == OMX_ErrorNone)
...@@ -976,6 +981,7 @@ static OMX_ERRORTYPE InitialiseComponent(decoder_t *p_dec, ...@@ -976,6 +981,7 @@ static OMX_ERRORTYPE InitialiseComponent(decoder_t *p_dec,
} }
} }
p_sys->i_quirks = i_quirks;
*p_handle = omx_handle; *p_handle = omx_handle;
return OMX_ErrorNone; return OMX_ErrorNone;
......
...@@ -119,6 +119,7 @@ struct decoder_sys_t ...@@ -119,6 +119,7 @@ struct decoder_sys_t
char psz_component[OMX_MAX_STRINGNAME_SIZE]; char psz_component[OMX_MAX_STRINGNAME_SIZE];
char ppsz_components[MAX_COMPONENTS_LIST_SIZE][OMX_MAX_STRINGNAME_SIZE]; char ppsz_components[MAX_COMPONENTS_LIST_SIZE][OMX_MAX_STRINGNAME_SIZE];
unsigned int components; unsigned int components;
int i_quirks;
OmxEventQueue event_queue; OmxEventQueue event_queue;
......
...@@ -209,8 +209,6 @@ void CopyOmxPicture( int i_color_format, picture_t *p_pic, ...@@ -209,8 +209,6 @@ void CopyOmxPicture( int i_color_format, picture_t *p_pic,
void CopyVlcPicture( decoder_t *, OMX_BUFFERHEADERTYPE *, picture_t * ); void CopyVlcPicture( decoder_t *, OMX_BUFFERHEADERTYPE *, picture_t * );
int IgnoreOmxDecoderPadding(const char *psz_name);
/***************************************************************************** /*****************************************************************************
* Logging utility functions * Logging utility functions
*****************************************************************************/ *****************************************************************************/
...@@ -226,6 +224,16 @@ void PrintOmx(decoder_t *p_dec, OMX_HANDLETYPE omx_handle, OMX_U32 i_port); ...@@ -226,6 +224,16 @@ void PrintOmx(decoder_t *p_dec, OMX_HANDLETYPE omx_handle, OMX_U32 i_port);
*****************************************************************************/ *****************************************************************************/
bool OMXCodec_IsBlacklisted( const char *p_name, unsigned int i_name_len ); bool OMXCodec_IsBlacklisted( const char *p_name, unsigned int i_name_len );
enum {
OMXCODEC_NO_QUIRKS = 0,
OMXCODEC_QUIRKS_NEED_CSD = 0x1,
OMXCODEC_VIDEO_QUIRKS_NEED_SIZE = 0x2,
OMXCODEC_VIDEO_QUIRKS_IGNORE_PADDING = 0x4,
OMXCODEC_AUDIO_QUIRKS_NEED_CHANNELS = 0x8,
};
int OMXCodec_GetQuirks( int i_cat, vlc_fourcc_t i_codec,
const char *p_name, unsigned int i_name_len );
/***************************************************************************** /*****************************************************************************
* fourcc -> omx id mapping * fourcc -> omx id mapping
*****************************************************************************/ *****************************************************************************/
......
...@@ -278,35 +278,6 @@ void CopyVlcPicture( decoder_t *p_dec, OMX_BUFFERHEADERTYPE *p_header, ...@@ -278,35 +278,6 @@ void CopyVlcPicture( decoder_t *p_dec, OMX_BUFFERHEADERTYPE *p_header,
} }
} }
int IgnoreOmxDecoderPadding(const char *name)
{
// The list of decoders that signal padding properly is not necessary,
// since that is the default, but keep it here for reference. (This is
// only relevant for manufacturers that are known to have decoders with
// this kind of bug.)
/*
static const char *padding_decoders[] = {
"OMX.SEC.AVC.Decoder",
"OMX.SEC.wmv7.dec",
"OMX.SEC.wmv8.dec",
NULL
};
*/
static const char *nopadding_decoders[] = {
"OMX.SEC.avc.dec",
"OMX.SEC.avcdec",
"OMX.SEC.MPEG4.Decoder",
"OMX.SEC.mpeg4.dec",
"OMX.SEC.vc1.dec",
NULL
};
for (const char **ptr = nopadding_decoders; *ptr; ptr++) {
if (!strcmp(*ptr, name))
return 1;
}
return 0;
}
/***************************************************************************** /*****************************************************************************
* Utility functions * Utility functions
*****************************************************************************/ *****************************************************************************/
...@@ -335,8 +306,6 @@ bool OMXCodec_IsBlacklisted( const char *p_name, unsigned int i_name_len ) ...@@ -335,8 +306,6 @@ bool OMXCodec_IsBlacklisted( const char *p_name, unsigned int i_name_len )
* it) and for WMV3 it outputs plain black buffers. Thus ignore * it) and for WMV3 it outputs plain black buffers. Thus ignore
* it until we can make it work properly. */ * it until we can make it work properly. */
"OMX.Nvidia.vc1.decode", "OMX.Nvidia.vc1.decode",
/* crashes mediaserver */
"OMX.MTK.VIDEO.DECODER.MPEG4",
/* black screen */ /* black screen */
"OMX.MTK.VIDEO.DECODER.VC1", "OMX.MTK.VIDEO.DECODER.VC1",
/* Not working or crashing (Samsung) */ /* Not working or crashing (Samsung) */
...@@ -377,6 +346,90 @@ bool OMXCodec_IsBlacklisted( const char *p_name, unsigned int i_name_len ) ...@@ -377,6 +346,90 @@ bool OMXCodec_IsBlacklisted( const char *p_name, unsigned int i_name_len )
return false; return false;
} }
struct str2quirks {
const char *psz_name;
int i_quirks;
};
int OMXCodec_GetQuirks( int i_cat, vlc_fourcc_t i_codec,
const char *p_name, unsigned int i_name_len )
{
static const struct str2quirks quirks_prefix[] = {
{ "OMX.MTK.VIDEO.DECODER.MPEG4", OMXCODEC_QUIRKS_NEED_CSD },
{ "OMX.Marvell", OMXCODEC_AUDIO_QUIRKS_NEED_CHANNELS },
/* The list of decoders that signal padding properly is not necessary,
* since that is the default, but keep it here for reference. (This is
* only relevant for manufacturers that are known to have decoders with
* this kind of bug.)
* static const char *padding_decoders[] = {
* "OMX.SEC.AVC.Decoder",
* "OMX.SEC.wmv7.dec",
* "OMX.SEC.wmv8.dec",
* NULL
* };
*/
{ "OMX.SEC.avc.dec", OMXCODEC_VIDEO_QUIRKS_IGNORE_PADDING },
{ "OMX.SEC.avcdec", OMXCODEC_VIDEO_QUIRKS_IGNORE_PADDING },
{ "OMX.SEC.MPEG4.Decoder", OMXCODEC_VIDEO_QUIRKS_IGNORE_PADDING },
{ "OMX.SEC.mpeg4.dec", OMXCODEC_VIDEO_QUIRKS_IGNORE_PADDING },
{ "OMX.SEC.vc1.dec", OMXCODEC_VIDEO_QUIRKS_IGNORE_PADDING },
{ NULL, 0 }
};
static struct str2quirks quirks_suffix[] = {
{ NULL, 0 }
};
int i_quirks = OMXCODEC_NO_QUIRKS;
if( i_cat == VIDEO_ES )
{
i_quirks |= OMXCODEC_VIDEO_QUIRKS_NEED_SIZE;
switch( i_codec )
{
case VLC_CODEC_H264:
case VLC_CODEC_VC1:
i_quirks |= OMXCODEC_QUIRKS_NEED_CSD;
break;
}
} else if( i_cat == AUDIO_ES )
{
switch( i_codec )
{
case VLC_CODEC_VORBIS:
case VLC_CODEC_MP4A:
i_quirks |= OMXCODEC_QUIRKS_NEED_CSD;
break;
}
}
/* p_name is not '\0' terminated */
for( const struct str2quirks *p_q_prefix = quirks_prefix; p_q_prefix->psz_name;
p_q_prefix++ )
{
const char *psz_prefix = p_q_prefix->psz_name;
if( !strncmp( p_name, psz_prefix,
__MIN( strlen(psz_prefix), i_name_len ) ) )
i_quirks |= p_q_prefix->i_quirks;
}
for( const struct str2quirks *p_q_suffix = quirks_suffix; p_q_suffix->psz_name;
p_q_suffix++ )
{
const char *psz_suffix = p_q_suffix->psz_name;
size_t i_suffix_len = strlen( psz_suffix );
if( i_name_len > i_suffix_len
&& !strncmp( p_name + i_name_len - i_suffix_len, psz_suffix,
i_suffix_len ) )
i_quirks |= p_q_suffix->i_quirks;
}
return i_quirks;
}
/***************************************************************************** /*****************************************************************************
* Logging utility functions * Logging utility functions
*****************************************************************************/ *****************************************************************************/
......
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