webrtc/nice: Support domain name as connection-address of ICE candidate
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-bad / sys / va / gstjpegdecoder.c
1 /* GStreamer
2  * Copyright (C) 2022 Víctor Jáquez <vjaquez@igalia.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 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <gst/base/base.h>
25 #include "gstjpegdecoder.h"
26
27 #define MAX_SAMPLE_FACTOR 4     /* JPEG limit on sampling factors */
28 #define DCT_SIZE          8     /* The basic DCT block is 8x8 samples */
29
30 typedef enum
31 {
32   GST_JPEG_DECODER_STATE_GOT_SOI = 1 << 0,
33   GST_JPEG_DECODER_STATE_GOT_SOF = 1 << 1,
34   GST_JPEG_DECODER_STATE_GOT_SOS = 1 << 2,
35   GST_JPEG_DECODER_STATE_GOT_HUF_TABLE = 1 << 3,
36   GST_JPEG_DECODER_STATE_GOT_IQ_TABLE = 1 << 4,
37
38   GST_JPEG_DECODER_STATE_VALID_PICTURE = (GST_JPEG_DECODER_STATE_GOT_SOI |
39       GST_JPEG_DECODER_STATE_GOT_SOF | GST_JPEG_DECODER_STATE_GOT_SOS),
40 } GstJpegDecoderState;
41
42 struct _GstJpegDecoderPrivate
43 {
44   guint state;
45   guint restart_interval;
46   GstJpegHuffmanTables huf_tables;
47   GstJpegQuantTables quant_tables;
48   GstJpegFrameHdr frame_hdr;
49
50   guint8 max_h, max_v;
51   gboolean lossless;
52 };
53
54 GST_DEBUG_CATEGORY (gst_jpeg_decoder_debug);
55 #define GST_CAT_DEFAULT gst_jpeg_decoder_debug
56
57 /**
58  * GstJpegDecoder:
59  *
60  * Base class to implement statelesss JPEG decoders
61  *
62  * Since: 1.22
63  */
64 #define parent_class gst_jpeg_decoder_parent_clas
65 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstJpegDecoder, gst_jpeg_decoder,
66     GST_TYPE_VIDEO_DECODER, G_ADD_PRIVATE (GstJpegDecoder);
67     GST_DEBUG_CATEGORY_INIT (gst_jpeg_decoder_debug, "jpegdecoder", 0,
68         "JPEG Image Decoder"));
69
70 static gboolean gst_jpeg_decoder_set_format (GstVideoDecoder * decoder,
71     GstVideoCodecState * state);
72 static GstFlowReturn gst_jpeg_decoder_handle_frame (GstVideoDecoder * decoder,
73     GstVideoCodecFrame * frame);
74 static gboolean gst_jpeg_decoder_stop (GstVideoDecoder * decoder);
75
76 static void
77 gst_jpeg_decoder_class_init (GstJpegDecoderClass * klass)
78 {
79   GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass);
80
81   decoder_class->stop = GST_DEBUG_FUNCPTR (gst_jpeg_decoder_stop);
82   decoder_class->set_format = GST_DEBUG_FUNCPTR (gst_jpeg_decoder_set_format);
83   decoder_class->handle_frame =
84       GST_DEBUG_FUNCPTR (gst_jpeg_decoder_handle_frame);
85
86   gst_type_mark_as_plugin_api (GST_TYPE_JPEG_DECODER, 0);
87 }
88
89 static void
90 gst_jpeg_decoder_init (GstJpegDecoder * self)
91 {
92   gst_video_decoder_set_packetized (GST_VIDEO_DECODER (self), TRUE);
93   gst_video_decoder_set_needs_format (GST_VIDEO_DECODER (self), TRUE);
94
95   self->priv = gst_jpeg_decoder_get_instance_private (self);
96 }
97
98 static gboolean
99 gst_jpeg_decoder_stop (GstVideoDecoder * decoder)
100 {
101   GstJpegDecoder *self = GST_JPEG_DECODER (decoder);
102
103   g_clear_pointer (&self->input_state, gst_video_codec_state_unref);
104
105   return TRUE;
106 }
107
108 static gboolean
109 gst_jpeg_decoder_set_format (GstVideoDecoder * decoder,
110     GstVideoCodecState * state)
111 {
112   GstJpegDecoder *self = GST_JPEG_DECODER (decoder);
113
114   GST_DEBUG_OBJECT (decoder, "Set format");
115
116   if (self->input_state)
117     gst_video_codec_state_unref (self->input_state);
118
119   self->input_state = gst_video_codec_state_ref (state);
120
121   return TRUE;
122 }
123
124 static inline gboolean
125 valid_state (guint state, guint ref_state)
126 {
127   return (state & ref_state) == ref_state;
128 }
129
130 static gboolean
131 decode_huffman_table (GstJpegDecoder * self, GstJpegSegment * seg)
132 {
133   GstJpegDecoderPrivate *priv = self->priv;
134
135   if (!gst_jpeg_segment_parse_huffman_table (seg, &priv->huf_tables)) {
136     GST_ERROR_OBJECT (self, "failed to parse Huffman table");
137     return FALSE;
138   }
139
140   priv->state |= GST_JPEG_DECODER_STATE_GOT_HUF_TABLE;
141   return TRUE;
142 }
143
144 static gboolean
145 decode_quant_table (GstJpegDecoder * self, GstJpegSegment * seg)
146 {
147   GstJpegDecoderPrivate *priv = self->priv;
148
149   if (!gst_jpeg_segment_parse_quantization_table (seg, &priv->quant_tables)) {
150     GST_ERROR_OBJECT (self, "failed to parse quantization table");
151     return FALSE;
152   }
153
154   priv->state |= GST_JPEG_DECODER_STATE_GOT_IQ_TABLE;
155   return TRUE;
156 }
157
158 static gboolean
159 decode_restart_interval (GstJpegDecoder * self, GstJpegSegment * seg)
160 {
161   GstJpegDecoderPrivate *priv = self->priv;
162
163   if (!gst_jpeg_segment_parse_restart_interval (seg, &priv->restart_interval)) {
164     GST_ERROR_OBJECT (self, "failed to parse restart interval");
165     return FALSE;
166   }
167   return TRUE;
168 }
169
170 static GstFlowReturn
171 decode_frame (GstJpegDecoder * self, GstJpegSegment * seg,
172     GstVideoCodecFrame * frame)
173 {
174   GstJpegDecoderPrivate *priv = self->priv;
175   GstJpegDecoderClass *klass = GST_JPEG_DECODER_GET_CLASS (self);
176   GstJpegFrameHdr *frame_hdr = &self->priv->frame_hdr;
177   GstFlowReturn ret = GST_FLOW_OK;
178   guint i;
179
180   if (!gst_jpeg_segment_parse_frame_header (seg, frame_hdr)) {
181     GST_ERROR_OBJECT (self, "failed to parse frame header");
182     return GST_FLOW_ERROR;
183   }
184
185   /* A.1.1 Dimensions and sampling factors */
186   priv->max_h = priv->max_v = 0;
187   for (i = 0; i < frame_hdr->num_components; i++) {
188     if (frame_hdr->components[i].horizontal_factor >= MAX_SAMPLE_FACTOR
189         || frame_hdr->components[i].vertical_factor >= MAX_SAMPLE_FACTOR) {
190       ret = GST_FLOW_ERROR;
191       GST_ERROR_OBJECT (self, "frame header with bad sampling factor");
192       goto beach;
193     }
194
195     priv->max_h = MAX (priv->max_h, frame_hdr->components[i].horizontal_factor);
196     priv->max_v = MAX (priv->max_v, frame_hdr->components[i].vertical_factor);
197   }
198
199   if (priv->max_h == 0 || priv->max_v == 0) {
200     ret = GST_FLOW_ERROR;
201     GST_ERROR_OBJECT (self, "frame header with bad sampling factor");
202     goto beach;
203   }
204
205   priv->lossless = seg->marker == GST_JPEG_MARKER_SOF3;
206
207   g_assert (klass->new_picture);
208   ret = klass->new_picture (self, frame, seg->marker, &priv->frame_hdr);
209   if (ret != GST_FLOW_OK) {
210     GST_WARNING_OBJECT (self, "subclass failed to handle new picture");
211     goto beach;
212   }
213
214   priv->state |= GST_JPEG_DECODER_STATE_GOT_SOF;
215
216 beach:
217   return ret;
218 }
219
220
221 static const GstJpegFrameComponent *
222 get_component (const GstJpegFrameHdr * frame_hdr, guint selector)
223 {
224   guint i;
225
226   for (i = 0; i < frame_hdr->num_components; i++) {
227     const GstJpegFrameComponent *fcp = &frame_hdr->components[i];
228     if (fcp->identifier == selector)
229       return fcp;
230   }
231   return NULL;
232 }
233
234 static GstFlowReturn
235 decode_scan (GstJpegDecoder * self, GstJpegSegment * seg)
236 {
237   GstJpegDecoderPrivate *priv = self->priv;
238   GstJpegDecoderClass *klass = GST_JPEG_DECODER_GET_CLASS (self);
239   GstJpegDecoderScan scan;
240   GstJpegScanHdr scan_hdr;
241   GstFlowReturn ret;
242   const guint8 *data;
243   guint size, scan_hdr_size;
244   guint64 mcus_per_row, mcu_rows_in_scan;
245   guint blocksize = priv->lossless ? 1 : DCT_SIZE;
246
247   /* E.2.3 Control procedure for decoding a scan */
248   if (!valid_state (priv->state, GST_JPEG_DECODER_STATE_GOT_SOF))
249     return GST_FLOW_OK;         /* ignore segment */
250
251   if (!gst_jpeg_segment_parse_scan_header (seg, &scan_hdr)) {
252     GST_ERROR_OBJECT (self, "failed to parse scan header");
253     return GST_FLOW_ERROR;
254   }
255
256   if (!valid_state (priv->state, GST_JPEG_DECODER_STATE_GOT_HUF_TABLE))
257     gst_jpeg_get_default_huffman_tables (&priv->huf_tables);
258
259   if (!valid_state (priv->state, GST_JPEG_DECODER_STATE_GOT_IQ_TABLE))
260     gst_jpeg_get_default_quantization_tables (&priv->quant_tables);
261
262   /* Non-interleaved */
263   if (scan_hdr.num_components == 1) {
264     const guint cs = scan_hdr.components[0].component_selector;
265     const GstJpegFrameComponent *fc = get_component (&priv->frame_hdr, cs);
266
267     if (!fc || fc->horizontal_factor == 0 || fc->vertical_factor == 0) {
268       GST_ERROR_OBJECT (self, "failed to validate frame component %u", cs);
269       return GST_FLOW_ERROR;
270     }
271
272     mcus_per_row = gst_util_uint64_scale_int_ceil (priv->frame_hdr.width,
273         fc->horizontal_factor, priv->max_h * blocksize);
274     mcu_rows_in_scan = gst_util_uint64_scale_int_ceil (priv->frame_hdr.height,
275         fc->vertical_factor, priv->max_v * blocksize);
276   } else {
277     mcus_per_row = gst_util_uint64_scale_int_ceil (priv->frame_hdr.width, 1,
278         priv->max_h * blocksize);
279     mcu_rows_in_scan =
280         gst_util_uint64_scale_int_ceil (priv->frame_hdr.height, 1,
281         priv->max_v * blocksize);
282   }
283
284   scan_hdr_size = (seg->data[seg->offset] << 8) | seg->data[seg->offset + 1];
285   size = seg->size - scan_hdr_size;
286   data = seg->data + seg->offset + scan_hdr_size;
287
288   if (size <= 0)
289     return GST_FLOW_ERROR;
290
291   /* *INDENT-OFF* */
292   scan = (GstJpegDecoderScan) {
293     .scan_hdr = &scan_hdr,
294     .huffman_tables = &priv->huf_tables,
295     .quantization_tables = &priv->quant_tables,
296     .restart_interval = priv->restart_interval,
297     .mcus_per_row = mcus_per_row,
298     .mcu_rows_in_scan = mcu_rows_in_scan,
299   };
300   /* *INDENT-ON* */
301
302   g_assert (klass->decode_scan);
303   ret = klass->decode_scan (self, &scan, data, size);
304
305   if (ret == GST_FLOW_OK)
306     priv->state |= GST_JPEG_DECODER_STATE_GOT_SOS;
307
308   return ret;
309 }
310
311 #ifndef GST_DISABLE_GST_DEBUG
312 static const char *
313 _get_marker_name (guint marker)
314 {
315 #define MARKERS(V)                              \
316   V (SOF0)                                      \
317     V (SOF1)                                    \
318     V (SOF2)                                    \
319     V (SOF3)                                    \
320     V (SOF5)                                    \
321     V (SOF6)                                    \
322     V (SOF7)                                    \
323     V (SOF9)                                    \
324     V (SOF10)                                   \
325     V (SOF11)                                   \
326     V (SOF13)                                   \
327     V (SOF14)                                   \
328     V (SOF15)                                   \
329     V (DHT)                                     \
330     V (DAC)                                     \
331     V (RST0)                                    \
332     V (RST1)                                    \
333     V (RST2)                                    \
334     V (RST3)                                    \
335     V (RST4)                                    \
336     V (RST5)                                    \
337     V (RST6)                                    \
338     V (RST7)                                    \
339     V (SOI)                                     \
340     V (EOI)                                     \
341     V (SOS)                                     \
342     V (DQT)                                     \
343     V (DNL)                                     \
344     V (DRI)                                     \
345     V (APP0)                                    \
346     V (APP1)                                    \
347     V (APP2)                                    \
348     V (APP3)                                    \
349     V (APP4)                                    \
350     V (APP5)                                    \
351     V (APP6)                                    \
352     V (APP7)                                    \
353     V (APP8)                                    \
354     V (APP9)                                    \
355     V (APP10)                                   \
356     V (APP11)                                   \
357     V (APP12)                                   \
358     V (APP13)                                   \
359     V (APP14)                                   \
360     V (APP15)                                   \
361     V (COM)
362 #define CASE(marker) case G_PASTE(GST_JPEG_MARKER_, marker): return G_STRINGIFY (marker);
363   switch (marker) {
364       MARKERS (CASE)
365     default:
366       return "Unknown";
367   }
368 #undef CASE
369 #undef MARKERS
370 }
371 #endif
372
373 static GstFlowReturn
374 gst_jpeg_decoder_handle_frame (GstVideoDecoder * decoder,
375     GstVideoCodecFrame * frame)
376 {
377   GstJpegDecoder *self = GST_JPEG_DECODER (decoder);
378   GstJpegDecoderPrivate *priv = self->priv;
379   GstJpegDecoderClass *klass = GST_JPEG_DECODER_GET_CLASS (self);
380   GstBuffer *in_buf = frame->input_buffer;
381   GstFlowReturn ret = GST_FLOW_OK;
382   GstMapInfo map;
383   GstJpegMarker marker;
384   GstJpegSegment seg;
385   guint offset = 0;
386
387   GST_LOG_OBJECT (self, "handle frame %" GST_PTR_FORMAT, in_buf);
388
389   if (!gst_buffer_map (in_buf, &map, GST_MAP_READ)) {
390     GST_ERROR_OBJECT (self, "Cannot map input buffer");
391     ret = GST_FLOW_ERROR;
392     goto error;
393   }
394
395   priv->state = 0;
396
397   /* E.2.1 Control procedure for decoding compressed image data */
398   while (offset < map.size) {
399     if (!gst_jpeg_parse (&seg, map.data, map.size, offset))
400       goto unmap_and_error;
401
402     offset = seg.offset + seg.size;
403     marker = seg.marker;
404
405     if (!valid_state (priv->state, GST_JPEG_DECODER_STATE_GOT_SOI)
406         && marker != GST_JPEG_MARKER_SOI)
407       goto unmap_and_error;
408
409     GST_LOG_OBJECT (self, "marker %s: %" G_GSIZE_FORMAT,
410         _get_marker_name (marker), seg.size);
411
412     switch (marker) {
413
414         /* Start of Image */
415       case GST_JPEG_MARKER_SOI:
416         priv->state |= GST_JPEG_DECODER_STATE_GOT_SOI;
417         priv->restart_interval = 0;
418         break;
419
420         /* End of Image */
421       case GST_JPEG_MARKER_EOI:
422         if (!valid_state (priv->state, GST_JPEG_DECODER_STATE_VALID_PICTURE))
423           goto unmap_and_error;
424
425         g_assert (klass->end_picture);
426         ret = klass->end_picture (self);
427         if (ret != GST_FLOW_OK)
428           goto unmap_and_error;
429
430         priv->state = 0;
431
432         gst_buffer_unmap (in_buf, &map);
433
434         GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
435
436         g_assert (klass->output_picture);
437         return klass->output_picture (self, frame);
438
439         /* Start of Scan */
440       case GST_JPEG_MARKER_SOS:{
441         /* get whole scan + ECSs, with RSTi */
442         GstJpegSegment seg_scan;
443
444         for (;;) {
445           if (!gst_jpeg_parse (&seg_scan, map.data, map.size, offset))
446             goto unmap_and_error;
447
448           if (seg_scan.marker < GST_JPEG_MARKER_RST_MIN
449               || seg_scan.marker > GST_JPEG_MARKER_RST_MAX)
450             break;
451
452           offset = seg_scan.offset + seg_scan.size;
453         }
454
455         offset = seg_scan.offset - 2;
456         seg.size = offset - seg.offset;
457
458         ret = decode_scan (self, &seg);
459         if (ret != GST_FLOW_OK)
460           goto unmap_and_error;
461
462         break;
463       }
464
465         /* Interpret markers */
466       case GST_JPEG_MARKER_DAC:
467         /* FIXME: Annex D - Arithmetic coding */
468         GST_FIXME_OBJECT (self, "Arithmetic coding mode unsupported");
469         goto unmap_and_error;
470       case GST_JPEG_MARKER_DHT:
471         if (!decode_huffman_table (self, &seg)) {
472           ret = GST_FLOW_ERROR;
473           goto unmap_and_error;
474         }
475         break;
476       case GST_JPEG_MARKER_DQT:
477         if (!decode_quant_table (self, &seg)) {
478           ret = GST_FLOW_ERROR;
479           goto unmap_and_error;
480         }
481         break;
482
483       case GST_JPEG_MARKER_DRI:
484         if (!decode_restart_interval (self, &seg)) {
485           GST_WARNING_OBJECT (self, "Fail to decode restart interval");
486           goto unmap_and_error;
487         }
488         break;
489       case GST_JPEG_MARKER_DNL:
490         break;
491       default:
492         /* SOFn (Start Of Frame) */
493         if (marker >= GST_JPEG_MARKER_SOF_MIN &&
494             marker <= GST_JPEG_MARKER_SOF_MAX) {
495           ret = decode_frame (self, &seg, frame);
496           if (ret != GST_FLOW_OK)
497             goto unmap_and_error;
498         }
499         break;
500     }
501   }
502
503   ret = GST_FLOW_ERROR;
504
505 unmap_and_error:
506   {
507     gst_buffer_unmap (in_buf, &map);
508     goto error;
509   }
510
511 error:
512   {
513     if (ret == GST_FLOW_ERROR) {
514       GST_VIDEO_DECODER_ERROR (self, 1, STREAM, DECODE,
515           ("Failed to decode data"), (NULL), ret);
516     }
517
518     gst_video_decoder_drop_frame (decoder, frame);
519
520     return ret;
521   }
522 }