From d83f25325893f5a2d6bea6ca74f94b8e37dc547e Mon Sep 17 00:00:00 2001 From: He Junyan Date: Sat, 23 Jan 2021 19:05:57 +0800 Subject: [PATCH] av1parse: Output each OBU when output is aligned to obu. The current behaviour for obu aligned output is not very precise. Several OBUs will be output together within one gst buffer. We should output each gst buffer just containing one OBU. This is the same way as the h264/h265 parse do when NAL aligned. Part-of: --- gst/videoparsers/gstav1parse.c | 83 +++++++++++++++++----------------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/gst/videoparsers/gstav1parse.c b/gst/videoparsers/gstav1parse.c index d616863e61..9269468f14 100644 --- a/gst/videoparsers/gstav1parse.c +++ b/gst/videoparsers/gstav1parse.c @@ -514,6 +514,9 @@ gst_av1_parse_update_src_caps (GstAV1Parse * self, GstCaps * caps) gint fps_n = 0, fps_d = 0; const gchar *profile = NULL; + if (G_UNLIKELY (!gst_pad_has_current_caps (GST_BASE_PARSE_SRC_PAD (self)))) + self->update_caps = TRUE; + if (!self->update_caps) return; @@ -1213,7 +1216,7 @@ gst_av1_parse_handle_obu_to_obu (GstBaseParse * parse, GstFlowReturn ret = GST_FLOW_OK; GstAV1ParserResult res; GstBuffer *buffer = gst_buffer_ref (frame->buffer); - guint32 consumed, total_consumed; + guint32 consumed; gboolean frame_complete; if (!gst_buffer_map (buffer, &map_info, GST_MAP_READ)) { @@ -1222,42 +1225,14 @@ gst_av1_parse_handle_obu_to_obu (GstBaseParse * parse, return GST_FLOW_ERROR; } - total_consumed = 0; -again: - while (total_consumed < map_info.size) { - frame_complete = FALSE; - res = gst_av1_parser_identify_one_obu (self->parser, - map_info.data + total_consumed, map_info.size - total_consumed, - &obu, &consumed); - if (res == GST_AV1_PARSER_OK) - res = gst_av1_parse_handle_one_obu (self, &obu, &frame_complete); - if (res != GST_AV1_PARSER_OK) - break; + consumed = 0; + frame_complete = FALSE; + res = gst_av1_parser_identify_one_obu (self->parser, map_info.data, + map_info.size, &obu, &consumed); + if (res == GST_AV1_PARSER_OK) + res = gst_av1_parse_handle_one_obu (self, &obu, &frame_complete); - total_consumed += consumed; - } - g_assert (total_consumed <= map_info.size); - - if (total_consumed) { - /* If we get something, always output it even already met some error. - Next handle_frame loop will handle that error. */ - gst_av1_parse_update_src_caps (self, NULL); - if (self->discont) { - GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT); - self->discont = FALSE; - } - if (self->header) { - GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_HEADER); - self->header = FALSE; - } - /* happen to be a frame boundary */ - if (frame_complete) - GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_MARKER); - - ret = gst_base_parse_finish_frame (parse, frame, total_consumed); - *skipsize = 0; - goto out; - } + g_assert (consumed <= map_info.size); if (res == GST_AV1_PARSER_BITSTREAM_ERROR) { if (consumed) { @@ -1267,6 +1242,7 @@ again: } GST_WARNING_OBJECT (parse, "Parse obu error, discard %d.", *skipsize); ret = GST_FLOW_OK; + goto out; } else if (res == GST_AV1_PARSER_NO_MORE_DATA) { *skipsize = 0; @@ -1281,17 +1257,38 @@ again: *skipsize); } ret = GST_FLOW_OK; + goto out; } else if (res == GST_AV1_PARSER_DROP) { GST_DEBUG_OBJECT (parse, "Drop %d data", consumed); - total_consumed += consumed; - res = GST_AV1_PARSER_OK; - goto again; + *skipsize = consumed; + ret = GST_FLOW_OK; + goto out; } else if (res != GST_AV1_PARSER_OK) { GST_ERROR_OBJECT (parse, "Parse obu get unexpect error %d", res); *skipsize = 0; ret = GST_FLOW_ERROR; + goto out; } + g_assert (consumed); + + gst_av1_parse_update_src_caps (self, NULL); + if (self->discont) { + GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT); + self->discont = FALSE; + } + if (self->header) { + GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_HEADER); + self->header = FALSE; + } + /* happen to be a frame boundary */ + if (frame_complete) + GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_MARKER); + + GST_LOG_OBJECT (self, "Output one buffer with size %d", consumed); + ret = gst_base_parse_finish_frame (parse, frame, consumed); + *skipsize = 0; + out: gst_buffer_unmap (buffer, &map_info); gst_buffer_unref (buffer); @@ -1341,10 +1338,12 @@ again: total_consumed += consumed; + if (self->align == GST_AV1_PARSE_ALIGN_OBU) + break; + if (self->align == GST_AV1_PARSE_ALIGN_FRAME && frame_complete) break; } - g_assert (total_consumed <= map_info.size); if (res == GST_AV1_PARSER_BITSTREAM_ERROR) { /* Discard the whole frame */ @@ -1375,7 +1374,9 @@ again: goto out; } - g_assert (total_consumed >= map_info.size || frame_complete); + g_assert (total_consumed >= map_info.size || frame_complete + || self->align == GST_AV1_PARSE_ALIGN_OBU); + if (total_consumed >= map_info.size && !frame_complete && self->align == GST_AV1_PARSE_ALIGN_FRAME) { /* Warning and still consider this frame as complete */