diff options
Diffstat (limited to 'gst-libs/gst/codecparsers/gsth264parser.c')
-rw-r--r-- | gst-libs/gst/codecparsers/gsth264parser.c | 99 |
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 |