av1parse: Only check the TU bound when the alignment is TU.
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-bad / gst / videoparsers / gstav1parse.c
1 /* GStreamer
2  * Copyright (C) 2020 He Junyan <junyan.he@intel.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 /*
21  * SECTION:element-av1parse
22  * @title: av1parse
23  * @short_description: An AV1 stream parse.
24  *
25  * The minimal unit should be the BYTE.
26  * There are four types of AV1 alignment in the AV1 stream.
27  *
28  * alignment: byte, obu, frame, tu
29  *
30  * 1. Aligned to byte. The basic and default one for input.
31  * 2. Aligned to obu(Open Bitstream Units).
32  * 3. Aligned to frame. The default one for output. This ensures that
33  *    each buffer contains only one frame or frame header with the
34  *    show_existing flag for the base or sub layer. It is useful for
35  *    the decoder.
36  * 4. Aligned to tu(Temporal Unit). A temporal unit consists of all the
37  *    OBUs that are associated with a specific, distinct time instant.
38  *    When scalability is disabled, it contains just exact one showing
39  *    frame(may contain several unshowing frames). When scalability is
40  *    enabled, it contains frames depending on the layer number. It should
41  *    begin with a temporal delimiter obu. It may be useful for mux/demux
42  *    to index the data of some timestamp.
43  *
44  * The annex B define a special format for the temporal unit. The size of
45  * each temporal unit is extract out to the header of the buffer, and no
46  * size field inside the each obu. There are two stream formats:
47  *
48  * stream-format: obu-stream, annexb
49  *
50  * 1. obu-stream. The basic and default one.
51  * 2. annexb. A special stream of temporal unit. It also implies that the
52  *    alignment should be TU.
53  *
54  * This AV1 parse implements the conversion between the alignments and the
55  * stream-formats. If the input and output have the same alignment and the
56  * same stream-format, it will check and bypass the data.
57  *
58  * ## Example launch line to generate annex B format AV1 stream:
59  * ```
60  * gst-launch-1.0 filesrc location=sample.av1 ! ivfparse ! av1parse !  \
61  *   video/x-av1,alignment=\(string\)tu,stream-format=\(string\)annexb ! \
62  *   filesink location=matroskamux ! filesink location=trans.mkv
63  * ```
64  *
65  * Since: 1.20
66  */
67
68 #ifdef HAVE_CONFIG_H
69 #include "config.h"
70 #endif
71
72 #include <gst/base/gstbitreader.h>
73 #include <gst/base/gstbitwriter.h>
74 #include <gst/codecparsers/gstav1parser.h>
75 #include <gst/video/video.h>
76 #include "gstvideoparserselements.h"
77 #include "gstav1parse.h"
78
79 #include <string.h>
80
81 #define GST_AV1_MAX_LEB_128_SIZE 8
82
83 GST_DEBUG_CATEGORY (av1_parse_debug);
84 #define GST_CAT_DEFAULT av1_parse_debug
85
86 /* We combine the stream format and the alignment
87    together. When stream format is annexb, the
88    alignment must be TU. */
89 typedef enum
90 {
91   GST_AV1_PARSE_ALIGN_ERROR = -1,
92   GST_AV1_PARSE_ALIGN_NONE = 0,
93   GST_AV1_PARSE_ALIGN_BYTE,
94   GST_AV1_PARSE_ALIGN_OBU,
95   GST_AV1_PARSE_ALIGN_FRAME,
96   GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT,
97   GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B,
98 } GstAV1ParseAligment;
99
100 struct _GstAV1Parse
101 {
102   GstBaseParse parent;
103
104   gint width;
105   gint height;
106   gint subsampling_x;
107   gint subsampling_y;
108   gboolean mono_chrome;
109   guint8 bit_depth;
110   gchar *colorimetry;
111   GstAV1Profile profile;
112
113   GstAV1ParseAligment in_align;
114   gboolean detect_annex_b;
115   GstAV1ParseAligment align;
116
117   GstAV1Parser *parser;
118   GstAdapter *cache_out;
119   guint last_parsed_offset;
120   GstAdapter *frame_cache;
121   guint highest_spatial_id;
122   gint last_shown_frame_temporal_id;
123   gint last_shown_frame_spatial_id;
124   gboolean within_one_frame;
125   gboolean update_caps;
126   gboolean discont;
127   gboolean header;
128   gboolean keyframe;
129   gboolean show_frame;
130 };
131
132 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
133     GST_PAD_SINK,
134     GST_PAD_ALWAYS,
135     GST_STATIC_CAPS ("video/x-av1"));
136
137 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
138     GST_PAD_SRC,
139     GST_PAD_ALWAYS,
140     GST_STATIC_CAPS ("video/x-av1, parsed = (boolean) true, "
141         "stream-format=(string) { obu-stream, annexb }, "
142         "alignment=(string) { obu, tu, frame }"));
143
144 #define parent_class gst_av1_parse_parent_class
145 G_DEFINE_TYPE (GstAV1Parse, gst_av1_parse, GST_TYPE_BASE_PARSE);
146 GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (av1parse, "av1parse", GST_RANK_SECONDARY,
147     GST_TYPE_AV1_PARSE, videoparsers_element_init (plugin));
148
149 static void
150 remove_fields (GstCaps * caps, gboolean all)
151 {
152   guint i, n;
153
154   n = gst_caps_get_size (caps);
155   for (i = 0; i < n; i++) {
156     GstStructure *s = gst_caps_get_structure (caps, i);
157
158     if (all) {
159       gst_structure_remove_field (s, "alignment");
160       gst_structure_remove_field (s, "stream-format");
161     }
162     gst_structure_remove_field (s, "parsed");
163   }
164 }
165
166 static const gchar *
167 _obu_name (GstAV1OBUType type)
168 {
169   switch (type) {
170     case GST_AV1_OBU_SEQUENCE_HEADER:
171       return "sequence header";
172     case GST_AV1_OBU_TEMPORAL_DELIMITER:
173       return "temporal delimiter";
174     case GST_AV1_OBU_FRAME_HEADER:
175       return "frame header";
176     case GST_AV1_OBU_TILE_GROUP:
177       return "tile group";
178     case GST_AV1_OBU_METADATA:
179       return "metadata";
180     case GST_AV1_OBU_FRAME:
181       return "frame";
182     case GST_AV1_OBU_REDUNDANT_FRAME_HEADER:
183       return "redundant frame header";
184     case GST_AV1_OBU_TILE_LIST:
185       return "tile list";
186     case GST_AV1_OBU_PADDING:
187       return "padding";
188     default:
189       return "unknown";
190   }
191
192   return NULL;
193 }
194
195 static guint32
196 _read_leb128 (guint8 * data, GstAV1ParserResult * retval, guint32 * comsumed)
197 {
198   guint8 leb128_byte = 0;
199   guint64 value = 0;
200   gint i;
201   gboolean result;
202   GstBitReader br;
203   guint32 cur_pos;
204
205   gst_bit_reader_init (&br, data, 8);
206
207   cur_pos = gst_bit_reader_get_pos (&br);
208   for (i = 0; i < 8; i++) {
209     leb128_byte = 0;
210     result = gst_bit_reader_get_bits_uint8 (&br, &leb128_byte, 8);
211     if (result == FALSE) {
212       *retval = GST_AV1_PARSER_BITSTREAM_ERROR;
213       return 0;
214     }
215
216     value |= (((gint) leb128_byte & 0x7f) << (i * 7));
217     if (!(leb128_byte & 0x80))
218       break;
219   }
220
221   *comsumed = (gst_bit_reader_get_pos (&br) - cur_pos) / 8;
222   /* check for bitstream conformance see chapter4.10.5 */
223   if (value < G_MAXUINT32) {
224     *retval = GST_AV1_PARSER_OK;
225     return (guint32) value;
226   } else {
227     GST_WARNING ("invalid leb128");
228     *retval = GST_AV1_PARSER_BITSTREAM_ERROR;
229     return 0;
230   }
231 }
232
233 static gsize
234 _leb_size_in_bytes (guint64 value)
235 {
236   gsize size = 0;
237   do {
238     ++size;
239   } while ((value >>= 7) != 0);
240
241   return size;
242 }
243
244 static gboolean
245 _write_leb128 (guint8 * data, guint * len, guint64 value)
246 {
247   guint leb_size = _leb_size_in_bytes (value);
248   guint i;
249
250   if (value > G_MAXUINT32 || leb_size > GST_AV1_MAX_LEB_128_SIZE)
251     return FALSE;
252
253   for (i = 0; i < leb_size; ++i) {
254     guint8 byte = value & 0x7f;
255     value >>= 7;
256
257     /* Signal that more bytes follow. */
258     if (value != 0)
259       byte |= 0x80;
260
261     *(data + i) = byte;
262   }
263
264   *len = leb_size;
265   return TRUE;
266 }
267
268 static gboolean gst_av1_parse_start (GstBaseParse * parse);
269 static gboolean gst_av1_parse_stop (GstBaseParse * parse);
270 static GstFlowReturn gst_av1_parse_handle_frame (GstBaseParse * parse,
271     GstBaseParseFrame * frame, gint * skipsize);
272 static gboolean gst_av1_parse_set_sink_caps (GstBaseParse * parse,
273     GstCaps * caps);
274 static GstCaps *gst_av1_parse_get_sink_caps (GstBaseParse * parse,
275     GstCaps * filter);
276
277 /* Clear the parse state related to data kind OBUs. */
278 static void
279 gst_av1_parse_reset_obu_data_state (GstAV1Parse * self)
280 {
281   self->last_shown_frame_temporal_id = -1;
282   self->last_shown_frame_spatial_id = -1;
283   self->within_one_frame = FALSE;
284 }
285
286 static void
287 gst_av1_parse_reset (GstAV1Parse * self)
288 {
289   self->width = 0;
290   self->height = 0;
291   self->subsampling_x = -1;
292   self->subsampling_y = -1;
293   self->mono_chrome = FALSE;
294   self->profile = GST_AV1_PROFILE_UNDEFINED;
295   self->bit_depth = 0;
296   self->align = GST_AV1_PARSE_ALIGN_NONE;
297   self->in_align = GST_AV1_PARSE_ALIGN_NONE;
298   self->detect_annex_b = FALSE;
299   self->discont = TRUE;
300   self->header = FALSE;
301   self->keyframe = FALSE;
302   self->show_frame = FALSE;
303   self->last_parsed_offset = 0;
304   self->highest_spatial_id = 0;
305   gst_av1_parse_reset_obu_data_state (self);
306   g_clear_pointer (&self->colorimetry, g_free);
307   g_clear_pointer (&self->parser, gst_av1_parser_free);
308   gst_adapter_clear (self->cache_out);
309   gst_adapter_clear (self->frame_cache);
310 }
311
312 static void
313 gst_av1_parse_init (GstAV1Parse * self)
314 {
315   gst_base_parse_set_pts_interpolation (GST_BASE_PARSE (self), FALSE);
316   gst_base_parse_set_infer_ts (GST_BASE_PARSE (self), FALSE);
317
318   GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (self));
319   GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (self));
320
321   self->cache_out = gst_adapter_new ();
322   self->frame_cache = gst_adapter_new ();
323 }
324
325 static void
326 gst_av1_parse_finalize (GObject * object)
327 {
328   GstAV1Parse *self = GST_AV1_PARSE (object);
329
330   gst_av1_parse_reset (self);
331   g_object_unref (self->cache_out);
332   g_object_unref (self->frame_cache);
333
334   G_OBJECT_CLASS (parent_class)->finalize (object);
335 }
336
337 static void
338 gst_av1_parse_class_init (GstAV1ParseClass * klass)
339 {
340   GObjectClass *gobject_class = (GObjectClass *) klass;
341   GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
342   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
343
344   gobject_class->finalize = gst_av1_parse_finalize;
345   parse_class->start = GST_DEBUG_FUNCPTR (gst_av1_parse_start);
346   parse_class->stop = GST_DEBUG_FUNCPTR (gst_av1_parse_stop);
347   parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_av1_parse_handle_frame);
348   parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_av1_parse_set_sink_caps);
349   parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_av1_parse_get_sink_caps);
350
351   gst_element_class_add_static_pad_template (element_class, &srctemplate);
352   gst_element_class_add_static_pad_template (element_class, &sinktemplate);
353
354   gst_element_class_set_static_metadata (element_class, "AV1 parser",
355       "Codec/Parser/Converter/Video",
356       "Parses AV1 streams", "He Junyan <junyan.he@intel.com>");
357
358   GST_DEBUG_CATEGORY_INIT (av1_parse_debug, "av1parse", 0, "av1 parser");
359 }
360
361 static gboolean
362 gst_av1_parse_start (GstBaseParse * parse)
363 {
364   GstAV1Parse *self = GST_AV1_PARSE (parse);
365
366   GST_DEBUG_OBJECT (self, "start");
367
368   gst_av1_parse_reset (self);
369   self->parser = gst_av1_parser_new ();
370
371   /* At least the OBU header. */
372   gst_base_parse_set_min_frame_size (parse, 1);
373
374   return TRUE;
375 }
376
377 static gboolean
378 gst_av1_parse_stop (GstBaseParse * parse)
379 {
380   GstAV1Parse *self = GST_AV1_PARSE (parse);
381
382   GST_DEBUG_OBJECT (self, "stop");
383   g_clear_pointer (&self->parser, gst_av1_parser_free);
384
385   return TRUE;
386 }
387
388 static const gchar *
389 gst_av1_parse_profile_to_string (GstAV1Profile profile)
390 {
391   switch (profile) {
392     case GST_AV1_PROFILE_0:
393       return "main";
394     case GST_AV1_PROFILE_1:
395       return "high";
396     case GST_AV1_PROFILE_2:
397       return "professional";
398     default:
399       break;
400   }
401
402   return NULL;
403 }
404
405 static GstAV1Profile
406 gst_av1_parse_profile_from_string (const gchar * profile)
407 {
408   if (!profile)
409     return GST_AV1_PROFILE_UNDEFINED;
410
411   if (g_strcmp0 (profile, "main") == 0)
412     return GST_AV1_PROFILE_0;
413   else if (g_strcmp0 (profile, "high") == 0)
414     return GST_AV1_PROFILE_1;
415   else if (g_strcmp0 (profile, "professional") == 0)
416     return GST_AV1_PROFILE_2;
417
418   return GST_AV1_PROFILE_UNDEFINED;
419 }
420
421 static const gchar *
422 gst_av1_parse_alignment_to_steam_format_string (GstAV1ParseAligment align)
423 {
424   switch (align) {
425     case GST_AV1_PARSE_ALIGN_BYTE:
426       return "obu-stream";
427     case GST_AV1_PARSE_ALIGN_OBU:
428     case GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT:
429     case GST_AV1_PARSE_ALIGN_FRAME:
430       return "obu-stream";
431     case GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B:
432       return "annexb";
433     default:
434       GST_WARNING ("Unrecognized steam format");
435       break;
436   }
437
438   return NULL;
439 }
440
441 static const gchar *
442 gst_av1_parse_alignment_to_string (GstAV1ParseAligment align)
443 {
444   switch (align) {
445     case GST_AV1_PARSE_ALIGN_BYTE:
446       return "byte";
447     case GST_AV1_PARSE_ALIGN_OBU:
448       return "obu";
449     case GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT:
450     case GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B:
451       return "tu";
452     case GST_AV1_PARSE_ALIGN_FRAME:
453       return "frame";
454     default:
455       GST_WARNING ("Unrecognized alignment");
456       break;
457   }
458
459   return NULL;
460 }
461
462 static GstAV1ParseAligment
463 gst_av1_parse_alignment_from_string (const gchar * align,
464     const gchar * stream_format)
465 {
466   if (!align && !stream_format)
467     return GST_AV1_PARSE_ALIGN_NONE;
468
469   if (stream_format) {
470     if (g_strcmp0 (stream_format, "annexb") == 0) {
471       if (align && g_strcmp0 (align, "tu") != 0) {
472         /* annex b stream must align to TU. */
473         return GST_AV1_PARSE_ALIGN_ERROR;
474       } else {
475         return GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B;
476       }
477     } else if (g_strcmp0 (stream_format, "obu-stream") != 0) {
478       /* unrecognized */
479       return GST_AV1_PARSE_ALIGN_NONE;
480     }
481
482     /* stream-format is obu-stream, depends on align */
483   }
484
485   if (align) {
486     if (g_strcmp0 (align, "byte") == 0) {
487       return GST_AV1_PARSE_ALIGN_BYTE;
488     } else if (g_strcmp0 (align, "obu") == 0) {
489       return GST_AV1_PARSE_ALIGN_OBU;
490     } else if (g_strcmp0 (align, "tu") == 0) {
491       return GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT;
492     } else if (g_strcmp0 (align, "frame") == 0) {
493       return GST_AV1_PARSE_ALIGN_FRAME;
494     } else {
495       /* unrecognized */
496       return GST_AV1_PARSE_ALIGN_NONE;
497     }
498   }
499
500   return GST_AV1_PARSE_ALIGN_NONE;
501 }
502
503 static gboolean
504 gst_av1_parse_caps_has_alignment (GstCaps * caps, GstAV1ParseAligment alignment)
505 {
506   guint i, j, caps_size;
507   const gchar *cmp_align_str = NULL;
508   const gchar *cmp_stream_str = NULL;
509
510   GST_DEBUG ("Try to find alignment %d in caps: %" GST_PTR_FORMAT,
511       alignment, caps);
512
513   caps_size = gst_caps_get_size (caps);
514   if (caps_size == 0)
515     return FALSE;
516
517   switch (alignment) {
518     case GST_AV1_PARSE_ALIGN_BYTE:
519       cmp_align_str = "byte";
520       cmp_stream_str = "obu-stream";
521       break;
522     case GST_AV1_PARSE_ALIGN_OBU:
523       cmp_align_str = "obu";
524       cmp_stream_str = "obu-stream";
525       break;
526     case GST_AV1_PARSE_ALIGN_FRAME:
527       cmp_align_str = "frame";
528       cmp_stream_str = "obu-stream";
529       break;
530     case GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT:
531       cmp_align_str = "tu";
532       cmp_stream_str = "obu-stream";
533       break;
534     case GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B:
535       cmp_align_str = "tu";
536       cmp_stream_str = "annexb";
537       break;
538     default:
539       return FALSE;
540   }
541
542   for (i = 0; i < caps_size; i++) {
543     GstStructure *s = gst_caps_get_structure (caps, i);
544     const GValue *alignment_value = gst_structure_get_value (s, "alignment");
545     const GValue *stream_value = gst_structure_get_value (s, "stream-format");
546
547     if (!alignment_value || !stream_value)
548       continue;
549
550     if (G_VALUE_HOLDS_STRING (alignment_value)) {
551       const gchar *align_str = g_value_get_string (alignment_value);
552
553       if (g_strcmp0 (align_str, cmp_align_str) != 0)
554         continue;
555     } else if (GST_VALUE_HOLDS_LIST (alignment_value)) {
556       guint num_values = gst_value_list_get_size (alignment_value);
557
558       for (j = 0; j < num_values; j++) {
559         const GValue *v = gst_value_list_get_value (alignment_value, j);
560         const gchar *align_str = g_value_get_string (v);
561
562         if (g_strcmp0 (align_str, cmp_align_str) == 0)
563           break;
564       }
565
566       if (j == num_values)
567         continue;
568     }
569
570     if (G_VALUE_HOLDS_STRING (stream_value)) {
571       const gchar *stream_str = g_value_get_string (stream_value);
572
573       if (g_strcmp0 (stream_str, cmp_stream_str) != 0)
574         continue;
575     } else if (GST_VALUE_HOLDS_LIST (stream_value)) {
576       guint num_values = gst_value_list_get_size (stream_value);
577
578       for (j = 0; j < num_values; j++) {
579         const GValue *v = gst_value_list_get_value (stream_value, j);
580         const gchar *stream_str = g_value_get_string (v);
581
582         if (g_strcmp0 (stream_str, cmp_stream_str) == 0)
583           break;
584       }
585
586       if (j == num_values)
587         continue;
588     }
589
590     return TRUE;
591   }
592
593   return FALSE;
594 }
595
596 static GstAV1ParseAligment
597 gst_av1_parse_alignment_from_caps (GstCaps * caps)
598 {
599   GstAV1ParseAligment align;
600
601   align = GST_AV1_PARSE_ALIGN_NONE;
602
603   GST_DEBUG ("parsing caps: %" GST_PTR_FORMAT, caps);
604
605   if (caps && gst_caps_get_size (caps) > 0) {
606     GstStructure *s = gst_caps_get_structure (caps, 0);
607     const gchar *str_align = NULL;
608     const gchar *str_stream = NULL;
609
610     str_align = gst_structure_get_string (s, "alignment");
611     str_stream = gst_structure_get_string (s, "stream-format");
612
613     align = gst_av1_parse_alignment_from_string (str_align, str_stream);
614   }
615
616   return align;
617 }
618
619 static void
620 gst_av1_parse_update_src_caps (GstAV1Parse * self, GstCaps * caps)
621 {
622   GstCaps *sink_caps, *src_caps;
623   GstCaps *final_caps = NULL;
624   GstStructure *s = NULL;
625   gint width, height;
626   gint par_n = 0, par_d = 0;
627   gint fps_n = 0, fps_d = 0;
628   const gchar *profile = NULL;
629
630   if (G_UNLIKELY (!gst_pad_has_current_caps (GST_BASE_PARSE_SRC_PAD (self))))
631     self->update_caps = TRUE;
632
633   if (!self->update_caps)
634     return;
635
636   /* if this is being called from the first _setcaps call, caps on the sinkpad
637    * aren't set yet and so they need to be passed as an argument */
638   if (caps)
639     sink_caps = gst_caps_ref (caps);
640   else
641     sink_caps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (self));
642
643   /* carry over input caps as much as possible; override with our own stuff */
644   if (!sink_caps)
645     sink_caps = gst_caps_new_empty_simple ("video/x-av1");
646   else
647     s = gst_caps_get_structure (sink_caps, 0);
648
649   final_caps = gst_caps_copy (sink_caps);
650
651   if (s && gst_structure_has_field (s, "width") &&
652       gst_structure_has_field (s, "height")) {
653     gst_structure_get_int (s, "width", &width);
654     gst_structure_get_int (s, "height", &height);
655   } else {
656     width = self->width;
657     height = self->height;
658   }
659
660   if (width > 0 && height > 0)
661     gst_caps_set_simple (final_caps, "width", G_TYPE_INT, width,
662         "height", G_TYPE_INT, height, NULL);
663
664   if (s && gst_structure_get_fraction (s, "pixel-aspect-ratio", &par_n, &par_d)) {
665     if (par_n != 0 && par_d != 0) {
666       gst_caps_set_simple (final_caps, "pixel-aspect-ratio",
667           GST_TYPE_FRACTION, par_n, par_d, NULL);
668     }
669   }
670
671   if (s && gst_structure_has_field (s, "framerate")) {
672     gst_structure_get_fraction (s, "framerate", &fps_n, &fps_d);
673   }
674
675   if (fps_n > 0 && fps_d > 0) {
676     gst_caps_set_simple (final_caps, "framerate",
677         GST_TYPE_FRACTION, fps_n, fps_d, NULL);
678     gst_base_parse_set_frame_rate (GST_BASE_PARSE (self), fps_n, fps_d, 0, 0);
679   }
680
681   /* When not RGB, the chroma format is needed. */
682   if (self->colorimetry == NULL ||
683       (g_strcmp0 (self->colorimetry, GST_VIDEO_COLORIMETRY_SRGB) != 0)) {
684     const gchar *chroma_format = NULL;
685
686     if (self->subsampling_x == 1 && self->subsampling_y == 1) {
687       if (!self->mono_chrome) {
688         chroma_format = "4:2:0";
689       } else {
690         chroma_format = "4:0:0";
691       }
692     } else if (self->subsampling_x == 1 && self->subsampling_y == 0) {
693       chroma_format = "4:2:2";
694     } else if (self->subsampling_x == 0 && self->subsampling_y == 0) {
695       chroma_format = "4:4:4";
696     }
697
698     if (chroma_format)
699       gst_caps_set_simple (final_caps,
700           "chroma-format", G_TYPE_STRING, chroma_format, NULL);
701   }
702
703   if (self->bit_depth)
704     gst_caps_set_simple (final_caps,
705         "bit-depth-luma", G_TYPE_UINT, self->bit_depth,
706         "bit-depth-chroma", G_TYPE_UINT, self->bit_depth, NULL);
707
708   if (self->colorimetry && (!s || !gst_structure_has_field (s, "colorimetry")))
709     gst_caps_set_simple (final_caps,
710         "colorimetry", G_TYPE_STRING, self->colorimetry, NULL);
711
712   g_assert (self->align > GST_AV1_PARSE_ALIGN_NONE);
713   gst_caps_set_simple (final_caps, "parsed", G_TYPE_BOOLEAN, TRUE,
714       "stream-format", G_TYPE_STRING,
715       gst_av1_parse_alignment_to_steam_format_string (self->align),
716       "alignment", G_TYPE_STRING,
717       gst_av1_parse_alignment_to_string (self->align), NULL);
718
719   profile = gst_av1_parse_profile_to_string (self->profile);
720   if (profile)
721     gst_caps_set_simple (final_caps, "profile", G_TYPE_STRING, profile, NULL);
722
723   src_caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (self));
724
725   if (!(src_caps && gst_caps_is_strictly_equal (src_caps, final_caps))) {
726     GST_DEBUG_OBJECT (self, "Update src caps %" GST_PTR_FORMAT, final_caps);
727     gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (self), final_caps);
728   }
729
730   gst_clear_caps (&src_caps);
731   gst_caps_unref (final_caps);
732   gst_caps_unref (sink_caps);
733
734   self->update_caps = FALSE;
735 }
736
737 /* check downstream caps to configure format and alignment */
738 static void
739 gst_av1_parse_negotiate (GstAV1Parse * self, GstCaps * in_caps)
740 {
741   GstCaps *caps;
742   GstAV1ParseAligment align;
743
744   caps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (self));
745   GST_DEBUG_OBJECT (self, "allowed caps: %" GST_PTR_FORMAT, caps);
746
747   /* concentrate on leading structure, since decodebin parser
748    * capsfilter always includes parser template caps */
749   if (caps) {
750     caps = gst_caps_truncate (caps);
751     GST_DEBUG_OBJECT (self, "negotiating with caps: %" GST_PTR_FORMAT, caps);
752   }
753
754   /* prefer TU as default */
755   if (gst_av1_parse_caps_has_alignment (caps,
756           GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT)) {
757     self->align = GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT;
758     goto done;
759   }
760
761   /* Both upsteam and downstream support, best */
762   if (in_caps && caps) {
763     if (gst_caps_can_intersect (in_caps, caps)) {
764       GstCaps *common_caps = NULL;
765
766       common_caps = gst_caps_intersect (in_caps, caps);
767       align = gst_av1_parse_alignment_from_caps (common_caps);
768       gst_clear_caps (&common_caps);
769
770       if (align != GST_AV1_PARSE_ALIGN_NONE
771           && align != GST_AV1_PARSE_ALIGN_ERROR) {
772         self->align = align;
773         goto done;
774       }
775     }
776   }
777
778   /* Select first one of downstream support */
779   if (caps && !gst_caps_is_empty (caps)) {
780     /* fixate to avoid ambiguity with lists when parsing */
781     caps = gst_caps_fixate (caps);
782     align = gst_av1_parse_alignment_from_caps (caps);
783
784     if (align != GST_AV1_PARSE_ALIGN_NONE && align != GST_AV1_PARSE_ALIGN_ERROR) {
785       self->align = align;
786       goto done;
787     }
788   }
789
790   /* default */
791   self->align = GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT;
792
793 done:
794   GST_INFO_OBJECT (self, "selected alignment %s",
795       gst_av1_parse_alignment_to_string (self->align));
796
797   gst_clear_caps (&caps);
798 }
799
800 static GstCaps *
801 gst_av1_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter)
802 {
803   GstCaps *peercaps, *templ;
804   GstCaps *res, *tmp, *pcopy;
805
806   templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
807   if (filter) {
808     GstCaps *fcopy = gst_caps_copy (filter);
809     /* Remove the fields we convert */
810     remove_fields (fcopy, TRUE);
811     peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), fcopy);
812     gst_caps_unref (fcopy);
813   } else {
814     peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), NULL);
815   }
816
817   pcopy = gst_caps_copy (peercaps);
818   remove_fields (pcopy, TRUE);
819
820   res = gst_caps_intersect_full (pcopy, templ, GST_CAPS_INTERSECT_FIRST);
821   gst_caps_unref (pcopy);
822   gst_caps_unref (templ);
823
824   if (filter) {
825     GstCaps *tmp = gst_caps_intersect_full (res, filter,
826         GST_CAPS_INTERSECT_FIRST);
827     gst_caps_unref (res);
828     res = tmp;
829   }
830
831   /* Try if we can put the downstream caps first */
832   pcopy = gst_caps_copy (peercaps);
833   remove_fields (pcopy, FALSE);
834   tmp = gst_caps_intersect_full (pcopy, res, GST_CAPS_INTERSECT_FIRST);
835   gst_caps_unref (pcopy);
836   if (!gst_caps_is_empty (tmp))
837     res = gst_caps_merge (tmp, res);
838   else
839     gst_caps_unref (tmp);
840
841   gst_caps_unref (peercaps);
842
843   return res;
844 }
845
846 static gboolean
847 gst_av1_parse_set_sink_caps (GstBaseParse * parse, GstCaps * caps)
848 {
849   GstAV1Parse *self = GST_AV1_PARSE (parse);
850   GstStructure *str;
851   GstAV1ParseAligment align;
852   GstCaps *in_caps = NULL;
853   const gchar *profile;
854
855   str = gst_caps_get_structure (caps, 0);
856
857   /* accept upstream info if provided */
858   gst_structure_get_int (str, "width", &self->width);
859   gst_structure_get_int (str, "height", &self->height);
860   profile = gst_structure_get_string (str, "profile");
861   if (profile)
862     self->profile = gst_av1_parse_profile_from_string (profile);
863
864   /* get upstream align from caps */
865   align = gst_av1_parse_alignment_from_caps (caps);
866   if (align == GST_AV1_PARSE_ALIGN_ERROR) {
867     GST_ERROR_OBJECT (self, "Sink caps %" GST_PTR_FORMAT " set stream-format"
868         " and alignment conflict.", caps);
869     return FALSE;
870   }
871
872   in_caps = gst_caps_copy (caps);
873   /* default */
874   if (align == GST_AV1_PARSE_ALIGN_NONE) {
875     align = GST_AV1_PARSE_ALIGN_BYTE;
876     gst_caps_set_simple (in_caps, "alignment", G_TYPE_STRING,
877         gst_av1_parse_alignment_to_string (align),
878         "stream-format", G_TYPE_STRING, "obu-stream", NULL);
879   }
880
881   /* negotiate with downstream, set output align */
882   gst_av1_parse_negotiate (self, in_caps);
883
884   self->update_caps = TRUE;
885
886   /* if all of decoder's capability related values are provided
887    * by upstream, update src caps now */
888   if (self->width > 0 && self->height > 0 && profile)
889     gst_av1_parse_update_src_caps (self, in_caps);
890
891   gst_caps_unref (in_caps);
892
893   self->in_align = align;
894
895   if (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT)
896     self->detect_annex_b = TRUE;
897
898   if (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B) {
899     gst_av1_parser_reset (self->parser, TRUE);
900   } else {
901     gst_av1_parser_reset (self->parser, FALSE);
902   }
903
904   return TRUE;
905 }
906
907 static GstFlowReturn
908 gst_av1_parse_push_data (GstAV1Parse * self, GstBaseParseFrame * frame,
909     guint32 finish_sz, gboolean frame_finished)
910 {
911   gsize sz;
912   GstBuffer *buf, *header_buf;
913   GstBuffer *buffer = frame->buffer;
914   GstFlowReturn ret = GST_FLOW_OK;
915
916   /* Need to generate the final TU annex-b format */
917   if (self->align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B) {
918     guint8 size_data[GST_AV1_MAX_LEB_128_SIZE];
919     guint size_len = 0;
920     guint len;
921
922     /* When push a TU, it must also be a frame end. */
923     g_assert (frame_finished);
924
925     /* Still some left in the frame cache */
926     len = gst_adapter_available (self->frame_cache);
927     if (len) {
928       buf = gst_adapter_take_buffer (self->frame_cache, len);
929
930       /* frame_unit_size */
931       _write_leb128 (size_data, &size_len, len);
932       header_buf = gst_buffer_new_memdup (size_data, size_len);
933       GST_BUFFER_PTS (header_buf) = GST_BUFFER_PTS (buf);
934       GST_BUFFER_DTS (header_buf) = GST_BUFFER_DTS (buf);
935       GST_BUFFER_DURATION (header_buf) = GST_BUFFER_DURATION (buf);
936
937       gst_adapter_push (self->cache_out, header_buf);
938       gst_adapter_push (self->cache_out, buf);
939     }
940
941     len = gst_adapter_available (self->cache_out);
942     if (len) {
943       buf = gst_adapter_take_buffer (self->cache_out, len);
944
945       /* temporal_unit_size */
946       _write_leb128 (size_data, &size_len, len);
947       header_buf = gst_buffer_new_memdup (size_data, size_len);
948       GST_BUFFER_PTS (header_buf) = GST_BUFFER_PTS (buf);
949       GST_BUFFER_DTS (header_buf) = GST_BUFFER_DTS (buf);
950       GST_BUFFER_DURATION (header_buf) = GST_BUFFER_DURATION (buf);
951
952       gst_adapter_push (self->cache_out, header_buf);
953       gst_adapter_push (self->cache_out, buf);
954     }
955   }
956
957   sz = gst_adapter_available (self->cache_out);
958   if (sz) {
959     buf = gst_adapter_take_buffer (self->cache_out, sz);
960     gst_buffer_copy_into (buf, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
961     if (self->discont) {
962       GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
963       self->discont = FALSE;
964     } else {
965       GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
966     }
967
968     if (self->header) {
969       GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
970       self->header = FALSE;
971     } else {
972       GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_HEADER);
973     }
974
975     if (self->keyframe) {
976       GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
977       self->keyframe = FALSE;
978     } else {
979       GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
980     }
981
982     if (frame_finished) {
983       GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_MARKER);
984     } else {
985       GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_MARKER);
986     }
987
988     if (self->align == GST_AV1_PARSE_ALIGN_FRAME) {
989       if (!self->show_frame) {
990         GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DECODE_ONLY);
991       } else {
992         GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DECODE_ONLY);
993       }
994     } else {
995       GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DECODE_ONLY);
996     }
997
998     gst_buffer_replace (&frame->out_buffer, buf);
999     gst_buffer_unref (buf);
1000
1001     gst_av1_parse_update_src_caps (self, NULL);
1002     GST_LOG_OBJECT (self, "comsumed %d, output one buffer with size %"
1003         G_GSSIZE_FORMAT, finish_sz, sz);
1004     ret = gst_base_parse_finish_frame (GST_BASE_PARSE (self), frame, finish_sz);
1005   }
1006
1007   return ret;
1008 }
1009
1010 static void
1011 gst_av1_parse_convert_to_annexb (GstAV1Parse * self, GstBuffer * buffer,
1012     GstAV1OBU * obu, gboolean frame_complete)
1013 {
1014   guint8 size_data[GST_AV1_MAX_LEB_128_SIZE];
1015   guint size_len = 0;
1016   GstBitWriter bs;
1017   GstBuffer *buf, *buf2;
1018   guint8 *data;
1019   guint len, len2, offset;
1020
1021   /* obu_length */
1022   _write_leb128 (size_data, &size_len,
1023       obu->obu_size + 1 + obu->header.obu_extention_flag);
1024
1025   gst_bit_writer_init_with_size (&bs, 128, FALSE);
1026   /* obu_forbidden_bit */
1027   gst_bit_writer_put_bits_uint8 (&bs, 0, 1);
1028   /* obu_type */
1029   gst_bit_writer_put_bits_uint8 (&bs, obu->obu_type, 4);
1030   /* obu_extension_flag */
1031   gst_bit_writer_put_bits_uint8 (&bs, obu->header.obu_extention_flag, 1);
1032   /* obu_has_size_field */
1033   gst_bit_writer_put_bits_uint8 (&bs, 0, 1);
1034   /* obu_reserved_1bit */
1035   gst_bit_writer_put_bits_uint8 (&bs, 0, 1);
1036   if (obu->header.obu_extention_flag) {
1037     /* temporal_id */
1038     gst_bit_writer_put_bits_uint8 (&bs, obu->header.obu_temporal_id, 3);
1039     /* spatial_id */
1040     gst_bit_writer_put_bits_uint8 (&bs, obu->header.obu_spatial_id, 2);
1041     /* extension_header_reserved_3bits */
1042     gst_bit_writer_put_bits_uint8 (&bs, 0, 3);
1043   }
1044   g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
1045
1046   len = size_len;
1047   len += GST_BIT_WRITER_BIT_SIZE (&bs) / 8;
1048   len += obu->obu_size;
1049
1050   data = g_malloc (len);
1051   offset = 0;
1052
1053   memcpy (data + offset, size_data, size_len);
1054   offset += size_len;
1055
1056   memcpy (data + offset, GST_BIT_WRITER_DATA (&bs),
1057       GST_BIT_WRITER_BIT_SIZE (&bs) / 8);
1058   offset += GST_BIT_WRITER_BIT_SIZE (&bs) / 8;
1059
1060   memcpy (data + offset, obu->data, obu->obu_size);
1061
1062   /* The buf of this OBU */
1063   buf = gst_buffer_new_wrapped (data, len);
1064   GST_BUFFER_PTS (buf) = GST_BUFFER_PTS (buffer);
1065   GST_BUFFER_DTS (buf) = GST_BUFFER_DTS (buffer);
1066   GST_BUFFER_DURATION (buf) = GST_BUFFER_DURATION (buffer);
1067
1068   gst_adapter_push (self->frame_cache, buf);
1069
1070   if (frame_complete) {
1071     len2 = gst_adapter_available (self->frame_cache);
1072     buf2 = gst_adapter_take_buffer (self->frame_cache, len2);
1073
1074     /* frame_unit_size */
1075     _write_leb128 (size_data, &size_len, len2);
1076     buf = gst_buffer_new_memdup (size_data, size_len);
1077     GST_BUFFER_PTS (buf) = GST_BUFFER_PTS (buf2);
1078     GST_BUFFER_DTS (buf) = GST_BUFFER_DTS (buf2);
1079     GST_BUFFER_DURATION (buf) = GST_BUFFER_DURATION (buf2);
1080
1081     gst_adapter_push (self->cache_out, buf);
1082     gst_adapter_push (self->cache_out, buf2);
1083   }
1084
1085   gst_bit_writer_reset (&bs);
1086 }
1087
1088 static void
1089 gst_av1_parse_convert_from_annexb (GstAV1Parse * self, GstBuffer * buffer,
1090     GstAV1OBU * obu)
1091 {
1092   guint8 size_data[GST_AV1_MAX_LEB_128_SIZE];
1093   guint size_len = 0;
1094   GstBuffer *buf;
1095   guint len, offset;
1096   guint8 *data;
1097   GstBitWriter bs;
1098
1099   _write_leb128 (size_data, &size_len, obu->obu_size);
1100
1101   /* obu_header */
1102   len = 1;
1103   if (obu->header.obu_extention_flag)
1104     len += 1;
1105   len += size_len;
1106   len += obu->obu_size;
1107
1108   gst_bit_writer_init_with_size (&bs, 128, FALSE);
1109   /* obu_forbidden_bit */
1110   gst_bit_writer_put_bits_uint8 (&bs, 0, 1);
1111   /* obu_type */
1112   gst_bit_writer_put_bits_uint8 (&bs, obu->obu_type, 4);
1113   /* obu_extension_flag */
1114   gst_bit_writer_put_bits_uint8 (&bs, obu->header.obu_extention_flag, 1);
1115   /* obu_has_size_field */
1116   gst_bit_writer_put_bits_uint8 (&bs, 1, 1);
1117   /* obu_reserved_1bit */
1118   gst_bit_writer_put_bits_uint8 (&bs, 0, 1);
1119   if (obu->header.obu_extention_flag) {
1120     /* temporal_id */
1121     gst_bit_writer_put_bits_uint8 (&bs, obu->header.obu_temporal_id, 3);
1122     /* spatial_id */
1123     gst_bit_writer_put_bits_uint8 (&bs, obu->header.obu_spatial_id, 2);
1124     /* extension_header_reserved_3bits */
1125     gst_bit_writer_put_bits_uint8 (&bs, 0, 3);
1126   }
1127   g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
1128
1129   data = g_malloc (len);
1130   offset = 0;
1131   memcpy (data + offset, GST_BIT_WRITER_DATA (&bs),
1132       GST_BIT_WRITER_BIT_SIZE (&bs) / 8);
1133   offset += GST_BIT_WRITER_BIT_SIZE (&bs) / 8;
1134
1135   memcpy (data + offset, size_data, size_len);
1136   offset += size_len;
1137
1138   memcpy (data + offset, obu->data, obu->obu_size);
1139
1140   buf = gst_buffer_new_wrapped (data, len);
1141   GST_BUFFER_PTS (buf) = GST_BUFFER_PTS (buffer);
1142   GST_BUFFER_DTS (buf) = GST_BUFFER_DTS (buffer);
1143   GST_BUFFER_DURATION (buf) = GST_BUFFER_DURATION (buffer);
1144
1145   gst_adapter_push (self->cache_out, buf);
1146
1147   gst_bit_writer_reset (&bs);
1148 }
1149
1150 static void
1151 gst_av1_parse_cache_one_obu (GstAV1Parse * self, GstBuffer * buffer,
1152     GstAV1OBU * obu, guint8 * data, guint32 size, gboolean frame_complete)
1153 {
1154   gboolean need_convert = FALSE;
1155   GstBuffer *buf;
1156
1157   if (self->in_align != self->align
1158       && (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B
1159           || self->align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B))
1160     need_convert = TRUE;
1161
1162   if (need_convert) {
1163     if (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B) {
1164       gst_av1_parse_convert_from_annexb (self, buffer, obu);
1165     } else {
1166       gst_av1_parse_convert_to_annexb (self, buffer, obu, frame_complete);
1167     }
1168   } else if (self->align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B) {
1169     g_assert (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B);
1170     gst_av1_parse_convert_to_annexb (self, buffer, obu, frame_complete);
1171   } else {
1172     buf = gst_buffer_new_memdup (data, size);
1173     GST_BUFFER_PTS (buf) = GST_BUFFER_PTS (buffer);
1174     GST_BUFFER_DTS (buf) = GST_BUFFER_DTS (buffer);
1175     GST_BUFFER_DURATION (buf) = GST_BUFFER_DURATION (buffer);
1176
1177     gst_adapter_push (self->cache_out, buf);
1178   }
1179 }
1180
1181 static GstAV1ParserResult
1182 gst_av1_parse_handle_sequence_obu (GstAV1Parse * self, GstAV1OBU * obu)
1183 {
1184   GstAV1SequenceHeaderOBU seq_header;
1185   GstAV1ParserResult res;
1186   guint i;
1187   guint val;
1188
1189   res = gst_av1_parser_parse_sequence_header_obu (self->parser,
1190       obu, &seq_header);
1191   if (res != GST_AV1_PARSER_OK)
1192     return res;
1193
1194   if (self->width != seq_header.max_frame_width_minus_1 + 1) {
1195     self->width = seq_header.max_frame_width_minus_1 + 1;
1196     self->update_caps = TRUE;
1197   }
1198   if (self->height != seq_header.max_frame_height_minus_1 + 1) {
1199     self->height = seq_header.max_frame_height_minus_1 + 1;
1200     self->update_caps = TRUE;
1201   }
1202
1203   if (seq_header.color_config.color_description_present_flag) {
1204     GstVideoColorimetry cinfo;
1205     gchar *colorimetry = NULL;
1206
1207     if (seq_header.color_config.color_range)
1208       cinfo.range = GST_VIDEO_COLOR_RANGE_0_255;
1209     else
1210       cinfo.range = GST_VIDEO_COLOR_RANGE_16_235;
1211
1212     cinfo.matrix = gst_video_color_matrix_from_iso
1213         (seq_header.color_config.matrix_coefficients);
1214     cinfo.transfer = gst_video_transfer_function_from_iso
1215         (seq_header.color_config.transfer_characteristics);
1216     cinfo.primaries = gst_video_color_primaries_from_iso
1217         (seq_header.color_config.color_primaries);
1218
1219     colorimetry = gst_video_colorimetry_to_string (&cinfo);
1220
1221     if (g_strcmp0 (colorimetry, self->colorimetry) != 0) {
1222       g_free (self->colorimetry);
1223       self->colorimetry = colorimetry;
1224       colorimetry = NULL;
1225       self->update_caps = TRUE;
1226     }
1227
1228     g_clear_pointer (&colorimetry, g_free);
1229   }
1230
1231   if (self->subsampling_x != seq_header.color_config.subsampling_x) {
1232     self->subsampling_x = seq_header.color_config.subsampling_x;
1233     self->update_caps = TRUE;
1234   }
1235
1236   if (self->subsampling_y != seq_header.color_config.subsampling_y) {
1237     self->subsampling_y = seq_header.color_config.subsampling_y;
1238     self->update_caps = TRUE;
1239   }
1240
1241   if (self->mono_chrome != seq_header.color_config.mono_chrome) {
1242     self->mono_chrome = seq_header.color_config.mono_chrome;
1243     self->update_caps = TRUE;
1244   }
1245
1246   if (self->bit_depth != seq_header.bit_depth) {
1247     self->bit_depth = seq_header.bit_depth;
1248     self->update_caps = TRUE;
1249   }
1250
1251   if (self->profile != seq_header.seq_profile) {
1252     self->profile = seq_header.seq_profile;
1253     self->update_caps = TRUE;
1254   }
1255
1256   val = (self->parser->state.operating_point_idc >> 8) & 0x0f;
1257   for (i = 0; i < (1 << GST_AV1_MAX_SPATIAL_LAYERS); i++) {
1258     if (val & (1 << i))
1259       self->highest_spatial_id = i;
1260   }
1261
1262   return GST_AV1_PARSER_OK;
1263 }
1264
1265 /* Check whether the frame start a new TU.
1266    The obu here should be a shown frame/frame header. */
1267 static gboolean
1268 gst_av1_parse_frame_start_new_temporal_unit (GstAV1Parse * self,
1269     GstAV1OBU * obu)
1270 {
1271   gboolean ret = FALSE;
1272
1273   g_assert (obu->obu_type == GST_AV1_OBU_FRAME_HEADER
1274       || obu->obu_type == GST_AV1_OBU_FRAME);
1275
1276   /* 7.5.Ordering of OBUs: The value of temporal_id must be the same in all
1277      OBU extension headers that are contained in the same temporal unit. */
1278   if (self->last_shown_frame_temporal_id >= 0 &&
1279       obu->header.obu_temporal_id != self->last_shown_frame_temporal_id) {
1280     ret = TRUE;
1281     goto new_tu;
1282   }
1283
1284   /* If scalability is not being used, only one shown frame for each
1285      temporal unit. So the new frame belongs to a new temporal unit. */
1286   if (!self->within_one_frame && self->last_shown_frame_temporal_id >= 0 &&
1287       self->parser->state.operating_point_idc == 0) {
1288     ret = TRUE;
1289     goto new_tu;
1290   }
1291
1292   /* The new frame has the same layer IDs with the last shown frame,
1293      it should belong to a new temporal unit. */
1294   if (!self->within_one_frame &&
1295       obu->header.obu_temporal_id == self->last_shown_frame_temporal_id &&
1296       obu->header.obu_spatial_id == self->last_shown_frame_spatial_id) {
1297     ret = TRUE;
1298     goto new_tu;
1299   }
1300
1301 new_tu:
1302   if (ret) {
1303     if (self->within_one_frame)
1304       GST_WARNING_OBJECT (self,
1305           "Start a new temporal unit with incompleted frame.");
1306
1307     gst_av1_parse_reset_obu_data_state (self);
1308   }
1309
1310   return ret;
1311 }
1312
1313 /* frame_complete will be set true if it is the frame edge. */
1314 static GstAV1ParserResult
1315 gst_av1_parse_handle_one_obu (GstAV1Parse * self, GstAV1OBU * obu,
1316     gboolean * frame_complete, gboolean * check_new_tu)
1317 {
1318   GstAV1ParserResult res = GST_AV1_PARSER_OK;
1319   GstAV1MetadataOBU metadata;
1320   GstAV1FrameHeaderOBU frame_header;
1321   GstAV1TileListOBU tile_list;
1322   GstAV1TileGroupOBU tile_group;
1323   GstAV1FrameOBU frame;
1324
1325   *frame_complete = FALSE;
1326
1327   switch (obu->obu_type) {
1328     case GST_AV1_OBU_TEMPORAL_DELIMITER:
1329       res = gst_av1_parser_parse_temporal_delimiter_obu (self->parser, obu);
1330       break;
1331     case GST_AV1_OBU_SEQUENCE_HEADER:
1332       res = gst_av1_parse_handle_sequence_obu (self, obu);
1333       break;
1334     case GST_AV1_OBU_REDUNDANT_FRAME_HEADER:
1335       res = gst_av1_parser_parse_frame_header_obu (self->parser, obu,
1336           &frame_header);
1337       break;
1338     case GST_AV1_OBU_FRAME_HEADER:
1339       res = gst_av1_parser_parse_frame_header_obu (self->parser, obu,
1340           &frame_header);
1341       break;
1342     case GST_AV1_OBU_FRAME:
1343       res = gst_av1_parser_parse_frame_obu (self->parser, obu, &frame);
1344       break;
1345     case GST_AV1_OBU_METADATA:
1346       res = gst_av1_parser_parse_metadata_obu (self->parser, obu, &metadata);
1347       break;
1348     case GST_AV1_OBU_TILE_GROUP:
1349       res =
1350           gst_av1_parser_parse_tile_group_obu (self->parser, obu, &tile_group);
1351       break;
1352     case GST_AV1_OBU_TILE_LIST:
1353       res = gst_av1_parser_parse_tile_list_obu (self->parser, obu, &tile_list);
1354       break;
1355     case GST_AV1_OBU_PADDING:
1356       break;
1357     default:
1358       GST_WARNING_OBJECT (self, "an unrecognized obu type %d", obu->obu_type);
1359       res = GST_AV1_PARSER_BITSTREAM_ERROR;
1360       break;
1361   }
1362
1363   GST_LOG_OBJECT (self, "parsing the obu %s, result is %d",
1364       _obu_name (obu->obu_type), res);
1365   if (res != GST_AV1_PARSER_OK)
1366     goto out;
1367
1368   /* 7.5:
1369      All OBU extension headers that are contained in the same temporal
1370      unit and have the same spatial_id value must have the same temporal_id
1371      value.
1372      And
1373      OBUs with spatial level IDs (spatial_id) greater than 0 must
1374      appear within a temporal unit in increasing order of the spatial
1375      level ID values. */
1376   if (obu->header.obu_spatial_id > self->highest_spatial_id) {
1377     GST_WARNING_OBJECT (self,
1378         "spatial_id %d is bigger than highest_spatial_id %d",
1379         obu->header.obu_spatial_id, self->highest_spatial_id);
1380     res = GST_AV1_PARSER_BITSTREAM_ERROR;
1381     goto out;
1382   }
1383
1384   /* If to check a new temporal starts, return early.
1385      In 7.5.Ordering of OBUs: Sequence header OBUs may appear in any order
1386      within a coded video sequence. So it is allowed to repeat the sequence
1387      header within one temporal unit, and sequence header does not definitely
1388      start a TU. We only check TD here. */
1389   if (obu->obu_type == GST_AV1_OBU_TEMPORAL_DELIMITER) {
1390     gst_av1_parse_reset_obu_data_state (self);
1391
1392     if (check_new_tu) {
1393       *check_new_tu = TRUE;
1394       res = GST_AV1_PARSER_OK;
1395       goto out;
1396     }
1397   }
1398
1399   if (obu->obu_type == GST_AV1_OBU_SEQUENCE_HEADER)
1400     self->header = TRUE;
1401
1402   if (obu->obu_type == GST_AV1_OBU_FRAME_HEADER
1403       || obu->obu_type == GST_AV1_OBU_FRAME
1404       || obu->obu_type == GST_AV1_OBU_REDUNDANT_FRAME_HEADER) {
1405     GstAV1FrameHeaderOBU *fh = &frame_header;
1406
1407     if (obu->obu_type == GST_AV1_OBU_FRAME)
1408       fh = &frame.frame_header;
1409
1410     self->show_frame = fh->show_frame || fh->show_existing_frame;
1411     if (self->show_frame) {
1412       /* Check whether a new temporal starts, and return early. */
1413       if (check_new_tu && obu->obu_type != GST_AV1_OBU_REDUNDANT_FRAME_HEADER
1414           && gst_av1_parse_frame_start_new_temporal_unit (self, obu)) {
1415         *check_new_tu = TRUE;
1416         res = GST_AV1_PARSER_OK;
1417         goto out;
1418       }
1419
1420       self->last_shown_frame_temporal_id = obu->header.obu_temporal_id;
1421       self->last_shown_frame_spatial_id = obu->header.obu_spatial_id;
1422     }
1423
1424     self->within_one_frame = TRUE;
1425
1426     /* if a show_existing_frame case, only update key frame.
1427        otherwise, update all type of frame.  */
1428     if (!fh->show_existing_frame || fh->frame_type == GST_AV1_KEY_FRAME)
1429       res = gst_av1_parser_reference_frame_update (self->parser, fh);
1430
1431     if (res != GST_AV1_PARSER_OK)
1432       GST_WARNING_OBJECT (self, "update frame get result %d", res);
1433
1434     if (fh->show_existing_frame) {
1435       *frame_complete = TRUE;
1436       self->within_one_frame = FALSE;
1437     }
1438
1439     if (fh->frame_type == GST_AV1_KEY_FRAME)
1440       self->keyframe = TRUE;
1441   }
1442
1443   if (obu->obu_type == GST_AV1_OBU_TILE_GROUP
1444       || obu->obu_type == GST_AV1_OBU_FRAME) {
1445     GstAV1TileGroupOBU *tg = &tile_group;
1446
1447     self->within_one_frame = TRUE;
1448
1449     if (obu->obu_type == GST_AV1_OBU_FRAME)
1450       tg = &frame.tile_group;
1451
1452     if (tg->tg_end == tg->num_tiles - 1) {
1453       *frame_complete = TRUE;
1454       self->within_one_frame = FALSE;
1455     }
1456   }
1457
1458 out:
1459   if (res != GST_AV1_PARSER_OK) {
1460     /* Some verbose OBU can be skip */
1461     if (obu->obu_type == GST_AV1_OBU_REDUNDANT_FRAME_HEADER) {
1462       GST_WARNING_OBJECT (self, "Ignore a verbose %s OBU parsing error",
1463           _obu_name (obu->obu_type));
1464       gst_av1_parse_reset_obu_data_state (self);
1465       res = GST_AV1_PARSER_OK;
1466     }
1467   }
1468
1469   return res;
1470 }
1471
1472 static GstFlowReturn
1473 gst_av1_parse_handle_obu_to_obu (GstBaseParse * parse,
1474     GstBaseParseFrame * frame, gint * skipsize)
1475 {
1476   GstAV1Parse *self = GST_AV1_PARSE (parse);
1477   GstMapInfo map_info;
1478   GstAV1OBU obu;
1479   GstFlowReturn ret = GST_FLOW_OK;
1480   GstAV1ParserResult res;
1481   GstBuffer *buffer = gst_buffer_ref (frame->buffer);
1482   guint32 consumed;
1483   gboolean frame_complete;
1484
1485   if (!gst_buffer_map (buffer, &map_info, GST_MAP_READ)) {
1486     *skipsize = 0;
1487     GST_ERROR_OBJECT (parse, "Couldn't map incoming buffer");
1488     return GST_FLOW_ERROR;
1489   }
1490
1491   consumed = 0;
1492   frame_complete = FALSE;
1493   res = gst_av1_parser_identify_one_obu (self->parser, map_info.data,
1494       map_info.size, &obu, &consumed);
1495   if (res == GST_AV1_PARSER_OK)
1496     res = gst_av1_parse_handle_one_obu (self, &obu, &frame_complete, NULL);
1497
1498   g_assert (consumed <= map_info.size);
1499
1500   if (res == GST_AV1_PARSER_BITSTREAM_ERROR ||
1501       res == GST_AV1_PARSER_MISSING_OBU_REFERENCE) {
1502     if (consumed) {
1503       *skipsize = consumed;
1504     } else {
1505       *skipsize = map_info.size;
1506     }
1507     GST_WARNING_OBJECT (parse, "Parse obu error, discard %d.", *skipsize);
1508     gst_av1_parse_reset_obu_data_state (self);
1509     ret = GST_FLOW_OK;
1510     goto out;
1511   } else if (res == GST_AV1_PARSER_NO_MORE_DATA) {
1512     *skipsize = 0;
1513
1514     if (self->in_align == GST_AV1_PARSE_ALIGN_OBU) {
1515       /* The buffer is already aligned to OBU, should not happen. */
1516       if (consumed) {
1517         *skipsize = consumed;
1518       } else {
1519         *skipsize = map_info.size;
1520       }
1521       GST_WARNING_OBJECT (parse, "Parse obu need more data, discard %d.",
1522           *skipsize);
1523       gst_av1_parse_reset_obu_data_state (self);
1524     }
1525     ret = GST_FLOW_OK;
1526     goto out;
1527   } else if (res == GST_AV1_PARSER_DROP) {
1528     GST_DEBUG_OBJECT (parse, "Drop %d data", consumed);
1529     *skipsize = consumed;
1530     gst_av1_parse_reset_obu_data_state (self);
1531     ret = GST_FLOW_OK;
1532     goto out;
1533   } else if (res != GST_AV1_PARSER_OK) {
1534     GST_ERROR_OBJECT (parse, "Parse obu get unexpect error %d", res);
1535     *skipsize = 0;
1536     ret = GST_FLOW_ERROR;
1537     goto out;
1538   }
1539
1540   g_assert (consumed);
1541
1542   gst_av1_parse_update_src_caps (self, NULL);
1543   if (self->discont) {
1544     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
1545     self->discont = FALSE;
1546   }
1547   if (self->header) {
1548     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_HEADER);
1549     self->header = FALSE;
1550   }
1551   /* happen to be a frame boundary */
1552   if (frame_complete)
1553     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_MARKER);
1554
1555   GST_LOG_OBJECT (self, "Output one buffer with size %d", consumed);
1556   ret = gst_base_parse_finish_frame (parse, frame, consumed);
1557   *skipsize = 0;
1558
1559 out:
1560   gst_buffer_unmap (buffer, &map_info);
1561   gst_buffer_unref (buffer);
1562   return ret;
1563 }
1564
1565 static void
1566 gst_av1_parse_create_subframe (GstBaseParseFrame * frame,
1567     GstBaseParseFrame * subframe, GstBuffer * buffer)
1568 {
1569   gst_base_parse_frame_init (subframe);
1570   subframe->flags |= frame->flags;
1571   subframe->offset = frame->offset;
1572   subframe->overhead = frame->overhead;
1573   /* Just ref the input buffer. The base parse will check that
1574      pointer, and it will be replaced by its out_buffer later. */
1575   subframe->buffer = gst_buffer_ref (buffer);
1576 }
1577
1578 static GstFlowReturn
1579 gst_av1_parse_handle_to_small_and_equal_align (GstBaseParse * parse,
1580     GstBaseParseFrame * frame, gint * skipsize)
1581 {
1582   GstAV1Parse *self = GST_AV1_PARSE (parse);
1583   GstMapInfo map_info;
1584   GstAV1OBU obu;
1585   GstFlowReturn ret = GST_FLOW_OK;
1586   GstAV1ParserResult res = GST_AV1_PARSER_INVALID_OPERATION;
1587   GstBuffer *buffer = gst_buffer_ref (frame->buffer);
1588   guint32 offset, consumed_before_push, consumed;
1589   gboolean frame_complete;
1590   GstBaseParseFrame subframe;
1591
1592   if (!gst_buffer_map (buffer, &map_info, GST_MAP_READ)) {
1593     GST_ERROR_OBJECT (parse, "Couldn't map incoming buffer");
1594     return GST_FLOW_ERROR;
1595   }
1596
1597   consumed_before_push = 0;
1598   offset = 0;
1599   frame_complete = FALSE;
1600 again:
1601   while (offset < map_info.size) {
1602     res = gst_av1_parser_identify_one_obu (self->parser,
1603         map_info.data + offset, map_info.size - offset, &obu, &consumed);
1604     if (res == GST_AV1_PARSER_OK)
1605       res = gst_av1_parse_handle_one_obu (self, &obu, &frame_complete, NULL);
1606     if (res != GST_AV1_PARSER_OK)
1607       break;
1608
1609     if (obu.obu_type == GST_AV1_OBU_TEMPORAL_DELIMITER
1610         && consumed_before_push > 0) {
1611       GST_DEBUG_OBJECT (self, "Encounter TD inside one %s aligned"
1612           " buffer, should not happen normally.",
1613           gst_av1_parse_alignment_to_string (self->in_align));
1614
1615       if (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B)
1616         gst_av1_parser_reset_annex_b (self->parser);
1617
1618       /* Not include this TD obu, it should belong to the next TU or frame,
1619          we push all the data we already got. */
1620       gst_av1_parse_create_subframe (frame, &subframe, buffer);
1621       ret = gst_av1_parse_push_data (self, &subframe,
1622           consumed_before_push, TRUE);
1623       if (ret != GST_FLOW_OK)
1624         goto out;
1625
1626       /* Begin to find the next. */
1627       frame_complete = FALSE;
1628       consumed_before_push = 0;
1629       continue;
1630     }
1631
1632     gst_av1_parse_cache_one_obu (self, buffer, &obu,
1633         map_info.data + offset, consumed, frame_complete);
1634
1635     offset += consumed;
1636     consumed_before_push += consumed;
1637
1638     if ((self->align == GST_AV1_PARSE_ALIGN_OBU) ||
1639         (self->align == GST_AV1_PARSE_ALIGN_FRAME && frame_complete)) {
1640       gst_av1_parse_create_subframe (frame, &subframe, buffer);
1641       ret = gst_av1_parse_push_data (self, &subframe,
1642           consumed_before_push, frame_complete);
1643       if (ret != GST_FLOW_OK)
1644         goto out;
1645
1646       /* Begin to find the next. */
1647       frame_complete = FALSE;
1648       consumed_before_push = 0;
1649       continue;
1650     }
1651   }
1652
1653   if (res == GST_AV1_PARSER_BITSTREAM_ERROR ||
1654       res == GST_AV1_PARSER_MISSING_OBU_REFERENCE) {
1655     /* Discard the whole frame */
1656     *skipsize = map_info.size;
1657     GST_WARNING_OBJECT (parse, "Parse obu error, discard %d", *skipsize);
1658     if (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B)
1659       gst_av1_parser_reset_annex_b (self->parser);
1660     gst_av1_parse_reset_obu_data_state (self);
1661     ret = GST_FLOW_OK;
1662     goto out;
1663   } else if (res == GST_AV1_PARSER_NO_MORE_DATA) {
1664     /* Discard the whole buffer */
1665     *skipsize = map_info.size;
1666     GST_WARNING_OBJECT (parse, "Parse obu need more data, discard %d.",
1667         *skipsize);
1668     if (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B)
1669       gst_av1_parser_reset_annex_b (self->parser);
1670
1671     gst_av1_parse_reset_obu_data_state (self);
1672     ret = GST_FLOW_OK;
1673     goto out;
1674   } else if (res == GST_AV1_PARSER_DROP) {
1675     GST_DEBUG_OBJECT (parse, "Drop %d data", consumed);
1676     offset += consumed;
1677     gst_av1_parse_reset_obu_data_state (self);
1678     res = GST_AV1_PARSER_OK;
1679     goto again;
1680   } else if (res != GST_AV1_PARSER_OK) {
1681     GST_ERROR_OBJECT (parse, "Parse obu get unexpect error %d", res);
1682     *skipsize = 0;
1683     ret = GST_FLOW_ERROR;
1684     goto out;
1685   }
1686
1687   /* If the total buffer exhausted but frame is not complete, we just
1688      push the left data and consider it as a frame. */
1689   if (consumed_before_push > 0 && !frame_complete
1690       && self->align == GST_AV1_PARSE_ALIGN_FRAME) {
1691     g_assert (offset >= map_info.size);
1692     /* Warning and still consider the frame is complete */
1693     GST_WARNING_OBJECT (self, "Exhaust the buffer but still incomplete frame,"
1694         " should not happend in %s alignment",
1695         gst_av1_parse_alignment_to_string (self->in_align));
1696   }
1697
1698   ret = gst_av1_parse_push_data (self, frame, consumed_before_push, TRUE);
1699
1700 out:
1701   gst_buffer_unmap (buffer, &map_info);
1702   gst_buffer_unref (buffer);
1703   return ret;
1704 }
1705
1706 static GstFlowReturn
1707 gst_av1_parse_handle_to_big_align (GstBaseParse * parse,
1708     GstBaseParseFrame * frame, gint * skipsize)
1709 {
1710   GstAV1Parse *self = GST_AV1_PARSE (parse);
1711   GstMapInfo map_info;
1712   GstAV1OBU obu;
1713   GstFlowReturn ret = GST_FLOW_OK;
1714   GstAV1ParserResult res = GST_AV1_PARSER_OK;
1715   GstBuffer *buffer = gst_buffer_ref (frame->buffer);
1716   guint32 consumed;
1717   gboolean frame_complete;
1718   gboolean check_new_tu;
1719   gboolean complete;
1720
1721   g_assert (self->in_align <= GST_AV1_PARSE_ALIGN_FRAME);
1722
1723   if (!gst_buffer_map (buffer, &map_info, GST_MAP_READ)) {
1724     *skipsize = 0;
1725     GST_ERROR_OBJECT (parse, "Couldn't map incoming buffer");
1726     return GST_FLOW_ERROR;
1727   }
1728
1729   complete = FALSE;
1730 again:
1731   while (self->last_parsed_offset < map_info.size) {
1732     res = gst_av1_parser_identify_one_obu (self->parser,
1733         map_info.data + self->last_parsed_offset,
1734         map_info.size - self->last_parsed_offset, &obu, &consumed);
1735     if (res != GST_AV1_PARSER_OK)
1736       break;
1737
1738     check_new_tu = FALSE;
1739     if (self->align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT
1740         || self->align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B) {
1741       res = gst_av1_parse_handle_one_obu (self, &obu, &frame_complete,
1742           &check_new_tu);
1743     } else {
1744       res = gst_av1_parse_handle_one_obu (self, &obu, &frame_complete, NULL);
1745     }
1746     if (res != GST_AV1_PARSER_OK)
1747       break;
1748
1749     if (check_new_tu && (gst_adapter_available (self->cache_out) ||
1750             gst_adapter_available (self->frame_cache))) {
1751       complete = TRUE;
1752       break;
1753     }
1754
1755     if (self->align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT ||
1756         self->align == GST_AV1_PARSE_ALIGN_FRAME) {
1757       GstBuffer *buf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL,
1758           self->last_parsed_offset, consumed);
1759       gst_adapter_push (self->cache_out, buf);
1760     } else if (self->align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B) {
1761       gst_av1_parse_convert_to_annexb (self, buffer, &obu, frame_complete);
1762     } else {
1763       g_assert_not_reached ();
1764     }
1765     self->last_parsed_offset += consumed;
1766
1767     if (self->align == GST_AV1_PARSE_ALIGN_FRAME && frame_complete)
1768       complete = TRUE;
1769
1770     if (complete)
1771       break;
1772   }
1773
1774   /* Finish a complete frame anyway */
1775   if (complete || GST_BASE_PARSE_DRAINING (parse)) {
1776     *skipsize = 0;
1777
1778     /* push the left anyway if no error */
1779     if (res == GST_AV1_PARSER_OK)
1780       ret = gst_av1_parse_push_data (self, frame,
1781           self->last_parsed_offset, TRUE);
1782
1783     self->last_parsed_offset = 0;
1784
1785     goto out;
1786   }
1787
1788   if (res == GST_AV1_PARSER_BITSTREAM_ERROR ||
1789       res == GST_AV1_PARSER_MISSING_OBU_REFERENCE) {
1790     *skipsize = map_info.size;
1791     GST_WARNING_OBJECT (parse, "Parse obu error, discard whole buffer %d.",
1792         *skipsize);
1793     /* The adapter will be cleared in next loop because of
1794        GST_BASE_PARSE_FRAME_FLAG_NEW_FRAME flag */
1795     gst_av1_parse_reset_obu_data_state (self);
1796     ret = GST_FLOW_OK;
1797   } else if (res == GST_AV1_PARSER_NO_MORE_DATA) {
1798     *skipsize = 0;
1799
1800     if (self->in_align >= GST_AV1_PARSE_ALIGN_OBU) {
1801       /* The buffer is already aligned to OBU, should not happen.
1802          The adapter will be cleared in next loop because of
1803          GST_BASE_PARSE_FRAME_FLAG_NEW_FRAME flag */
1804       *skipsize = map_info.size;
1805       gst_av1_parse_reset_obu_data_state (self);
1806       GST_WARNING_OBJECT (parse,
1807           "Parse obu need more data, discard whole buffer %d.", *skipsize);
1808     }
1809     ret = GST_FLOW_OK;
1810   } else if (res == GST_AV1_PARSER_DROP) {
1811     GST_DEBUG_OBJECT (parse, "Drop %d data", consumed);
1812     self->last_parsed_offset += consumed;
1813     gst_av1_parse_reset_obu_data_state (self);
1814     res = GST_AV1_PARSER_OK;
1815     goto again;
1816   } else if (res == GST_AV1_PARSER_OK) {
1817     /* Everything is correct but still not get a frame or tu,
1818        need more data */
1819     GST_DEBUG_OBJECT (parse, "Need more data");
1820     *skipsize = 0;
1821     ret = GST_FLOW_OK;
1822   } else {
1823     GST_ERROR_OBJECT (parse, "Parse obu get unexpect error %d", res);
1824     *skipsize = 0;
1825     ret = GST_FLOW_ERROR;
1826   }
1827
1828 out:
1829   gst_buffer_unmap (buffer, &map_info);
1830   gst_buffer_unref (buffer);
1831   return ret;
1832 }
1833
1834 /* Try to recognize whether the input is annex-b format.
1835    return TRUE if we decide, FALSE if we can not decide or
1836    encounter some error. */
1837 static gboolean
1838 gst_av1_parse_detect_stream_format (GstBaseParse * parse,
1839     GstBaseParseFrame * frame)
1840 {
1841   GstAV1Parse *self = GST_AV1_PARSE (parse);
1842   GstMapInfo map_info;
1843   GstAV1OBU obu;
1844   GstAV1ParserResult res = GST_AV1_PARSER_INVALID_OPERATION;
1845   GstBuffer *buffer = gst_buffer_ref (frame->buffer);
1846   gboolean got_seq, got_frame;
1847   gboolean frame_complete;
1848   guint32 consumed;
1849   guint32 total_consumed;
1850   guint32 tu_sz;
1851   gboolean ret = FALSE;
1852
1853   g_assert (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT);
1854   g_assert (self->detect_annex_b == TRUE);
1855
1856   if (!gst_buffer_map (buffer, &map_info, GST_MAP_READ)) {
1857     GST_ERROR_OBJECT (parse, "Couldn't map incoming buffer");
1858     return FALSE;
1859   }
1860
1861   gst_av1_parser_reset (self->parser, FALSE);
1862
1863   got_seq = FALSE;
1864   got_frame = FALSE;
1865   total_consumed = 0;
1866
1867 again:
1868   while (total_consumed < map_info.size) {
1869     res = gst_av1_parser_identify_one_obu (self->parser,
1870         map_info.data + total_consumed, map_info.size - total_consumed,
1871         &obu, &consumed);
1872     if (res == GST_AV1_PARSER_OK) {
1873       total_consumed += consumed;
1874       res = gst_av1_parse_handle_one_obu (self, &obu, &frame_complete, NULL);
1875     }
1876
1877     if (res != GST_AV1_PARSER_OK)
1878       break;
1879
1880     if (obu.obu_type == GST_AV1_OBU_SEQUENCE_HEADER)
1881       got_seq = TRUE;
1882
1883     if (obu.obu_type == GST_AV1_OBU_REDUNDANT_FRAME_HEADER ||
1884         obu.obu_type == GST_AV1_OBU_FRAME ||
1885         obu.obu_type == GST_AV1_OBU_FRAME_HEADER)
1886       got_frame = TRUE;
1887
1888     if (got_seq || got_frame)
1889       break;
1890   }
1891
1892   gst_av1_parser_reset (self->parser, FALSE);
1893
1894   /* If succeed recognize seq or frame, it's done.
1895      otherwise, just need to get more data. */
1896   if (got_seq || got_frame) {
1897     ret = TRUE;
1898     self->detect_annex_b = FALSE;
1899     goto out;
1900   }
1901
1902   if (res == GST_AV1_PARSER_DROP) {
1903     total_consumed += consumed;
1904     res = GST_AV1_PARSER_OK;
1905     gst_av1_parse_reset_obu_data_state (self);
1906     goto again;
1907   }
1908
1909   /* Try the annex b format. The buffer should contain the whole TU,
1910      and the buffer start with the TU size in leb128() format. */
1911   if (map_info.size < 8) {
1912     /* Too small. */
1913     goto out;
1914   }
1915
1916   tu_sz = _read_leb128 (map_info.data, &res, &consumed);
1917   if (tu_sz == 0 || res != GST_AV1_PARSER_OK) {
1918     /* error to get the TU size, should not be annex b. */
1919     goto out;
1920   }
1921
1922   if (tu_sz + consumed != map_info.size) {
1923     GST_DEBUG_OBJECT (self, "Buffer size %" G_GSSIZE_FORMAT ", TU size %d,"
1924         " do not match.", map_info.size, tu_sz);
1925     goto out;
1926   }
1927
1928   GST_INFO_OBJECT (self, "Detect the annex-b format");
1929   self->in_align = GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B;
1930   self->detect_annex_b = FALSE;
1931   gst_av1_parser_reset (self->parser, TRUE);
1932   ret = TRUE;
1933
1934 out:
1935   gst_av1_parse_reset_obu_data_state (self);
1936   gst_buffer_unmap (buffer, &map_info);
1937   gst_buffer_unref (buffer);
1938   return ret;
1939 }
1940
1941 static GstFlowReturn
1942 gst_av1_parse_handle_frame (GstBaseParse * parse,
1943     GstBaseParseFrame * frame, gint * skipsize)
1944 {
1945   GstAV1Parse *self = GST_AV1_PARSE (parse);
1946   GstFlowReturn ret = GST_FLOW_OK;
1947   guint in_level, out_level;
1948
1949   if (GST_BUFFER_FLAG_IS_SET (frame->buffer, GST_BUFFER_FLAG_DISCONT)) {
1950     self->discont = TRUE;
1951
1952     if (frame->flags & GST_BASE_PARSE_FRAME_FLAG_NEW_FRAME)
1953       gst_av1_parse_reset_obu_data_state (self);
1954   } else {
1955     self->discont = FALSE;
1956   }
1957
1958   GST_LOG_OBJECT (self, "Input frame size %" G_GSSIZE_FORMAT,
1959       gst_buffer_get_size (frame->buffer));
1960
1961   /* avoid stale cached parsing state */
1962   if (frame->flags & GST_BASE_PARSE_FRAME_FLAG_NEW_FRAME) {
1963     GST_LOG_OBJECT (self, "parsing new frame");
1964     gst_adapter_clear (self->cache_out);
1965     gst_adapter_clear (self->frame_cache);
1966     self->last_parsed_offset = 0;
1967     self->header = FALSE;
1968     self->keyframe = FALSE;
1969     self->show_frame = FALSE;
1970   } else {
1971     GST_LOG_OBJECT (self, "resuming frame parsing");
1972   }
1973
1974   /* When in pull mode, the sink pad has no caps, we may get the
1975      caps by query the upstream element */
1976   if (self->in_align == GST_AV1_PARSE_ALIGN_NONE) {
1977     GstCaps *upstream_caps;
1978
1979     upstream_caps =
1980         gst_pad_peer_query_caps (GST_BASE_PARSE_SINK_PAD (self), NULL);
1981     if (upstream_caps) {
1982       if (!gst_caps_is_empty (upstream_caps)
1983           && !gst_caps_is_any (upstream_caps)) {
1984         GstAV1ParseAligment align;
1985
1986         GST_LOG_OBJECT (self, "upstream caps: %" GST_PTR_FORMAT, upstream_caps);
1987
1988         /* fixate to avoid ambiguity with lists when parsing */
1989         upstream_caps = gst_caps_fixate (upstream_caps);
1990         align = gst_av1_parse_alignment_from_caps (upstream_caps);
1991         if (align == GST_AV1_PARSE_ALIGN_ERROR) {
1992           GST_ERROR_OBJECT (self, "upstream caps %" GST_PTR_FORMAT
1993               " set stream-format and alignment conflict.", upstream_caps);
1994
1995           gst_caps_unref (upstream_caps);
1996           return GST_FLOW_ERROR;
1997         }
1998
1999         self->in_align = align;
2000       }
2001
2002       gst_caps_unref (upstream_caps);
2003
2004       gst_av1_parser_reset (self->parser,
2005           self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B);
2006     }
2007
2008     if (self->in_align != GST_AV1_PARSE_ALIGN_NONE) {
2009       GST_LOG_OBJECT (self, "Query the upstream get the alignment %s",
2010           gst_av1_parse_alignment_to_string (self->in_align));
2011     } else {
2012       self->in_align = GST_AV1_PARSE_ALIGN_BYTE;
2013       GST_DEBUG_OBJECT (self, "alignment set to default %s",
2014           gst_av1_parse_alignment_to_string (GST_AV1_PARSE_ALIGN_BYTE));
2015     }
2016   }
2017
2018   if (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT
2019       && self->detect_annex_b) {
2020     /* Only happend at the first time of handle_frame, try to
2021        recognize the annex b stream format. */
2022     if (gst_av1_parse_detect_stream_format (parse, frame)) {
2023       GST_INFO_OBJECT (self, "Input alignment %s",
2024           gst_av1_parse_alignment_to_string (self->in_align));
2025     } else {
2026       /* Because the input is already TU aligned, we should skip
2027          the whole problematic TU and check the next one. */
2028       *skipsize = gst_buffer_get_size (frame->buffer);
2029       GST_WARNING_OBJECT (self, "Fail to detect the stream format for TU,"
2030           " skip the whole TU %d", *skipsize);
2031       return GST_FLOW_OK;
2032     }
2033   }
2034
2035   /* We may in pull mode and no caps is set */
2036   if (self->align == GST_AV1_PARSE_ALIGN_NONE)
2037     gst_av1_parse_negotiate (self, NULL);
2038
2039   in_level = self->in_align;
2040   if (self->in_align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B)
2041     in_level = GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT;
2042   out_level = self->align;
2043   if (self->align == GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT_ANNEX_B)
2044     out_level = GST_AV1_PARSE_ALIGN_TEMPORAL_UNIT;
2045
2046   if (self->in_align <= GST_AV1_PARSE_ALIGN_OBU
2047       && self->align == GST_AV1_PARSE_ALIGN_OBU) {
2048     ret = gst_av1_parse_handle_obu_to_obu (parse, frame, skipsize);
2049   } else if (in_level < out_level) {
2050     ret = gst_av1_parse_handle_to_big_align (parse, frame, skipsize);
2051   } else {
2052     ret = gst_av1_parse_handle_to_small_and_equal_align (parse,
2053         frame, skipsize);
2054   }
2055
2056   return ret;
2057 }