summaryrefslogtreecommitdiff
path: root/gst/videoparsers
diff options
context:
space:
mode:
authorHe Junyan <junyan.he@intel.com>2021-01-23 19:05:57 +0800
committerVíctor Manuel Jáquez Leal <vjaquez@igalia.com>2021-01-26 12:22:31 +0000
commitd83f25325893f5a2d6bea6ca74f94b8e37dc547e (patch)
tree0d0bb5a9d070398571e5a7ada6cea975ec68dd50 /gst/videoparsers
parentee1f6017ac48243cbbf0d5976482ae6043416bc6 (diff)
downloadgstreamer-plugins-bad-d83f25325893f5a2d6bea6ca74f94b8e37dc547e.tar.gz
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: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1979>
Diffstat (limited to 'gst/videoparsers')
-rw-r--r--gst/videoparsers/gstav1parse.c83
1 files changed, 42 insertions, 41 deletions
diff --git a/gst/videoparsers/gstav1parse.c b/gst/videoparsers/gstav1parse.c
index d616863e6..9269468f1 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;
-
- 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);
+ 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);
- 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,16 +1257,37 @@ 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);
@@ -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 */