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, 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,
1179 size = MAX (size, dec->info.size);
1181 GST_DEBUG_OBJECT (dec, "peer query failed, using defaults");
1182 size = dec->info.size;
1187 gst_query_unref (query);
1190 /* we did not get a pool, make one ourselves then */
1191 pool = gst_buffer_pool_new ();
1194 config = gst_buffer_pool_get_config (pool);
1195 gst_buffer_pool_config_set (config, caps, size, min, max, prefix,
1198 gst_buffer_pool_set_config (pool, config);
1201 gst_buffer_pool_set_active (dec->pool, FALSE);
1202 gst_object_unref (dec->pool);
1207 gst_buffer_pool_set_active (pool, TRUE);
1213 gst_jpeg_dec_negotiate (GstJpegDec * dec, gint width, gint height, gint clrspc)
1216 GstVideoFormat format;
1219 if (G_UNLIKELY (width == dec->info.width && height == dec->info.height &&
1220 dec->in_fps_n == dec->info.fps_n && dec->in_fps_d == dec->info.fps_d
1221 && clrspc == dec->clrspc))
1224 gst_video_info_init (&info);
1226 /* framerate == 0/1 is a still frame */
1227 if (dec->in_fps_d == 0) {
1231 info.fps_n = dec->in_fps_n;
1232 info.fps_d = dec->in_fps_d;
1235 /* calculate or assume an average frame duration for QoS purposes */
1236 GST_OBJECT_LOCK (dec);
1237 if (info.fps_n != 0) {
1239 gst_util_uint64_scale (GST_SECOND, info.fps_d, info.fps_n);
1240 dec->duration = dec->qos_duration;
1242 /* if not set just use 25fps */
1243 dec->qos_duration = gst_util_uint64_scale (GST_SECOND, 1, 25);
1244 dec->duration = GST_CLOCK_TIME_NONE;
1246 GST_OBJECT_UNLOCK (dec);
1248 if (dec->cinfo.jpeg_color_space == JCS_RGB) {
1250 GstCaps *allowed_caps;
1251 GstVideoInfo tmpinfo;
1253 GST_DEBUG_OBJECT (dec, "selecting RGB format");
1254 /* retrieve allowed caps, and find the first one that reasonably maps
1255 * to the parameters of the colourspace */
1256 caps = gst_pad_get_allowed_caps (dec->srcpad);
1258 GST_DEBUG_OBJECT (dec, "... but no peer, using template caps");
1259 /* need to copy because get_allowed_caps returns a ref,
1260 * and get_pad_template_caps doesn't */
1261 caps = gst_pad_get_pad_template_caps (dec->srcpad);
1263 /* avoid lists of formats, etc */
1264 allowed_caps = gst_caps_normalize (caps);
1266 GST_LOG_OBJECT (dec, "allowed source caps %" GST_PTR_FORMAT, allowed_caps);
1268 for (i = 0; i < gst_caps_get_size (allowed_caps); i++) {
1270 gst_caps_unref (caps);
1271 caps = gst_caps_copy_nth (allowed_caps, i);
1272 /* sigh, ds and _parse_caps need fixed caps for parsing, fixate */
1273 caps = gst_caps_fixate (caps);
1274 GST_LOG_OBJECT (dec, "checking caps %" GST_PTR_FORMAT, caps);
1276 if (!gst_video_info_from_caps (&tmpinfo, caps))
1278 /* we'll settle for the first (preferred) downstream rgb format */
1279 if (GST_VIDEO_INFO_IS_RGB (&tmpinfo))
1281 /* default fall-back */
1282 format = GST_VIDEO_FORMAT_RGB;
1285 gst_caps_unref (caps);
1286 gst_caps_unref (allowed_caps);
1287 } else if (dec->cinfo.jpeg_color_space == JCS_GRAYSCALE) {
1288 /* TODO is anything else then 8bit supported in jpeg? */
1289 format = GST_VIDEO_FORMAT_GRAY8;
1291 /* go for plain and simple I420 */
1292 /* TODO other YUV cases ? */
1293 format = GST_VIDEO_FORMAT_I420;
1296 gst_video_info_set_format (&info, format, width, height);
1297 caps = gst_video_info_to_caps (&info);
1299 GST_DEBUG_OBJECT (dec, "setting caps %" GST_PTR_FORMAT, caps);
1300 GST_DEBUG_OBJECT (dec, "max_v_samp_factor=%d", dec->cinfo.max_v_samp_factor);
1301 GST_DEBUG_OBJECT (dec, "max_h_samp_factor=%d", dec->cinfo.max_h_samp_factor);
1303 gst_pad_set_caps (dec->srcpad, caps);
1306 dec->clrspc = clrspc;
1308 gst_jpeg_dec_buffer_pool (dec, caps);
1309 gst_caps_unref (caps);
1314 static GstFlowReturn
1315 gst_jpeg_dec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
1317 GstFlowReturn ret = GST_FLOW_OK;
1319 GstBuffer *outbuf = NULL;
1324 GstClockTime timestamp, duration;
1325 GstVideoFrame frame;
1327 dec = GST_JPEG_DEC (parent);
1329 timestamp = GST_BUFFER_TIMESTAMP (buf);
1330 duration = GST_BUFFER_DURATION (buf);
1332 if (GST_CLOCK_TIME_IS_VALID (timestamp))
1333 dec->next_ts = timestamp;
1335 if (GST_BUFFER_IS_DISCONT (buf)) {
1336 GST_DEBUG_OBJECT (dec, "buffer has DISCONT flag set");
1337 dec->discont = TRUE;
1338 if (!dec->packetized && gst_adapter_available (dec->adapter)) {
1339 GST_WARNING_OBJECT (dec, "DISCONT buffer in non-packetized mode, bad");
1340 gst_adapter_clear (dec->adapter);
1344 gst_adapter_push (dec->adapter, buf);
1347 /* If we are non-packetized and know the total incoming size in bytes,
1348 * just wait until we have enough before doing any processing. */
1350 if (!dec->packetized && (dec->segment.format == GST_FORMAT_BYTES) &&
1351 (dec->segment.stop != -1) &&
1352 (gst_adapter_available (dec->adapter) < dec->segment.stop)) {
1353 /* We assume that non-packetized input in bytes is *one* single jpeg image */
1354 GST_DEBUG ("Non-packetized mode. Got %" G_GSIZE_FORMAT " bytes, "
1355 "need %" G_GINT64_FORMAT, gst_adapter_available (dec->adapter),
1357 goto need_more_data;
1361 if (!gst_jpeg_dec_ensure_header (dec))
1362 goto need_more_data;
1364 /* If we know that each input buffer contains data
1365 * for a whole jpeg image (e.g. MJPEG streams), just
1366 * do some sanity checking instead of parsing all of
1368 if (dec->packetized) {
1369 img_len = gst_adapter_available (dec->adapter);
1371 /* Parse jpeg image to handle jpeg input that
1372 * is not aligned to buffer boundaries */
1373 img_len = gst_jpeg_dec_parse_image_data (dec);
1376 goto need_more_data;
1377 } else if (img_len < 0) {
1378 gst_adapter_flush (dec->adapter, -img_len);
1383 dec->rem_img_len = img_len;
1385 GST_LOG_OBJECT (dec, "image size = %u", img_len);
1387 /* QoS: if we're too late anyway, skip decoding */
1388 if (dec->packetized && !gst_jpeg_dec_do_qos (dec, timestamp))
1391 #ifndef GST_DISABLE_GST_DEBUG
1395 gst_adapter_copy (dec->adapter, data, 0, 4);
1396 GST_LOG_OBJECT (dec, "reading header %02x %02x %02x %02x", data[0], data[1],
1401 gst_jpeg_dec_fill_input_buffer (&dec->cinfo);
1403 if (setjmp (dec->jerr.setjmp_buffer)) {
1404 code = dec->jerr.pub.msg_code;
1406 if (code == JERR_INPUT_EOF) {
1407 GST_DEBUG ("jpeg input EOF error, we probably need more data");
1408 goto need_more_data;
1414 hdr_ok = jpeg_read_header (&dec->cinfo, TRUE);
1415 if (G_UNLIKELY (hdr_ok != JPEG_HEADER_OK)) {
1416 GST_WARNING_OBJECT (dec, "reading the header failed, %d", hdr_ok);
1419 GST_LOG_OBJECT (dec, "num_components=%d", dec->cinfo.num_components);
1420 GST_LOG_OBJECT (dec, "jpeg_color_space=%d", dec->cinfo.jpeg_color_space);
1422 if (!dec->cinfo.num_components || !dec->cinfo.comp_info)
1423 goto components_not_supported;
1425 r_h = dec->cinfo.comp_info[0].h_samp_factor;
1426 r_v = dec->cinfo.comp_info[0].v_samp_factor;
1428 GST_LOG_OBJECT (dec, "r_h = %d, r_v = %d", r_h, r_v);
1430 if (dec->cinfo.num_components > 3)
1431 goto components_not_supported;
1433 /* verify color space expectation to avoid going *boom* or bogus output */
1434 if (dec->cinfo.jpeg_color_space != JCS_YCbCr &&
1435 dec->cinfo.jpeg_color_space != JCS_GRAYSCALE &&
1436 dec->cinfo.jpeg_color_space != JCS_RGB)
1437 goto unsupported_colorspace;
1439 #ifndef GST_DISABLE_GST_DEBUG
1443 for (i = 0; i < dec->cinfo.num_components; ++i) {
1444 GST_LOG_OBJECT (dec, "[%d] h_samp_factor=%d, v_samp_factor=%d, cid=%d",
1445 i, dec->cinfo.comp_info[i].h_samp_factor,
1446 dec->cinfo.comp_info[i].v_samp_factor,
1447 dec->cinfo.comp_info[i].component_id);
1452 /* prepare for raw output */
1453 dec->cinfo.do_fancy_upsampling = FALSE;
1454 dec->cinfo.do_block_smoothing = FALSE;
1455 dec->cinfo.out_color_space = dec->cinfo.jpeg_color_space;
1456 dec->cinfo.dct_method = dec->idct_method;
1457 dec->cinfo.raw_data_out = TRUE;
1459 GST_LOG_OBJECT (dec, "starting decompress");
1460 guarantee_huff_tables (&dec->cinfo);
1461 if (!jpeg_start_decompress (&dec->cinfo)) {
1462 GST_WARNING_OBJECT (dec, "failed to start decompression cycle");
1465 /* sanity checks to get safe and reasonable output */
1466 switch (dec->cinfo.jpeg_color_space) {
1468 if (dec->cinfo.num_components != 1)
1469 goto invalid_yuvrgbgrayscale;
1472 if (dec->cinfo.num_components != 3 || dec->cinfo.max_v_samp_factor > 1 ||
1473 dec->cinfo.max_h_samp_factor > 1)
1474 goto invalid_yuvrgbgrayscale;
1477 if (dec->cinfo.num_components != 3 ||
1478 r_v > 2 || r_v < dec->cinfo.comp_info[0].v_samp_factor ||
1479 r_v < dec->cinfo.comp_info[1].v_samp_factor ||
1480 r_h < dec->cinfo.comp_info[0].h_samp_factor ||
1481 r_h < dec->cinfo.comp_info[1].h_samp_factor)
1482 goto invalid_yuvrgbgrayscale;
1485 g_assert_not_reached ();
1489 width = dec->cinfo.output_width;
1490 height = dec->cinfo.output_height;
1492 if (G_UNLIKELY (width < MIN_WIDTH || width > MAX_WIDTH ||
1493 height < MIN_HEIGHT || height > MAX_HEIGHT))
1496 gst_jpeg_dec_negotiate (dec, width, height, dec->cinfo.jpeg_color_space);
1498 ret = gst_buffer_pool_acquire_buffer (dec->pool, &outbuf, NULL);
1499 if (G_UNLIKELY (ret != GST_FLOW_OK))
1502 if (!gst_video_frame_map (&frame, &dec->info, outbuf, GST_MAP_READWRITE))
1505 GST_LOG_OBJECT (dec, "width %d, height %d", width, height);
1507 GST_BUFFER_TIMESTAMP (outbuf) = dec->next_ts;
1509 if (dec->packetized && GST_CLOCK_TIME_IS_VALID (dec->next_ts)) {
1510 if (GST_CLOCK_TIME_IS_VALID (duration)) {
1511 /* use duration from incoming buffer for outgoing buffer */
1512 dec->next_ts += duration;
1513 } else if (GST_CLOCK_TIME_IS_VALID (dec->duration)) {
1514 duration = dec->duration;
1515 dec->next_ts += dec->duration;
1517 duration = GST_CLOCK_TIME_NONE;
1518 dec->next_ts = GST_CLOCK_TIME_NONE;
1521 duration = GST_CLOCK_TIME_NONE;
1522 dec->next_ts = GST_CLOCK_TIME_NONE;
1524 GST_BUFFER_DURATION (outbuf) = duration;
1526 if (dec->cinfo.jpeg_color_space == JCS_RGB) {
1527 gst_jpeg_dec_decode_rgb (dec, &frame);
1528 } else if (dec->cinfo.jpeg_color_space == JCS_GRAYSCALE) {
1529 gst_jpeg_dec_decode_grayscale (dec, &frame);
1531 GST_LOG_OBJECT (dec, "decompressing (reqired scanline buffer height = %u)",
1532 dec->cinfo.rec_outbuf_height);
1534 /* For some widths jpeglib requires more horizontal padding than I420
1535 * provides. In those cases we need to decode into separate buffers and then
1536 * copy over the data into our final picture buffer, otherwise jpeglib might
1537 * write over the end of a line into the beginning of the next line,
1538 * resulting in blocky artifacts on the left side of the picture. */
1539 if (G_UNLIKELY (width % (dec->cinfo.max_h_samp_factor * DCTSIZE) != 0
1540 || dec->cinfo.comp_info[0].h_samp_factor != 2
1541 || dec->cinfo.comp_info[1].h_samp_factor != 1
1542 || dec->cinfo.comp_info[2].h_samp_factor != 1)) {
1543 GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, dec,
1544 "indirect decoding using extra buffer copy");
1545 gst_jpeg_dec_decode_indirect (dec, &frame, r_v, r_h,
1546 dec->cinfo.num_components);
1548 ret = gst_jpeg_dec_decode_direct (dec, &frame);
1549 if (G_UNLIKELY (ret != GST_FLOW_OK))
1550 goto decode_direct_failed;
1554 GST_LOG_OBJECT (dec, "decompressing finished");
1555 jpeg_finish_decompress (&dec->cinfo);
1557 gst_video_frame_unmap (&frame);
1560 if (dec->segment.format == GST_FORMAT_TIME) {
1561 guint64 start, stop, clip_start, clip_stop;
1563 GST_LOG_OBJECT (dec, "Attempting clipping");
1565 start = GST_BUFFER_TIMESTAMP (outbuf);
1566 if (GST_BUFFER_DURATION (outbuf) == GST_CLOCK_TIME_NONE)
1569 stop = start + GST_BUFFER_DURATION (outbuf);
1571 if (gst_segment_clip (&dec->segment, GST_FORMAT_TIME,
1572 start, stop, &clip_start, &clip_stop)) {
1573 GST_LOG_OBJECT (dec, "Clipping start to %" GST_TIME_FORMAT,
1574 GST_TIME_ARGS (clip_start));
1575 GST_BUFFER_TIMESTAMP (outbuf) = clip_start;
1576 if (GST_BUFFER_DURATION (outbuf) != GST_CLOCK_TIME_NONE) {
1577 GST_LOG_OBJECT (dec, "Clipping duration to %" GST_TIME_FORMAT,
1578 GST_TIME_ARGS (clip_stop - clip_start));
1579 GST_BUFFER_DURATION (outbuf) = clip_stop - clip_start;
1585 /* reset error count on successful decode */
1586 dec->error_count = 0;
1590 GST_LOG_OBJECT (dec, "pushing buffer (ts=%" GST_TIME_FORMAT ", dur=%"
1591 GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
1592 GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
1594 ret = gst_pad_push (dec->srcpad, outbuf);
1598 gst_adapter_flush (dec->adapter, dec->rem_img_len);
1602 if (G_UNLIKELY (ret == GST_FLOW_ERROR)) {
1603 jpeg_abort_decompress (&dec->cinfo);
1604 ret = gst_jpeg_dec_post_error_or_warning (dec);
1612 GST_LOG_OBJECT (dec, "we need more data");
1614 gst_buffer_unref (outbuf);
1623 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1624 "Picture is too small or too big (%ux%u)", width, height);
1625 ret = GST_FLOW_ERROR;
1630 gchar err_msg[JMSG_LENGTH_MAX];
1632 dec->jerr.pub.format_message ((j_common_ptr) (&dec->cinfo), err_msg);
1634 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1635 "Decode error #%u: %s", code, err_msg);
1638 gst_buffer_unref (outbuf);
1641 ret = GST_FLOW_ERROR;
1644 decode_direct_failed:
1646 /* already posted an error message */
1647 jpeg_abort_decompress (&dec->cinfo);
1648 gst_buffer_replace (&outbuf, NULL);
1653 const gchar *reason;
1655 reason = gst_flow_get_name (ret);
1657 GST_DEBUG_OBJECT (dec, "failed to alloc buffer, reason %s", reason);
1658 /* Reset for next time */
1659 jpeg_abort_decompress (&dec->cinfo);
1660 if (ret != GST_FLOW_EOS && ret != GST_FLOW_FLUSHING &&
1661 ret != GST_FLOW_NOT_LINKED) {
1662 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1663 "Buffer allocation failed, reason: %s", reason);
1669 jpeg_abort_decompress (&dec->cinfo);
1670 gst_buffer_unref (outbuf);
1676 GST_WARNING_OBJECT (dec, "Outgoing buffer is outside configured segment");
1677 gst_buffer_unref (outbuf);
1681 components_not_supported:
1683 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1684 "number of components not supported: %d (max 3)",
1685 dec->cinfo.num_components);
1686 ret = GST_FLOW_ERROR;
1689 unsupported_colorspace:
1691 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1692 "Picture has unknown or unsupported colourspace");
1693 ret = GST_FLOW_ERROR;
1696 invalid_yuvrgbgrayscale:
1698 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1699 "Picture is corrupt or unhandled YUV/RGB/grayscale layout");
1700 ret = GST_FLOW_ERROR;
1706 gst_jpeg_dec_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
1711 dec = GST_JPEG_DEC (parent);
1713 switch (GST_EVENT_TYPE (event)) {
1714 case GST_EVENT_QOS:{
1716 GstClockTimeDiff diff;
1717 GstClockTime timestamp;
1720 gst_event_parse_qos (event, &type, &proportion, &diff, ×tamp);
1721 gst_jpeg_dec_update_qos (dec, proportion, diff, timestamp);
1728 res = gst_pad_push_event (dec->sinkpad, event);
1734 gst_jpeg_dec_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
1736 gboolean ret = TRUE, forward = TRUE;
1737 GstJpegDec *dec = GST_JPEG_DEC (parent);
1739 GST_DEBUG_OBJECT (dec, "event : %s", GST_EVENT_TYPE_NAME (event));
1741 switch (GST_EVENT_TYPE (event)) {
1742 case GST_EVENT_FLUSH_STOP:
1743 GST_DEBUG_OBJECT (dec, "Aborting decompress");
1744 jpeg_abort_decompress (&dec->cinfo);
1745 gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED);
1746 gst_adapter_clear (dec->adapter);
1747 g_free (dec->cur_buf);
1748 dec->cur_buf = NULL;
1749 dec->parse_offset = 0;
1750 dec->parse_entropy_len = 0;
1751 dec->parse_resync = FALSE;
1752 gst_jpeg_dec_reset_qos (dec);
1754 case GST_EVENT_SEGMENT:
1755 gst_event_copy_segment (event, &dec->segment);
1756 GST_DEBUG_OBJECT (dec, "Got NEWSEGMENT %" GST_SEGMENT_FORMAT,
1759 case GST_EVENT_CAPS:
1763 gst_event_parse_caps (event, &caps);
1764 ret = gst_jpeg_dec_setcaps (dec, caps);
1773 ret = gst_pad_push_event (dec->srcpad, event);
1775 gst_event_unref (event);
1781 gst_jpeg_dec_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
1783 gboolean res = FALSE;
1785 switch (GST_QUERY_TYPE (query)) {
1786 case GST_QUERY_CAPS:
1788 GstCaps *filter, *caps;
1790 gst_query_parse_caps (query, &filter);
1791 caps = gst_jpeg_dec_getcaps (pad, filter);
1792 gst_query_set_caps_result (query, caps);
1793 gst_caps_unref (caps);
1798 res = gst_pad_query_default (pad, parent, query);
1805 gst_jpeg_dec_set_property (GObject * object, guint prop_id,
1806 const GValue * value, GParamSpec * pspec)
1810 dec = GST_JPEG_DEC (object);
1813 case PROP_IDCT_METHOD:
1814 dec->idct_method = g_value_get_enum (value);
1816 case PROP_MAX_ERRORS:
1817 g_atomic_int_set (&dec->max_errors, g_value_get_int (value));
1821 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1827 gst_jpeg_dec_get_property (GObject * object, guint prop_id, GValue * value,
1832 dec = GST_JPEG_DEC (object);
1835 case PROP_IDCT_METHOD:
1836 g_value_set_enum (value, dec->idct_method);
1838 case PROP_MAX_ERRORS:
1839 g_value_set_int (value, g_atomic_int_get (&dec->max_errors));
1843 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1848 static GstStateChangeReturn
1849 gst_jpeg_dec_change_state (GstElement * element, GstStateChange transition)
1851 GstStateChangeReturn ret;
1854 dec = GST_JPEG_DEC (element);
1856 switch (transition) {
1857 case GST_STATE_CHANGE_READY_TO_PAUSED:
1858 dec->error_count = 0;
1859 dec->good_count = 0;
1862 gst_video_info_init (&dec->info);
1864 dec->packetized = FALSE;
1866 dec->discont = TRUE;
1867 dec->parse_offset = 0;
1868 dec->parse_entropy_len = 0;
1869 dec->parse_resync = FALSE;
1870 dec->cur_buf = NULL;
1871 gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED);
1872 gst_jpeg_dec_reset_qos (dec);
1877 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1878 if (ret != GST_STATE_CHANGE_SUCCESS)
1881 switch (transition) {
1882 case GST_STATE_CHANGE_PAUSED_TO_READY:
1883 gst_adapter_clear (dec->adapter);
1884 g_free (dec->cur_buf);
1885 dec->cur_buf = NULL;
1886 gst_jpeg_dec_free_buffers (dec);
1888 gst_buffer_pool_set_active (dec->pool, FALSE);
1889 gst_object_unref (dec->pool);