mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 17:50:36 +00:00
decoder: h264: add support for MVC base views.
Allow decoding for base views of MVC encoded streams. For now, just skip the slice extension and prefix NAL units, and skip non-base view frames. Signed-off-by: Xiaowei Li <xiaowei.a.li@intel.com> [fixed memory leak, improved check for MVC NAL units] Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
This commit is contained in:
parent
1c46990ecd
commit
79118904a0
1 changed files with 76 additions and 0 deletions
|
@ -76,6 +76,10 @@ static void
|
||||||
gst_vaapi_parser_info_h264_finalize(GstVaapiParserInfoH264 *pi)
|
gst_vaapi_parser_info_h264_finalize(GstVaapiParserInfoH264 *pi)
|
||||||
{
|
{
|
||||||
switch (pi->nalu.type) {
|
switch (pi->nalu.type) {
|
||||||
|
case GST_H264_NAL_SPS:
|
||||||
|
case GST_H264_NAL_SUBSET_SPS:
|
||||||
|
gst_h264_sps_clear(&pi->data.sps);
|
||||||
|
break;
|
||||||
case GST_H264_NAL_SEI:
|
case GST_H264_NAL_SEI:
|
||||||
if (pi->data.sei) {
|
if (pi->data.sei) {
|
||||||
g_array_unref(pi->data.sei);
|
g_array_unref(pi->data.sei);
|
||||||
|
@ -1104,6 +1108,29 @@ parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
|
||||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstVaapiDecoderStatus
|
||||||
|
parse_subset_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
|
||||||
|
{
|
||||||
|
GstVaapiDecoderH264Private * const priv = &decoder->priv;
|
||||||
|
GstVaapiParserInfoH264 * const pi = unit->parsed_info;
|
||||||
|
GstH264SPS * const sps = &pi->data.sps;
|
||||||
|
GstH264ParserResult result;
|
||||||
|
|
||||||
|
GST_DEBUG("parse subset SPS");
|
||||||
|
|
||||||
|
/* Variables that don't have inferred values per the H.264
|
||||||
|
standard but that should get a default value anyway */
|
||||||
|
sps->log2_max_pic_order_cnt_lsb_minus4 = 0;
|
||||||
|
|
||||||
|
result = gst_h264_parser_parse_subset_sps(priv->parser, &pi->nalu, sps,
|
||||||
|
TRUE);
|
||||||
|
if (result != GST_H264_PARSER_OK)
|
||||||
|
return get_status(result);
|
||||||
|
|
||||||
|
priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SPS;
|
||||||
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static GstVaapiDecoderStatus
|
static GstVaapiDecoderStatus
|
||||||
parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
|
parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
|
||||||
{
|
{
|
||||||
|
@ -1187,6 +1214,19 @@ decode_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
|
||||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstVaapiDecoderStatus
|
||||||
|
decode_subset_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
|
||||||
|
{
|
||||||
|
GstVaapiDecoderH264Private * const priv = &decoder->priv;
|
||||||
|
GstVaapiParserInfoH264 * const pi = unit->parsed_info;
|
||||||
|
GstH264SPS * const sps = &pi->data.sps;
|
||||||
|
|
||||||
|
GST_DEBUG("decode subset SPS");
|
||||||
|
|
||||||
|
gst_vaapi_parser_info_h264_replace(&priv->sps[sps->id], pi);
|
||||||
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static GstVaapiDecoderStatus
|
static GstVaapiDecoderStatus
|
||||||
decode_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
|
decode_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
|
||||||
{
|
{
|
||||||
|
@ -2637,6 +2677,17 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
|
||||||
g_return_val_if_fail(pps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN);
|
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);
|
g_return_val_if_fail(sps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN);
|
||||||
|
|
||||||
|
/* Only decode base stream for MVC */
|
||||||
|
switch (sps->profile_idc) {
|
||||||
|
case GST_H264_PROFILE_MULTIVIEW_HIGH:
|
||||||
|
case GST_H264_PROFILE_STEREO_HIGH:
|
||||||
|
if (1) {
|
||||||
|
GST_DEBUG("drop picture from substream");
|
||||||
|
return GST_VAAPI_DECODER_STATUS_DROP_FRAME;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
status = ensure_context(decoder, sps);
|
status = ensure_context(decoder, sps);
|
||||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||||
return status;
|
return status;
|
||||||
|
@ -2909,9 +2960,13 @@ decode_unit(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
|
||||||
case GST_H264_NAL_SPS:
|
case GST_H264_NAL_SPS:
|
||||||
status = decode_sps(decoder, unit);
|
status = decode_sps(decoder, unit);
|
||||||
break;
|
break;
|
||||||
|
case GST_H264_NAL_SUBSET_SPS:
|
||||||
|
status = decode_subset_sps(decoder, unit);
|
||||||
|
break;
|
||||||
case GST_H264_NAL_PPS:
|
case GST_H264_NAL_PPS:
|
||||||
status = decode_pps(decoder, unit);
|
status = decode_pps(decoder, unit);
|
||||||
break;
|
break;
|
||||||
|
case GST_H264_NAL_SLICE_EXT:
|
||||||
case GST_H264_NAL_SLICE_IDR:
|
case GST_H264_NAL_SLICE_IDR:
|
||||||
/* fall-through. IDR specifics are handled in init_picture() */
|
/* fall-through. IDR specifics are handled in init_picture() */
|
||||||
case GST_H264_NAL_SLICE:
|
case GST_H264_NAL_SLICE:
|
||||||
|
@ -3140,12 +3195,21 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder,
|
||||||
case GST_H264_NAL_SPS:
|
case GST_H264_NAL_SPS:
|
||||||
status = parse_sps(decoder, unit);
|
status = parse_sps(decoder, unit);
|
||||||
break;
|
break;
|
||||||
|
case GST_H264_NAL_SUBSET_SPS:
|
||||||
|
status = parse_subset_sps(decoder, unit);
|
||||||
|
break;
|
||||||
case GST_H264_NAL_PPS:
|
case GST_H264_NAL_PPS:
|
||||||
status = parse_pps(decoder, unit);
|
status = parse_pps(decoder, unit);
|
||||||
break;
|
break;
|
||||||
case GST_H264_NAL_SEI:
|
case GST_H264_NAL_SEI:
|
||||||
status = parse_sei(decoder, unit);
|
status = parse_sei(decoder, unit);
|
||||||
break;
|
break;
|
||||||
|
case GST_H264_NAL_SLICE_EXT:
|
||||||
|
if (!GST_H264_IS_MVC_NALU(&pi->nalu)) {
|
||||||
|
status = GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* fall-through */
|
||||||
case GST_H264_NAL_SLICE_IDR:
|
case GST_H264_NAL_SLICE_IDR:
|
||||||
case GST_H264_NAL_SLICE:
|
case GST_H264_NAL_SLICE:
|
||||||
status = parse_slice(decoder, unit);
|
status = parse_slice(decoder, unit);
|
||||||
|
@ -3172,10 +3236,17 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder,
|
||||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END;
|
flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END;
|
||||||
break;
|
break;
|
||||||
case GST_H264_NAL_SPS:
|
case GST_H264_NAL_SPS:
|
||||||
|
case GST_H264_NAL_SUBSET_SPS:
|
||||||
case GST_H264_NAL_PPS:
|
case GST_H264_NAL_PPS:
|
||||||
case GST_H264_NAL_SEI:
|
case GST_H264_NAL_SEI:
|
||||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
|
flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
|
||||||
break;
|
break;
|
||||||
|
case GST_H264_NAL_SLICE_EXT:
|
||||||
|
if (!GST_H264_IS_MVC_NALU(&pi->nalu)) {
|
||||||
|
flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* fall-through */
|
||||||
case GST_H264_NAL_SLICE_IDR:
|
case GST_H264_NAL_SLICE_IDR:
|
||||||
case GST_H264_NAL_SLICE:
|
case GST_H264_NAL_SLICE:
|
||||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
|
flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
|
||||||
|
@ -3188,6 +3259,11 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder,
|
||||||
/* skip SPS extension and auxiliary slice for now */
|
/* skip SPS extension and auxiliary slice for now */
|
||||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP;
|
flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP;
|
||||||
break;
|
break;
|
||||||
|
case GST_H264_NAL_PREFIX_UNIT:
|
||||||
|
/* skip Prefix NAL units for now */
|
||||||
|
flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP |
|
||||||
|
GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (pi->nalu.type >= 14 && pi->nalu.type <= 18)
|
if (pi->nalu.type >= 14 && pi->nalu.type <= 18)
|
||||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
|
flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
|
||||||
|
|
Loading…
Reference in a new issue