mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 16:50:47 +00:00
av1parse: Always copy the OBU to cache.
The current optimization when input align and out out align are the same is not very correct. We simply copy the data from input buffer to output buffer, but we failed to consider the dropping of OBUs. When we need to drop some OBUs(such as filter out the OBUs of some temporal ID), we can not do simple copy. So we need to always copy the input OBUs into a cache. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1979>
This commit is contained in:
parent
a9c8aa4788
commit
ee1f6017ac
1 changed files with 44 additions and 40 deletions
|
@ -770,19 +770,22 @@ gst_av1_parse_set_sink_caps (GstBaseParse * parse, GstCaps * caps)
|
|||
|
||||
static GstFlowReturn
|
||||
gst_av1_parse_push_data (GstAV1Parse * self, GstBaseParseFrame * frame,
|
||||
guint32 finish_sz)
|
||||
guint32 finish_sz, gboolean frame_finished)
|
||||
{
|
||||
gsize sz;
|
||||
GstBuffer *buf;
|
||||
GstBuffer *buffer = frame->buffer;
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
|
||||
g_assert (self->align != self->in_align);
|
||||
/* Need to generate the final TU annex-b format */
|
||||
if (self->align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B) {
|
||||
guint8 size_data[GST_AV1_MAX_LEB_128_SIZE];
|
||||
guint size_len = 0;
|
||||
guint len;
|
||||
|
||||
/* When push a TU, it must also be a frame end. */
|
||||
g_assert (frame_finished);
|
||||
|
||||
/* Still some left in the frame cache */
|
||||
len = gst_adapter_available (self->frame_cache);
|
||||
if (len) {
|
||||
|
@ -825,13 +828,16 @@ gst_av1_parse_push_data (GstAV1Parse * self, GstBaseParseFrame * frame,
|
|||
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||
self->keyframe = FALSE;
|
||||
}
|
||||
/* Always be a frame boundary. */
|
||||
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_MARKER);
|
||||
|
||||
if (frame_finished)
|
||||
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_MARKER);
|
||||
|
||||
gst_buffer_replace (&frame->out_buffer, buf);
|
||||
gst_buffer_unref (buf);
|
||||
|
||||
gst_av1_parse_update_src_caps (self, NULL);
|
||||
GST_LOG_OBJECT (self, "complete one frame with size %" G_GSSIZE_FORMAT, sz);
|
||||
GST_LOG_OBJECT (self, "comsumed %d, output one buffer with size %"
|
||||
G_GSSIZE_FORMAT, finish_sz, sz);
|
||||
ret = gst_base_parse_finish_frame (GST_BASE_PARSE (self), frame, finish_sz);
|
||||
}
|
||||
|
||||
|
@ -967,6 +973,33 @@ gst_av1_parse_convert_from_annexb (GstAV1Parse * self, GstAV1OBU * obu)
|
|||
gst_bit_writer_reset (&bs);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_av1_parse_cache_one_obu (GstAV1Parse * self, GstAV1OBU * obu,
|
||||
guint8 * data, guint32 size, gboolean frame_complete)
|
||||
{
|
||||
gboolean need_convert = FALSE;
|
||||
GstBuffer *buf;
|
||||
|
||||
if (self->in_align != self->align
|
||||
&& (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B
|
||||
|| self->align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B))
|
||||
need_convert = TRUE;
|
||||
|
||||
if (need_convert) {
|
||||
if (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B) {
|
||||
gst_av1_parse_convert_from_annexb (self, obu);
|
||||
} else {
|
||||
gst_av1_parse_convert_to_annexb (self, obu, frame_complete);
|
||||
}
|
||||
} else if (self->align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B) {
|
||||
g_assert (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B);
|
||||
gst_av1_parse_convert_to_annexb (self, obu, frame_complete);
|
||||
} else {
|
||||
buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
|
||||
gst_adapter_push (self->cache_out, buf);
|
||||
}
|
||||
}
|
||||
|
||||
static GstAV1ParserResult
|
||||
gst_av1_parse_handle_sequence_obu (GstAV1Parse * self, GstAV1OBU * obu)
|
||||
{
|
||||
|
@ -1276,7 +1309,6 @@ gst_av1_parse_handle_to_small_and_equal_align (GstBaseParse * parse,
|
|||
GstAV1ParserResult res;
|
||||
GstBuffer *buffer = gst_buffer_ref (frame->buffer);
|
||||
guint32 total_consumed, consumed;
|
||||
gboolean need_convert = FALSE;
|
||||
gboolean frame_complete;
|
||||
|
||||
if (!gst_buffer_map (buffer, &map_info, GST_MAP_READ)) {
|
||||
|
@ -1284,11 +1316,6 @@ gst_av1_parse_handle_to_small_and_equal_align (GstBaseParse * parse,
|
|||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
if (self->in_align != self->align
|
||||
&& (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B
|
||||
|| self->align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B))
|
||||
need_convert = TRUE;
|
||||
|
||||
total_consumed = 0;
|
||||
frame_complete = FALSE;
|
||||
again:
|
||||
|
@ -1309,15 +1336,10 @@ again:
|
|||
break;
|
||||
}
|
||||
|
||||
total_consumed += consumed;
|
||||
gst_av1_parse_cache_one_obu (self, &obu,
|
||||
map_info.data + total_consumed, consumed, frame_complete);
|
||||
|
||||
if (need_convert) {
|
||||
if (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B) {
|
||||
gst_av1_parse_convert_from_annexb (self, &obu);
|
||||
} else {
|
||||
gst_av1_parse_convert_to_annexb (self, &obu, frame_complete);
|
||||
}
|
||||
}
|
||||
total_consumed += consumed;
|
||||
|
||||
if (self->align == GST_AV1_PARSE_ALIGN_FRAME && frame_complete)
|
||||
break;
|
||||
|
@ -1362,26 +1384,7 @@ again:
|
|||
gst_av1_parse_alignment_to_string (self->in_align));
|
||||
}
|
||||
|
||||
if (!need_convert) {
|
||||
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;
|
||||
}
|
||||
if (self->keyframe) {
|
||||
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||
self->keyframe = FALSE;
|
||||
}
|
||||
/* Always be a frame boundary. */
|
||||
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_MARKER);
|
||||
ret = gst_base_parse_finish_frame (parse, frame, total_consumed);
|
||||
} else {
|
||||
ret = gst_av1_parse_push_data (self, frame, total_consumed);
|
||||
}
|
||||
ret = gst_av1_parse_push_data (self, frame, total_consumed, frame_complete);
|
||||
|
||||
out:
|
||||
gst_buffer_unmap (buffer, &map_info);
|
||||
|
@ -1455,7 +1458,8 @@ again:
|
|||
|
||||
/* push the left anyway if no error */
|
||||
if (res == GST_AV1_PARSER_OK)
|
||||
ret = gst_av1_parse_push_data (self, frame, self->last_parsed_offset);
|
||||
ret = gst_av1_parse_push_data (self, frame,
|
||||
self->last_parsed_offset, TRUE);
|
||||
|
||||
self->last_parsed_offset = 0;
|
||||
|
||||
|
|
Loading…
Reference in a new issue