aboutsummaryrefslogtreecommitdiff
path: root/gst-libs/gst/codecparsers/gsth264parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst-libs/gst/codecparsers/gsth264parser.c')
-rw-r--r--gst-libs/gst/codecparsers/gsth264parser.c99
1 files changed, 90 insertions, 9 deletions
diff --git a/gst-libs/gst/codecparsers/gsth264parser.c b/gst-libs/gst/codecparsers/gsth264parser.c
index 41489b88..e5047229 100644
--- a/gst-libs/gst/codecparsers/gsth264parser.c
+++ b/gst-libs/gst/codecparsers/gsth264parser.c
@@ -216,6 +216,32 @@ gst_h264_parse_nalu_header (GstH264NalUnit * nalu)
return TRUE;
}
+/*
+ * gst_h264_pps_copy:
+ * @dst_pps: The destination #GstH264PPS to copy into
+ * @src_pps: The source #GstH264PPS to copy from
+ *
+ * Copies @src_pps into @dst_pps.
+ *
+ * Returns: %TRUE if everything went fine, %FALSE otherwise
+ */
+static gboolean
+gst_h264_pps_copy (GstH264PPS * dst_pps, const GstH264PPS * src_pps)
+{
+ g_return_val_if_fail (dst_pps != NULL, FALSE);
+ g_return_val_if_fail (src_pps != NULL, FALSE);
+
+ gst_h264_pps_clear (dst_pps);
+
+ *dst_pps = *src_pps;
+
+ if (src_pps->slice_group_id)
+ dst_pps->slice_group_id = g_memdup (src_pps->slice_group_id,
+ src_pps->pic_size_in_map_units_minus1 + 1);
+
+ return TRUE;
+}
+
/****** Parsing functions *****/
static gboolean
@@ -853,6 +879,31 @@ error:
}
static GstH264ParserResult
+gst_h264_parser_parse_recovery_point (GstH264NalParser * nalparser,
+ GstH264RecoveryPoint * rp, NalReader * nr)
+{
+ GstH264SPS *const sps = nalparser->last_sps;
+
+ GST_DEBUG ("parsing \"Recovery point\"");
+ if (!sps || !sps->valid) {
+ GST_WARNING ("didn't get the associated sequence paramater set for the "
+ "current access unit");
+ goto error;
+ }
+
+ READ_UE_ALLOWED (nr, rp->recovery_frame_cnt, 0, sps->max_frame_num - 1);
+ READ_UINT8 (nr, rp->exact_match_flag, 1);
+ READ_UINT8 (nr, rp->broken_link_flag, 1);
+ READ_UINT8 (nr, rp->changing_slice_group_idc, 2);
+
+ return GST_H264_PARSER_OK;
+
+error:
+ GST_WARNING ("error parsing \"Recovery point\"");
+ return GST_H264_PARSER_ERROR;
+}
+
+static GstH264ParserResult
gst_h264_parser_parse_sei_message (GstH264NalParser * nalparser,
NalReader * nr, GstH264SEIMessage * sei)
{
@@ -893,18 +944,17 @@ gst_h264_parser_parse_sei_message (GstH264NalParser * nalparser,
res = gst_h264_parser_parse_pic_timing (nalparser,
&sei->payload.pic_timing, nr);
break;
- default:{
+ case GST_H264_SEI_RECOVERY_POINT:
+ res = gst_h264_parser_parse_recovery_point (nalparser,
+ &sei->payload.recovery_point, nr);
+ break;
+ default:
/* Just consume payloadSize bytes, which does not account for
emulation prevention bytes */
- guint nbits = payload_size % 8;
- while (payload_size > 0) {
- nal_reader_skip (nr, nbits);
- payload_size -= nbits;
- nbits = 8;
- }
+ if (!nal_reader_skip_long (nr, payload_size))
+ goto error;
res = GST_H264_PARSER_OK;
break;
- }
}
/* When SEI message doesn't end at byte boundary,
@@ -961,6 +1011,10 @@ gst_h264_nal_parser_new (void)
void
gst_h264_nal_parser_free (GstH264NalParser * nalparser)
{
+ guint i;
+
+ for (i = 0; i < GST_H264_MAX_PPS_COUNT; i++)
+ gst_h264_pps_clear (&nalparser->pps[i]);
g_slice_free (GstH264NalParser, nalparser);
nalparser = NULL;
@@ -1415,6 +1469,10 @@ error:
*
* Parses @data, and fills the @pps structure.
*
+ * The resulting @pps data structure shall be deallocated with the
+ * gst_h264_pps_clear() function when it is no longer needed, or prior
+ * to parsing a new PPS NAL unit.
+ *
* Returns: a #GstH264ParserResult
*/
GstH264ParserResult
@@ -1535,6 +1593,7 @@ done:
error:
GST_WARNING ("error parsing \"Picture parameter set\"");
pps->valid = FALSE;
+ gst_h264_pps_clear (pps);
return GST_H264_PARSER_ERROR;
}
@@ -1546,6 +1605,10 @@ error:
*
* Parses @data, and fills the @pps structure.
*
+ * The resulting @pps data structure shall be deallocated with the
+ * gst_h264_pps_clear() function when it is no longer needed, or prior
+ * to parsing a new PPS NAL unit.
+ *
* Returns: a #GstH264ParserResult
*/
GstH264ParserResult
@@ -1557,7 +1620,8 @@ gst_h264_parser_parse_pps (GstH264NalParser * nalparser,
if (res == GST_H264_PARSER_OK) {
GST_DEBUG ("adding picture parameter set with id: %d to array", pps->id);
- nalparser->pps[pps->id] = *pps;
+ if (!gst_h264_pps_copy (&nalparser->pps[pps->id], pps))
+ return GST_H264_PARSER_ERROR;
nalparser->last_pps = &nalparser->pps[pps->id];
}
@@ -1565,6 +1629,23 @@ gst_h264_parser_parse_pps (GstH264NalParser * nalparser,
}
/**
+ * gst_h264_pps_clear:
+ * @pps: The #GstH264PPS to free
+ *
+ * Clears all @pps internal resources.
+ *
+ * Since: 1.4
+ */
+void
+gst_h264_pps_clear (GstH264PPS * pps)
+{
+ g_return_if_fail (pps != NULL);
+
+ g_free (pps->slice_group_id);
+ pps->slice_group_id = NULL;
+}
+
+/**
* gst_h264_parser_parse_slice_hdr:
* @nalparser: a #GstH264NalParser
* @nalu: The #GST_H264_NAL_SLICE #GstH264NalUnit to parse