From 67df2072801012dd084b4da6e916db9967f5650f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Zanelli?= Date: Fri, 31 Jan 2014 17:07:42 +0100 Subject: [PATCH] codecparsers: h264: add support for Recovery Point SEI message. The recovery point SEI message helps a decoder in determining if the decoding process would produce acceptable pictures for display after the decoder initiates random access or after the encoder indicates a broken link in the coded video sequence. This is not used in the h264parse element, but it could help debugging. https://bugzilla.gnome.org/show_bug.cgi?id=723380 --- gst-libs/gst/codecparsers/gsth264parser.c | 29 +++++++++++++++++++++++ gst-libs/gst/codecparsers/gsth264parser.h | 14 ++++++++++- gst/videoparsers/gsth264parse.c | 10 ++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/codecparsers/gsth264parser.c b/gst-libs/gst/codecparsers/gsth264parser.c index f960824ac4..a0988e6e67 100644 --- a/gst-libs/gst/codecparsers/gsth264parser.c +++ b/gst-libs/gst/codecparsers/gsth264parser.c @@ -852,6 +852,31 @@ error: return GST_H264_PARSER_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,6 +918,10 @@ gst_h264_parser_parse_sei_message (GstH264NalParser * nalparser, res = gst_h264_parser_parse_pic_timing (nalparser, &sei->payload.pic_timing, nr); break; + 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 */ diff --git a/gst-libs/gst/codecparsers/gsth264parser.h b/gst-libs/gst/codecparsers/gsth264parser.h index f9e5083eb0..6c7d6a0f26 100644 --- a/gst-libs/gst/codecparsers/gsth264parser.h +++ b/gst-libs/gst/codecparsers/gsth264parser.h @@ -156,6 +156,7 @@ typedef enum * GstH264SEIPayloadType: * @GST_H264_SEI_BUF_PERIOD: Buffering Period SEI Message * @GST_H264_SEI_PIC_TIMING: Picture Timing SEI Message + * @GST_H264_SEI_RECOVERY_POINT: Recovery Point SEI Message (D.2.7) * ... * * The type of SEI message. @@ -163,7 +164,8 @@ typedef enum typedef enum { GST_H264_SEI_BUF_PERIOD = 0, - GST_H264_SEI_PIC_TIMING = 1 + GST_H264_SEI_PIC_TIMING = 1, + GST_H264_SEI_RECOVERY_POINT = 6, /* and more... */ } GstH264SEIPayloadType; @@ -234,6 +236,7 @@ typedef struct _GstH264SliceHdr GstH264SliceHdr; typedef struct _GstH264ClockTimestamp GstH264ClockTimestamp; typedef struct _GstH264PicTiming GstH264PicTiming; typedef struct _GstH264BufferingPeriod GstH264BufferingPeriod; +typedef struct _GstH264RecoveryPoint GstH264RecoveryPoint; typedef struct _GstH264SEIMessage GstH264SEIMessage; /** @@ -706,6 +709,14 @@ struct _GstH264BufferingPeriod guint8 vcl_initial_cpb_removal_delay_offset[32]; }; +struct _GstH264RecoveryPoint +{ + guint32 recovery_frame_cnt; + guint8 exact_match_flag; + guint8 broken_link_flag; + guint8 changing_slice_group_idc; +}; + struct _GstH264SEIMessage { GstH264SEIPayloadType payloadType; @@ -713,6 +724,7 @@ struct _GstH264SEIMessage union { GstH264BufferingPeriod buffering_period; GstH264PicTiming pic_timing; + GstH264RecoveryPoint recovery_point; /* ... could implement more */ } payload; }; diff --git a/gst/videoparsers/gsth264parse.c b/gst/videoparsers/gsth264parse.c index 2b43b301d9..dbee6a6cbd 100644 --- a/gst/videoparsers/gsth264parse.c +++ b/gst/videoparsers/gsth264parse.c @@ -501,6 +501,16 @@ gst_h264_parse_process_sei (GstH264Parse * h264parse, GstH264NalUnit * nalu) "new buffering period; ts_trn_nb updated: %" GST_TIME_FORMAT, GST_TIME_ARGS (h264parse->ts_trn_nb)); break; + + /* Additional messages that are not innerly useful to the + * element but for debugging purposes */ + case GST_H264_SEI_RECOVERY_POINT: + GST_LOG_OBJECT (h264parse, "recovery point found: %u %u %u %u", + sei.payload.recovery_point.recovery_frame_cnt, + sei.payload.recovery_point.exact_match_flag, + sei.payload.recovery_point.broken_link_flag, + sei.payload.recovery_point.changing_slice_group_idc); + break; } } g_array_free (messages, TRUE);