mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
codecparsers: h264: parse seq_parameter_set_mvc_extension().
https://bugzilla.gnome.org/show_bug.cgi?id=685215 Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
This commit is contained in:
parent
c1deab84e6
commit
8911a80662
2 changed files with 396 additions and 6 deletions
|
@ -275,6 +275,114 @@ gst_h264_pps_copy (GstH264PPS * dst_pps, const GstH264PPS * src_pps)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* Copy MVC-specific data for subset SPS header */
|
||||
static gboolean
|
||||
gst_h264_sps_mvc_copy (GstH264SPS * dst_sps, const GstH264SPS * src_sps)
|
||||
{
|
||||
GstH264SPSExtMVC *const dst_mvc = &dst_sps->extension.mvc;
|
||||
const GstH264SPSExtMVC *const src_mvc = &src_sps->extension.mvc;
|
||||
guint i, j, k;
|
||||
|
||||
g_assert (dst_sps->extension_type == GST_H264_NAL_EXTENSION_MVC);
|
||||
|
||||
dst_mvc->num_views_minus1 = src_mvc->num_views_minus1;
|
||||
dst_mvc->view = g_new0 (GstH264SPSExtMVCView, dst_mvc->num_views_minus1 + 1);
|
||||
if (!dst_mvc->view)
|
||||
return FALSE;
|
||||
|
||||
dst_mvc->view[0].view_id = src_mvc->view[0].view_id;
|
||||
|
||||
for (i = 1; i <= dst_mvc->num_views_minus1; i++) {
|
||||
GstH264SPSExtMVCView *const dst_view = &dst_mvc->view[i];
|
||||
const GstH264SPSExtMVCView *const src_view = &src_mvc->view[i];
|
||||
|
||||
dst_view->view_id = src_view->view_id;
|
||||
|
||||
dst_view->num_anchor_refs_l0 = src_view->num_anchor_refs_l1;
|
||||
for (j = 0; j < dst_view->num_anchor_refs_l0; j++)
|
||||
dst_view->anchor_ref_l0[j] = src_view->anchor_ref_l0[j];
|
||||
|
||||
dst_view->num_anchor_refs_l1 = src_view->num_anchor_refs_l1;
|
||||
for (j = 0; j < dst_view->num_anchor_refs_l1; j++)
|
||||
dst_view->anchor_ref_l1[j] = src_view->anchor_ref_l1[j];
|
||||
|
||||
dst_view->num_non_anchor_refs_l0 = src_view->num_non_anchor_refs_l1;
|
||||
for (j = 0; j < dst_view->num_non_anchor_refs_l0; j++)
|
||||
dst_view->non_anchor_ref_l0[j] = src_view->non_anchor_ref_l0[j];
|
||||
|
||||
dst_view->num_non_anchor_refs_l1 = src_view->num_non_anchor_refs_l1;
|
||||
for (j = 0; j < dst_view->num_non_anchor_refs_l1; j++)
|
||||
dst_view->non_anchor_ref_l1[j] = src_view->non_anchor_ref_l1[j];
|
||||
}
|
||||
|
||||
dst_mvc->num_level_values_signalled_minus1 =
|
||||
src_mvc->num_level_values_signalled_minus1;
|
||||
dst_mvc->level_value = g_new0 (GstH264SPSExtMVCLevelValue,
|
||||
dst_mvc->num_level_values_signalled_minus1 + 1);
|
||||
if (!dst_mvc->level_value)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i <= dst_mvc->num_level_values_signalled_minus1; i++) {
|
||||
GstH264SPSExtMVCLevelValue *const dst_value = &dst_mvc->level_value[i];
|
||||
const GstH264SPSExtMVCLevelValue *const src_value =
|
||||
&src_mvc->level_value[i];
|
||||
|
||||
dst_value->level_idc = src_value->level_idc;
|
||||
|
||||
dst_value->num_applicable_ops_minus1 = src_value->num_applicable_ops_minus1;
|
||||
dst_value->applicable_op = g_new0 (GstH264SPSExtMVCLevelValueOp,
|
||||
dst_value->num_applicable_ops_minus1 + 1);
|
||||
if (!dst_value->applicable_op)
|
||||
return FALSE;
|
||||
|
||||
for (j = 0; j <= dst_value->num_applicable_ops_minus1; j++) {
|
||||
GstH264SPSExtMVCLevelValueOp *const dst_op = &dst_value->applicable_op[j];
|
||||
const GstH264SPSExtMVCLevelValueOp *const src_op =
|
||||
&src_value->applicable_op[j];
|
||||
|
||||
dst_op->temporal_id = src_op->temporal_id;
|
||||
dst_op->num_target_views_minus1 = src_op->num_target_views_minus1;
|
||||
dst_op->target_view_id =
|
||||
g_new (guint16, dst_op->num_target_views_minus1 + 1);
|
||||
if (!dst_op->target_view_id)
|
||||
return FALSE;
|
||||
|
||||
for (k = 0; k <= dst_op->num_target_views_minus1; k++)
|
||||
dst_op->target_view_id[k] = src_op->target_view_id[k];
|
||||
dst_op->num_views_minus1 = src_op->num_views_minus1;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* gst_h264_sps_copy:
|
||||
* @dst_sps: The destination #GstH264SPS to copy into
|
||||
* @src_sps: The source #GstH264SPS to copy from
|
||||
*
|
||||
* Copies @src_sps into @dst_sps.
|
||||
*
|
||||
* Returns: %TRUE if everything went fine, %FALSE otherwise
|
||||
*/
|
||||
static gboolean
|
||||
gst_h264_sps_copy (GstH264SPS * dst_sps, const GstH264SPS * src_sps)
|
||||
{
|
||||
g_return_val_if_fail (dst_sps != NULL, FALSE);
|
||||
g_return_val_if_fail (src_sps != NULL, FALSE);
|
||||
|
||||
gst_h264_sps_clear (dst_sps);
|
||||
|
||||
*dst_sps = *src_sps;
|
||||
|
||||
switch (dst_sps->extension_type) {
|
||||
case GST_H264_NAL_EXTENSION_MVC:
|
||||
if (!gst_h264_sps_mvc_copy (dst_sps, src_sps))
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/****** Parsing functions *****/
|
||||
|
||||
static gboolean
|
||||
|
@ -1054,6 +1162,8 @@ gst_h264_nal_parser_free (GstH264NalParser * nalparser)
|
|||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < GST_H264_MAX_SPS_COUNT; i++)
|
||||
gst_h264_sps_clear (&nalparser->sps[i]);
|
||||
for (i = 0; i < GST_H264_MAX_PPS_COUNT; i++)
|
||||
gst_h264_pps_clear (&nalparser->pps[i]);
|
||||
g_slice_free (GstH264NalParser, nalparser);
|
||||
|
@ -1286,12 +1396,10 @@ gst_h264_parser_parse_sps (GstH264NalParser * nalparser, GstH264NalUnit * nalu,
|
|||
if (res == GST_H264_PARSER_OK) {
|
||||
GST_DEBUG ("adding sequence parameter set with id: %d to array", sps->id);
|
||||
|
||||
nalparser->sps[sps->id] = *sps;
|
||||
if (!gst_h264_sps_copy (&nalparser->sps[sps->id], sps))
|
||||
return GST_H264_PARSER_ERROR;
|
||||
nalparser->last_sps = &nalparser->sps[sps->id];
|
||||
}
|
||||
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1307,6 +1415,7 @@ gst_h264_parse_sps_data (NalReader * nr, GstH264SPS * sps,
|
|||
|
||||
/* set default values for fields that might not be present in the bitstream
|
||||
and have valid defaults */
|
||||
sps->extension_type = GST_H264_NAL_EXTENSION_NONE;
|
||||
sps->chroma_format_idc = 1;
|
||||
sps->separate_colour_plane_flag = 0;
|
||||
sps->bit_depth_luma_minus8 = 0;
|
||||
|
@ -1471,6 +1580,109 @@ error:
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* Parse subset_seq_parameter_set() data for MVC */
|
||||
static gboolean
|
||||
gst_h264_parse_sps_mvc_data (NalReader * nr, GstH264SPS * sps,
|
||||
gboolean parse_vui_params)
|
||||
{
|
||||
GstH264SPSExtMVC *const mvc = &sps->extension.mvc;
|
||||
guint8 bit_equal_to_one;
|
||||
guint i, j, k;
|
||||
|
||||
READ_UINT8 (nr, bit_equal_to_one, 1);
|
||||
if (!bit_equal_to_one)
|
||||
return FALSE;
|
||||
|
||||
sps->extension_type = GST_H264_NAL_EXTENSION_MVC;
|
||||
|
||||
READ_UE_ALLOWED (nr, mvc->num_views_minus1, 0, GST_H264_MAX_VIEW_COUNT - 1);
|
||||
|
||||
mvc->view = g_new0 (GstH264SPSExtMVCView, mvc->num_views_minus1 + 1);
|
||||
if (!mvc->view)
|
||||
goto error_allocation_failed;
|
||||
|
||||
for (i = 0; i <= mvc->num_views_minus1; i++)
|
||||
READ_UE_ALLOWED (nr, mvc->view[i].view_id, 0, GST_H264_MAX_VIEW_ID);
|
||||
|
||||
for (i = 1; i <= mvc->num_views_minus1; i++) {
|
||||
/* for RefPicList0 */
|
||||
READ_UE_ALLOWED (nr, mvc->view[i].num_anchor_refs_l0, 0, 15);
|
||||
for (j = 0; j < mvc->view[i].num_anchor_refs_l0; j++) {
|
||||
READ_UE_ALLOWED (nr, mvc->view[i].anchor_ref_l0[j], 0,
|
||||
GST_H264_MAX_VIEW_ID);
|
||||
}
|
||||
|
||||
/* for RefPicList1 */
|
||||
READ_UE_ALLOWED (nr, mvc->view[i].num_anchor_refs_l1, 0, 15);
|
||||
for (j = 0; j < mvc->view[i].num_anchor_refs_l1; j++) {
|
||||
READ_UE_ALLOWED (nr, mvc->view[i].anchor_ref_l1[j], 0,
|
||||
GST_H264_MAX_VIEW_ID);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 1; i <= mvc->num_views_minus1; i++) {
|
||||
/* for RefPicList0 */
|
||||
READ_UE_ALLOWED (nr, mvc->view[i].num_non_anchor_refs_l0, 0, 15);
|
||||
for (j = 0; j < mvc->view[i].num_non_anchor_refs_l0; j++) {
|
||||
READ_UE_ALLOWED (nr, mvc->view[i].non_anchor_ref_l0[j], 0,
|
||||
GST_H264_MAX_VIEW_ID);
|
||||
}
|
||||
|
||||
/* for RefPicList1 */
|
||||
READ_UE_ALLOWED (nr, mvc->view[i].num_non_anchor_refs_l1, 0, 15);
|
||||
for (j = 0; j < mvc->view[i].num_non_anchor_refs_l1; j++) {
|
||||
READ_UE_ALLOWED (nr, mvc->view[i].non_anchor_ref_l1[j], 0,
|
||||
GST_H264_MAX_VIEW_ID);
|
||||
}
|
||||
}
|
||||
|
||||
READ_UE_ALLOWED (nr, mvc->num_level_values_signalled_minus1, 0, 63);
|
||||
|
||||
mvc->level_value =
|
||||
g_new0 (GstH264SPSExtMVCLevelValue,
|
||||
mvc->num_level_values_signalled_minus1 + 1);
|
||||
if (!mvc->level_value)
|
||||
goto error_allocation_failed;
|
||||
|
||||
for (i = 0; i <= mvc->num_level_values_signalled_minus1; i++) {
|
||||
GstH264SPSExtMVCLevelValue *const level_value = &mvc->level_value[i];
|
||||
|
||||
READ_UINT8 (nr, level_value->level_idc, 8);
|
||||
|
||||
READ_UE_ALLOWED (nr, level_value->num_applicable_ops_minus1, 0, 1023);
|
||||
level_value->applicable_op =
|
||||
g_new0 (GstH264SPSExtMVCLevelValueOp,
|
||||
level_value->num_applicable_ops_minus1 + 1);
|
||||
if (!level_value->applicable_op)
|
||||
goto error_allocation_failed;
|
||||
|
||||
for (j = 0; j <= level_value->num_applicable_ops_minus1; j++) {
|
||||
GstH264SPSExtMVCLevelValueOp *const op = &level_value->applicable_op[j];
|
||||
|
||||
READ_UINT8 (nr, op->temporal_id, 3);
|
||||
|
||||
READ_UE_ALLOWED (nr, op->num_target_views_minus1, 0, 1023);
|
||||
op->target_view_id = g_new (guint16, op->num_target_views_minus1 + 1);
|
||||
if (!op->target_view_id)
|
||||
goto error_allocation_failed;
|
||||
|
||||
for (k = 0; k <= op->num_target_views_minus1; k++)
|
||||
READ_UE_ALLOWED (nr, op->target_view_id[k], 0, GST_H264_MAX_VIEW_ID);
|
||||
READ_UE_ALLOWED (nr, op->num_views_minus1, 0, 1023);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
error_allocation_failed:
|
||||
GST_WARNING ("failed to allocate memory");
|
||||
gst_h264_sps_clear (sps);
|
||||
return FALSE;
|
||||
|
||||
error:
|
||||
gst_h264_sps_clear (sps);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_h264_parse_sps:
|
||||
* @nalu: The #GST_H264_NAL_SPS #GstH264NalUnit to parse
|
||||
|
@ -1515,6 +1727,15 @@ error:
|
|||
*
|
||||
* Parses @data, and fills in the @sps structure.
|
||||
*
|
||||
* This function fully parses @data and allocates all the necessary
|
||||
* data structures needed for MVC extensions. The resulting @sps
|
||||
* structure shall be deallocated with gst_h264_sps_clear() when it is
|
||||
* no longer needed.
|
||||
*
|
||||
* Note: if the caller doesn't need any of the MVC-specific data, then
|
||||
* gst_h264_parser_parse_sps() is more efficient because those extra
|
||||
* syntax elements are not parsed and no extra memory is allocated.
|
||||
*
|
||||
* Returns: a #GstH264ParserResult
|
||||
*/
|
||||
GstH264ParserResult
|
||||
|
@ -1527,7 +1748,8 @@ gst_h264_parser_parse_subset_sps (GstH264NalParser * nalparser,
|
|||
if (res == GST_H264_PARSER_OK) {
|
||||
GST_DEBUG ("adding sequence parameter set with id: %d to array", sps->id);
|
||||
|
||||
nalparser->sps[sps->id] = *sps;
|
||||
if (!gst_h264_sps_copy (&nalparser->sps[sps->id], sps))
|
||||
return GST_H264_PARSER_ERROR;
|
||||
nalparser->last_sps = &nalparser->sps[sps->id];
|
||||
}
|
||||
return res;
|
||||
|
@ -1541,6 +1763,15 @@ gst_h264_parser_parse_subset_sps (GstH264NalParser * nalparser,
|
|||
*
|
||||
* Parses @data, and fills in the @sps structure.
|
||||
*
|
||||
* This function fully parses @data and allocates all the necessary
|
||||
* data structures needed for MVC extensions. The resulting @sps
|
||||
* structure shall be deallocated with gst_h264_sps_clear() when it is
|
||||
* no longer needed.
|
||||
*
|
||||
* Note: if the caller doesn't need any of the MVC-specific data, then
|
||||
* gst_h264_parser_parse_sps() is more efficient because those extra
|
||||
* syntax elements are not parsed and no extra memory is allocated.
|
||||
*
|
||||
* Returns: a #GstH264ParserResult
|
||||
*/
|
||||
GstH264ParserResult
|
||||
|
@ -1555,9 +1786,15 @@ gst_h264_parse_subset_sps (GstH264NalUnit * nalu, GstH264SPS * sps,
|
|||
nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
|
||||
nalu->size - nalu->header_bytes);
|
||||
|
||||
if (!gst_h264_parse_sps_data (&nr, sps, parse_vui_params))
|
||||
if (!gst_h264_parse_sps_data (&nr, sps, TRUE))
|
||||
goto error;
|
||||
|
||||
if (sps->profile_idc == GST_H264_PROFILE_MULTIVIEW_HIGH ||
|
||||
sps->profile_idc == GST_H264_PROFILE_STEREO_HIGH) {
|
||||
if (!gst_h264_parse_sps_mvc_data (&nr, sps, parse_vui_params))
|
||||
goto error;
|
||||
}
|
||||
|
||||
sps->valid = TRUE;
|
||||
return GST_H264_PARSER_OK;
|
||||
|
||||
|
@ -1933,6 +2170,54 @@ error:
|
|||
return GST_H264_PARSER_ERROR;
|
||||
}
|
||||
|
||||
/* Free MVC-specific data from subset SPS header */
|
||||
static void
|
||||
gst_h264_sps_mvc_clear (GstH264SPS * sps)
|
||||
{
|
||||
GstH264SPSExtMVC *const mvc = &sps->extension.mvc;
|
||||
guint i, j;
|
||||
|
||||
g_assert (sps->extension_type == GST_H264_NAL_EXTENSION_MVC);
|
||||
|
||||
g_free (mvc->view);
|
||||
mvc->view = NULL;
|
||||
|
||||
for (i = 0; i <= mvc->num_level_values_signalled_minus1; i++) {
|
||||
GstH264SPSExtMVCLevelValue *const level_value = &mvc->level_value[i];
|
||||
|
||||
for (j = 0; j <= level_value->num_applicable_ops_minus1; j++) {
|
||||
g_free (level_value->applicable_op[j].target_view_id);
|
||||
level_value->applicable_op[j].target_view_id = NULL;
|
||||
}
|
||||
g_free (level_value->applicable_op);
|
||||
level_value->applicable_op = NULL;
|
||||
}
|
||||
g_free (mvc->level_value);
|
||||
mvc->level_value = NULL;
|
||||
|
||||
/* All meaningful MVC info are now gone, just pretend to be a
|
||||
* standard AVC struct now */
|
||||
sps->extension_type = GST_H264_NAL_EXTENSION_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_h264_sps_clear:
|
||||
* @sps: The #GstH264SPS to free
|
||||
*
|
||||
* Clears all @sps internal resources.
|
||||
*/
|
||||
void
|
||||
gst_h264_sps_clear (GstH264SPS * sps)
|
||||
{
|
||||
g_return_if_fail (sps != NULL);
|
||||
|
||||
switch (sps->extension_type) {
|
||||
case GST_H264_NAL_EXTENSION_MVC:
|
||||
gst_h264_sps_mvc_clear (sps);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_h264_parser_parse_sei:
|
||||
* @nalparser: a #GstH264NalParser
|
||||
|
|
|
@ -41,6 +41,8 @@ G_BEGIN_DECLS
|
|||
|
||||
#define GST_H264_MAX_SPS_COUNT 32
|
||||
#define GST_H264_MAX_PPS_COUNT 256
|
||||
#define GST_H264_MAX_VIEW_COUNT 1024
|
||||
#define GST_H264_MAX_VIEW_ID (GST_H264_MAX_VIEW_COUNT - 1)
|
||||
|
||||
#define GST_H264_IS_P_SLICE(slice) (((slice)->type % 5) == GST_H264_P_SLICE)
|
||||
#define GST_H264_IS_B_SLICE(slice) (((slice)->type % 5) == GST_H264_B_SLICE)
|
||||
|
@ -239,6 +241,11 @@ typedef struct _GstH264NalParser GstH264NalParser;
|
|||
typedef struct _GstH264NalUnit GstH264NalUnit;
|
||||
typedef struct _GstH264NalUnitExtensionMVC GstH264NalUnitExtensionMVC;
|
||||
|
||||
typedef struct _GstH264SPSExtMVCView GstH264SPSExtMVCView;
|
||||
typedef struct _GstH264SPSExtMVCLevelValue GstH264SPSExtMVCLevelValue;
|
||||
typedef struct _GstH264SPSExtMVCLevelValueOp GstH264SPSExtMVCLevelValueOp;
|
||||
typedef struct _GstH264SPSExtMVC GstH264SPSExtMVC;
|
||||
|
||||
typedef struct _GstH264SPS GstH264SPS;
|
||||
typedef struct _GstH264PPS GstH264PPS;
|
||||
typedef struct _GstH264HRDParams GstH264HRDParams;
|
||||
|
@ -470,6 +477,97 @@ struct _GstH264VUIParams
|
|||
guint par_d;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstH264SPSExtMVCView:
|
||||
* @num_anchor_refs_l0: specifies the number of view components for
|
||||
* inter-view prediction in the initialized RefPicList0 in decoding
|
||||
* anchor view components.
|
||||
* @anchor_ref_l0: specifies the view_id for inter-view prediction in
|
||||
* the initialized RefPicList0 in decoding anchor view components.
|
||||
* @num_anchor_refs_l1: specifies the number of view components for
|
||||
* inter-view prediction in the initialized RefPicList1 in decoding
|
||||
* anchor view components.
|
||||
* @anchor_ref_l1: specifies the view_id for inter-view prediction in
|
||||
* the initialized RefPicList1 in decoding anchor view components.
|
||||
* @num_non_anchor_refs_l0: specifies the number of view components
|
||||
* for inter-view prediction in the initialized RefPicList0 in
|
||||
* decoding non-anchor view components.
|
||||
* @non_anchor_ref_l0: specifies the view_id for inter-view prediction
|
||||
* in the initialized RefPicList0 in decoding non-anchor view
|
||||
* components.
|
||||
* @num_non_anchor_refs_l1: specifies the number of view components
|
||||
* for inter-view prediction in the initialized RefPicList1 in
|
||||
* decoding non-anchor view components.
|
||||
* @non_anchor_ref_l1: specifies the view_id for inter-view prediction
|
||||
* in the initialized RefPicList1 in decoding non-anchor view
|
||||
* components.
|
||||
*
|
||||
* Represents inter-view dependency relationships for the coded video
|
||||
* sequence.
|
||||
*/
|
||||
struct _GstH264SPSExtMVCView
|
||||
{
|
||||
guint16 view_id;
|
||||
guint8 num_anchor_refs_l0;
|
||||
guint16 anchor_ref_l0[15];
|
||||
guint8 num_anchor_refs_l1;
|
||||
guint16 anchor_ref_l1[15];
|
||||
guint8 num_non_anchor_refs_l0;
|
||||
guint16 non_anchor_ref_l0[15];
|
||||
guint8 num_non_anchor_refs_l1;
|
||||
guint16 non_anchor_ref_l1[15];
|
||||
};
|
||||
|
||||
/**
|
||||
* GstH264SPSExtMVCLevelValueOp:
|
||||
*
|
||||
* Represents an operation point for the coded video sequence.
|
||||
*/
|
||||
struct _GstH264SPSExtMVCLevelValueOp
|
||||
{
|
||||
guint8 temporal_id;
|
||||
guint16 num_target_views_minus1;
|
||||
guint16 *target_view_id;
|
||||
guint16 num_views_minus1;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstH264SPSExtMVCLevelValue:
|
||||
* @level_idc: specifies the level value signalled for the coded video
|
||||
* sequence
|
||||
* @num_applicable_ops_minus1: plus 1 specifies the number of
|
||||
* operation points to which the level indicated by level_idc applies
|
||||
* @applicable_op: specifies the applicable operation point
|
||||
*
|
||||
* Represents level values for a subset of the operation points for
|
||||
* the coded video sequence.
|
||||
*/
|
||||
struct _GstH264SPSExtMVCLevelValue
|
||||
{
|
||||
guint8 level_idc;
|
||||
guint16 num_applicable_ops_minus1;
|
||||
GstH264SPSExtMVCLevelValueOp *applicable_op;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstH264SPSExtMVC:
|
||||
* @num_views_minus1: plus 1 specifies the maximum number of coded
|
||||
* views in the coded video sequence
|
||||
* @view: array of #GstH264SPSExtMVCView
|
||||
* @num_level_values_signalled_minus1: plus 1 specifies the number of
|
||||
* level values signalled for the coded video sequence.
|
||||
* @level_value: array of #GstH264SPSExtMVCLevelValue
|
||||
*
|
||||
* Represents the parsed seq_parameter_set_mvc_extension().
|
||||
*/
|
||||
struct _GstH264SPSExtMVC
|
||||
{
|
||||
guint16 num_views_minus1;
|
||||
GstH264SPSExtMVCView *view;
|
||||
guint8 num_level_values_signalled_minus1;
|
||||
GstH264SPSExtMVCLevelValue *level_value;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstH264SPS:
|
||||
* @id: The ID of the sequence parameter set
|
||||
|
@ -543,6 +641,12 @@ struct _GstH264SPS
|
|||
gint crop_rect_x, crop_rect_y;
|
||||
gint fps_num, fps_den;
|
||||
gboolean valid;
|
||||
|
||||
/* Subset SPS extensions */
|
||||
guint8 extension_type;
|
||||
union {
|
||||
GstH264SPSExtMVC mvc;
|
||||
} extension;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -842,6 +946,7 @@ GstH264ParserResult gst_h264_parse_sps (GstH264NalUnit *nalu,
|
|||
GstH264ParserResult gst_h264_parse_pps (GstH264NalParser *nalparser,
|
||||
GstH264NalUnit *nalu, GstH264PPS *pps);
|
||||
|
||||
void gst_h264_sps_clear (GstH264SPS *sps);
|
||||
void gst_h264_pps_clear (GstH264PPS *pps);
|
||||
|
||||
void gst_h264_quant_matrix_8x8_get_zigzag_from_raster (guint8 out_quant[64],
|
||||
|
|
Loading…
Reference in a new issue