[vlc-commits] demux: heif: refactor pic setup
Francois Cartegnie
git at videolan.org
Mon Nov 19 14:04:47 CET 2018
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Sun Nov 18 16:39:27 2018 +0100| [e0e3e2b0fa591063bc8836e37cc87f9cd8d942af] | committer: Francois Cartegnie
demux: heif: refactor pic setup
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=e0e3e2b0fa591063bc8836e37cc87f9cd8d942af
---
modules/demux/mp4/heif.c | 242 ++++++++++++++++++++++++++---------------------
1 file changed, 135 insertions(+), 107 deletions(-)
diff --git a/modules/demux/mp4/heif.c b/modules/demux/mp4/heif.c
index 3298667809..cb3be7de11 100644
--- a/modules/demux/mp4/heif.c
+++ b/modules/demux/mp4/heif.c
@@ -313,97 +313,27 @@ static block_t *ReadItemExtents( demux_t *p_demux, uint32_t i_item_id,
return p_block;
}
-static int DemuxHEIF( demux_t *p_demux )
+static int SetPictureProperties( demux_t *p_demux, uint32_t i_item_id,
+ es_format_t *fmt, const MP4_Box_t **p_header )
{
struct heif_private_t *p_sys = (void *) p_demux->p_sys;
- /* Displaying a picture */
- if( p_sys->i_end_display_time > 0 )
- {
- bool b_empty;
- es_out_Control( p_demux->out, ES_OUT_GET_EMPTY, &b_empty );
- if( !b_empty || vlc_tick_now() <= p_sys->i_end_display_time )
- {
- vlc_tick_sleep( VLC_TICK_FROM_MS(40) );
- return VLC_DEMUXER_SUCCESS;
- }
- p_sys->i_end_display_time = 0;
- }
-
- /* Reset prev pic params */
- p_sys->current.p_shared_header = NULL;
-
- /* First or next picture */
- if( !p_sys->current.p_infe )
- {
- MP4_Box_t *p_pitm = MP4_BoxGet( p_sys->p_root, "meta/pitm" );
- if( !p_pitm )
- return VLC_DEMUXER_EOF;
-
- p_sys->current.p_infe = GetAtom( p_sys->p_root, NULL,
- ATOM_infe, "meta/iinf/infe",
- MatchInfeID, &BOXDATA(p_pitm)->i_item_id );
- }
- else
- {
- p_sys->current.p_infe = GetAtom( p_sys->p_root, p_sys->current.p_infe,
- ATOM_infe, "meta/iinf/infe",
- MatchPureImage, p_sys->p_root );
- }
-
- if( !p_sys->current.p_infe )
- return VLC_DEMUXER_EOF;
-
- const uint32_t i_current_item_id = p_sys->current.BOXDATA(p_infe)->i_item_id;
- const MP4_Box_t *p_ipco = MP4_BoxGet( p_sys->p_root, "meta/iprp/ipco" );
const MP4_Box_t *p_ipma = MP4_BoxGet( p_sys->p_root, "meta/iprp/ipma" );
- if( !p_ipma || !p_ipco )
- return VLC_DEMUXER_EOF;
-
- es_format_t fmt;
- const char *psz_mime = p_sys->current.BOXDATA(p_infe)->psz_content_type;
- switch( p_sys->current.BOXDATA(p_infe)->item_type )
- {
- case VLC_FOURCC('h','v','c','1'):
- es_format_Init( &fmt, VIDEO_ES, VLC_CODEC_HEVC );
- break;
- case VLC_FOURCC('a','v','c','1'):
- es_format_Init( &fmt, VIDEO_ES, VLC_CODEC_H264 );
- break;
- case ATOM_av01:
- es_format_Init( &fmt, VIDEO_ES, VLC_CODEC_AV1 );
- break;
- case VLC_FOURCC('j','p','e','g'):
- es_format_Init( &fmt, VIDEO_ES, VLC_CODEC_JPEG );
- break;
- default:
- if( psz_mime )
- {
- if( !strcasecmp( "image/jpeg", psz_mime ) )
- {
- es_format_Init( &fmt, VIDEO_ES, VLC_CODEC_JPEG );
- break;
- }
- else if( !strcasecmp( "image/avif", psz_mime ) )
- {
- es_format_Init( &fmt, VIDEO_ES, VLC_CODEC_AV1 );
- break;
- }
- }
- return VLC_DEMUXER_SUCCESS; /* Unsupported picture, goto next */
- }
+ if( !p_ipma )
+ return VLC_EGENERIC;
/* Load properties */
for( uint32_t i=0; i<BOXDATA(p_ipma)->i_entry_count; i++ )
{
- if( BOXDATA(p_ipma)->p_entries[i].i_item_id != i_current_item_id )
+ if( BOXDATA(p_ipma)->p_entries[i].i_item_id != i_item_id )
continue;
+
for( uint8_t j=0; j<BOXDATA(p_ipma)->p_entries[i].i_association_count; j++ )
{
if( !BOXDATA(p_ipma)->p_entries[i].p_assocs[j].i_property_index )
continue;
- const MP4_Box_t *p_prop = MP4_BoxGet( p_ipco, "./[%u]",
+ const MP4_Box_t *p_prop = MP4_BoxGet( p_sys->p_root, "meta/iprp/ipco/[%u]",
BOXDATA(p_ipma)->p_entries[i].p_assocs[j].i_property_index - 1 );
if( !p_prop )
continue;
@@ -413,72 +343,170 @@ static int DemuxHEIF( demux_t *p_demux )
case ATOM_hvcC:
case ATOM_avcC:
case ATOM_av1C:
- if( !fmt.p_extra &&
- ((fmt.i_codec == VLC_CODEC_HEVC && p_prop->i_type == ATOM_hvcC) ||
- (fmt.i_codec == VLC_CODEC_H264 && p_prop->i_type == ATOM_avcC) ||
- (fmt.i_codec == VLC_CODEC_AV1 && p_prop->i_type == ATOM_av1C)) )
+ if( !fmt->p_extra &&
+ ((fmt->i_codec == VLC_CODEC_HEVC && p_prop->i_type == ATOM_hvcC) ||
+ (fmt->i_codec == VLC_CODEC_H264 && p_prop->i_type == ATOM_avcC) ||
+ (fmt->i_codec == VLC_CODEC_AV1 && p_prop->i_type == ATOM_av1C)) )
{
- fmt.p_extra = malloc( p_prop->data.p_binary->i_blob );
- if( fmt.p_extra )
+ fmt->p_extra = malloc( p_prop->data.p_binary->i_blob );
+ if( fmt->p_extra )
{
- fmt.i_extra = p_prop->data.p_binary->i_blob;
- memcpy( fmt.p_extra, p_prop->data.p_binary->p_blob, fmt.i_extra );
+ fmt->i_extra = p_prop->data.p_binary->i_blob;
+ memcpy( fmt->p_extra, p_prop->data.p_binary->p_blob, fmt->i_extra );
}
}
break;
case ATOM_jpeC:
- if( fmt.i_codec == VLC_CODEC_JPEG )
- p_sys->current.p_shared_header = p_prop;
+ if( fmt->i_codec == VLC_CODEC_JPEG )
+ *p_header = p_prop;
break;
case ATOM_ispe:
- fmt.video.i_visible_width = p_prop->data.p_ispe->i_width;
- fmt.video.i_visible_height = p_prop->data.p_ispe->i_height;
+ fmt->video.i_visible_width = p_prop->data.p_ispe->i_width;
+ fmt->video.i_visible_height = p_prop->data.p_ispe->i_height;
break;
case ATOM_pasp:
if( p_prop->data.p_pasp->i_horizontal_spacing &&
p_prop->data.p_pasp->i_vertical_spacing )
{
- fmt.video.i_sar_num = p_prop->data.p_pasp->i_horizontal_spacing;
- fmt.video.i_sar_den = p_prop->data.p_pasp->i_vertical_spacing;
+ fmt->video.i_sar_num = p_prop->data.p_pasp->i_horizontal_spacing;
+ fmt->video.i_sar_den = p_prop->data.p_pasp->i_vertical_spacing;
}
break;
case ATOM_irot:
switch( p_prop->data.p_irot->i_ccw_degrees % 360 )
{
default:
- case 0: fmt.video.orientation = ORIENT_NORMAL ; break;
- case 90: fmt.video.orientation = ORIENT_ROTATED_90; break;
- case 180: fmt.video.orientation = ORIENT_ROTATED_180 ; break;
- case 270: fmt.video.orientation = ORIENT_ROTATED_270 ; break;
+ case 0: fmt->video.orientation = ORIENT_NORMAL ; break;
+ case 90: fmt->video.orientation = ORIENT_ROTATED_90; break;
+ case 180: fmt->video.orientation = ORIENT_ROTATED_180 ; break;
+ case 270: fmt->video.orientation = ORIENT_ROTATED_270 ; break;
}
break;
case ATOM_colr:
- fmt.video.primaries = iso_23001_8_cp_to_vlc_primaries(
+ fmt->video.primaries = iso_23001_8_cp_to_vlc_primaries(
p_prop->data.p_colr->nclc.i_primary_idx );
- fmt.video.transfer = iso_23001_8_tc_to_vlc_xfer(
+ fmt->video.transfer = iso_23001_8_tc_to_vlc_xfer(
p_prop->data.p_colr->nclc.i_transfer_function_idx );
- fmt.video.space = iso_23001_8_mc_to_vlc_coeffs(
+ fmt->video.space = iso_23001_8_mc_to_vlc_coeffs(
p_prop->data.p_colr->nclc.i_matrix_idx );
- fmt.video.b_color_range_full = p_prop->data.p_colr->nclc.i_full_range;
+ fmt->video.b_color_range_full = p_prop->data.p_colr->nclc.i_full_range;
break;
case ATOM_clli:
- fmt.video.lighting.MaxCLL = p_prop->data.p_CoLL->i_maxCLL;
- fmt.video.lighting.MaxFALL = p_prop->data.p_CoLL->i_maxFALL;
+ fmt->video.lighting.MaxCLL = p_prop->data.p_CoLL->i_maxCLL;
+ fmt->video.lighting.MaxFALL = p_prop->data.p_CoLL->i_maxFALL;
break;
case ATOM_mdcv:
- memcpy( fmt.video.mastering.primaries,
+ memcpy( fmt->video.mastering.primaries,
p_prop->data.p_SmDm->primaries, sizeof(uint16_t) * 6 );
- memcpy( fmt.video.mastering.white_point,
+ memcpy( fmt->video.mastering.white_point,
p_prop->data.p_SmDm->white_point, sizeof(uint16_t) * 2 );
- fmt.video.mastering.max_luminance = p_prop->data.p_SmDm->i_luminanceMax;
- fmt.video.mastering.min_luminance = p_prop->data.p_SmDm->i_luminanceMin;
+ fmt->video.mastering.max_luminance = p_prop->data.p_SmDm->i_luminanceMax;
+ fmt->video.mastering.min_luminance = p_prop->data.p_SmDm->i_luminanceMin;
break;
}
}
}
- fmt.video.i_frame_rate = 1000;
- fmt.video.i_frame_rate_base = p_sys->i_image_duration / 1000;
+ fmt->video.i_frame_rate = 1000;
+ fmt->video.i_frame_rate_base = p_sys->i_image_duration / 1000;
+
+ return VLC_SUCCESS;
+}
+
+static int SetupPicture( demux_t *p_demux, const MP4_Box_t *p_infe,
+ es_format_t *fmt, const MP4_Box_t **p_header )
+{
+ fmt->i_codec = 0;
+ *p_header = NULL;
+
+ const uint32_t i_item_id = BOXDATA(p_infe)->i_item_id;
+ const char *psz_mime = BOXDATA(p_infe)->psz_content_type;
+ switch( BOXDATA(p_infe)->item_type )
+ {
+ case VLC_FOURCC('h','v','c','1'):
+ es_format_Init( fmt, VIDEO_ES, VLC_CODEC_HEVC );
+ break;
+ case VLC_FOURCC('a','v','c','1'):
+ es_format_Init( fmt, VIDEO_ES, VLC_CODEC_H264 );
+ break;
+ case ATOM_av01:
+ es_format_Init( fmt, VIDEO_ES, VLC_CODEC_AV1 );
+ break;
+ case VLC_FOURCC('j','p','e','g'):
+ es_format_Init( fmt, VIDEO_ES, VLC_CODEC_JPEG );
+ break;
+ default:
+ if( psz_mime )
+ {
+ if( !strcasecmp( "image/jpeg", psz_mime ) )
+ es_format_Init( fmt, VIDEO_ES, VLC_CODEC_JPEG );
+ else if( !strcasecmp( "image/avif", psz_mime ) )
+ es_format_Init( fmt, VIDEO_ES, VLC_CODEC_AV1 );
+ }
+ break;
+ }
+
+ if( fmt->i_codec == 0 )
+ return VLC_EGENERIC;
+
+ return SetPictureProperties( p_demux, i_item_id, fmt, p_header );
+}
+
+static int DemuxHEIF( demux_t *p_demux )
+{
+ struct heif_private_t *p_sys = (void *) p_demux->p_sys;
+
+ /* Displaying a picture */
+ if( p_sys->i_end_display_time > 0 )
+ {
+ bool b_empty;
+ es_out_Control( p_demux->out, ES_OUT_GET_EMPTY, &b_empty );
+ if( !b_empty || vlc_tick_now() <= p_sys->i_end_display_time )
+ {
+ vlc_tick_sleep( VLC_TICK_FROM_MS(40) );
+ return VLC_DEMUXER_SUCCESS;
+ }
+ p_sys->i_end_display_time = 0;
+ }
+
+ /* Reset prev pic params */
+ p_sys->current.p_shared_header = NULL;
+
+ /* First or next picture */
+ if( !p_sys->current.p_infe )
+ {
+ MP4_Box_t *p_pitm = MP4_BoxGet( p_sys->p_root, "meta/pitm" );
+ if( !p_pitm )
+ return VLC_DEMUXER_EOF;
+
+ p_sys->current.p_infe = GetAtom( p_sys->p_root, NULL,
+ ATOM_infe, "meta/iinf/infe",
+ MatchInfeID, &BOXDATA(p_pitm)->i_item_id );
+ }
+ else
+ {
+ p_sys->current.p_infe = GetAtom( p_sys->p_root, p_sys->current.p_infe,
+ ATOM_infe, "meta/iinf/infe",
+ MatchPureImage, p_sys->p_root );
+ }
+
+ if( !p_sys->current.p_infe )
+ return VLC_DEMUXER_EOF;
+
+ const uint32_t i_current_item_id = p_sys->current.BOXDATA(p_infe)->i_item_id;
+ const MP4_Box_t *p_ipco = MP4_BoxGet( p_sys->p_root, "meta/iprp/ipco" );
+ if( !p_ipco )
+ return VLC_DEMUXER_EOF;
+
+ es_format_t fmt;
+ es_format_Init(&fmt, UNKNOWN_ES, 0);
+
+ if( SetupPicture( p_demux, p_sys->current.p_infe,
+ &fmt, &p_sys->current.p_shared_header ) != VLC_SUCCESS )
+ {
+ es_format_Clean( &fmt );
+ return VLC_DEMUXER_SUCCESS; /* Unsupported picture, goto next */
+ }
es_format_Clean( &p_sys->current.fmt );
es_format_Copy( &p_sys->current.fmt, &fmt );
More information about the vlc-commits
mailing list