2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3 * Copyright (C) <2009> Tim-Philipp Müller <tim centricular net>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 * SECTION:element-jpegdec
24 * Decodes jpeg images.
27 * <title>Example launch line</title>
29 * gst-launch -v v4l2src ! jpegdec ! ffmpegcolorspace ! xvimagesink
30 * ]| The above pipeline reads a motion JPEG stream from a v4l2 camera
31 * and renders it to the screen.
40 #include "gstjpegdec.h"
42 #include <gst/video/video.h>
43 #include "gst/gst-i18n-plugin.h"
47 #define MAX_WIDTH 65535
49 #define MAX_HEIGHT 65535
51 #define CINFO_GET_JPEGDEC(cinfo_ptr) \
52 (((struct GstJpegDecSourceMgr*)((cinfo_ptr)->src))->dec)
54 #define JPEG_DEFAULT_IDCT_METHOD JDCT_FASTEST
55 #define JPEG_DEFAULT_MAX_ERRORS 0
65 static GstStaticPadTemplate gst_jpeg_dec_src_pad_template =
66 GST_STATIC_PAD_TEMPLATE ("src",
69 GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
70 ("{ I420, RGB, BGR, RGBx, xRGB, BGRx, xBGR, GRAY8 }"))
75 /* FIXME: sof-marker is for IJG libjpeg 8, should be different for 6.2 */
76 static GstStaticPadTemplate gst_jpeg_dec_sink_pad_template =
77 GST_STATIC_PAD_TEMPLATE ("sink",
80 GST_STATIC_CAPS ("image/jpeg, "
81 "width = (int) [ " G_STRINGIFY (MIN_WIDTH) ", " G_STRINGIFY (MAX_WIDTH)
82 " ], " "height = (int) [ " G_STRINGIFY (MIN_HEIGHT) ", "
83 G_STRINGIFY (MAX_HEIGHT) " ], framerate = (fraction) [ 0/1, MAX ], "
84 "sof-marker = (int) { 0, 1, 2, 5, 6, 7, 9, 10, 13, 14 }")
87 GST_DEBUG_CATEGORY_STATIC (jpeg_dec_debug);
88 #define GST_CAT_DEFAULT jpeg_dec_debug
89 GST_DEBUG_CATEGORY_STATIC (GST_CAT_PERFORMANCE);
91 static void gst_jpeg_dec_set_property (GObject * object, guint prop_id,
92 const GValue * value, GParamSpec * pspec);
93 static void gst_jpeg_dec_get_property (GObject * object, guint prop_id,
94 GValue * value, GParamSpec * pspec);
96 static GstFlowReturn gst_jpeg_dec_chain (GstPad * pad, GstObject * parent,
98 static GstCaps *gst_jpeg_dec_getcaps (GstPad * pad, GstCaps * filter);
99 static gboolean gst_jpeg_dec_sink_query (GstPad * pad, GstObject * parent,
101 static gboolean gst_jpeg_dec_sink_event (GstPad * pad, GstObject * parent,
103 static gboolean gst_jpeg_dec_src_event (GstPad * pad, GstObject * parent,
105 static GstStateChangeReturn gst_jpeg_dec_change_state (GstElement * element,
106 GstStateChange transition);
107 static void gst_jpeg_dec_update_qos (GstJpegDec * dec, gdouble proportion,
108 GstClockTimeDiff diff, GstClockTime ts);
109 static void gst_jpeg_dec_reset_qos (GstJpegDec * dec);
110 static void gst_jpeg_dec_read_qos (GstJpegDec * dec, gdouble * proportion,
111 GstClockTime * time);
113 #define gst_jpeg_dec_parent_class parent_class
114 G_DEFINE_TYPE (GstJpegDec, gst_jpeg_dec, GST_TYPE_ELEMENT);
117 gst_jpeg_dec_finalize (GObject * object)
119 GstJpegDec *dec = GST_JPEG_DEC (object);
121 jpeg_destroy_decompress (&dec->cinfo);
123 g_object_unref (dec->adapter);
125 G_OBJECT_CLASS (parent_class)->finalize (object);
129 gst_jpeg_dec_class_init (GstJpegDecClass * klass)
131 GstElementClass *gstelement_class;
132 GObjectClass *gobject_class;
134 gstelement_class = (GstElementClass *) klass;
135 gobject_class = (GObjectClass *) klass;
137 parent_class = g_type_class_peek_parent (klass);
139 gobject_class->finalize = gst_jpeg_dec_finalize;
140 gobject_class->set_property = gst_jpeg_dec_set_property;
141 gobject_class->get_property = gst_jpeg_dec_get_property;
143 g_object_class_install_property (gobject_class, PROP_IDCT_METHOD,
144 g_param_spec_enum ("idct-method", "IDCT Method",
145 "The IDCT algorithm to use", GST_TYPE_IDCT_METHOD,
146 JPEG_DEFAULT_IDCT_METHOD,
147 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
150 * GstJpegDec:max-errors
152 * Error out after receiving N consecutive decoding errors
153 * (-1 = never error out, 0 = automatic, 1 = fail on first error, etc.)
157 g_object_class_install_property (gobject_class, PROP_MAX_ERRORS,
158 g_param_spec_int ("max-errors", "Maximum Consecutive Decoding Errors",
159 "Error out after receiving N consecutive decoding errors "
160 "(-1 = never fail, 0 = automatic, 1 = fail on first error)",
161 -1, G_MAXINT, JPEG_DEFAULT_MAX_ERRORS,
162 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
164 gst_element_class_add_pad_template (gstelement_class,
165 gst_static_pad_template_get (&gst_jpeg_dec_src_pad_template));
166 gst_element_class_add_pad_template (gstelement_class,
167 gst_static_pad_template_get (&gst_jpeg_dec_sink_pad_template));
168 gst_element_class_set_details_simple (gstelement_class, "JPEG image decoder",
169 "Codec/Decoder/Image",
170 "Decode images from JPEG format", "Wim Taymans <wim@fluendo.com>");
172 gstelement_class->change_state =
173 GST_DEBUG_FUNCPTR (gst_jpeg_dec_change_state);
175 GST_DEBUG_CATEGORY_INIT (jpeg_dec_debug, "jpegdec", 0, "JPEG decoder");
176 GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE");
180 gst_jpeg_dec_clear_error (GstJpegDec * dec)
182 g_free (dec->error_msg);
183 dec->error_msg = NULL;
185 dec->error_func = NULL;
189 gst_jpeg_dec_set_error_va (GstJpegDec * dec, const gchar * func, gint line,
190 const gchar * debug_msg_format, va_list args)
192 #ifndef GST_DISABLE_GST_DEBUG
193 gst_debug_log_valist (GST_CAT_DEFAULT, GST_LEVEL_WARNING, __FILE__, func,
194 line, (GObject *) dec, debug_msg_format, args);
197 g_free (dec->error_msg);
198 if (debug_msg_format)
199 dec->error_msg = g_strdup_vprintf (debug_msg_format, args);
201 dec->error_msg = NULL;
203 dec->error_line = line;
204 dec->error_func = func;
208 gst_jpeg_dec_set_error (GstJpegDec * dec, const gchar * func, gint line,
209 const gchar * debug_msg_format, ...)
213 va_start (va, debug_msg_format);
214 gst_jpeg_dec_set_error_va (dec, func, line, debug_msg_format, va);
219 gst_jpeg_dec_post_error_or_warning (GstJpegDec * dec)
225 max_errors = g_atomic_int_get (&dec->max_errors);
227 if (max_errors < 0) {
229 } else if (max_errors == 0) {
230 /* FIXME: do something more clever in "automatic mode" */
231 if (dec->packetized) {
232 ret = (dec->error_count < 3) ? GST_FLOW_OK : GST_FLOW_ERROR;
234 ret = GST_FLOW_ERROR;
237 ret = (dec->error_count < max_errors) ? GST_FLOW_OK : GST_FLOW_ERROR;
240 GST_INFO_OBJECT (dec, "decoding error %d/%d (%s)", dec->error_count,
241 max_errors, (ret == GST_FLOW_OK) ? "ignoring error" : "erroring out");
243 gst_element_message_full (GST_ELEMENT (dec),
244 (ret == GST_FLOW_OK) ? GST_MESSAGE_WARNING : GST_MESSAGE_ERROR,
245 GST_STREAM_ERROR, GST_STREAM_ERROR_DECODE,
246 g_strdup (_("Failed to decode JPEG image")), dec->error_msg,
247 __FILE__, dec->error_func, dec->error_line);
249 dec->error_msg = NULL;
250 gst_jpeg_dec_clear_error (dec);
255 gst_jpeg_dec_fill_input_buffer (j_decompress_ptr cinfo)
260 dec = CINFO_GET_JPEGDEC (cinfo);
261 g_return_val_if_fail (dec != NULL, FALSE);
263 av = gst_adapter_available_fast (dec->adapter);
264 GST_DEBUG_OBJECT (dec, "fill_input_buffer: fast av=%u, remaining=%u", av,
268 GST_DEBUG_OBJECT (dec, "Out of data");
272 if (dec->rem_img_len < av)
273 av = dec->rem_img_len;
274 dec->rem_img_len -= av;
276 g_free (dec->cur_buf);
277 dec->cur_buf = gst_adapter_take (dec->adapter, av);
279 cinfo->src->next_input_byte = dec->cur_buf;
280 cinfo->src->bytes_in_buffer = av;
286 gst_jpeg_dec_init_source (j_decompress_ptr cinfo)
288 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "init_source");
293 gst_jpeg_dec_skip_input_data (j_decompress_ptr cinfo, glong num_bytes)
295 GstJpegDec *dec = CINFO_GET_JPEGDEC (cinfo);
297 GST_DEBUG_OBJECT (dec, "skip %ld bytes", num_bytes);
299 if (num_bytes > 0 && cinfo->src->bytes_in_buffer >= num_bytes) {
300 cinfo->src->next_input_byte += (size_t) num_bytes;
301 cinfo->src->bytes_in_buffer -= (size_t) num_bytes;
302 } else if (num_bytes > 0) {
305 num_bytes -= cinfo->src->bytes_in_buffer;
306 cinfo->src->next_input_byte += (size_t) cinfo->src->bytes_in_buffer;
307 cinfo->src->bytes_in_buffer = 0;
309 available = gst_adapter_available (dec->adapter);
310 if (available < num_bytes || available < dec->rem_img_len) {
311 GST_WARNING_OBJECT (dec, "Less bytes to skip than available in the "
312 "adapter or the remaining image length %ld < %d or %u",
313 num_bytes, available, dec->rem_img_len);
315 num_bytes = MIN (MIN (num_bytes, available), dec->rem_img_len);
316 gst_adapter_flush (dec->adapter, num_bytes);
317 dec->rem_img_len -= num_bytes;
322 gst_jpeg_dec_resync_to_restart (j_decompress_ptr cinfo, gint desired)
324 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "resync_to_start");
329 gst_jpeg_dec_term_source (j_decompress_ptr cinfo)
331 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "term_source");
336 gst_jpeg_dec_my_output_message (j_common_ptr cinfo)
338 return; /* do nothing */
342 gst_jpeg_dec_my_emit_message (j_common_ptr cinfo, int msg_level)
344 /* GST_LOG_OBJECT (CINFO_GET_JPEGDEC (&cinfo), "msg_level=%d", msg_level); */
349 gst_jpeg_dec_my_error_exit (j_common_ptr cinfo)
351 struct GstJpegDecErrorMgr *err_mgr = (struct GstJpegDecErrorMgr *) cinfo->err;
353 (*cinfo->err->output_message) (cinfo);
354 longjmp (err_mgr->setjmp_buffer, 1);
358 gst_jpeg_dec_init (GstJpegDec * dec)
360 GST_DEBUG ("initializing");
362 /* create the sink and src pads */
364 gst_pad_new_from_static_template (&gst_jpeg_dec_sink_pad_template,
366 gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
367 gst_pad_set_chain_function (dec->sinkpad,
368 GST_DEBUG_FUNCPTR (gst_jpeg_dec_chain));
369 gst_pad_set_event_function (dec->sinkpad,
370 GST_DEBUG_FUNCPTR (gst_jpeg_dec_sink_event));
371 gst_pad_set_query_function (dec->sinkpad,
372 GST_DEBUG_FUNCPTR (gst_jpeg_dec_sink_query));
375 gst_pad_new_from_static_template (&gst_jpeg_dec_src_pad_template, "src");
376 gst_pad_set_event_function (dec->srcpad,
377 GST_DEBUG_FUNCPTR (gst_jpeg_dec_src_event));
378 gst_pad_use_fixed_caps (dec->srcpad);
379 gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
382 memset (&dec->cinfo, 0, sizeof (dec->cinfo));
383 memset (&dec->jerr, 0, sizeof (dec->jerr));
384 dec->cinfo.err = jpeg_std_error (&dec->jerr.pub);
385 dec->jerr.pub.output_message = gst_jpeg_dec_my_output_message;
386 dec->jerr.pub.emit_message = gst_jpeg_dec_my_emit_message;
387 dec->jerr.pub.error_exit = gst_jpeg_dec_my_error_exit;
389 jpeg_create_decompress (&dec->cinfo);
391 dec->cinfo.src = (struct jpeg_source_mgr *) &dec->jsrc;
392 dec->cinfo.src->init_source = gst_jpeg_dec_init_source;
393 dec->cinfo.src->fill_input_buffer = gst_jpeg_dec_fill_input_buffer;
394 dec->cinfo.src->skip_input_data = gst_jpeg_dec_skip_input_data;
395 dec->cinfo.src->resync_to_restart = gst_jpeg_dec_resync_to_restart;
396 dec->cinfo.src->term_source = gst_jpeg_dec_term_source;
399 /* init properties */
400 dec->idct_method = JPEG_DEFAULT_IDCT_METHOD;
401 dec->max_errors = JPEG_DEFAULT_MAX_ERRORS;
403 dec->adapter = gst_adapter_new ();
407 gst_jpeg_dec_ensure_header (GstJpegDec * dec)
412 av = gst_adapter_available (dec->adapter);
413 /* we expect at least 4 bytes, first of which start marker */
414 offset = gst_adapter_masked_scan_uint32 (dec->adapter, 0xffffff00, 0xffd8ff00,
416 if (G_UNLIKELY (offset < 0)) {
417 GST_DEBUG_OBJECT (dec, "No JPEG header in current buffer");
420 gst_adapter_flush (dec->adapter, av - 4);
425 GST_LOG_OBJECT (dec, "Skipping %u bytes.", offset);
426 gst_adapter_flush (dec->adapter, offset);
428 GST_DEBUG_OBJECT (dec, "Found JPEG header");
433 static inline gboolean
434 gst_jpeg_dec_parse_tag_has_entropy_segment (guint8 tag)
436 if (tag == 0xda || (tag >= 0xd0 && tag <= 0xd7))
441 /* returns image length in bytes if parsed successfully,
442 * otherwise 0 if more data needed,
443 * if < 0 the absolute value needs to be flushed */
445 gst_jpeg_dec_parse_image_data (GstJpegDec * dec)
449 GstAdapter *adapter = dec->adapter;
450 gint offset, noffset;
452 size = gst_adapter_available (adapter);
454 /* we expect at least 4 bytes, first of which start marker */
455 if (gst_adapter_masked_scan_uint32 (adapter, 0xffff0000, 0xffd80000, 0, 4))
458 GST_DEBUG ("Parsing jpeg image data (%u bytes)", size);
460 GST_DEBUG ("Parse state: offset=%d, resync=%d, entropy len=%d",
461 dec->parse_offset, dec->parse_resync, dec->parse_entropy_len);
463 /* offset is 2 less than actual offset;
464 * - adapter needs at least 4 bytes for scanning,
465 * - start and end marker ensure at least that much
467 /* resume from state offset */
468 offset = dec->parse_offset;
475 gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00, 0x0000ff00,
476 offset, size - offset, &value);
477 /* lost sync if 0xff marker not where expected */
478 if ((resync = (noffset != offset))) {
479 GST_DEBUG ("Lost sync at 0x%08x, resyncing", offset + 2);
481 /* may have marker, but could have been resyncng */
482 resync = resync || dec->parse_resync;
483 /* Skip over extra 0xff */
484 while ((noffset >= 0) && ((value & 0xff) == 0xff)) {
487 gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00, 0x0000ff00,
488 noffset, size - noffset, &value);
490 /* enough bytes left for marker? (we need 0xNN after the 0xff) */
492 GST_DEBUG ("at end of input and no EOI marker found, need more data");
496 /* now lock on the marker we found */
498 value = value & 0xff;
500 GST_DEBUG ("0x%08x: EOI marker", offset + 2);
501 /* clear parse state */
502 dec->parse_resync = FALSE;
503 dec->parse_offset = 0;
505 } else if (value == 0xd8) {
506 /* Skip this frame if we found another SOI marker */
507 GST_DEBUG ("0x%08x: SOI marker before EOI, skipping", offset + 2);
508 dec->parse_resync = FALSE;
509 dec->parse_offset = 0;
510 return -(offset + 2);
514 if (value >= 0xd0 && value <= 0xd7)
517 /* peek tag and subsequent length */
518 if (offset + 2 + 4 > size)
521 gst_adapter_masked_scan_uint32_peek (adapter, 0x0, 0x0, offset + 2, 4,
523 frame_len = frame_len & 0xffff;
525 GST_DEBUG ("0x%08x: tag %02x, frame_len=%u", offset + 2, value, frame_len);
526 /* the frame length includes the 2 bytes for the length; here we want at
527 * least 2 more bytes at the end for an end marker */
528 if (offset + 2 + 2 + frame_len + 2 > size) {
532 if (gst_jpeg_dec_parse_tag_has_entropy_segment (value)) {
533 guint eseglen = dec->parse_entropy_len;
535 GST_DEBUG ("0x%08x: finding entropy segment length", offset + 2);
536 noffset = offset + 2 + frame_len + dec->parse_entropy_len;
538 noffset = gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00,
539 0x0000ff00, noffset, size - noffset, &value);
542 dec->parse_entropy_len = size - offset - 4 - frame_len - 2;
545 if ((value & 0xff) != 0x00) {
546 eseglen = noffset - offset - frame_len - 2;
551 dec->parse_entropy_len = 0;
552 frame_len += eseglen;
553 GST_DEBUG ("entropy segment length=%u => frame_len=%u", eseglen,
557 /* check if we will still be in sync if we interpret
558 * this as a sync point and skip this frame */
559 noffset = offset + frame_len + 2;
560 noffset = gst_adapter_masked_scan_uint32 (adapter, 0x0000ff00, 0x0000ff00,
563 /* ignore and continue resyncing until we hit the end
564 * of our data or find a sync point that looks okay */
568 GST_DEBUG ("found sync at 0x%x", offset + 2);
571 offset += frame_len + 2;
577 dec->parse_offset = offset;
578 dec->parse_resync = resync;
583 /* shamelessly ripped from jpegutils.c in mjpegtools */
585 add_huff_table (j_decompress_ptr dinfo,
586 JHUFF_TBL ** htblptr, const UINT8 * bits, const UINT8 * val)
587 /* Define a Huffman table */
591 if (*htblptr == NULL)
592 *htblptr = jpeg_alloc_huff_table ((j_common_ptr) dinfo);
596 /* Copy the number-of-symbols-of-each-code-length counts */
597 memcpy ((*htblptr)->bits, bits, sizeof ((*htblptr)->bits));
599 /* Validate the counts. We do this here mainly so we can copy the right
600 * number of symbols from the val[] array, without risking marching off
601 * the end of memory. jchuff.c will do a more thorough test later.
604 for (len = 1; len <= 16; len++)
605 nsymbols += bits[len];
606 if (nsymbols < 1 || nsymbols > 256)
607 g_error ("jpegutils.c: add_huff_table failed badly. ");
609 memcpy ((*htblptr)->huffval, val, nsymbols * sizeof (UINT8));
615 std_huff_tables (j_decompress_ptr dinfo)
616 /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
617 /* IMPORTANT: these are only valid for 8-bit data precision! */
619 static const UINT8 bits_dc_luminance[17] =
620 { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
621 static const UINT8 val_dc_luminance[] =
622 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
624 static const UINT8 bits_dc_chrominance[17] =
625 { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
626 static const UINT8 val_dc_chrominance[] =
627 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
629 static const UINT8 bits_ac_luminance[17] =
630 { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
631 static const UINT8 val_ac_luminance[] =
632 { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
633 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
634 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
635 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
636 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
637 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
638 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
639 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
640 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
641 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
642 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
643 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
644 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
645 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
646 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
647 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
648 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
649 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
650 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
651 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
655 static const UINT8 bits_ac_chrominance[17] =
656 { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
657 static const UINT8 val_ac_chrominance[] =
658 { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
659 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
660 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
661 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
662 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
663 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
664 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
665 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
666 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
667 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
668 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
669 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
670 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
671 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
672 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
673 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
674 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
675 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
676 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
677 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
681 add_huff_table (dinfo, &dinfo->dc_huff_tbl_ptrs[0],
682 bits_dc_luminance, val_dc_luminance);
683 add_huff_table (dinfo, &dinfo->ac_huff_tbl_ptrs[0],
684 bits_ac_luminance, val_ac_luminance);
685 add_huff_table (dinfo, &dinfo->dc_huff_tbl_ptrs[1],
686 bits_dc_chrominance, val_dc_chrominance);
687 add_huff_table (dinfo, &dinfo->ac_huff_tbl_ptrs[1],
688 bits_ac_chrominance, val_ac_chrominance);
694 guarantee_huff_tables (j_decompress_ptr dinfo)
696 if ((dinfo->dc_huff_tbl_ptrs[0] == NULL) &&
697 (dinfo->dc_huff_tbl_ptrs[1] == NULL) &&
698 (dinfo->ac_huff_tbl_ptrs[0] == NULL) &&
699 (dinfo->ac_huff_tbl_ptrs[1] == NULL)) {
700 GST_DEBUG ("Generating standard Huffman tables for this frame.");
701 std_huff_tables (dinfo);
706 gst_jpeg_dec_setcaps (GstJpegDec * dec, GstCaps * caps)
709 const GValue *framerate;
711 s = gst_caps_get_structure (caps, 0);
713 if ((framerate = gst_structure_get_value (s, "framerate")) != NULL) {
714 dec->in_fps_n = gst_value_get_fraction_numerator (framerate);
715 dec->in_fps_d = gst_value_get_fraction_denominator (framerate);
716 dec->packetized = TRUE;
717 GST_DEBUG ("got framerate of %d/%d fps => packetized mode",
718 dec->in_fps_n, dec->in_fps_d);
721 /* do not extract width/height here. we do that in the chain
722 * function on a per-frame basis (including the line[] array
725 /* But we can take the framerate values and set them on the src pad */
731 gst_jpeg_dec_getcaps (GstPad * pad, GstCaps * filter)
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 = NULL;
1167 guint size, min, max, prefix, padding, alignment;
1168 GstStructure *config;
1170 GST_DEBUG_OBJECT (dec, "setting up bufferpool");
1172 /* find a pool for the negotiated caps now */
1173 query = gst_query_new_allocation (caps, TRUE);
1175 if (gst_pad_peer_query (dec->srcpad, query)) {
1176 /* we got configuration from our peer, parse them */
1177 gst_query_parse_allocation_params (query, &size, &min, &max, &prefix,
1178 &padding, &alignment, &pool);
1179 size = MAX (size, dec->info.size);
1181 GST_DEBUG_OBJECT (dec, "peer query failed, using defaults");
1182 size = dec->info.size;
1188 gst_query_unref (query);
1191 /* we did not get a pool, make one ourselves then */
1192 pool = gst_buffer_pool_new ();
1195 config = gst_buffer_pool_get_config (pool);
1196 gst_buffer_pool_config_set (config, caps, size, min, max, prefix,
1197 padding, alignment | 15);
1199 gst_buffer_pool_set_config (pool, config);
1202 gst_buffer_pool_set_active (dec->pool, FALSE);
1203 gst_object_unref (dec->pool);
1208 gst_buffer_pool_set_active (pool, TRUE);
1214 gst_jpeg_dec_negotiate (GstJpegDec * dec, gint width, gint height, gint clrspc)
1217 GstVideoFormat format;
1220 if (G_UNLIKELY (width == dec->info.width && height == dec->info.height &&
1221 dec->in_fps_n == dec->info.fps_n && dec->in_fps_d == dec->info.fps_d
1222 && clrspc == dec->clrspc))
1225 gst_video_info_init (&info);
1227 /* framerate == 0/1 is a still frame */
1228 if (dec->in_fps_d == 0) {
1232 info.fps_n = dec->in_fps_n;
1233 info.fps_d = dec->in_fps_d;
1236 /* calculate or assume an average frame duration for QoS purposes */
1237 GST_OBJECT_LOCK (dec);
1238 if (info.fps_n != 0) {
1240 gst_util_uint64_scale (GST_SECOND, info.fps_d, info.fps_n);
1241 dec->duration = dec->qos_duration;
1243 /* if not set just use 25fps */
1244 dec->qos_duration = gst_util_uint64_scale (GST_SECOND, 1, 25);
1245 dec->duration = GST_CLOCK_TIME_NONE;
1247 GST_OBJECT_UNLOCK (dec);
1249 if (dec->cinfo.jpeg_color_space == JCS_RGB) {
1251 GstCaps *allowed_caps;
1252 GstVideoInfo tmpinfo;
1254 GST_DEBUG_OBJECT (dec, "selecting RGB format");
1255 /* retrieve allowed caps, and find the first one that reasonably maps
1256 * to the parameters of the colourspace */
1257 caps = gst_pad_get_allowed_caps (dec->srcpad);
1259 GST_DEBUG_OBJECT (dec, "... but no peer, using template caps");
1260 /* need to copy because get_allowed_caps returns a ref,
1261 * and get_pad_template_caps doesn't */
1262 caps = gst_pad_get_pad_template_caps (dec->srcpad);
1264 /* avoid lists of formats, etc */
1265 allowed_caps = gst_caps_normalize (caps);
1267 GST_LOG_OBJECT (dec, "allowed source caps %" GST_PTR_FORMAT, allowed_caps);
1269 for (i = 0; i < gst_caps_get_size (allowed_caps); i++) {
1271 gst_caps_unref (caps);
1272 caps = gst_caps_copy_nth (allowed_caps, i);
1273 /* sigh, ds and _parse_caps need fixed caps for parsing, fixate */
1274 caps = gst_caps_fixate (caps);
1275 GST_LOG_OBJECT (dec, "checking caps %" GST_PTR_FORMAT, caps);
1277 if (!gst_video_info_from_caps (&tmpinfo, caps))
1279 /* we'll settle for the first (preferred) downstream rgb format */
1280 if (GST_VIDEO_INFO_IS_RGB (&tmpinfo))
1282 /* default fall-back */
1283 format = GST_VIDEO_FORMAT_RGB;
1286 gst_caps_unref (caps);
1287 gst_caps_unref (allowed_caps);
1288 } else if (dec->cinfo.jpeg_color_space == JCS_GRAYSCALE) {
1289 /* TODO is anything else then 8bit supported in jpeg? */
1290 format = GST_VIDEO_FORMAT_GRAY8;
1292 /* go for plain and simple I420 */
1293 /* TODO other YUV cases ? */
1294 format = GST_VIDEO_FORMAT_I420;
1297 gst_video_info_set_format (&info, format, width, height);
1298 caps = gst_video_info_to_caps (&info);
1300 GST_DEBUG_OBJECT (dec, "setting caps %" GST_PTR_FORMAT, caps);
1301 GST_DEBUG_OBJECT (dec, "max_v_samp_factor=%d", dec->cinfo.max_v_samp_factor);
1302 GST_DEBUG_OBJECT (dec, "max_h_samp_factor=%d", dec->cinfo.max_h_samp_factor);
1304 gst_pad_set_caps (dec->srcpad, caps);
1307 dec->clrspc = clrspc;
1309 gst_jpeg_dec_buffer_pool (dec, caps);
1310 gst_caps_unref (caps);
1315 static GstFlowReturn
1316 gst_jpeg_dec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
1318 GstFlowReturn ret = GST_FLOW_OK;
1320 GstBuffer *outbuf = NULL;
1325 GstClockTime timestamp, duration;
1326 GstVideoFrame frame;
1328 dec = GST_JPEG_DEC (parent);
1330 timestamp = GST_BUFFER_TIMESTAMP (buf);
1331 duration = GST_BUFFER_DURATION (buf);
1333 if (GST_CLOCK_TIME_IS_VALID (timestamp))
1334 dec->next_ts = timestamp;
1336 if (GST_BUFFER_IS_DISCONT (buf)) {
1337 GST_DEBUG_OBJECT (dec, "buffer has DISCONT flag set");
1338 dec->discont = TRUE;
1339 if (!dec->packetized && gst_adapter_available (dec->adapter)) {
1340 GST_WARNING_OBJECT (dec, "DISCONT buffer in non-packetized mode, bad");
1341 gst_adapter_clear (dec->adapter);
1345 gst_adapter_push (dec->adapter, buf);
1348 /* If we are non-packetized and know the total incoming size in bytes,
1349 * just wait until we have enough before doing any processing. */
1351 if (!dec->packetized && (dec->segment.format == GST_FORMAT_BYTES) &&
1352 (dec->segment.stop != -1) &&
1353 (gst_adapter_available (dec->adapter) < dec->segment.stop)) {
1354 /* We assume that non-packetized input in bytes is *one* single jpeg image */
1355 GST_DEBUG ("Non-packetized mode. Got %" G_GSIZE_FORMAT " bytes, "
1356 "need %" G_GINT64_FORMAT, gst_adapter_available (dec->adapter),
1358 goto need_more_data;
1362 if (!gst_jpeg_dec_ensure_header (dec))
1363 goto need_more_data;
1365 /* If we know that each input buffer contains data
1366 * for a whole jpeg image (e.g. MJPEG streams), just
1367 * do some sanity checking instead of parsing all of
1369 if (dec->packetized) {
1370 img_len = gst_adapter_available (dec->adapter);
1372 /* Parse jpeg image to handle jpeg input that
1373 * is not aligned to buffer boundaries */
1374 img_len = gst_jpeg_dec_parse_image_data (dec);
1377 goto need_more_data;
1378 } else if (img_len < 0) {
1379 gst_adapter_flush (dec->adapter, -img_len);
1384 dec->rem_img_len = img_len;
1386 GST_LOG_OBJECT (dec, "image size = %u", img_len);
1388 /* QoS: if we're too late anyway, skip decoding */
1389 if (dec->packetized && !gst_jpeg_dec_do_qos (dec, timestamp))
1392 #ifndef GST_DISABLE_GST_DEBUG
1396 gst_adapter_copy (dec->adapter, data, 0, 4);
1397 GST_LOG_OBJECT (dec, "reading header %02x %02x %02x %02x", data[0], data[1],
1402 gst_jpeg_dec_fill_input_buffer (&dec->cinfo);
1404 if (setjmp (dec->jerr.setjmp_buffer)) {
1405 code = dec->jerr.pub.msg_code;
1407 if (code == JERR_INPUT_EOF) {
1408 GST_DEBUG ("jpeg input EOF error, we probably need more data");
1409 goto need_more_data;
1415 hdr_ok = jpeg_read_header (&dec->cinfo, TRUE);
1416 if (G_UNLIKELY (hdr_ok != JPEG_HEADER_OK)) {
1417 GST_WARNING_OBJECT (dec, "reading the header failed, %d", hdr_ok);
1420 GST_LOG_OBJECT (dec, "num_components=%d", dec->cinfo.num_components);
1421 GST_LOG_OBJECT (dec, "jpeg_color_space=%d", dec->cinfo.jpeg_color_space);
1423 if (!dec->cinfo.num_components || !dec->cinfo.comp_info)
1424 goto components_not_supported;
1426 r_h = dec->cinfo.comp_info[0].h_samp_factor;
1427 r_v = dec->cinfo.comp_info[0].v_samp_factor;
1429 GST_LOG_OBJECT (dec, "r_h = %d, r_v = %d", r_h, r_v);
1431 if (dec->cinfo.num_components > 3)
1432 goto components_not_supported;
1434 /* verify color space expectation to avoid going *boom* or bogus output */
1435 if (dec->cinfo.jpeg_color_space != JCS_YCbCr &&
1436 dec->cinfo.jpeg_color_space != JCS_GRAYSCALE &&
1437 dec->cinfo.jpeg_color_space != JCS_RGB)
1438 goto unsupported_colorspace;
1440 #ifndef GST_DISABLE_GST_DEBUG
1444 for (i = 0; i < dec->cinfo.num_components; ++i) {
1445 GST_LOG_OBJECT (dec, "[%d] h_samp_factor=%d, v_samp_factor=%d, cid=%d",
1446 i, dec->cinfo.comp_info[i].h_samp_factor,
1447 dec->cinfo.comp_info[i].v_samp_factor,
1448 dec->cinfo.comp_info[i].component_id);
1453 /* prepare for raw output */
1454 dec->cinfo.do_fancy_upsampling = FALSE;
1455 dec->cinfo.do_block_smoothing = FALSE;
1456 dec->cinfo.out_color_space = dec->cinfo.jpeg_color_space;
1457 dec->cinfo.dct_method = dec->idct_method;
1458 dec->cinfo.raw_data_out = TRUE;
1460 GST_LOG_OBJECT (dec, "starting decompress");
1461 guarantee_huff_tables (&dec->cinfo);
1462 if (!jpeg_start_decompress (&dec->cinfo)) {
1463 GST_WARNING_OBJECT (dec, "failed to start decompression cycle");
1466 /* sanity checks to get safe and reasonable output */
1467 switch (dec->cinfo.jpeg_color_space) {
1469 if (dec->cinfo.num_components != 1)
1470 goto invalid_yuvrgbgrayscale;
1473 if (dec->cinfo.num_components != 3 || dec->cinfo.max_v_samp_factor > 1 ||
1474 dec->cinfo.max_h_samp_factor > 1)
1475 goto invalid_yuvrgbgrayscale;
1478 if (dec->cinfo.num_components != 3 ||
1479 r_v > 2 || r_v < dec->cinfo.comp_info[0].v_samp_factor ||
1480 r_v < dec->cinfo.comp_info[1].v_samp_factor ||
1481 r_h < dec->cinfo.comp_info[0].h_samp_factor ||
1482 r_h < dec->cinfo.comp_info[1].h_samp_factor)
1483 goto invalid_yuvrgbgrayscale;
1486 g_assert_not_reached ();
1490 width = dec->cinfo.output_width;
1491 height = dec->cinfo.output_height;
1493 if (G_UNLIKELY (width < MIN_WIDTH || width > MAX_WIDTH ||
1494 height < MIN_HEIGHT || height > MAX_HEIGHT))
1497 gst_jpeg_dec_negotiate (dec, width, height, dec->cinfo.jpeg_color_space);
1499 ret = gst_buffer_pool_acquire_buffer (dec->pool, &outbuf, NULL);
1500 if (G_UNLIKELY (ret != GST_FLOW_OK))
1503 if (!gst_video_frame_map (&frame, &dec->info, outbuf, GST_MAP_READWRITE))
1506 GST_LOG_OBJECT (dec, "width %d, height %d", width, height);
1508 GST_BUFFER_TIMESTAMP (outbuf) = dec->next_ts;
1510 if (dec->packetized && GST_CLOCK_TIME_IS_VALID (dec->next_ts)) {
1511 if (GST_CLOCK_TIME_IS_VALID (duration)) {
1512 /* use duration from incoming buffer for outgoing buffer */
1513 dec->next_ts += duration;
1514 } else if (GST_CLOCK_TIME_IS_VALID (dec->duration)) {
1515 duration = dec->duration;
1516 dec->next_ts += dec->duration;
1518 duration = GST_CLOCK_TIME_NONE;
1519 dec->next_ts = GST_CLOCK_TIME_NONE;
1522 duration = GST_CLOCK_TIME_NONE;
1523 dec->next_ts = GST_CLOCK_TIME_NONE;
1525 GST_BUFFER_DURATION (outbuf) = duration;
1527 if (dec->cinfo.jpeg_color_space == JCS_RGB) {
1528 gst_jpeg_dec_decode_rgb (dec, &frame);
1529 } else if (dec->cinfo.jpeg_color_space == JCS_GRAYSCALE) {
1530 gst_jpeg_dec_decode_grayscale (dec, &frame);
1532 GST_LOG_OBJECT (dec, "decompressing (reqired scanline buffer height = %u)",
1533 dec->cinfo.rec_outbuf_height);
1535 /* For some widths jpeglib requires more horizontal padding than I420
1536 * provides. In those cases we need to decode into separate buffers and then
1537 * copy over the data into our final picture buffer, otherwise jpeglib might
1538 * write over the end of a line into the beginning of the next line,
1539 * resulting in blocky artifacts on the left side of the picture. */
1540 if (G_UNLIKELY (width % (dec->cinfo.max_h_samp_factor * DCTSIZE) != 0
1541 || dec->cinfo.comp_info[0].h_samp_factor != 2
1542 || dec->cinfo.comp_info[1].h_samp_factor != 1
1543 || dec->cinfo.comp_info[2].h_samp_factor != 1)) {
1544 GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, dec,
1545 "indirect decoding using extra buffer copy");
1546 gst_jpeg_dec_decode_indirect (dec, &frame, r_v, r_h,
1547 dec->cinfo.num_components);
1549 ret = gst_jpeg_dec_decode_direct (dec, &frame);
1550 if (G_UNLIKELY (ret != GST_FLOW_OK))
1551 goto decode_direct_failed;
1555 GST_LOG_OBJECT (dec, "decompressing finished");
1556 jpeg_finish_decompress (&dec->cinfo);
1558 gst_video_frame_unmap (&frame);
1561 if (dec->segment.format == GST_FORMAT_TIME) {
1562 guint64 start, stop, clip_start, clip_stop;
1564 GST_LOG_OBJECT (dec, "Attempting clipping");
1566 start = GST_BUFFER_TIMESTAMP (outbuf);
1567 if (GST_BUFFER_DURATION (outbuf) == GST_CLOCK_TIME_NONE)
1570 stop = start + GST_BUFFER_DURATION (outbuf);
1572 if (gst_segment_clip (&dec->segment, GST_FORMAT_TIME,
1573 start, stop, &clip_start, &clip_stop)) {
1574 GST_LOG_OBJECT (dec, "Clipping start to %" GST_TIME_FORMAT,
1575 GST_TIME_ARGS (clip_start));
1576 GST_BUFFER_TIMESTAMP (outbuf) = clip_start;
1577 if (GST_BUFFER_DURATION (outbuf) != GST_CLOCK_TIME_NONE) {
1578 GST_LOG_OBJECT (dec, "Clipping duration to %" GST_TIME_FORMAT,
1579 GST_TIME_ARGS (clip_stop - clip_start));
1580 GST_BUFFER_DURATION (outbuf) = clip_stop - clip_start;
1586 /* reset error count on successful decode */
1587 dec->error_count = 0;
1591 GST_LOG_OBJECT (dec, "pushing buffer (ts=%" GST_TIME_FORMAT ", dur=%"
1592 GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
1593 GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
1595 ret = gst_pad_push (dec->srcpad, outbuf);
1599 gst_adapter_flush (dec->adapter, dec->rem_img_len);
1603 if (G_UNLIKELY (ret == GST_FLOW_ERROR)) {
1604 jpeg_abort_decompress (&dec->cinfo);
1605 ret = gst_jpeg_dec_post_error_or_warning (dec);
1613 GST_LOG_OBJECT (dec, "we need more data");
1615 gst_buffer_unref (outbuf);
1624 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1625 "Picture is too small or too big (%ux%u)", width, height);
1626 ret = GST_FLOW_ERROR;
1631 gchar err_msg[JMSG_LENGTH_MAX];
1633 dec->jerr.pub.format_message ((j_common_ptr) (&dec->cinfo), err_msg);
1635 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1636 "Decode error #%u: %s", code, err_msg);
1639 gst_buffer_unref (outbuf);
1642 ret = GST_FLOW_ERROR;
1645 decode_direct_failed:
1647 /* already posted an error message */
1648 jpeg_abort_decompress (&dec->cinfo);
1649 gst_buffer_replace (&outbuf, NULL);
1654 const gchar *reason;
1656 reason = gst_flow_get_name (ret);
1658 GST_DEBUG_OBJECT (dec, "failed to alloc buffer, reason %s", reason);
1659 /* Reset for next time */
1660 jpeg_abort_decompress (&dec->cinfo);
1661 if (ret != GST_FLOW_EOS && ret != GST_FLOW_FLUSHING &&
1662 ret != GST_FLOW_NOT_LINKED) {
1663 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1664 "Buffer allocation failed, reason: %s", reason);
1670 jpeg_abort_decompress (&dec->cinfo);
1671 gst_buffer_unref (outbuf);
1677 GST_WARNING_OBJECT (dec, "Outgoing buffer is outside configured segment");
1678 gst_buffer_unref (outbuf);
1682 components_not_supported:
1684 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1685 "number of components not supported: %d (max 3)",
1686 dec->cinfo.num_components);
1687 ret = GST_FLOW_ERROR;
1690 unsupported_colorspace:
1692 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1693 "Picture has unknown or unsupported colourspace");
1694 ret = GST_FLOW_ERROR;
1697 invalid_yuvrgbgrayscale:
1699 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1700 "Picture is corrupt or unhandled YUV/RGB/grayscale layout");
1701 ret = GST_FLOW_ERROR;
1707 gst_jpeg_dec_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
1712 dec = GST_JPEG_DEC (parent);
1714 switch (GST_EVENT_TYPE (event)) {
1715 case GST_EVENT_QOS:{
1717 GstClockTimeDiff diff;
1718 GstClockTime timestamp;
1721 gst_event_parse_qos (event, &type, &proportion, &diff, ×tamp);
1722 gst_jpeg_dec_update_qos (dec, proportion, diff, timestamp);
1729 res = gst_pad_push_event (dec->sinkpad, event);
1735 gst_jpeg_dec_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
1737 gboolean ret = TRUE, forward = TRUE;
1738 GstJpegDec *dec = GST_JPEG_DEC (parent);
1740 GST_DEBUG_OBJECT (dec, "event : %s", GST_EVENT_TYPE_NAME (event));
1742 switch (GST_EVENT_TYPE (event)) {
1743 case GST_EVENT_FLUSH_STOP:
1744 GST_DEBUG_OBJECT (dec, "Aborting decompress");
1745 jpeg_abort_decompress (&dec->cinfo);
1746 gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED);
1747 gst_adapter_clear (dec->adapter);
1748 g_free (dec->cur_buf);
1749 dec->cur_buf = NULL;
1750 dec->parse_offset = 0;
1751 dec->parse_entropy_len = 0;
1752 dec->parse_resync = FALSE;
1753 gst_jpeg_dec_reset_qos (dec);
1755 case GST_EVENT_SEGMENT:
1756 gst_event_copy_segment (event, &dec->segment);
1757 GST_DEBUG_OBJECT (dec, "Got NEWSEGMENT %" GST_SEGMENT_FORMAT,
1760 case GST_EVENT_CAPS:
1764 gst_event_parse_caps (event, &caps);
1765 ret = gst_jpeg_dec_setcaps (dec, caps);
1774 ret = gst_pad_push_event (dec->srcpad, event);
1776 gst_event_unref (event);
1782 gst_jpeg_dec_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
1784 gboolean res = FALSE;
1786 switch (GST_QUERY_TYPE (query)) {
1787 case GST_QUERY_CAPS:
1789 GstCaps *filter, *caps;
1791 gst_query_parse_caps (query, &filter);
1792 caps = gst_jpeg_dec_getcaps (pad, filter);
1793 gst_query_set_caps_result (query, caps);
1794 gst_caps_unref (caps);
1799 res = gst_pad_query_default (pad, parent, query);
1806 gst_jpeg_dec_set_property (GObject * object, guint prop_id,
1807 const GValue * value, GParamSpec * pspec)
1811 dec = GST_JPEG_DEC (object);
1814 case PROP_IDCT_METHOD:
1815 dec->idct_method = g_value_get_enum (value);
1817 case PROP_MAX_ERRORS:
1818 g_atomic_int_set (&dec->max_errors, g_value_get_int (value));
1822 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1828 gst_jpeg_dec_get_property (GObject * object, guint prop_id, GValue * value,
1833 dec = GST_JPEG_DEC (object);
1836 case PROP_IDCT_METHOD:
1837 g_value_set_enum (value, dec->idct_method);
1839 case PROP_MAX_ERRORS:
1840 g_value_set_int (value, g_atomic_int_get (&dec->max_errors));
1844 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1849 static GstStateChangeReturn
1850 gst_jpeg_dec_change_state (GstElement * element, GstStateChange transition)
1852 GstStateChangeReturn ret;
1855 dec = GST_JPEG_DEC (element);
1857 switch (transition) {
1858 case GST_STATE_CHANGE_READY_TO_PAUSED:
1859 dec->error_count = 0;
1860 dec->good_count = 0;
1863 gst_video_info_init (&dec->info);
1865 dec->packetized = FALSE;
1867 dec->discont = TRUE;
1868 dec->parse_offset = 0;
1869 dec->parse_entropy_len = 0;
1870 dec->parse_resync = FALSE;
1871 dec->cur_buf = NULL;
1872 gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED);
1873 gst_jpeg_dec_reset_qos (dec);
1878 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1879 if (ret != GST_STATE_CHANGE_SUCCESS)
1882 switch (transition) {
1883 case GST_STATE_CHANGE_PAUSED_TO_READY:
1884 gst_adapter_clear (dec->adapter);
1885 g_free (dec->cur_buf);
1886 dec->cur_buf = NULL;
1887 gst_jpeg_dec_free_buffers (dec);
1889 gst_buffer_pool_set_active (dec->pool, FALSE);
1890 gst_object_unref (dec->pool);