[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