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 static GstStaticPadTemplate gst_jpeg_dec_sink_pad_template =
76 GST_STATIC_PAD_TEMPLATE ("sink",
79 GST_STATIC_CAPS ("image/jpeg, "
80 "width = (int) [ " G_STRINGIFY (MIN_WIDTH) ", " G_STRINGIFY (MAX_WIDTH)
81 " ], " "height = (int) [ " G_STRINGIFY (MIN_HEIGHT) ", "
82 G_STRINGIFY (MAX_HEIGHT) " ], " "framerate = (fraction) [ 0/1, MAX ]")
85 GST_DEBUG_CATEGORY_STATIC (jpeg_dec_debug);
86 #define GST_CAT_DEFAULT jpeg_dec_debug
87 GST_DEBUG_CATEGORY_STATIC (GST_CAT_PERFORMANCE);
89 static void gst_jpeg_dec_set_property (GObject * object, guint prop_id,
90 const GValue * value, GParamSpec * pspec);
91 static void gst_jpeg_dec_get_property (GObject * object, guint prop_id,
92 GValue * value, GParamSpec * pspec);
94 static GstFlowReturn gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buffer);
95 static GstCaps *gst_jpeg_dec_getcaps (GstPad * pad, GstCaps * filter);
96 static gboolean gst_jpeg_dec_sink_event (GstPad * pad, GstEvent * event);
97 static gboolean gst_jpeg_dec_src_event (GstPad * pad, GstEvent * event);
98 static GstStateChangeReturn gst_jpeg_dec_change_state (GstElement * element,
99 GstStateChange transition);
100 static void gst_jpeg_dec_update_qos (GstJpegDec * dec, gdouble proportion,
101 GstClockTimeDiff diff, GstClockTime ts);
102 static void gst_jpeg_dec_reset_qos (GstJpegDec * dec);
103 static void gst_jpeg_dec_read_qos (GstJpegDec * dec, gdouble * proportion,
104 GstClockTime * time);
106 #define gst_jpeg_dec_parent_class parent_class
107 G_DEFINE_TYPE (GstJpegDec, gst_jpeg_dec, GST_TYPE_ELEMENT);
110 gst_jpeg_dec_finalize (GObject * object)
112 GstJpegDec *dec = GST_JPEG_DEC (object);
114 jpeg_destroy_decompress (&dec->cinfo);
116 g_object_unref (dec->adapter);
118 G_OBJECT_CLASS (parent_class)->finalize (object);
122 gst_jpeg_dec_class_init (GstJpegDecClass * klass)
124 GstElementClass *gstelement_class;
125 GObjectClass *gobject_class;
127 gstelement_class = (GstElementClass *) klass;
128 gobject_class = (GObjectClass *) klass;
130 parent_class = g_type_class_peek_parent (klass);
132 gobject_class->finalize = gst_jpeg_dec_finalize;
133 gobject_class->set_property = gst_jpeg_dec_set_property;
134 gobject_class->get_property = gst_jpeg_dec_get_property;
136 g_object_class_install_property (gobject_class, PROP_IDCT_METHOD,
137 g_param_spec_enum ("idct-method", "IDCT Method",
138 "The IDCT algorithm to use", GST_TYPE_IDCT_METHOD,
139 JPEG_DEFAULT_IDCT_METHOD,
140 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
143 * GstJpegDec:max-errors
145 * Error out after receiving N consecutive decoding errors
146 * (-1 = never error out, 0 = automatic, 1 = fail on first error, etc.)
150 g_object_class_install_property (gobject_class, PROP_MAX_ERRORS,
151 g_param_spec_int ("max-errors", "Maximum Consecutive Decoding Errors",
152 "Error out after receiving N consecutive decoding errors "
153 "(-1 = never fail, 0 = automatic, 1 = fail on first error)",
154 -1, G_MAXINT, JPEG_DEFAULT_MAX_ERRORS,
155 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
157 gst_element_class_add_pad_template (gstelement_class,
158 gst_static_pad_template_get (&gst_jpeg_dec_src_pad_template));
159 gst_element_class_add_pad_template (gstelement_class,
160 gst_static_pad_template_get (&gst_jpeg_dec_sink_pad_template));
161 gst_element_class_set_details_simple (gstelement_class, "JPEG image decoder",
162 "Codec/Decoder/Image",
163 "Decode images from JPEG format", "Wim Taymans <wim@fluendo.com>");
165 gstelement_class->change_state =
166 GST_DEBUG_FUNCPTR (gst_jpeg_dec_change_state);
168 GST_DEBUG_CATEGORY_INIT (jpeg_dec_debug, "jpegdec", 0, "JPEG decoder");
169 GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE");
173 gst_jpeg_dec_clear_error (GstJpegDec * dec)
175 g_free (dec->error_msg);
176 dec->error_msg = NULL;
178 dec->error_func = NULL;
182 gst_jpeg_dec_set_error_va (GstJpegDec * dec, const gchar * func, gint line,
183 const gchar * debug_msg_format, va_list args)
185 #ifndef GST_DISABLE_GST_DEBUG
186 gst_debug_log_valist (GST_CAT_DEFAULT, GST_LEVEL_WARNING, __FILE__, func,
187 line, (GObject *) dec, debug_msg_format, args);
190 g_free (dec->error_msg);
191 if (debug_msg_format)
192 dec->error_msg = g_strdup_vprintf (debug_msg_format, args);
194 dec->error_msg = NULL;
196 dec->error_line = line;
197 dec->error_func = func;
201 gst_jpeg_dec_set_error (GstJpegDec * dec, const gchar * func, gint line,
202 const gchar * debug_msg_format, ...)
206 va_start (va, debug_msg_format);
207 gst_jpeg_dec_set_error_va (dec, func, line, debug_msg_format, va);
212 gst_jpeg_dec_post_error_or_warning (GstJpegDec * dec)
218 max_errors = g_atomic_int_get (&dec->max_errors);
220 if (max_errors < 0) {
222 } else if (max_errors == 0) {
223 /* FIXME: do something more clever in "automatic mode" */
224 if (dec->packetized) {
225 ret = (dec->error_count < 3) ? GST_FLOW_OK : GST_FLOW_ERROR;
227 ret = GST_FLOW_ERROR;
230 ret = (dec->error_count < max_errors) ? GST_FLOW_OK : GST_FLOW_ERROR;
233 GST_INFO_OBJECT (dec, "decoding error %d/%d (%s)", dec->error_count,
234 max_errors, (ret == GST_FLOW_OK) ? "ignoring error" : "erroring out");
236 gst_element_message_full (GST_ELEMENT (dec),
237 (ret == GST_FLOW_OK) ? GST_MESSAGE_WARNING : GST_MESSAGE_ERROR,
238 GST_STREAM_ERROR, GST_STREAM_ERROR_DECODE,
239 g_strdup (_("Failed to decode JPEG image")), dec->error_msg,
240 __FILE__, dec->error_func, dec->error_line);
242 dec->error_msg = NULL;
243 gst_jpeg_dec_clear_error (dec);
248 gst_jpeg_dec_fill_input_buffer (j_decompress_ptr cinfo)
253 dec = CINFO_GET_JPEGDEC (cinfo);
254 g_return_val_if_fail (dec != NULL, FALSE);
256 av = gst_adapter_available_fast (dec->adapter);
257 GST_DEBUG_OBJECT (dec, "fill_input_buffer: fast av=%u, remaining=%u", av,
261 GST_DEBUG_OBJECT (dec, "Out of data");
265 if (dec->rem_img_len < av)
266 av = dec->rem_img_len;
267 dec->rem_img_len -= av;
269 g_free (dec->cur_buf);
270 dec->cur_buf = gst_adapter_take (dec->adapter, av);
272 cinfo->src->next_input_byte = dec->cur_buf;
273 cinfo->src->bytes_in_buffer = av;
279 gst_jpeg_dec_init_source (j_decompress_ptr cinfo)
281 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "init_source");
286 gst_jpeg_dec_skip_input_data (j_decompress_ptr cinfo, glong num_bytes)
288 GstJpegDec *dec = CINFO_GET_JPEGDEC (cinfo);
290 GST_DEBUG_OBJECT (dec, "skip %ld bytes", num_bytes);
292 if (num_bytes > 0 && cinfo->src->bytes_in_buffer >= num_bytes) {
293 cinfo->src->next_input_byte += (size_t) num_bytes;
294 cinfo->src->bytes_in_buffer -= (size_t) num_bytes;
295 } else if (num_bytes > 0) {
298 num_bytes -= cinfo->src->bytes_in_buffer;
299 cinfo->src->next_input_byte += (size_t) cinfo->src->bytes_in_buffer;
300 cinfo->src->bytes_in_buffer = 0;
302 available = gst_adapter_available (dec->adapter);
303 if (available < num_bytes || available < dec->rem_img_len) {
304 GST_WARNING_OBJECT (dec, "Less bytes to skip than available in the "
305 "adapter or the remaining image length %ld < %d or %u",
306 num_bytes, available, dec->rem_img_len);
308 num_bytes = MIN (MIN (num_bytes, available), dec->rem_img_len);
309 gst_adapter_flush (dec->adapter, num_bytes);
310 dec->rem_img_len -= num_bytes;
315 gst_jpeg_dec_resync_to_restart (j_decompress_ptr cinfo, gint desired)
317 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "resync_to_start");
322 gst_jpeg_dec_term_source (j_decompress_ptr cinfo)
324 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "term_source");
329 gst_jpeg_dec_my_output_message (j_common_ptr cinfo)
331 return; /* do nothing */
335 gst_jpeg_dec_my_emit_message (j_common_ptr cinfo, int msg_level)
337 /* GST_LOG_OBJECT (CINFO_GET_JPEGDEC (&cinfo), "msg_level=%d", msg_level); */
342 gst_jpeg_dec_my_error_exit (j_common_ptr cinfo)
344 struct GstJpegDecErrorMgr *err_mgr = (struct GstJpegDecErrorMgr *) cinfo->err;
346 (*cinfo->err->output_message) (cinfo);
347 longjmp (err_mgr->setjmp_buffer, 1);
351 gst_jpeg_dec_init (GstJpegDec * dec)
353 GST_DEBUG ("initializing");
355 /* create the sink and src pads */
357 gst_pad_new_from_static_template (&gst_jpeg_dec_sink_pad_template,
359 gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
360 gst_pad_set_getcaps_function (dec->sinkpad,
361 GST_DEBUG_FUNCPTR (gst_jpeg_dec_getcaps));
362 gst_pad_set_chain_function (dec->sinkpad,
363 GST_DEBUG_FUNCPTR (gst_jpeg_dec_chain));
364 gst_pad_set_event_function (dec->sinkpad,
365 GST_DEBUG_FUNCPTR (gst_jpeg_dec_sink_event));
368 gst_pad_new_from_static_template (&gst_jpeg_dec_src_pad_template, "src");
369 gst_pad_set_event_function (dec->srcpad,
370 GST_DEBUG_FUNCPTR (gst_jpeg_dec_src_event));
371 gst_pad_use_fixed_caps (dec->srcpad);
372 gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
375 memset (&dec->cinfo, 0, sizeof (dec->cinfo));
376 memset (&dec->jerr, 0, sizeof (dec->jerr));
377 dec->cinfo.err = jpeg_std_error (&dec->jerr.pub);
378 dec->jerr.pub.output_message = gst_jpeg_dec_my_output_message;
379 dec->jerr.pub.emit_message = gst_jpeg_dec_my_emit_message;
380 dec->jerr.pub.error_exit = gst_jpeg_dec_my_error_exit;
382 jpeg_create_decompress (&dec->cinfo);
384 dec->cinfo.src = (struct jpeg_source_mgr *) &dec->jsrc;
385 dec->cinfo.src->init_source = gst_jpeg_dec_init_source;
386 dec->cinfo.src->fill_input_buffer = gst_jpeg_dec_fill_input_buffer;
387 dec->cinfo.src->skip_input_data = gst_jpeg_dec_skip_input_data;
388 dec->cinfo.src->resync_to_restart = gst_jpeg_dec_resync_to_restart;
389 dec->cinfo.src->term_source = gst_jpeg_dec_term_source;
392 /* init properties */
393 dec->idct_method = JPEG_DEFAULT_IDCT_METHOD;
394 dec->max_errors = JPEG_DEFAULT_MAX_ERRORS;
396 dec->adapter = gst_adapter_new ();
400 gst_jpeg_dec_ensure_header (GstJpegDec * dec)
405 av = gst_adapter_available (dec->adapter);
406 /* we expect at least 4 bytes, first of which start marker */
407 offset = gst_adapter_masked_scan_uint32 (dec->adapter, 0xffffff00, 0xffd8ff00,
409 if (G_UNLIKELY (offset < 0)) {
410 GST_DEBUG_OBJECT (dec, "No JPEG header in current buffer");
413 gst_adapter_flush (dec->adapter, av - 4);
418 GST_LOG_OBJECT (dec, "Skipping %u bytes.", offset);
419 gst_adapter_flush (dec->adapter, offset);
421 GST_DEBUG_OBJECT (dec, "Found JPEG header");
426 static inline gboolean
427 gst_jpeg_dec_parse_tag_has_entropy_segment (guint8 tag)
429 if (tag == 0xda || (tag >= 0xd0 && tag <= 0xd7))
434 /* returns image length in bytes if parsed successfully,
435 * otherwise 0 if more data needed,
436 * if < 0 the absolute value needs to be flushed */
438 gst_jpeg_dec_parse_image_data (GstJpegDec * dec)
442 GstAdapter *adapter = dec->adapter;
443 gint offset, noffset;
445 size = gst_adapter_available (adapter);
447 /* we expect at least 4 bytes, first of which start marker */
448 if (gst_adapter_masked_scan_uint32 (adapter, 0xffff0000, 0xffd80000, 0, 4))
451 GST_DEBUG ("Parsing jpeg image data (%u bytes)", size);
453 GST_DEBUG ("Parse state: offset=%d, resync=%d, entropy len=%d",
454 dec->parse_offset, dec->parse_resync, dec->parse_entropy_len);
456 /* offset is 2 less than actual offset;
457 * - adapter needs at least 4 bytes for scanning,
458 * - start and end marker ensure at least that much
460 /* resume from state offset */
461 offset = dec->parse_offset;
468 gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00, 0x0000ff00,
469 offset, size - offset, &value);
470 /* lost sync if 0xff marker not where expected */
471 if ((resync = (noffset != offset))) {
472 GST_DEBUG ("Lost sync at 0x%08x, resyncing", offset + 2);
474 /* may have marker, but could have been resyncng */
475 resync = resync || dec->parse_resync;
476 /* Skip over extra 0xff */
477 while ((noffset >= 0) && ((value & 0xff) == 0xff)) {
480 gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00, 0x0000ff00,
481 noffset, size - noffset, &value);
483 /* enough bytes left for marker? (we need 0xNN after the 0xff) */
485 GST_DEBUG ("at end of input and no EOI marker found, need more data");
489 /* now lock on the marker we found */
491 value = value & 0xff;
493 GST_DEBUG ("0x%08x: EOI marker", offset + 2);
494 /* clear parse state */
495 dec->parse_resync = FALSE;
496 dec->parse_offset = 0;
498 } else if (value == 0xd8) {
499 /* Skip this frame if we found another SOI marker */
500 GST_DEBUG ("0x%08x: SOI marker before EOI, skipping", offset + 2);
501 dec->parse_resync = FALSE;
502 dec->parse_offset = 0;
503 return -(offset + 2);
507 if (value >= 0xd0 && value <= 0xd7)
510 /* peek tag and subsequent length */
511 if (offset + 2 + 4 > size)
514 gst_adapter_masked_scan_uint32_peek (adapter, 0x0, 0x0, offset + 2, 4,
516 frame_len = frame_len & 0xffff;
518 GST_DEBUG ("0x%08x: tag %02x, frame_len=%u", offset + 2, value, frame_len);
519 /* the frame length includes the 2 bytes for the length; here we want at
520 * least 2 more bytes at the end for an end marker */
521 if (offset + 2 + 2 + frame_len + 2 > size) {
525 if (gst_jpeg_dec_parse_tag_has_entropy_segment (value)) {
526 guint eseglen = dec->parse_entropy_len;
528 GST_DEBUG ("0x%08x: finding entropy segment length", offset + 2);
529 noffset = offset + 2 + frame_len + dec->parse_entropy_len;
531 noffset = gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00,
532 0x0000ff00, noffset, size - noffset, &value);
535 dec->parse_entropy_len = size - offset - 4 - frame_len - 2;
538 if ((value & 0xff) != 0x00) {
539 eseglen = noffset - offset - frame_len - 2;
544 dec->parse_entropy_len = 0;
545 frame_len += eseglen;
546 GST_DEBUG ("entropy segment length=%u => frame_len=%u", eseglen,
550 /* check if we will still be in sync if we interpret
551 * this as a sync point and skip this frame */
552 noffset = offset + frame_len + 2;
553 noffset = gst_adapter_masked_scan_uint32 (adapter, 0x0000ff00, 0x0000ff00,
556 /* ignore and continue resyncing until we hit the end
557 * of our data or find a sync point that looks okay */
561 GST_DEBUG ("found sync at 0x%x", offset + 2);
564 offset += frame_len + 2;
570 dec->parse_offset = offset;
571 dec->parse_resync = resync;
576 /* shamelessly ripped from jpegutils.c in mjpegtools */
578 add_huff_table (j_decompress_ptr dinfo,
579 JHUFF_TBL ** htblptr, const UINT8 * bits, const UINT8 * val)
580 /* Define a Huffman table */
584 if (*htblptr == NULL)
585 *htblptr = jpeg_alloc_huff_table ((j_common_ptr) dinfo);
589 /* Copy the number-of-symbols-of-each-code-length counts */
590 memcpy ((*htblptr)->bits, bits, sizeof ((*htblptr)->bits));
592 /* Validate the counts. We do this here mainly so we can copy the right
593 * number of symbols from the val[] array, without risking marching off
594 * the end of memory. jchuff.c will do a more thorough test later.
597 for (len = 1; len <= 16; len++)
598 nsymbols += bits[len];
599 if (nsymbols < 1 || nsymbols > 256)
600 g_error ("jpegutils.c: add_huff_table failed badly. ");
602 memcpy ((*htblptr)->huffval, val, nsymbols * sizeof (UINT8));
608 std_huff_tables (j_decompress_ptr dinfo)
609 /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
610 /* IMPORTANT: these are only valid for 8-bit data precision! */
612 static const UINT8 bits_dc_luminance[17] =
613 { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
614 static const UINT8 val_dc_luminance[] =
615 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
617 static const UINT8 bits_dc_chrominance[17] =
618 { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
619 static const UINT8 val_dc_chrominance[] =
620 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
622 static const UINT8 bits_ac_luminance[17] =
623 { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
624 static const UINT8 val_ac_luminance[] =
625 { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
626 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
627 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
628 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
629 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
630 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
631 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
632 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
633 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
634 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
635 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
636 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
637 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
638 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
639 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
640 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
641 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
642 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
643 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
644 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
648 static const UINT8 bits_ac_chrominance[17] =
649 { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
650 static const UINT8 val_ac_chrominance[] =
651 { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
652 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
653 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
654 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
655 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
656 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
657 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
658 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
659 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
660 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
661 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
662 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
663 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
664 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
665 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
666 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
667 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
668 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
669 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
670 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
674 add_huff_table (dinfo, &dinfo->dc_huff_tbl_ptrs[0],
675 bits_dc_luminance, val_dc_luminance);
676 add_huff_table (dinfo, &dinfo->ac_huff_tbl_ptrs[0],
677 bits_ac_luminance, val_ac_luminance);
678 add_huff_table (dinfo, &dinfo->dc_huff_tbl_ptrs[1],
679 bits_dc_chrominance, val_dc_chrominance);
680 add_huff_table (dinfo, &dinfo->ac_huff_tbl_ptrs[1],
681 bits_ac_chrominance, val_ac_chrominance);
687 guarantee_huff_tables (j_decompress_ptr dinfo)
689 if ((dinfo->dc_huff_tbl_ptrs[0] == NULL) &&
690 (dinfo->dc_huff_tbl_ptrs[1] == NULL) &&
691 (dinfo->ac_huff_tbl_ptrs[0] == NULL) &&
692 (dinfo->ac_huff_tbl_ptrs[1] == NULL)) {
693 GST_DEBUG ("Generating standard Huffman tables for this frame.");
694 std_huff_tables (dinfo);
699 gst_jpeg_dec_setcaps (GstJpegDec * dec, GstCaps * caps)
702 const GValue *framerate;
704 s = gst_caps_get_structure (caps, 0);
706 if ((framerate = gst_structure_get_value (s, "framerate")) != NULL) {
707 dec->in_fps_n = gst_value_get_fraction_numerator (framerate);
708 dec->in_fps_d = gst_value_get_fraction_denominator (framerate);
709 dec->packetized = TRUE;
710 GST_DEBUG ("got framerate of %d/%d fps => packetized mode",
711 dec->in_fps_n, dec->in_fps_d);
714 /* do not extract width/height here. we do that in the chain
715 * function on a per-frame basis (including the line[] array
718 /* But we can take the framerate values and set them on the src pad */
724 gst_jpeg_dec_getcaps (GstPad * pad, GstCaps * filter)
730 dec = GST_JPEG_DEC (GST_OBJECT_PARENT (pad));
732 if (gst_pad_has_current_caps (pad))
733 return gst_pad_get_current_caps (pad);
735 peer = gst_pad_get_peer (dec->srcpad);
739 const GstCaps *templ_caps;
743 peer_caps = gst_pad_get_caps (peer, filter);
745 /* Translate peercaps to image/jpeg */
746 peer_caps = gst_caps_make_writable (peer_caps);
747 n = gst_caps_get_size (peer_caps);
748 for (i = 0; i < n; i++) {
749 s = gst_caps_get_structure (peer_caps, i);
751 gst_structure_set_name (s, "image/jpeg");
754 templ_caps = gst_pad_get_pad_template_caps (pad);
755 caps = gst_caps_intersect_full (peer_caps, templ_caps,
756 GST_CAPS_INTERSECT_FIRST);
758 gst_object_unref (peer);
760 caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
769 hresamplecpy1 (guint8 * dest, const guint8 * src, guint len)
773 for (i = 0; i < len; ++i) {
774 /* equivalent to: dest[i] = src[i << 1] */
783 gst_jpeg_dec_free_buffers (GstJpegDec * dec)
787 for (i = 0; i < 16; i++) {
788 g_free (dec->idr_y[i]);
789 g_free (dec->idr_u[i]);
790 g_free (dec->idr_v[i]);
791 dec->idr_y[i] = NULL;
792 dec->idr_u[i] = NULL;
793 dec->idr_v[i] = NULL;
796 dec->idr_width_allocated = 0;
799 static inline gboolean
800 gst_jpeg_dec_ensure_buffers (GstJpegDec * dec, guint maxrowbytes)
804 if (G_LIKELY (dec->idr_width_allocated >= maxrowbytes))
807 /* FIXME: maybe just alloc one or three blocks altogether? */
808 for (i = 0; i < 16; i++) {
809 dec->idr_y[i] = g_try_realloc (dec->idr_y[i], maxrowbytes);
810 dec->idr_u[i] = g_try_realloc (dec->idr_u[i], maxrowbytes);
811 dec->idr_v[i] = g_try_realloc (dec->idr_v[i], maxrowbytes);
813 if (G_UNLIKELY (!dec->idr_y[i] || !dec->idr_u[i] || !dec->idr_v[i])) {
814 GST_WARNING_OBJECT (dec, "out of memory, i=%d, bytes=%u", i, maxrowbytes);
819 dec->idr_width_allocated = maxrowbytes;
820 GST_LOG_OBJECT (dec, "allocated temp memory, %u bytes/row", maxrowbytes);
825 gst_jpeg_dec_decode_grayscale (GstJpegDec * dec, GstVideoFrame * frame)
828 guchar **scanarray[1] = { rows };
833 gint pstride, rstride;
835 GST_DEBUG_OBJECT (dec, "indirect decoding of grayscale");
837 width = GST_VIDEO_FRAME_WIDTH (frame);
838 height = GST_VIDEO_FRAME_HEIGHT (frame);
840 if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
843 base[0] = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
844 pstride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0);
845 rstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
847 memcpy (rows, dec->idr_y, 16 * sizeof (gpointer));
851 lines = jpeg_read_raw_data (&dec->cinfo, scanarray, DCTSIZE);
852 if (G_LIKELY (lines > 0)) {
853 for (j = 0; (j < DCTSIZE) && (i < height); j++, i++) {
857 for (k = 0; k < width; k++) {
858 base[0][p] = rows[j][k];
864 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
870 gst_jpeg_dec_decode_rgb (GstJpegDec * dec, GstVideoFrame * frame)
872 guchar *r_rows[16], *g_rows[16], *b_rows[16];
873 guchar **scanarray[3] = { r_rows, g_rows, b_rows };
877 guint pstride, rstride;
880 GST_DEBUG_OBJECT (dec, "indirect decoding of RGB");
882 width = GST_VIDEO_FRAME_WIDTH (frame);
883 height = GST_VIDEO_FRAME_HEIGHT (frame);
885 if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
888 for (i = 0; i < 3; i++)
889 base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
891 pstride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0);
892 rstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
894 memcpy (r_rows, dec->idr_y, 16 * sizeof (gpointer));
895 memcpy (g_rows, dec->idr_u, 16 * sizeof (gpointer));
896 memcpy (b_rows, dec->idr_v, 16 * sizeof (gpointer));
900 lines = jpeg_read_raw_data (&dec->cinfo, scanarray, DCTSIZE);
901 if (G_LIKELY (lines > 0)) {
902 for (j = 0; (j < DCTSIZE) && (i < height); j++, i++) {
906 for (k = 0; k < width; k++) {
907 base[0][p] = r_rows[j][k];
908 base[1][p] = g_rows[j][k];
909 base[2][p] = b_rows[j][k];
917 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
923 gst_jpeg_dec_decode_indirect (GstJpegDec * dec, GstVideoFrame * frame,
924 gint r_v, gint r_h, gint comp)
926 guchar *y_rows[16], *u_rows[16], *v_rows[16];
927 guchar **scanarray[3] = { y_rows, u_rows, v_rows };
930 guchar *base[3], *last[3];
934 GST_DEBUG_OBJECT (dec,
935 "unadvantageous width or r_h, taking slow route involving memcpy");
937 width = GST_VIDEO_FRAME_WIDTH (frame);
938 height = GST_VIDEO_FRAME_HEIGHT (frame);
940 if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
943 for (i = 0; i < 3; i++) {
944 base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
945 stride[i] = GST_VIDEO_FRAME_COMP_STRIDE (frame, i);
946 /* make sure we don't make jpeglib write beyond our buffer,
947 * which might happen if (height % (r_v*DCTSIZE)) != 0 */
948 last[i] = base[i] + (GST_VIDEO_FRAME_COMP_STRIDE (frame, i) *
949 (GST_VIDEO_FRAME_COMP_HEIGHT (frame, i) - 1));
952 memcpy (y_rows, dec->idr_y, 16 * sizeof (gpointer));
953 memcpy (u_rows, dec->idr_u, 16 * sizeof (gpointer));
954 memcpy (v_rows, dec->idr_v, 16 * sizeof (gpointer));
956 /* fill chroma components for grayscale */
958 GST_DEBUG_OBJECT (dec, "grayscale, filling chroma");
959 for (i = 0; i < 16; i++) {
960 memset (u_rows[i], GST_ROUND_UP_32 (width), 0x80);
961 memset (v_rows[i], GST_ROUND_UP_32 (width), 0x80);
965 for (i = 0; i < height; i += r_v * DCTSIZE) {
966 lines = jpeg_read_raw_data (&dec->cinfo, scanarray, r_v * DCTSIZE);
967 if (G_LIKELY (lines > 0)) {
968 for (j = 0, k = 0; j < (r_v * DCTSIZE); j += r_v, k++) {
969 if (G_LIKELY (base[0] <= last[0])) {
970 memcpy (base[0], y_rows[j], stride[0]);
971 base[0] += stride[0];
974 if (G_LIKELY (base[0] <= last[0])) {
975 memcpy (base[0], y_rows[j + 1], stride[0]);
976 base[0] += stride[0];
979 if (G_LIKELY (base[1] <= last[1] && base[2] <= last[2])) {
981 memcpy (base[1], u_rows[k], stride[1]);
982 memcpy (base[2], v_rows[k], stride[2]);
983 } else if (r_h == 1) {
984 hresamplecpy1 (base[1], u_rows[k], stride[1]);
985 hresamplecpy1 (base[2], v_rows[k], stride[2]);
987 /* FIXME: implement (at least we avoid crashing by doing nothing) */
991 if (r_v == 2 || (k & 1) != 0) {
992 base[1] += stride[1];
993 base[2] += stride[2];
997 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
1002 static GstFlowReturn
1003 gst_jpeg_dec_decode_direct (GstJpegDec * dec, GstVideoFrame * frame)
1005 guchar **line[3]; /* the jpeg line buffer */
1006 guchar *y[4 * DCTSIZE] = { NULL, }; /* alloc enough for the lines */
1007 guchar *u[4 * DCTSIZE] = { NULL, }; /* r_v will be <4 */
1008 guchar *v[4 * DCTSIZE] = { NULL, };
1010 gint lines, v_samp[3];
1011 guchar *base[3], *last[3];
1019 v_samp[0] = dec->cinfo.comp_info[0].v_samp_factor;
1020 v_samp[1] = dec->cinfo.comp_info[1].v_samp_factor;
1021 v_samp[2] = dec->cinfo.comp_info[2].v_samp_factor;
1023 if (G_UNLIKELY (v_samp[0] > 2 || v_samp[1] > 2 || v_samp[2] > 2))
1024 goto format_not_supported;
1026 height = GST_VIDEO_FRAME_HEIGHT (frame);
1028 for (i = 0; i < 3; i++) {
1029 base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
1030 stride[i] = GST_VIDEO_FRAME_COMP_STRIDE (frame, i);
1031 /* make sure we don't make jpeglib write beyond our buffer,
1032 * which might happen if (height % (r_v*DCTSIZE)) != 0 */
1033 last[i] = base[i] + (GST_VIDEO_FRAME_COMP_STRIDE (frame, i) *
1034 (GST_VIDEO_FRAME_COMP_HEIGHT (frame, i) - 1));
1037 /* let jpeglib decode directly into our final buffer */
1038 GST_DEBUG_OBJECT (dec, "decoding directly into output buffer");
1040 for (i = 0; i < height; i += v_samp[0] * DCTSIZE) {
1041 for (j = 0; j < (v_samp[0] * DCTSIZE); ++j) {
1043 line[0][j] = base[0] + (i + j) * stride[0];
1044 if (G_UNLIKELY (line[0][j] > last[0]))
1045 line[0][j] = last[0];
1047 if (v_samp[1] == v_samp[0]) {
1048 line[1][j] = base[1] + ((i + j) / 2) * stride[1];
1049 } else if (j < (v_samp[1] * DCTSIZE)) {
1050 line[1][j] = base[1] + ((i / 2) + j) * stride[1];
1052 if (G_UNLIKELY (line[1][j] > last[1]))
1053 line[1][j] = last[1];
1055 if (v_samp[2] == v_samp[0]) {
1056 line[2][j] = base[2] + ((i + j) / 2) * stride[2];
1057 } else if (j < (v_samp[2] * DCTSIZE)) {
1058 line[2][j] = base[2] + ((i / 2) + j) * stride[2];
1060 if (G_UNLIKELY (line[2][j] > last[2]))
1061 line[2][j] = last[2];
1064 lines = jpeg_read_raw_data (&dec->cinfo, line, v_samp[0] * DCTSIZE);
1065 if (G_UNLIKELY (!lines)) {
1066 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
1071 format_not_supported:
1073 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1074 "Unsupported subsampling schema: v_samp factors: %u %u %u",
1075 v_samp[0], v_samp[1], v_samp[2]);
1076 return GST_FLOW_ERROR;
1081 gst_jpeg_dec_update_qos (GstJpegDec * dec, gdouble proportion,
1082 GstClockTimeDiff diff, GstClockTime ts)
1084 GST_OBJECT_LOCK (dec);
1085 dec->proportion = proportion;
1086 if (G_LIKELY (ts != GST_CLOCK_TIME_NONE)) {
1087 if (G_UNLIKELY (diff > dec->qos_duration))
1088 dec->earliest_time = ts + 2 * diff + dec->qos_duration;
1090 dec->earliest_time = ts + diff;
1092 dec->earliest_time = GST_CLOCK_TIME_NONE;
1094 GST_OBJECT_UNLOCK (dec);
1098 gst_jpeg_dec_reset_qos (GstJpegDec * dec)
1100 gst_jpeg_dec_update_qos (dec, 0.5, 0, GST_CLOCK_TIME_NONE);
1104 gst_jpeg_dec_read_qos (GstJpegDec * dec, gdouble * proportion,
1105 GstClockTime * time)
1107 GST_OBJECT_LOCK (dec);
1108 *proportion = dec->proportion;
1109 *time = dec->earliest_time;
1110 GST_OBJECT_UNLOCK (dec);
1113 /* Perform qos calculations before decoding the next frame. Returns TRUE if the
1114 * frame should be decoded, FALSE if the frame can be dropped entirely */
1116 gst_jpeg_dec_do_qos (GstJpegDec * dec, GstClockTime timestamp)
1118 GstClockTime qostime, earliest_time;
1121 /* no timestamp, can't do QoS => decode frame */
1122 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (timestamp))) {
1123 GST_LOG_OBJECT (dec, "invalid timestamp, can't do QoS, decode frame");
1127 /* get latest QoS observation values */
1128 gst_jpeg_dec_read_qos (dec, &proportion, &earliest_time);
1130 /* skip qos if we have no observation (yet) => decode frame */
1131 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (earliest_time))) {
1132 GST_LOG_OBJECT (dec, "no observation yet, decode frame");
1136 /* qos is done on running time */
1137 qostime = gst_segment_to_running_time (&dec->segment, GST_FORMAT_TIME,
1140 /* see how our next timestamp relates to the latest qos timestamp */
1141 GST_LOG_OBJECT (dec, "qostime %" GST_TIME_FORMAT ", earliest %"
1142 GST_TIME_FORMAT, GST_TIME_ARGS (qostime), GST_TIME_ARGS (earliest_time));
1144 if (qostime != GST_CLOCK_TIME_NONE && qostime <= earliest_time) {
1145 GST_DEBUG_OBJECT (dec, "we are late, drop frame");
1149 GST_LOG_OBJECT (dec, "decode frame");
1154 gst_jpeg_dec_buffer_pool (GstJpegDec * dec, GstCaps * caps)
1157 GstBufferPool *pool = NULL;
1158 guint size, min, max, prefix, alignment;
1159 GstStructure *config;
1161 GST_DEBUG_OBJECT (dec, "setting up bufferpool");
1163 /* find a pool for the negotiated caps now */
1164 query = gst_query_new_allocation (caps, TRUE);
1166 if (gst_pad_peer_query (dec->srcpad, query)) {
1167 /* we got configuration from our peer, parse them */
1168 gst_query_parse_allocation_params (query, &size, &min, &max, &prefix,
1170 size = MAX (size, dec->info.size);
1172 GST_DEBUG_OBJECT (dec, "peer query failed, using defaults");
1173 size = dec->info.size;
1178 gst_query_unref (query);
1181 /* we did not get a pool, make one ourselves then */
1182 pool = gst_buffer_pool_new ();
1185 config = gst_buffer_pool_get_config (pool);
1186 gst_buffer_pool_config_set (config, caps, size, min, max, prefix,
1189 gst_buffer_pool_set_config (pool, config);
1192 gst_buffer_pool_set_active (dec->pool, FALSE);
1193 gst_object_unref (dec->pool);
1198 gst_buffer_pool_set_active (pool, TRUE);
1204 gst_jpeg_dec_negotiate (GstJpegDec * dec, gint width, gint height, gint clrspc)
1207 GstVideoFormat format;
1210 if (G_UNLIKELY (width == dec->info.width && height == dec->info.height &&
1211 dec->in_fps_n == dec->info.fps_n && dec->in_fps_d == dec->info.fps_d
1212 && clrspc == dec->clrspc))
1215 gst_video_info_init (&info);
1217 /* framerate == 0/1 is a still frame */
1218 if (dec->in_fps_d == 0) {
1222 info.fps_n = dec->in_fps_n;
1223 info.fps_d = dec->in_fps_d;
1226 /* calculate or assume an average frame duration for QoS purposes */
1227 GST_OBJECT_LOCK (dec);
1228 if (info.fps_n != 0) {
1230 gst_util_uint64_scale (GST_SECOND, info.fps_d, info.fps_n);
1231 dec->duration = dec->qos_duration;
1233 /* if not set just use 25fps */
1234 dec->qos_duration = gst_util_uint64_scale (GST_SECOND, 1, 25);
1235 dec->duration = GST_CLOCK_TIME_NONE;
1237 GST_OBJECT_UNLOCK (dec);
1239 if (dec->cinfo.jpeg_color_space == JCS_RGB) {
1241 GstCaps *allowed_caps;
1242 GstVideoInfo tmpinfo;
1244 GST_DEBUG_OBJECT (dec, "selecting RGB format");
1245 /* retrieve allowed caps, and find the first one that reasonably maps
1246 * to the parameters of the colourspace */
1247 caps = gst_pad_get_allowed_caps (dec->srcpad);
1249 GST_DEBUG_OBJECT (dec, "... but no peer, using template caps");
1250 /* need to copy because get_allowed_caps returns a ref,
1251 * and get_pad_template_caps doesn't */
1252 caps = gst_caps_copy (gst_pad_get_pad_template_caps (dec->srcpad));
1254 /* avoid lists of formats, etc */
1255 allowed_caps = gst_caps_normalize (caps);
1256 gst_caps_unref (caps);
1258 GST_LOG_OBJECT (dec, "allowed source caps %" GST_PTR_FORMAT, allowed_caps);
1260 for (i = 0; i < gst_caps_get_size (allowed_caps); i++) {
1262 gst_caps_unref (caps);
1263 caps = gst_caps_copy_nth (allowed_caps, i);
1264 /* sigh, ds and _parse_caps need fixed caps for parsing, fixate */
1265 gst_pad_fixate_caps (dec->srcpad, caps);
1266 GST_LOG_OBJECT (dec, "checking caps %" GST_PTR_FORMAT, caps);
1268 if (!gst_video_info_from_caps (&tmpinfo, caps))
1270 /* we'll settle for the first (preferred) downstream rgb format */
1271 if (GST_VIDEO_INFO_IS_RGB (&tmpinfo))
1273 /* default fall-back */
1274 format = GST_VIDEO_FORMAT_RGB;
1277 gst_caps_unref (caps);
1278 gst_caps_unref (allowed_caps);
1279 } else if (dec->cinfo.jpeg_color_space == JCS_GRAYSCALE) {
1280 /* TODO is anything else then 8bit supported in jpeg? */
1281 format = GST_VIDEO_FORMAT_GRAY8;
1283 /* go for plain and simple I420 */
1284 /* TODO other YUV cases ? */
1285 format = GST_VIDEO_FORMAT_I420;
1288 gst_video_info_set_format (&info, format, width, height);
1289 caps = gst_video_info_to_caps (&info);
1291 GST_DEBUG_OBJECT (dec, "setting caps %" GST_PTR_FORMAT, caps);
1292 GST_DEBUG_OBJECT (dec, "max_v_samp_factor=%d", dec->cinfo.max_v_samp_factor);
1293 GST_DEBUG_OBJECT (dec, "max_h_samp_factor=%d", dec->cinfo.max_h_samp_factor);
1295 gst_pad_set_caps (dec->srcpad, caps);
1298 dec->clrspc = clrspc;
1300 gst_jpeg_dec_buffer_pool (dec, caps);
1301 gst_caps_unref (caps);
1306 static GstFlowReturn
1307 gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf)
1309 GstFlowReturn ret = GST_FLOW_OK;
1311 GstBuffer *outbuf = NULL;
1316 GstClockTime timestamp, duration;
1317 GstVideoFrame frame;
1319 dec = GST_JPEG_DEC (GST_PAD_PARENT (pad));
1321 timestamp = GST_BUFFER_TIMESTAMP (buf);
1322 duration = GST_BUFFER_DURATION (buf);
1324 if (GST_CLOCK_TIME_IS_VALID (timestamp))
1325 dec->next_ts = timestamp;
1327 if (GST_BUFFER_IS_DISCONT (buf)) {
1328 GST_DEBUG_OBJECT (dec, "buffer has DISCONT flag set");
1329 dec->discont = TRUE;
1330 if (!dec->packetized && gst_adapter_available (dec->adapter)) {
1331 GST_WARNING_OBJECT (dec, "DISCONT buffer in non-packetized mode, bad");
1332 gst_adapter_clear (dec->adapter);
1336 gst_adapter_push (dec->adapter, buf);
1339 /* If we are non-packetized and know the total incoming size in bytes,
1340 * just wait until we have enough before doing any processing. */
1342 if (!dec->packetized && (dec->segment.format == GST_FORMAT_BYTES) &&
1343 (dec->segment.stop != -1) &&
1344 (gst_adapter_available (dec->adapter) < dec->segment.stop)) {
1345 /* We assume that non-packetized input in bytes is *one* single jpeg image */
1346 GST_DEBUG ("Non-packetized mode. Got %d bytes, need %" G_GINT64_FORMAT,
1347 gst_adapter_available (dec->adapter), dec->segment.stop);
1348 goto need_more_data;
1352 if (!gst_jpeg_dec_ensure_header (dec))
1353 goto need_more_data;
1355 /* If we know that each input buffer contains data
1356 * for a whole jpeg image (e.g. MJPEG streams), just
1357 * do some sanity checking instead of parsing all of
1359 if (dec->packetized) {
1360 img_len = gst_adapter_available (dec->adapter);
1362 /* Parse jpeg image to handle jpeg input that
1363 * is not aligned to buffer boundaries */
1364 img_len = gst_jpeg_dec_parse_image_data (dec);
1367 goto need_more_data;
1368 } else if (img_len < 0) {
1369 gst_adapter_flush (dec->adapter, -img_len);
1374 dec->rem_img_len = img_len;
1376 GST_LOG_OBJECT (dec, "image size = %u", img_len);
1378 /* QoS: if we're too late anyway, skip decoding */
1379 if (dec->packetized && !gst_jpeg_dec_do_qos (dec, timestamp))
1382 #ifndef GST_DISABLE_GST_DEBUG
1386 gst_adapter_copy (dec->adapter, data, 0, 4);
1387 GST_LOG_OBJECT (dec, "reading header %02x %02x %02x %02x", data[0], data[1],
1392 gst_jpeg_dec_fill_input_buffer (&dec->cinfo);
1394 if (setjmp (dec->jerr.setjmp_buffer)) {
1395 code = dec->jerr.pub.msg_code;
1397 if (code == JERR_INPUT_EOF) {
1398 GST_DEBUG ("jpeg input EOF error, we probably need more data");
1399 goto need_more_data;
1405 hdr_ok = jpeg_read_header (&dec->cinfo, TRUE);
1406 if (G_UNLIKELY (hdr_ok != JPEG_HEADER_OK)) {
1407 GST_WARNING_OBJECT (dec, "reading the header failed, %d", hdr_ok);
1410 GST_LOG_OBJECT (dec, "num_components=%d", dec->cinfo.num_components);
1411 GST_LOG_OBJECT (dec, "jpeg_color_space=%d", dec->cinfo.jpeg_color_space);
1413 if (!dec->cinfo.num_components || !dec->cinfo.comp_info)
1414 goto components_not_supported;
1416 r_h = dec->cinfo.comp_info[0].h_samp_factor;
1417 r_v = dec->cinfo.comp_info[0].v_samp_factor;
1419 GST_LOG_OBJECT (dec, "r_h = %d, r_v = %d", r_h, r_v);
1421 if (dec->cinfo.num_components > 3)
1422 goto components_not_supported;
1424 /* verify color space expectation to avoid going *boom* or bogus output */
1425 if (dec->cinfo.jpeg_color_space != JCS_YCbCr &&
1426 dec->cinfo.jpeg_color_space != JCS_GRAYSCALE &&
1427 dec->cinfo.jpeg_color_space != JCS_RGB)
1428 goto unsupported_colorspace;
1430 #ifndef GST_DISABLE_GST_DEBUG
1434 for (i = 0; i < dec->cinfo.num_components; ++i) {
1435 GST_LOG_OBJECT (dec, "[%d] h_samp_factor=%d, v_samp_factor=%d, cid=%d",
1436 i, dec->cinfo.comp_info[i].h_samp_factor,
1437 dec->cinfo.comp_info[i].v_samp_factor,
1438 dec->cinfo.comp_info[i].component_id);
1443 /* prepare for raw output */
1444 dec->cinfo.do_fancy_upsampling = FALSE;
1445 dec->cinfo.do_block_smoothing = FALSE;
1446 dec->cinfo.out_color_space = dec->cinfo.jpeg_color_space;
1447 dec->cinfo.dct_method = dec->idct_method;
1448 dec->cinfo.raw_data_out = TRUE;
1450 GST_LOG_OBJECT (dec, "starting decompress");
1451 guarantee_huff_tables (&dec->cinfo);
1452 if (!jpeg_start_decompress (&dec->cinfo)) {
1453 GST_WARNING_OBJECT (dec, "failed to start decompression cycle");
1456 /* sanity checks to get safe and reasonable output */
1457 switch (dec->cinfo.jpeg_color_space) {
1459 if (dec->cinfo.num_components != 1)
1460 goto invalid_yuvrgbgrayscale;
1463 if (dec->cinfo.num_components != 3 || dec->cinfo.max_v_samp_factor > 1 ||
1464 dec->cinfo.max_h_samp_factor > 1)
1465 goto invalid_yuvrgbgrayscale;
1468 if (dec->cinfo.num_components != 3 ||
1469 r_v > 2 || r_v < dec->cinfo.comp_info[0].v_samp_factor ||
1470 r_v < dec->cinfo.comp_info[1].v_samp_factor ||
1471 r_h < dec->cinfo.comp_info[0].h_samp_factor ||
1472 r_h < dec->cinfo.comp_info[1].h_samp_factor)
1473 goto invalid_yuvrgbgrayscale;
1476 g_assert_not_reached ();
1480 width = dec->cinfo.output_width;
1481 height = dec->cinfo.output_height;
1483 if (G_UNLIKELY (width < MIN_WIDTH || width > MAX_WIDTH ||
1484 height < MIN_HEIGHT || height > MAX_HEIGHT))
1487 gst_jpeg_dec_negotiate (dec, width, height, dec->cinfo.jpeg_color_space);
1489 ret = gst_buffer_pool_acquire_buffer (dec->pool, &outbuf, NULL);
1490 if (G_UNLIKELY (ret != GST_FLOW_OK))
1493 if (!gst_video_frame_map (&frame, &dec->info, outbuf, GST_MAP_READWRITE))
1496 GST_LOG_OBJECT (dec, "width %d, height %d", width, height);
1498 GST_BUFFER_TIMESTAMP (outbuf) = dec->next_ts;
1500 if (dec->packetized && GST_CLOCK_TIME_IS_VALID (dec->next_ts)) {
1501 if (GST_CLOCK_TIME_IS_VALID (duration)) {
1502 /* use duration from incoming buffer for outgoing buffer */
1503 dec->next_ts += duration;
1504 } else if (GST_CLOCK_TIME_IS_VALID (dec->duration)) {
1505 duration = dec->duration;
1506 dec->next_ts += dec->duration;
1508 duration = GST_CLOCK_TIME_NONE;
1509 dec->next_ts = GST_CLOCK_TIME_NONE;
1512 duration = GST_CLOCK_TIME_NONE;
1513 dec->next_ts = GST_CLOCK_TIME_NONE;
1515 GST_BUFFER_DURATION (outbuf) = duration;
1517 if (dec->cinfo.jpeg_color_space == JCS_RGB) {
1518 gst_jpeg_dec_decode_rgb (dec, &frame);
1519 } else if (dec->cinfo.jpeg_color_space == JCS_GRAYSCALE) {
1520 gst_jpeg_dec_decode_grayscale (dec, &frame);
1522 GST_LOG_OBJECT (dec, "decompressing (reqired scanline buffer height = %u)",
1523 dec->cinfo.rec_outbuf_height);
1525 /* For some widths jpeglib requires more horizontal padding than I420
1526 * provides. In those cases we need to decode into separate buffers and then
1527 * copy over the data into our final picture buffer, otherwise jpeglib might
1528 * write over the end of a line into the beginning of the next line,
1529 * resulting in blocky artifacts on the left side of the picture. */
1530 if (G_UNLIKELY (width % (dec->cinfo.max_h_samp_factor * DCTSIZE) != 0
1531 || dec->cinfo.comp_info[0].h_samp_factor != 2
1532 || dec->cinfo.comp_info[1].h_samp_factor != 1
1533 || dec->cinfo.comp_info[2].h_samp_factor != 1)) {
1534 GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, dec,
1535 "indirect decoding using extra buffer copy");
1536 gst_jpeg_dec_decode_indirect (dec, &frame, r_v, r_h,
1537 dec->cinfo.num_components);
1539 ret = gst_jpeg_dec_decode_direct (dec, &frame);
1540 if (G_UNLIKELY (ret != GST_FLOW_OK))
1541 goto decode_direct_failed;
1545 GST_LOG_OBJECT (dec, "decompressing finished");
1546 jpeg_finish_decompress (&dec->cinfo);
1548 gst_video_frame_unmap (&frame);
1551 if (dec->segment.format == GST_FORMAT_TIME) {
1552 guint64 start, stop, clip_start, clip_stop;
1554 GST_LOG_OBJECT (dec, "Attempting clipping");
1556 start = GST_BUFFER_TIMESTAMP (outbuf);
1557 if (GST_BUFFER_DURATION (outbuf) == GST_CLOCK_TIME_NONE)
1560 stop = start + GST_BUFFER_DURATION (outbuf);
1562 if (gst_segment_clip (&dec->segment, GST_FORMAT_TIME,
1563 start, stop, &clip_start, &clip_stop)) {
1564 GST_LOG_OBJECT (dec, "Clipping start to %" GST_TIME_FORMAT,
1565 GST_TIME_ARGS (clip_start));
1566 GST_BUFFER_TIMESTAMP (outbuf) = clip_start;
1567 if (GST_BUFFER_DURATION (outbuf) != GST_CLOCK_TIME_NONE) {
1568 GST_LOG_OBJECT (dec, "Clipping duration to %" GST_TIME_FORMAT,
1569 GST_TIME_ARGS (clip_stop - clip_start));
1570 GST_BUFFER_DURATION (outbuf) = clip_stop - clip_start;
1576 /* reset error count on successful decode */
1577 dec->error_count = 0;
1581 GST_LOG_OBJECT (dec, "pushing buffer (ts=%" GST_TIME_FORMAT ", dur=%"
1582 GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
1583 GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
1585 ret = gst_pad_push (dec->srcpad, outbuf);
1589 gst_adapter_flush (dec->adapter, dec->rem_img_len);
1593 if (G_UNLIKELY (ret == GST_FLOW_ERROR)) {
1594 jpeg_abort_decompress (&dec->cinfo);
1595 ret = gst_jpeg_dec_post_error_or_warning (dec);
1603 GST_LOG_OBJECT (dec, "we need more data");
1605 gst_buffer_unref (outbuf);
1614 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1615 "Picture is too small or too big (%ux%u)", width, height);
1616 ret = GST_FLOW_ERROR;
1621 gchar err_msg[JMSG_LENGTH_MAX];
1623 dec->jerr.pub.format_message ((j_common_ptr) (&dec->cinfo), err_msg);
1625 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1626 "Decode error #%u: %s", code, err_msg);
1629 gst_buffer_unref (outbuf);
1632 ret = GST_FLOW_ERROR;
1635 decode_direct_failed:
1637 /* already posted an error message */
1638 jpeg_abort_decompress (&dec->cinfo);
1639 gst_buffer_replace (&outbuf, NULL);
1644 const gchar *reason;
1646 reason = gst_flow_get_name (ret);
1648 GST_DEBUG_OBJECT (dec, "failed to alloc buffer, reason %s", reason);
1649 /* Reset for next time */
1650 jpeg_abort_decompress (&dec->cinfo);
1651 if (ret != GST_FLOW_UNEXPECTED && ret != GST_FLOW_WRONG_STATE &&
1652 ret != GST_FLOW_NOT_LINKED) {
1653 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1654 "Buffer allocation failed, reason: %s", reason);
1660 jpeg_abort_decompress (&dec->cinfo);
1661 gst_buffer_unref (outbuf);
1667 GST_WARNING_OBJECT (dec, "Outgoing buffer is outside configured segment");
1668 gst_buffer_unref (outbuf);
1672 components_not_supported:
1674 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1675 "number of components not supported: %d (max 3)",
1676 dec->cinfo.num_components);
1677 ret = GST_FLOW_ERROR;
1680 unsupported_colorspace:
1682 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1683 "Picture has unknown or unsupported colourspace");
1684 ret = GST_FLOW_ERROR;
1687 invalid_yuvrgbgrayscale:
1689 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1690 "Picture is corrupt or unhandled YUV/RGB/grayscale layout");
1691 ret = GST_FLOW_ERROR;
1697 gst_jpeg_dec_src_event (GstPad * pad, GstEvent * event)
1702 dec = GST_JPEG_DEC (gst_pad_get_parent (pad));
1703 if (G_UNLIKELY (dec == NULL)) {
1704 gst_event_unref (event);
1708 switch (GST_EVENT_TYPE (event)) {
1709 case GST_EVENT_QOS:{
1711 GstClockTimeDiff diff;
1712 GstClockTime timestamp;
1715 gst_event_parse_qos (event, &type, &proportion, &diff, ×tamp);
1716 gst_jpeg_dec_update_qos (dec, proportion, diff, timestamp);
1723 res = gst_pad_push_event (dec->sinkpad, event);
1725 gst_object_unref (dec);
1730 gst_jpeg_dec_sink_event (GstPad * pad, GstEvent * event)
1732 gboolean ret = TRUE, forward = TRUE;
1733 GstJpegDec *dec = GST_JPEG_DEC (GST_OBJECT_PARENT (pad));
1735 GST_DEBUG_OBJECT (dec, "event : %s", GST_EVENT_TYPE_NAME (event));
1737 switch (GST_EVENT_TYPE (event)) {
1738 case GST_EVENT_FLUSH_STOP:
1739 GST_DEBUG_OBJECT (dec, "Aborting decompress");
1740 jpeg_abort_decompress (&dec->cinfo);
1741 gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED);
1742 gst_adapter_clear (dec->adapter);
1743 g_free (dec->cur_buf);
1744 dec->cur_buf = NULL;
1745 dec->parse_offset = 0;
1746 dec->parse_entropy_len = 0;
1747 dec->parse_resync = FALSE;
1748 gst_jpeg_dec_reset_qos (dec);
1750 case GST_EVENT_SEGMENT:
1751 gst_event_copy_segment (event, &dec->segment);
1752 GST_DEBUG_OBJECT (dec, "Got NEWSEGMENT %" GST_SEGMENT_FORMAT,
1755 case GST_EVENT_CAPS:
1759 gst_event_parse_caps (event, &caps);
1760 ret = gst_jpeg_dec_setcaps (dec, caps);
1769 ret = gst_pad_push_event (dec->srcpad, event);
1771 gst_event_unref (event);
1777 gst_jpeg_dec_set_property (GObject * object, guint prop_id,
1778 const GValue * value, GParamSpec * pspec)
1782 dec = GST_JPEG_DEC (object);
1785 case PROP_IDCT_METHOD:
1786 dec->idct_method = g_value_get_enum (value);
1788 case PROP_MAX_ERRORS:
1789 g_atomic_int_set (&dec->max_errors, g_value_get_int (value));
1793 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1799 gst_jpeg_dec_get_property (GObject * object, guint prop_id, GValue * value,
1804 dec = GST_JPEG_DEC (object);
1807 case PROP_IDCT_METHOD:
1808 g_value_set_enum (value, dec->idct_method);
1810 case PROP_MAX_ERRORS:
1811 g_value_set_int (value, g_atomic_int_get (&dec->max_errors));
1815 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1820 static GstStateChangeReturn
1821 gst_jpeg_dec_change_state (GstElement * element, GstStateChange transition)
1823 GstStateChangeReturn ret;
1826 dec = GST_JPEG_DEC (element);
1828 switch (transition) {
1829 case GST_STATE_CHANGE_READY_TO_PAUSED:
1830 dec->error_count = 0;
1831 dec->good_count = 0;
1834 gst_video_info_init (&dec->info);
1836 dec->packetized = FALSE;
1838 dec->discont = TRUE;
1839 dec->parse_offset = 0;
1840 dec->parse_entropy_len = 0;
1841 dec->parse_resync = FALSE;
1842 dec->cur_buf = NULL;
1843 gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED);
1844 gst_jpeg_dec_reset_qos (dec);
1849 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1850 if (ret != GST_STATE_CHANGE_SUCCESS)
1853 switch (transition) {
1854 case GST_STATE_CHANGE_PAUSED_TO_READY:
1855 gst_adapter_clear (dec->adapter);
1856 g_free (dec->cur_buf);
1857 dec->cur_buf = NULL;
1858 gst_jpeg_dec_free_buffers (dec);
1860 gst_buffer_pool_set_active (dec->pool, FALSE);
1861 gst_object_unref (dec->pool);