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