[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