mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
h26xparse: Handle state change on IDR first slice
As the H265/H264 bitstream can support multiple slices, mastering_display_info_state and content_light_level_state should be changed only on first slice segment. Fix #1152
This commit is contained in:
parent
d414e90eff
commit
4b8c47ee37
2 changed files with 34 additions and 31 deletions
|
@ -879,6 +879,7 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu)
|
|||
GstH264SPS sps = { 0, };
|
||||
GstH264NalParser *nalparser = h264parse->nalparser;
|
||||
GstH264ParserResult pres;
|
||||
GstH264SliceHdr slice;
|
||||
|
||||
/* nothing to do for broken input */
|
||||
if (G_UNLIKELY (nalu->size < 2)) {
|
||||
|
@ -1006,30 +1007,29 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu)
|
|||
GST_DEBUG_OBJECT (h264parse, "frame start: %i", h264parse->frame_start);
|
||||
if (nal_type == GST_H264_NAL_SLICE_EXT && !GST_H264_IS_MVC_NALU (nalu))
|
||||
break;
|
||||
{
|
||||
GstH264SliceHdr slice;
|
||||
|
||||
pres = gst_h264_parser_parse_slice_hdr (nalparser, nalu, &slice,
|
||||
FALSE, FALSE);
|
||||
GST_DEBUG_OBJECT (h264parse,
|
||||
"parse result %d, first MB: %u, slice type: %u",
|
||||
pres, slice.first_mb_in_slice, slice.type);
|
||||
if (pres == GST_H264_PARSER_OK) {
|
||||
if (GST_H264_IS_I_SLICE (&slice) || GST_H264_IS_SI_SLICE (&slice))
|
||||
h264parse->keyframe = TRUE;
|
||||
else if (GST_H264_IS_P_SLICE (&slice)
|
||||
|| GST_H264_IS_SP_SLICE (&slice))
|
||||
h264parse->predicted = TRUE;
|
||||
else if (GST_H264_IS_B_SLICE (&slice))
|
||||
h264parse->bidirectional = TRUE;
|
||||
pres = gst_h264_parser_parse_slice_hdr (nalparser, nalu, &slice,
|
||||
FALSE, FALSE);
|
||||
GST_DEBUG_OBJECT (h264parse,
|
||||
"parse result %d, first MB: %u, slice type: %u",
|
||||
pres, slice.first_mb_in_slice, slice.type);
|
||||
if (pres == GST_H264_PARSER_OK) {
|
||||
if (GST_H264_IS_I_SLICE (&slice) || GST_H264_IS_SI_SLICE (&slice))
|
||||
h264parse->keyframe = TRUE;
|
||||
else if (GST_H264_IS_P_SLICE (&slice)
|
||||
|| GST_H264_IS_SP_SLICE (&slice))
|
||||
h264parse->predicted = TRUE;
|
||||
else if (GST_H264_IS_B_SLICE (&slice))
|
||||
h264parse->bidirectional = TRUE;
|
||||
|
||||
h264parse->state |= GST_H264_PARSE_STATE_GOT_SLICE;
|
||||
h264parse->field_pic_flag = slice.field_pic_flag;
|
||||
}
|
||||
h264parse->state |= GST_H264_PARSE_STATE_GOT_SLICE;
|
||||
h264parse->field_pic_flag = slice.field_pic_flag;
|
||||
}
|
||||
|
||||
if (G_LIKELY (nal_type != GST_H264_NAL_SLICE_IDR &&
|
||||
!h264parse->push_codec))
|
||||
break;
|
||||
|
||||
/* if we need to sneak codec NALs into the stream,
|
||||
* this is a good place, so fake it as IDR
|
||||
* (which should be at start anyway) */
|
||||
|
@ -1049,19 +1049,21 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu)
|
|||
GST_DEBUG_OBJECT (h264parse, "moved IDR mark to SEI position %d",
|
||||
h264parse->idr_pos);
|
||||
}
|
||||
/* Reset state only on first IDR slice of CVS D.2.29 */
|
||||
if (slice.first_mb_in_slice == 0) {
|
||||
if (h264parse->mastering_display_info_state ==
|
||||
GST_H264_PARSE_SEI_PARSED)
|
||||
h264parse->mastering_display_info_state = GST_H264_PARSE_SEI_ACTIVE;
|
||||
else if (h264parse->mastering_display_info_state ==
|
||||
GST_H264_PARSE_SEI_ACTIVE)
|
||||
h264parse->mastering_display_info_state = GST_H264_PARSE_SEI_EXPIRED;
|
||||
|
||||
if (h264parse->mastering_display_info_state == GST_H264_PARSE_SEI_PARSED)
|
||||
h264parse->mastering_display_info_state = GST_H264_PARSE_SEI_ACTIVE;
|
||||
else if (h264parse->mastering_display_info_state ==
|
||||
GST_H264_PARSE_SEI_ACTIVE)
|
||||
h264parse->mastering_display_info_state = GST_H264_PARSE_SEI_EXPIRED;
|
||||
|
||||
if (h264parse->content_light_level_state == GST_H264_PARSE_SEI_PARSED)
|
||||
h264parse->content_light_level_state = GST_H264_PARSE_SEI_ACTIVE;
|
||||
else if (h264parse->content_light_level_state ==
|
||||
GST_H264_PARSE_SEI_ACTIVE)
|
||||
h264parse->content_light_level_state = GST_H264_PARSE_SEI_EXPIRED;
|
||||
|
||||
if (h264parse->content_light_level_state == GST_H264_PARSE_SEI_PARSED)
|
||||
h264parse->content_light_level_state = GST_H264_PARSE_SEI_ACTIVE;
|
||||
else if (h264parse->content_light_level_state ==
|
||||
GST_H264_PARSE_SEI_ACTIVE)
|
||||
h264parse->content_light_level_state = GST_H264_PARSE_SEI_EXPIRED;
|
||||
}
|
||||
break;
|
||||
case GST_H264_NAL_AU_DELIMITER:
|
||||
/* Just accumulate AU Delimiter, whether it's before SPS or not */
|
||||
|
|
|
@ -921,7 +921,8 @@ gst_h265_parse_process_nal (GstH265Parse * h265parse, GstH265NalUnit * nalu)
|
|||
is_irap = ((nal_type >= GST_H265_NAL_SLICE_BLA_W_LP)
|
||||
&& (nal_type <= GST_H265_NAL_SLICE_CRA_NUT)) ? TRUE : FALSE;
|
||||
|
||||
if (no_rasl_output_flag && is_irap) {
|
||||
if (no_rasl_output_flag && is_irap
|
||||
&& slice.first_slice_segment_in_pic_flag == 1) {
|
||||
if (h265parse->mastering_display_info_state ==
|
||||
GST_H265_PARSE_SEI_PARSED)
|
||||
h265parse->mastering_display_info_state = GST_H265_PARSE_SEI_ACTIVE;
|
||||
|
|
Loading…
Reference in a new issue