libs: decoder: h264: decode SVC base layer only

Drops non-base NALs when the base-only property is set to TRUE.
This modifies the behavior for MVC streams with base-only too: All the
non-base units are dropped before they are decoded instead of dropping
the non-base frames.

The relevant part from the H264 spec is:
> Decoders that conform to one or more of the profiles specified in
Annex A rather than the profiles specified in Annexes G or H shall
ignore (remove from the bitstream and discard) the contents of all NAL
units with nal_unit_type equal to 14, 15, or 20.

To eliminate side effects from the offending units:
- PPS's with a broken seq_parameter_set_id (referring to dropped subset
SPS's) are ignored.
- The NAL parsing is skipped and their flags are set to
GST_VAAPI_DECODER_UNIT_FLAG_SKIP.
- Prefix units are not stored in prev_pi. Otherwise, parse_slice() would
use them even if they are flagged to be skipped. Subset SPS's and slice
extension units are not stored there either.

https://bugzilla.gnome.org/show_bug.cgi?id=732266

Signed-off-by: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
This commit is contained in:
Orestis Floros 2017-08-28 17:32:57 -07:00 committed by Sreerenj Balachandran
parent a016aa181b
commit 0955752898

View file

@ -1805,8 +1805,6 @@ parse_pps (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit)
GST_DEBUG ("parse PPS");
priv->parser_state &= GST_H264_VIDEO_STATE_GOT_SPS;
/* Variables that don't have inferred values per the H.264
standard but that should get a default value anyway */
pps->slice_group_map_type = 0;
@ -1814,6 +1812,15 @@ parse_pps (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit)
pps->slice_group_id = NULL;
result = gst_h264_parser_parse_pps (priv->parser, &pi->nalu, pps);
/* PPS's sps id might be an ignored subset sps in SVC streams */
if (priv->base_only && result == GST_H264_PARSER_BROKEN_LINK) {
pi->nalu.valid = FALSE;
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
priv->parser_state &= GST_H264_VIDEO_STATE_GOT_SPS;
if (result != GST_H264_PARSER_OK)
return get_status (result);
@ -4049,12 +4056,6 @@ decode_picture (GstVaapiDecoderH264 * decoder, GstVaapiDecoderUnit * unit)
g_return_val_if_fail (pps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN);
g_return_val_if_fail (sps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN);
/* Only decode base stream for MVC */
if (priv->base_only && is_mvc_profile (sps->profile_idc)) {
GST_DEBUG ("multiview sequence but base-only is set: dropping frame");
return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME;
}
status = ensure_context (decoder, sps);
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
return status;
@ -4593,6 +4594,13 @@ gst_vaapi_decoder_h264_parse (GstVaapiDecoder * base_decoder,
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
goto exit;
if (priv->base_only && (pi->nalu.type == GST_H264_NAL_PREFIX_UNIT
|| pi->nalu.type == GST_H264_NAL_SUBSET_SPS
|| pi->nalu.type == GST_H264_NAL_SLICE_EXT)) {
GST_VAAPI_DECODER_UNIT_FLAG_SET (unit, GST_VAAPI_DECODER_UNIT_FLAG_SKIP);
pi->nalu.valid = FALSE;
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
switch (pi->nalu.type) {
case GST_H264_NAL_SPS:
status = parse_sps (decoder, unit);
@ -4805,7 +4813,7 @@ gst_vaapi_decoder_h264_set_alignment (GstVaapiDecoderH264 * decoder,
* @decoder: a #GstVaapiDecoderH264
* @base_only: %TRUE to force decoding the base view only
*
* if @base_only is %TRUE only the base view of MVC encoded streams
* if @base_only is %TRUE only the base view of MVC or SVC encoded streams
* is decoded.
*
**/