2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3 * Copyright (C) <2009> Tim-Philipp Müller <tim centricular net>
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.
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.
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.
22 * SECTION:element-jpegdec
24 * Decodes jpeg images.
27 * <title>Example launch line</title>
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.
40 #include "gstjpegdec.h"
42 #include <gst/video/video.h>
43 #include "gst/gst-i18n-plugin.h"
47 #define MAX_WIDTH 65535
49 #define MAX_HEIGHT 65535
51 #define CINFO_GET_JPEGDEC(cinfo_ptr) \
52 (((struct GstJpegDecSourceMgr*)((cinfo_ptr)->src))->dec)
54 #define JPEG_DEFAULT_IDCT_METHOD JDCT_FASTEST
55 #define JPEG_DEFAULT_MAX_ERRORS 0
65 static GstStaticPadTemplate gst_jpeg_dec_src_pad_template =
66 GST_STATIC_PAD_TEMPLATE ("src",
69 GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
70 ("{ I420, RGB, BGR, RGBx, xRGB, BGRx, xBGR, GRAY8 }"))
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",
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 }")
87 GST_DEBUG_CATEGORY_STATIC (jpeg_dec_debug);
88 #define GST_CAT_DEFAULT jpeg_dec_debug
89 GST_DEBUG_CATEGORY_STATIC (GST_CAT_PERFORMANCE);
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);
96 static GstFlowReturn gst_jpeg_dec_chain (GstPad * pad, GstObject * parent,
98 static GstCaps *gst_jpeg_dec_getcaps (GstPad * pad, GstCaps * filter);
99 static gboolean gst_jpeg_dec_sink_query (GstPad * pad, GstObject * parent,
101 static gboolean gst_jpeg_dec_sink_event (GstPad * pad, GstObject * parent,
103 static gboolean gst_jpeg_dec_src_event (GstPad * pad, GstObject * parent,
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);
113 #define gst_jpeg_dec_parent_class parent_class
114 G_DEFINE_TYPE (GstJpegDec, gst_jpeg_dec, GST_TYPE_ELEMENT);
117 gst_jpeg_dec_finalize (GObject * object)
119 GstJpegDec *dec = GST_JPEG_DEC (object);
121 jpeg_destroy_decompress (&dec->cinfo);
123 g_object_unref (dec->adapter);
125 G_OBJECT_CLASS (parent_class)->finalize (object);
129 gst_jpeg_dec_class_init (GstJpegDecClass * klass)
131 GstElementClass *gstelement_class;
132 GObjectClass *gobject_class;
134 gstelement_class = (GstElementClass *) klass;
135 gobject_class = (GObjectClass *) klass;
137 parent_class = g_type_class_peek_parent (klass);
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;
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));
150 * GstJpegDec:max-errors
152 * Error out after receiving N consecutive decoding errors
153 * (-1 = never error out, 0 = automatic, 1 = fail on first error, etc.)
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));
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>");
172 gstelement_class->change_state =
173 GST_DEBUG_FUNCPTR (gst_jpeg_dec_change_state);
175 GST_DEBUG_CATEGORY_INIT (jpeg_dec_debug, "jpegdec", 0, "JPEG decoder");
176 GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE");
180 gst_jpeg_dec_clear_error (GstJpegDec * dec)
182 g_free (dec->error_msg);
183 dec->error_msg = NULL;
185 dec->error_func = NULL;
189 gst_jpeg_dec_set_error_va (GstJpegDec * dec, const gchar * func, gint line,
190 const gchar * debug_msg_format, va_list args)
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);
197 g_free (dec->error_msg);
198 if (debug_msg_format)
199 dec->error_msg = g_strdup_vprintf (debug_msg_format, args);
201 dec->error_msg = NULL;
203 dec->error_line = line;
204 dec->error_func = func;
208 gst_jpeg_dec_set_error (GstJpegDec * dec, const gchar * func, gint line,
209 const gchar * debug_msg_format, ...)
213 va_start (va, debug_msg_format);
214 gst_jpeg_dec_set_error_va (dec, func, line, debug_msg_format, va);
219 gst_jpeg_dec_post_error_or_warning (GstJpegDec * dec)
225 max_errors = g_atomic_int_get (&dec->max_errors);
227 if (max_errors < 0) {
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;
234 ret = GST_FLOW_ERROR;
237 ret = (dec->error_count < max_errors) ? GST_FLOW_OK : GST_FLOW_ERROR;
240 GST_INFO_OBJECT (dec, "decoding error %d/%d (%s)", dec->error_count,
241 max_errors, (ret == GST_FLOW_OK) ? "ignoring error" : "erroring out");
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);
249 dec->error_msg = NULL;
250 gst_jpeg_dec_clear_error (dec);
255 gst_jpeg_dec_fill_input_buffer (j_decompress_ptr cinfo)
260 dec = CINFO_GET_JPEGDEC (cinfo);
261 g_return_val_if_fail (dec != NULL, FALSE);
263 av = gst_adapter_available_fast (dec->adapter);
264 GST_DEBUG_OBJECT (dec, "fill_input_buffer: fast av=%u, remaining=%u", av,
268 GST_DEBUG_OBJECT (dec, "Out of data");
272 if (dec->rem_img_len < av)
273 av = dec->rem_img_len;
274 dec->rem_img_len -= av;
276 g_free (dec->cur_buf);
277 dec->cur_buf = gst_adapter_take (dec->adapter, av);
279 cinfo->src->next_input_byte = dec->cur_buf;
280 cinfo->src->bytes_in_buffer = av;
286 gst_jpeg_dec_init_source (j_decompress_ptr cinfo)
288 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "init_source");
293 gst_jpeg_dec_skip_input_data (j_decompress_ptr cinfo, glong num_bytes)
295 GstJpegDec *dec = CINFO_GET_JPEGDEC (cinfo);
297 GST_DEBUG_OBJECT (dec, "skip %ld bytes", num_bytes);
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) {
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;
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);
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;
322 gst_jpeg_dec_resync_to_restart (j_decompress_ptr cinfo, gint desired)
324 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "resync_to_start");
329 gst_jpeg_dec_term_source (j_decompress_ptr cinfo)
331 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "term_source");
336 gst_jpeg_dec_my_output_message (j_common_ptr cinfo)
338 return; /* do nothing */
342 gst_jpeg_dec_my_emit_message (j_common_ptr cinfo, int msg_level)
344 /* GST_LOG_OBJECT (CINFO_GET_JPEGDEC (&cinfo), "msg_level=%d", msg_level); */
349 gst_jpeg_dec_my_error_exit (j_common_ptr cinfo)
351 struct GstJpegDecErrorMgr *err_mgr = (struct GstJpegDecErrorMgr *) cinfo->err;
353 (*cinfo->err->output_message) (cinfo);
354 longjmp (err_mgr->setjmp_buffer, 1);
358 gst_jpeg_dec_init (GstJpegDec * dec)
360 GST_DEBUG ("initializing");
362 /* create the sink and src pads */
364 gst_pad_new_from_static_template (&gst_jpeg_dec_sink_pad_template,
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));
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);
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;
389 jpeg_create_decompress (&dec->cinfo);
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;
399 /* init properties */
400 dec->idct_method = JPEG_DEFAULT_IDCT_METHOD;
401 dec->max_errors = JPEG_DEFAULT_MAX_ERRORS;
403 dec->adapter = gst_adapter_new ();
407 gst_jpeg_dec_ensure_header (GstJpegDec * dec)
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,
416 if (G_UNLIKELY (offset < 0)) {
417 GST_DEBUG_OBJECT (dec, "No JPEG header in current buffer");
420 gst_adapter_flush (dec->adapter, av - 4);
425 GST_LOG_OBJECT (dec, "Skipping %u bytes.", offset);
426 gst_adapter_flush (dec->adapter, offset);
428 GST_DEBUG_OBJECT (dec, "Found JPEG header");
433 static inline gboolean
434 gst_jpeg_dec_parse_tag_has_entropy_segment (guint8 tag)
436 if (tag == 0xda || (tag >= 0xd0 && tag <= 0xd7))
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 */
445 gst_jpeg_dec_parse_image_data (GstJpegDec * dec)
449 GstAdapter *adapter = dec->adapter;
450 gint offset, noffset;
452 size = gst_adapter_available (adapter);
454 /* we expect at least 4 bytes, first of which start marker */
455 if (gst_adapter_masked_scan_uint32 (adapter, 0xffff0000, 0xffd80000, 0, 4))
458 GST_DEBUG ("Parsing jpeg image data (%u bytes)", size);
460 GST_DEBUG ("Parse state: offset=%d, resync=%d, entropy len=%d",
461 dec->parse_offset, dec->parse_resync, dec->parse_entropy_len);
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
467 /* resume from state offset */
468 offset = dec->parse_offset;
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);
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)) {
487 gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00, 0x0000ff00,
488 noffset, size - noffset, &value);
490 /* enough bytes left for marker? (we need 0xNN after the 0xff) */
492 GST_DEBUG ("at end of input and no EOI marker found, need more data");
496 /* now lock on the marker we found */
498 value = value & 0xff;
500 GST_DEBUG ("0x%08x: EOI marker", offset + 2);
501 /* clear parse state */
502 dec->parse_resync = FALSE;
503 dec->parse_offset = 0;
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);
514 if (value >= 0xd0 && value <= 0xd7)
517 /* peek tag and subsequent length */
518 if (offset + 2 + 4 > size)
521 gst_adapter_masked_scan_uint32_peek (adapter, 0x0, 0x0, offset + 2, 4,
523 frame_len = frame_len & 0xffff;
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) {
532 if (gst_jpeg_dec_parse_tag_has_entropy_segment (value)) {
533 guint eseglen = dec->parse_entropy_len;
535 GST_DEBUG ("0x%08x: finding entropy segment length", offset + 2);
536 noffset = offset + 2 + frame_len + dec->parse_entropy_len;
538 noffset = gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00,
539 0x0000ff00, noffset, size - noffset, &value);
542 dec->parse_entropy_len = size - offset - 4 - frame_len - 2;
545 if ((value & 0xff) != 0x00) {
546 eseglen = noffset - offset - frame_len - 2;
551 dec->parse_entropy_len = 0;
552 frame_len += eseglen;
553 GST_DEBUG ("entropy segment length=%u => frame_len=%u", eseglen,
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,
563 /* ignore and continue resyncing until we hit the end
564 * of our data or find a sync point that looks okay */
568 GST_DEBUG ("found sync at 0x%x", offset + 2);
571 offset += frame_len + 2;
577 dec->parse_offset = offset;
578 dec->parse_resync = resync;
583 /* shamelessly ripped from jpegutils.c in mjpegtools */
585 add_huff_table (j_decompress_ptr dinfo,
586 JHUFF_TBL ** htblptr, const UINT8 * bits, const UINT8 * val)
587 /* Define a Huffman table */
591 if (*htblptr == NULL)
592 *htblptr = jpeg_alloc_huff_table ((j_common_ptr) dinfo);
596 /* Copy the number-of-symbols-of-each-code-length counts */
597 memcpy ((*htblptr)->bits, bits, sizeof ((*htblptr)->bits));
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.
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. ");
609 memcpy ((*htblptr)->huffval, val, nsymbols * sizeof (UINT8));
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! */
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 };
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 };
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,
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,
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);
694 guarantee_huff_tables (j_decompress_ptr dinfo)
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);
706 gst_jpeg_dec_setcaps (GstJpegDec * dec, GstCaps * caps)
709 const GValue *framerate;
711 s = gst_caps_get_structure (caps, 0);
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);
721 /* do not extract width/height here. we do that in the chain
722 * function on a per-frame basis (including the line[] array
725 /* But we can take the framerate values and set them on the src pad */
731 gst_jpeg_dec_getcaps (GstPad * pad, GstCaps * filter)
737 dec = GST_JPEG_DEC (GST_OBJECT_PARENT (pad));
739 if (gst_pad_has_current_caps (pad))
740 return gst_pad_get_current_caps (pad);
742 peer = gst_pad_get_peer (dec->srcpad);
746 const GstCaps *templ_caps;
750 peer_caps = gst_pad_query_caps (peer, filter);
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);
758 gst_structure_set_name (s, "image/jpeg");
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);
765 gst_object_unref (peer);
767 caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
776 hresamplecpy1 (guint8 * dest, const guint8 * src, guint len)
780 for (i = 0; i < len; ++i) {
781 /* equivalent to: dest[i] = src[i << 1] */
790 gst_jpeg_dec_free_buffers (GstJpegDec * dec)
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;
803 dec->idr_width_allocated = 0;
806 static inline gboolean
807 gst_jpeg_dec_ensure_buffers (GstJpegDec * dec, guint maxrowbytes)
811 if (G_LIKELY (dec->idr_width_allocated >= maxrowbytes))
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);
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);
826 dec->idr_width_allocated = maxrowbytes;
827 GST_LOG_OBJECT (dec, "allocated temp memory, %u bytes/row", maxrowbytes);
832 gst_jpeg_dec_decode_grayscale (GstJpegDec * dec, GstVideoFrame * frame)
835 guchar **scanarray[1] = { rows };
840 gint pstride, rstride;
842 GST_DEBUG_OBJECT (dec, "indirect decoding of grayscale");
844 width = GST_VIDEO_FRAME_WIDTH (frame);
845 height = GST_VIDEO_FRAME_HEIGHT (frame);
847 if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
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);
854 memcpy (rows, dec->idr_y, 16 * sizeof (gpointer));
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++) {
864 for (k = 0; k < width; k++) {
865 base[0][p] = rows[j][k];
871 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
877 gst_jpeg_dec_decode_rgb (GstJpegDec * dec, GstVideoFrame * frame)
879 guchar *r_rows[16], *g_rows[16], *b_rows[16];
880 guchar **scanarray[3] = { r_rows, g_rows, b_rows };
884 guint pstride, rstride;
887 GST_DEBUG_OBJECT (dec, "indirect decoding of RGB");
889 width = GST_VIDEO_FRAME_WIDTH (frame);
890 height = GST_VIDEO_FRAME_HEIGHT (frame);
892 if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
895 for (i = 0; i < 3; i++)
896 base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
898 pstride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0);
899 rstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
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));
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++) {
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];
924 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
930 gst_jpeg_dec_decode_indirect (GstJpegDec * dec, GstVideoFrame * frame,
931 gint r_v, gint r_h, gint comp)
933 guchar *y_rows[16], *u_rows[16], *v_rows[16];
934 guchar **scanarray[3] = { y_rows, u_rows, v_rows };
937 guchar *base[3], *last[3];
941 GST_DEBUG_OBJECT (dec,
942 "unadvantageous width or r_h, taking slow route involving memcpy");
944 width = GST_VIDEO_FRAME_WIDTH (frame);
945 height = GST_VIDEO_FRAME_HEIGHT (frame);
947 if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
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));
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));
963 /* fill chroma components for grayscale */
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);
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];
981 if (G_LIKELY (base[0] <= last[0])) {
982 memcpy (base[0], y_rows[j + 1], stride[0]);
983 base[0] += stride[0];
986 if (G_LIKELY (base[1] <= last[1] && base[2] <= last[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]);
994 /* FIXME: implement (at least we avoid crashing by doing nothing) */
998 if (r_v == 2 || (k & 1) != 0) {
999 base[1] += stride[1];
1000 base[2] += stride[2];
1004 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
1009 static GstFlowReturn
1010 gst_jpeg_dec_decode_direct (GstJpegDec * dec, GstVideoFrame * frame)
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, };
1017 gint lines, v_samp[3];
1018 guchar *base[3], *last[3];
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;
1030 if (G_UNLIKELY (v_samp[0] > 2 || v_samp[1] > 2 || v_samp[2] > 2))
1031 goto format_not_supported;
1033 height = GST_VIDEO_FRAME_HEIGHT (frame);
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));
1044 /* let jpeglib decode directly into our final buffer */
1045 GST_DEBUG_OBJECT (dec, "decoding directly into output buffer");
1047 for (i = 0; i < height; i += v_samp[0] * DCTSIZE) {
1048 for (j = 0; j < (v_samp[0] * DCTSIZE); ++j) {
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];
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];
1059 if (G_UNLIKELY (line[1][j] > last[1]))
1060 line[1][j] = last[1];
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];
1067 if (G_UNLIKELY (line[2][j] > last[2]))
1068 line[2][j] = last[2];
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");
1078 format_not_supported:
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;
1088 gst_jpeg_dec_update_qos (GstJpegDec * dec, gdouble proportion,
1089 GstClockTimeDiff diff, GstClockTime ts)
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;
1097 dec->earliest_time = ts + diff;
1099 dec->earliest_time = GST_CLOCK_TIME_NONE;
1101 GST_OBJECT_UNLOCK (dec);
1105 gst_jpeg_dec_reset_qos (GstJpegDec * dec)
1107 gst_jpeg_dec_update_qos (dec, 0.5, 0, GST_CLOCK_TIME_NONE);
1111 gst_jpeg_dec_read_qos (GstJpegDec * dec, gdouble * proportion,
1112 GstClockTime * time)
1114 GST_OBJECT_LOCK (dec);
1115 *proportion = dec->proportion;
1116 *time = dec->earliest_time;
1117 GST_OBJECT_UNLOCK (dec);
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 */
1123 gst_jpeg_dec_do_qos (GstJpegDec * dec, GstClockTime timestamp)
1125 GstClockTime qostime, earliest_time;
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");
1134 /* get latest QoS observation values */
1135 gst_jpeg_dec_read_qos (dec, &proportion, &earliest_time);
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");
1143 /* qos is done on running time */
1144 qostime = gst_segment_to_running_time (&dec->segment, GST_FORMAT_TIME,
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));
1151 if (qostime != GST_CLOCK_TIME_NONE && qostime <= earliest_time) {
1152 GST_DEBUG_OBJECT (dec, "we are late, drop frame");
1156 GST_LOG_OBJECT (dec, "decode frame");
1161 gst_jpeg_dec_buffer_pool (GstJpegDec * dec, GstCaps * caps)
1164 GstBufferPool *pool = NULL;
1165 guint size, min, max, prefix, alignment;
1166 GstStructure *config;
1168 GST_DEBUG_OBJECT (dec, "setting up bufferpool");
1170 /* find a pool for the negotiated caps now */
1171 query = gst_query_new_allocation (caps, TRUE);
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,
1177 size = MAX (size, dec->info.size);
1179 GST_DEBUG_OBJECT (dec, "peer query failed, using defaults");
1180 size = dec->info.size;
1185 gst_query_unref (query);
1188 /* we did not get a pool, make one ourselves then */
1189 pool = gst_buffer_pool_new ();
1192 config = gst_buffer_pool_get_config (pool);
1193 gst_buffer_pool_config_set (config, caps, size, min, max, prefix,
1196 gst_buffer_pool_set_config (pool, config);
1199 gst_buffer_pool_set_active (dec->pool, FALSE);
1200 gst_object_unref (dec->pool);
1205 gst_buffer_pool_set_active (pool, TRUE);
1211 gst_jpeg_dec_negotiate (GstJpegDec * dec, gint width, gint height, gint clrspc)
1214 GstVideoFormat format;
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))
1222 gst_video_info_init (&info);
1224 /* framerate == 0/1 is a still frame */
1225 if (dec->in_fps_d == 0) {
1229 info.fps_n = dec->in_fps_n;
1230 info.fps_d = dec->in_fps_d;
1233 /* calculate or assume an average frame duration for QoS purposes */
1234 GST_OBJECT_LOCK (dec);
1235 if (info.fps_n != 0) {
1237 gst_util_uint64_scale (GST_SECOND, info.fps_d, info.fps_n);
1238 dec->duration = dec->qos_duration;
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;
1244 GST_OBJECT_UNLOCK (dec);
1246 if (dec->cinfo.jpeg_color_space == JCS_RGB) {
1248 GstCaps *allowed_caps;
1249 GstVideoInfo tmpinfo;
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);
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));
1261 /* avoid lists of formats, etc */
1262 allowed_caps = gst_caps_normalize (caps);
1263 gst_caps_unref (caps);
1265 GST_LOG_OBJECT (dec, "allowed source caps %" GST_PTR_FORMAT, allowed_caps);
1267 for (i = 0; i < gst_caps_get_size (allowed_caps); i++) {
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);
1275 if (!gst_video_info_from_caps (&tmpinfo, caps))
1277 /* we'll settle for the first (preferred) downstream rgb format */
1278 if (GST_VIDEO_INFO_IS_RGB (&tmpinfo))
1280 /* default fall-back */
1281 format = GST_VIDEO_FORMAT_RGB;
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;
1290 /* go for plain and simple I420 */
1291 /* TODO other YUV cases ? */
1292 format = GST_VIDEO_FORMAT_I420;
1295 gst_video_info_set_format (&info, format, width, height);
1296 caps = gst_video_info_to_caps (&info);
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);
1302 gst_pad_set_caps (dec->srcpad, caps);
1305 dec->clrspc = clrspc;
1307 gst_jpeg_dec_buffer_pool (dec, caps);
1308 gst_caps_unref (caps);
1313 static GstFlowReturn
1314 gst_jpeg_dec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
1316 GstFlowReturn ret = GST_FLOW_OK;
1318 GstBuffer *outbuf = NULL;
1323 GstClockTime timestamp, duration;
1324 GstVideoFrame frame;
1326 dec = GST_JPEG_DEC (parent);
1328 timestamp = GST_BUFFER_TIMESTAMP (buf);
1329 duration = GST_BUFFER_DURATION (buf);
1331 if (GST_CLOCK_TIME_IS_VALID (timestamp))
1332 dec->next_ts = timestamp;
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);
1343 gst_adapter_push (dec->adapter, buf);
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. */
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 %" G_GSIZE_FORMAT " bytes, "
1354 "need %" G_GINT64_FORMAT, gst_adapter_available (dec->adapter),
1356 goto need_more_data;
1360 if (!gst_jpeg_dec_ensure_header (dec))
1361 goto need_more_data;
1363 /* If we know that each input buffer contains data
1364 * for a whole jpeg image (e.g. MJPEG streams), just
1365 * do some sanity checking instead of parsing all of
1367 if (dec->packetized) {
1368 img_len = gst_adapter_available (dec->adapter);
1370 /* Parse jpeg image to handle jpeg input that
1371 * is not aligned to buffer boundaries */
1372 img_len = gst_jpeg_dec_parse_image_data (dec);
1375 goto need_more_data;
1376 } else if (img_len < 0) {
1377 gst_adapter_flush (dec->adapter, -img_len);
1382 dec->rem_img_len = img_len;
1384 GST_LOG_OBJECT (dec, "image size = %u", img_len);
1386 /* QoS: if we're too late anyway, skip decoding */
1387 if (dec->packetized && !gst_jpeg_dec_do_qos (dec, timestamp))
1390 #ifndef GST_DISABLE_GST_DEBUG
1394 gst_adapter_copy (dec->adapter, data, 0, 4);
1395 GST_LOG_OBJECT (dec, "reading header %02x %02x %02x %02x", data[0], data[1],
1400 gst_jpeg_dec_fill_input_buffer (&dec->cinfo);
1402 if (setjmp (dec->jerr.setjmp_buffer)) {
1403 code = dec->jerr.pub.msg_code;
1405 if (code == JERR_INPUT_EOF) {
1406 GST_DEBUG ("jpeg input EOF error, we probably need more data");
1407 goto need_more_data;
1413 hdr_ok = jpeg_read_header (&dec->cinfo, TRUE);
1414 if (G_UNLIKELY (hdr_ok != JPEG_HEADER_OK)) {
1415 GST_WARNING_OBJECT (dec, "reading the header failed, %d", hdr_ok);
1418 GST_LOG_OBJECT (dec, "num_components=%d", dec->cinfo.num_components);
1419 GST_LOG_OBJECT (dec, "jpeg_color_space=%d", dec->cinfo.jpeg_color_space);
1421 if (!dec->cinfo.num_components || !dec->cinfo.comp_info)
1422 goto components_not_supported;
1424 r_h = dec->cinfo.comp_info[0].h_samp_factor;
1425 r_v = dec->cinfo.comp_info[0].v_samp_factor;
1427 GST_LOG_OBJECT (dec, "r_h = %d, r_v = %d", r_h, r_v);
1429 if (dec->cinfo.num_components > 3)
1430 goto components_not_supported;
1432 /* verify color space expectation to avoid going *boom* or bogus output */
1433 if (dec->cinfo.jpeg_color_space != JCS_YCbCr &&
1434 dec->cinfo.jpeg_color_space != JCS_GRAYSCALE &&
1435 dec->cinfo.jpeg_color_space != JCS_RGB)
1436 goto unsupported_colorspace;
1438 #ifndef GST_DISABLE_GST_DEBUG
1442 for (i = 0; i < dec->cinfo.num_components; ++i) {
1443 GST_LOG_OBJECT (dec, "[%d] h_samp_factor=%d, v_samp_factor=%d, cid=%d",
1444 i, dec->cinfo.comp_info[i].h_samp_factor,
1445 dec->cinfo.comp_info[i].v_samp_factor,
1446 dec->cinfo.comp_info[i].component_id);
1451 /* prepare for raw output */
1452 dec->cinfo.do_fancy_upsampling = FALSE;
1453 dec->cinfo.do_block_smoothing = FALSE;
1454 dec->cinfo.out_color_space = dec->cinfo.jpeg_color_space;
1455 dec->cinfo.dct_method = dec->idct_method;
1456 dec->cinfo.raw_data_out = TRUE;
1458 GST_LOG_OBJECT (dec, "starting decompress");
1459 guarantee_huff_tables (&dec->cinfo);
1460 if (!jpeg_start_decompress (&dec->cinfo)) {
1461 GST_WARNING_OBJECT (dec, "failed to start decompression cycle");
1464 /* sanity checks to get safe and reasonable output */
1465 switch (dec->cinfo.jpeg_color_space) {
1467 if (dec->cinfo.num_components != 1)
1468 goto invalid_yuvrgbgrayscale;
1471 if (dec->cinfo.num_components != 3 || dec->cinfo.max_v_samp_factor > 1 ||
1472 dec->cinfo.max_h_samp_factor > 1)
1473 goto invalid_yuvrgbgrayscale;
1476 if (dec->cinfo.num_components != 3 ||
1477 r_v > 2 || r_v < dec->cinfo.comp_info[0].v_samp_factor ||
1478 r_v < dec->cinfo.comp_info[1].v_samp_factor ||
1479 r_h < dec->cinfo.comp_info[0].h_samp_factor ||
1480 r_h < dec->cinfo.comp_info[1].h_samp_factor)
1481 goto invalid_yuvrgbgrayscale;
1484 g_assert_not_reached ();
1488 width = dec->cinfo.output_width;
1489 height = dec->cinfo.output_height;
1491 if (G_UNLIKELY (width < MIN_WIDTH || width > MAX_WIDTH ||
1492 height < MIN_HEIGHT || height > MAX_HEIGHT))
1495 gst_jpeg_dec_negotiate (dec, width, height, dec->cinfo.jpeg_color_space);
1497 ret = gst_buffer_pool_acquire_buffer (dec->pool, &outbuf, NULL);
1498 if (G_UNLIKELY (ret != GST_FLOW_OK))
1501 if (!gst_video_frame_map (&frame, &dec->info, outbuf, GST_MAP_READWRITE))
1504 GST_LOG_OBJECT (dec, "width %d, height %d", width, height);
1506 GST_BUFFER_TIMESTAMP (outbuf) = dec->next_ts;
1508 if (dec->packetized && GST_CLOCK_TIME_IS_VALID (dec->next_ts)) {
1509 if (GST_CLOCK_TIME_IS_VALID (duration)) {
1510 /* use duration from incoming buffer for outgoing buffer */
1511 dec->next_ts += duration;
1512 } else if (GST_CLOCK_TIME_IS_VALID (dec->duration)) {
1513 duration = dec->duration;
1514 dec->next_ts += dec->duration;
1516 duration = GST_CLOCK_TIME_NONE;
1517 dec->next_ts = GST_CLOCK_TIME_NONE;
1520 duration = GST_CLOCK_TIME_NONE;
1521 dec->next_ts = GST_CLOCK_TIME_NONE;
1523 GST_BUFFER_DURATION (outbuf) = duration;
1525 if (dec->cinfo.jpeg_color_space == JCS_RGB) {
1526 gst_jpeg_dec_decode_rgb (dec, &frame);
1527 } else if (dec->cinfo.jpeg_color_space == JCS_GRAYSCALE) {
1528 gst_jpeg_dec_decode_grayscale (dec, &frame);
1530 GST_LOG_OBJECT (dec, "decompressing (reqired scanline buffer height = %u)",
1531 dec->cinfo.rec_outbuf_height);
1533 /* For some widths jpeglib requires more horizontal padding than I420
1534 * provides. In those cases we need to decode into separate buffers and then
1535 * copy over the data into our final picture buffer, otherwise jpeglib might
1536 * write over the end of a line into the beginning of the next line,
1537 * resulting in blocky artifacts on the left side of the picture. */
1538 if (G_UNLIKELY (width % (dec->cinfo.max_h_samp_factor * DCTSIZE) != 0
1539 || dec->cinfo.comp_info[0].h_samp_factor != 2
1540 || dec->cinfo.comp_info[1].h_samp_factor != 1
1541 || dec->cinfo.comp_info[2].h_samp_factor != 1)) {
1542 GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, dec,
1543 "indirect decoding using extra buffer copy");
1544 gst_jpeg_dec_decode_indirect (dec, &frame, r_v, r_h,
1545 dec->cinfo.num_components);
1547 ret = gst_jpeg_dec_decode_direct (dec, &frame);
1548 if (G_UNLIKELY (ret != GST_FLOW_OK))
1549 goto decode_direct_failed;
1553 GST_LOG_OBJECT (dec, "decompressing finished");
1554 jpeg_finish_decompress (&dec->cinfo);
1556 gst_video_frame_unmap (&frame);
1559 if (dec->segment.format == GST_FORMAT_TIME) {
1560 guint64 start, stop, clip_start, clip_stop;
1562 GST_LOG_OBJECT (dec, "Attempting clipping");
1564 start = GST_BUFFER_TIMESTAMP (outbuf);
1565 if (GST_BUFFER_DURATION (outbuf) == GST_CLOCK_TIME_NONE)
1568 stop = start + GST_BUFFER_DURATION (outbuf);
1570 if (gst_segment_clip (&dec->segment, GST_FORMAT_TIME,
1571 start, stop, &clip_start, &clip_stop)) {
1572 GST_LOG_OBJECT (dec, "Clipping start to %" GST_TIME_FORMAT,
1573 GST_TIME_ARGS (clip_start));
1574 GST_BUFFER_TIMESTAMP (outbuf) = clip_start;
1575 if (GST_BUFFER_DURATION (outbuf) != GST_CLOCK_TIME_NONE) {
1576 GST_LOG_OBJECT (dec, "Clipping duration to %" GST_TIME_FORMAT,
1577 GST_TIME_ARGS (clip_stop - clip_start));
1578 GST_BUFFER_DURATION (outbuf) = clip_stop - clip_start;
1584 /* reset error count on successful decode */
1585 dec->error_count = 0;
1589 GST_LOG_OBJECT (dec, "pushing buffer (ts=%" GST_TIME_FORMAT ", dur=%"
1590 GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
1591 GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
1593 ret = gst_pad_push (dec->srcpad, outbuf);
1597 gst_adapter_flush (dec->adapter, dec->rem_img_len);
1601 if (G_UNLIKELY (ret == GST_FLOW_ERROR)) {
1602 jpeg_abort_decompress (&dec->cinfo);
1603 ret = gst_jpeg_dec_post_error_or_warning (dec);
1611 GST_LOG_OBJECT (dec, "we need more data");
1613 gst_buffer_unref (outbuf);
1622 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1623 "Picture is too small or too big (%ux%u)", width, height);
1624 ret = GST_FLOW_ERROR;
1629 gchar err_msg[JMSG_LENGTH_MAX];
1631 dec->jerr.pub.format_message ((j_common_ptr) (&dec->cinfo), err_msg);
1633 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1634 "Decode error #%u: %s", code, err_msg);
1637 gst_buffer_unref (outbuf);
1640 ret = GST_FLOW_ERROR;
1643 decode_direct_failed:
1645 /* already posted an error message */
1646 jpeg_abort_decompress (&dec->cinfo);
1647 gst_buffer_replace (&outbuf, NULL);
1652 const gchar *reason;
1654 reason = gst_flow_get_name (ret);
1656 GST_DEBUG_OBJECT (dec, "failed to alloc buffer, reason %s", reason);
1657 /* Reset for next time */
1658 jpeg_abort_decompress (&dec->cinfo);
1659 if (ret != GST_FLOW_UNEXPECTED && ret != GST_FLOW_WRONG_STATE &&
1660 ret != GST_FLOW_NOT_LINKED) {
1661 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1662 "Buffer allocation failed, reason: %s", reason);
1668 jpeg_abort_decompress (&dec->cinfo);
1669 gst_buffer_unref (outbuf);
1675 GST_WARNING_OBJECT (dec, "Outgoing buffer is outside configured segment");
1676 gst_buffer_unref (outbuf);
1680 components_not_supported:
1682 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1683 "number of components not supported: %d (max 3)",
1684 dec->cinfo.num_components);
1685 ret = GST_FLOW_ERROR;
1688 unsupported_colorspace:
1690 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1691 "Picture has unknown or unsupported colourspace");
1692 ret = GST_FLOW_ERROR;
1695 invalid_yuvrgbgrayscale:
1697 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1698 "Picture is corrupt or unhandled YUV/RGB/grayscale layout");
1699 ret = GST_FLOW_ERROR;
1705 gst_jpeg_dec_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
1710 dec = GST_JPEG_DEC (parent);
1712 switch (GST_EVENT_TYPE (event)) {
1713 case GST_EVENT_QOS:{
1715 GstClockTimeDiff diff;
1716 GstClockTime timestamp;
1719 gst_event_parse_qos (event, &type, &proportion, &diff, ×tamp);
1720 gst_jpeg_dec_update_qos (dec, proportion, diff, timestamp);
1727 res = gst_pad_push_event (dec->sinkpad, event);
1733 gst_jpeg_dec_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
1735 gboolean ret = TRUE, forward = TRUE;
1736 GstJpegDec *dec = GST_JPEG_DEC (parent);
1738 GST_DEBUG_OBJECT (dec, "event : %s", GST_EVENT_TYPE_NAME (event));
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);
1753 case GST_EVENT_SEGMENT:
1754 gst_event_copy_segment (event, &dec->segment);
1755 GST_DEBUG_OBJECT (dec, "Got NEWSEGMENT %" GST_SEGMENT_FORMAT,
1758 case GST_EVENT_CAPS:
1762 gst_event_parse_caps (event, &caps);
1763 ret = gst_jpeg_dec_setcaps (dec, caps);
1772 ret = gst_pad_push_event (dec->srcpad, event);
1774 gst_event_unref (event);
1780 gst_jpeg_dec_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
1782 gboolean res = FALSE;
1784 switch (GST_QUERY_TYPE (query)) {
1785 case GST_QUERY_CAPS:
1787 GstCaps *filter, *caps;
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);
1797 res = gst_pad_query_default (pad, parent, query);
1804 gst_jpeg_dec_set_property (GObject * object, guint prop_id,
1805 const GValue * value, GParamSpec * pspec)
1809 dec = GST_JPEG_DEC (object);
1812 case PROP_IDCT_METHOD:
1813 dec->idct_method = g_value_get_enum (value);
1815 case PROP_MAX_ERRORS:
1816 g_atomic_int_set (&dec->max_errors, g_value_get_int (value));
1820 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1826 gst_jpeg_dec_get_property (GObject * object, guint prop_id, GValue * value,
1831 dec = GST_JPEG_DEC (object);
1834 case PROP_IDCT_METHOD:
1835 g_value_set_enum (value, dec->idct_method);
1837 case PROP_MAX_ERRORS:
1838 g_value_set_int (value, g_atomic_int_get (&dec->max_errors));
1842 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1847 static GstStateChangeReturn
1848 gst_jpeg_dec_change_state (GstElement * element, GstStateChange transition)
1850 GstStateChangeReturn ret;
1853 dec = GST_JPEG_DEC (element);
1855 switch (transition) {
1856 case GST_STATE_CHANGE_READY_TO_PAUSED:
1857 dec->error_count = 0;
1858 dec->good_count = 0;
1861 gst_video_info_init (&dec->info);
1863 dec->packetized = FALSE;
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);
1876 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1877 if (ret != GST_STATE_CHANGE_SUCCESS)
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);
1887 gst_buffer_pool_set_active (dec->pool, FALSE);
1888 gst_object_unref (dec->pool);