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