[vlc-commits] [Git][videolan/vlc][master] 15 commits: codec: avcodec: create buffers with original flags

François Cartegnie (@fcartegnie) gitlab at videolan.org
Tue Jun 25 11:55:03 UTC 2024



François Cartegnie pushed to branch master at VideoLAN / VLC


Commits:
175f7da2 by François Cartegnie at 2024-06-25T10:36:25+00:00
codec: avcodec: create buffers with original flags

- - - - -
210b7a95 by François Cartegnie at 2024-06-25T10:36:25+00:00
packetizer: hevc: refactor common mpeg code

- - - - -
e0b52caf by François Cartegnie at 2024-06-25T10:36:25+00:00
packetizer: hevc: reuse annexb startcode definition

- - - - -
e730825a by François Cartegnie at 2024-06-25T10:36:25+00:00
packetizer: h264: reuse annexb startcode definition

- - - - -
7b12facc by François Cartegnie at 2024-06-25T10:36:25+00:00
packetizer: mpegvideo: use common code

- - - - -
d52113ef by François Cartegnie at 2024-06-25T10:36:25+00:00
packetizer: mpeg4video: use common mpeg code

- - - - -
a6f0f69f by François Cartegnie at 2024-06-25T10:36:25+00:00
packetizer: h264: vui is already checked later

- - - - -
181447e3 by François Cartegnie at 2024-06-25T10:36:25+00:00
packetizer: h264: rename vui flag

- - - - -
41b19d58 by François Cartegnie at 2024-06-25T10:36:25+00:00
packetizer: h264: improve h264_slice abstraction

- - - - -
ddd43192 by François Cartegnie at 2024-06-25T10:36:25+00:00
packetizer: h264: fix debug format string

- - - - -
464ca42d by François Cartegnie at 2024-06-25T10:36:25+00:00
packetizer: h264: add h264_get_aspect_ratio

- - - - -
4e9a45b4 by François Cartegnie at 2024-06-25T10:36:25+00:00
packetizer: h264: add decode_sei_timing

- - - - -
8ceb19ec by François Cartegnie at 2024-06-25T10:36:25+00:00
packetizer: h264: add h264_get_frame_rate

- - - - -
cbccd2a2 by François Cartegnie at 2024-06-25T10:36:25+00:00
packetizer: h264: improve nal abstraction

- - - - -
7cf5345c by François Cartegnie at 2024-06-25T10:36:25+00:00
packetizer: h264: check few values

- - - - -


15 changed files:

- modules/codec/Makefile.am
- modules/codec/avcodec/video.c
- modules/codec/hxxx_helper.c
- modules/codec/videotoolbox/decoder.c
- modules/packetizer/Makefile.am
- modules/packetizer/h264.c
- modules/packetizer/h264_nal.c
- modules/packetizer/h264_nal.h
- modules/packetizer/h264_slice.c
- modules/packetizer/h264_slice.h
- + modules/packetizer/h26x_nal_common.h
- modules/packetizer/hevc.c
- modules/packetizer/hevc_nal.c
- modules/packetizer/mpeg4video.c
- modules/packetizer/mpegvideo.c


Changes:

=====================================
modules/codec/Makefile.am
=====================================
@@ -449,6 +449,7 @@ libdxva2_plugin_la_SOURCES = \
 	codec/avcodec/va_surface.c codec/avcodec/va_surface.h \
 	packetizer/h264_nal.c packetizer/h264_nal.h \
 	packetizer/hevc_nal.c packetizer/hevc_nal.h \
+	packetizer/h26x_nal_common.h \
 	codec/avcodec/dxva_blocklist.c
 libdxva2_plugin_la_LIBADD = libd3d9_common.la $(LIBCOM) -luuid
 if !HAVE_WINSTORE
@@ -470,6 +471,7 @@ libd3d11va_plugin_la_SOURCES = \
         codec/avcodec/va_surface.c codec/avcodec/va_surface.h \
 	packetizer/h264_nal.c packetizer/h264_nal.h \
 	packetizer/hevc_nal.c packetizer/hevc_nal.h \
+	packetizer/h26x_nal_common.h \
 	codec/avcodec/dxva_blocklist.c
 libd3d11va_plugin_la_LIBADD = libd3d11_common.la $(LIBCOM) -luuid
 if HAVE_WINSTORE
@@ -497,6 +499,7 @@ libomxil_plugin_la_SOURCES = \
 	codec/omxil/utils.c codec/omxil/omxil_utils.h \
 	packetizer/h264_nal.c packetizer/h264_nal.h \
 	packetizer/hevc_nal.c packetizer/hevc_nal.h \
+	packetizer/h26x_nal_common.h \
 	codec/omxil/qcom.c codec/omxil/qcom.h \
 	codec/omxil/omxil.c codec/omxil/omxil.h codec/omxil/omxil_core.c codec/omxil/omxil_core.h
 libomxil_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/codec/omxil $(CFLAGS_omxil)
@@ -689,6 +692,7 @@ libvlc_hxxxhelper_la_SOURCES = \
 	packetizer/hxxx_sei.h packetizer/hxxx_sei.c \
 	packetizer/h264_slice.c packetizer/h264_slice.h \
 	packetizer/h264_nal.c packetizer/h264_nal.h \
+	packetizer/h26x_nal_common.h \
 	packetizer/hevc_nal.c packetizer/hevc_nal.h
 libvlc_hxxxhelper_la_CPPFLAGS = -Dneedsomethinghere
 libvlc_hxxxhelper_la_LDFLAGS = -static


=====================================
modules/codec/avcodec/video.c
=====================================
@@ -1772,7 +1772,7 @@ static void lavc_ReleaseFrame(void *opaque, uint8_t *data)
     picture_Release(picture);
 }
 
-static int lavc_va_GetFrame(struct AVCodecContext *ctx, AVFrame *frame)
+static int lavc_va_GetFrame(struct AVCodecContext *ctx, AVFrame *frame, int flags)
 {
     decoder_t *dec = ctx->opaque;
     decoder_sys_t *p_sys = dec->p_sys;
@@ -1794,7 +1794,7 @@ static int lavc_va_GetFrame(struct AVCodecContext *ctx, AVFrame *frame)
         return -1;
     }
 
-    AVBufferRef *buf = av_buffer_create(NULL, 0, lavc_ReleaseFrame, pic, 0);
+    AVBufferRef *buf = av_buffer_create(NULL, 0, lavc_ReleaseFrame, pic, flags);
     if (unlikely(buf == NULL))
     {
         lavc_ReleaseFrame(pic, NULL);
@@ -1822,7 +1822,7 @@ static int lavc_va_GetFrame(struct AVCodecContext *ctx, AVFrame *frame)
     return 0;
 }
 
