add parent to query function
[platform/upstream/gst-plugins-good.git] / ext / jpeg / gstjpegdec.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  * Copyright (C) <2009> Tim-Philipp Müller <tim centricular net>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 /**
22  * SECTION:element-jpegdec
23  *
24  * Decodes jpeg images.
25  *
26  * <refsect2>
27  * <title>Example launch line</title>
28  * |[
29  * gst-launch -v v4l2src ! jpegdec ! ffmpegcolorspace ! xvimagesink
30  * ]| The above pipeline reads a motion JPEG stream from a v4l2 camera
31  * and renders it to the screen.
32  * </refsect2>
33  */
34
35 #ifdef HAVE_CONFIG_H
36 #include "config.h"
37 #endif
38 #include <string.h>
39
40 #include "gstjpegdec.h"
41 #include "gstjpeg.h"
42 #include <gst/video/video.h>
43 #include "gst/gst-i18n-plugin.h"
44 #include <jerror.h>
45
46 #define MIN_WIDTH  1
47 #define MAX_WIDTH  65535
48 #define MIN_HEIGHT 1
49 #define MAX_HEIGHT 65535
50
51 #define CINFO_GET_JPEGDEC(cinfo_ptr) \
52         (((struct GstJpegDecSourceMgr*)((cinfo_ptr)->src))->dec)
53
54 #define JPEG_DEFAULT_IDCT_METHOD        JDCT_FASTEST
55 #define JPEG_DEFAULT_MAX_ERRORS         0
56
57 enum
58 {
59   PROP_0,
60   PROP_IDCT_METHOD,
61   PROP_MAX_ERRORS
62 };
63
64 /* *INDENT-OFF* */
65 static GstStaticPadTemplate gst_jpeg_dec_src_pad_template =
66 GST_STATIC_PAD_TEMPLATE ("src",
67     GST_PAD_SRC,
68     GST_PAD_ALWAYS,
69     GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
70         ("{ I420, RGB, BGR, RGBx, xRGB, BGRx, xBGR, GRAY8 }"))
71     );
72
73 /* *INDENT-ON* */
74
75 /* FIXME: sof-marker is for IJG libjpeg 8, should be different for 6.2 */
76 static GstStaticPadTemplate gst_jpeg_dec_sink_pad_template =
77 GST_STATIC_PAD_TEMPLATE ("sink",
78     GST_PAD_SINK,
79     GST_PAD_ALWAYS,
80     GST_STATIC_CAPS ("image/jpeg, "
81         "width = (int) [ " G_STRINGIFY (MIN_WIDTH) ", " G_STRINGIFY (MAX_WIDTH)
82         " ], " "height = (int) [ " G_STRINGIFY (MIN_HEIGHT) ", "
83         G_STRINGIFY (MAX_HEIGHT) " ], framerate = (fraction) [ 0/1, MAX ], "
84         "sof-marker = (int) { 0, 1, 2, 5, 6, 7, 9, 10, 13, 14 }")
85     );
86
87 GST_DEBUG_CATEGORY_STATIC (jpeg_dec_debug);
88 #define GST_CAT_DEFAULT jpeg_dec_debug
89 GST_DEBUG_CATEGORY_STATIC (GST_CAT_PERFORMANCE);
90
91 static void gst_jpeg_dec_set_property (GObject * object, guint prop_id,
92     const GValue * value, GParamSpec * pspec);
93 static void gst_jpeg_dec_get_property (GObject * object, guint prop_id,
94     GValue * value, GParamSpec * pspec);
95
96 static GstFlowReturn gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buffer);
97 static GstCaps *gst_jpeg_dec_getcaps (GstPad * pad, GstCaps * filter);
98 static gboolean gst_jpeg_dec_sink_query (GstPad * pad, GstObject * parent,
99     GstQuery * query);
100 static gboolean gst_jpeg_dec_sink_event (GstPad * pad, GstEvent * event);
101 static gboolean gst_jpeg_dec_src_event (GstPad * pad, GstEvent * event);
102 static GstStateChangeReturn gst_jpeg_dec_change_state (GstElement * element,
103     GstStateChange transition);
104 static void gst_jpeg_dec_update_qos (GstJpegDec * dec, gdouble proportion,
105     GstClockTimeDiff diff, GstClockTime ts);
106 static void gst_jpeg_dec_reset_qos (GstJpegDec * dec);
107 static void gst_jpeg_dec_read_qos (GstJpegDec * dec, gdouble * proportion,
108     GstClockTime * time);
109
110 #define gst_jpeg_dec_parent_class parent_class
111 G_DEFINE_TYPE (GstJpegDec, gst_jpeg_dec, GST_TYPE_ELEMENT);
112
113 static void
114 gst_jpeg_dec_finalize (GObject * object)
115 {
116   GstJpegDec *dec = GST_JPEG_DEC (object);
117
118   jpeg_destroy_decompress (&dec->cinfo);
119
120   g_object_unref (dec->adapter);
121
122   G_OBJECT_CLASS (parent_class)->finalize (object);
123 }
124
125 static void
126 gst_jpeg_dec_class_init (GstJpegDecClass * klass)
127 {
128   GstElementClass *gstelement_class;
129   GObjectClass *gobject_class;
130
131   gstelement_class = (GstElementClass *) klass;
132   gobject_class = (GObjectClass *) klass;
133
134   parent_class = g_type_class_peek_parent (klass);
135
136   gobject_class->finalize = gst_jpeg_dec_finalize;
137   gobject_class->set_property = gst_jpeg_dec_set_property;
138   gobject_class->get_property = gst_jpeg_dec_get_property;
139
140   g_object_class_install_property (gobject_class, PROP_IDCT_METHOD,
141       g_param_spec_enum ("idct-method", "IDCT Method",
142           "The IDCT algorithm to use", GST_TYPE_IDCT_METHOD,
143           JPEG_DEFAULT_IDCT_METHOD,
144           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
145
146   /**
147    * GstJpegDec:max-errors
148    *
149    * Error out after receiving N consecutive decoding errors
150    * (-1 = never error out, 0 = automatic, 1 = fail on first error, etc.)
151    *
152    * Since: 0.10.27
153    **/
154   g_object_class_install_property (gobject_class, PROP_MAX_ERRORS,
155       g_param_spec_int ("max-errors", "Maximum Consecutive Decoding Errors",
156           "Error out after receiving N consecutive decoding errors "
157           "(-1 = never fail, 0 = automatic, 1 = fail on first error)",
158           -1, G_MAXINT, JPEG_DEFAULT_MAX_ERRORS,
159           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
160
161   gst_element_class_add_pad_template (gstelement_class,
162       gst_static_pad_template_get (&gst_jpeg_dec_src_pad_template));
163   gst_element_class_add_pad_template (gstelement_class,
164       gst_static_pad_template_get (&gst_jpeg_dec_sink_pad_template));
165   gst_element_class_set_details_simple (gstelement_class, "JPEG image decoder",
166       "Codec/Decoder/Image",
167       "Decode images from JPEG format", "Wim Taymans <wim@fluendo.com>");
168
169   gstelement_class->change_state =
170       GST_DEBUG_FUNCPTR (gst_jpeg_dec_change_state);
171
172   GST_DEBUG_CATEGORY_INIT (jpeg_dec_debug, "jpegdec", 0, "JPEG decoder");
173   GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE");
174 }
175
176 static void
177 gst_jpeg_dec_clear_error (GstJpegDec * dec)
178 {
179   g_free (dec->error_msg);
180   dec->error_msg = NULL;
181   dec->error_line = 0;
182   dec->error_func = NULL;
183 }
184
185 static void
186 gst_jpeg_dec_set_error_va (GstJpegDec * dec, const gchar * func, gint line,
187     const gchar * debug_msg_format, va_list args)
188 {
189 #ifndef GST_DISABLE_GST_DEBUG
190   gst_debug_log_valist (GST_CAT_DEFAULT, GST_LEVEL_WARNING, __FILE__, func,
191       line, (GObject *) dec, debug_msg_format, args);
192 #endif
193
194   g_free (dec->error_msg);
195   if (debug_msg_format)
196     dec->error_msg = g_strdup_vprintf (debug_msg_format, args);
197   else
198     dec->error_msg = NULL;
199
200   dec->error_line = line;
201   dec->error_func = func;
202 }
203
204 static void
205 gst_jpeg_dec_set_error (GstJpegDec * dec, const gchar * func, gint line,
206     const gchar * debug_msg_format, ...)
207 {
208   va_list va;
209
210   va_start (va, debug_msg_format);
211   gst_jpeg_dec_set_error_va (dec, func, line, debug_msg_format, va);
212   va_end (va);
213 }
214
215 static GstFlowReturn
216 gst_jpeg_dec_post_error_or_warning (GstJpegDec * dec)
217 {
218   GstFlowReturn ret;
219   int max_errors;
220
221   ++dec->error_count;
222   max_errors = g_atomic_int_get (&dec->max_errors);
223
224   if (max_errors < 0) {
225     ret = GST_FLOW_OK;
226   } else if (max_errors == 0) {
227     /* FIXME: do something more clever in "automatic mode" */
228     if (dec->packetized) {
229       ret = (dec->error_count < 3) ? GST_FLOW_OK : GST_FLOW_ERROR;
230     } else {
231       ret = GST_FLOW_ERROR;
232     }
233   } else {
234     ret = (dec->error_count < max_errors) ? GST_FLOW_OK : GST_FLOW_ERROR;
235   }
236
237   GST_INFO_OBJECT (dec, "decoding error %d/%d (%s)", dec->error_count,
238       max_errors, (ret == GST_FLOW_OK) ? "ignoring error" : "erroring out");
239
240   gst_element_message_full (GST_ELEMENT (dec),
241       (ret == GST_FLOW_OK) ? GST_MESSAGE_WARNING : GST_MESSAGE_ERROR,
242       GST_STREAM_ERROR, GST_STREAM_ERROR_DECODE,
243       g_strdup (_("Failed to decode JPEG image")), dec->error_msg,
244       __FILE__, dec->error_func, dec->error_line);
245
246   dec->error_msg = NULL;
247   gst_jpeg_dec_clear_error (dec);
248   return ret;
249 }
250
251 static boolean
252 gst_jpeg_dec_fill_input_buffer (j_decompress_ptr cinfo)
253 {
254   GstJpegDec *dec;
255   guint av;
256
257   dec = CINFO_GET_JPEGDEC (cinfo);
258   g_return_val_if_fail (dec != NULL, FALSE);
259
260   av = gst_adapter_available_fast (dec->adapter);
261   GST_DEBUG_OBJECT (dec, "fill_input_buffer: fast av=%u, remaining=%u", av,
262       dec->rem_img_len);
263
264   if (av == 0) {
265     GST_DEBUG_OBJECT (dec, "Out of data");
266     return FALSE;
267   }
268
269   if (dec->rem_img_len < av)
270     av = dec->rem_img_len;
271   dec->rem_img_len -= av;
272
273   g_free (dec->cur_buf);
274   dec->cur_buf = gst_adapter_take (dec->adapter, av);
275
276   cinfo->src->next_input_byte = dec->cur_buf;
277   cinfo->src->bytes_in_buffer = av;
278
279   return TRUE;
280 }
281
282 static void
283 gst_jpeg_dec_init_source (j_decompress_ptr cinfo)
284 {
285   GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "init_source");
286 }
287
288
289 static void
290 gst_jpeg_dec_skip_input_data (j_decompress_ptr cinfo, glong num_bytes)
291 {
292   GstJpegDec *dec = CINFO_GET_JPEGDEC (cinfo);
293
294   GST_DEBUG_OBJECT (dec, "skip %ld bytes", num_bytes);
295
296   if (num_bytes > 0 && cinfo->src->bytes_in_buffer >= num_bytes) {
297     cinfo->src->next_input_byte += (size_t) num_bytes;
298     cinfo->src->bytes_in_buffer -= (size_t) num_bytes;
299   } else if (num_bytes > 0) {
300     gint available;
301
302     num_bytes -= cinfo->src->bytes_in_buffer;
303     cinfo->src->next_input_byte += (size_t) cinfo->src->bytes_in_buffer;
304     cinfo->src->bytes_in_buffer = 0;
305
306     available = gst_adapter_available (dec->adapter);
307     if (available < num_bytes || available < dec->rem_img_len) {
308       GST_WARNING_OBJECT (dec, "Less bytes to skip than available in the "
309           "adapter or the remaining image length %ld < %d or %u",
310           num_bytes, available, dec->rem_img_len);
311     }
312     num_bytes = MIN (MIN (num_bytes, available), dec->rem_img_len);
313     gst_adapter_flush (dec->adapter, num_bytes);
314     dec->rem_img_len -= num_bytes;
315   }
316 }
317
318 static boolean
319 gst_jpeg_dec_resync_to_restart (j_decompress_ptr cinfo, gint desired)
320 {
321   GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "resync_to_start");
322   return TRUE;
323 }
324
325 static void
326 gst_jpeg_dec_term_source (j_decompress_ptr cinfo)
327 {
328   GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "term_source");
329   return;
330 }
331
332 METHODDEF (void)
333     gst_jpeg_dec_my_output_message (j_common_ptr cinfo)
334 {
335   return;                       /* do nothing */
336 }
337
338 METHODDEF (void)
339     gst_jpeg_dec_my_emit_message (j_common_ptr cinfo, int msg_level)
340 {
341   /* GST_LOG_OBJECT (CINFO_GET_JPEGDEC (&cinfo), "msg_level=%d", msg_level); */
342   return;
343 }
344
345 METHODDEF (void)
346     gst_jpeg_dec_my_error_exit (j_common_ptr cinfo)
347 {
348   struct GstJpegDecErrorMgr *err_mgr = (struct GstJpegDecErrorMgr *) cinfo->err;
349
350   (*cinfo->err->output_message) (cinfo);
351   longjmp (err_mgr->setjmp_buffer, 1);
352 }
353
354 static void
355 gst_jpeg_dec_init (GstJpegDec * dec)
356 {
357   GST_DEBUG ("initializing");
358
359   /* create the sink and src pads */
360   dec->sinkpad =
361       gst_pad_new_from_static_template (&gst_jpeg_dec_sink_pad_template,
362       "sink");
363   gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
364   gst_pad_set_chain_function (dec->sinkpad,
365       GST_DEBUG_FUNCPTR (gst_jpeg_dec_chain));
366   gst_pad_set_event_function (dec->sinkpad,
367       GST_DEBUG_FUNCPTR (gst_jpeg_dec_sink_event));
368   gst_pad_set_query_function (dec->sinkpad,
369       GST_DEBUG_FUNCPTR (gst_jpeg_dec_sink_query));
370
371   dec->srcpad =
372       gst_pad_new_from_static_template (&gst_jpeg_dec_src_pad_template, "src");
373   gst_pad_set_event_function (dec->srcpad,
374       GST_DEBUG_FUNCPTR (gst_jpeg_dec_src_event));
375   gst_pad_use_fixed_caps (dec->srcpad);
376   gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
377
378   /* setup jpeglib */
379   memset (&dec->cinfo, 0, sizeof (dec->cinfo));
380   memset (&dec->jerr, 0, sizeof (dec->jerr));
381   dec->cinfo.err = jpeg_std_error (&dec->jerr.pub);
382   dec->jerr.pub.output_message = gst_jpeg_dec_my_output_message;
383   dec->jerr.pub.emit_message = gst_jpeg_dec_my_emit_message;
384   dec->jerr.pub.error_exit = gst_jpeg_dec_my_error_exit;
385
386   jpeg_create_decompress (&dec->cinfo);
387
388   dec->cinfo.src = (struct jpeg_source_mgr *) &dec->jsrc;
389   dec->cinfo.src->init_source = gst_jpeg_dec_init_source;
390   dec->cinfo.src->fill_input_buffer = gst_jpeg_dec_fill_input_buffer;
391   dec->cinfo.src->skip_input_data = gst_jpeg_dec_skip_input_data;
392   dec->cinfo.src->resync_to_restart = gst_jpeg_dec_resync_to_restart;
393   dec->cinfo.src->term_source = gst_jpeg_dec_term_source;
394   dec->jsrc.dec = dec;
395
396   /* init properties */
397   dec->idct_method = JPEG_DEFAULT_IDCT_METHOD;
398   dec->max_errors = JPEG_DEFAULT_MAX_ERRORS;
399
400   dec->adapter = gst_adapter_new ();
401 }
402
403 static gboolean
404 gst_jpeg_dec_ensure_header (GstJpegDec * dec)
405 {
406   gint av;
407   gint offset;
408
409   av = gst_adapter_available (dec->adapter);
410   /* we expect at least 4 bytes, first of which start marker */
411   offset = gst_adapter_masked_scan_uint32 (dec->adapter, 0xffffff00, 0xffd8ff00,
412       0, av);
413   if (G_UNLIKELY (offset < 0)) {
414     GST_DEBUG_OBJECT (dec, "No JPEG header in current buffer");
415     /* not found */
416     if (av > 4)
417       gst_adapter_flush (dec->adapter, av - 4);
418     return FALSE;
419   }
420
421   if (offset > 0) {
422     GST_LOG_OBJECT (dec, "Skipping %u bytes.", offset);
423     gst_adapter_flush (dec->adapter, offset);
424   }
425   GST_DEBUG_OBJECT (dec, "Found JPEG header");
426
427   return TRUE;
428 }
429
430 static inline gboolean
431 gst_jpeg_dec_parse_tag_has_entropy_segment (guint8 tag)
432 {
433   if (tag == 0xda || (tag >= 0xd0 && tag <= 0xd7))
434     return TRUE;
435   return FALSE;
436 }
437
438 /* returns image length in bytes if parsed successfully,
439  * otherwise 0 if more data needed,
440  * if < 0 the absolute value needs to be flushed */
441 static gint
442 gst_jpeg_dec_parse_image_data (GstJpegDec * dec)
443 {
444   guint size;
445   gboolean resync;
446   GstAdapter *adapter = dec->adapter;
447   gint offset, noffset;
448
449   size = gst_adapter_available (adapter);
450
451   /* we expect at least 4 bytes, first of which start marker */
452   if (gst_adapter_masked_scan_uint32 (adapter, 0xffff0000, 0xffd80000, 0, 4))
453     return 0;
454
455   GST_DEBUG ("Parsing jpeg image data (%u bytes)", size);
456
457   GST_DEBUG ("Parse state: offset=%d, resync=%d, entropy len=%d",
458       dec->parse_offset, dec->parse_resync, dec->parse_entropy_len);
459
460   /* offset is 2 less than actual offset;
461    * - adapter needs at least 4 bytes for scanning,
462    * - start and end marker ensure at least that much
463    */
464   /* resume from state offset */
465   offset = dec->parse_offset;
466
467   while (1) {
468     guint frame_len;
469     guint32 value;
470
471     noffset =
472         gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00, 0x0000ff00,
473         offset, size - offset, &value);
474     /* lost sync if 0xff marker not where expected */
475     if ((resync = (noffset != offset))) {
476       GST_DEBUG ("Lost sync at 0x%08x, resyncing", offset + 2);
477     }
478     /* may have marker, but could have been resyncng */
479     resync = resync || dec->parse_resync;
480     /* Skip over extra 0xff */
481     while ((noffset >= 0) && ((value & 0xff) == 0xff)) {
482       noffset++;
483       noffset =
484           gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00, 0x0000ff00,
485           noffset, size - noffset, &value);
486     }
487     /* enough bytes left for marker? (we need 0xNN after the 0xff) */
488     if (noffset < 0) {
489       GST_DEBUG ("at end of input and no EOI marker found, need more data");
490       goto need_more_data;
491     }
492
493     /* now lock on the marker we found */
494     offset = noffset;
495     value = value & 0xff;
496     if (value == 0xd9) {
497       GST_DEBUG ("0x%08x: EOI marker", offset + 2);
498       /* clear parse state */
499       dec->parse_resync = FALSE;
500       dec->parse_offset = 0;
501       return (offset + 4);
502     } else if (value == 0xd8) {
503       /* Skip this frame if we found another SOI marker */
504       GST_DEBUG ("0x%08x: SOI marker before EOI, skipping", offset + 2);
505       dec->parse_resync = FALSE;
506       dec->parse_offset = 0;
507       return -(offset + 2);
508     }
509
510
511     if (value >= 0xd0 && value <= 0xd7)
512       frame_len = 0;
513     else {
514       /* peek tag and subsequent length */
515       if (offset + 2 + 4 > size)
516         goto need_more_data;
517       else
518         gst_adapter_masked_scan_uint32_peek (adapter, 0x0, 0x0, offset + 2, 4,
519             &frame_len);
520       frame_len = frame_len & 0xffff;
521     }
522     GST_DEBUG ("0x%08x: tag %02x, frame_len=%u", offset + 2, value, frame_len);
523     /* the frame length includes the 2 bytes for the length; here we want at
524      * least 2 more bytes at the end for an end marker */
525     if (offset + 2 + 2 + frame_len + 2 > size) {
526       goto need_more_data;
527     }
528
529     if (gst_jpeg_dec_parse_tag_has_entropy_segment (value)) {
530       guint eseglen = dec->parse_entropy_len;
531
532       GST_DEBUG ("0x%08x: finding entropy segment length", offset + 2);
533       noffset = offset + 2 + frame_len + dec->parse_entropy_len;
534       while (1) {
535         noffset = gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00,
536             0x0000ff00, noffset, size - noffset, &value);
537         if (noffset < 0) {
538           /* need more data */
539           dec->parse_entropy_len = size - offset - 4 - frame_len - 2;
540           goto need_more_data;
541         }
542         if ((value & 0xff) != 0x00) {
543           eseglen = noffset - offset - frame_len - 2;
544           break;
545         }
546         noffset++;
547       }
548       dec->parse_entropy_len = 0;
549       frame_len += eseglen;
550       GST_DEBUG ("entropy segment length=%u => frame_len=%u", eseglen,
551           frame_len);
552     }
553     if (resync) {
554       /* check if we will still be in sync if we interpret
555        * this as a sync point and skip this frame */
556       noffset = offset + frame_len + 2;
557       noffset = gst_adapter_masked_scan_uint32 (adapter, 0x0000ff00, 0x0000ff00,
558           noffset, 4);
559       if (noffset < 0) {
560         /* ignore and continue resyncing until we hit the end
561          * of our data or find a sync point that looks okay */
562         offset++;
563         continue;
564       }
565       GST_DEBUG ("found sync at 0x%x", offset + 2);
566     }
567
568     offset += frame_len + 2;
569   }
570
571   /* EXITS */
572 need_more_data:
573   {
574     dec->parse_offset = offset;
575     dec->parse_resync = resync;
576     return 0;
577   }
578 }
579
580 /* shamelessly ripped from jpegutils.c in mjpegtools */
581 static void
582 add_huff_table (j_decompress_ptr dinfo,
583     JHUFF_TBL ** htblptr, const UINT8 * bits, const UINT8 * val)
584 /* Define a Huffman table */
585 {
586   int nsymbols, len;
587
588   if (*htblptr == NULL)
589     *htblptr = jpeg_alloc_huff_table ((j_common_ptr) dinfo);
590
591   g_assert (*htblptr);
592
593   /* Copy the number-of-symbols-of-each-code-length counts */
594   memcpy ((*htblptr)->bits, bits, sizeof ((*htblptr)->bits));
595
596   /* Validate the counts.  We do this here mainly so we can copy the right
597    * number of symbols from the val[] array, without risking marching off
598    * the end of memory.  jchuff.c will do a more thorough test later.
599    */
600   nsymbols = 0;
601   for (len = 1; len <= 16; len++)
602     nsymbols += bits[len];
603   if (nsymbols < 1 || nsymbols > 256)
604     g_error ("jpegutils.c:  add_huff_table failed badly. ");
605
606   memcpy ((*htblptr)->huffval, val, nsymbols * sizeof (UINT8));
607 }
608
609
610
611 static void
612 std_huff_tables (j_decompress_ptr dinfo)
613 /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
614 /* IMPORTANT: these are only valid for 8-bit data precision! */
615 {
616   static const UINT8 bits_dc_luminance[17] =
617       { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
618   static const UINT8 val_dc_luminance[] =
619       { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
620
621   static const UINT8 bits_dc_chrominance[17] =
622       { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
623   static const UINT8 val_dc_chrominance[] =
624       { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
625
626   static const UINT8 bits_ac_luminance[17] =
627       { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
628   static const UINT8 val_ac_luminance[] =
629       { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
630     0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
631     0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
632     0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
633     0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
634     0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
635     0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
636     0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
637     0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
638     0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
639     0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
640     0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
641     0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
642     0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
643     0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
644     0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
645     0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
646     0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
647     0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
648     0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
649     0xf9, 0xfa
650   };
651
652   static const UINT8 bits_ac_chrominance[17] =
653       { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
654   static const UINT8 val_ac_chrominance[] =
655       { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
656     0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
657     0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
658     0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
659     0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
660     0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
661     0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
662     0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
663     0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
664     0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
665     0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
666     0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
667     0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
668     0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
669     0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
670     0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
671     0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
672     0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
673     0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
674     0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
675     0xf9, 0xfa
676   };
677
678   add_huff_table (dinfo, &dinfo->dc_huff_tbl_ptrs[0],
679       bits_dc_luminance, val_dc_luminance);
680   add_huff_table (dinfo, &dinfo->ac_huff_tbl_ptrs[0],
681       bits_ac_luminance, val_ac_luminance);
682   add_huff_table (dinfo, &dinfo->dc_huff_tbl_ptrs[1],
683       bits_dc_chrominance, val_dc_chrominance);
684   add_huff_table (dinfo, &dinfo->ac_huff_tbl_ptrs[1],
685       bits_ac_chrominance, val_ac_chrominance);
686 }
687
688
689
690 static void
691 guarantee_huff_tables (j_decompress_ptr dinfo)
692 {
693   if ((dinfo->dc_huff_tbl_ptrs[0] == NULL) &&
694       (dinfo->dc_huff_tbl_ptrs[1] == NULL) &&
695       (dinfo->ac_huff_tbl_ptrs[0] == NULL) &&
696       (dinfo->ac_huff_tbl_ptrs[1] == NULL)) {
697     GST_DEBUG ("Generating standard Huffman tables for this frame.");
698     std_huff_tables (dinfo);
699   }
700 }
701
702 static gboolean
703 gst_jpeg_dec_setcaps (GstJpegDec * dec, GstCaps * caps)
704 {
705   GstStructure *s;
706   const GValue *framerate;
707
708   s = gst_caps_get_structure (caps, 0);
709
710   if ((framerate = gst_structure_get_value (s, "framerate")) != NULL) {
711     dec->in_fps_n = gst_value_get_fraction_numerator (framerate);
712     dec->in_fps_d = gst_value_get_fraction_denominator (framerate);
713     dec->packetized = TRUE;
714     GST_DEBUG ("got framerate of %d/%d fps => packetized mode",
715         dec->in_fps_n, dec->in_fps_d);
716   }
717
718   /* do not extract width/height here. we do that in the chain
719    * function on a per-frame basis (including the line[] array
720    * setup) */
721
722   /* But we can take the framerate values and set them on the src pad */
723
724   return TRUE;
725 }
726
727 static GstCaps *
728 gst_jpeg_dec_getcaps (GstPad * pad, GstCaps * filter)
729 {
730   GstJpegDec *dec;
731   GstCaps *caps;
732   GstPad *peer;
733
734   dec = GST_JPEG_DEC (GST_OBJECT_PARENT (pad));
735
736   if (gst_pad_has_current_caps (pad))
737     return gst_pad_get_current_caps (pad);
738
739   peer = gst_pad_get_peer (dec->srcpad);
740
741   if (peer) {
742     GstCaps *peer_caps;
743     const GstCaps *templ_caps;
744     GstStructure *s;
745     guint i, n;
746
747     peer_caps = gst_pad_query_caps (peer, filter);
748
749     /* Translate peercaps to image/jpeg */
750     peer_caps = gst_caps_make_writable (peer_caps);
751     n = gst_caps_get_size (peer_caps);
752     for (i = 0; i < n; i++) {
753       s = gst_caps_get_structure (peer_caps, i);
754
755       gst_structure_set_name (s, "image/jpeg");
756     }
757
758     templ_caps = gst_pad_get_pad_template_caps (pad);
759     caps = gst_caps_intersect_full (peer_caps, templ_caps,
760         GST_CAPS_INTERSECT_FIRST);
761
762     gst_object_unref (peer);
763   } else {
764     caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
765   }
766
767   return caps;
768 }
769
770
771 /* yuk */
772 static void
773 hresamplecpy1 (guint8 * dest, const guint8 * src, guint len)
774 {
775   gint i;
776
777   for (i = 0; i < len; ++i) {
778     /* equivalent to: dest[i] = src[i << 1] */
779     *dest = *src;
780     ++dest;
781     ++src;
782     ++src;
783   }
784 }
785
786 static void
787 gst_jpeg_dec_free_buffers (GstJpegDec * dec)
788 {
789   gint i;
790
791   for (i = 0; i < 16; i++) {
792     g_free (dec->idr_y[i]);
793     g_free (dec->idr_u[i]);
794     g_free (dec->idr_v[i]);
795     dec->idr_y[i] = NULL;
796     dec->idr_u[i] = NULL;
797     dec->idr_v[i] = NULL;
798   }
799
800   dec->idr_width_allocated = 0;
801 }
802
803 static inline gboolean
804 gst_jpeg_dec_ensure_buffers (GstJpegDec * dec, guint maxrowbytes)
805 {
806   gint i;
807
808   if (G_LIKELY (dec->idr_width_allocated >= maxrowbytes))
809     return TRUE;
810
811   /* FIXME: maybe just alloc one or three blocks altogether? */
812   for (i = 0; i < 16; i++) {
813     dec->idr_y[i] = g_try_realloc (dec->idr_y[i], maxrowbytes);
814     dec->idr_u[i] = g_try_realloc (dec->idr_u[i], maxrowbytes);
815     dec->idr_v[i] = g_try_realloc (dec->idr_v[i], maxrowbytes);
816
817     if (G_UNLIKELY (!dec->idr_y[i] || !dec->idr_u[i] || !dec->idr_v[i])) {
818       GST_WARNING_OBJECT (dec, "out of memory, i=%d, bytes=%u", i, maxrowbytes);
819       return FALSE;
820     }
821   }
822
823   dec->idr_width_allocated = maxrowbytes;
824   GST_LOG_OBJECT (dec, "allocated temp memory, %u bytes/row", maxrowbytes);
825   return TRUE;
826 }
827
828 static void
829 gst_jpeg_dec_decode_grayscale (GstJpegDec * dec, GstVideoFrame * frame)
830 {
831   guchar *rows[16];
832   guchar **scanarray[1] = { rows };
833   gint i, j, k;
834   gint lines;
835   guint8 *base[1];
836   gint width, height;
837   gint pstride, rstride;
838
839   GST_DEBUG_OBJECT (dec, "indirect decoding of grayscale");
840
841   width = GST_VIDEO_FRAME_WIDTH (frame);
842   height = GST_VIDEO_FRAME_HEIGHT (frame);
843
844   if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
845     return;
846
847   base[0] = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
848   pstride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0);
849   rstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
850
851   memcpy (rows, dec->idr_y, 16 * sizeof (gpointer));
852
853   i = 0;
854   while (i < height) {
855     lines = jpeg_read_raw_data (&dec->cinfo, scanarray, DCTSIZE);
856     if (G_LIKELY (lines > 0)) {
857       for (j = 0; (j < DCTSIZE) && (i < height); j++, i++) {
858         gint p;
859
860         p = 0;
861         for (k = 0; k < width; k++) {
862           base[0][p] = rows[j][k];
863           p += pstride;
864         }
865         base[0] += rstride;
866       }
867     } else {
868       GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
869     }
870   }
871 }
872
873 static void
874 gst_jpeg_dec_decode_rgb (GstJpegDec * dec, GstVideoFrame * frame)
875 {
876   guchar *r_rows[16], *g_rows[16], *b_rows[16];
877   guchar **scanarray[3] = { r_rows, g_rows, b_rows };
878   gint i, j, k;
879   gint lines;
880   guint8 *base[3];
881   guint pstride, rstride;
882   gint width, height;
883
884   GST_DEBUG_OBJECT (dec, "indirect decoding of RGB");
885
886   width = GST_VIDEO_FRAME_WIDTH (frame);
887   height = GST_VIDEO_FRAME_HEIGHT (frame);
888
889   if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
890     return;
891
892   for (i = 0; i < 3; i++)
893     base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
894
895   pstride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0);
896   rstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
897
898   memcpy (r_rows, dec->idr_y, 16 * sizeof (gpointer));
899   memcpy (g_rows, dec->idr_u, 16 * sizeof (gpointer));
900   memcpy (b_rows, dec->idr_v, 16 * sizeof (gpointer));
901
902   i = 0;
903   while (i < height) {
904     lines = jpeg_read_raw_data (&dec->cinfo, scanarray, DCTSIZE);
905     if (G_LIKELY (lines > 0)) {
906       for (j = 0; (j < DCTSIZE) && (i < height); j++, i++) {
907         gint p;
908
909         p = 0;
910         for (k = 0; k < width; k++) {
911           base[0][p] = r_rows[j][k];
912           base[1][p] = g_rows[j][k];
913           base[2][p] = b_rows[j][k];
914           p += pstride;
915         }
916         base[0] += rstride;
917         base[1] += rstride;
918         base[2] += rstride;
919       }
920     } else {
921       GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
922     }
923   }
924 }
925
926 static void
927 gst_jpeg_dec_decode_indirect (GstJpegDec * dec, GstVideoFrame * frame,
928     gint r_v, gint r_h, gint comp)
929 {
930   guchar *y_rows[16], *u_rows[16], *v_rows[16];
931   guchar **scanarray[3] = { y_rows, u_rows, v_rows };
932   gint i, j, k;
933   gint lines;
934   guchar *base[3], *last[3];
935   gint stride[3];
936   gint width, height;
937
938   GST_DEBUG_OBJECT (dec,
939       "unadvantageous width or r_h, taking slow route involving memcpy");
940
941   width = GST_VIDEO_FRAME_WIDTH (frame);
942   height = GST_VIDEO_FRAME_HEIGHT (frame);
943
944   if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
945     return;
946
947   for (i = 0; i < 3; i++) {
948     base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
949     stride[i] = GST_VIDEO_FRAME_COMP_STRIDE (frame, i);
950     /* make sure we don't make jpeglib write beyond our buffer,
951      * which might happen if (height % (r_v*DCTSIZE)) != 0 */
952     last[i] = base[i] + (GST_VIDEO_FRAME_COMP_STRIDE (frame, i) *
953         (GST_VIDEO_FRAME_COMP_HEIGHT (frame, i) - 1));
954   }
955
956   memcpy (y_rows, dec->idr_y, 16 * sizeof (gpointer));
957   memcpy (u_rows, dec->idr_u, 16 * sizeof (gpointer));
958   memcpy (v_rows, dec->idr_v, 16 * sizeof (gpointer));
959
960   /* fill chroma components for grayscale */
961   if (comp == 1) {
962     GST_DEBUG_OBJECT (dec, "grayscale, filling chroma");
963     for (i = 0; i < 16; i++) {
964       memset (u_rows[i], GST_ROUND_UP_32 (width), 0x80);
965       memset (v_rows[i], GST_ROUND_UP_32 (width), 0x80);
966     }
967   }
968
969   for (i = 0; i < height; i += r_v * DCTSIZE) {
970     lines = jpeg_read_raw_data (&dec->cinfo, scanarray, r_v * DCTSIZE);
971     if (G_LIKELY (lines > 0)) {
972       for (j = 0, k = 0; j < (r_v * DCTSIZE); j += r_v, k++) {
973         if (G_LIKELY (base[0] <= last[0])) {
974           memcpy (base[0], y_rows[j], stride[0]);
975           base[0] += stride[0];
976         }
977         if (r_v == 2) {
978           if (G_LIKELY (base[0] <= last[0])) {
979             memcpy (base[0], y_rows[j + 1], stride[0]);
980             base[0] += stride[0];
981           }
982         }
983         if (G_LIKELY (base[1] <= last[1] && base[2] <= last[2])) {
984           if (r_h == 2) {
985             memcpy (base[1], u_rows[k], stride[1]);
986             memcpy (base[2], v_rows[k], stride[2]);
987           } else if (r_h == 1) {
988             hresamplecpy1 (base[1], u_rows[k], stride[1]);
989             hresamplecpy1 (base[2], v_rows[k], stride[2]);
990           } else {
991             /* FIXME: implement (at least we avoid crashing by doing nothing) */
992           }
993         }
994
995         if (r_v == 2 || (k & 1) != 0) {
996           base[1] += stride[1];
997           base[2] += stride[2];
998         }
999       }
1000     } else {
1001       GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
1002     }
1003   }
1004 }
1005
1006 static GstFlowReturn
1007 gst_jpeg_dec_decode_direct (GstJpegDec * dec, GstVideoFrame * frame)
1008 {
1009   guchar **line[3];             /* the jpeg line buffer         */
1010   guchar *y[4 * DCTSIZE] = { NULL, };   /* alloc enough for the lines   */
1011   guchar *u[4 * DCTSIZE] = { NULL, };   /* r_v will be <4               */
1012   guchar *v[4 * DCTSIZE] = { NULL, };
1013   gint i, j;
1014   gint lines, v_samp[3];
1015   guchar *base[3], *last[3];
1016   gint stride[3];
1017   guint height;
1018
1019   line[0] = y;
1020   line[1] = u;
1021   line[2] = v;
1022
1023   v_samp[0] = dec->cinfo.comp_info[0].v_samp_factor;
1024   v_samp[1] = dec->cinfo.comp_info[1].v_samp_factor;
1025   v_samp[2] = dec->cinfo.comp_info[2].v_samp_factor;
1026
1027   if (G_UNLIKELY (v_samp[0] > 2 || v_samp[1] > 2 || v_samp[2] > 2))
1028     goto format_not_supported;
1029
1030   height = GST_VIDEO_FRAME_HEIGHT (frame);
1031
1032   for (i = 0; i < 3; i++) {
1033     base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
1034     stride[i] = GST_VIDEO_FRAME_COMP_STRIDE (frame, i);
1035     /* make sure we don't make jpeglib write beyond our buffer,
1036      * which might happen if (height % (r_v*DCTSIZE)) != 0 */
1037     last[i] = base[i] + (GST_VIDEO_FRAME_COMP_STRIDE (frame, i) *
1038         (GST_VIDEO_FRAME_COMP_HEIGHT (frame, i) - 1));
1039   }
1040
1041   /* let jpeglib decode directly into our final buffer */
1042   GST_DEBUG_OBJECT (dec, "decoding directly into output buffer");
1043
1044   for (i = 0; i < height; i += v_samp[0] * DCTSIZE) {
1045     for (j = 0; j < (v_samp[0] * DCTSIZE); ++j) {
1046       /* Y */
1047       line[0][j] = base[0] + (i + j) * stride[0];
1048       if (G_UNLIKELY (line[0][j] > last[0]))
1049         line[0][j] = last[0];
1050       /* U */
1051       if (v_samp[1] == v_samp[0]) {
1052         line[1][j] = base[1] + ((i + j) / 2) * stride[1];
1053       } else if (j < (v_samp[1] * DCTSIZE)) {
1054         line[1][j] = base[1] + ((i / 2) + j) * stride[1];
1055       }
1056       if (G_UNLIKELY (line[1][j] > last[1]))
1057         line[1][j] = last[1];
1058       /* V */
1059       if (v_samp[2] == v_samp[0]) {
1060         line[2][j] = base[2] + ((i + j) / 2) * stride[2];
1061       } else if (j < (v_samp[2] * DCTSIZE)) {
1062         line[2][j] = base[2] + ((i / 2) + j) * stride[2];
1063       }
1064       if (G_UNLIKELY (line[2][j] > last[2]))
1065         line[2][j] = last[2];
1066     }
1067
1068     lines = jpeg_read_raw_data (&dec->cinfo, line, v_samp[0] * DCTSIZE);
1069     if (G_UNLIKELY (!lines)) {
1070       GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
1071     }
1072   }
1073   return GST_FLOW_OK;
1074
1075 format_not_supported:
1076   {
1077     gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1078         "Unsupported subsampling schema: v_samp factors: %u %u %u",
1079         v_samp[0], v_samp[1], v_samp[2]);
1080     return GST_FLOW_ERROR;
1081   }
1082 }
1083
1084 static void
1085 gst_jpeg_dec_update_qos (GstJpegDec * dec, gdouble proportion,
1086     GstClockTimeDiff diff, GstClockTime ts)
1087 {
1088   GST_OBJECT_LOCK (dec);
1089   dec->proportion = proportion;
1090   if (G_LIKELY (ts != GST_CLOCK_TIME_NONE)) {
1091     if (G_UNLIKELY (diff > dec->qos_duration))
1092       dec->earliest_time = ts + 2 * diff + dec->qos_duration;
1093     else
1094       dec->earliest_time = ts + diff;
1095   } else {
1096     dec->earliest_time = GST_CLOCK_TIME_NONE;
1097   }
1098   GST_OBJECT_UNLOCK (dec);
1099 }
1100
1101 static void
1102 gst_jpeg_dec_reset_qos (GstJpegDec * dec)
1103 {
1104   gst_jpeg_dec_update_qos (dec, 0.5, 0, GST_CLOCK_TIME_NONE);
1105 }
1106
1107 static void
1108 gst_jpeg_dec_read_qos (GstJpegDec * dec, gdouble * proportion,
1109     GstClockTime * time)
1110 {
1111   GST_OBJECT_LOCK (dec);
1112   *proportion = dec->proportion;
1113   *time = dec->earliest_time;
1114   GST_OBJECT_UNLOCK (dec);
1115 }
1116
1117 /* Perform qos calculations before decoding the next frame. Returns TRUE if the
1118  * frame should be decoded, FALSE if the frame can be dropped entirely */
1119 static gboolean
1120 gst_jpeg_dec_do_qos (GstJpegDec * dec, GstClockTime timestamp)
1121 {
1122   GstClockTime qostime, earliest_time;
1123   gdouble proportion;
1124
1125   /* no timestamp, can't do QoS => decode frame */
1126   if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (timestamp))) {
1127     GST_LOG_OBJECT (dec, "invalid timestamp, can't do QoS, decode frame");
1128     return TRUE;
1129   }
1130
1131   /* get latest QoS observation values */
1132   gst_jpeg_dec_read_qos (dec, &proportion, &earliest_time);
1133
1134   /* skip qos if we have no observation (yet) => decode frame */
1135   if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (earliest_time))) {
1136     GST_LOG_OBJECT (dec, "no observation yet, decode frame");
1137     return TRUE;
1138   }
1139
1140   /* qos is done on running time */
1141   qostime = gst_segment_to_running_time (&dec->segment, GST_FORMAT_TIME,
1142       timestamp);
1143
1144   /* see how our next timestamp relates to the latest qos timestamp */
1145   GST_LOG_OBJECT (dec, "qostime %" GST_TIME_FORMAT ", earliest %"
1146       GST_TIME_FORMAT, GST_TIME_ARGS (qostime), GST_TIME_ARGS (earliest_time));
1147
1148   if (qostime != GST_CLOCK_TIME_NONE && qostime <= earliest_time) {
1149     GST_DEBUG_OBJECT (dec, "we are late, drop frame");
1150     return FALSE;
1151   }
1152
1153   GST_LOG_OBJECT (dec, "decode frame");
1154   return TRUE;
1155 }
1156
1157 static gboolean
1158 gst_jpeg_dec_buffer_pool (GstJpegDec * dec, GstCaps * caps)
1159 {
1160   GstQuery *query;
1161   GstBufferPool *pool = NULL;
1162   guint size, min, max, prefix, alignment;
1163   GstStructure *config;
1164
1165   GST_DEBUG_OBJECT (dec, "setting up bufferpool");
1166
1167   /* find a pool for the negotiated caps now */
1168   query = gst_query_new_allocation (caps, TRUE);
1169
1170   if (gst_pad_peer_query (dec->srcpad, query)) {
1171     /* we got configuration from our peer, parse them */
1172     gst_query_parse_allocation_params (query, &size, &min, &max, &prefix,
1173         &alignment, &pool);
1174     size = MAX (size, dec->info.size);
1175   } else {
1176     GST_DEBUG_OBJECT (dec, "peer query failed, using defaults");
1177     size = dec->info.size;
1178     min = max = 0;
1179     prefix = 0;
1180     alignment = 15;
1181   }
1182   gst_query_unref (query);
1183
1184   if (pool == NULL) {
1185     /* we did not get a pool, make one ourselves then */
1186     pool = gst_buffer_pool_new ();
1187   }
1188
1189   config = gst_buffer_pool_get_config (pool);
1190   gst_buffer_pool_config_set (config, caps, size, min, max, prefix,
1191       alignment | 15);
1192   /* and store */
1193   gst_buffer_pool_set_config (pool, config);
1194
1195   if (dec->pool) {
1196     gst_buffer_pool_set_active (dec->pool, FALSE);
1197     gst_object_unref (dec->pool);
1198   }
1199   dec->pool = pool;
1200
1201   /* and activate */
1202   gst_buffer_pool_set_active (pool, TRUE);
1203
1204   return TRUE;
1205 }
1206
1207 static gboolean
1208 gst_jpeg_dec_negotiate (GstJpegDec * dec, gint width, gint height, gint clrspc)
1209 {
1210   GstCaps *caps;
1211   GstVideoFormat format;
1212   GstVideoInfo info;
1213
1214   if (G_UNLIKELY (width == dec->info.width && height == dec->info.height &&
1215           dec->in_fps_n == dec->info.fps_n && dec->in_fps_d == dec->info.fps_d
1216           && clrspc == dec->clrspc))
1217     return TRUE;
1218
1219   gst_video_info_init (&info);
1220
1221   /* framerate == 0/1 is a still frame */
1222   if (dec->in_fps_d == 0) {
1223     info.fps_n = 0;
1224     info.fps_d = 1;
1225   } else {
1226     info.fps_n = dec->in_fps_n;
1227     info.fps_d = dec->in_fps_d;
1228   }
1229
1230   /* calculate or assume an average frame duration for QoS purposes */
1231   GST_OBJECT_LOCK (dec);
1232   if (info.fps_n != 0) {
1233     dec->qos_duration =
1234         gst_util_uint64_scale (GST_SECOND, info.fps_d, info.fps_n);
1235     dec->duration = dec->qos_duration;
1236   } else {
1237     /* if not set just use 25fps */
1238     dec->qos_duration = gst_util_uint64_scale (GST_SECOND, 1, 25);
1239     dec->duration = GST_CLOCK_TIME_NONE;
1240   }
1241   GST_OBJECT_UNLOCK (dec);
1242
1243   if (dec->cinfo.jpeg_color_space == JCS_RGB) {
1244     gint i;
1245     GstCaps *allowed_caps;
1246     GstVideoInfo tmpinfo;
1247
1248     GST_DEBUG_OBJECT (dec, "selecting RGB format");
1249     /* retrieve allowed caps, and find the first one that reasonably maps
1250      * to the parameters of the colourspace */
1251     caps = gst_pad_get_allowed_caps (dec->srcpad);
1252     if (!caps) {
1253       GST_DEBUG_OBJECT (dec, "... but no peer, using template caps");
1254       /* need to copy because get_allowed_caps returns a ref,
1255        * and get_pad_template_caps doesn't */
1256       caps = gst_caps_copy (gst_pad_get_pad_template_caps (dec->srcpad));
1257     }
1258     /* avoid lists of formats, etc */
1259     allowed_caps = gst_caps_normalize (caps);
1260     gst_caps_unref (caps);
1261     caps = NULL;
1262     GST_LOG_OBJECT (dec, "allowed source caps %" GST_PTR_FORMAT, allowed_caps);
1263
1264     for (i = 0; i < gst_caps_get_size (allowed_caps); i++) {
1265       if (caps)
1266         gst_caps_unref (caps);
1267       caps = gst_caps_copy_nth (allowed_caps, i);
1268       /* sigh, ds and _parse_caps need fixed caps for parsing, fixate */
1269       gst_caps_fixate (caps);
1270       GST_LOG_OBJECT (dec, "checking caps %" GST_PTR_FORMAT, caps);
1271
1272       if (!gst_video_info_from_caps (&tmpinfo, caps))
1273         continue;
1274       /* we'll settle for the first (preferred) downstream rgb format */
1275       if (GST_VIDEO_INFO_IS_RGB (&tmpinfo))
1276         break;
1277       /* default fall-back */
1278       format = GST_VIDEO_FORMAT_RGB;
1279     }
1280     if (caps)
1281       gst_caps_unref (caps);
1282     gst_caps_unref (allowed_caps);
1283   } else if (dec->cinfo.jpeg_color_space == JCS_GRAYSCALE) {
1284     /* TODO is anything else then 8bit supported in jpeg? */
1285     format = GST_VIDEO_FORMAT_GRAY8;
1286   } else {
1287     /* go for plain and simple I420 */
1288     /* TODO other YUV cases ? */
1289     format = GST_VIDEO_FORMAT_I420;
1290   }
1291
1292   gst_video_info_set_format (&info, format, width, height);
1293   caps = gst_video_info_to_caps (&info);
1294
1295   GST_DEBUG_OBJECT (dec, "setting caps %" GST_PTR_FORMAT, caps);
1296   GST_DEBUG_OBJECT (dec, "max_v_samp_factor=%d", dec->cinfo.max_v_samp_factor);
1297   GST_DEBUG_OBJECT (dec, "max_h_samp_factor=%d", dec->cinfo.max_h_samp_factor);
1298
1299   gst_pad_set_caps (dec->srcpad, caps);
1300
1301   dec->info = info;
1302   dec->clrspc = clrspc;
1303
1304   gst_jpeg_dec_buffer_pool (dec, caps);
1305   gst_caps_unref (caps);
1306
1307   return TRUE;
1308 }
1309
1310 static GstFlowReturn
1311 gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf)
1312 {
1313   GstFlowReturn ret = GST_FLOW_OK;
1314   GstJpegDec *dec;
1315   GstBuffer *outbuf = NULL;
1316   gint img_len;
1317   gint width, height;
1318   gint r_h, r_v;
1319   guint code, hdr_ok;
1320   GstClockTime timestamp, duration;
1321   GstVideoFrame frame;
1322
1323   dec = GST_JPEG_DEC (GST_PAD_PARENT (pad));
1324
1325   timestamp = GST_BUFFER_TIMESTAMP (buf);
1326   duration = GST_BUFFER_DURATION (buf);
1327
1328   if (GST_CLOCK_TIME_IS_VALID (timestamp))
1329     dec->next_ts = timestamp;
1330
1331   if (GST_BUFFER_IS_DISCONT (buf)) {
1332     GST_DEBUG_OBJECT (dec, "buffer has DISCONT flag set");
1333     dec->discont = TRUE;
1334     if (!dec->packetized && gst_adapter_available (dec->adapter)) {
1335       GST_WARNING_OBJECT (dec, "DISCONT buffer in non-packetized mode, bad");
1336       gst_adapter_clear (dec->adapter);
1337     }
1338   }
1339
1340   gst_adapter_push (dec->adapter, buf);
1341   buf = NULL;
1342
1343   /* If we are non-packetized and know the total incoming size in bytes,
1344    * just wait until we have enough before doing any processing. */
1345
1346   if (!dec->packetized && (dec->segment.format == GST_FORMAT_BYTES) &&
1347       (dec->segment.stop != -1) &&
1348       (gst_adapter_available (dec->adapter) < dec->segment.stop)) {
1349     /* We assume that non-packetized input in bytes is *one* single jpeg image */
1350     GST_DEBUG ("Non-packetized mode. Got %d bytes, need %" G_GINT64_FORMAT,
1351         gst_adapter_available (dec->adapter), dec->segment.stop);
1352     goto need_more_data;
1353   }
1354
1355 again:
1356   if (!gst_jpeg_dec_ensure_header (dec))
1357     goto need_more_data;
1358
1359   /* If we know that each input buffer contains data
1360    * for a whole jpeg image (e.g. MJPEG streams), just 
1361    * do some sanity checking instead of parsing all of 
1362    * the jpeg data */
1363   if (dec->packetized) {
1364     img_len = gst_adapter_available (dec->adapter);
1365   } else {
1366     /* Parse jpeg image to handle jpeg input that
1367      * is not aligned to buffer boundaries */
1368     img_len = gst_jpeg_dec_parse_image_data (dec);
1369
1370     if (img_len == 0) {
1371       goto need_more_data;
1372     } else if (img_len < 0) {
1373       gst_adapter_flush (dec->adapter, -img_len);
1374       goto again;
1375     }
1376   }
1377
1378   dec->rem_img_len = img_len;
1379
1380   GST_LOG_OBJECT (dec, "image size = %u", img_len);
1381
1382   /* QoS: if we're too late anyway, skip decoding */
1383   if (dec->packetized && !gst_jpeg_dec_do_qos (dec, timestamp))
1384     goto skip_decoding;
1385
1386 #ifndef GST_DISABLE_GST_DEBUG
1387   {
1388     guchar data[4];
1389
1390     gst_adapter_copy (dec->adapter, data, 0, 4);
1391     GST_LOG_OBJECT (dec, "reading header %02x %02x %02x %02x", data[0], data[1],
1392         data[2], data[3]);
1393   }
1394 #endif
1395
1396   gst_jpeg_dec_fill_input_buffer (&dec->cinfo);
1397
1398   if (setjmp (dec->jerr.setjmp_buffer)) {
1399     code = dec->jerr.pub.msg_code;
1400
1401     if (code == JERR_INPUT_EOF) {
1402       GST_DEBUG ("jpeg input EOF error, we probably need more data");
1403       goto need_more_data;
1404     }
1405     goto decode_error;
1406   }
1407
1408   /* read header */
1409   hdr_ok = jpeg_read_header (&dec->cinfo, TRUE);
1410   if (G_UNLIKELY (hdr_ok != JPEG_HEADER_OK)) {
1411     GST_WARNING_OBJECT (dec, "reading the header failed, %d", hdr_ok);
1412   }
1413
1414   GST_LOG_OBJECT (dec, "num_components=%d", dec->cinfo.num_components);
1415   GST_LOG_OBJECT (dec, "jpeg_color_space=%d", dec->cinfo.jpeg_color_space);
1416
1417   if (!dec->cinfo.num_components || !dec->cinfo.comp_info)
1418     goto components_not_supported;
1419
1420   r_h = dec->cinfo.comp_info[0].h_samp_factor;
1421   r_v = dec->cinfo.comp_info[0].v_samp_factor;
1422
1423   GST_LOG_OBJECT (dec, "r_h = %d, r_v = %d", r_h, r_v);
1424
1425   if (dec->cinfo.num_components > 3)
1426     goto components_not_supported;
1427
1428   /* verify color space expectation to avoid going *boom* or bogus output */
1429   if (dec->cinfo.jpeg_color_space != JCS_YCbCr &&
1430       dec->cinfo.jpeg_color_space != JCS_GRAYSCALE &&
1431       dec->cinfo.jpeg_color_space != JCS_RGB)
1432     goto unsupported_colorspace;
1433
1434 #ifndef GST_DISABLE_GST_DEBUG
1435   {
1436     gint i;
1437
1438     for (i = 0; i < dec->cinfo.num_components; ++i) {
1439       GST_LOG_OBJECT (dec, "[%d] h_samp_factor=%d, v_samp_factor=%d, cid=%d",
1440           i, dec->cinfo.comp_info[i].h_samp_factor,
1441           dec->cinfo.comp_info[i].v_samp_factor,
1442           dec->cinfo.comp_info[i].component_id);
1443     }
1444   }
1445 #endif
1446
1447   /* prepare for raw output */
1448   dec->cinfo.do_fancy_upsampling = FALSE;
1449   dec->cinfo.do_block_smoothing = FALSE;
1450   dec->cinfo.out_color_space = dec->cinfo.jpeg_color_space;
1451   dec->cinfo.dct_method = dec->idct_method;
1452   dec->cinfo.raw_data_out = TRUE;
1453
1454   GST_LOG_OBJECT (dec, "starting decompress");
1455   guarantee_huff_tables (&dec->cinfo);
1456   if (!jpeg_start_decompress (&dec->cinfo)) {
1457     GST_WARNING_OBJECT (dec, "failed to start decompression cycle");
1458   }
1459
1460   /* sanity checks to get safe and reasonable output */
1461   switch (dec->cinfo.jpeg_color_space) {
1462     case JCS_GRAYSCALE:
1463       if (dec->cinfo.num_components != 1)
1464         goto invalid_yuvrgbgrayscale;
1465       break;
1466     case JCS_RGB:
1467       if (dec->cinfo.num_components != 3 || dec->cinfo.max_v_samp_factor > 1 ||
1468           dec->cinfo.max_h_samp_factor > 1)
1469         goto invalid_yuvrgbgrayscale;
1470       break;
1471     case JCS_YCbCr:
1472       if (dec->cinfo.num_components != 3 ||
1473           r_v > 2 || r_v < dec->cinfo.comp_info[0].v_samp_factor ||
1474           r_v < dec->cinfo.comp_info[1].v_samp_factor ||
1475           r_h < dec->cinfo.comp_info[0].h_samp_factor ||
1476           r_h < dec->cinfo.comp_info[1].h_samp_factor)
1477         goto invalid_yuvrgbgrayscale;
1478       break;
1479     default:
1480       g_assert_not_reached ();
1481       break;
1482   }
1483
1484   width = dec->cinfo.output_width;
1485   height = dec->cinfo.output_height;
1486
1487   if (G_UNLIKELY (width < MIN_WIDTH || width > MAX_WIDTH ||
1488           height < MIN_HEIGHT || height > MAX_HEIGHT))
1489     goto wrong_size;
1490
1491   gst_jpeg_dec_negotiate (dec, width, height, dec->cinfo.jpeg_color_space);
1492
1493   ret = gst_buffer_pool_acquire_buffer (dec->pool, &outbuf, NULL);
1494   if (G_UNLIKELY (ret != GST_FLOW_OK))
1495     goto alloc_failed;
1496
1497   if (!gst_video_frame_map (&frame, &dec->info, outbuf, GST_MAP_READWRITE))
1498     goto invalid_frame;
1499
1500   GST_LOG_OBJECT (dec, "width %d, height %d", width, height);
1501
1502   GST_BUFFER_TIMESTAMP (outbuf) = dec->next_ts;
1503
1504   if (dec->packetized && GST_CLOCK_TIME_IS_VALID (dec->next_ts)) {
1505     if (GST_CLOCK_TIME_IS_VALID (duration)) {
1506       /* use duration from incoming buffer for outgoing buffer */
1507       dec->next_ts += duration;
1508     } else if (GST_CLOCK_TIME_IS_VALID (dec->duration)) {
1509       duration = dec->duration;
1510       dec->next_ts += dec->duration;
1511     } else {
1512       duration = GST_CLOCK_TIME_NONE;
1513       dec->next_ts = GST_CLOCK_TIME_NONE;
1514     }
1515   } else {
1516     duration = GST_CLOCK_TIME_NONE;
1517     dec->next_ts = GST_CLOCK_TIME_NONE;
1518   }
1519   GST_BUFFER_DURATION (outbuf) = duration;
1520
1521   if (dec->cinfo.jpeg_color_space == JCS_RGB) {
1522     gst_jpeg_dec_decode_rgb (dec, &frame);
1523   } else if (dec->cinfo.jpeg_color_space == JCS_GRAYSCALE) {
1524     gst_jpeg_dec_decode_grayscale (dec, &frame);
1525   } else {
1526     GST_LOG_OBJECT (dec, "decompressing (reqired scanline buffer height = %u)",
1527         dec->cinfo.rec_outbuf_height);
1528
1529     /* For some widths jpeglib requires more horizontal padding than I420 
1530      * provides. In those cases we need to decode into separate buffers and then
1531      * copy over the data into our final picture buffer, otherwise jpeglib might
1532      * write over the end of a line into the beginning of the next line,
1533      * resulting in blocky artifacts on the left side of the picture. */
1534     if (G_UNLIKELY (width % (dec->cinfo.max_h_samp_factor * DCTSIZE) != 0
1535             || dec->cinfo.comp_info[0].h_samp_factor != 2
1536             || dec->cinfo.comp_info[1].h_samp_factor != 1
1537             || dec->cinfo.comp_info[2].h_samp_factor != 1)) {
1538       GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, dec,
1539           "indirect decoding using extra buffer copy");
1540       gst_jpeg_dec_decode_indirect (dec, &frame, r_v, r_h,
1541           dec->cinfo.num_components);
1542     } else {
1543       ret = gst_jpeg_dec_decode_direct (dec, &frame);
1544       if (G_UNLIKELY (ret != GST_FLOW_OK))
1545         goto decode_direct_failed;
1546     }
1547   }
1548
1549   GST_LOG_OBJECT (dec, "decompressing finished");
1550   jpeg_finish_decompress (&dec->cinfo);
1551
1552   gst_video_frame_unmap (&frame);
1553
1554   /* Clipping */
1555   if (dec->segment.format == GST_FORMAT_TIME) {
1556     guint64 start, stop, clip_start, clip_stop;
1557
1558     GST_LOG_OBJECT (dec, "Attempting clipping");
1559
1560     start = GST_BUFFER_TIMESTAMP (outbuf);
1561     if (GST_BUFFER_DURATION (outbuf) == GST_CLOCK_TIME_NONE)
1562       stop = start;
1563     else
1564       stop = start + GST_BUFFER_DURATION (outbuf);
1565
1566     if (gst_segment_clip (&dec->segment, GST_FORMAT_TIME,
1567             start, stop, &clip_start, &clip_stop)) {
1568       GST_LOG_OBJECT (dec, "Clipping start to %" GST_TIME_FORMAT,
1569           GST_TIME_ARGS (clip_start));
1570       GST_BUFFER_TIMESTAMP (outbuf) = clip_start;
1571       if (GST_BUFFER_DURATION (outbuf) != GST_CLOCK_TIME_NONE) {
1572         GST_LOG_OBJECT (dec, "Clipping duration to %" GST_TIME_FORMAT,
1573             GST_TIME_ARGS (clip_stop - clip_start));
1574         GST_BUFFER_DURATION (outbuf) = clip_stop - clip_start;
1575       }
1576     } else
1577       goto drop_buffer;
1578   }
1579
1580   /* reset error count on successful decode */
1581   dec->error_count = 0;
1582
1583   ++dec->good_count;
1584
1585   GST_LOG_OBJECT (dec, "pushing buffer (ts=%" GST_TIME_FORMAT ", dur=%"
1586       GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
1587       GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
1588
1589   ret = gst_pad_push (dec->srcpad, outbuf);
1590
1591 skip_decoding:
1592 done:
1593   gst_adapter_flush (dec->adapter, dec->rem_img_len);
1594
1595 exit:
1596
1597   if (G_UNLIKELY (ret == GST_FLOW_ERROR)) {
1598     jpeg_abort_decompress (&dec->cinfo);
1599     ret = gst_jpeg_dec_post_error_or_warning (dec);
1600   }
1601
1602   return ret;
1603
1604   /* special cases */
1605 need_more_data:
1606   {
1607     GST_LOG_OBJECT (dec, "we need more data");
1608     if (outbuf) {
1609       gst_buffer_unref (outbuf);
1610       outbuf = NULL;
1611     }
1612     ret = GST_FLOW_OK;
1613     goto exit;
1614   }
1615   /* ERRORS */
1616 wrong_size:
1617   {
1618     gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1619         "Picture is too small or too big (%ux%u)", width, height);
1620     ret = GST_FLOW_ERROR;
1621     goto done;
1622   }
1623 decode_error:
1624   {
1625     gchar err_msg[JMSG_LENGTH_MAX];
1626
1627     dec->jerr.pub.format_message ((j_common_ptr) (&dec->cinfo), err_msg);
1628
1629     gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1630         "Decode error #%u: %s", code, err_msg);
1631
1632     if (outbuf) {
1633       gst_buffer_unref (outbuf);
1634       outbuf = NULL;
1635     }
1636     ret = GST_FLOW_ERROR;
1637     goto done;
1638   }
1639 decode_direct_failed:
1640   {
1641     /* already posted an error message */
1642     jpeg_abort_decompress (&dec->cinfo);
1643     gst_buffer_replace (&outbuf, NULL);
1644     goto done;
1645   }
1646 alloc_failed:
1647   {
1648     const gchar *reason;
1649
1650     reason = gst_flow_get_name (ret);
1651
1652     GST_DEBUG_OBJECT (dec, "failed to alloc buffer, reason %s", reason);
1653     /* Reset for next time */
1654     jpeg_abort_decompress (&dec->cinfo);
1655     if (ret != GST_FLOW_UNEXPECTED && ret != GST_FLOW_WRONG_STATE &&
1656         ret != GST_FLOW_NOT_LINKED) {
1657       gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1658           "Buffer allocation failed, reason: %s", reason);
1659     }
1660     goto exit;
1661   }
1662 invalid_frame:
1663   {
1664     jpeg_abort_decompress (&dec->cinfo);
1665     gst_buffer_unref (outbuf);
1666     ret = GST_FLOW_OK;
1667     goto exit;
1668   }
1669 drop_buffer:
1670   {
1671     GST_WARNING_OBJECT (dec, "Outgoing buffer is outside configured segment");
1672     gst_buffer_unref (outbuf);
1673     ret = GST_FLOW_OK;
1674     goto exit;
1675   }
1676 components_not_supported:
1677   {
1678     gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1679         "number of components not supported: %d (max 3)",
1680         dec->cinfo.num_components);
1681     ret = GST_FLOW_ERROR;
1682     goto done;
1683   }
1684 unsupported_colorspace:
1685   {
1686     gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1687         "Picture has unknown or unsupported colourspace");
1688     ret = GST_FLOW_ERROR;
1689     goto done;
1690   }
1691 invalid_yuvrgbgrayscale:
1692   {
1693     gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1694         "Picture is corrupt or unhandled YUV/RGB/grayscale layout");
1695     ret = GST_FLOW_ERROR;
1696     goto done;
1697   }
1698 }
1699
1700 static gboolean
1701 gst_jpeg_dec_src_event (GstPad * pad, GstEvent * event)
1702 {
1703   GstJpegDec *dec;
1704   gboolean res;
1705
1706   dec = GST_JPEG_DEC (gst_pad_get_parent (pad));
1707   if (G_UNLIKELY (dec == NULL)) {
1708     gst_event_unref (event);
1709     return FALSE;
1710   }
1711
1712   switch (GST_EVENT_TYPE (event)) {
1713     case GST_EVENT_QOS:{
1714       GstQOSType type;
1715       GstClockTimeDiff diff;
1716       GstClockTime timestamp;
1717       gdouble proportion;
1718
1719       gst_event_parse_qos (event, &type, &proportion, &diff, &timestamp);
1720       gst_jpeg_dec_update_qos (dec, proportion, diff, timestamp);
1721       break;
1722     }
1723     default:
1724       break;
1725   }
1726
1727   res = gst_pad_push_event (dec->sinkpad, event);
1728
1729   gst_object_unref (dec);
1730   return res;
1731 }
1732
1733 static gboolean
1734 gst_jpeg_dec_sink_event (GstPad * pad, GstEvent * event)
1735 {
1736   gboolean ret = TRUE, forward = TRUE;
1737   GstJpegDec *dec = GST_JPEG_DEC (GST_OBJECT_PARENT (pad));
1738
1739   GST_DEBUG_OBJECT (dec, "event : %s", GST_EVENT_TYPE_NAME (event));
1740
1741   switch (GST_EVENT_TYPE (event)) {
1742     case GST_EVENT_FLUSH_STOP:
1743       GST_DEBUG_OBJECT (dec, "Aborting decompress");
1744       jpeg_abort_decompress (&dec->cinfo);
1745       gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED);
1746       gst_adapter_clear (dec->adapter);
1747       g_free (dec->cur_buf);
1748       dec->cur_buf = NULL;
1749       dec->parse_offset = 0;
1750       dec->parse_entropy_len = 0;
1751       dec->parse_resync = FALSE;
1752       gst_jpeg_dec_reset_qos (dec);
1753       break;
1754     case GST_EVENT_SEGMENT:
1755       gst_event_copy_segment (event, &dec->segment);
1756       GST_DEBUG_OBJECT (dec, "Got NEWSEGMENT %" GST_SEGMENT_FORMAT,
1757           &dec->segment);
1758       break;
1759     case GST_EVENT_CAPS:
1760     {
1761       GstCaps *caps;
1762
1763       gst_event_parse_caps (event, &caps);
1764       ret = gst_jpeg_dec_setcaps (dec, caps);
1765       forward = FALSE;
1766       break;
1767     }
1768     default:
1769       break;
1770   }
1771
1772   if (forward)
1773     ret = gst_pad_push_event (dec->srcpad, event);
1774   else
1775     gst_event_unref (event);
1776
1777   return ret;
1778 }
1779
1780 static gboolean
1781 gst_jpeg_dec_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
1782 {
1783   gboolean res = FALSE;
1784
1785   switch (GST_QUERY_TYPE (query)) {
1786     case GST_QUERY_CAPS:
1787     {
1788       GstCaps *filter, *caps;
1789
1790       gst_query_parse_caps (query, &filter);
1791       caps = gst_jpeg_dec_getcaps (pad, filter);
1792       gst_query_set_caps_result (query, caps);
1793       gst_caps_unref (caps);
1794       res = TRUE;
1795       break;
1796     }
1797     default:
1798       res = gst_pad_query_default (pad, parent, query);
1799       break;
1800   }
1801   return res;
1802 }
1803
1804 static void
1805 gst_jpeg_dec_set_property (GObject * object, guint prop_id,
1806     const GValue * value, GParamSpec * pspec)
1807 {
1808   GstJpegDec *dec;
1809
1810   dec = GST_JPEG_DEC (object);
1811
1812   switch (prop_id) {
1813     case PROP_IDCT_METHOD:
1814       dec->idct_method = g_value_get_enum (value);
1815       break;
1816     case PROP_MAX_ERRORS:
1817       g_atomic_int_set (&dec->max_errors, g_value_get_int (value));
1818       break;
1819
1820     default:
1821       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1822       break;
1823   }
1824 }
1825
1826 static void
1827 gst_jpeg_dec_get_property (GObject * object, guint prop_id, GValue * value,
1828     GParamSpec * pspec)
1829 {
1830   GstJpegDec *dec;
1831
1832   dec = GST_JPEG_DEC (object);
1833
1834   switch (prop_id) {
1835     case PROP_IDCT_METHOD:
1836       g_value_set_enum (value, dec->idct_method);
1837       break;
1838     case PROP_MAX_ERRORS:
1839       g_value_set_int (value, g_atomic_int_get (&dec->max_errors));
1840       break;
1841
1842     default:
1843       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1844       break;
1845   }
1846 }
1847
1848 static GstStateChangeReturn
1849 gst_jpeg_dec_change_state (GstElement * element, GstStateChange transition)
1850 {
1851   GstStateChangeReturn ret;
1852   GstJpegDec *dec;
1853
1854   dec = GST_JPEG_DEC (element);
1855
1856   switch (transition) {
1857     case GST_STATE_CHANGE_READY_TO_PAUSED:
1858       dec->error_count = 0;
1859       dec->good_count = 0;
1860       dec->in_fps_n = 0;
1861       dec->in_fps_d = 1;
1862       gst_video_info_init (&dec->info);
1863       dec->clrspc = -1;
1864       dec->packetized = FALSE;
1865       dec->next_ts = 0;
1866       dec->discont = TRUE;
1867       dec->parse_offset = 0;
1868       dec->parse_entropy_len = 0;
1869       dec->parse_resync = FALSE;
1870       dec->cur_buf = NULL;
1871       gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED);
1872       gst_jpeg_dec_reset_qos (dec);
1873     default:
1874       break;
1875   }
1876
1877   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1878   if (ret != GST_STATE_CHANGE_SUCCESS)
1879     return ret;
1880
1881   switch (transition) {
1882     case GST_STATE_CHANGE_PAUSED_TO_READY:
1883       gst_adapter_clear (dec->adapter);
1884       g_free (dec->cur_buf);
1885       dec->cur_buf = NULL;
1886       gst_jpeg_dec_free_buffers (dec);
1887       if (dec->pool) {
1888         gst_buffer_pool_set_active (dec->pool, FALSE);
1889         gst_object_unref (dec->pool);
1890       }
1891       dec->pool = NULL;
1892       break;
1893     default:
1894       break;
1895   }
1896
1897   return ret;
1898 }