2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3 * Copyright (C) <2009> Tim-Philipp Müller <tim centricular net>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 * SECTION:element-jpegdec
24 * Decodes jpeg images.
27 * <title>Example launch line</title>
29 * gst-launch -v v4l2src ! jpegdec ! ffmpegcolorspace ! xvimagesink
30 * ]| The above pipeline reads a motion JPEG stream from a v4l2 camera
31 * and renders it to the screen.
40 #include "gstjpegdec.h"
42 #include <gst/video/video.h>
43 #include "gst/gst-i18n-plugin.h"
47 #define MAX_WIDTH 65535
49 #define MAX_HEIGHT 65535
51 #define CINFO_GET_JPEGDEC(cinfo_ptr) \
52 (((struct GstJpegDecSourceMgr*)((cinfo_ptr)->src))->dec)
54 #define JPEG_DEFAULT_IDCT_METHOD JDCT_FASTEST
55 #define JPEG_DEFAULT_MAX_ERRORS 0
65 static GstStaticPadTemplate gst_jpeg_dec_src_pad_template =
66 GST_STATIC_PAD_TEMPLATE ("src",
69 GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
70 ("{ I420, RGB, BGR, RGBx, xRGB, BGRx, xBGR, GRAY8 }"))
75 /* FIXME: sof-marker is for IJG libjpeg 8, should be different for 6.2 */
76 static GstStaticPadTemplate gst_jpeg_dec_sink_pad_template =
77 GST_STATIC_PAD_TEMPLATE ("sink",
80 GST_STATIC_CAPS ("image/jpeg, "
81 "width = (int) [ " G_STRINGIFY (MIN_WIDTH) ", " G_STRINGIFY (MAX_WIDTH)
82 " ], " "height = (int) [ " G_STRINGIFY (MIN_HEIGHT) ", "
83 G_STRINGIFY (MAX_HEIGHT) " ], framerate = (fraction) [ 0/1, MAX ], "
84 "sof-marker = (int) { 0, 1, 2, 5, 6, 7, 9, 10, 13, 14 }")
87 GST_DEBUG_CATEGORY_STATIC (jpeg_dec_debug);
88 #define GST_CAT_DEFAULT jpeg_dec_debug
89 GST_DEBUG_CATEGORY_STATIC (GST_CAT_PERFORMANCE);
91 static void gst_jpeg_dec_set_property (GObject * object, guint prop_id,
92 const GValue * value, GParamSpec * pspec);
93 static void gst_jpeg_dec_get_property (GObject * object, guint prop_id,
94 GValue * value, GParamSpec * pspec);
96 static GstFlowReturn gst_jpeg_dec_chain (GstPad * pad, GstObject * parent,
98 static GstCaps *gst_jpeg_dec_getcaps (GstPad * pad, GstCaps * filter);
99 static gboolean gst_jpeg_dec_sink_query (GstPad * pad, GstObject * parent,
101 static gboolean gst_jpeg_dec_sink_event (GstPad * pad, GstObject * parent,
103 static gboolean gst_jpeg_dec_src_event (GstPad * pad, GstObject * parent,
105 static GstStateChangeReturn gst_jpeg_dec_change_state (GstElement * element,
106 GstStateChange transition);
107 static void gst_jpeg_dec_update_qos (GstJpegDec * dec, gdouble proportion,
108 GstClockTimeDiff diff, GstClockTime ts);
109 static void gst_jpeg_dec_reset_qos (GstJpegDec * dec);
110 static void gst_jpeg_dec_read_qos (GstJpegDec * dec, gdouble * proportion,
111 GstClockTime * time);
113 #define gst_jpeg_dec_parent_class parent_class
114 G_DEFINE_TYPE (GstJpegDec, gst_jpeg_dec, GST_TYPE_ELEMENT);
117 gst_jpeg_dec_finalize (GObject * object)
119 GstJpegDec *dec = GST_JPEG_DEC (object);
121 jpeg_destroy_decompress (&dec->cinfo);
123 g_object_unref (dec->adapter);
125 G_OBJECT_CLASS (parent_class)->finalize (object);
129 gst_jpeg_dec_class_init (GstJpegDecClass * klass)
131 GstElementClass *gstelement_class;
132 GObjectClass *gobject_class;
134 gstelement_class = (GstElementClass *) klass;
135 gobject_class = (GObjectClass *) klass;
137 parent_class = g_type_class_peek_parent (klass);
139 gobject_class->finalize = gst_jpeg_dec_finalize;
140 gobject_class->set_property = gst_jpeg_dec_set_property;
141 gobject_class->get_property = gst_jpeg_dec_get_property;
143 g_object_class_install_property (gobject_class, PROP_IDCT_METHOD,
144 g_param_spec_enum ("idct-method", "IDCT Method",
145 "The IDCT algorithm to use", GST_TYPE_IDCT_METHOD,
146 JPEG_DEFAULT_IDCT_METHOD,
147 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
150 * GstJpegDec:max-errors
152 * Error out after receiving N consecutive decoding errors
153 * (-1 = never error out, 0 = automatic, 1 = fail on first error, etc.)
157 g_object_class_install_property (gobject_class, PROP_MAX_ERRORS,
158 g_param_spec_int ("max-errors", "Maximum Consecutive Decoding Errors",
159 "Error out after receiving N consecutive decoding errors "
160 "(-1 = never fail, 0 = automatic, 1 = fail on first error)",
161 -1, G_MAXINT, JPEG_DEFAULT_MAX_ERRORS,
162 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
164 gst_element_class_add_pad_template (gstelement_class,
165 gst_static_pad_template_get (&gst_jpeg_dec_src_pad_template));
166 gst_element_class_add_pad_template (gstelement_class,
167 gst_static_pad_template_get (&gst_jpeg_dec_sink_pad_template));
168 gst_element_class_set_static_metadata (gstelement_class, "JPEG image decoder",
169 "Codec/Decoder/Image",
170 "Decode images from JPEG format", "Wim Taymans <wim@fluendo.com>");
172 gstelement_class->change_state =
173 GST_DEBUG_FUNCPTR (gst_jpeg_dec_change_state);
175 GST_DEBUG_CATEGORY_INIT (jpeg_dec_debug, "jpegdec", 0, "JPEG decoder");
176 GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE");
180 gst_jpeg_dec_clear_error (GstJpegDec * dec)
182 g_free (dec->error_msg);
183 dec->error_msg = NULL;
185 dec->error_func = NULL;
189 gst_jpeg_dec_set_error_va (GstJpegDec * dec, const gchar * func, gint line,
190 const gchar * debug_msg_format, va_list args)
192 #ifndef GST_DISABLE_GST_DEBUG
193 gst_debug_log_valist (GST_CAT_DEFAULT, GST_LEVEL_WARNING, __FILE__, func,
194 line, (GObject *) dec, debug_msg_format, args);
197 g_free (dec->error_msg);
198 if (debug_msg_format)
199 dec->error_msg = g_strdup_vprintf (debug_msg_format, args);
201 dec->error_msg = NULL;
203 dec->error_line = line;
204 dec->error_func = func;
208 gst_jpeg_dec_set_error (GstJpegDec * dec, const gchar * func, gint line,
209 const gchar * debug_msg_format, ...)
213 va_start (va, debug_msg_format);
214 gst_jpeg_dec_set_error_va (dec, func, line, debug_msg_format, va);
219 gst_jpeg_dec_post_error_or_warning (GstJpegDec * dec)
225 max_errors = g_atomic_int_get (&dec->max_errors);
227 if (max_errors < 0) {
229 } else if (max_errors == 0) {
230 /* FIXME: do something more clever in "automatic mode" */
231 if (dec->packetized) {
232 ret = (dec->error_count < 3) ? GST_FLOW_OK : GST_FLOW_ERROR;
234 ret = GST_FLOW_ERROR;
237 ret = (dec->error_count < max_errors) ? GST_FLOW_OK : GST_FLOW_ERROR;
240 GST_INFO_OBJECT (dec, "decoding error %d/%d (%s)", dec->error_count,
241 max_errors, (ret == GST_FLOW_OK) ? "ignoring error" : "erroring out");
243 gst_element_message_full (GST_ELEMENT (dec),
244 (ret == GST_FLOW_OK) ? GST_MESSAGE_WARNING : GST_MESSAGE_ERROR,
245 GST_STREAM_ERROR, GST_STREAM_ERROR_DECODE,
246 g_strdup (_("Failed to decode JPEG image")), dec->error_msg,
247 __FILE__, dec->error_func, dec->error_line);
249 dec->error_msg = NULL;
250 gst_jpeg_dec_clear_error (dec);
255 gst_jpeg_dec_fill_input_buffer (j_decompress_ptr cinfo)
260 dec = CINFO_GET_JPEGDEC (cinfo);
261 g_return_val_if_fail (dec != NULL, FALSE);
263 av = gst_adapter_available_fast (dec->adapter);
264 GST_DEBUG_OBJECT (dec, "fill_input_buffer: fast av=%u, remaining=%u", av,
268 GST_DEBUG_OBJECT (dec, "Out of data");
272 if (dec->rem_img_len < av)
273 av = dec->rem_img_len;
274 dec->rem_img_len -= av;
276 g_free (dec->cur_buf);
277 dec->cur_buf = gst_adapter_take (dec->adapter, av);
279 cinfo->src->next_input_byte = dec->cur_buf;
280 cinfo->src->bytes_in_buffer = av;
286 gst_jpeg_dec_init_source (j_decompress_ptr cinfo)
288 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "init_source");
293 gst_jpeg_dec_skip_input_data (j_decompress_ptr cinfo, glong num_bytes)
295 GstJpegDec *dec = CINFO_GET_JPEGDEC (cinfo);
297 GST_DEBUG_OBJECT (dec, "skip %ld bytes", num_bytes);
299 if (num_bytes > 0 && cinfo->src->bytes_in_buffer >= num_bytes) {
300 cinfo->src->next_input_byte += (size_t) num_bytes;
301 cinfo->src->bytes_in_buffer -= (size_t) num_bytes;
302 } else if (num_bytes > 0) {
305 num_bytes -= cinfo->src->bytes_in_buffer;
306 cinfo->src->next_input_byte += (size_t) cinfo->src->bytes_in_buffer;
307 cinfo->src->bytes_in_buffer = 0;
309 available = gst_adapter_available (dec->adapter);
310 if (available < num_bytes || available < dec->rem_img_len) {
311 GST_WARNING_OBJECT (dec, "Less bytes to skip than available in the "
312 "adapter or the remaining image length %ld < %d or %u",
313 num_bytes, available, dec->rem_img_len);
315 num_bytes = MIN (MIN (num_bytes, available), dec->rem_img_len);
316 gst_adapter_flush (dec->adapter, num_bytes);
317 dec->rem_img_len -= num_bytes;
322 gst_jpeg_dec_resync_to_restart (j_decompress_ptr cinfo, gint desired)
324 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "resync_to_start");
329 gst_jpeg_dec_term_source (j_decompress_ptr cinfo)
331 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "term_source");
336 gst_jpeg_dec_my_output_message (j_common_ptr cinfo)
338 return; /* do nothing */
342 gst_jpeg_dec_my_emit_message (j_common_ptr cinfo, int msg_level)
344 /* GST_LOG_OBJECT (CINFO_GET_JPEGDEC (&cinfo), "msg_level=%d", msg_level); */
349 gst_jpeg_dec_my_error_exit (j_common_ptr cinfo)
351 struct GstJpegDecErrorMgr *err_mgr = (struct GstJpegDecErrorMgr *) cinfo->err;
353 (*cinfo->err->output_message) (cinfo);
354 longjmp (err_mgr->setjmp_buffer, 1);
358 gst_jpeg_dec_init (GstJpegDec * dec)
360 GST_DEBUG ("initializing");
362 /* create the sink and src pads */
364 gst_pad_new_from_static_template (&gst_jpeg_dec_sink_pad_template,
366 gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
367 gst_pad_set_chain_function (dec->sinkpad,
368 GST_DEBUG_FUNCPTR (gst_jpeg_dec_chain));
369 gst_pad_set_event_function (dec->sinkpad,
370 GST_DEBUG_FUNCPTR (gst_jpeg_dec_sink_event));
371 gst_pad_set_query_function (dec->sinkpad,
372 GST_DEBUG_FUNCPTR (gst_jpeg_dec_sink_query));
375 gst_pad_new_from_static_template (&gst_jpeg_dec_src_pad_template, "src");
376 gst_pad_set_event_function (dec->srcpad,
377 GST_DEBUG_FUNCPTR (gst_jpeg_dec_src_event));
378 gst_pad_use_fixed_caps (dec->srcpad);
379 gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
382 memset (&dec->cinfo, 0, sizeof (dec->cinfo));
383 memset (&dec->jerr, 0, sizeof (dec->jerr));
384 dec->cinfo.err = jpeg_std_error (&dec->jerr.pub);
385 dec->jerr.pub.output_message = gst_jpeg_dec_my_output_message;
386 dec->jerr.pub.emit_message = gst_jpeg_dec_my_emit_message;
387 dec->jerr.pub.error_exit = gst_jpeg_dec_my_error_exit;
389 jpeg_create_decompress (&dec->cinfo);
391 dec->cinfo.src = (struct jpeg_source_mgr *) &dec->jsrc;
392 dec->cinfo.src->init_source = gst_jpeg_dec_init_source;
393 dec->cinfo.src->fill_input_buffer = gst_jpeg_dec_fill_input_buffer;
394 dec->cinfo.src->skip_input_data = gst_jpeg_dec_skip_input_data;
395 dec->cinfo.src->resync_to_restart = gst_jpeg_dec_resync_to_restart;
396 dec->cinfo.src->term_source = gst_jpeg_dec_term_source;
399 /* init properties */
400 dec->idct_method = JPEG_DEFAULT_IDCT_METHOD;
401 dec->max_errors = JPEG_DEFAULT_MAX_ERRORS;
403 dec->adapter = gst_adapter_new ();
407 gst_jpeg_dec_ensure_header (GstJpegDec * dec)
412 av = gst_adapter_available (dec->adapter);
413 /* we expect at least 4 bytes, first of which start marker */
414 offset = gst_adapter_masked_scan_uint32 (dec->adapter, 0xffffff00, 0xffd8ff00,
416 if (G_UNLIKELY (offset < 0)) {
417 GST_DEBUG_OBJECT (dec, "No JPEG header in current buffer");
420 gst_adapter_flush (dec->adapter, av - 4);
425 GST_LOG_OBJECT (dec, "Skipping %u bytes.", offset);
426 gst_adapter_flush (dec->adapter, offset);
428 GST_DEBUG_OBJECT (dec, "Found JPEG header");
433 static inline gboolean
434 gst_jpeg_dec_parse_tag_has_entropy_segment (guint8 tag)
436 if (tag == 0xda || (tag >= 0xd0 && tag <= 0xd7))
441 /* returns image length in bytes if parsed successfully,
442 * otherwise 0 if more data needed,
443 * if < 0 the absolute value needs to be flushed */
445 gst_jpeg_dec_parse_image_data (GstJpegDec * dec)
449 GstAdapter *adapter = dec->adapter;
450 gint offset, noffset;
452 size = gst_adapter_available (adapter);
454 /* we expect at least 4 bytes, first of which start marker */
455 if (gst_adapter_masked_scan_uint32 (adapter, 0xffff0000, 0xffd80000, 0, 4))
458 GST_DEBUG ("Parsing jpeg image data (%u bytes)", size);
460 GST_DEBUG ("Parse state: offset=%d, resync=%d, entropy len=%d",
461 dec->parse_offset, dec->parse_resync, dec->parse_entropy_len);
463 /* offset is 2 less than actual offset;
464 * - adapter needs at least 4 bytes for scanning,
465 * - start and end marker ensure at least that much
467 /* resume from state offset */
468 offset = dec->parse_offset;
475 gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00, 0x0000ff00,
476 offset, size - offset, &value);
477 /* lost sync if 0xff marker not where expected */
478 if ((resync = (noffset != offset))) {
479 GST_DEBUG ("Lost sync at 0x%08x, resyncing", offset + 2);
481 /* may have marker, but could have been resyncng */
482 resync = resync || dec->parse_resync;
483 /* Skip over extra 0xff */
484 while ((noffset >= 0) && ((value & 0xff) == 0xff)) {
487 gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00, 0x0000ff00,
488 noffset, size - noffset, &value);
490 /* enough bytes left for marker? (we need 0xNN after the 0xff) */
492 GST_DEBUG ("at end of input and no EOI marker found, need more data");
496 /* now lock on the marker we found */
498 value = value & 0xff;
500 GST_DEBUG ("0x%08x: EOI marker", offset + 2);
501 /* clear parse state */
502 dec->parse_resync = FALSE;
503 dec->parse_offset = 0;
505 } else if (value == 0xd8) {
506 /* Skip this frame if we found another SOI marker */
507 GST_DEBUG ("0x%08x: SOI marker before EOI, skipping", offset + 2);
508 dec->parse_resync = FALSE;
509 dec->parse_offset = 0;
510 return -(offset + 2);
514 if (value >= 0xd0 && value <= 0xd7)
517 /* peek tag and subsequent length */
518 if (offset + 2 + 4 > size)
521 gst_adapter_masked_scan_uint32_peek (adapter, 0x0, 0x0, offset + 2, 4,
523 frame_len = frame_len & 0xffff;
525 GST_DEBUG ("0x%08x: tag %02x, frame_len=%u", offset + 2, value, frame_len);
526 /* the frame length includes the 2 bytes for the length; here we want at
527 * least 2 more bytes at the end for an end marker */
528 if (offset + 2 + 2 + frame_len + 2 > size) {
532 if (gst_jpeg_dec_parse_tag_has_entropy_segment (value)) {
533 guint eseglen = dec->parse_entropy_len;
535 GST_DEBUG ("0x%08x: finding entropy segment length", offset + 2);
536 noffset = offset + 2 + frame_len + dec->parse_entropy_len;
538 noffset = gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00,
539 0x0000ff00, noffset, size - noffset, &value);
542 dec->parse_entropy_len = size - offset - 4 - frame_len - 2;
545 if ((value & 0xff) != 0x00) {
546 eseglen = noffset - offset - frame_len - 2;
551 dec->parse_entropy_len = 0;
552 frame_len += eseglen;
553 GST_DEBUG ("entropy segment length=%u => frame_len=%u", eseglen,
557 /* check if we will still be in sync if we interpret
558 * this as a sync point and skip this frame */
559 noffset = offset + frame_len + 2;
560 noffset = gst_adapter_masked_scan_uint32 (adapter, 0x0000ff00, 0x0000ff00,
563 /* ignore and continue resyncing until we hit the end
564 * of our data or find a sync point that looks okay */
568 GST_DEBUG ("found sync at 0x%x", offset + 2);
571 offset += frame_len + 2;
577 dec->parse_offset = offset;
578 dec->parse_resync = resync;
583 /* shamelessly ripped from jpegutils.c in mjpegtools */
585 add_huff_table (j_decompress_ptr dinfo,
586 JHUFF_TBL ** htblptr, const UINT8 * bits, const UINT8 * val)
587 /* Define a Huffman table */
591 if (*htblptr == NULL)
592 *htblptr = jpeg_alloc_huff_table ((j_common_ptr) dinfo);
596 /* Copy the number-of-symbols-of-each-code-length counts */
597 memcpy ((*htblptr)->bits, bits, sizeof ((*htblptr)->bits));
599 /* Validate the counts. We do this here mainly so we can copy the right
600 * number of symbols from the val[] array, without risking marching off
601 * the end of memory. jchuff.c will do a more thorough test later.
604 for (len = 1; len <= 16; len++)
605 nsymbols += bits[len];
606 if (nsymbols < 1 || nsymbols > 256)
607 g_error ("jpegutils.c: add_huff_table failed badly. ");
609 memcpy ((*htblptr)->huffval, val, nsymbols * sizeof (UINT8));
615 std_huff_tables (j_decompress_ptr dinfo)
616 /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
617 /* IMPORTANT: these are only valid for 8-bit data precision! */
619 static const UINT8 bits_dc_luminance[17] =
620 { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
621 static const UINT8 val_dc_luminance[] =
622 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
624 static const UINT8 bits_dc_chrominance[17] =
625 { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
626 static const UINT8 val_dc_chrominance[] =
627 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
629 static const UINT8 bits_ac_luminance[17] =
630 { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
631 static const UINT8 val_ac_luminance[] =
632 { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
633 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
634 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
635 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
636 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
637 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
638 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
639 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
640 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
641 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
642 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
643 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
644 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
645 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
646 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
647 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
648 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
649 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
650 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
651 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
655 static const UINT8 bits_ac_chrominance[17] =
656 { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
657 static const UINT8 val_ac_chrominance[] =
658 { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
659 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
660 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
661 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
662 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
663 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
664 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
665 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
666 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
667 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
668 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
669 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
670 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
671 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
672 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
673 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
674 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
675 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
676 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
677 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
681 add_huff_table (dinfo, &dinfo->dc_huff_tbl_ptrs[0],
682 bits_dc_luminance, val_dc_luminance);
683 add_huff_table (dinfo, &dinfo->ac_huff_tbl_ptrs[0],
684 bits_ac_luminance, val_ac_luminance);
685 add_huff_table (dinfo, &dinfo->dc_huff_tbl_ptrs[1],
686 bits_dc_chrominance, val_dc_chrominance);
687 add_huff_table (dinfo, &dinfo->ac_huff_tbl_ptrs[1],
688 bits_ac_chrominance, val_ac_chrominance);
694 guarantee_huff_tables (j_decompress_ptr dinfo)
696 if ((dinfo->dc_huff_tbl_ptrs[0] == NULL) &&
697 (dinfo->dc_huff_tbl_ptrs[1] == NULL) &&
698 (dinfo->ac_huff_tbl_ptrs[0] == NULL) &&
699 (dinfo->ac_huff_tbl_ptrs[1] == NULL)) {
700 GST_DEBUG ("Generating standard Huffman tables for this frame.");
701 std_huff_tables (dinfo);
706 gst_jpeg_dec_setcaps (GstJpegDec * dec, GstCaps * caps)
709 const GValue *framerate;
711 s = gst_caps_get_structure (caps, 0);
713 if ((framerate = gst_structure_get_value (s, "framerate")) != NULL) {
714 dec->in_fps_n = gst_value_get_fraction_numerator (framerate);
715 dec->in_fps_d = gst_value_get_fraction_denominator (framerate);
716 dec->packetized = TRUE;
717 GST_DEBUG ("got framerate of %d/%d fps => packetized mode",
718 dec->in_fps_n, dec->in_fps_d);
721 /* do not extract width/height here. we do that in the chain
722 * function on a per-frame basis (including the line[] array
725 /* But we can take the framerate values and set them on the src pad */
731 gst_jpeg_dec_getcaps (GstPad * pad, GstCaps * filter)
738 dec = GST_JPEG_DEC (GST_OBJECT_PARENT (pad));
740 if (gst_pad_has_current_caps (pad))
741 return gst_pad_get_current_caps (pad);
743 peer = gst_pad_get_peer (dec->srcpad);
745 templ_caps = gst_pad_get_pad_template_caps (pad);
752 peer_caps = gst_pad_query_caps (peer, filter);
754 /* Translate peercaps to image/jpeg */
755 peer_caps = gst_caps_make_writable (peer_caps);
756 n = gst_caps_get_size (peer_caps);
757 for (i = 0; i < n; i++) {
758 s = gst_caps_get_structure (peer_caps, i);
760 gst_structure_set_name (s, "image/jpeg");
763 caps = gst_caps_intersect_full (peer_caps, templ_caps,
764 GST_CAPS_INTERSECT_FIRST);
765 gst_caps_unref (peer_caps);
766 gst_caps_unref (templ_caps);
767 gst_object_unref (peer);
778 hresamplecpy1 (guint8 * dest, const guint8 * src, guint len)
782 for (i = 0; i < len; ++i) {
783 /* equivalent to: dest[i] = src[i << 1] */
792 gst_jpeg_dec_free_buffers (GstJpegDec * dec)
796 for (i = 0; i < 16; i++) {
797 g_free (dec->idr_y[i]);
798 g_free (dec->idr_u[i]);
799 g_free (dec->idr_v[i]);
800 dec->idr_y[i] = NULL;
801 dec->idr_u[i] = NULL;
802 dec->idr_v[i] = NULL;
805 dec->idr_width_allocated = 0;
808 static inline gboolean
809 gst_jpeg_dec_ensure_buffers (GstJpegDec * dec, guint maxrowbytes)
813 if (G_LIKELY (dec->idr_width_allocated >= maxrowbytes))
816 /* FIXME: maybe just alloc one or three blocks altogether? */
817 for (i = 0; i < 16; i++) {
818 dec->idr_y[i] = g_try_realloc (dec->idr_y[i], maxrowbytes);
819 dec->idr_u[i] = g_try_realloc (dec->idr_u[i], maxrowbytes);
820 dec->idr_v[i] = g_try_realloc (dec->idr_v[i], maxrowbytes);
822 if (G_UNLIKELY (!dec->idr_y[i] || !dec->idr_u[i] || !dec->idr_v[i])) {
823 GST_WARNING_OBJECT (dec, "out of memory, i=%d, bytes=%u", i, maxrowbytes);
828 dec->idr_width_allocated = maxrowbytes;
829 GST_LOG_OBJECT (dec, "allocated temp memory, %u bytes/row", maxrowbytes);
834 gst_jpeg_dec_decode_grayscale (GstJpegDec * dec, GstVideoFrame * frame)
837 guchar **scanarray[1] = { rows };
842 gint pstride, rstride;
844 GST_DEBUG_OBJECT (dec, "indirect decoding of grayscale");
846 width = GST_VIDEO_FRAME_WIDTH (frame);
847 height = GST_VIDEO_FRAME_HEIGHT (frame);
849 if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
852 base[0] = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
853 pstride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0);
854 rstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
856 memcpy (rows, dec->idr_y, 16 * sizeof (gpointer));
860 lines = jpeg_read_raw_data (&dec->cinfo, scanarray, DCTSIZE);
861 if (G_LIKELY (lines > 0)) {
862 for (j = 0; (j < DCTSIZE) && (i < height); j++, i++) {
866 for (k = 0; k < width; k++) {
867 base[0][p] = rows[j][k];
873 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
879 gst_jpeg_dec_decode_rgb (GstJpegDec * dec, GstVideoFrame * frame)
881 guchar *r_rows[16], *g_rows[16], *b_rows[16];
882 guchar **scanarray[3] = { r_rows, g_rows, b_rows };
886 guint pstride, rstride;
889 GST_DEBUG_OBJECT (dec, "indirect decoding of RGB");
891 width = GST_VIDEO_FRAME_WIDTH (frame);
892 height = GST_VIDEO_FRAME_HEIGHT (frame);
894 if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
897 for (i = 0; i < 3; i++)
898 base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
900 pstride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0);
901 rstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
903 memcpy (r_rows, dec->idr_y, 16 * sizeof (gpointer));
904 memcpy (g_rows, dec->idr_u, 16 * sizeof (gpointer));
905 memcpy (b_rows, dec->idr_v, 16 * sizeof (gpointer));
909 lines = jpeg_read_raw_data (&dec->cinfo, scanarray, DCTSIZE);
910 if (G_LIKELY (lines > 0)) {
911 for (j = 0; (j < DCTSIZE) && (i < height); j++, i++) {
915 for (k = 0; k < width; k++) {
916 base[0][p] = r_rows[j][k];
917 base[1][p] = g_rows[j][k];
918 base[2][p] = b_rows[j][k];
926 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
932 gst_jpeg_dec_decode_indirect (GstJpegDec * dec, GstVideoFrame * frame,
933 gint r_v, gint r_h, gint comp)
935 guchar *y_rows[16], *u_rows[16], *v_rows[16];
936 guchar **scanarray[3] = { y_rows, u_rows, v_rows };
939 guchar *base[3], *last[3];
943 GST_DEBUG_OBJECT (dec,
944 "unadvantageous width or r_h, taking slow route involving memcpy");
946 width = GST_VIDEO_FRAME_WIDTH (frame);
947 height = GST_VIDEO_FRAME_HEIGHT (frame);
949 if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
952 for (i = 0; i < 3; i++) {
953 base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
954 stride[i] = GST_VIDEO_FRAME_COMP_STRIDE (frame, i);
955 /* make sure we don't make jpeglib write beyond our buffer,
956 * which might happen if (height % (r_v*DCTSIZE)) != 0 */
957 last[i] = base[i] + (GST_VIDEO_FRAME_COMP_STRIDE (frame, i) *
958 (GST_VIDEO_FRAME_COMP_HEIGHT (frame, i) - 1));
961 memcpy (y_rows, dec->idr_y, 16 * sizeof (gpointer));
962 memcpy (u_rows, dec->idr_u, 16 * sizeof (gpointer));
963 memcpy (v_rows, dec->idr_v, 16 * sizeof (gpointer));
965 /* fill chroma components for grayscale */
967 GST_DEBUG_OBJECT (dec, "grayscale, filling chroma");
968 for (i = 0; i < 16; i++) {
969 memset (u_rows[i], GST_ROUND_UP_32 (width), 0x80);
970 memset (v_rows[i], GST_ROUND_UP_32 (width), 0x80);
974 for (i = 0; i < height; i += r_v * DCTSIZE) {
975 lines = jpeg_read_raw_data (&dec->cinfo, scanarray, r_v * DCTSIZE);
976 if (G_LIKELY (lines > 0)) {
977 for (j = 0, k = 0; j < (r_v * DCTSIZE); j += r_v, k++) {
978 if (G_LIKELY (base[0] <= last[0])) {
979 memcpy (base[0], y_rows[j], stride[0]);
980 base[0] += stride[0];
983 if (G_LIKELY (base[0] <= last[0])) {
984 memcpy (base[0], y_rows[j + 1], stride[0]);
985 base[0] += stride[0];
988 if (G_LIKELY (base[1] <= last[1] && base[2] <= last[2])) {
990 memcpy (base[1], u_rows[k], stride[1]);
991 memcpy (base[2], v_rows[k], stride[2]);
992 } else if (r_h == 1) {
993 hresamplecpy1 (base[1], u_rows[k], stride[1]);
994 hresamplecpy1 (base[2], v_rows[k], stride[2]);
996 /* FIXME: implement (at least we avoid crashing by doing nothing) */
1000 if (r_v == 2 || (k & 1) != 0) {
1001 base[1] += stride[1];
1002 base[2] += stride[2];
1006 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
1011 static GstFlowReturn
1012 gst_jpeg_dec_decode_direct (GstJpegDec * dec, GstVideoFrame * frame)
1014 guchar **line[3]; /* the jpeg line buffer */
1015 guchar *y[4 * DCTSIZE] = { NULL, }; /* alloc enough for the lines */
1016 guchar *u[4 * DCTSIZE] = { NULL, }; /* r_v will be <4 */
1017 guchar *v[4 * DCTSIZE] = { NULL, };
1019 gint lines, v_samp[3];
1020 guchar *base[3], *last[3];
1028 v_samp[0] = dec->cinfo.comp_info[0].v_samp_factor;
1029 v_samp[1] = dec->cinfo.comp_info[1].v_samp_factor;
1030 v_samp[2] = dec->cinfo.comp_info[2].v_samp_factor;
1032 if (G_UNLIKELY (v_samp[0] > 2 || v_samp[1] > 2 || v_samp[2] > 2))
1033 goto format_not_supported;
1035 height = GST_VIDEO_FRAME_HEIGHT (frame);
1037 for (i = 0; i < 3; i++) {
1038 base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
1039 stride[i] = GST_VIDEO_FRAME_COMP_STRIDE (frame, i);
1040 /* make sure we don't make jpeglib write beyond our buffer,
1041 * which might happen if (height % (r_v*DCTSIZE)) != 0 */
1042 last[i] = base[i] + (GST_VIDEO_FRAME_COMP_STRIDE (frame, i) *
1043 (GST_VIDEO_FRAME_COMP_HEIGHT (frame, i) - 1));
1046 /* let jpeglib decode directly into our final buffer */
1047 GST_DEBUG_OBJECT (dec, "decoding directly into output buffer");
1049 for (i = 0; i < height; i += v_samp[0] * DCTSIZE) {
1050 for (j = 0; j < (v_samp[0] * DCTSIZE); ++j) {
1052 line[0][j] = base[0] + (i + j) * stride[0];
1053 if (G_UNLIKELY (line[0][j] > last[0]))
1054 line[0][j] = last[0];
1056 if (v_samp[1] == v_samp[0]) {
1057 line[1][j] = base[1] + ((i + j) / 2) * stride[1];
1058 } else if (j < (v_samp[1] * DCTSIZE)) {
1059 line[1][j] = base[1] + ((i / 2) + j) * stride[1];
1061 if (G_UNLIKELY (line[1][j] > last[1]))
1062 line[1][j] = last[1];
1064 if (v_samp[2] == v_samp[0]) {
1065 line[2][j] = base[2] + ((i + j) / 2) * stride[2];
1066 } else if (j < (v_samp[2] * DCTSIZE)) {
1067 line[2][j] = base[2] + ((i / 2) + j) * stride[2];
1069 if (G_UNLIKELY (line[2][j] > last[2]))
1070 line[2][j] = last[2];
1073 lines = jpeg_read_raw_data (&dec->cinfo, line, v_samp[0] * DCTSIZE);
1074 if (G_UNLIKELY (!lines)) {
1075 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
1080 format_not_supported:
1082 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1083 "Unsupported subsampling schema: v_samp factors: %u %u %u",
1084 v_samp[0], v_samp[1], v_samp[2]);
1085 return GST_FLOW_ERROR;
1090 gst_jpeg_dec_update_qos (GstJpegDec * dec, gdouble proportion,
1091 GstClockTimeDiff diff, GstClockTime ts)
1093 GST_OBJECT_LOCK (dec);
1094 dec->proportion = proportion;
1095 if (G_LIKELY (ts != GST_CLOCK_TIME_NONE)) {
1096 if (G_UNLIKELY (diff > dec->qos_duration))
1097 dec->earliest_time = ts + 2 * diff + dec->qos_duration;
1099 dec->earliest_time = ts + diff;
1101 dec->earliest_time = GST_CLOCK_TIME_NONE;
1103 GST_OBJECT_UNLOCK (dec);
1107 gst_jpeg_dec_reset_qos (GstJpegDec * dec)
1109 gst_jpeg_dec_update_qos (dec, 0.5, 0, GST_CLOCK_TIME_NONE);
1113 gst_jpeg_dec_read_qos (GstJpegDec * dec, gdouble * proportion,
1114 GstClockTime * time)
1116 GST_OBJECT_LOCK (dec);
1117 *proportion = dec->proportion;
1118 *time = dec->earliest_time;
1119 GST_OBJECT_UNLOCK (dec);
1122 /* Perform qos calculations before decoding the next frame. Returns TRUE if the
1123 * frame should be decoded, FALSE if the frame can be dropped entirely */
1125 gst_jpeg_dec_do_qos (GstJpegDec * dec, GstClockTime timestamp)
1127 GstClockTime qostime, earliest_time;
1130 /* no timestamp, can't do QoS => decode frame */
1131 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (timestamp))) {
1132 GST_LOG_OBJECT (dec, "invalid timestamp, can't do QoS, decode frame");
1136 /* get latest QoS observation values */
1137 gst_jpeg_dec_read_qos (dec, &proportion, &earliest_time);
1139 /* skip qos if we have no observation (yet) => decode frame */
1140 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (earliest_time))) {
1141 GST_LOG_OBJECT (dec, "no observation yet, decode frame");
1145 /* qos is done on running time */
1146 qostime = gst_segment_to_running_time (&dec->segment, GST_FORMAT_TIME,
1149 /* see how our next timestamp relates to the latest qos timestamp */
1150 GST_LOG_OBJECT (dec, "qostime %" GST_TIME_FORMAT ", earliest %"
1151 GST_TIME_FORMAT, GST_TIME_ARGS (qostime), GST_TIME_ARGS (earliest_time));
1153 if (qostime != GST_CLOCK_TIME_NONE && qostime <= earliest_time) {
1154 GST_DEBUG_OBJECT (dec, "we are late, drop frame");
1158 GST_LOG_OBJECT (dec, "decode frame");
1163 gst_jpeg_dec_buffer_pool (GstJpegDec * dec, GstCaps * caps)
1166 GstBufferPool *pool;
1167 guint size, min, max;
1168 GstStructure *config;
1169 static GstAllocationParams params = { 0, 0, 0, 15, };
1171 GST_DEBUG_OBJECT (dec, "setting up bufferpool");
1173 /* find a pool for the negotiated caps now */
1174 query = gst_query_new_allocation (caps, TRUE);
1176 if (!gst_pad_peer_query (dec->srcpad, query)) {
1177 GST_DEBUG_OBJECT (dec, "peer query failed, using defaults");
1180 if (gst_query_get_n_allocation_pools (query) > 0) {
1181 /* we got configuration from our peer, parse them */
1182 gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
1183 size = MAX (size, dec->info.size);
1186 size = dec->info.size;
1189 gst_query_unref (query);
1192 /* we did not get a pool, make one ourselves then */
1193 pool = gst_buffer_pool_new ();
1196 config = gst_buffer_pool_get_config (pool);
1197 gst_buffer_pool_config_set_params (config, caps, size, min, max);
1198 gst_buffer_pool_config_set_allocator (config, NULL, ¶ms);
1200 gst_buffer_pool_set_config (pool, config);
1203 gst_buffer_pool_set_active (dec->pool, FALSE);
1204 gst_object_unref (dec->pool);
1209 gst_buffer_pool_set_active (pool, TRUE);
1215 gst_jpeg_dec_negotiate (GstJpegDec * dec, gint width, gint height, gint clrspc)
1218 GstVideoFormat format;
1221 if (G_UNLIKELY (width == dec->info.width && height == dec->info.height &&
1222 dec->in_fps_n == dec->info.fps_n && dec->in_fps_d == dec->info.fps_d
1223 && clrspc == dec->clrspc))
1226 gst_video_info_init (&info);
1228 /* framerate == 0/1 is a still frame */
1229 if (dec->in_fps_d == 0) {
1233 info.fps_n = dec->in_fps_n;
1234 info.fps_d = dec->in_fps_d;
1237 /* calculate or assume an average frame duration for QoS purposes */
1238 GST_OBJECT_LOCK (dec);
1239 if (info.fps_n != 0) {
1241 gst_util_uint64_scale (GST_SECOND, info.fps_d, info.fps_n);
1242 dec->duration = dec->qos_duration;
1244 /* if not set just use 25fps */
1245 dec->qos_duration = gst_util_uint64_scale (GST_SECOND, 1, 25);
1246 dec->duration = GST_CLOCK_TIME_NONE;
1248 GST_OBJECT_UNLOCK (dec);
1250 if (dec->cinfo.jpeg_color_space == JCS_RGB) {
1252 GstCaps *allowed_caps;
1253 GstVideoInfo tmpinfo;
1255 GST_DEBUG_OBJECT (dec, "selecting RGB format");
1256 /* retrieve allowed caps, and find the first one that reasonably maps
1257 * to the parameters of the colourspace */
1258 caps = gst_pad_get_allowed_caps (dec->srcpad);
1260 GST_DEBUG_OBJECT (dec, "... but no peer, using template caps");
1261 /* need to copy because get_allowed_caps returns a ref,
1262 * and get_pad_template_caps doesn't */
1263 caps = gst_pad_get_pad_template_caps (dec->srcpad);
1265 /* avoid lists of formats, etc */
1266 allowed_caps = gst_caps_normalize (caps);
1268 GST_LOG_OBJECT (dec, "allowed source caps %" GST_PTR_FORMAT, allowed_caps);
1270 for (i = 0; i < gst_caps_get_size (allowed_caps); i++) {
1272 gst_caps_unref (caps);
1273 caps = gst_caps_copy_nth (allowed_caps, i);
1274 /* sigh, ds and _parse_caps need fixed caps for parsing, fixate */
1275 caps = gst_caps_fixate (caps);
1276 GST_LOG_OBJECT (dec, "checking caps %" GST_PTR_FORMAT, caps);
1278 if (!gst_video_info_from_caps (&tmpinfo, caps))
1280 /* we'll settle for the first (preferred) downstream rgb format */
1281 if (GST_VIDEO_INFO_IS_RGB (&tmpinfo))
1283 /* default fall-back */
1284 format = GST_VIDEO_FORMAT_RGB;
1287 gst_caps_unref (caps);
1288 gst_caps_unref (allowed_caps);
1289 } else if (dec->cinfo.jpeg_color_space == JCS_GRAYSCALE) {
1290 /* TODO is anything else then 8bit supported in jpeg? */
1291 format = GST_VIDEO_FORMAT_GRAY8;
1293 /* go for plain and simple I420 */
1294 /* TODO other YUV cases ? */
1295 format = GST_VIDEO_FORMAT_I420;
1298 gst_video_info_set_format (&info, format, width, height);
1299 caps = gst_video_info_to_caps (&info);
1301 GST_DEBUG_OBJECT (dec, "setting caps %" GST_PTR_FORMAT, caps);
1302 GST_DEBUG_OBJECT (dec, "max_v_samp_factor=%d", dec->cinfo.max_v_samp_factor);
1303 GST_DEBUG_OBJECT (dec, "max_h_samp_factor=%d", dec->cinfo.max_h_samp_factor);
1305 gst_pad_set_caps (dec->srcpad, caps);
1308 dec->clrspc = clrspc;
1310 gst_jpeg_dec_buffer_pool (dec, caps);
1311 gst_caps_unref (caps);
1316 static GstFlowReturn
1317 gst_jpeg_dec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
1319 GstFlowReturn ret = GST_FLOW_OK;
1321 GstBuffer *outbuf = NULL;
1326 GstClockTime timestamp, duration;
1327 GstVideoFrame frame;
1329 dec = GST_JPEG_DEC (parent);
1331 timestamp = GST_BUFFER_TIMESTAMP (buf);
1332 duration = GST_BUFFER_DURATION (buf);
1334 if (GST_CLOCK_TIME_IS_VALID (timestamp))
1335 dec->next_ts = timestamp;
1337 if (GST_BUFFER_IS_DISCONT (buf)) {
1338 GST_DEBUG_OBJECT (dec, "buffer has DISCONT flag set");
1339 dec->discont = TRUE;
1340 if (!dec->packetized && gst_adapter_available (dec->adapter)) {
1341 GST_WARNING_OBJECT (dec, "DISCONT buffer in non-packetized mode, bad");
1342 gst_adapter_clear (dec->adapter);
1346 gst_adapter_push (dec->adapter, buf);
1349 /* If we are non-packetized and know the total incoming size in bytes,
1350 * just wait until we have enough before doing any processing. */
1352 if (!dec->packetized && (dec->segment.format == GST_FORMAT_BYTES) &&
1353 (dec->segment.stop != -1) &&
1354 (gst_adapter_available (dec->adapter) < dec->segment.stop)) {
1355 /* We assume that non-packetized input in bytes is *one* single jpeg image */
1356 GST_DEBUG ("Non-packetized mode. Got %" G_GSIZE_FORMAT " bytes, "
1357 "need %" G_GINT64_FORMAT, gst_adapter_available (dec->adapter),
1359 goto need_more_data;
1363 if (!gst_jpeg_dec_ensure_header (dec))
1364 goto need_more_data;
1366 /* If we know that each input buffer contains data
1367 * for a whole jpeg image (e.g. MJPEG streams), just
1368 * do some sanity checking instead of parsing all of
1370 if (dec->packetized) {
1371 img_len = gst_adapter_available (dec->adapter);
1373 /* Parse jpeg image to handle jpeg input that
1374 * is not aligned to buffer boundaries */
1375 img_len = gst_jpeg_dec_parse_image_data (dec);
1378 goto need_more_data;
1379 } else if (img_len < 0) {
1380 gst_adapter_flush (dec->adapter, -img_len);
1385 dec->rem_img_len = img_len;
1387 GST_LOG_OBJECT (dec, "image size = %u", img_len);
1389 /* QoS: if we're too late anyway, skip decoding */
1390 if (dec->packetized && !gst_jpeg_dec_do_qos (dec, timestamp))
1393 #ifndef GST_DISABLE_GST_DEBUG
1397 gst_adapter_copy (dec->adapter, data, 0, 4);
1398 GST_LOG_OBJECT (dec, "reading header %02x %02x %02x %02x", data[0], data[1],
1403 gst_jpeg_dec_fill_input_buffer (&dec->cinfo);
1405 if (setjmp (dec->jerr.setjmp_buffer)) {
1406 code = dec->jerr.pub.msg_code;
1408 if (code == JERR_INPUT_EOF) {
1409 GST_DEBUG ("jpeg input EOF error, we probably need more data");
1410 goto need_more_data;
1416 hdr_ok = jpeg_read_header (&dec->cinfo, TRUE);
1417 if (G_UNLIKELY (hdr_ok != JPEG_HEADER_OK)) {
1418 GST_WARNING_OBJECT (dec, "reading the header failed, %d", hdr_ok);
1421 GST_LOG_OBJECT (dec, "num_components=%d", dec->cinfo.num_components);
1422 GST_LOG_OBJECT (dec, "jpeg_color_space=%d", dec->cinfo.jpeg_color_space);
1424 if (!dec->cinfo.num_components || !dec->cinfo.comp_info)
1425 goto components_not_supported;
1427 r_h = dec->cinfo.comp_info[0].h_samp_factor;
1428 r_v = dec->cinfo.comp_info[0].v_samp_factor;
1430 GST_LOG_OBJECT (dec, "r_h = %d, r_v = %d", r_h, r_v);
1432 if (dec->cinfo.num_components > 3)
1433 goto components_not_supported;
1435 /* verify color space expectation to avoid going *boom* or bogus output */
1436 if (dec->cinfo.jpeg_color_space != JCS_YCbCr &&
1437 dec->cinfo.jpeg_color_space != JCS_GRAYSCALE &&
1438 dec->cinfo.jpeg_color_space != JCS_RGB)
1439 goto unsupported_colorspace;
1441 #ifndef GST_DISABLE_GST_DEBUG
1445 for (i = 0; i < dec->cinfo.num_components; ++i) {
1446 GST_LOG_OBJECT (dec, "[%d] h_samp_factor=%d, v_samp_factor=%d, cid=%d",
1447 i, dec->cinfo.comp_info[i].h_samp_factor,
1448 dec->cinfo.comp_info[i].v_samp_factor,
1449 dec->cinfo.comp_info[i].component_id);
1454 /* prepare for raw output */
1455 dec->cinfo.do_fancy_upsampling = FALSE;
1456 dec->cinfo.do_block_smoothing = FALSE;
1457 dec->cinfo.out_color_space = dec->cinfo.jpeg_color_space;
1458 dec->cinfo.dct_method = dec->idct_method;
1459 dec->cinfo.raw_data_out = TRUE;
1461 GST_LOG_OBJECT (dec, "starting decompress");
1462 guarantee_huff_tables (&dec->cinfo);
1463 if (!jpeg_start_decompress (&dec->cinfo)) {
1464 GST_WARNING_OBJECT (dec, "failed to start decompression cycle");
1467 /* sanity checks to get safe and reasonable output */
1468 switch (dec->cinfo.jpeg_color_space) {
1470 if (dec->cinfo.num_components != 1)
1471 goto invalid_yuvrgbgrayscale;
1474 if (dec->cinfo.num_components != 3 || dec->cinfo.max_v_samp_factor > 1 ||
1475 dec->cinfo.max_h_samp_factor > 1)
1476 goto invalid_yuvrgbgrayscale;
1479 if (dec->cinfo.num_components != 3 ||
1480 r_v > 2 || r_v < dec->cinfo.comp_info[0].v_samp_factor ||
1481 r_v < dec->cinfo.comp_info[1].v_samp_factor ||
1482 r_h < dec->cinfo.comp_info[0].h_samp_factor ||
1483 r_h < dec->cinfo.comp_info[1].h_samp_factor)
1484 goto invalid_yuvrgbgrayscale;
1487 g_assert_not_reached ();
1491 width = dec->cinfo.output_width;
1492 height = dec->cinfo.output_height;
1494 if (G_UNLIKELY (width < MIN_WIDTH || width > MAX_WIDTH ||
1495 height < MIN_HEIGHT || height > MAX_HEIGHT))
1498 gst_jpeg_dec_negotiate (dec, width, height, dec->cinfo.jpeg_color_space);
1500 ret = gst_buffer_pool_acquire_buffer (dec->pool, &outbuf, NULL);
1501 if (G_UNLIKELY (ret != GST_FLOW_OK))
1504 if (!gst_video_frame_map (&frame, &dec->info, outbuf, GST_MAP_READWRITE))
1507 GST_LOG_OBJECT (dec, "width %d, height %d", width, height);
1509 GST_BUFFER_TIMESTAMP (outbuf) = dec->next_ts;
1511 if (dec->packetized && GST_CLOCK_TIME_IS_VALID (dec->next_ts)) {
1512 if (GST_CLOCK_TIME_IS_VALID (duration)) {
1513 /* use duration from incoming buffer for outgoing buffer */
1514 dec->next_ts += duration;
1515 } else if (GST_CLOCK_TIME_IS_VALID (dec->duration)) {
1516 duration = dec->duration;
1517 dec->next_ts += dec->duration;
1519 duration = GST_CLOCK_TIME_NONE;
1520 dec->next_ts = GST_CLOCK_TIME_NONE;
1523 duration = GST_CLOCK_TIME_NONE;
1524 dec->next_ts = GST_CLOCK_TIME_NONE;
1526 GST_BUFFER_DURATION (outbuf) = duration;
1528 if (dec->cinfo.jpeg_color_space == JCS_RGB) {
1529 gst_jpeg_dec_decode_rgb (dec, &frame);
1530 } else if (dec->cinfo.jpeg_color_space == JCS_GRAYSCALE) {
1531 gst_jpeg_dec_decode_grayscale (dec, &frame);
1533 GST_LOG_OBJECT (dec, "decompressing (reqired scanline buffer height = %u)",
1534 dec->cinfo.rec_outbuf_height);
1536 /* For some widths jpeglib requires more horizontal padding than I420
1537 * provides. In those cases we need to decode into separate buffers and then
1538 * copy over the data into our final picture buffer, otherwise jpeglib might
1539 * write over the end of a line into the beginning of the next line,
1540 * resulting in blocky artifacts on the left side of the picture. */
1541 if (G_UNLIKELY (width % (dec->cinfo.max_h_samp_factor * DCTSIZE) != 0
1542 || dec->cinfo.comp_info[0].h_samp_factor != 2
1543 || dec->cinfo.comp_info[1].h_samp_factor != 1
1544 || dec->cinfo.comp_info[2].h_samp_factor != 1)) {
1545 GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, dec,
1546 "indirect decoding using extra buffer copy");
1547 gst_jpeg_dec_decode_indirect (dec, &frame, r_v, r_h,
1548 dec->cinfo.num_components);
1550 ret = gst_jpeg_dec_decode_direct (dec, &frame);
1551 if (G_UNLIKELY (ret != GST_FLOW_OK))
1552 goto decode_direct_failed;
1556 GST_LOG_OBJECT (dec, "decompressing finished");
1557 jpeg_finish_decompress (&dec->cinfo);
1559 gst_video_frame_unmap (&frame);
1562 if (dec->segment.format == GST_FORMAT_TIME) {
1563 guint64 start, stop, clip_start, clip_stop;
1565 GST_LOG_OBJECT (dec, "Attempting clipping");
1567 start = GST_BUFFER_TIMESTAMP (outbuf);
1568 if (GST_BUFFER_DURATION (outbuf) == GST_CLOCK_TIME_NONE)
1571 stop = start + GST_BUFFER_DURATION (outbuf);
1573 if (gst_segment_clip (&dec->segment, GST_FORMAT_TIME,
1574 start, stop, &clip_start, &clip_stop)) {
1575 GST_LOG_OBJECT (dec, "Clipping start to %" GST_TIME_FORMAT,
1576 GST_TIME_ARGS (clip_start));
1577 GST_BUFFER_TIMESTAMP (outbuf) = clip_start;
1578 if (GST_BUFFER_DURATION (outbuf) != GST_CLOCK_TIME_NONE) {
1579 GST_LOG_OBJECT (dec, "Clipping duration to %" GST_TIME_FORMAT,
1580 GST_TIME_ARGS (clip_stop - clip_start));
1581 GST_BUFFER_DURATION (outbuf) = clip_stop - clip_start;
1587 /* reset error count on successful decode */
1588 dec->error_count = 0;
1592 GST_LOG_OBJECT (dec, "pushing buffer (ts=%" GST_TIME_FORMAT ", dur=%"
1593 GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
1594 GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
1596 ret = gst_pad_push (dec->srcpad, outbuf);
1600 gst_adapter_flush (dec->adapter, dec->rem_img_len);
1604 if (G_UNLIKELY (ret == GST_FLOW_ERROR)) {
1605 jpeg_abort_decompress (&dec->cinfo);
1606 ret = gst_jpeg_dec_post_error_or_warning (dec);
1614 GST_LOG_OBJECT (dec, "we need more data");
1616 gst_buffer_unref (outbuf);
1625 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1626 "Picture is too small or too big (%ux%u)", width, height);
1627 ret = GST_FLOW_ERROR;
1632 gchar err_msg[JMSG_LENGTH_MAX];
1634 dec->jerr.pub.format_message ((j_common_ptr) (&dec->cinfo), err_msg);
1636 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1637 "Decode error #%u: %s", code, err_msg);
1640 gst_buffer_unref (outbuf);
1643 ret = GST_FLOW_ERROR;
1646 decode_direct_failed:
1648 /* already posted an error message */
1649 jpeg_abort_decompress (&dec->cinfo);
1650 gst_buffer_replace (&outbuf, NULL);
1655 const gchar *reason;
1657 reason = gst_flow_get_name (ret);
1659 GST_DEBUG_OBJECT (dec, "failed to alloc buffer, reason %s", reason);
1660 /* Reset for next time */
1661 jpeg_abort_decompress (&dec->cinfo);
1662 if (ret != GST_FLOW_EOS && ret != GST_FLOW_FLUSHING &&
1663 ret != GST_FLOW_NOT_LINKED) {
1664 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1665 "Buffer allocation failed, reason: %s", reason);
1671 jpeg_abort_decompress (&dec->cinfo);
1672 gst_buffer_unref (outbuf);
1678 GST_WARNING_OBJECT (dec, "Outgoing buffer is outside configured segment");
1679 gst_buffer_unref (outbuf);
1683 components_not_supported:
1685 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1686 "number of components not supported: %d (max 3)",
1687 dec->cinfo.num_components);
1688 ret = GST_FLOW_ERROR;
1691 unsupported_colorspace:
1693 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1694 "Picture has unknown or unsupported colourspace");
1695 ret = GST_FLOW_ERROR;
1698 invalid_yuvrgbgrayscale:
1700 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1701 "Picture is corrupt or unhandled YUV/RGB/grayscale layout");
1702 ret = GST_FLOW_ERROR;
1708 gst_jpeg_dec_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
1713 dec = GST_JPEG_DEC (parent);
1715 switch (GST_EVENT_TYPE (event)) {
1716 case GST_EVENT_QOS:{
1718 GstClockTimeDiff diff;
1719 GstClockTime timestamp;
1722 gst_event_parse_qos (event, &type, &proportion, &diff, ×tamp);
1723 gst_jpeg_dec_update_qos (dec, proportion, diff, timestamp);
1730 res = gst_pad_push_event (dec->sinkpad, event);
1736 gst_jpeg_dec_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
1738 gboolean ret = TRUE, forward = TRUE;
1739 GstJpegDec *dec = GST_JPEG_DEC (parent);
1741 GST_DEBUG_OBJECT (dec, "event : %s", GST_EVENT_TYPE_NAME (event));
1743 switch (GST_EVENT_TYPE (event)) {
1744 case GST_EVENT_FLUSH_STOP:
1745 GST_DEBUG_OBJECT (dec, "Aborting decompress");
1746 jpeg_abort_decompress (&dec->cinfo);
1747 gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED);
1748 gst_adapter_clear (dec->adapter);
1749 g_free (dec->cur_buf);
1750 dec->cur_buf = NULL;
1751 dec->parse_offset = 0;
1752 dec->parse_entropy_len = 0;
1753 dec->parse_resync = FALSE;
1754 gst_jpeg_dec_reset_qos (dec);
1756 case GST_EVENT_SEGMENT:
1757 gst_event_copy_segment (event, &dec->segment);
1758 GST_DEBUG_OBJECT (dec, "Got NEWSEGMENT %" GST_SEGMENT_FORMAT,
1761 case GST_EVENT_CAPS:
1765 gst_event_parse_caps (event, &caps);
1766 ret = gst_jpeg_dec_setcaps (dec, caps);
1775 ret = gst_pad_push_event (dec->srcpad, event);
1777 gst_event_unref (event);
1783 gst_jpeg_dec_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
1785 gboolean res = FALSE;
1787 switch (GST_QUERY_TYPE (query)) {
1788 case GST_QUERY_CAPS:
1790 GstCaps *filter, *caps;
1792 gst_query_parse_caps (query, &filter);
1793 caps = gst_jpeg_dec_getcaps (pad, filter);
1794 gst_query_set_caps_result (query, caps);
1795 gst_caps_unref (caps);
1800 res = gst_pad_query_default (pad, parent, query);
1807 gst_jpeg_dec_set_property (GObject * object, guint prop_id,
1808 const GValue * value, GParamSpec * pspec)
1812 dec = GST_JPEG_DEC (object);
1815 case PROP_IDCT_METHOD:
1816 dec->idct_method = g_value_get_enum (value);
1818 case PROP_MAX_ERRORS:
1819 g_atomic_int_set (&dec->max_errors, g_value_get_int (value));
1823 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1829 gst_jpeg_dec_get_property (GObject * object, guint prop_id, GValue * value,
1834 dec = GST_JPEG_DEC (object);
1837 case PROP_IDCT_METHOD:
1838 g_value_set_enum (value, dec->idct_method);
1840 case PROP_MAX_ERRORS:
1841 g_value_set_int (value, g_atomic_int_get (&dec->max_errors));
1845 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1850 static GstStateChangeReturn
1851 gst_jpeg_dec_change_state (GstElement * element, GstStateChange transition)
1853 GstStateChangeReturn ret;
1856 dec = GST_JPEG_DEC (element);
1858 switch (transition) {
1859 case GST_STATE_CHANGE_READY_TO_PAUSED:
1860 dec->error_count = 0;
1861 dec->good_count = 0;
1864 gst_video_info_init (&dec->info);
1866 dec->packetized = FALSE;
1868 dec->discont = TRUE;
1869 dec->parse_offset = 0;
1870 dec->parse_entropy_len = 0;
1871 dec->parse_resync = FALSE;
1872 dec->cur_buf = NULL;
1873 gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED);
1874 gst_jpeg_dec_reset_qos (dec);
1879 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1880 if (ret != GST_STATE_CHANGE_SUCCESS)
1883 switch (transition) {
1884 case GST_STATE_CHANGE_PAUSED_TO_READY:
1885 gst_adapter_clear (dec->adapter);
1886 g_free (dec->cur_buf);
1887 dec->cur_buf = NULL;
1888 gst_jpeg_dec_free_buffers (dec);
1890 gst_buffer_pool_set_active (dec->pool, FALSE);
1891 gst_object_unref (dec->pool);