-static int lavc_dr_GetFrame(struct AVCodecContext *ctx, AVFrame *frame)
+static int lavc_dr_GetFrame(struct AVCodecContext *ctx, AVFrame *frame, int flags)
 {
     decoder_t *dec = ctx->opaque;
     decoder_sys_t *sys = dec->p_sys;
@@ -1876,7 +1876,7 @@ static int lavc_dr_GetFrame(struct AVCodecContext *ctx, AVFrame *frame)
         frame->data[i] = data;
         frame->linesize[i] = pic->p[i].i_pitch;
         frame->buf[i] = av_buffer_create(data, size, lavc_ReleaseFrame,
-                                         pic, 0);
+                                         pic, flags);
         if (unlikely(frame->buf[i] == NULL))
         {
             while (i > 0)
@@ -1937,14 +1937,14 @@ static int lavc_GetFrame(struct AVCodecContext *ctx, AVFrame *frame, int flags)
 
     if (sys->p_va != NULL)
     {
-        int ret = lavc_va_GetFrame(ctx, frame);
+        int ret = lavc_va_GetFrame(ctx, frame, flags);
         vlc_mutex_unlock(&sys->lock);
         return ret;
     }
 
     /* Some codecs set pix_fmt only after the 1st frame has been decoded,
      * so we need to check for direct rendering again. */
-    int ret = lavc_dr_GetFrame(ctx, frame);
+    int ret = lavc_dr_GetFrame(ctx, frame, flags);
     vlc_mutex_unlock(&sys->lock);
     if (ret)
         ret = avcodec_default_get_buffer2(ctx, frame, flags);


=====================================
modules/codec/hxxx_helper.c
=====================================
@@ -201,34 +201,38 @@ h264_helper_parse_nal(struct hxxx_helper *hh, const uint8_t *p_nal, size_t i_nal
         return VLC_EGENERIC;
 
     const enum h264_nal_unit_type_e i_nal_type = p_nal[0] & 0x1F;
+    uint8_t i_id;
 
     if (i_nal_type == H264_NAL_SPS)
     {
+        h264_get_xps_id(p_nal, i_nal, &i_id);
         LOAD_xPS(hh->h264.sps_list, hh->h264.i_sps_count,
-                 p_xps->i_id, H264_SPS_ID_MAX,
+                 i_id, H264_SPS_ID_MAX,
                  h264_sequence_parameter_set_t,
                  h264_decode_sps,
                  h264_release_sps);
-        hh->h264.i_current_sps = ((h264_sequence_parameter_set_t*)p_xps)->i_id;
-        msg_Dbg(hh->p_obj, "new SPS parsed: %u", hh->h264.i_current_sps);
+        hh->h264.i_current_sps = i_id;
+        msg_Dbg(hh->p_obj, "new SPS parsed: %u", i_id);
     }
     else if (i_nal_type == H264_NAL_PPS)
     {
+        h264_get_xps_id(p_nal, i_nal, &i_id);
         LOAD_xPS(hh->h264.pps_list, hh->h264.i_pps_count,
-                 p_xps->i_id, H264_PPS_ID_MAX,
+                 i_id, H264_PPS_ID_MAX,
                  h264_picture_parameter_set_t,
                  h264_decode_pps,
                  h264_release_pps);
-        msg_Dbg(hh->p_obj, "new PPS parsed: %u", ((h264_picture_parameter_set_t*)p_xps)->i_id);
+        msg_Dbg(hh->p_obj, "new PPS parsed: %u", i_id);
     }
     else if(i_nal_type == H264_NAL_SPS_EXT)
     {
+        h264_get_xps_id(p_nal, i_nal, &i_id);
         LOAD_xPS(hh->h264.spsext_list, hh->h264.i_spsext_count,
-                 p_xps->i_sps_id, H264_SPSEXT_ID_MAX,
+                 i_id, H264_SPSEXT_ID_MAX,
                  h264_sequence_parameter_set_extension_t,
                  h264_decode_sps_extension,
                  h264_release_sps_extension);
-        msg_Dbg(hh->p_obj, "new SPSEXT parsed: %u", ((h264_sequence_parameter_set_extension_t*)p_xps)->i_sps_id);
+        msg_Dbg(hh->p_obj, "new SPSEXT parsed: %u", i_id);
     }
     else if (i_nal_type <= H264_NAL_SLICE_IDR
              && i_nal_type != H264_NAL_UNKNOWN)
@@ -254,14 +258,14 @@ h264_helper_parse_nal(struct hxxx_helper *hh, const uint8_t *p_nal, size_t i_nal
                 return VLC_EGENERIC;
 
             struct hxxx_helper_nal *hsps =
-                    &hh->h264.sps_list[hpps->h264_pps->i_sps_id];
+                &hh->h264.sps_list[h264_get_pps_sps_id(hpps->h264_pps)];
             if (hsps->b == NULL)
                 return VLC_EGENERIC;
 
-            assert(hpps->h264_pps->i_sps_id == hsps->h264_sps->i_id);
-            if (hsps->h264_sps->i_id != hh->h264.i_current_sps)
+            assert(h264_get_pps_sps_id(hpps->h264_pps) == h264_get_sps_id(hsps->h264_sps));
+            if (h264_get_sps_id(hsps->h264_sps) != hh->h264.i_current_sps)
             {
-                hh->h264.i_current_sps = hsps->h264_sps->i_id;
+                hh->h264.i_current_sps = h264_get_sps_id(hsps->h264_sps);
                 hh->i_config_version++;
             }
         }
@@ -832,20 +836,20 @@ hxxx_helper_get_current_picture_size(const struct hxxx_helper *hh,
 int
 hxxx_helper_get_current_sar(const struct hxxx_helper *hh, int *p_num, int *p_den)
 {
+    unsigned num, den;
     if(hh->i_codec == VLC_CODEC_H264)
     {
         const struct hxxx_helper_nal *hsps = h264_helper_get_current_sps(hh);
-        if (hsps)
+        if (hsps && hsps->h264_sps && h264_get_aspect_ratio(hsps->h264_sps, &num, &den))
         {
-            *p_num = hsps->h264_sps->vui.i_sar_num;
-            *p_den = hsps->h264_sps->vui.i_sar_den;
+            *p_num = num;
+            *p_den = den;
             return VLC_SUCCESS;
         }
     }
     else if(hh->i_codec == VLC_CODEC_HEVC)
     {
         const struct hxxx_helper_nal *hsps = &hh->hevc.sps_list[hh->hevc.i_current_sps];
-        unsigned num, den;
         if(hsps && hsps->hevc_sps && hevc_get_aspect_ratio(hsps->hevc_sps, &num, &den))
         {
             *p_num = num;
@@ -874,12 +878,9 @@ hxxx_helper_get_current_profile_level(const struct hxxx_helper *hh,
     if(hh->i_codec == VLC_CODEC_H264)
     {
         const struct hxxx_helper_nal *hsps = h264_helper_get_current_sps(hh);
-        if (hsps)
-        {
-            *p_profile = hsps->h264_sps->i_profile;
-            *p_level = hsps->h264_sps->i_level;
+        if (hsps && hsps->h264_sps &&
+            h264_get_sps_profile_tier_level(hsps->h264_sps, p_profile, p_level))
             return VLC_SUCCESS;
-        }
     }
     else if(hh->i_codec == VLC_CODEC_HEVC)
     {
@@ -896,11 +897,9 @@ int h264_helper_get_constraint_flag(const struct hxxx_helper *hh,
     
     assert(hh->i_codec == VLC_CODEC_H264);
     const struct hxxx_helper_nal *hsps = h264_helper_get_current_sps(hh);
-    if (hsps)
-    {
-        *pi_constraints = hsps->h264_sps->i_constraint_set_flags;
+    if (hsps && hsps->h264_sps &&
+        h264_get_constraints_set(hsps->h264_sps, pi_constraints))
         return VLC_SUCCESS;
-    }
     return VLC_EGENERIC;
 }
 


=====================================
modules/codec/videotoolbox/decoder.c
=====================================
@@ -201,7 +201,7 @@ static void GetxPSH264(uint8_t i_pps_id, void *priv,
     if (*pp_pps == NULL)
         *pp_sps = NULL;
     else
-        *pp_sps = h264ctx->hh.h264.sps_list[(*pp_pps)->i_sps_id].h264_sps;
+        *pp_sps = h264ctx->hh.h264.sps_list[h264_get_pps_sps_id(*pp_pps)].h264_sps;
 }
 
 struct sei_callback_h264_s
@@ -215,16 +215,13 @@ static bool ParseH264SEI(const hxxx_sei_data_t *p_sei_data, void *priv)
     if (p_sei_data->i_type == HXXX_SEI_PIC_TIMING)
     {
         struct sei_callback_h264_s *s = priv;
-        if (s->p_sps && s->p_sps->vui.b_valid)
+        if (s->p_sps)
         {
-            if (s->p_sps->vui.b_hrd_parameters_present_flag)
-            {
-                bs_read(p_sei_data->p_bs, s->p_sps->vui.i_cpb_removal_delay_length_minus1 + 1);
-                bs_read(p_sei_data->p_bs, s->p_sps->vui.i_dpb_output_delay_length_minus1 + 1);
-            }
-
-            if (s->p_sps->vui.b_pic_struct_present_flag)
-                s->i_pic_struct = bs_read( p_sei_data->p_bs, 4);
+            uint8_t i_dpb_output_delay;
+            h264_decode_sei_pic_timing( p_sei_data->p_bs, s->p_sps,
+                                       &s->i_pic_struct,
+                                       &i_dpb_output_delay );
+            VLC_UNUSED(i_dpb_output_delay);
         }
         return false;
     }
@@ -257,24 +254,25 @@ static bool FillReorderInfoH264(decoder_t *p_dec, const block_t *p_block,
 
         if (i_nal_type <= H264_NAL_SLICE_IDR && i_nal_type != H264_NAL_UNKNOWN)
         {
-            h264_slice_t slice;
-            if (!h264_decode_slice(p_nal, i_nal, GetxPSH264, h264ctx, &slice))
+            h264_slice_t *slice = h264_decode_slice(p_nal, i_nal, GetxPSH264, h264ctx);
+            if (!slice)
                 return false;
 
             const h264_sequence_parameter_set_t *p_sps;
             const h264_picture_parameter_set_t *p_pps;
-            GetxPSH264(slice.i_pic_parameter_set_id, h264ctx, &p_sps, &p_pps);
+            GetxPSH264(h264_get_slice_pps_id(slice), h264ctx, &p_sps, &p_pps);
             if (p_sps)
             {
                 int bFOC;
-                h264_compute_poc(p_sps, &slice, &h264ctx->poc,
+                h264_compute_poc(p_sps, slice, &h264ctx->poc,
                                  &p_info->i_poc, &p_info->i_foc, &bFOC);
 
-                p_info->b_keyframe = slice.type == H264_SLICE_TYPE_I;
-                p_info->b_flush = (slice.type == H264_SLICE_TYPE_I) || slice.has_mmco5;
-                p_info->b_field = slice.i_field_pic_flag;
-                p_info->b_progressive = !p_sps->mb_adaptive_frame_field_flag &&
-                                        !slice.i_field_pic_flag;
+                enum h264_slice_type_e slicetype = h264_get_slice_type(slice);
+                p_info->b_keyframe = slicetype == H264_SLICE_TYPE_I;
+                p_info->b_flush = p_info->b_keyframe || h264_has_mmco5(slice);
+                p_info->b_field = h264_is_field_pic(slice);
+                p_info->b_progressive = !h264_using_adaptive_frames(p_sps) &&
+                                        !p_info->b_field;
 
                 struct sei_callback_h264_s sei;
                 sei.p_sps = p_sps;
@@ -284,7 +282,7 @@ static bool FillReorderInfoH264(decoder_t *p_dec, const block_t *p_block,
                     HxxxParseSEI(sei_array[i].p_nal, sei_array[i].i_nal, 1,
                                  ParseH264SEI, &sei);
 
-                p_info->i_num_ts = h264_get_num_ts(p_sps, &slice, sei.i_pic_struct,
+                p_info->i_num_ts = h264_get_num_ts(p_sps, slice, sei.i_pic_struct,
                                                    p_info->i_foc, bFOC);
                 unsigned dummy;
                 h264_get_dpb_values(p_sps, &p_info->i_max_pics_buffering, &dummy);
@@ -293,12 +291,14 @@ static bool FillReorderInfoH264(decoder_t *p_dec, const block_t *p_block,
                     p_info->b_top_field_first = (sei.i_pic_struct % 2 == 1);
 
                 /* Set frame rate for timings in case of missing rate */
-                if (p_sps->vui.i_time_scale && p_sps->vui.i_num_units_in_tick)
+                unsigned fr[2];
+                if(h264_get_frame_rate(p_sps, fr, &fr[1]))
                 {
-                    p_info->field_rate_num = p_sps->vui.i_time_scale;
-                    p_info->field_rate_den = p_sps->vui.i_num_units_in_tick;
+                    p_info->field_rate_num = fr[0];
+                    p_info->field_rate_den = fr[1];
                 }
             }
+            h264_slice_release(slice);
 
             return true; /* No need to parse further NAL */
         }


=====================================
modules/packetizer/Makefile.am
=====================================
@@ -7,8 +7,10 @@ libpacketizer_av1_plugin_la_SOURCES = packetizer/av1.c \
 libpacketizer_copy_plugin_la_SOURCES = packetizer/copy.c
 libpacketizer_mpegvideo_plugin_la_SOURCES = packetizer/mpegvideo.c \
                                             packetizer/mpegvideo.h \
+                                            packetizer/h26x_nal_common.h \
                                             packetizer/iso_color_tables.h
 libpacketizer_mpeg4video_plugin_la_SOURCES = packetizer/mpeg4video.c \
+                                             packetizer/h26x_nal_common.h \
                                              packetizer/iso_color_tables.h
 libpacketizer_mjpeg_plugin_la_SOURCES = packetizer/mjpeg.c
 libpacketizer_mpeg4audio_plugin_la_SOURCES = packetizer/mpeg4audio.c \
@@ -32,6 +34,7 @@ libpacketizer_flac_plugin_la_SOURCES = packetizer/flac.c \
         packetizer/flac.h
 libpacketizer_hevc_plugin_la_SOURCES = packetizer/hevc.c \
 	packetizer/hevc_nal.h packetizer/hevc_nal.c \
+	packetizer/h26x_nal_common.h \
 	packetizer/hxxx_sei.c packetizer/hxxx_sei.h \
 	packetizer/hxxx_nal.h \
 	packetizer/hxxx_common.c packetizer/hxxx_common.h \


=====================================
modules/packetizer/h264.c
=====================================
@@ -73,7 +73,6 @@ typedef struct
     packetizer_t packetizer;
 
     /* */
-    bool    b_slice;
     struct
     {
         block_t *p_head;
@@ -109,8 +108,8 @@ typedef struct
     uint8_t i_dpb_output_delay;
     unsigned i_recovery_frame_cnt;
 
-    /* Useful values of the Slice Header */
-    h264_slice_t slice;
+    /* Current Slice Header */
+    h264_slice_t *p_slice;
 
     /* */
     int i_next_block_flags;
@@ -154,11 +153,10 @@ static block_t *ParseNALBlock( decoder_t *, bool *pb_ts_used, block_t * );
 static block_t *OutputPicture( decoder_t *p_dec );
 static void ReleaseXPS( decoder_sys_t *p_sys );
 static bool PutXPS( decoder_t *p_dec, uint8_t i_nal_type, block_t *p_frag );
-static bool ParseSliceHeader( decoder_t *p_dec, const block_t *p_frag, h264_slice_t *p_slice );
+static h264_slice_t * ParseSliceHeader( decoder_t *p_dec, const block_t *p_frag );
 static bool ParseSeiCallback( const hxxx_sei_data_t *, void * );
 
 
-static const uint8_t p_h264_startcode[3] = { 0x00, 0x00, 0x01 };
 
 /*****************************************************************************
  * Helpers
@@ -202,8 +200,12 @@ static void ActivateSets( decoder_t *p_dec, const h264_sequence_parameter_set_t
 
     if( p_sps )
     {
-        p_dec->fmt_out.i_profile = p_sps->i_profile;
-        p_dec->fmt_out.i_level = p_sps->i_level;
+        uint8_t pl[2];
+        if( h264_get_sps_profile_tier_level( p_sps, pl, &pl[1] ) )
+        {
+            p_dec->fmt_out.i_profile = pl[0];
+            p_dec->fmt_out.i_level = pl[1];
+        }
 
         (void) h264_get_picture_size( p_sps,
                                       &p_dec->fmt_out.video.i_x_offset,
@@ -213,31 +215,24 @@ static void ActivateSets( decoder_t *p_dec, const h264_sequence_parameter_set_t
                                       &p_dec->fmt_out.video.i_visible_width,
                                       &p_dec->fmt_out.video.i_visible_height );
 
-        if( p_sps->vui.i_sar_num != 0 && p_sps->vui.i_sar_den != 0 )
-        {
-            p_dec->fmt_out.video.i_sar_num = p_sps->vui.i_sar_num;
-            p_dec->fmt_out.video.i_sar_den = p_sps->vui.i_sar_den;
-        }
+        h264_get_aspect_ratio( p_sps,
+                              &p_dec->fmt_out.video.i_sar_num,
+                              &p_dec->fmt_out.video.i_sar_den );
 
         if( !p_dec->fmt_out.video.i_frame_rate ||
             !p_dec->fmt_out.video.i_frame_rate_base )
         {
             /* on first run == if fmt_in does not provide frame rate info */
             /* If we have frame rate info in the stream */
-            if(p_sps->vui.b_valid &&
-               p_sps->vui.i_num_units_in_tick > 0 &&
-               p_sps->vui.i_time_scale > 1 )
-            {
-                date_Change( &p_sys->dts, p_sps->vui.i_time_scale,
-                                          p_sps->vui.i_num_units_in_tick );
-            }
+            unsigned nd[2];
+            if( h264_get_frame_rate( p_sps, nd, &nd[1] ) )
+                date_Change( &p_sys->dts, nd[0], nd[1] );
             /* else use the default num/den */
             p_dec->fmt_out.video.i_frame_rate = p_sys->dts.i_divider_num >> 1; /* num_clock_ts == 2 */
             p_dec->fmt_out.video.i_frame_rate_base = p_sys->dts.i_divider_den;
         }
 
-        if( p_dec->fmt_in->video.primaries == COLOR_PRIMARIES_UNDEF &&
-            p_sps->vui.b_valid )
+        if( p_dec->fmt_in->video.primaries == COLOR_PRIMARIES_UNDEF )
         {
             h264_get_colorimetry( p_sps, &p_dec->fmt_out.video.primaries,
                                   &p_dec->fmt_out.video.transfer,
@@ -264,34 +259,6 @@ static void ActivateSets( decoder_t *p_dec, const h264_sequence_parameter_set_t
     }
 }
 
-static bool IsFirstVCLNALUnit( const h264_slice_t *p_prev, const h264_slice_t *p_cur )
-{
-    /* Detection of the first VCL NAL unit of a primary coded picture
-     * (cf. 7.4.1.2.4) */
-    if( p_cur->i_frame_num != p_prev->i_frame_num ||
-        p_cur->i_pic_parameter_set_id != p_prev->i_pic_parameter_set_id ||
-        p_cur->i_field_pic_flag != p_prev->i_field_pic_flag ||
-       !p_cur->i_nal_ref_idc != !p_prev->i_nal_ref_idc )
-        return true;
-    if( (p_cur->i_bottom_field_flag != -1) &&
-        (p_prev->i_bottom_field_flag != -1) &&
-        (p_cur->i_bottom_field_flag != p_prev->i_bottom_field_flag) )
-        return true;
-    if( p_cur->i_pic_order_cnt_type == 0 &&
-       ( p_cur->i_pic_order_cnt_lsb != p_prev->i_pic_order_cnt_lsb ||
-         p_cur->i_delta_pic_order_cnt_bottom != p_prev->i_delta_pic_order_cnt_bottom ) )
-        return true;
-    else if( p_cur->i_pic_order_cnt_type == 1 &&
-           ( p_cur->i_delta_pic_order_cnt0 != p_prev->i_delta_pic_order_cnt0 ||
-             p_cur->i_delta_pic_order_cnt1 != p_prev->i_delta_pic_order_cnt1 ) )
-        return true;
-    if( ( p_cur->i_nal_type == H264_NAL_SLICE_IDR || p_prev->i_nal_type == H264_NAL_SLICE_IDR ) &&
-        ( p_cur->i_nal_type != p_prev->i_nal_type || p_cur->i_idr_pic_id != p_prev->i_idr_pic_id ) )
-        return true;
-
-    return false;
-}
-
 static void DropStoredNAL( decoder_sys_t *p_sys )
 {
     block_ChainRelease( p_sys->frame.p_head );
@@ -334,12 +301,12 @@ static int Open( vlc_object_t *p_this )
     }
 
     packetizer_Init( &p_sys->packetizer,
-                     p_h264_startcode, sizeof(p_h264_startcode), startcode_FindAnnexB,
-                     p_h264_startcode, 1, 5,
+                     annexb_startcode3, 3, startcode_FindAnnexB,
+                     annexb_startcode3, 1, 5,
                      PacketizeReset, PacketizeParse, PacketizeValidate, PacketizeDrain,
                      p_dec );
 
-    p_sys->b_slice = false;
+    p_sys->p_slice = NULL;
     p_sys->frame.p_head = NULL;
     p_sys->frame.pp_append = &p_sys->frame.p_head;
     p_sys->leading.p_head = NULL;
@@ -363,8 +330,6 @@ static int Open( vlc_object_t *p_this )
         p_sys->spsext[i].p_block = NULL;
     p_sys->i_recovery_frame_cnt = UINT_MAX;
 
-    h264_slice_init( &p_sys->slice );
-
     p_sys->i_next_block_flags = 0;
     p_sys->b_recovered = false;
     p_sys->i_recoveryfnum = UINT_MAX;
@@ -475,6 +440,9 @@ static void Close( vlc_object_t *p_this )
     DropStoredNAL( p_sys );
     ReleaseXPS( p_sys );
 
+    if( p_sys->p_slice )
+        h264_slice_release( p_sys->p_slice );
+
     packetizer_Clean( &p_sys->packetizer );
 
     cc_storage_delete( p_sys->p_ccs );
@@ -530,10 +498,11 @@ static void ResetOutputVariables( decoder_sys_t *p_sys )
 {
     p_sys->i_frame_dts = VLC_TICK_INVALID;
     p_sys->i_frame_pts = VLC_TICK_INVALID;
-    p_sys->slice.type = H264_SLICE_TYPE_UNKNOWN;
+    if( p_sys->p_slice )
+        h264_slice_release( p_sys->p_slice );
+    p_sys->p_slice = NULL;
     p_sys->b_new_sps = false;
     p_sys->b_new_pps = false;
-    p_sys->b_slice = false;
     /* From SEI */
     p_sys->i_dpb_output_delay = 0;
     p_sys->i_pic_struct = UINT8_MAX;
@@ -545,7 +514,7 @@ static void PacketizeReset( void *p_private, bool b_flush )
     decoder_t *p_dec = p_private;
     decoder_sys_t *p_sys = p_dec->p_sys;
 
-    if( b_flush || !p_sys->b_slice )
+    if( b_flush || !p_sys->p_slice )
     {
         DropStoredNAL( p_sys );
         ResetOutputVariables( p_sys );
@@ -582,7 +551,7 @@ static block_t * PacketizeDrain( void *p_private )
     decoder_t *p_dec = p_private;
     decoder_sys_t *p_sys = p_dec->p_sys;
 
-    if( !p_sys->b_slice )
+    if( !p_sys->p_slice )
         return NULL;
 
     block_t *p_out = OutputPicture( p_dec );
@@ -610,7 +579,7 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
     bool b_au_end = p_frag->i_flags & BLOCK_FLAG_AU_END;
     p_frag->i_flags &= ~BLOCK_FLAG_AU_END;
 
-    if( p_sys->b_slice && (!p_sys->p_active_pps || !p_sys->p_active_sps) )
+    if( p_sys->p_slice && (!p_sys->p_active_pps || !p_sys->p_active_sps) )
     {
         msg_Warn( p_dec, "waiting for SPS/PPS" );
 
@@ -629,7 +598,7 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
         case H264_NAL_SLICE_DPC:
         case H264_NAL_SLICE_IDR:
         {
-            h264_slice_t newslice;
+            h264_slice_t *p_newslice;
 
             if( i_nal_type == H264_NAL_SLICE_IDR )
             {
@@ -638,13 +607,12 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
                 p_sys->i_recoveryfnum = UINT_MAX;
             }
 
-            if( ParseSliceHeader( p_dec, p_frag, &newslice ) )
+            if( (p_newslice = ParseSliceHeader( p_dec, p_frag )) )
             {
                 /* Only IDR carries the id, to be propagated */
-                if( newslice.i_idr_pic_id == -1 )
-                    newslice.i_idr_pic_id = p_sys->slice.i_idr_pic_id;
+                h264_slice_copy_idr_id( p_sys->p_slice, p_newslice );
 
-                bool b_new_picture = IsFirstVCLNALUnit( &p_sys->slice, &newslice );
+                bool b_new_picture = h264_IsFirstVCLNALUnit( p_sys->p_slice, p_newslice );
                 if( b_new_picture )
                 {
                     /* Parse SEI for that frame now we should have matched SPS/PPS */
@@ -656,19 +624,19 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
                                               1 /* nal header */, ParseSeiCallback, p_dec );
                     }
 
-                    if( p_sys->b_slice )
+                    if( p_sys->p_slice )
                         p_pic = OutputPicture( p_dec );
                 }
 
                 /* */
-                p_sys->slice = newslice;
+                h264_slice_release( p_sys->p_slice );
+                p_sys->p_slice = p_newslice;
             }
             else
             {
                 p_sys->p_active_pps = NULL;
                 /* Fragment will be discarded later on */
             }
-            p_sys->b_slice = true;
 
             block_ChainLastAppend( &p_sys->frame.pp_append, p_frag );
         } break;
@@ -676,7 +644,7 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
         /*** Prefix NALs ***/
 
         case H264_NAL_AU_DELIMITER:
-            if( p_sys->b_slice )
+            if( p_sys->p_slice )
                 p_pic = OutputPicture( p_dec );
 
             /* clear junk if no pic, we're always the first nal */
@@ -689,7 +657,7 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
 
         case H264_NAL_SPS:
         case H264_NAL_PPS:
-            if( p_sys->b_slice )
+            if( p_sys->p_slice )
                 p_pic = OutputPicture( p_dec );
 
             /* Stored for insert on keyframes */
@@ -700,7 +668,7 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
         break;
 
         case H264_NAL_SEI:
-            if( p_sys->b_slice )
+            if( p_sys->p_slice )
                 p_pic = OutputPicture( p_dec );
 
             p_frag->i_flags |= BLOCK_FLAG_PRIVATE_SEI;
@@ -709,7 +677,7 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
 
         case H264_NAL_SPS_EXT:
             PutXPS( p_dec, i_nal_type, p_frag );
-            if( p_sys->b_slice )
+            if( p_sys->p_slice )
                 p_pic = OutputPicture( p_dec );
             break;
 
@@ -718,7 +686,7 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
         case H264_NAL_DEPTH_PS:
         case H264_NAL_RESERVED_17:
         case H264_NAL_RESERVED_18:
-            if( p_sys->b_slice )
+            if( p_sys->p_slice )
                 p_pic = OutputPicture( p_dec );
 
             block_ChainLastAppend( &p_sys->leading.pp_append, p_frag );
@@ -733,7 +701,7 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
 
             /* important for still pictures/menus */
             p_sys->i_next_block_flags |= BLOCK_FLAG_END_OF_SEQUENCE;
-            if( p_sys->b_slice )
+            if( p_sys->p_slice )
                 p_pic = OutputPicture( p_dec );
         break;
 
@@ -760,7 +728,7 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
             date_Set( &p_sys->dts, i_frag_dts );
     }
 
-    if( p_sys->b_slice && b_au_end && !p_pic )
+    if( p_sys->p_slice && b_au_end && !p_pic )
     {
         p_pic = OutputPicture( p_dec );
     }
@@ -774,17 +742,6 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr
     return p_pic;
 }
 
-static bool CanSwapPTSwithDTS( const h264_slice_t *p_slice,
-                               const h264_sequence_parameter_set_t *p_sps )
-{
-    if( p_slice->i_nal_ref_idc == 0 && p_slice->type == H264_SLICE_TYPE_B )
-        return true;
-    else if( p_sps->vui.b_valid )
-        return p_sps->vui.i_max_num_reorder_frames == 0;
-    else
-        return p_sps->i_profile == PROFILE_H264_CAVLC_INTRA;
-}
-
 static block_t *OutputPicture( decoder_t *p_dec )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
@@ -812,21 +769,23 @@ static block_t *OutputPicture( decoder_t *p_dec )
     }
 
     if( !p_sys->b_recovered && p_sys->i_recoveryfnum == UINT_MAX &&
-         p_sys->i_recovery_frame_cnt == UINT_MAX && p_sys->slice.type == H264_SLICE_TYPE_I )
+        p_sys->i_recovery_frame_cnt == UINT_MAX && h264_get_slice_type(p_sys->p_slice) == H264_SLICE_TYPE_I )
     {
         /* No way to recover using SEI, just sync on I Slice */
         p_sys->b_recovered = true;
     }
 
-    bool b_need_sps_pps = p_sys->slice.type == H264_SLICE_TYPE_I &&
+    bool b_need_sps_pps = h264_get_slice_type(p_sys->p_slice) == H264_SLICE_TYPE_I &&
                           p_sys->p_active_pps && p_sys->p_active_sps;
 
+    const unsigned i_frame_num = h264_get_frame_num(p_sys->p_slice);
+
     /* Handle SEI recovery */
     if ( !p_sys->b_recovered && p_sys->i_recovery_frame_cnt != UINT_MAX &&
          p_sys->i_recoveryfnum == UINT_MAX )
     {
-        p_sys->i_recoveryfnum = p_sys->slice.i_frame_num + p_sys->i_recovery_frame_cnt;
-        p_sys->i_recoverystartfnum = p_sys->slice.i_frame_num;
+        p_sys->i_recoveryfnum = i_frame_num + p_sys->i_recovery_frame_cnt;
+        p_sys->i_recoverystartfnum = i_frame_num;
         b_need_sps_pps = true; /* SPS/PPS must be inserted for SEI recovery */
         msg_Dbg( p_dec, "Recovering using SEI, prerolling %u reference pics", p_sys->i_recovery_frame_cnt );
     }
@@ -834,13 +793,13 @@ static block_t *OutputPicture( decoder_t *p_dec )
     if( p_sys->i_recoveryfnum != UINT_MAX )
     {
         assert(p_sys->b_recovered == false);
-        const unsigned maxFrameNum = 1 << (p_sps->i_log2_max_frame_num + 4);
+        const unsigned maxFrameNum = h264_get_max_frame_num( p_sps );
 
         if( ( p_sys->i_recoveryfnum > maxFrameNum &&
-              p_sys->slice.i_frame_num < p_sys->i_recoverystartfnum &&
-              p_sys->slice.i_frame_num >= p_sys->i_recoveryfnum % maxFrameNum ) ||
+              i_frame_num < p_sys->i_recoverystartfnum &&
+              i_frame_num >= p_sys->i_recoveryfnum % maxFrameNum ) ||
             ( p_sys->i_recoveryfnum <= maxFrameNum &&
-              p_sys->slice.i_frame_num >= p_sys->i_recoveryfnum ) )
+              i_frame_num >= p_sys->i_recoveryfnum ) )
         {
             p_sys->i_recoveryfnum = UINT_MAX;
             p_sys->b_recovered = true;
@@ -892,11 +851,11 @@ static block_t *OutputPicture( decoder_t *p_dec )
 
     /* for PTS Fixup, interlaced fields (multiple AU/block) */
     int tFOC = 0, bFOC = 0, PictureOrderCount = 0;
-    h264_compute_poc( p_sps, &p_sys->slice, &p_sys->pocctx, &PictureOrderCount, &tFOC, &bFOC );
+    h264_compute_poc( p_sps, p_sys->p_slice, &p_sys->pocctx, &PictureOrderCount, &tFOC, &bFOC );
 
-    unsigned i_num_clock_ts = h264_get_num_ts( p_sps, &p_sys->slice, p_sys->i_pic_struct, tFOC, bFOC );
+    unsigned i_num_clock_ts = h264_get_num_ts( p_sps, p_sys->p_slice, p_sys->i_pic_struct, tFOC, bFOC );
 
-    if( p_sps->frame_mbs_only_flag == 0 && p_sps->vui.b_pic_struct_present_flag )
+    if( !h264_is_frames_only( p_sps ) && p_sys->i_pic_struct != UINT8_MAX )
     {
         switch( p_sys->i_pic_struct )
         {
@@ -904,8 +863,8 @@ static block_t *OutputPicture( decoder_t *p_dec )
         case 1:
         case 2:
             p_pic->i_flags |= BLOCK_FLAG_SINGLE_FIELD;
-            p_pic->i_flags |= (!p_sys->slice.i_bottom_field_flag) ? BLOCK_FLAG_TOP_FIELD_FIRST
-                                                                  : BLOCK_FLAG_BOTTOM_FIELD_FIRST;
+            p_pic->i_flags |= h264_slice_top_field(p_sys->p_slice) ? BLOCK_FLAG_TOP_FIELD_FIRST
+                                                                   : BLOCK_FLAG_BOTTOM_FIELD_FIRST;
             break;
         /* Each of the following slices contains multiple fields */
         case 3:
@@ -933,7 +892,7 @@ static block_t *OutputPicture( decoder_t *p_dec )
     if( p_pic->i_dts == VLC_TICK_INVALID )
         p_pic->i_dts = date_Get( &p_sys->dts );
 
-    if( p_sys->slice.type == H264_SLICE_TYPE_I )
+    if( h264_get_slice_type( p_sys->p_slice ) == H264_SLICE_TYPE_I )
         p_sys->prevdatedpoc.pts = VLC_TICK_INVALID;
 
     if( p_pic->i_pts == VLC_TICK_INVALID )
@@ -956,11 +915,11 @@ static block_t *OutputPicture( decoder_t *p_dec )
                 p_pic->i_pts = p_pic->i_dts;
         }
         /* In case there's no PTS at all */
-        else if( CanSwapPTSwithDTS( &p_sys->slice, p_sps ) )
+        else if( h264_CanSwapPTSWithDTS( p_sys->p_slice, p_sps ) )
         {
             p_pic->i_pts = p_pic->i_dts;
         }
-        else if( p_sys->slice.type == H264_SLICE_TYPE_I &&
+        else if( h264_get_slice_type( p_sys->p_slice ) == H264_SLICE_TYPE_I &&
                  date_Get( &p_sys->dts ) != VLC_TICK_INVALID )
         {
             /* Hell no PTS on IDR. We're totally blind */
@@ -970,7 +929,7 @@ static block_t *OutputPicture( decoder_t *p_dec )
         }
     }
     else if( p_pic->i_dts == VLC_TICK_INVALID &&
-             CanSwapPTSwithDTS( &p_sys->slice, p_sps ) )
+             h264_CanSwapPTSWithDTS( p_sys->p_slice, p_sps ) )
     {
         p_pic->i_dts = p_pic->i_pts;
         if( date_Get( &p_sys->dts ) == VLC_TICK_INVALID )
@@ -991,10 +950,11 @@ static block_t *OutputPicture( decoder_t *p_dec )
     }
 
 #if 0
-    msg_Err(p_dec, "F/BOC %d/%d POC %d %d rec %d flags %x ref%d fn %d fp %d %d pts %ld len %ld",
+    msg_Err(p_dec, "F/BOC %d/%d POC %d %d rec %d flags %x ref%d fn %d fp %d %ld pts %ld len %ld",
                     tFOC, bFOC, PictureOrderCount,
-                    p_sys->slice.type, p_sys->b_recovered, p_pic->i_flags,
-                    p_sys->slice.i_nal_ref_idc, p_sys->slice.i_frame_num, p_sys->slice.i_field_pic_flag,
+                    h264_get_slice_type(p_sys->p_slice), p_sys->b_recovered, p_pic->i_flags,
+                    h264_get_nal_ref_idc(p_sys->p_slice), h264_get_frame_num(p_sys->p_slice),
+                    h264_is_field_pic(p_sys->p_slice),
                     p_pic->i_pts - p_pic->i_dts, p_pic->i_pts % VLC_TICK_FROM_SEC(100), p_pic->i_length);
 #endif
 
@@ -1013,7 +973,7 @@ static block_t *OutputPicture( decoder_t *p_dec )
         p_sys->i_next_block_flags = 0;
     }
 
-    switch( p_sys->slice.type )
+    switch( h264_get_slice_type( p_sys->p_slice ) )
     {
         case H264_SLICE_TYPE_P:
             p_pic->i_flags |= BLOCK_FLAG_TYPE_P;
@@ -1182,10 +1142,10 @@ static void GetSPSPPS( uint8_t i_pps_id, void *priv,
     if( *pp_pps == NULL )
         *pp_sps = NULL;
     else
-        *pp_sps = p_sys->sps[(*pp_pps)->i_sps_id].p_sps;
+        *pp_sps = p_sys->sps[h264_get_pps_sps_id(*pp_pps)].p_sps;
 }
 
-static bool ParseSliceHeader( decoder_t *p_dec, const block_t *p_frag, h264_slice_t *p_slice )
+static h264_slice_t * ParseSliceHeader( decoder_t *p_dec, const block_t *p_frag )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
 
@@ -1193,20 +1153,24 @@ static bool ParseSliceHeader( decoder_t *p_dec, const block_t *p_frag, h264_slic
     size_t i_stripped = p_frag->i_buffer;
 
     if( !hxxx_strip_AnnexB_startcode( &p_stripped, &i_stripped ) || i_stripped < 2 )
-        return false;
+        return NULL;
 
-    if( !h264_decode_slice( p_stripped, i_stripped, GetSPSPPS, p_sys, p_slice ) )
-        return false;
+    h264_slice_t *p_slice = h264_decode_slice( p_stripped, i_stripped, GetSPSPPS, p_sys );
+    if( !p_slice )
+        return NULL;
 
     const h264_sequence_parameter_set_t *p_sps;
     const h264_picture_parameter_set_t *p_pps;
-    GetSPSPPS( p_slice->i_pic_parameter_set_id, p_sys, &p_sps, &p_pps );
+    GetSPSPPS( h264_get_slice_pps_id( p_slice ), p_sys, &p_sps, &p_pps );
     if( unlikely( !p_sps || !p_pps) )
-        return false;
+    {
+        h264_slice_release( p_slice );
+        return NULL;
+    }
 
     ActivateSets( p_dec, p_sps, p_pps );
 
-    return true;
+    return p_slice;
 }
 
 static bool ParseSeiCallback( const hxxx_sei_data_t *p_sei_data, void *cbdata )
@@ -1226,19 +1190,9 @@ static bool ParseSeiCallback( const hxxx_sei_data_t *p_sei_data, void *cbdata )
                 break;
             }
 
-            if( p_sps->vui.b_valid )
-            {
-                if( p_sps->vui.b_hrd_parameters_present_flag )
-                {
-                    bs_read( p_sei_data->p_bs, p_sps->vui.i_cpb_removal_delay_length_minus1 + 1 );
-                    p_sys->i_dpb_output_delay =
-                            bs_read( p_sei_data->p_bs, p_sps->vui.i_dpb_output_delay_length_minus1 + 1 );
-                }
-
-                if( p_sps->vui.b_pic_struct_present_flag )
-                    p_sys->i_pic_struct = bs_read( p_sei_data->p_bs, 4 );
-                /* + unparsed remains */
-            }
+            h264_decode_sei_pic_timing( p_sei_data->p_bs, p_sps,
+                                       &p_sys->i_pic_struct,
+                                       &p_sys->i_dpb_output_delay );
         } break;
 
             /* Look for user_data_registered_itu_t_t35 */


=====================================
modules/packetizer/h264_nal.c
=====================================
@@ -400,10 +400,9 @@ static bool h264_parse_sequence_parameter_set_rbsp( bs_t *p_bs,
     }
 
     /* vui */
-    i_tmp = bs_read( p_bs, 1 );
-    if( i_tmp )
+    p_sps->vui_parameters_present_flag = bs_read( p_bs, 1 );
+    if( p_sps->vui_parameters_present_flag )
     {
-        p_sps->vui.b_valid = true;
         /* read the aspect ratio part if any */
         i_tmp = bs_read( p_bs, 1 );
         if( i_tmp )
@@ -775,6 +774,16 @@ bool h264_get_xps_id( const uint8_t *p_buf, size_t i_buf, uint8_t *pi_id )
     return !bs_error( &bs ) && *pi_id <= i_max;
 }
 
+uint8_t h264_get_sps_id( const h264_sequence_parameter_set_t *p_sps )
+{
+    return p_sps->i_id;
+}
+
+uint8_t h264_get_pps_sps_id( const h264_picture_parameter_set_t *p_pps )
+{
+    return p_pps->i_sps_id;
+}
+
 static const h264_level_limits_t * h264_get_level_limits( const h264_sequence_parameter_set_t *p_sps )
 {
     uint16_t i_level_number = p_sps->i_level;
@@ -845,6 +854,37 @@ bool h264_get_dpb_values( const h264_sequence_parameter_set_t *p_sps,
     return true;
 }
 
+unsigned h264_get_max_frame_num( const h264_sequence_parameter_set_t *p_sps )
+{
+    return 1 << (p_sps->i_log2_max_frame_num + 4);
+}
+
+bool h264_is_frames_only( const h264_sequence_parameter_set_t *p_sps )
+{
+    return p_sps->frame_mbs_only_flag;
+}
+
+bool h264_using_adaptive_frames( const h264_sequence_parameter_set_t *p_sps )
+{
+    return p_sps->mb_adaptive_frame_field_flag;
+}
+
+
+bool h264_get_sps_profile_tier_level( const h264_sequence_parameter_set_t *p_sps,
+                                      uint8_t *pi_profile, uint8_t *pi_level)
+{
+    *pi_profile = p_sps->i_profile;
+    *pi_level = p_sps->i_level;
+    return true;
+}
+
+bool h264_get_constraints_set( const h264_sequence_parameter_set_t *p_sps,
+                               uint8_t *pi_constraints )
+{
+    *pi_constraints = p_sps->i_constraint_set_flags;
+    return true;
+}
+
 bool h264_get_picture_size( const h264_sequence_parameter_set_t *p_sps,
                             unsigned *p_ox, unsigned *p_oy,
                             unsigned *p_w, unsigned *p_h,
@@ -881,6 +921,27 @@ bool h264_get_picture_size( const h264_sequence_parameter_set_t *p_sps,
     return true;
 }
 
+bool h264_get_frame_rate( const h264_sequence_parameter_set_t *p_sps,
+                         unsigned *pi_num, unsigned *pi_den )
+{
+    if(!p_sps->vui_parameters_present_flag || !p_sps->vui.i_num_units_in_tick ||
+        p_sps->vui.i_time_scale <= 1)
+        return false;
+    *pi_num = p_sps->vui.i_time_scale;
+    *pi_den = p_sps->vui.i_num_units_in_tick;
+    return true;
+}
+
+bool h264_get_aspect_ratio( const h264_sequence_parameter_set_t *p_sps,
+                           unsigned *pi_num, unsigned *pi_den )
+{
+    if(!p_sps->vui.i_sar_num || !p_sps->vui.i_sar_den)
+        return false;
+    *pi_num = p_sps->vui.i_sar_num;
+    *pi_den = p_sps->vui.i_sar_den;
+    return true;
+}
+
 bool h264_get_chroma_luma( const h264_sequence_parameter_set_t *p_sps, uint8_t *pi_chroma_format,
                            uint8_t *pi_depth_luma, uint8_t *pi_depth_chroma )
 {
@@ -895,7 +956,7 @@ bool h264_get_colorimetry( const h264_sequence_parameter_set_t *p_sps,
                            video_color_space_t *p_colorspace,
                            video_color_range_t *p_full_range )
 {
-    if( !p_sps->vui.b_valid )
+    if( !p_sps->vui_parameters_present_flag )
         return false;
     *p_primaries =
         iso_23001_8_cp_to_vlc_primaries( p_sps->vui.colour.i_colour_primaries );
@@ -952,3 +1013,24 @@ bool h264_decode_sei_recovery_point( bs_t *p_bs, h264_sei_recovery_point_t *p_re
     //int i_changing_slice_group = bs_read( p_bs, 2 );
     return true;
 }
+
+bool h264_decode_sei_pic_timing(  bs_t *p_bs,
+                                  const h264_sequence_parameter_set_t *p_sps,
+                                  uint8_t *pic_struct, uint8_t *output_delay  )
+{
+    if( !p_sps->vui_parameters_present_flag )
+        return false;
+
+    if( p_sps->vui.b_hrd_parameters_present_flag )
+    {
+        bs_read( p_bs, p_sps->vui.i_cpb_removal_delay_length_minus1 + 1 );
+        *output_delay =
+            bs_read( p_bs, p_sps->vui.i_dpb_output_delay_length_minus1 + 1 );
+    }
+
+    if( p_sps->vui.b_pic_struct_present_flag )
+        *pic_struct = bs_read( p_bs, 4 );
+
+    /* + unparsed remains */
+    return true;
+}


=====================================
modules/packetizer/h264_nal.h
=====================================
@@ -99,6 +99,9 @@ void h264_release_sps( h264_sequence_parameter_set_t * );
 void h264_release_pps( h264_picture_parameter_set_t * );
 void h264_release_sps_extension( h264_sequence_parameter_set_extension_t * );
 
+uint8_t h264_get_sps_id( const h264_sequence_parameter_set_t * );
+uint8_t h264_get_pps_sps_id( const h264_picture_parameter_set_t * );
+
 struct h264_sequence_parameter_set_t
 {
     uint8_t i_id;
@@ -130,8 +133,8 @@ struct h264_sequence_parameter_set_t
     int32_t offset_for_ref_frame[255];
     int i_log2_max_pic_order_cnt_lsb;
 
+    bool vui_parameters_present_flag;
     struct {
-        bool b_valid;
         int i_sar_num, i_sar_den;
         struct {
             bool b_full_range;
@@ -207,10 +210,22 @@ uint8_t * h264_avcC_to_AnnexB_NAL( const uint8_t *p_buf, size_t i_buf,
 bool h264_get_dpb_values( const h264_sequence_parameter_set_t *,
                           uint8_t *pi_depth, unsigned *pi_delay );
 
+unsigned h264_get_max_frame_num( const h264_sequence_parameter_set_t * );
+bool h264_is_frames_only( const h264_sequence_parameter_set_t * );
+bool h264_using_adaptive_frames( const h264_sequence_parameter_set_t * );
+
+bool h264_get_sps_profile_tier_level( const h264_sequence_parameter_set_t *,
+                                     uint8_t *pi_profile, uint8_t *pi_level );
+bool h264_get_constraints_set( const h264_sequence_parameter_set_t *p_sps,
+                               uint8_t *pi_constraints );
 bool h264_get_picture_size( const h264_sequence_parameter_set_t *,
                             unsigned *p_ox, unsigned *p_oy,
                             unsigned *p_w, unsigned *p_h,
                             unsigned *p_vw, unsigned *p_vh );
+bool h264_get_frame_rate( const h264_sequence_parameter_set_t *,
+                          unsigned *pi_num, unsigned *pi_den );
+bool h264_get_aspect_ratio( const h264_sequence_parameter_set_t *,
+                           unsigned *pi_num, unsigned *pi_den );
 bool h264_get_chroma_luma( const h264_sequence_parameter_set_t *, uint8_t *pi_chroma_format,
                            uint8_t *pi_depth_luma, uint8_t *pi_depth_chroma );
 bool h264_get_colorimetry( const h264_sequence_parameter_set_t *p_sps,
@@ -229,6 +244,9 @@ typedef struct
 } h264_sei_recovery_point_t;
 
 bool h264_decode_sei_recovery_point( bs_t *, h264_sei_recovery_point_t * );
+bool h264_decode_sei_pic_timing(  bs_t *, const h264_sequence_parameter_set_t *,
+                                  uint8_t *, uint8_t *  );
+
 
 #ifdef __cplusplus
 }


=====================================
modules/packetizer/h264_slice.c
=====================================
@@ -29,14 +29,84 @@
 #include "hxxx_nal.h"
 #include "hxxx_ep3b.h"
 
-bool h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
-                        void (* get_sps_pps)(uint8_t, void *,
+struct h264_slice_s
+{
+    int i_nal_type;
+    int i_nal_ref_idc;
+
+    int type;
+    int i_pic_parameter_set_id;
+    unsigned i_frame_num;
+
+    int i_field_pic_flag;
+    int i_bottom_field_flag;
+
+    int i_idr_pic_id;
+
+    int i_pic_order_cnt_type;
+    int i_pic_order_cnt_lsb;
+    int i_delta_pic_order_cnt_bottom;
+
+    int i_delta_pic_order_cnt0;
+    int i_delta_pic_order_cnt1;
+
+    bool no_output_of_prior_pics_flag;
+    bool has_mmco5;
+};
+
+enum h264_slice_type_e h264_get_slice_type( const h264_slice_t *p_slice )
+{
+    return p_slice->type;
+}
+
+bool h264_has_mmco5( const h264_slice_t *p_slice )
+{
+    return p_slice->has_mmco5;
+}
+
+bool h264_is_field_pic( const h264_slice_t *p_slice )
+{
+    return p_slice->i_field_pic_flag;
+}
+
+int h264_get_slice_pps_id( const h264_slice_t *p_slice )
+{
+    return p_slice->i_pic_parameter_set_id;
+}
+
+unsigned h264_get_frame_num( const h264_slice_t *p_slice )
+{
+    return p_slice->i_frame_num;
+}
+
+unsigned h264_get_nal_ref_idc( const h264_slice_t *p_slice )
+{
+    return p_slice->i_nal_ref_idc;
+}
+
+void h264_slice_release( h264_slice_t *p_slice )
+{
+    free( p_slice );
+}
+
+void h264_slice_copy_idr_id( const h264_slice_t *src, h264_slice_t *dst )
+{
+    if( !src || src->i_nal_type != H264_NAL_SLICE_IDR ) /* value only set on IDR */
+        return;
+    dst->i_idr_pic_id = src->i_idr_pic_id;
+}
+
+h264_slice_t * h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
+                                  void (* get_sps_pps)(uint8_t, void *,
                                              const h264_sequence_parameter_set_t **,
                                              const h264_picture_parameter_set_t ** ),
-                        void *priv, h264_slice_t *p_slice )
+                                  void *priv )
 {
+    h264_slice_t *p_slice = calloc( 1, sizeof(*p_slice) );
+    if( !p_slice )
+        return NULL;
+
     int i_slice_type;
-    h264_slice_init( p_slice );
     bs_t s;
     struct hxxx_bsfw_ep3b_ctx_s bsctx;
     hxxx_bsfw_ep3b_ctx_init( &bsctx );
@@ -52,6 +122,8 @@ bool h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
 
     /* slice_type */
     i_slice_type = bs_read_ue( &s );
+    if( i_slice_type > 9 )
+        goto error;
     p_slice->type = i_slice_type % 5;
 
     /* */
@@ -60,7 +132,7 @@ bool h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
 
     p_slice->i_pic_parameter_set_id = bs_read_ue( &s );
     if( p_slice->i_pic_parameter_set_id > H264_PPS_ID_MAX )
-        return false;
+        goto error;
 
     const h264_sequence_parameter_set_t *p_sps;
     const h264_picture_parameter_set_t *p_pps;
@@ -68,7 +140,7 @@ bool h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
     /* Bind matched/referred PPS and SPS */
     get_sps_pps( p_slice->i_pic_parameter_set_id, priv, &p_sps, &p_pps );
     if( !p_sps || !p_pps )
-        return false;
+        goto error;
 
     p_slice->i_frame_num = bs_read( &s, p_sps->i_log2_max_frame_num + 4 );
 
@@ -81,7 +153,11 @@ bool h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
     }
 
     if( p_slice->i_nal_type == H264_NAL_SLICE_IDR )
+    {
         p_slice->i_idr_pic_id = bs_read_ue( &s );
+        if( p_slice->i_idr_pic_id > 65535 )
+            goto error;
+    }
 
     p_slice->i_pic_order_cnt_type = p_sps->i_pic_order_cnt_type;
     if( p_sps->i_pic_order_cnt_type == 0 )
@@ -122,7 +198,7 @@ bool h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
     {
         /* Early END, don't waste parsing below */
         p_slice->has_mmco5 = false;
-        return true;
+        return p_slice;
     }
 
     /* ref_pic_list_[mvc_]modification() */
@@ -149,7 +225,7 @@ bool h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
     }
 
     if( bs_error( &s ) )
-        return false;
+        goto error;
 
     /* pred_weight_table() */
     if( ( p_pps->weighted_pred_flag && ( i_slice_type == 0 || i_slice_type == 5 || /* P, SP */
@@ -198,6 +274,8 @@ bool h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
             do
             {
                 mmco = bs_read_ue( &s );
+                if( mmco > 6 )
+                    goto error;
                 if( mmco == 1 || mmco == 3 )
                     bs_read_ue( &s ); /* diff_pics_minus1 */
                 if( mmco == 2 )
@@ -218,7 +296,13 @@ bool h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
 
     /* If you need to store anything else than MMCO presence above, care of "Early END" cases */
 
-    return !bs_error( &s );
+    if(bs_error( &s ))
+        goto error;
+    return p_slice;
+
+error:
+    h264_slice_release( p_slice );
+    return NULL;
 }
 
 
@@ -383,3 +467,49 @@ uint8_t h264_get_num_ts( const h264_sequence_parameter_set_t *p_sps,
     const uint8_t rgi_numclock[9] = { 2, 1, 1, 2, 2, 3, 3, 4, 6 };
     return rgi_numclock[ i_pic_struct ];
 }
+
+bool h264_slice_top_field( const h264_slice_t *p_slice )
+{
+    return !p_slice->i_bottom_field_flag;
+}
+
+bool h264_IsFirstVCLNALUnit( const h264_slice_t *p_prev, const h264_slice_t *p_cur )
+{
+    /* Detection of the first VCL NAL unit of a primary coded picture
+     * (cf. 7.4.1.2.4) */
+    if( !p_prev )
+        return true;
+    if( p_cur->i_frame_num != p_prev->i_frame_num ||
+        p_cur->i_pic_parameter_set_id != p_prev->i_pic_parameter_set_id ||
+        p_cur->i_field_pic_flag != p_prev->i_field_pic_flag ||
+        !p_cur->i_nal_ref_idc != !p_prev->i_nal_ref_idc )
+        return true;
+    if( p_cur->i_field_pic_flag && /* present in both and differs in value */
+        p_cur->i_bottom_field_flag != p_prev->i_bottom_field_flag )
+        return true;
+    if( p_cur->i_pic_order_cnt_type == p_prev->i_pic_order_cnt_type )
+    {
+        if( p_cur->i_pic_order_cnt_type == 0 &&
+            ( p_cur->i_pic_order_cnt_lsb != p_prev->i_pic_order_cnt_lsb ||
+             p_cur->i_delta_pic_order_cnt_bottom != p_prev->i_delta_pic_order_cnt_bottom ) )
+            return true;
+        else if( p_cur->i_pic_order_cnt_type == 1 &&
+                 ( p_cur->i_delta_pic_order_cnt0 != p_prev->i_delta_pic_order_cnt0 ||
+                  p_cur->i_delta_pic_order_cnt1 != p_prev->i_delta_pic_order_cnt1 ) )
+            return true;
+    }
+    if( ( p_cur->i_nal_type == H264_NAL_SLICE_IDR || p_prev->i_nal_type == H264_NAL_SLICE_IDR ) &&
+        ( p_cur->i_nal_type != p_prev->i_nal_type || p_cur->i_idr_pic_id != p_prev->i_idr_pic_id ) )
+        return true;
+    return false;
+}
+
+bool h264_CanSwapPTSWithDTS( const h264_slice_t *p_slice, const h264_sequence_parameter_set_t *p_sps )
+{
+    if( p_slice->i_nal_ref_idc == 0 && p_slice->type == H264_SLICE_TYPE_B )
+        return true;
+    else if( p_sps->vui_parameters_present_flag )
+        return p_sps->vui.i_max_num_reorder_frames == 0;
+    else
+        return p_sps->i_profile == PROFILE_H264_CAVLC_INTRA;
+}


=====================================
modules/packetizer/h264_slice.h
=====================================
@@ -30,54 +30,33 @@ enum h264_slice_type_e
     H264_SLICE_TYPE_UNKNOWN,
 };
 
-typedef struct
-{
-    int i_nal_type;
-    int i_nal_ref_idc;
-
-    enum h264_slice_type_e type;
-    int i_pic_parameter_set_id;
-    unsigned i_frame_num;
+typedef struct h264_slice_s h264_slice_t;
 
-    int i_field_pic_flag;
-    int i_bottom_field_flag;
+enum h264_slice_type_e h264_get_slice_type( const h264_slice_t *p_slice );
 
-    int i_idr_pic_id;
+enum h264_slice_struct_e
+{
+    H264_SLICE_FRAME,
+    H264_SLICE_FIELD,
+    H264_SLICE_MBAFF,
+};
 
-    int i_pic_order_cnt_type;
-    int i_pic_order_cnt_lsb;
-    int i_delta_pic_order_cnt_bottom;
+enum h264_slice_struct_e h264_get_slice_struct( const h264_slice_t *p_slice );
+bool h264_is_field_pic( const h264_slice_t *p_slice );
 
-    int i_delta_pic_order_cnt0;
-    int i_delta_pic_order_cnt1;
+int h264_get_slice_pps_id( const h264_slice_t *p_slice );
+unsigned h264_get_frame_num( const h264_slice_t *p_slice );
+unsigned h264_get_nal_ref_idc( const h264_slice_t *p_slice );
+bool h264_has_mmco5( const h264_slice_t *p_slice );
+void h264_slice_release( h264_slice_t *p_slice );
+void h264_slice_copy_idr_id( const h264_slice_t *src, h264_slice_t *dst );
 
-    bool no_output_of_prior_pics_flag;
-    bool has_mmco5;
-} h264_slice_t;
 
-static inline void h264_slice_init( h264_slice_t *p_slice )
-{
-    p_slice->i_nal_type = -1;
-    p_slice->i_nal_ref_idc = -1;
-    p_slice->i_idr_pic_id = -1;
-    p_slice->i_frame_num = 0;
-    p_slice->type = H264_SLICE_TYPE_UNKNOWN;
-    p_slice->i_pic_parameter_set_id = -1;
-    p_slice->i_field_pic_flag = 0;
-    p_slice->i_bottom_field_flag = -1;
-    p_slice->i_pic_order_cnt_type = -1;
-    p_slice->i_pic_order_cnt_lsb = -1;
-    p_slice->i_delta_pic_order_cnt_bottom = -1;
-    p_slice->i_delta_pic_order_cnt0 = 0;
-    p_slice->i_delta_pic_order_cnt1 = 0;
-    p_slice->has_mmco5 = false;
-}
-
-bool h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
+h264_slice_t * h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
                         void (* get_sps_pps)(uint8_t pps_id, void *,
                                              const h264_sequence_parameter_set_t **,
                                              const h264_picture_parameter_set_t ** ),
-                        void *, h264_slice_t *p_slice );
+                        void * );
 
 typedef struct
 {
@@ -110,4 +89,10 @@ void h264_compute_poc( const h264_sequence_parameter_set_t *p_sps,
 uint8_t h264_get_num_ts( const h264_sequence_parameter_set_t *p_sps,
                          const h264_slice_t *p_slice, uint8_t pic_struct, int tFOC, int bFOC );
 
+bool h264_slice_top_field( const h264_slice_t *p_slice );
+
+bool h264_IsFirstVCLNALUnit( const h264_slice_t *p_prev, const h264_slice_t *p_cur );
+
+bool h264_CanSwapPTSWithDTS( const h264_slice_t *p_slice, const h264_sequence_parameter_set_t * );
+
 #endif


=====================================
modules/packetizer/h26x_nal_common.h
=====================================
@@ -0,0 +1,148 @@
+/*****************************************************************************
+ * h26x_nal_common.h: h26x shared code
+ *****************************************************************************
+ * Copyright © 2010-2024 VideoLabs, VideoLAN and VLC Authors
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#ifndef H26X_NAL_COMMON_H
+# define H26X_NAL_COMMON_H
+
+#include <vlc_common.h>
+#include "iso_color_tables.h"
+
+typedef uint8_t  nal_u1_t;
+typedef uint8_t  nal_u2_t;
+typedef uint8_t  nal_u3_t;
+typedef uint8_t  nal_u4_t;
+typedef uint8_t  nal_u5_t;
+typedef uint8_t  nal_u6_t;
+typedef uint8_t  nal_u7_t;
+typedef uint8_t  nal_u8_t;
+typedef int32_t  nal_se_t;
+typedef uint32_t nal_ue_t;
+
+typedef struct
+{
+    nal_ue_t left_offset;
+    nal_ue_t right_offset;
+    nal_ue_t top_offset;
+    nal_ue_t bottom_offset;
+} h26x_conf_window_t;
+
+static inline
+bool h26x_get_picture_size( nal_u2_t chroma_format_idc,
+                            nal_ue_t pic_width_in_luma_samples,
+                            nal_ue_t pic_height_in_luma_samples,
+                            const h26x_conf_window_t *conf_win,
+                            unsigned *p_ox, unsigned *p_oy,
+                            unsigned *p_w, unsigned *p_h,
+                            unsigned *p_vw, unsigned *p_vh )
+{
+    unsigned ox, oy, w, h, vw, vh;
+    w = vw = pic_width_in_luma_samples;
+    h = vh = pic_height_in_luma_samples;
+
+    static const uint8_t SubWidthHeight[4][2] = { {1, 1}, {2, 2}, {2, 1}, {1, 1} };
+
+    ox = conf_win->left_offset * SubWidthHeight[chroma_format_idc][0];
+    oy = conf_win->top_offset * SubWidthHeight[chroma_format_idc][1];
+
+    vw -= (conf_win->left_offset +  conf_win->right_offset) *
+          SubWidthHeight[chroma_format_idc][0];
+    vh -= (conf_win->bottom_offset + conf_win->top_offset) *
+          SubWidthHeight[chroma_format_idc][1];
+
+    if ( vw > w || vh > h )
+        return false;
+
+    *p_ox = ox; *p_oy = oy;
+    *p_w = w; *p_h = h;
+    *p_vw = vw; *p_vh = vh;
+    return true;
+}
+
+typedef struct
+{
+    nal_u8_t aspect_ratio_idc;
+    uint16_t sar_width;
+    uint16_t sar_height;
+} h26x_aspect_ratio_t;
+
+static inline
+bool h26x_get_aspect_ratio( const h26x_aspect_ratio_t *ar,
+                            unsigned *num, unsigned *den )
+{
+    if( ar->aspect_ratio_idc != 255 )
+    {
+        static const uint8_t ar_table[16][2] =
+            {
+             {    1,      1 },
+             {   12,     11 },
+             {   10,     11 },
+             {   16,     11 },
+             {   40,     33 },
+             {   24,     11 },
+             {   20,     11 },
+             {   32,     11 },
+             {   80,     33 },
+             {   18,     11 },
+             {   15,     11 },
+             {   64,     33 },
+             {  160,     99 },
+             {    4,      3 },
+             {    3,      2 },
+             {    2,      1 },
+             };
+        if( ar->aspect_ratio_idc == 0 ||
+            ar->aspect_ratio_idc >= 17 )
+            return false;
+        *num = ar_table[ar->aspect_ratio_idc - 1][0];
+        *den = ar_table[ar->aspect_ratio_idc - 1][1];
+    }
+    else
+    {
+        *num = ar->sar_width;
+        *den = ar->sar_height;
+    }
+    return true;
+}
+
+typedef struct
+{
+    nal_u8_t colour_primaries;
+    nal_u8_t transfer_characteristics;
+    nal_u8_t matrix_coeffs;
+    nal_u1_t full_range_flag;
+} h26x_colour_description_t;
+
+static inline
+bool h26x_get_colorimetry( const h26x_colour_description_t *colour,
+                           video_color_primaries_t *p_primaries,
+                           video_transfer_func_t *p_transfer,
+                           video_color_space_t *p_colorspace,
+                           video_color_range_t *p_full_range )
+{
+    *p_primaries =
+        iso_23001_8_cp_to_vlc_primaries( colour->colour_primaries );
+    *p_transfer =
+        iso_23001_8_tc_to_vlc_xfer( colour->transfer_characteristics );
+    *p_colorspace =
+        iso_23001_8_mc_to_vlc_coeffs( colour->matrix_coeffs );
+    *p_full_range = colour->full_range_flag ? COLOR_RANGE_FULL : COLOR_RANGE_LIMITED;
+    return true;
+}
+
+#endif


=====================================
modules/packetizer/hevc.c
=====================================
@@ -120,7 +120,6 @@ static block_t *GetXPSCopy(decoder_sys_t *);
 
 #define BLOCK_FLAG_DROP (1 << BLOCK_FLAG_PRIVATE_SHIFT)
 
-static const uint8_t p_hevc_startcode[3] = {0x00, 0x00, 0x01};
 /****************************************************************************
  * Helpers
  ****************************************************************************/
@@ -220,8 +219,8 @@ static int Open(vlc_object_t *p_this)
     INITQ(post);
 
     packetizer_Init(&p_sys->packetizer,
-                    p_hevc_startcode, sizeof(p_hevc_startcode), startcode_FindAnnexB,
-                    p_hevc_startcode, 1, 5,
+                    annexb_startcode3, 3, startcode_FindAnnexB,
+                    annexb_startcode3, 1, 5,
                     PacketizeReset, PacketizeParse, PacketizeValidate, PacketizeDrain,
                     p_dec);
 


=====================================
modules/packetizer/hevc_nal.c
=====================================
@@ -24,9 +24,9 @@
 #include <stdbit.h>
 
 #include "hevc_nal.h"
+#include "h26x_nal_common.h"
 #include "hxxx_nal.h"
 #include "hxxx_ep3b.h"
-#include "iso_color_tables.h"
 
 #include <vlc_common.h>
 #include <vlc_bits.h>
@@ -35,17 +35,6 @@
 
 //#define HEVC_POC_DEBUG
 
-typedef uint8_t  nal_u1_t;
-typedef uint8_t  nal_u2_t;
-typedef uint8_t  nal_u3_t;
-typedef uint8_t  nal_u4_t;
-typedef uint8_t  nal_u5_t;
-typedef uint8_t  nal_u6_t;
-typedef uint8_t  nal_u7_t;
-typedef uint8_t  nal_u8_t;
-typedef int32_t  nal_se_t;
-typedef uint32_t nal_ue_t;
-
 typedef struct
 {
     nal_u2_t profile_space;
@@ -97,12 +86,7 @@ typedef struct
 typedef struct
 {
     nal_u1_t aspect_ratio_info_present_flag;
-    struct
-    {
-        nal_u8_t aspect_ratio_idc;
-        uint16_t sar_width;
-        uint16_t sar_height;
-    } ar;
+    h26x_aspect_ratio_t ar;
     nal_u1_t overscan_info_present_flag;
     nal_u1_t overscan_appropriate_flag;
 
@@ -110,14 +94,8 @@ typedef struct
     struct
     {
         nal_u3_t video_format;
-        nal_u1_t video_full_range_flag;
         nal_u1_t colour_description_present_flag;
-        struct
-        {
-            nal_u8_t colour_primaries;
-            nal_u8_t transfer_characteristics;
-            nal_u8_t matrix_coeffs;
-        } colour;
+        h26x_colour_description_t colour;
     } vs;
 
     nal_u1_t chroma_loc_info_present_flag;
@@ -197,13 +175,7 @@ struct hevc_sequence_parameter_set_t
     nal_ue_t pic_height_in_luma_samples;
 
     nal_u1_t conformance_window_flag;
-    struct
-    {
-    nal_ue_t left_offset;
-    nal_ue_t right_offset;
-    nal_ue_t top_offset;
-    nal_ue_t bottom_offset;
-    } conf_win;
+    h26x_conf_window_t conf_win;
 
     nal_ue_t bit_depth_luma_minus8;
     nal_ue_t bit_depth_chroma_minus8;
@@ -461,7 +433,7 @@ static bool hevc_parse_vui_parameters_rbsp( bs_t *p_bs, hevc_vui_parameters_t *p
     if( p_vui->video_signal_type_present_flag )
     {
         p_vui->vs.video_format = bs_read( p_bs, 3 );
-        p_vui->vs.video_full_range_flag = bs_read1( p_bs );
+        p_vui->vs.colour.full_range_flag = bs_read1( p_bs );
         p_vui->vs.colour_description_present_flag = bs_read1( p_bs );
         if( p_vui->vs.colour_description_present_flag )
         {
@@ -1065,38 +1037,11 @@ bool hevc_get_picture_size( const hevc_sequence_parameter_set_t *p_sps,
                             unsigned *p_w, unsigned *p_h,
                             unsigned *p_vw, unsigned *p_vh )
 {
-    *p_w = *p_vw = p_sps->pic_width_in_luma_samples;
-    *p_h = *p_vh = p_sps->pic_height_in_luma_samples;
-    if( p_sps->conformance_window_flag )
-    {
-        unsigned sub_width_c, sub_height_c;
-
-        if( p_sps->chroma_format_idc == 1 )
-        {
-            sub_width_c = 2;
-            sub_height_c = 2;
-        }
-        else if( p_sps->chroma_format_idc == 2 )
-        {
-            sub_width_c = 2;
-            sub_height_c = 1;
-        }
-        else
-        {
-            sub_width_c = 1;
-            sub_height_c = 1;
-        }
-
-        *p_oy = p_sps->conf_win.top_offset * sub_height_c;
-        *p_ox = p_sps->conf_win.left_offset * sub_width_c;
-        *p_vh -= (p_sps->conf_win.bottom_offset + p_sps->conf_win.top_offset) * sub_height_c;
-        *p_vw -= (p_sps->conf_win.left_offset +  p_sps->conf_win.right_offset) * sub_width_c;
-    }
-    else
-    {
-        *p_oy = *p_ox = 0;
-    }
-    return true;
+    return h26x_get_picture_size( p_sps->chroma_format_idc,
+                                  p_sps->pic_width_in_luma_samples,
+                                  p_sps->pic_height_in_luma_samples,
+                                  &p_sps->conf_win,
+                                  p_ox, p_oy, p_w, p_h, p_vw, p_vh );
 }
 
 void hevc_get_dpb_values( const hevc_sequence_parameter_set_t *p_sps, uint8_t *max_num_reorder_pics,
@@ -1152,45 +1097,9 @@ bool hevc_get_frame_rate( const hevc_sequence_parameter_set_t *p_sps,
 bool hevc_get_aspect_ratio( const hevc_sequence_parameter_set_t *p_sps,
                             unsigned *num, unsigned *den )
 {
-    if( p_sps->vui_parameters_present_flag )
-    {
-        if( p_sps->vui.ar.aspect_ratio_idc != 255 )
-        {
-            static const uint8_t ar_table[16][2] =
-            {
-                {    1,      1 },
-                {   12,     11 },
-                {   10,     11 },
-                {   16,     11 },
-                {   40,     33 },
-                {   24,     11 },
-                {   20,     11 },
-                {   32,     11 },
-                {   80,     33 },
-                {   18,     11 },
-                {   15,     11 },
-                {   64,     33 },
-                {  160,     99 },
-                {    4,      3 },
-                {    3,      2 },
-                {    2,      1 },
-            };
-            if( p_sps->vui.ar.aspect_ratio_idc > 0 &&
-                p_sps->vui.ar.aspect_ratio_idc < 17 )
-            {
-                *num = ar_table[p_sps->vui.ar.aspect_ratio_idc - 1][0];
-                *den = ar_table[p_sps->vui.ar.aspect_ratio_idc - 1][1];
-                return true;
-            }
-        }
-        else
-        {
-            *num = p_sps->vui.ar.sar_width;
-            *den = p_sps->vui.ar.sar_height;
-            return true;
-        }
-    }
-    return false;
+    if( !p_sps->vui_parameters_present_flag )
+        return false;
+    return h26x_get_aspect_ratio( &p_sps->vui.ar, num, den );
 }
 
 bool hevc_get_chroma_luma( const hevc_sequence_parameter_set_t *p_sps, uint8_t *pi_chroma_format,
@@ -1210,14 +1119,8 @@ bool hevc_get_colorimetry( const hevc_sequence_parameter_set_t *p_sps,
 {
     if( !p_sps->vui_parameters_present_flag )
         return false;
-    *p_primaries =
-        iso_23001_8_cp_to_vlc_primaries( p_sps->vui.vs.colour.colour_primaries );
-    *p_transfer =
-        iso_23001_8_tc_to_vlc_xfer( p_sps->vui.vs.colour.transfer_characteristics );
-    *p_colorspace =
-        iso_23001_8_mc_to_vlc_coeffs( p_sps->vui.vs.colour.matrix_coeffs );
-    *p_full_range = p_sps->vui.vs.video_full_range_flag ? COLOR_RANGE_FULL : COLOR_RANGE_LIMITED;
-    return true;
+    return h26x_get_colorimetry( &p_sps->vui.vs.colour,
+                                p_primaries, p_transfer, p_colorspace, p_full_range );
 }
 
 static bool hevc_parse_slice_segment_header_rbsp( bs_t *p_bs,


=====================================
modules/packetizer/mpeg4video.c
=====================================
@@ -40,7 +40,7 @@
 #include <vlc_block_helper.h>
 #include "packetizer_helper.h"
 #include "startcode_helper.h"
-#include "iso_color_tables.h"
+#include "h26x_nal_common.h"
 
 /*****************************************************************************
  * Module descriptor
@@ -460,28 +460,32 @@ static int ParseVO( decoder_t *p_dec, block_t *p_vo )
     if( visual_object_type == 1 /* video ID */ ||
         visual_object_type == 2 /* still texture ID */ )
     {
-        uint8_t colour_primaries = 1;
-        uint8_t colour_xfer = 1;
-        uint8_t colour_matrix_coeff = 1;
-        uint8_t full_range = 0;
+        h26x_colour_description_t colour =
+        {
+            .colour_primaries = 1,
+            .transfer_characteristics = 1,
+            .matrix_coeffs = 1,
+            .full_range_flag = 0,
+        };
         if( bs_read1( &s ) ) /* video_signal_type */
         {
             bs_read( &s, 3 );
-            full_range = bs_read( &s, 1 );
+            colour.full_range_flag = bs_read( &s, 1 );
             if( bs_read( &s, 1 ) ) /* colour description */
             {
-                colour_primaries = bs_read( &s, 8 );
-                colour_xfer = bs_read( &s, 8 );
-                colour_matrix_coeff = bs_read( &s, 8 );
+                colour.colour_primaries = bs_read( &s, 8 );
+                colour.transfer_characteristics = bs_read( &s, 8 );
+                colour.matrix_coeffs = bs_read( &s, 8 );
             }
         }
 
         if( p_dec->fmt_in->video.primaries == COLOR_PRIMARIES_UNDEF )
         {
-            p_dec->fmt_out.video.primaries = iso_23001_8_cp_to_vlc_primaries( colour_primaries );
-            p_dec->fmt_out.video.transfer = iso_23001_8_tc_to_vlc_xfer( colour_xfer );
-            p_dec->fmt_out.video.space = iso_23001_8_mc_to_vlc_coeffs( colour_matrix_coeff );
-            p_dec->fmt_out.video.color_range = full_range ? COLOR_RANGE_FULL : COLOR_RANGE_LIMITED;
+            h26x_get_colorimetry( &colour,
+                                  &p_dec->fmt_out.video.primaries,
+                                  &p_dec->fmt_out.video.transfer,
+                                  &p_dec->fmt_out.video.space,
+                                  &p_dec->fmt_out.video.color_range );
         }
     }
 


=====================================
modules/packetizer/mpegvideo.c
=====================================
@@ -54,7 +54,7 @@
 #include "../codec/cc.h"
 #include "packetizer_helper.h"
 #include "startcode_helper.h"
-#include "iso_color_tables.h"
+#include "h26x_nal_common.h"
 
 #include <limits.h>
 
@@ -947,17 +947,20 @@ static block_t *ParseMPEGBlock( decoder_t *p_dec, block_t *p_frag )
             /* Sequence display extension */
             bool contains_color_description = (p_frag->p_buffer[4] & 0x01);
             //uint8_t video_format = (p_frag->p_buffer[4] & 0x0f) >> 1;
-
             if( contains_color_description && p_frag->i_buffer > 11 )
             {
-                p_dec->fmt_out.video.primaries =
-                        iso_23001_8_cp_to_vlc_primaries( p_frag->p_buffer[5] );
-                p_dec->fmt_out.video.transfer =
-                        iso_23001_8_tc_to_vlc_xfer( p_frag->p_buffer[6] );
-                p_dec->fmt_out.video.space =
-                        iso_23001_8_mc_to_vlc_coeffs( p_frag->p_buffer[7] );
+                h26x_colour_description_t colour;
+                colour.colour_primaries = p_frag->p_buffer[5];
+                colour.transfer_characteristics = p_frag->p_buffer[6];
+                colour.matrix_coeffs = p_frag->p_buffer[7];
+                colour.full_range_flag = 0;
+                video_color_range_t range;
+                h26x_get_colorimetry( &colour,
+                                      &p_dec->fmt_out.video.primaries,
+                                      &p_dec->fmt_out.video.transfer,
+                                      &p_dec->fmt_out.video.space,
+                                      &range );
             }
-
         }
     }
     else if( startcode == USER_DATA_STARTCODE && p_frag->i_buffer > 8 )



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/08397190bbeb88c5d1246e3c67d0e43a763f72b9...7cf5345c17cdb80b4d47d2b0b78b8042f1d4cb9d

-- 
This project does not include diff previews in email notifications.
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/08397190bbeb88c5d1246e3c67d0e43a763f72b9...7cf5345c17cdb80b4d47d2b0b78b8042f1d4cb9d
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list