mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
av1parse: push all data once when input alignment not smaller than output.
When the incoming data has big alignment than the output, we do not need to call finish_frame() and exit the current handle_frame() for each splitted frame. We can push them all at one shot with in one handle_frame(), whcih may improve the performance and can help us to find the edge of TU. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3182>
This commit is contained in:
parent
b7d3a219ab
commit
ee5d7ce075
1 changed files with 57 additions and 22 deletions
|
@ -1562,6 +1562,19 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_av1_parse_create_subframe (GstBaseParseFrame * frame,
|
||||||
|
GstBaseParseFrame * subframe, GstBuffer * buffer)
|
||||||
|
{
|
||||||
|
gst_base_parse_frame_init (subframe);
|
||||||
|
subframe->flags |= frame->flags;
|
||||||
|
subframe->offset = frame->offset;
|
||||||
|
subframe->overhead = frame->overhead;
|
||||||
|
/* Just ref the input buffer. The base parse will check that
|
||||||
|
pointer, and it will be replaced by its out_buffer later. */
|
||||||
|
subframe->buffer = gst_buffer_ref (buffer);
|
||||||
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_av1_parse_handle_to_small_and_equal_align (GstBaseParse * parse,
|
gst_av1_parse_handle_to_small_and_equal_align (GstBaseParse * parse,
|
||||||
GstBaseParseFrame * frame, gint * skipsize)
|
GstBaseParseFrame * frame, gint * skipsize)
|
||||||
|
@ -1572,47 +1585,69 @@ gst_av1_parse_handle_to_small_and_equal_align (GstBaseParse * parse,
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
GstAV1ParserResult res = GST_AV1_PARSER_INVALID_OPERATION;
|
GstAV1ParserResult res = GST_AV1_PARSER_INVALID_OPERATION;
|
||||||
GstBuffer *buffer = gst_buffer_ref (frame->buffer);
|
GstBuffer *buffer = gst_buffer_ref (frame->buffer);
|
||||||
guint32 total_consumed, consumed;
|
guint32 offset, consumed_before_push, consumed;
|
||||||
gboolean frame_complete;
|
gboolean frame_complete;
|
||||||
|
GstBaseParseFrame subframe;
|
||||||
|
|
||||||
if (!gst_buffer_map (buffer, &map_info, GST_MAP_READ)) {
|
if (!gst_buffer_map (buffer, &map_info, GST_MAP_READ)) {
|
||||||
GST_ERROR_OBJECT (parse, "Couldn't map incoming buffer");
|
GST_ERROR_OBJECT (parse, "Couldn't map incoming buffer");
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
total_consumed = 0;
|
consumed_before_push = 0;
|
||||||
|
offset = 0;
|
||||||
frame_complete = FALSE;
|
frame_complete = FALSE;
|
||||||
again:
|
again:
|
||||||
while (total_consumed < map_info.size) {
|
while (offset < map_info.size) {
|
||||||
res = gst_av1_parser_identify_one_obu (self->parser,
|
res = gst_av1_parser_identify_one_obu (self->parser,
|
||||||
map_info.data + total_consumed, map_info.size - total_consumed,
|
map_info.data + offset, map_info.size - offset, &obu, &consumed);
|
||||||
&obu, &consumed);
|
|
||||||
if (res == GST_AV1_PARSER_OK)
|
if (res == GST_AV1_PARSER_OK)
|
||||||
res = gst_av1_parse_handle_one_obu (self, &obu, &frame_complete, NULL);
|
res = gst_av1_parse_handle_one_obu (self, &obu, &frame_complete, NULL);
|
||||||
if (res != GST_AV1_PARSER_OK)
|
if (res != GST_AV1_PARSER_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (obu.obu_type == GST_AV1_OBU_TEMPORAL_DELIMITER && total_consumed) {
|
if (obu.obu_type == GST_AV1_OBU_TEMPORAL_DELIMITER
|
||||||
|
&& consumed_before_push > 0) {
|
||||||
GST_DEBUG_OBJECT (self, "Encounter TD inside one %s aligned"
|
GST_DEBUG_OBJECT (self, "Encounter TD inside one %s aligned"
|
||||||
" buffer, should not happen normally.",
|
" buffer, should not happen normally.",
|
||||||
gst_av1_parse_alignment_to_string (self->in_align));
|
gst_av1_parse_alignment_to_string (self->in_align));
|
||||||
frame_complete = TRUE;
|
|
||||||
if (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B)
|
if (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B)
|
||||||
gst_av1_parser_reset_annex_b (self->parser);
|
gst_av1_parser_reset_annex_b (self->parser);
|
||||||
/* Not include this TD obu, it should belong to the next TU or frame */
|
|
||||||
break;
|
/* Not include this TD obu, it should belong to the next TU or frame,
|
||||||
|
we push all the data we already got. */
|
||||||
|
gst_av1_parse_create_subframe (frame, &subframe, buffer);
|
||||||
|
ret = gst_av1_parse_push_data (self, &subframe,
|
||||||
|
consumed_before_push, TRUE);
|
||||||
|
if (ret != GST_FLOW_OK)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* Begin to find the next. */
|
||||||
|
frame_complete = FALSE;
|
||||||
|
consumed_before_push = 0;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_av1_parse_cache_one_obu (self, buffer, &obu,
|
gst_av1_parse_cache_one_obu (self, buffer, &obu,
|
||||||
map_info.data + total_consumed, consumed, frame_complete);
|
map_info.data + offset, consumed, frame_complete);
|
||||||
|
|
||||||
total_consumed += consumed;
|
offset += consumed;
|
||||||
|
consumed_before_push += consumed;
|
||||||
|
|
||||||
if (self->align == GST_AV1_PARSE_ALIGN_OBU)
|
if ((self->align == GST_AV1_PARSE_ALIGN_OBU) ||
|
||||||
break;
|
(self->align == GST_AV1_PARSE_ALIGN_FRAME && frame_complete)) {
|
||||||
|
gst_av1_parse_create_subframe (frame, &subframe, buffer);
|
||||||
|
ret = gst_av1_parse_push_data (self, &subframe,
|
||||||
|
consumed_before_push, frame_complete);
|
||||||
|
if (ret != GST_FLOW_OK)
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (self->align == GST_AV1_PARSE_ALIGN_FRAME && frame_complete)
|
/* Begin to find the next. */
|
||||||
break;
|
frame_complete = FALSE;
|
||||||
|
consumed_before_push = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res == GST_AV1_PARSER_BITSTREAM_ERROR ||
|
if (res == GST_AV1_PARSER_BITSTREAM_ERROR ||
|
||||||
|
@ -1638,7 +1673,7 @@ again:
|
||||||
goto out;
|
goto out;
|
||||||
} else if (res == GST_AV1_PARSER_DROP) {
|
} else if (res == GST_AV1_PARSER_DROP) {
|
||||||
GST_DEBUG_OBJECT (parse, "Drop %d data", consumed);
|
GST_DEBUG_OBJECT (parse, "Drop %d data", consumed);
|
||||||
total_consumed += consumed;
|
offset += consumed;
|
||||||
gst_av1_parse_reset_obu_data_state (self);
|
gst_av1_parse_reset_obu_data_state (self);
|
||||||
res = GST_AV1_PARSER_OK;
|
res = GST_AV1_PARSER_OK;
|
||||||
goto again;
|
goto again;
|
||||||
|
@ -1649,18 +1684,18 @@ again:
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_assert (total_consumed >= map_info.size || frame_complete
|
/* If the total buffer exhausted but frame is not complete, we just
|
||||||
|| self->align == GST_AV1_PARSE_ALIGN_OBU);
|
push the left data and consider it as a frame. */
|
||||||
|
if (consumed_before_push > 0 && !frame_complete
|
||||||
if (total_consumed >= map_info.size && !frame_complete
|
|
||||||
&& self->align == GST_AV1_PARSE_ALIGN_FRAME) {
|
&& self->align == GST_AV1_PARSE_ALIGN_FRAME) {
|
||||||
/* Warning and still consider this frame as complete */
|
g_assert (offset >= map_info.size);
|
||||||
|
/* Warning and still consider the frame is complete */
|
||||||
GST_WARNING_OBJECT (self, "Exhaust the buffer but still incomplete frame,"
|
GST_WARNING_OBJECT (self, "Exhaust the buffer but still incomplete frame,"
|
||||||
" should not happend in %s alignment",
|
" should not happend in %s alignment",
|
||||||
gst_av1_parse_alignment_to_string (self->in_align));
|
gst_av1_parse_alignment_to_string (self->in_align));
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = gst_av1_parse_push_data (self, frame, total_consumed, frame_complete);
|
ret = gst_av1_parse_push_data (self, frame, consumed_before_push, TRUE);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
gst_buffer_unmap (buffer, &map_info);
|
gst_buffer_unmap (buffer, &map_info);
|
||||||
|
|
Loading…
Reference in a new issue