h264parse->idr_pos = -1;
h264parse->sei_pos = -1;
h264parse->keyframe = FALSE;
+ h264parse->predicted = FALSE;
+ h264parse->bidirectional = FALSE;
h264parse->header = FALSE;
h264parse->frame_start = FALSE;
h264parse->aud_insert = TRUE;
gst_event_replace (&h264parse->force_key_unit_event, NULL);
h264parse->discont = FALSE;
+ h264parse->discard_bidirectional = FALSE;
gst_h264_parse_reset_stream_info (h264parse);
}
if (pres != GST_H264_PARSER_OK) {
GST_WARNING_OBJECT (h264parse, "failed to parse SPS:");
h264parse->state |= GST_H264_PARSE_STATE_GOT_SPS;
- h264parse->header |= TRUE;
+ h264parse->header = TRUE;
return FALSE;
}
gst_h264_parser_store_nal (h264parse, sps.id, nal_type, nalu);
gst_h264_sps_clear (&sps);
h264parse->state |= GST_H264_PARSE_STATE_GOT_SPS;
- h264parse->header |= TRUE;
+ h264parse->header = TRUE;
break;
case GST_H264_NAL_PPS:
/* expected state: got-sps */
gst_h264_parser_store_nal (h264parse, pps.id, nal_type, nalu);
gst_h264_pps_clear (&pps);
h264parse->state |= GST_H264_PARSE_STATE_GOT_PPS;
- h264parse->header |= TRUE;
+ h264parse->header = TRUE;
break;
case GST_H264_NAL_SEI:
/* expected state: got-sps */
if (!GST_H264_PARSE_STATE_VALID (h264parse, GST_H264_PARSE_STATE_GOT_SPS))
return FALSE;
- h264parse->header |= TRUE;
+ h264parse->header = TRUE;
gst_h264_parse_process_sei (h264parse, nalu);
/* mark SEI pos */
if (h264parse->sei_pos == -1) {
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;
+ 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;
else
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
+ if (h264parse->discard_bidirectional && h264parse->bidirectional)
+ goto discard;
+
if (h264parse->header)
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_HEADER);
else
gst_buffer_unref (buf);
}
+done:
return GST_FLOW_OK;
+
+discard:
+ GST_DEBUG_OBJECT (h264parse, "Discarding bidirectional frame");
+ frame->flags |= GST_BASE_PARSE_FRAME_FLAG_DROP;
+ gst_h264_parse_reset_frame (h264parse);
+ goto done;
}
/* sends a codec NAL downstream, decorating and transforming as needed.
|| segment->applied_rate != 1.0))
h264parse->do_ts = FALSE;
+ if (segment->flags & GST_SEEK_FLAG_TRICKMODE_FORWARD_PREDICTED) {
+ GST_DEBUG_OBJECT (h264parse, "Will discard bidirectional frames");
+ h264parse->discard_bidirectional = TRUE;
+ }
+
+
h264parse->last_report = GST_CLOCK_TIME_NONE;
res = GST_BASE_PARSE_CLASS (parent_class)->sink_event (parse, event);
h265parse->idr_pos = -1;
h265parse->sei_pos = -1;
h265parse->keyframe = FALSE;
+ h265parse->predicted = FALSE;
+ h265parse->bidirectional = FALSE;
h265parse->header = FALSE;
h265parse->have_vps_in_frame = FALSE;
h265parse->have_sps_in_frame = FALSE;
gst_event_replace (&h265parse->force_key_unit_event, NULL);
h265parse->discont = FALSE;
+ h265parse->discard_bidirectional = FALSE;
gst_h265_parse_reset_stream_info (h265parse);
}
minfo.Wx_n = sei.payload.mastering_display_colour_volume.white_point_x;
minfo.Wy_n = sei.payload.mastering_display_colour_volume.white_point_y;
minfo.max_luma_n =
- sei.payload.
- mastering_display_colour_volume.max_display_mastering_luminance;
+ sei.payload.mastering_display_colour_volume.
+ max_display_mastering_luminance;
minfo.min_luma_n =
- sei.payload.
- mastering_display_colour_volume.min_display_mastering_luminance;
+ sei.payload.mastering_display_colour_volume.
+ min_display_mastering_luminance;
minfo.Gx_d = minfo.Gy_d = minfo.Bx_d = minfo.By_d =
minfo.Rx_d = minfo.Ry_d = minfo.Wx_d = minfo.Wy_d = chroma_den;
}
gst_h265_parser_store_nal (h265parse, vps.id, nal_type, nalu);
- h265parse->header |= TRUE;
+ h265parse->header = TRUE;
break;
case GST_H265_NAL_SPS:
/* reset state, everything else is obsolete */
if (pres != GST_H265_PARSER_OK) {
GST_WARNING_OBJECT (h265parse, "failed to parse SPS:");
h265parse->state |= GST_H265_PARSE_STATE_GOT_SPS;
- h265parse->header |= TRUE;
+ h265parse->header = TRUE;
return FALSE;
}
GST_WARNING_OBJECT (h265parse,
}
gst_h265_parser_store_nal (h265parse, sps.id, nal_type, nalu);
- h265parse->header |= TRUE;
+ h265parse->header = TRUE;
h265parse->state |= GST_H265_PARSE_STATE_GOT_SPS;
break;
case GST_H265_NAL_PPS:
}
gst_h265_parser_store_nal (h265parse, pps.id, nal_type, nalu);
- h265parse->header |= TRUE;
+ h265parse->header = TRUE;
h265parse->state |= GST_H265_PARSE_STATE_GOT_PPS;
break;
case GST_H265_NAL_PREFIX_SEI:
if (!GST_H265_PARSE_STATE_VALID (h265parse, GST_H265_PARSE_STATE_GOT_SPS))
return FALSE;
- h265parse->header |= TRUE;
+ h265parse->header = TRUE;
gst_h265_parse_process_sei (h265parse, nalu);
if (pres == GST_H265_PARSER_OK) {
if (GST_H265_IS_I_SLICE (&slice))
- h265parse->keyframe |= TRUE;
+ h265parse->keyframe = TRUE;
+ else if (GST_H265_IS_P_SLICE (&slice))
+ h265parse->predicted = TRUE;
+ else if (GST_H265_IS_B_SLICE (&slice))
+ h265parse->bidirectional = TRUE;
h265parse->state |= GST_H265_PARSE_STATE_GOT_SLICE;
}
else
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
+ if (h265parse->discard_bidirectional && h265parse->bidirectional)
+ goto discard;
+
+
if (h265parse->header)
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_HEADER);
else
gst_buffer_unref (buf);
}
+done:
return GST_FLOW_OK;
+
+discard:
+ GST_DEBUG_OBJECT (h265parse, "Discarding bidirectional frame");
+ frame->flags |= GST_BASE_PARSE_FRAME_FLAG_DROP;
+ gst_h265_parse_reset_frame (h265parse);
+ goto done;
+
}
/* sends a codec NAL downstream, decorating and transforming as needed.
h265parse->parsed_fps_d,
NULL,
flags,
- h265parse->time_code.hours_flag[i] ? h265parse->
- time_code.hours_value[i] : 0,
- h265parse->time_code.minutes_flag[i] ? h265parse->
- time_code.minutes_value[i] : 0,
- h265parse->time_code.seconds_flag[i] ? h265parse->
- time_code.seconds_value[i] : 0, n_frames, field_count);
+ h265parse->time_code.hours_flag[i] ? h265parse->time_code.
+ hours_value[i] : 0,
+ h265parse->time_code.minutes_flag[i] ? h265parse->time_code.
+ minutes_value[i] : 0,
+ h265parse->time_code.seconds_flag[i] ? h265parse->time_code.
+ seconds_value[i] : 0, n_frames, field_count);
}
}
break;
case GST_EVENT_SEGMENT:
{
+ const GstSegment *segment = NULL;
+
+ gst_event_parse_segment (event, &segment);
+
h265parse->last_report = GST_CLOCK_TIME_NONE;
+ if (segment->flags & GST_SEEK_FLAG_TRICKMODE_FORWARD_PREDICTED) {
+ GST_DEBUG_OBJECT (h265parse, "Will discard bidirectional frames");
+ h265parse->discard_bidirectional = TRUE;
+ }
+
res = GST_BASE_PARSE_CLASS (parent_class)->sink_event (parse, event);
break;
}