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 gboolean gst_jpeg_dec_sink_event (GstPad * pad, GstEvent * event);
96 static gboolean gst_jpeg_dec_src_event (GstPad * pad, GstEvent * event);
97 static GstStateChangeReturn gst_jpeg_dec_change_state (GstElement * element,
98 GstStateChange transition);
99 static void gst_jpeg_dec_update_qos (GstJpegDec * dec, gdouble proportion,
100 GstClockTimeDiff diff, GstClockTime ts);
101 static void gst_jpeg_dec_reset_qos (GstJpegDec * dec);
102 static void gst_jpeg_dec_read_qos (GstJpegDec * dec, gdouble * proportion,
103 GstClockTime * time);
105 #define gst_jpeg_dec_parent_class parent_class
106 G_DEFINE_TYPE (GstJpegDec, gst_jpeg_dec, GST_TYPE_ELEMENT);
109 gst_jpeg_dec_finalize (GObject * object)
111 GstJpegDec *dec = GST_JPEG_DEC (object);
113 jpeg_destroy_decompress (&dec->cinfo);
115 g_object_unref (dec->adapter);
117 G_OBJECT_CLASS (parent_class)->finalize (object);
121 gst_jpeg_dec_class_init (GstJpegDecClass * klass)
123 GstElementClass *gstelement_class;
124 GObjectClass *gobject_class;
126 gstelement_class = (GstElementClass *) klass;
127 gobject_class = (GObjectClass *) klass;
129 parent_class = g_type_class_peek_parent (klass);
131 gobject_class->finalize = gst_jpeg_dec_finalize;
132 gobject_class->set_property = gst_jpeg_dec_set_property;
133 gobject_class->get_property = gst_jpeg_dec_get_property;
135 g_object_class_install_property (gobject_class, PROP_IDCT_METHOD,
136 g_param_spec_enum ("idct-method", "IDCT Method",
137 "The IDCT algorithm to use", GST_TYPE_IDCT_METHOD,
138 JPEG_DEFAULT_IDCT_METHOD,
139 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
142 * GstJpegDec:max-errors
144 * Error out after receiving N consecutive decoding errors
145 * (-1 = never error out, 0 = automatic, 1 = fail on first error, etc.)
149 g_object_class_install_property (gobject_class, PROP_MAX_ERRORS,
150 g_param_spec_int ("max-errors", "Maximum Consecutive Decoding Errors",
151 "Error out after receiving N consecutive decoding errors "
152 "(-1 = never fail, 0 = automatic, 1 = fail on first error)",
153 -1, G_MAXINT, JPEG_DEFAULT_MAX_ERRORS,
154 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
156 gst_element_class_add_pad_template (gstelement_class,
157 gst_static_pad_template_get (&gst_jpeg_dec_src_pad_template));
158 gst_element_class_add_pad_template (gstelement_class,
159 gst_static_pad_template_get (&gst_jpeg_dec_sink_pad_template));
160 gst_element_class_set_details_simple (gstelement_class, "JPEG image decoder",
161 "Codec/Decoder/Image",
162 "Decode images from JPEG format", "Wim Taymans <wim@fluendo.com>");
164 gstelement_class->change_state =
165 GST_DEBUG_FUNCPTR (gst_jpeg_dec_change_state);
167 GST_DEBUG_CATEGORY_INIT (jpeg_dec_debug, "jpegdec", 0, "JPEG decoder");
168 GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE");
172 gst_jpeg_dec_clear_error (GstJpegDec * dec)
174 g_free (dec->error_msg);
175 dec->error_msg = NULL;
177 dec->error_func = NULL;
181 gst_jpeg_dec_set_error_va (GstJpegDec * dec, const gchar * func, gint line,
182 const gchar * debug_msg_format, va_list args)
184 #ifndef GST_DISABLE_GST_DEBUG
185 gst_debug_log_valist (GST_CAT_DEFAULT, GST_LEVEL_WARNING, __FILE__, func,
186 line, (GObject *) dec, debug_msg_format, args);
189 g_free (dec->error_msg);
190 if (debug_msg_format)
191 dec->error_msg = g_strdup_vprintf (debug_msg_format, args);
193 dec->error_msg = NULL;
195 dec->error_line = line;
196 dec->error_func = func;
200 gst_jpeg_dec_set_error (GstJpegDec * dec, const gchar * func, gint line,
201 const gchar * debug_msg_format, ...)
205 va_start (va, debug_msg_format);
206 gst_jpeg_dec_set_error_va (dec, func, line, debug_msg_format, va);
211 gst_jpeg_dec_post_error_or_warning (GstJpegDec * dec)
217 max_errors = g_atomic_int_get (&dec->max_errors);
219 if (max_errors < 0) {
221 } else if (max_errors == 0) {
222 /* FIXME: do something more clever in "automatic mode" */
223 if (dec->packetized) {
224 ret = (dec->error_count < 3) ? GST_FLOW_OK : GST_FLOW_ERROR;
226 ret = GST_FLOW_ERROR;
229 ret = (dec->error_count < max_errors) ? GST_FLOW_OK : GST_FLOW_ERROR;
232 GST_INFO_OBJECT (dec, "decoding error %d/%d (%s)", dec->error_count,
233 max_errors, (ret == GST_FLOW_OK) ? "ignoring error" : "erroring out");
235 gst_element_message_full (GST_ELEMENT (dec),
236 (ret == GST_FLOW_OK) ? GST_MESSAGE_WARNING : GST_MESSAGE_ERROR,
237 GST_STREAM_ERROR, GST_STREAM_ERROR_DECODE,
238 g_strdup (_("Failed to decode JPEG image")), dec->error_msg,
239 __FILE__, dec->error_func, dec->error_line);
241 dec->error_msg = NULL;
242 gst_jpeg_dec_clear_error (dec);
247 gst_jpeg_dec_fill_input_buffer (j_decompress_ptr cinfo)
252 dec = CINFO_GET_JPEGDEC (cinfo);
253 g_return_val_if_fail (dec != NULL, FALSE);
255 av = gst_adapter_available_fast (dec->adapter);
256 GST_DEBUG_OBJECT (dec, "fill_input_buffer: fast av=%u, remaining=%u", av,
260 GST_DEBUG_OBJECT (dec, "Out of data");
264 if (dec->rem_img_len < av)
265 av = dec->rem_img_len;
266 dec->rem_img_len -= av;
268 g_free (dec->cur_buf);
269 dec->cur_buf = gst_adapter_take (dec->adapter, av);
271 cinfo->src->next_input_byte = dec->cur_buf;
272 cinfo->src->bytes_in_buffer = av;
278 gst_jpeg_dec_init_source (j_decompress_ptr cinfo)
280 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "init_source");
285 gst_jpeg_dec_skip_input_data (j_decompress_ptr cinfo, glong num_bytes)
287 GstJpegDec *dec = CINFO_GET_JPEGDEC (cinfo);
289 GST_DEBUG_OBJECT (dec, "skip %ld bytes", num_bytes);
291 if (num_bytes > 0 && cinfo->src->bytes_in_buffer >= num_bytes) {
292 cinfo->src->next_input_byte += (size_t) num_bytes;
293 cinfo->src->bytes_in_buffer -= (size_t) num_bytes;
294 } else if (num_bytes > 0) {
297 num_bytes -= cinfo->src->bytes_in_buffer;
298 cinfo->src->next_input_byte += (size_t) cinfo->src->bytes_in_buffer;
299 cinfo->src->bytes_in_buffer = 0;
301 available = gst_adapter_available (dec->adapter);
302 if (available < num_bytes || available < dec->rem_img_len) {
303 GST_WARNING_OBJECT (dec, "Less bytes to skip than available in the "
304 "adapter or the remaining image length %ld < %d or %u",
305 num_bytes, available, dec->rem_img_len);
307 num_bytes = MIN (MIN (num_bytes, available), dec->rem_img_len);
308 gst_adapter_flush (dec->adapter, num_bytes);
309 dec->rem_img_len -= num_bytes;
314 gst_jpeg_dec_resync_to_restart (j_decompress_ptr cinfo, gint desired)
316 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "resync_to_start");
321 gst_jpeg_dec_term_source (j_decompress_ptr cinfo)
323 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "term_source");
328 gst_jpeg_dec_my_output_message (j_common_ptr cinfo)
330 return; /* do nothing */
334 gst_jpeg_dec_my_emit_message (j_common_ptr cinfo, int msg_level)
336 /* GST_LOG_OBJECT (CINFO_GET_JPEGDEC (&cinfo), "msg_level=%d", msg_level); */
341 gst_jpeg_dec_my_error_exit (j_common_ptr cinfo)
343 struct GstJpegDecErrorMgr *err_mgr = (struct GstJpegDecErrorMgr *) cinfo->err;
345 (*cinfo->err->output_message) (cinfo);
346 longjmp (err_mgr->setjmp_buffer, 1);
350 gst_jpeg_dec_init (GstJpegDec * dec)
352 GST_DEBUG ("initializing");
354 /* create the sink and src pads */
356 gst_pad_new_from_static_template (&gst_jpeg_dec_sink_pad_template,
358 gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
359 gst_pad_set_chain_function (dec->sinkpad,
360 GST_DEBUG_FUNCPTR (gst_jpeg_dec_chain));
361 gst_pad_set_event_function (dec->sinkpad,
362 GST_DEBUG_FUNCPTR (gst_jpeg_dec_sink_event));
365 gst_pad_new_from_static_template (&gst_jpeg_dec_src_pad_template, "src");
366 gst_pad_set_event_function (dec->srcpad,
367 GST_DEBUG_FUNCPTR (gst_jpeg_dec_src_event));
368 gst_pad_use_fixed_caps (dec->srcpad);
369 gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
372 memset (&dec->cinfo, 0, sizeof (dec->cinfo));
373 memset (&dec->jerr, 0, sizeof (dec->jerr));
374 dec->cinfo.err = jpeg_std_error (&dec->jerr.pub);
375 dec->jerr.pub.output_message = gst_jpeg_dec_my_output_message;
376 dec->jerr.pub.emit_message = gst_jpeg_dec_my_emit_message;
377 dec->jerr.pub.error_exit = gst_jpeg_dec_my_error_exit;
379 jpeg_create_decompress (&dec->cinfo);
381 dec->cinfo.src = (struct jpeg_source_mgr *) &dec->jsrc;
382 dec->cinfo.src->init_source = gst_jpeg_dec_init_source;
383 dec->cinfo.src->fill_input_buffer = gst_jpeg_dec_fill_input_buffer;
384 dec->cinfo.src->skip_input_data = gst_jpeg_dec_skip_input_data;
385 dec->cinfo.src->resync_to_restart = gst_jpeg_dec_resync_to_restart;
386 dec->cinfo.src->term_source = gst_jpeg_dec_term_source;
389 /* init properties */
390 dec->idct_method = JPEG_DEFAULT_IDCT_METHOD;
391 dec->max_errors = JPEG_DEFAULT_MAX_ERRORS;
393 dec->adapter = gst_adapter_new ();
397 gst_jpeg_dec_ensure_header (GstJpegDec * dec)
402 av = gst_adapter_available (dec->adapter);
403 /* we expect at least 4 bytes, first of which start marker */
404 offset = gst_adapter_masked_scan_uint32 (dec->adapter, 0xffffff00, 0xffd8ff00,
406 if (G_UNLIKELY (offset < 0)) {
407 GST_DEBUG_OBJECT (dec, "No JPEG header in current buffer");
410 gst_adapter_flush (dec->adapter, av - 4);
415 GST_LOG_OBJECT (dec, "Skipping %u bytes.", offset);
416 gst_adapter_flush (dec->adapter, offset);
418 GST_DEBUG_OBJECT (dec, "Found JPEG header");
423 static inline gboolean
424 gst_jpeg_dec_parse_tag_has_entropy_segment (guint8 tag)
426 if (tag == 0xda || (tag >= 0xd0 && tag <= 0xd7))
431 /* returns image length in bytes if parsed successfully,
432 * otherwise 0 if more data needed,
433 * if < 0 the absolute value needs to be flushed */
435 gst_jpeg_dec_parse_image_data (GstJpegDec * dec)
439 GstAdapter *adapter = dec->adapter;
440 gint offset, noffset;
442 size = gst_adapter_available (adapter);
444 /* we expect at least 4 bytes, first of which start marker */
445 if (gst_adapter_masked_scan_uint32 (adapter, 0xffff0000, 0xffd80000, 0, 4))
448 GST_DEBUG ("Parsing jpeg image data (%u bytes)", size);
450 GST_DEBUG ("Parse state: offset=%d, resync=%d, entropy len=%d",
451 dec->parse_offset, dec->parse_resync, dec->parse_entropy_len);
453 /* offset is 2 less than actual offset;
454 * - adapter needs at least 4 bytes for scanning,
455 * - start and end marker ensure at least that much
457 /* resume from state offset */
458 offset = dec->parse_offset;
465 gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00, 0x0000ff00,
466 offset, size - offset, &value);
467 /* lost sync if 0xff marker not where expected */
468 if ((resync = (noffset != offset))) {
469 GST_DEBUG ("Lost sync at 0x%08x, resyncing", offset + 2);
471 /* may have marker, but could have been resyncng */
472 resync = resync || dec->parse_resync;
473 /* Skip over extra 0xff */
474 while ((noffset >= 0) && ((value & 0xff) == 0xff)) {
477 gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00, 0x0000ff00,
478 noffset, size - noffset, &value);
480 /* enough bytes left for marker? (we need 0xNN after the 0xff) */
482 GST_DEBUG ("at end of input and no EOI marker found, need more data");
486 /* now lock on the marker we found */
488 value = value & 0xff;
490 GST_DEBUG ("0x%08x: EOI marker", offset + 2);
491 /* clear parse state */
492 dec->parse_resync = FALSE;
493 dec->parse_offset = 0;
495 } else if (value == 0xd8) {
496 /* Skip this frame if we found another SOI marker */
497 GST_DEBUG ("0x%08x: SOI marker before EOI, skipping", offset + 2);
498 dec->parse_resync = FALSE;
499 dec->parse_offset = 0;
500 return -(offset + 2);
504 if (value >= 0xd0 && value <= 0xd7)
507 /* peek tag and subsequent length */
508 if (offset + 2 + 4 > size)
511 gst_adapter_masked_scan_uint32_peek (adapter, 0x0, 0x0, offset + 2, 4,
513 frame_len = frame_len & 0xffff;
515 GST_DEBUG ("0x%08x: tag %02x, frame_len=%u", offset + 2, value, frame_len);
516 /* the frame length includes the 2 bytes for the length; here we want at
517 * least 2 more bytes at the end for an end marker */
518 if (offset + 2 + 2 + frame_len + 2 > size) {
522 if (gst_jpeg_dec_parse_tag_has_entropy_segment (value)) {
523 guint eseglen = dec->parse_entropy_len;
525 GST_DEBUG ("0x%08x: finding entropy segment length", offset + 2);
526 noffset = offset + 2 + frame_len + dec->parse_entropy_len;
528 noffset = gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00,
529 0x0000ff00, noffset, size - noffset, &value);
532 dec->parse_entropy_len = size - offset - 4 - frame_len - 2;
535 if ((value & 0xff) != 0x00) {
536 eseglen = noffset - offset - frame_len - 2;
541 dec->parse_entropy_len = 0;
542 frame_len += eseglen;
543 GST_DEBUG ("entropy segment length=%u => frame_len=%u", eseglen,
547 /* check if we will still be in sync if we interpret
548 * this as a sync point and skip this frame */
549 noffset = offset + frame_len + 2;
550 noffset = gst_adapter_masked_scan_uint32 (adapter, 0x0000ff00, 0x0000ff00,
553 /* ignore and continue resyncing until we hit the end
554 * of our data or find a sync point that looks okay */
558 GST_DEBUG ("found sync at 0x%x", offset + 2);
561 offset += frame_len + 2;
567 dec->parse_offset = offset;
568 dec->parse_resync = resync;
573 /* shamelessly ripped from jpegutils.c in mjpegtools */
575 add_huff_table (j_decompress_ptr dinfo,
576 JHUFF_TBL ** htblptr, const UINT8 * bits, const UINT8 * val)
577 /* Define a Huffman table */
581 if (*htblptr == NULL)
582 *htblptr = jpeg_alloc_huff_table ((j_common_ptr) dinfo);
586 /* Copy the number-of-symbols-of-each-code-length counts */
587 memcpy ((*htblptr)->bits, bits, sizeof ((*htblptr)->bits));
589 /* Validate the counts. We do this here mainly so we can copy the right
590 * number of symbols from the val[] array, without risking marching off
591 * the end of memory. jchuff.c will do a more thorough test later.
594 for (len = 1; len <= 16; len++)
595 nsymbols += bits[len];
596 if (nsymbols < 1 || nsymbols > 256)
597 g_error ("jpegutils.c: add_huff_table failed badly. ");
599 memcpy ((*htblptr)->huffval, val, nsymbols * sizeof (UINT8));
605 std_huff_tables (j_decompress_ptr dinfo)
606 /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
607 /* IMPORTANT: these are only valid for 8-bit data precision! */
609 static const UINT8 bits_dc_luminance[17] =
610 { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
611 static const UINT8 val_dc_luminance[] =
612 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
614 static const UINT8 bits_dc_chrominance[17] =
615 { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
616 static const UINT8 val_dc_chrominance[] =
617 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
619 static const UINT8 bits_ac_luminance[17] =
620 { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
621 static const UINT8 val_ac_luminance[] =
622 { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
623 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
624 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
625 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
626 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
627 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
628 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
629 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
630 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
631 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
632 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
633 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
634 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
635 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
636 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
637 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
638 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
639 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
640 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
641 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
645 static const UINT8 bits_ac_chrominance[17] =
646 { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
647 static const UINT8 val_ac_chrominance[] =
648 { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
649 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
650 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
651 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
652 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
653 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
654 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
655 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
656 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
657 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
658 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
659 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
660 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
661 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
662 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
663 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
664 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
665 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
666 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
667 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
671 add_huff_table (dinfo, &dinfo->dc_huff_tbl_ptrs[0],
672 bits_dc_luminance, val_dc_luminance);
673 add_huff_table (dinfo, &dinfo->ac_huff_tbl_ptrs[0],
674 bits_ac_luminance, val_ac_luminance);
675 add_huff_table (dinfo, &dinfo->dc_huff_tbl_ptrs[1],
676 bits_dc_chrominance, val_dc_chrominance);
677 add_huff_table (dinfo, &dinfo->ac_huff_tbl_ptrs[1],
678 bits_ac_chrominance, val_ac_chrominance);
684 guarantee_huff_tables (j_decompress_ptr dinfo)
686 if ((dinfo->dc_huff_tbl_ptrs[0] == NULL) &&
687 (dinfo->dc_huff_tbl_ptrs[1] == NULL) &&
688 (dinfo->ac_huff_tbl_ptrs[0] == NULL) &&
689 (dinfo->ac_huff_tbl_ptrs[1] == NULL)) {
690 GST_DEBUG ("Generating standard Huffman tables for this frame.");
691 std_huff_tables (dinfo);
696 gst_jpeg_dec_setcaps (GstJpegDec * dec, GstCaps * caps)
699 const GValue *framerate;
701 s = gst_caps_get_structure (caps, 0);
703 if ((framerate = gst_structure_get_value (s, "framerate")) != NULL) {
704 dec->in_fps_n = gst_value_get_fraction_numerator (framerate);
705 dec->in_fps_d = gst_value_get_fraction_denominator (framerate);
706 dec->packetized = TRUE;
707 GST_DEBUG ("got framerate of %d/%d fps => packetized mode",
708 dec->in_fps_n, dec->in_fps_d);
711 /* do not extract width/height here. we do that in the chain
712 * function on a per-frame basis (including the line[] array
715 /* But we can take the framerate values and set them on the src pad */
722 hresamplecpy1 (guint8 * dest, const guint8 * src, guint len)
726 for (i = 0; i < len; ++i) {
727 /* equivalent to: dest[i] = src[i << 1] */
736 gst_jpeg_dec_free_buffers (GstJpegDec * dec)
740 for (i = 0; i < 16; i++) {
741 g_free (dec->idr_y[i]);
742 g_free (dec->idr_u[i]);
743 g_free (dec->idr_v[i]);
744 dec->idr_y[i] = NULL;
745 dec->idr_u[i] = NULL;
746 dec->idr_v[i] = NULL;
749 dec->idr_width_allocated = 0;
752 static inline gboolean
753 gst_jpeg_dec_ensure_buffers (GstJpegDec * dec, guint maxrowbytes)
757 if (G_LIKELY (dec->idr_width_allocated >= maxrowbytes))
760 /* FIXME: maybe just alloc one or three blocks altogether? */
761 for (i = 0; i < 16; i++) {
762 dec->idr_y[i] = g_try_realloc (dec->idr_y[i], maxrowbytes);
763 dec->idr_u[i] = g_try_realloc (dec->idr_u[i], maxrowbytes);
764 dec->idr_v[i] = g_try_realloc (dec->idr_v[i], maxrowbytes);
766 if (G_UNLIKELY (!dec->idr_y[i] || !dec->idr_u[i] || !dec->idr_v[i])) {
767 GST_WARNING_OBJECT (dec, "out of memory, i=%d, bytes=%u", i, maxrowbytes);
772 dec->idr_width_allocated = maxrowbytes;
773 GST_LOG_OBJECT (dec, "allocated temp memory, %u bytes/row", maxrowbytes);
778 gst_jpeg_dec_decode_grayscale (GstJpegDec * dec, GstVideoFrame * frame)
781 guchar **scanarray[1] = { rows };
786 gint pstride, rstride;
788 GST_DEBUG_OBJECT (dec, "indirect decoding of grayscale");
790 width = GST_VIDEO_FRAME_WIDTH (frame);
791 height = GST_VIDEO_FRAME_HEIGHT (frame);
793 if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
796 base[0] = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
797 pstride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0);
798 rstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
800 memcpy (rows, dec->idr_y, 16 * sizeof (gpointer));
804 lines = jpeg_read_raw_data (&dec->cinfo, scanarray, DCTSIZE);
805 if (G_LIKELY (lines > 0)) {
806 for (j = 0; (j < DCTSIZE) && (i < height); j++, i++) {
810 for (k = 0; k < width; k++) {
811 base[0][p] = rows[j][k];
817 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
823 gst_jpeg_dec_decode_rgb (GstJpegDec * dec, GstVideoFrame * frame)
825 guchar *r_rows[16], *g_rows[16], *b_rows[16];
826 guchar **scanarray[3] = { r_rows, g_rows, b_rows };
830 guint pstride, rstride;
833 GST_DEBUG_OBJECT (dec, "indirect decoding of RGB");
835 width = GST_VIDEO_FRAME_WIDTH (frame);
836 height = GST_VIDEO_FRAME_HEIGHT (frame);
838 if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
841 for (i = 0; i < 3; i++)
842 base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
844 pstride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0);
845 rstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
847 memcpy (r_rows, dec->idr_y, 16 * sizeof (gpointer));
848 memcpy (g_rows, dec->idr_u, 16 * sizeof (gpointer));
849 memcpy (b_rows, dec->idr_v, 16 * sizeof (gpointer));
853 lines = jpeg_read_raw_data (&dec->cinfo, scanarray, DCTSIZE);
854 if (G_LIKELY (lines > 0)) {
855 for (j = 0; (j < DCTSIZE) && (i < height); j++, i++) {
859 for (k = 0; k < width; k++) {
860 base[0][p] = r_rows[j][k];
861 base[1][p] = g_rows[j][k];
862 base[2][p] = b_rows[j][k];
870 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
876 gst_jpeg_dec_decode_indirect (GstJpegDec * dec, GstVideoFrame * frame,
877 gint r_v, gint r_h, gint comp)
879 guchar *y_rows[16], *u_rows[16], *v_rows[16];
880 guchar **scanarray[3] = { y_rows, u_rows, v_rows };
883 guchar *base[3], *last[3];
887 GST_DEBUG_OBJECT (dec,
888 "unadvantageous width or r_h, taking slow route involving memcpy");
890 width = GST_VIDEO_FRAME_WIDTH (frame);
891 height = GST_VIDEO_FRAME_HEIGHT (frame);
893 if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
896 for (i = 0; i < 3; i++) {
897 base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
898 stride[i] = GST_VIDEO_FRAME_COMP_STRIDE (frame, i);
899 /* make sure we don't make jpeglib write beyond our buffer,
900 * which might happen if (height % (r_v*DCTSIZE)) != 0 */
901 last[i] = base[i] + (GST_VIDEO_FRAME_COMP_STRIDE (frame, i) *
902 (GST_VIDEO_FRAME_COMP_HEIGHT (frame, i) - 1));
905 memcpy (y_rows, dec->idr_y, 16 * sizeof (gpointer));
906 memcpy (u_rows, dec->idr_u, 16 * sizeof (gpointer));
907 memcpy (v_rows, dec->idr_v, 16 * sizeof (gpointer));
909 /* fill chroma components for grayscale */
911 GST_DEBUG_OBJECT (dec, "grayscale, filling chroma");
912 for (i = 0; i < 16; i++) {
913 memset (u_rows[i], GST_ROUND_UP_32 (width), 0x80);
914 memset (v_rows[i], GST_ROUND_UP_32 (width), 0x80);
918 for (i = 0; i < height; i += r_v * DCTSIZE) {
919 lines = jpeg_read_raw_data (&dec->cinfo, scanarray, r_v * DCTSIZE);
920 if (G_LIKELY (lines > 0)) {
921 for (j = 0, k = 0; j < (r_v * DCTSIZE); j += r_v, k++) {
922 if (G_LIKELY (base[0] <= last[0])) {
923 memcpy (base[0], y_rows[j], stride[0]);
924 base[0] += stride[0];
927 if (G_LIKELY (base[0] <= last[0])) {
928 memcpy (base[0], y_rows[j + 1], stride[0]);
929 base[0] += stride[0];
932 if (G_LIKELY (base[1] <= last[1] && base[2] <= last[2])) {
934 memcpy (base[1], u_rows[k], stride[1]);
935 memcpy (base[2], v_rows[k], stride[2]);
936 } else if (r_h == 1) {
937 hresamplecpy1 (base[1], u_rows[k], stride[1]);
938 hresamplecpy1 (base[2], v_rows[k], stride[2]);
940 /* FIXME: implement (at least we avoid crashing by doing nothing) */
944 if (r_v == 2 || (k & 1) != 0) {
945 base[1] += stride[1];
946 base[2] += stride[2];
950 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
956 gst_jpeg_dec_decode_direct (GstJpegDec * dec, GstVideoFrame * frame)
958 guchar **line[3]; /* the jpeg line buffer */
959 guchar *y[4 * DCTSIZE] = { NULL, }; /* alloc enough for the lines */
960 guchar *u[4 * DCTSIZE] = { NULL, }; /* r_v will be <4 */
961 guchar *v[4 * DCTSIZE] = { NULL, };
963 gint lines, v_samp[3];
964 guchar *base[3], *last[3];
972 v_samp[0] = dec->cinfo.comp_info[0].v_samp_factor;
973 v_samp[1] = dec->cinfo.comp_info[1].v_samp_factor;
974 v_samp[2] = dec->cinfo.comp_info[2].v_samp_factor;
976 if (G_UNLIKELY (v_samp[0] > 2 || v_samp[1] > 2 || v_samp[2] > 2))
977 goto format_not_supported;
979 height = GST_VIDEO_FRAME_HEIGHT (frame);
981 for (i = 0; i < 3; i++) {
982 base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
983 stride[i] = GST_VIDEO_FRAME_COMP_STRIDE (frame, i);
984 /* make sure we don't make jpeglib write beyond our buffer,
985 * which might happen if (height % (r_v*DCTSIZE)) != 0 */
986 last[i] = base[i] + (GST_VIDEO_FRAME_COMP_STRIDE (frame, i) *
987 (GST_VIDEO_FRAME_COMP_HEIGHT (frame, i) - 1));
990 /* let jpeglib decode directly into our final buffer */
991 GST_DEBUG_OBJECT (dec, "decoding directly into output buffer");
993 for (i = 0; i < height; i += v_samp[0] * DCTSIZE) {
994 for (j = 0; j < (v_samp[0] * DCTSIZE); ++j) {
996 line[0][j] = base[0] + (i + j) * stride[0];
997 if (G_UNLIKELY (line[0][j] > last[0]))
998 line[0][j] = last[0];
1000 if (v_samp[1] == v_samp[0]) {
1001 line[1][j] = base[1] + ((i + j) / 2) * stride[1];
1002 } else if (j < (v_samp[1] * DCTSIZE)) {
1003 line[1][j] = base[1] + ((i / 2) + j) * stride[1];
1005 if (G_UNLIKELY (line[1][j] > last[1]))
1006 line[1][j] = last[1];
1008 if (v_samp[2] == v_samp[0]) {
1009 line[2][j] = base[2] + ((i + j) / 2) * stride[2];
1010 } else if (j < (v_samp[2] * DCTSIZE)) {
1011 line[2][j] = base[2] + ((i / 2) + j) * stride[2];
1013 if (G_UNLIKELY (line[2][j] > last[2]))
1014 line[2][j] = last[2];
1017 lines = jpeg_read_raw_data (&dec->cinfo, line, v_samp[0] * DCTSIZE);
1018 if (G_UNLIKELY (!lines)) {
1019 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
1024 format_not_supported:
1026 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1027 "Unsupported subsampling schema: v_samp factors: %u %u %u",
1028 v_samp[0], v_samp[1], v_samp[2]);
1029 return GST_FLOW_ERROR;
1034 gst_jpeg_dec_update_qos (GstJpegDec * dec, gdouble proportion,
1035 GstClockTimeDiff diff, GstClockTime ts)
1037 GST_OBJECT_LOCK (dec);
1038 dec->proportion = proportion;
1039 if (G_LIKELY (ts != GST_CLOCK_TIME_NONE)) {
1040 if (G_UNLIKELY (diff > dec->qos_duration))
1041 dec->earliest_time = ts + 2 * diff + dec->qos_duration;
1043 dec->earliest_time = ts + diff;
1045 dec->earliest_time = GST_CLOCK_TIME_NONE;
1047 GST_OBJECT_UNLOCK (dec);
1051 gst_jpeg_dec_reset_qos (GstJpegDec * dec)
1053 gst_jpeg_dec_update_qos (dec, 0.5, 0, GST_CLOCK_TIME_NONE);
1057 gst_jpeg_dec_read_qos (GstJpegDec * dec, gdouble * proportion,
1058 GstClockTime * time)
1060 GST_OBJECT_LOCK (dec);
1061 *proportion = dec->proportion;
1062 *time = dec->earliest_time;
1063 GST_OBJECT_UNLOCK (dec);
1066 /* Perform qos calculations before decoding the next frame. Returns TRUE if the
1067 * frame should be decoded, FALSE if the frame can be dropped entirely */
1069 gst_jpeg_dec_do_qos (GstJpegDec * dec, GstClockTime timestamp)
1071 GstClockTime qostime, earliest_time;
1074 /* no timestamp, can't do QoS => decode frame */
1075 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (timestamp))) {
1076 GST_LOG_OBJECT (dec, "invalid timestamp, can't do QoS, decode frame");
1080 /* get latest QoS observation values */
1081 gst_jpeg_dec_read_qos (dec, &proportion, &earliest_time);
1083 /* skip qos if we have no observation (yet) => decode frame */
1084 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (earliest_time))) {
1085 GST_LOG_OBJECT (dec, "no observation yet, decode frame");
1089 /* qos is done on running time */
1090 qostime = gst_segment_to_running_time (&dec->segment, GST_FORMAT_TIME,
1093 /* see how our next timestamp relates to the latest qos timestamp */
1094 GST_LOG_OBJECT (dec, "qostime %" GST_TIME_FORMAT ", earliest %"
1095 GST_TIME_FORMAT, GST_TIME_ARGS (qostime), GST_TIME_ARGS (earliest_time));
1097 if (qostime != GST_CLOCK_TIME_NONE && qostime <= earliest_time) {
1098 GST_DEBUG_OBJECT (dec, "we are late, drop frame");
1102 GST_LOG_OBJECT (dec, "decode frame");
1107 gst_jpeg_dec_buffer_pool (GstJpegDec * dec, GstCaps * caps)
1110 GstBufferPool *pool = NULL;
1111 guint size, min, max, prefix, alignment;
1112 GstStructure *config;
1114 GST_DEBUG_OBJECT (dec, "setting up bufferpool");
1116 /* find a pool for the negotiated caps now */
1117 query = gst_query_new_allocation (caps, TRUE);
1119 if (gst_pad_peer_query (dec->srcpad, query)) {
1120 /* we got configuration from our peer, parse them */
1121 gst_query_parse_allocation_params (query, &size, &min, &max, &prefix,
1123 size = MAX (size, dec->info.size);
1125 GST_DEBUG_OBJECT (dec, "peer query failed, using defaults");
1126 size = dec->info.size;
1131 gst_query_unref (query);
1134 /* we did not get a pool, make one ourselves then */
1135 pool = gst_buffer_pool_new ();
1138 config = gst_buffer_pool_get_config (pool);
1139 gst_buffer_pool_config_set (config, caps, size, min, max, prefix,
1142 gst_buffer_pool_set_config (pool, config);
1145 gst_buffer_pool_set_active (dec->pool, FALSE);
1146 gst_object_unref (dec->pool);
1151 gst_buffer_pool_set_active (pool, TRUE);
1157 gst_jpeg_dec_negotiate (GstJpegDec * dec, gint width, gint height, gint clrspc)
1160 GstVideoFormat format;
1163 if (G_UNLIKELY (width == dec->info.width && height == dec->info.height &&
1164 dec->in_fps_n == dec->info.fps_n && dec->in_fps_d == dec->info.fps_d
1165 && clrspc == dec->clrspc))
1168 gst_video_info_init (&info);
1170 /* framerate == 0/1 is a still frame */
1171 if (dec->in_fps_d == 0) {
1175 info.fps_n = dec->in_fps_n;
1176 info.fps_d = dec->in_fps_d;
1179 /* calculate or assume an average frame duration for QoS purposes */
1180 GST_OBJECT_LOCK (dec);
1181 if (info.fps_n != 0) {
1183 gst_util_uint64_scale (GST_SECOND, info.fps_d, info.fps_n);
1184 dec->duration = dec->qos_duration;
1186 /* if not set just use 25fps */
1187 dec->qos_duration = gst_util_uint64_scale (GST_SECOND, 1, 25);
1188 dec->duration = GST_CLOCK_TIME_NONE;
1190 GST_OBJECT_UNLOCK (dec);
1192 if (dec->cinfo.jpeg_color_space == JCS_RGB) {
1194 GstCaps *allowed_caps;
1195 GstVideoInfo tmpinfo;
1197 GST_DEBUG_OBJECT (dec, "selecting RGB format");
1198 /* retrieve allowed caps, and find the first one that reasonably maps
1199 * to the parameters of the colourspace */
1200 caps = gst_pad_get_allowed_caps (dec->srcpad);
1202 GST_DEBUG_OBJECT (dec, "... but no peer, using template caps");
1203 /* need to copy because get_allowed_caps returns a ref,
1204 * and get_pad_template_caps doesn't */
1205 caps = gst_caps_copy (gst_pad_get_pad_template_caps (dec->srcpad));
1207 /* avoid lists of formats, etc */
1208 allowed_caps = gst_caps_normalize (caps);
1209 gst_caps_unref (caps);
1211 GST_LOG_OBJECT (dec, "allowed source caps %" GST_PTR_FORMAT, allowed_caps);
1213 for (i = 0; i < gst_caps_get_size (allowed_caps); i++) {
1215 gst_caps_unref (caps);
1216 caps = gst_caps_copy_nth (allowed_caps, i);
1217 /* sigh, ds and _parse_caps need fixed caps for parsing, fixate */
1218 gst_pad_fixate_caps (dec->srcpad, caps);
1219 GST_LOG_OBJECT (dec, "checking caps %" GST_PTR_FORMAT, caps);
1221 if (!gst_video_info_from_caps (&tmpinfo, caps))
1223 /* we'll settle for the first (preferred) downstream rgb format */
1224 if (GST_VIDEO_INFO_IS_RGB (&tmpinfo))
1226 /* default fall-back */
1227 format = GST_VIDEO_FORMAT_RGB;
1230 gst_caps_unref (caps);
1231 gst_caps_unref (allowed_caps);
1232 } else if (dec->cinfo.jpeg_color_space == JCS_GRAYSCALE) {
1233 /* TODO is anything else then 8bit supported in jpeg? */
1234 format = GST_VIDEO_FORMAT_GRAY8;
1236 /* go for plain and simple I420 */
1237 /* TODO other YUV cases ? */
1238 format = GST_VIDEO_FORMAT_I420;
1241 gst_video_info_set_format (&info, format, width, height);
1242 caps = gst_video_info_to_caps (&info);
1244 GST_DEBUG_OBJECT (dec, "setting caps %" GST_PTR_FORMAT, caps);
1245 GST_DEBUG_OBJECT (dec, "max_v_samp_factor=%d", dec->cinfo.max_v_samp_factor);
1246 GST_DEBUG_OBJECT (dec, "max_h_samp_factor=%d", dec->cinfo.max_h_samp_factor);
1248 gst_pad_set_caps (dec->srcpad, caps);
1251 dec->clrspc = clrspc;
1253 gst_jpeg_dec_buffer_pool (dec, caps);
1254 gst_caps_unref (caps);
1259 static GstFlowReturn
1260 gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf)
1262 GstFlowReturn ret = GST_FLOW_OK;
1264 GstBuffer *outbuf = NULL;
1269 GstClockTime timestamp, duration;
1270 GstVideoFrame frame;
1272 dec = GST_JPEG_DEC (GST_PAD_PARENT (pad));
1274 timestamp = GST_BUFFER_TIMESTAMP (buf);
1275 duration = GST_BUFFER_DURATION (buf);
1277 if (GST_CLOCK_TIME_IS_VALID (timestamp))
1278 dec->next_ts = timestamp;
1280 if (GST_BUFFER_IS_DISCONT (buf)) {
1281 GST_DEBUG_OBJECT (dec, "buffer has DISCONT flag set");
1282 dec->discont = TRUE;
1283 if (!dec->packetized && gst_adapter_available (dec->adapter)) {
1284 GST_WARNING_OBJECT (dec, "DISCONT buffer in non-packetized mode, bad");
1285 gst_adapter_clear (dec->adapter);
1289 gst_adapter_push (dec->adapter, buf);
1292 /* If we are non-packetized and know the total incoming size in bytes,
1293 * just wait until we have enough before doing any processing. */
1295 if (!dec->packetized && (dec->segment.format == GST_FORMAT_BYTES) &&
1296 (dec->segment.stop != -1) &&
1297 (gst_adapter_available (dec->adapter) < dec->segment.stop)) {
1298 /* We assume that non-packetized input in bytes is *one* single jpeg image */
1299 GST_DEBUG ("Non-packetized mode. Got %d bytes, need %" G_GINT64_FORMAT,
1300 gst_adapter_available (dec->adapter), dec->segment.stop);
1301 goto need_more_data;
1305 if (!gst_jpeg_dec_ensure_header (dec))
1306 goto need_more_data;
1308 /* If we know that each input buffer contains data
1309 * for a whole jpeg image (e.g. MJPEG streams), just
1310 * do some sanity checking instead of parsing all of
1312 if (dec->packetized) {
1313 img_len = gst_adapter_available (dec->adapter);
1315 /* Parse jpeg image to handle jpeg input that
1316 * is not aligned to buffer boundaries */
1317 img_len = gst_jpeg_dec_parse_image_data (dec);
1320 goto need_more_data;
1321 } else if (img_len < 0) {
1322 gst_adapter_flush (dec->adapter, -img_len);
1327 dec->rem_img_len = img_len;
1329 GST_LOG_OBJECT (dec, "image size = %u", img_len);
1331 /* QoS: if we're too late anyway, skip decoding */
1332 if (dec->packetized && !gst_jpeg_dec_do_qos (dec, timestamp))
1335 #ifndef GST_DISABLE_GST_DEBUG
1339 gst_adapter_copy (dec->adapter, data, 0, 4);
1340 GST_LOG_OBJECT (dec, "reading header %02x %02x %02x %02x", data[0], data[1],
1345 gst_jpeg_dec_fill_input_buffer (&dec->cinfo);
1347 if (setjmp (dec->jerr.setjmp_buffer)) {
1348 code = dec->jerr.pub.msg_code;
1350 if (code == JERR_INPUT_EOF) {
1351 GST_DEBUG ("jpeg input EOF error, we probably need more data");
1352 goto need_more_data;
1358 hdr_ok = jpeg_read_header (&dec->cinfo, TRUE);
1359 if (G_UNLIKELY (hdr_ok != JPEG_HEADER_OK)) {
1360 GST_WARNING_OBJECT (dec, "reading the header failed, %d", hdr_ok);
1363 GST_LOG_OBJECT (dec, "num_components=%d", dec->cinfo.num_components);
1364 GST_LOG_OBJECT (dec, "jpeg_color_space=%d", dec->cinfo.jpeg_color_space);
1366 if (!dec->cinfo.num_components || !dec->cinfo.comp_info)
1367 goto components_not_supported;
1369 r_h = dec->cinfo.comp_info[0].h_samp_factor;
1370 r_v = dec->cinfo.comp_info[0].v_samp_factor;
1372 GST_LOG_OBJECT (dec, "r_h = %d, r_v = %d", r_h, r_v);
1374 if (dec->cinfo.num_components > 3)
1375 goto components_not_supported;
1377 /* verify color space expectation to avoid going *boom* or bogus output */
1378 if (dec->cinfo.jpeg_color_space != JCS_YCbCr &&
1379 dec->cinfo.jpeg_color_space != JCS_GRAYSCALE &&
1380 dec->cinfo.jpeg_color_space != JCS_RGB)
1381 goto unsupported_colorspace;
1383 #ifndef GST_DISABLE_GST_DEBUG
1387 for (i = 0; i < dec->cinfo.num_components; ++i) {
1388 GST_LOG_OBJECT (dec, "[%d] h_samp_factor=%d, v_samp_factor=%d, cid=%d",
1389 i, dec->cinfo.comp_info[i].h_samp_factor,
1390 dec->cinfo.comp_info[i].v_samp_factor,
1391 dec->cinfo.comp_info[i].component_id);
1396 /* prepare for raw output */
1397 dec->cinfo.do_fancy_upsampling = FALSE;
1398 dec->cinfo.do_block_smoothing = FALSE;
1399 dec->cinfo.out_color_space = dec->cinfo.jpeg_color_space;
1400 dec->cinfo.dct_method = dec->idct_method;
1401 dec->cinfo.raw_data_out = TRUE;
1403 GST_LOG_OBJECT (dec, "starting decompress");
1404 guarantee_huff_tables (&dec->cinfo);
1405 if (!jpeg_start_decompress (&dec->cinfo)) {
1406 GST_WARNING_OBJECT (dec, "failed to start decompression cycle");
1409 /* sanity checks to get safe and reasonable output */
1410 switch (dec->cinfo.jpeg_color_space) {
1412 if (dec->cinfo.num_components != 1)
1413 goto invalid_yuvrgbgrayscale;
1416 if (dec->cinfo.num_components != 3 || dec->cinfo.max_v_samp_factor > 1 ||
1417 dec->cinfo.max_h_samp_factor > 1)
1418 goto invalid_yuvrgbgrayscale;
1421 if (dec->cinfo.num_components != 3 ||
1422 r_v > 2 || r_v < dec->cinfo.comp_info[0].v_samp_factor ||
1423 r_v < dec->cinfo.comp_info[1].v_samp_factor ||
1424 r_h < dec->cinfo.comp_info[0].h_samp_factor ||
1425 r_h < dec->cinfo.comp_info[1].h_samp_factor)
1426 goto invalid_yuvrgbgrayscale;
1429 g_assert_not_reached ();
1433 width = dec->cinfo.output_width;
1434 height = dec->cinfo.output_height;
1436 if (G_UNLIKELY (width < MIN_WIDTH || width > MAX_WIDTH ||
1437 height < MIN_HEIGHT || height > MAX_HEIGHT))
1440 gst_jpeg_dec_negotiate (dec, width, height, dec->cinfo.jpeg_color_space);
1442 ret = gst_buffer_pool_acquire_buffer (dec->pool, &outbuf, NULL);
1443 if (G_UNLIKELY (ret != GST_FLOW_OK))
1446 if (!gst_video_frame_map (&frame, &dec->info, outbuf, GST_MAP_READWRITE))
1449 GST_LOG_OBJECT (dec, "width %d, height %d", width, height);
1451 GST_BUFFER_TIMESTAMP (outbuf) = dec->next_ts;
1453 if (dec->packetized && GST_CLOCK_TIME_IS_VALID (dec->next_ts)) {
1454 if (GST_CLOCK_TIME_IS_VALID (duration)) {
1455 /* use duration from incoming buffer for outgoing buffer */
1456 dec->next_ts += duration;
1457 } else if (GST_CLOCK_TIME_IS_VALID (dec->duration)) {
1458 duration = dec->duration;
1459 dec->next_ts += dec->duration;
1461 duration = GST_CLOCK_TIME_NONE;
1462 dec->next_ts = GST_CLOCK_TIME_NONE;
1465 duration = GST_CLOCK_TIME_NONE;
1466 dec->next_ts = GST_CLOCK_TIME_NONE;
1468 GST_BUFFER_DURATION (outbuf) = duration;
1470 if (dec->cinfo.jpeg_color_space == JCS_RGB) {
1471 gst_jpeg_dec_decode_rgb (dec, &frame);
1472 } else if (dec->cinfo.jpeg_color_space == JCS_GRAYSCALE) {
1473 gst_jpeg_dec_decode_grayscale (dec, &frame);
1475 GST_LOG_OBJECT (dec, "decompressing (reqired scanline buffer height = %u)",
1476 dec->cinfo.rec_outbuf_height);
1478 /* For some widths jpeglib requires more horizontal padding than I420
1479 * provides. In those cases we need to decode into separate buffers and then
1480 * copy over the data into our final picture buffer, otherwise jpeglib might
1481 * write over the end of a line into the beginning of the next line,
1482 * resulting in blocky artifacts on the left side of the picture. */
1483 if (G_UNLIKELY (width % (dec->cinfo.max_h_samp_factor * DCTSIZE) != 0
1484 || dec->cinfo.comp_info[0].h_samp_factor != 2
1485 || dec->cinfo.comp_info[1].h_samp_factor != 1
1486 || dec->cinfo.comp_info[2].h_samp_factor != 1)) {
1487 GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, dec,
1488 "indirect decoding using extra buffer copy");
1489 gst_jpeg_dec_decode_indirect (dec, &frame, r_v, r_h,
1490 dec->cinfo.num_components);
1492 ret = gst_jpeg_dec_decode_direct (dec, &frame);
1493 if (G_UNLIKELY (ret != GST_FLOW_OK))
1494 goto decode_direct_failed;
1498 GST_LOG_OBJECT (dec, "decompressing finished");
1499 jpeg_finish_decompress (&dec->cinfo);
1501 gst_video_frame_unmap (&frame);
1504 if (dec->segment.format == GST_FORMAT_TIME) {
1505 guint64 start, stop, clip_start, clip_stop;
1507 GST_LOG_OBJECT (dec, "Attempting clipping");
1509 start = GST_BUFFER_TIMESTAMP (outbuf);
1510 if (GST_BUFFER_DURATION (outbuf) == GST_CLOCK_TIME_NONE)
1513 stop = start + GST_BUFFER_DURATION (outbuf);
1515 if (gst_segment_clip (&dec->segment, GST_FORMAT_TIME,
1516 start, stop, &clip_start, &clip_stop)) {
1517 GST_LOG_OBJECT (dec, "Clipping start to %" GST_TIME_FORMAT,
1518 GST_TIME_ARGS (clip_start));
1519 GST_BUFFER_TIMESTAMP (outbuf) = clip_start;
1520 if (GST_BUFFER_DURATION (outbuf) != GST_CLOCK_TIME_NONE) {
1521 GST_LOG_OBJECT (dec, "Clipping duration to %" GST_TIME_FORMAT,
1522 GST_TIME_ARGS (clip_stop - clip_start));
1523 GST_BUFFER_DURATION (outbuf) = clip_stop - clip_start;
1529 /* reset error count on successful decode */
1530 dec->error_count = 0;
1534 GST_LOG_OBJECT (dec, "pushing buffer (ts=%" GST_TIME_FORMAT ", dur=%"
1535 GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
1536 GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
1538 ret = gst_pad_push (dec->srcpad, outbuf);
1542 gst_adapter_flush (dec->adapter, dec->rem_img_len);
1546 if (G_UNLIKELY (ret == GST_FLOW_ERROR)) {
1547 jpeg_abort_decompress (&dec->cinfo);
1548 ret = gst_jpeg_dec_post_error_or_warning (dec);
1556 GST_LOG_OBJECT (dec, "we need more data");
1558 gst_buffer_unref (outbuf);
1567 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1568 "Picture is too small or too big (%ux%u)", width, height);
1569 ret = GST_FLOW_ERROR;
1574 gchar err_msg[JMSG_LENGTH_MAX];
1576 dec->jerr.pub.format_message ((j_common_ptr) (&dec->cinfo), err_msg);
1578 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1579 "Decode error #%u: %s", code, err_msg);
1582 gst_buffer_unref (outbuf);
1585 ret = GST_FLOW_ERROR;
1588 decode_direct_failed:
1590 /* already posted an error message */
1591 jpeg_abort_decompress (&dec->cinfo);
1592 gst_buffer_replace (&outbuf, NULL);
1597 const gchar *reason;
1599 reason = gst_flow_get_name (ret);
1601 GST_DEBUG_OBJECT (dec, "failed to alloc buffer, reason %s", reason);
1602 /* Reset for next time */
1603 jpeg_abort_decompress (&dec->cinfo);
1604 if (ret != GST_FLOW_UNEXPECTED && ret != GST_FLOW_WRONG_STATE &&
1605 ret != GST_FLOW_NOT_LINKED) {
1606 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1607 "Buffer allocation failed, reason: %s", reason);
1613 jpeg_abort_decompress (&dec->cinfo);
1614 gst_buffer_unref (outbuf);
1620 GST_WARNING_OBJECT (dec, "Outgoing buffer is outside configured segment");
1621 gst_buffer_unref (outbuf);
1625 components_not_supported:
1627 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1628 "number of components not supported: %d (max 3)",
1629 dec->cinfo.num_components);
1630 ret = GST_FLOW_ERROR;
1633 unsupported_colorspace:
1635 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1636 "Picture has unknown or unsupported colourspace");
1637 ret = GST_FLOW_ERROR;
1640 invalid_yuvrgbgrayscale:
1642 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1643 "Picture is corrupt or unhandled YUV/RGB/grayscale layout");
1644 ret = GST_FLOW_ERROR;
1650 gst_jpeg_dec_src_event (GstPad * pad, GstEvent * event)
1655 dec = GST_JPEG_DEC (gst_pad_get_parent (pad));
1656 if (G_UNLIKELY (dec == NULL)) {
1657 gst_event_unref (event);
1661 switch (GST_EVENT_TYPE (event)) {
1662 case GST_EVENT_QOS:{
1664 GstClockTimeDiff diff;
1665 GstClockTime timestamp;
1668 gst_event_parse_qos (event, &type, &proportion, &diff, ×tamp);
1669 gst_jpeg_dec_update_qos (dec, proportion, diff, timestamp);
1676 res = gst_pad_push_event (dec->sinkpad, event);
1678 gst_object_unref (dec);
1683 gst_jpeg_dec_sink_event (GstPad * pad, GstEvent * event)
1685 gboolean ret = TRUE, forward = TRUE;
1686 GstJpegDec *dec = GST_JPEG_DEC (GST_OBJECT_PARENT (pad));
1688 GST_DEBUG_OBJECT (dec, "event : %s", GST_EVENT_TYPE_NAME (event));
1690 switch (GST_EVENT_TYPE (event)) {
1691 case GST_EVENT_FLUSH_STOP:
1692 GST_DEBUG_OBJECT (dec, "Aborting decompress");
1693 jpeg_abort_decompress (&dec->cinfo);
1694 gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED);
1695 gst_adapter_clear (dec->adapter);
1696 g_free (dec->cur_buf);
1697 dec->cur_buf = NULL;
1698 dec->parse_offset = 0;
1699 dec->parse_entropy_len = 0;
1700 dec->parse_resync = FALSE;
1701 gst_jpeg_dec_reset_qos (dec);
1703 case GST_EVENT_SEGMENT:
1704 gst_event_copy_segment (event, &dec->segment);
1705 GST_DEBUG_OBJECT (dec, "Got NEWSEGMENT %" GST_SEGMENT_FORMAT,
1708 case GST_EVENT_CAPS:
1712 gst_event_parse_caps (event, &caps);
1713 ret = gst_jpeg_dec_setcaps (dec, caps);
1722 ret = gst_pad_push_event (dec->srcpad, event);
1724 gst_event_unref (event);
1730 gst_jpeg_dec_set_property (GObject * object, guint prop_id,
1731 const GValue * value, GParamSpec * pspec)
1735 dec = GST_JPEG_DEC (object);
1738 case PROP_IDCT_METHOD:
1739 dec->idct_method = g_value_get_enum (value);
1741 case PROP_MAX_ERRORS:
1742 g_atomic_int_set (&dec->max_errors, g_value_get_int (value));
1746 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1752 gst_jpeg_dec_get_property (GObject * object, guint prop_id, GValue * value,
1757 dec = GST_JPEG_DEC (object);
1760 case PROP_IDCT_METHOD:
1761 g_value_set_enum (value, dec->idct_method);
1763 case PROP_MAX_ERRORS:
1764 g_value_set_int (value, g_atomic_int_get (&dec->max_errors));
1768 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1773 static GstStateChangeReturn
1774 gst_jpeg_dec_change_state (GstElement * element, GstStateChange transition)
1776 GstStateChangeReturn ret;
1779 dec = GST_JPEG_DEC (element);
1781 switch (transition) {
1782 case GST_STATE_CHANGE_READY_TO_PAUSED:
1783 dec->error_count = 0;
1784 dec->good_count = 0;
1787 gst_video_info_init (&dec->info);
1789 dec->packetized = FALSE;
1791 dec->discont = TRUE;
1792 dec->parse_offset = 0;
1793 dec->parse_entropy_len = 0;
1794 dec->parse_resync = FALSE;
1795 dec->cur_buf = NULL;
1796 gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED);
1797 gst_jpeg_dec_reset_qos (dec);
1802 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1803 if (ret != GST_STATE_CHANGE_SUCCESS)
1806 switch (transition) {
1807 case GST_STATE_CHANGE_PAUSED_TO_READY:
1808 gst_adapter_clear (dec->adapter);
1809 g_free (dec->cur_buf);
1810 dec->cur_buf = NULL;
1811 gst_jpeg_dec_free_buffers (dec);
1813 gst_buffer_pool_set_active (dec->pool, FALSE);
1814 gst_object_unref (dec->pool);