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, GstBuffer * buffer);
97 static GstCaps *gst_jpeg_dec_getcaps (GstPad * pad, GstCaps * filter);
98 static gboolean gst_jpeg_dec_sink_event (GstPad * pad, GstEvent * event);
99 static gboolean gst_jpeg_dec_src_event (GstPad * pad, GstEvent * event);
100 static GstStateChangeReturn gst_jpeg_dec_change_state (GstElement * element,
101 GstStateChange transition);
102 static void gst_jpeg_dec_update_qos (GstJpegDec * dec, gdouble proportion,
103 GstClockTimeDiff diff, GstClockTime ts);
104 static void gst_jpeg_dec_reset_qos (GstJpegDec * dec);
105 static void gst_jpeg_dec_read_qos (GstJpegDec * dec, gdouble * proportion,
106 GstClockTime * time);
108 #define gst_jpeg_dec_parent_class parent_class
109 G_DEFINE_TYPE (GstJpegDec, gst_jpeg_dec, GST_TYPE_ELEMENT);
112 gst_jpeg_dec_finalize (GObject * object)
114 GstJpegDec *dec = GST_JPEG_DEC (object);
116 jpeg_destroy_decompress (&dec->cinfo);
118 g_object_unref (dec->adapter);
120 G_OBJECT_CLASS (parent_class)->finalize (object);
124 gst_jpeg_dec_class_init (GstJpegDecClass * klass)
126 GstElementClass *gstelement_class;
127 GObjectClass *gobject_class;
129 gstelement_class = (GstElementClass *) klass;
130 gobject_class = (GObjectClass *) klass;
132 parent_class = g_type_class_peek_parent (klass);
134 gobject_class->finalize = gst_jpeg_dec_finalize;
135 gobject_class->set_property = gst_jpeg_dec_set_property;
136 gobject_class->get_property = gst_jpeg_dec_get_property;
138 g_object_class_install_property (gobject_class, PROP_IDCT_METHOD,
139 g_param_spec_enum ("idct-method", "IDCT Method",
140 "The IDCT algorithm to use", GST_TYPE_IDCT_METHOD,
141 JPEG_DEFAULT_IDCT_METHOD,
142 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
145 * GstJpegDec:max-errors
147 * Error out after receiving N consecutive decoding errors
148 * (-1 = never error out, 0 = automatic, 1 = fail on first error, etc.)
152 g_object_class_install_property (gobject_class, PROP_MAX_ERRORS,
153 g_param_spec_int ("max-errors", "Maximum Consecutive Decoding Errors",
154 "Error out after receiving N consecutive decoding errors "
155 "(-1 = never fail, 0 = automatic, 1 = fail on first error)",
156 -1, G_MAXINT, JPEG_DEFAULT_MAX_ERRORS,
157 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
159 gst_element_class_add_pad_template (gstelement_class,
160 gst_static_pad_template_get (&gst_jpeg_dec_src_pad_template));
161 gst_element_class_add_pad_template (gstelement_class,
162 gst_static_pad_template_get (&gst_jpeg_dec_sink_pad_template));
163 gst_element_class_set_details_simple (gstelement_class, "JPEG image decoder",
164 "Codec/Decoder/Image",
165 "Decode images from JPEG format", "Wim Taymans <wim@fluendo.com>");
167 gstelement_class->change_state =
168 GST_DEBUG_FUNCPTR (gst_jpeg_dec_change_state);
170 GST_DEBUG_CATEGORY_INIT (jpeg_dec_debug, "jpegdec", 0, "JPEG decoder");
171 GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE");
175 gst_jpeg_dec_clear_error (GstJpegDec * dec)
177 g_free (dec->error_msg);
178 dec->error_msg = NULL;
180 dec->error_func = NULL;
184 gst_jpeg_dec_set_error_va (GstJpegDec * dec, const gchar * func, gint line,
185 const gchar * debug_msg_format, va_list args)
187 #ifndef GST_DISABLE_GST_DEBUG
188 gst_debug_log_valist (GST_CAT_DEFAULT, GST_LEVEL_WARNING, __FILE__, func,
189 line, (GObject *) dec, debug_msg_format, args);
192 g_free (dec->error_msg);
193 if (debug_msg_format)
194 dec->error_msg = g_strdup_vprintf (debug_msg_format, args);
196 dec->error_msg = NULL;
198 dec->error_line = line;
199 dec->error_func = func;
203 gst_jpeg_dec_set_error (GstJpegDec * dec, const gchar * func, gint line,
204 const gchar * debug_msg_format, ...)
208 va_start (va, debug_msg_format);
209 gst_jpeg_dec_set_error_va (dec, func, line, debug_msg_format, va);
214 gst_jpeg_dec_post_error_or_warning (GstJpegDec * dec)
220 max_errors = g_atomic_int_get (&dec->max_errors);
222 if (max_errors < 0) {
224 } else if (max_errors == 0) {
225 /* FIXME: do something more clever in "automatic mode" */
226 if (dec->packetized) {
227 ret = (dec->error_count < 3) ? GST_FLOW_OK : GST_FLOW_ERROR;
229 ret = GST_FLOW_ERROR;
232 ret = (dec->error_count < max_errors) ? GST_FLOW_OK : GST_FLOW_ERROR;
235 GST_INFO_OBJECT (dec, "decoding error %d/%d (%s)", dec->error_count,
236 max_errors, (ret == GST_FLOW_OK) ? "ignoring error" : "erroring out");
238 gst_element_message_full (GST_ELEMENT (dec),
239 (ret == GST_FLOW_OK) ? GST_MESSAGE_WARNING : GST_MESSAGE_ERROR,
240 GST_STREAM_ERROR, GST_STREAM_ERROR_DECODE,
241 g_strdup (_("Failed to decode JPEG image")), dec->error_msg,
242 __FILE__, dec->error_func, dec->error_line);
244 dec->error_msg = NULL;
245 gst_jpeg_dec_clear_error (dec);
250 gst_jpeg_dec_fill_input_buffer (j_decompress_ptr cinfo)
255 dec = CINFO_GET_JPEGDEC (cinfo);
256 g_return_val_if_fail (dec != NULL, FALSE);
258 av = gst_adapter_available_fast (dec->adapter);
259 GST_DEBUG_OBJECT (dec, "fill_input_buffer: fast av=%u, remaining=%u", av,
263 GST_DEBUG_OBJECT (dec, "Out of data");
267 if (dec->rem_img_len < av)
268 av = dec->rem_img_len;
269 dec->rem_img_len -= av;
271 g_free (dec->cur_buf);
272 dec->cur_buf = gst_adapter_take (dec->adapter, av);
274 cinfo->src->next_input_byte = dec->cur_buf;
275 cinfo->src->bytes_in_buffer = av;
281 gst_jpeg_dec_init_source (j_decompress_ptr cinfo)
283 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "init_source");
288 gst_jpeg_dec_skip_input_data (j_decompress_ptr cinfo, glong num_bytes)
290 GstJpegDec *dec = CINFO_GET_JPEGDEC (cinfo);
292 GST_DEBUG_OBJECT (dec, "skip %ld bytes", num_bytes);
294 if (num_bytes > 0 && cinfo->src->bytes_in_buffer >= num_bytes) {
295 cinfo->src->next_input_byte += (size_t) num_bytes;
296 cinfo->src->bytes_in_buffer -= (size_t) num_bytes;
297 } else if (num_bytes > 0) {
300 num_bytes -= cinfo->src->bytes_in_buffer;
301 cinfo->src->next_input_byte += (size_t) cinfo->src->bytes_in_buffer;
302 cinfo->src->bytes_in_buffer = 0;
304 available = gst_adapter_available (dec->adapter);
305 if (available < num_bytes || available < dec->rem_img_len) {
306 GST_WARNING_OBJECT (dec, "Less bytes to skip than available in the "
307 "adapter or the remaining image length %ld < %d or %u",
308 num_bytes, available, dec->rem_img_len);
310 num_bytes = MIN (MIN (num_bytes, available), dec->rem_img_len);
311 gst_adapter_flush (dec->adapter, num_bytes);
312 dec->rem_img_len -= num_bytes;
317 gst_jpeg_dec_resync_to_restart (j_decompress_ptr cinfo, gint desired)
319 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "resync_to_start");
324 gst_jpeg_dec_term_source (j_decompress_ptr cinfo)
326 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "term_source");
331 gst_jpeg_dec_my_output_message (j_common_ptr cinfo)
333 return; /* do nothing */
337 gst_jpeg_dec_my_emit_message (j_common_ptr cinfo, int msg_level)
339 /* GST_LOG_OBJECT (CINFO_GET_JPEGDEC (&cinfo), "msg_level=%d", msg_level); */
344 gst_jpeg_dec_my_error_exit (j_common_ptr cinfo)
346 struct GstJpegDecErrorMgr *err_mgr = (struct GstJpegDecErrorMgr *) cinfo->err;
348 (*cinfo->err->output_message) (cinfo);
349 longjmp (err_mgr->setjmp_buffer, 1);
353 gst_jpeg_dec_init (GstJpegDec * dec)
355 GST_DEBUG ("initializing");
357 /* create the sink and src pads */
359 gst_pad_new_from_static_template (&gst_jpeg_dec_sink_pad_template,
361 gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
362 gst_pad_set_getcaps_function (dec->sinkpad,
363 GST_DEBUG_FUNCPTR (gst_jpeg_dec_getcaps));
364 gst_pad_set_chain_function (dec->sinkpad,
365 GST_DEBUG_FUNCPTR (gst_jpeg_dec_chain));
366 gst_pad_set_event_function (dec->sinkpad,
367 GST_DEBUG_FUNCPTR (gst_jpeg_dec_sink_event));
370 gst_pad_new_from_static_template (&gst_jpeg_dec_src_pad_template, "src");
371 gst_pad_set_event_function (dec->srcpad,
372 GST_DEBUG_FUNCPTR (gst_jpeg_dec_src_event));
373 gst_pad_use_fixed_caps (dec->srcpad);
374 gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
377 memset (&dec->cinfo, 0, sizeof (dec->cinfo));
378 memset (&dec->jerr, 0, sizeof (dec->jerr));
379 dec->cinfo.err = jpeg_std_error (&dec->jerr.pub);
380 dec->jerr.pub.output_message = gst_jpeg_dec_my_output_message;
381 dec->jerr.pub.emit_message = gst_jpeg_dec_my_emit_message;
382 dec->jerr.pub.error_exit = gst_jpeg_dec_my_error_exit;
384 jpeg_create_decompress (&dec->cinfo);
386 dec->cinfo.src = (struct jpeg_source_mgr *) &dec->jsrc;
387 dec->cinfo.src->init_source = gst_jpeg_dec_init_source;
388 dec->cinfo.src->fill_input_buffer = gst_jpeg_dec_fill_input_buffer;
389 dec->cinfo.src->skip_input_data = gst_jpeg_dec_skip_input_data;
390 dec->cinfo.src->resync_to_restart = gst_jpeg_dec_resync_to_restart;
391 dec->cinfo.src->term_source = gst_jpeg_dec_term_source;
394 /* init properties */
395 dec->idct_method = JPEG_DEFAULT_IDCT_METHOD;
396 dec->max_errors = JPEG_DEFAULT_MAX_ERRORS;
398 dec->adapter = gst_adapter_new ();
402 gst_jpeg_dec_ensure_header (GstJpegDec * dec)
407 av = gst_adapter_available (dec->adapter);
408 /* we expect at least 4 bytes, first of which start marker */
409 offset = gst_adapter_masked_scan_uint32 (dec->adapter, 0xffffff00, 0xffd8ff00,
411 if (G_UNLIKELY (offset < 0)) {
412 GST_DEBUG_OBJECT (dec, "No JPEG header in current buffer");
415 gst_adapter_flush (dec->adapter, av - 4);
420 GST_LOG_OBJECT (dec, "Skipping %u bytes.", offset);
421 gst_adapter_flush (dec->adapter, offset);
423 GST_DEBUG_OBJECT (dec, "Found JPEG header");
428 static inline gboolean
429 gst_jpeg_dec_parse_tag_has_entropy_segment (guint8 tag)
431 if (tag == 0xda || (tag >= 0xd0 && tag <= 0xd7))
436 /* returns image length in bytes if parsed successfully,
437 * otherwise 0 if more data needed,
438 * if < 0 the absolute value needs to be flushed */
440 gst_jpeg_dec_parse_image_data (GstJpegDec * dec)
444 GstAdapter *adapter = dec->adapter;
445 gint offset, noffset;
447 size = gst_adapter_available (adapter);
449 /* we expect at least 4 bytes, first of which start marker */
450 if (gst_adapter_masked_scan_uint32 (adapter, 0xffff0000, 0xffd80000, 0, 4))
453 GST_DEBUG ("Parsing jpeg image data (%u bytes)", size);
455 GST_DEBUG ("Parse state: offset=%d, resync=%d, entropy len=%d",
456 dec->parse_offset, dec->parse_resync, dec->parse_entropy_len);
458 /* offset is 2 less than actual offset;
459 * - adapter needs at least 4 bytes for scanning,
460 * - start and end marker ensure at least that much
462 /* resume from state offset */
463 offset = dec->parse_offset;
470 gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00, 0x0000ff00,
471 offset, size - offset, &value);
472 /* lost sync if 0xff marker not where expected */
473 if ((resync = (noffset != offset))) {
474 GST_DEBUG ("Lost sync at 0x%08x, resyncing", offset + 2);
476 /* may have marker, but could have been resyncng */
477 resync = resync || dec->parse_resync;
478 /* Skip over extra 0xff */
479 while ((noffset >= 0) && ((value & 0xff) == 0xff)) {
482 gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00, 0x0000ff00,
483 noffset, size - noffset, &value);
485 /* enough bytes left for marker? (we need 0xNN after the 0xff) */
487 GST_DEBUG ("at end of input and no EOI marker found, need more data");
491 /* now lock on the marker we found */
493 value = value & 0xff;
495 GST_DEBUG ("0x%08x: EOI marker", offset + 2);
496 /* clear parse state */
497 dec->parse_resync = FALSE;
498 dec->parse_offset = 0;
500 } else if (value == 0xd8) {
501 /* Skip this frame if we found another SOI marker */
502 GST_DEBUG ("0x%08x: SOI marker before EOI, skipping", offset + 2);
503 dec->parse_resync = FALSE;
504 dec->parse_offset = 0;
505 return -(offset + 2);
509 if (value >= 0xd0 && value <= 0xd7)
512 /* peek tag and subsequent length */
513 if (offset + 2 + 4 > size)
516 gst_adapter_masked_scan_uint32_peek (adapter, 0x0, 0x0, offset + 2, 4,
518 frame_len = frame_len & 0xffff;
520 GST_DEBUG ("0x%08x: tag %02x, frame_len=%u", offset + 2, value, frame_len);
521 /* the frame length includes the 2 bytes for the length; here we want at
522 * least 2 more bytes at the end for an end marker */
523 if (offset + 2 + 2 + frame_len + 2 > size) {
527 if (gst_jpeg_dec_parse_tag_has_entropy_segment (value)) {
528 guint eseglen = dec->parse_entropy_len;
530 GST_DEBUG ("0x%08x: finding entropy segment length", offset + 2);
531 noffset = offset + 2 + frame_len + dec->parse_entropy_len;
533 noffset = gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00,
534 0x0000ff00, noffset, size - noffset, &value);
537 dec->parse_entropy_len = size - offset - 4 - frame_len - 2;
540 if ((value & 0xff) != 0x00) {
541 eseglen = noffset - offset - frame_len - 2;
546 dec->parse_entropy_len = 0;
547 frame_len += eseglen;
548 GST_DEBUG ("entropy segment length=%u => frame_len=%u", eseglen,
552 /* check if we will still be in sync if we interpret
553 * this as a sync point and skip this frame */
554 noffset = offset + frame_len + 2;
555 noffset = gst_adapter_masked_scan_uint32 (adapter, 0x0000ff00, 0x0000ff00,
558 /* ignore and continue resyncing until we hit the end
559 * of our data or find a sync point that looks okay */
563 GST_DEBUG ("found sync at 0x%x", offset + 2);
566 offset += frame_len + 2;
572 dec->parse_offset = offset;
573 dec->parse_resync = resync;
578 /* shamelessly ripped from jpegutils.c in mjpegtools */
580 add_huff_table (j_decompress_ptr dinfo,
581 JHUFF_TBL ** htblptr, const UINT8 * bits, const UINT8 * val)
582 /* Define a Huffman table */
586 if (*htblptr == NULL)
587 *htblptr = jpeg_alloc_huff_table ((j_common_ptr) dinfo);
591 /* Copy the number-of-symbols-of-each-code-length counts */
592 memcpy ((*htblptr)->bits, bits, sizeof ((*htblptr)->bits));
594 /* Validate the counts. We do this here mainly so we can copy the right
595 * number of symbols from the val[] array, without risking marching off
596 * the end of memory. jchuff.c will do a more thorough test later.
599 for (len = 1; len <= 16; len++)
600 nsymbols += bits[len];
601 if (nsymbols < 1 || nsymbols > 256)
602 g_error ("jpegutils.c: add_huff_table failed badly. ");
604 memcpy ((*htblptr)->huffval, val, nsymbols * sizeof (UINT8));
610 std_huff_tables (j_decompress_ptr dinfo)
611 /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
612 /* IMPORTANT: these are only valid for 8-bit data precision! */
614 static const UINT8 bits_dc_luminance[17] =
615 { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
616 static const UINT8 val_dc_luminance[] =
617 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
619 static const UINT8 bits_dc_chrominance[17] =
620 { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
621 static const UINT8 val_dc_chrominance[] =
622 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
624 static const UINT8 bits_ac_luminance[17] =
625 { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
626 static const UINT8 val_ac_luminance[] =
627 { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
628 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
629 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
630 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
631 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
632 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
633 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
634 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
635 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
636 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
637 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
638 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
639 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
640 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
641 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
642 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
643 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
644 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
645 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
646 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
650 static const UINT8 bits_ac_chrominance[17] =
651 { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
652 static const UINT8 val_ac_chrominance[] =
653 { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
654 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
655 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
656 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
657 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
658 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
659 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
660 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
661 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
662 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
663 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
664 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
665 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
666 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
667 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
668 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
669 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
670 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
671 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
672 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
676 add_huff_table (dinfo, &dinfo->dc_huff_tbl_ptrs[0],
677 bits_dc_luminance, val_dc_luminance);
678 add_huff_table (dinfo, &dinfo->ac_huff_tbl_ptrs[0],
679 bits_ac_luminance, val_ac_luminance);
680 add_huff_table (dinfo, &dinfo->dc_huff_tbl_ptrs[1],
681 bits_dc_chrominance, val_dc_chrominance);
682 add_huff_table (dinfo, &dinfo->ac_huff_tbl_ptrs[1],
683 bits_ac_chrominance, val_ac_chrominance);
689 guarantee_huff_tables (j_decompress_ptr dinfo)
691 if ((dinfo->dc_huff_tbl_ptrs[0] == NULL) &&
692 (dinfo->dc_huff_tbl_ptrs[1] == NULL) &&
693 (dinfo->ac_huff_tbl_ptrs[0] == NULL) &&
694 (dinfo->ac_huff_tbl_ptrs[1] == NULL)) {
695 GST_DEBUG ("Generating standard Huffman tables for this frame.");
696 std_huff_tables (dinfo);
701 gst_jpeg_dec_setcaps (GstJpegDec * dec, GstCaps * caps)
704 const GValue *framerate;
706 s = gst_caps_get_structure (caps, 0);
708 if ((framerate = gst_structure_get_value (s, "framerate")) != NULL) {
709 dec->in_fps_n = gst_value_get_fraction_numerator (framerate);
710 dec->in_fps_d = gst_value_get_fraction_denominator (framerate);
711 dec->packetized = TRUE;
712 GST_DEBUG ("got framerate of %d/%d fps => packetized mode",
713 dec->in_fps_n, dec->in_fps_d);
716 /* do not extract width/height here. we do that in the chain
717 * function on a per-frame basis (including the line[] array
720 /* But we can take the framerate values and set them on the src pad */
726 gst_jpeg_dec_getcaps (GstPad * pad, GstCaps * filter)
732 dec = GST_JPEG_DEC (GST_OBJECT_PARENT (pad));
734 if (gst_pad_has_current_caps (pad))
735 return gst_pad_get_current_caps (pad);
737 peer = gst_pad_get_peer (dec->srcpad);
741 const GstCaps *templ_caps;
745 peer_caps = gst_pad_get_caps (peer, filter);
747 /* Translate peercaps to image/jpeg */
748 peer_caps = gst_caps_make_writable (peer_caps);
749 n = gst_caps_get_size (peer_caps);
750 for (i = 0; i < n; i++) {
751 s = gst_caps_get_structure (peer_caps, i);
753 gst_structure_set_name (s, "image/jpeg");
756 templ_caps = gst_pad_get_pad_template_caps (pad);
757 caps = gst_caps_intersect_full (peer_caps, templ_caps,
758 GST_CAPS_INTERSECT_FIRST);
760 gst_object_unref (peer);
762 caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
771 hresamplecpy1 (guint8 * dest, const guint8 * src, guint len)
775 for (i = 0; i < len; ++i) {
776 /* equivalent to: dest[i] = src[i << 1] */
785 gst_jpeg_dec_free_buffers (GstJpegDec * dec)
789 for (i = 0; i < 16; i++) {
790 g_free (dec->idr_y[i]);
791 g_free (dec->idr_u[i]);
792 g_free (dec->idr_v[i]);
793 dec->idr_y[i] = NULL;
794 dec->idr_u[i] = NULL;
795 dec->idr_v[i] = NULL;
798 dec->idr_width_allocated = 0;
801 static inline gboolean
802 gst_jpeg_dec_ensure_buffers (GstJpegDec * dec, guint maxrowbytes)
806 if (G_LIKELY (dec->idr_width_allocated >= maxrowbytes))
809 /* FIXME: maybe just alloc one or three blocks altogether? */
810 for (i = 0; i < 16; i++) {
811 dec->idr_y[i] = g_try_realloc (dec->idr_y[i], maxrowbytes);
812 dec->idr_u[i] = g_try_realloc (dec->idr_u[i], maxrowbytes);
813 dec->idr_v[i] = g_try_realloc (dec->idr_v[i], maxrowbytes);
815 if (G_UNLIKELY (!dec->idr_y[i] || !dec->idr_u[i] || !dec->idr_v[i])) {
816 GST_WARNING_OBJECT (dec, "out of memory, i=%d, bytes=%u", i, maxrowbytes);
821 dec->idr_width_allocated = maxrowbytes;
822 GST_LOG_OBJECT (dec, "allocated temp memory, %u bytes/row", maxrowbytes);
827 gst_jpeg_dec_decode_grayscale (GstJpegDec * dec, GstVideoFrame * frame)
830 guchar **scanarray[1] = { rows };
835 gint pstride, rstride;
837 GST_DEBUG_OBJECT (dec, "indirect decoding of grayscale");
839 width = GST_VIDEO_FRAME_WIDTH (frame);
840 height = GST_VIDEO_FRAME_HEIGHT (frame);
842 if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
845 base[0] = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
846 pstride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0);
847 rstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
849 memcpy (rows, dec->idr_y, 16 * sizeof (gpointer));
853 lines = jpeg_read_raw_data (&dec->cinfo, scanarray, DCTSIZE);
854 if (G_LIKELY (lines > 0)) {
855 for (j = 0; (j < DCTSIZE) && (i < height); j++, i++) {
859 for (k = 0; k < width; k++) {
860 base[0][p] = rows[j][k];
866 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
872 gst_jpeg_dec_decode_rgb (GstJpegDec * dec, GstVideoFrame * frame)
874 guchar *r_rows[16], *g_rows[16], *b_rows[16];
875 guchar **scanarray[3] = { r_rows, g_rows, b_rows };
879 guint pstride, rstride;
882 GST_DEBUG_OBJECT (dec, "indirect decoding of RGB");
884 width = GST_VIDEO_FRAME_WIDTH (frame);
885 height = GST_VIDEO_FRAME_HEIGHT (frame);
887 if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
890 for (i = 0; i < 3; i++)
891 base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
893 pstride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0);
894 rstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
896 memcpy (r_rows, dec->idr_y, 16 * sizeof (gpointer));
897 memcpy (g_rows, dec->idr_u, 16 * sizeof (gpointer));
898 memcpy (b_rows, dec->idr_v, 16 * sizeof (gpointer));
902 lines = jpeg_read_raw_data (&dec->cinfo, scanarray, DCTSIZE);
903 if (G_LIKELY (lines > 0)) {
904 for (j = 0; (j < DCTSIZE) && (i < height); j++, i++) {
908 for (k = 0; k < width; k++) {
909 base[0][p] = r_rows[j][k];
910 base[1][p] = g_rows[j][k];
911 base[2][p] = b_rows[j][k];
919 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
925 gst_jpeg_dec_decode_indirect (GstJpegDec * dec, GstVideoFrame * frame,
926 gint r_v, gint r_h, gint comp)
928 guchar *y_rows[16], *u_rows[16], *v_rows[16];
929 guchar **scanarray[3] = { y_rows, u_rows, v_rows };
932 guchar *base[3], *last[3];
936 GST_DEBUG_OBJECT (dec,
937 "unadvantageous width or r_h, taking slow route involving memcpy");
939 width = GST_VIDEO_FRAME_WIDTH (frame);
940 height = GST_VIDEO_FRAME_HEIGHT (frame);
942 if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
945 for (i = 0; i < 3; i++) {
946 base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
947 stride[i] = GST_VIDEO_FRAME_COMP_STRIDE (frame, i);
948 /* make sure we don't make jpeglib write beyond our buffer,
949 * which might happen if (height % (r_v*DCTSIZE)) != 0 */
950 last[i] = base[i] + (GST_VIDEO_FRAME_COMP_STRIDE (frame, i) *
951 (GST_VIDEO_FRAME_COMP_HEIGHT (frame, i) - 1));
954 memcpy (y_rows, dec->idr_y, 16 * sizeof (gpointer));
955 memcpy (u_rows, dec->idr_u, 16 * sizeof (gpointer));
956 memcpy (v_rows, dec->idr_v, 16 * sizeof (gpointer));
958 /* fill chroma components for grayscale */
960 GST_DEBUG_OBJECT (dec, "grayscale, filling chroma");
961 for (i = 0; i < 16; i++) {
962 memset (u_rows[i], GST_ROUND_UP_32 (width), 0x80);
963 memset (v_rows[i], GST_ROUND_UP_32 (width), 0x80);
967 for (i = 0; i < height; i += r_v * DCTSIZE) {
968 lines = jpeg_read_raw_data (&dec->cinfo, scanarray, r_v * DCTSIZE);
969 if (G_LIKELY (lines > 0)) {
970 for (j = 0, k = 0; j < (r_v * DCTSIZE); j += r_v, k++) {
971 if (G_LIKELY (base[0] <= last[0])) {
972 memcpy (base[0], y_rows[j], stride[0]);
973 base[0] += stride[0];
976 if (G_LIKELY (base[0] <= last[0])) {
977 memcpy (base[0], y_rows[j + 1], stride[0]);
978 base[0] += stride[0];
981 if (G_LIKELY (base[1] <= last[1] && base[2] <= last[2])) {
983 memcpy (base[1], u_rows[k], stride[1]);
984 memcpy (base[2], v_rows[k], stride[2]);
985 } else if (r_h == 1) {
986 hresamplecpy1 (base[1], u_rows[k], stride[1]);
987 hresamplecpy1 (base[2], v_rows[k], stride[2]);
989 /* FIXME: implement (at least we avoid crashing by doing nothing) */
993 if (r_v == 2 || (k & 1) != 0) {
994 base[1] += stride[1];
995 base[2] += stride[2];
999 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
1004 static GstFlowReturn
1005 gst_jpeg_dec_decode_direct (GstJpegDec * dec, GstVideoFrame * frame)
1007 guchar **line[3]; /* the jpeg line buffer */
1008 guchar *y[4 * DCTSIZE] = { NULL, }; /* alloc enough for the lines */
1009 guchar *u[4 * DCTSIZE] = { NULL, }; /* r_v will be <4 */
1010 guchar *v[4 * DCTSIZE] = { NULL, };
1012 gint lines, v_samp[3];
1013 guchar *base[3], *last[3];
1021 v_samp[0] = dec->cinfo.comp_info[0].v_samp_factor;
1022 v_samp[1] = dec->cinfo.comp_info[1].v_samp_factor;
1023 v_samp[2] = dec->cinfo.comp_info[2].v_samp_factor;
1025 if (G_UNLIKELY (v_samp[0] > 2 || v_samp[1] > 2 || v_samp[2] > 2))
1026 goto format_not_supported;
1028 height = GST_VIDEO_FRAME_HEIGHT (frame);
1030 for (i = 0; i < 3; i++) {
1031 base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
1032 stride[i] = GST_VIDEO_FRAME_COMP_STRIDE (frame, i);
1033 /* make sure we don't make jpeglib write beyond our buffer,
1034 * which might happen if (height % (r_v*DCTSIZE)) != 0 */
1035 last[i] = base[i] + (GST_VIDEO_FRAME_COMP_STRIDE (frame, i) *
1036 (GST_VIDEO_FRAME_COMP_HEIGHT (frame, i) - 1));
1039 /* let jpeglib decode directly into our final buffer */
1040 GST_DEBUG_OBJECT (dec, "decoding directly into output buffer");
1042 for (i = 0; i < height; i += v_samp[0] * DCTSIZE) {
1043 for (j = 0; j < (v_samp[0] * DCTSIZE); ++j) {
1045 line[0][j] = base[0] + (i + j) * stride[0];
1046 if (G_UNLIKELY (line[0][j] > last[0]))
1047 line[0][j] = last[0];
1049 if (v_samp[1] == v_samp[0]) {
1050 line[1][j] = base[1] + ((i + j) / 2) * stride[1];
1051 } else if (j < (v_samp[1] * DCTSIZE)) {
1052 line[1][j] = base[1] + ((i / 2) + j) * stride[1];
1054 if (G_UNLIKELY (line[1][j] > last[1]))
1055 line[1][j] = last[1];
1057 if (v_samp[2] == v_samp[0]) {
1058 line[2][j] = base[2] + ((i + j) / 2) * stride[2];
1059 } else if (j < (v_samp[2] * DCTSIZE)) {
1060 line[2][j] = base[2] + ((i / 2) + j) * stride[2];
1062 if (G_UNLIKELY (line[2][j] > last[2]))
1063 line[2][j] = last[2];
1066 lines = jpeg_read_raw_data (&dec->cinfo, line, v_samp[0] * DCTSIZE);
1067 if (G_UNLIKELY (!lines)) {
1068 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
1073 format_not_supported:
1075 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1076 "Unsupported subsampling schema: v_samp factors: %u %u %u",
1077 v_samp[0], v_samp[1], v_samp[2]);
1078 return GST_FLOW_ERROR;
1083 gst_jpeg_dec_update_qos (GstJpegDec * dec, gdouble proportion,
1084 GstClockTimeDiff diff, GstClockTime ts)
1086 GST_OBJECT_LOCK (dec);
1087 dec->proportion = proportion;
1088 if (G_LIKELY (ts != GST_CLOCK_TIME_NONE)) {
1089 if (G_UNLIKELY (diff > dec->qos_duration))
1090 dec->earliest_time = ts + 2 * diff + dec->qos_duration;
1092 dec->earliest_time = ts + diff;
1094 dec->earliest_time = GST_CLOCK_TIME_NONE;
1096 GST_OBJECT_UNLOCK (dec);
1100 gst_jpeg_dec_reset_qos (GstJpegDec * dec)
1102 gst_jpeg_dec_update_qos (dec, 0.5, 0, GST_CLOCK_TIME_NONE);
1106 gst_jpeg_dec_read_qos (GstJpegDec * dec, gdouble * proportion,
1107 GstClockTime * time)
1109 GST_OBJECT_LOCK (dec);
1110 *proportion = dec->proportion;
1111 *time = dec->earliest_time;
1112 GST_OBJECT_UNLOCK (dec);
1115 /* Perform qos calculations before decoding the next frame. Returns TRUE if the
1116 * frame should be decoded, FALSE if the frame can be dropped entirely */
1118 gst_jpeg_dec_do_qos (GstJpegDec * dec, GstClockTime timestamp)
1120 GstClockTime qostime, earliest_time;
1123 /* no timestamp, can't do QoS => decode frame */
1124 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (timestamp))) {
1125 GST_LOG_OBJECT (dec, "invalid timestamp, can't do QoS, decode frame");
1129 /* get latest QoS observation values */
1130 gst_jpeg_dec_read_qos (dec, &proportion, &earliest_time);
1132 /* skip qos if we have no observation (yet) => decode frame */
1133 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (earliest_time))) {
1134 GST_LOG_OBJECT (dec, "no observation yet, decode frame");
1138 /* qos is done on running time */
1139 qostime = gst_segment_to_running_time (&dec->segment, GST_FORMAT_TIME,
1142 /* see how our next timestamp relates to the latest qos timestamp */
1143 GST_LOG_OBJECT (dec, "qostime %" GST_TIME_FORMAT ", earliest %"
1144 GST_TIME_FORMAT, GST_TIME_ARGS (qostime), GST_TIME_ARGS (earliest_time));
1146 if (qostime != GST_CLOCK_TIME_NONE && qostime <= earliest_time) {
1147 GST_DEBUG_OBJECT (dec, "we are late, drop frame");
1151 GST_LOG_OBJECT (dec, "decode frame");
1156 gst_jpeg_dec_buffer_pool (GstJpegDec * dec, GstCaps * caps)
1159 GstBufferPool *pool = NULL;
1160 guint size, min, max, prefix, alignment;
1161 GstStructure *config;
1163 GST_DEBUG_OBJECT (dec, "setting up bufferpool");
1165 /* find a pool for the negotiated caps now */
1166 query = gst_query_new_allocation (caps, TRUE);
1168 if (gst_pad_peer_query (dec->srcpad, query)) {
1169 /* we got configuration from our peer, parse them */
1170 gst_query_parse_allocation_params (query, &size, &min, &max, &prefix,
1172 size = MAX (size, dec->info.size);
1174 GST_DEBUG_OBJECT (dec, "peer query failed, using defaults");
1175 size = dec->info.size;
1180 gst_query_unref (query);
1183 /* we did not get a pool, make one ourselves then */
1184 pool = gst_buffer_pool_new ();
1187 config = gst_buffer_pool_get_config (pool);
1188 gst_buffer_pool_config_set (config, caps, size, min, max, prefix,
1191 gst_buffer_pool_set_config (pool, config);
1194 gst_buffer_pool_set_active (dec->pool, FALSE);
1195 gst_object_unref (dec->pool);
1200 gst_buffer_pool_set_active (pool, TRUE);
1206 gst_jpeg_dec_negotiate (GstJpegDec * dec, gint width, gint height, gint clrspc)
1209 GstVideoFormat format;
1212 if (G_UNLIKELY (width == dec->info.width && height == dec->info.height &&
1213 dec->in_fps_n == dec->info.fps_n && dec->in_fps_d == dec->info.fps_d
1214 && clrspc == dec->clrspc))
1217 gst_video_info_init (&info);
1219 /* framerate == 0/1 is a still frame */
1220 if (dec->in_fps_d == 0) {
1224 info.fps_n = dec->in_fps_n;
1225 info.fps_d = dec->in_fps_d;
1228 /* calculate or assume an average frame duration for QoS purposes */
1229 GST_OBJECT_LOCK (dec);
1230 if (info.fps_n != 0) {
1232 gst_util_uint64_scale (GST_SECOND, info.fps_d, info.fps_n);
1233 dec->duration = dec->qos_duration;
1235 /* if not set just use 25fps */
1236 dec->qos_duration = gst_util_uint64_scale (GST_SECOND, 1, 25);
1237 dec->duration = GST_CLOCK_TIME_NONE;
1239 GST_OBJECT_UNLOCK (dec);
1241 if (dec->cinfo.jpeg_color_space == JCS_RGB) {
1243 GstCaps *allowed_caps;
1244 GstVideoInfo tmpinfo;
1246 GST_DEBUG_OBJECT (dec, "selecting RGB format");
1247 /* retrieve allowed caps, and find the first one that reasonably maps
1248 * to the parameters of the colourspace */
1249 caps = gst_pad_get_allowed_caps (dec->srcpad);
1251 GST_DEBUG_OBJECT (dec, "... but no peer, using template caps");
1252 /* need to copy because get_allowed_caps returns a ref,
1253 * and get_pad_template_caps doesn't */
1254 caps = gst_caps_copy (gst_pad_get_pad_template_caps (dec->srcpad));
1256 /* avoid lists of formats, etc */
1257 allowed_caps = gst_caps_normalize (caps);
1258 gst_caps_unref (caps);
1260 GST_LOG_OBJECT (dec, "allowed source caps %" GST_PTR_FORMAT, allowed_caps);
1262 for (i = 0; i < gst_caps_get_size (allowed_caps); i++) {
1264 gst_caps_unref (caps);
1265 caps = gst_caps_copy_nth (allowed_caps, i);
1266 /* sigh, ds and _parse_caps need fixed caps for parsing, fixate */
1267 gst_caps_fixate (caps);
1268 GST_LOG_OBJECT (dec, "checking caps %" GST_PTR_FORMAT, caps);
1270 if (!gst_video_info_from_caps (&tmpinfo, caps))
1272 /* we'll settle for the first (preferred) downstream rgb format */
1273 if (GST_VIDEO_INFO_IS_RGB (&tmpinfo))
1275 /* default fall-back */
1276 format = GST_VIDEO_FORMAT_RGB;
1279 gst_caps_unref (caps);
1280 gst_caps_unref (allowed_caps);
1281 } else if (dec->cinfo.jpeg_color_space == JCS_GRAYSCALE) {
1282 /* TODO is anything else then 8bit supported in jpeg? */
1283 format = GST_VIDEO_FORMAT_GRAY8;
1285 /* go for plain and simple I420 */
1286 /* TODO other YUV cases ? */
1287 format = GST_VIDEO_FORMAT_I420;
1290 gst_video_info_set_format (&info, format, width, height);
1291 caps = gst_video_info_to_caps (&info);
1293 GST_DEBUG_OBJECT (dec, "setting caps %" GST_PTR_FORMAT, caps);
1294 GST_DEBUG_OBJECT (dec, "max_v_samp_factor=%d", dec->cinfo.max_v_samp_factor);
1295 GST_DEBUG_OBJECT (dec, "max_h_samp_factor=%d", dec->cinfo.max_h_samp_factor);
1297 gst_pad_set_caps (dec->srcpad, caps);
1300 dec->clrspc = clrspc;
1302 gst_jpeg_dec_buffer_pool (dec, caps);
1303 gst_caps_unref (caps);
1308 static GstFlowReturn
1309 gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf)
1311 GstFlowReturn ret = GST_FLOW_OK;
1313 GstBuffer *outbuf = NULL;
1318 GstClockTime timestamp, duration;
1319 GstVideoFrame frame;
1321 dec = GST_JPEG_DEC (GST_PAD_PARENT (pad));
1323 timestamp = GST_BUFFER_TIMESTAMP (buf);
1324 duration = GST_BUFFER_DURATION (buf);
1326 if (GST_CLOCK_TIME_IS_VALID (timestamp))
1327 dec->next_ts = timestamp;
1329 if (GST_BUFFER_IS_DISCONT (buf)) {
1330 GST_DEBUG_OBJECT (dec, "buffer has DISCONT flag set");
1331 dec->discont = TRUE;
1332 if (!dec->packetized && gst_adapter_available (dec->adapter)) {
1333 GST_WARNING_OBJECT (dec, "DISCONT buffer in non-packetized mode, bad");
1334 gst_adapter_clear (dec->adapter);
1338 gst_adapter_push (dec->adapter, buf);
1341 /* If we are non-packetized and know the total incoming size in bytes,
1342 * just wait until we have enough before doing any processing. */
1344 if (!dec->packetized && (dec->segment.format == GST_FORMAT_BYTES) &&
1345 (dec->segment.stop != -1) &&
1346 (gst_adapter_available (dec->adapter) < dec->segment.stop)) {
1347 /* We assume that non-packetized input in bytes is *one* single jpeg image */
1348 GST_DEBUG ("Non-packetized mode. Got %d bytes, need %" G_GINT64_FORMAT,
1349 gst_adapter_available (dec->adapter), dec->segment.stop);
1350 goto need_more_data;
1354 if (!gst_jpeg_dec_ensure_header (dec))
1355 goto need_more_data;
1357 /* If we know that each input buffer contains data
1358 * for a whole jpeg image (e.g. MJPEG streams), just
1359 * do some sanity checking instead of parsing all of
1361 if (dec->packetized) {
1362 img_len = gst_adapter_available (dec->adapter);
1364 /* Parse jpeg image to handle jpeg input that
1365 * is not aligned to buffer boundaries */
1366 img_len = gst_jpeg_dec_parse_image_data (dec);
1369 goto need_more_data;
1370 } else if (img_len < 0) {
1371 gst_adapter_flush (dec->adapter, -img_len);
1376 dec->rem_img_len = img_len;
1378 GST_LOG_OBJECT (dec, "image size = %u", img_len);
1380 /* QoS: if we're too late anyway, skip decoding */
1381 if (dec->packetized && !gst_jpeg_dec_do_qos (dec, timestamp))
1384 #ifndef GST_DISABLE_GST_DEBUG
1388 gst_adapter_copy (dec->adapter, data, 0, 4);
1389 GST_LOG_OBJECT (dec, "reading header %02x %02x %02x %02x", data[0], data[1],
1394 gst_jpeg_dec_fill_input_buffer (&dec->cinfo);
1396 if (setjmp (dec->jerr.setjmp_buffer)) {
1397 code = dec->jerr.pub.msg_code;
1399 if (code == JERR_INPUT_EOF) {
1400 GST_DEBUG ("jpeg input EOF error, we probably need more data");
1401 goto need_more_data;
1407 hdr_ok = jpeg_read_header (&dec->cinfo, TRUE);
1408 if (G_UNLIKELY (hdr_ok != JPEG_HEADER_OK)) {
1409 GST_WARNING_OBJECT (dec, "reading the header failed, %d", hdr_ok);
1412 GST_LOG_OBJECT (dec, "num_components=%d", dec->cinfo.num_components);
1413 GST_LOG_OBJECT (dec, "jpeg_color_space=%d", dec->cinfo.jpeg_color_space);
1415 if (!dec->cinfo.num_components || !dec->cinfo.comp_info)
1416 goto components_not_supported;
1418 r_h = dec->cinfo.comp_info[0].h_samp_factor;
1419 r_v = dec->cinfo.comp_info[0].v_samp_factor;
1421 GST_LOG_OBJECT (dec, "r_h = %d, r_v = %d", r_h, r_v);
1423 if (dec->cinfo.num_components > 3)
1424 goto components_not_supported;
1426 /* verify color space expectation to avoid going *boom* or bogus output */
1427 if (dec->cinfo.jpeg_color_space != JCS_YCbCr &&
1428 dec->cinfo.jpeg_color_space != JCS_GRAYSCALE &&
1429 dec->cinfo.jpeg_color_space != JCS_RGB)
1430 goto unsupported_colorspace;
1432 #ifndef GST_DISABLE_GST_DEBUG
1436 for (i = 0; i < dec->cinfo.num_components; ++i) {
1437 GST_LOG_OBJECT (dec, "[%d] h_samp_factor=%d, v_samp_factor=%d, cid=%d",
1438 i, dec->cinfo.comp_info[i].h_samp_factor,
1439 dec->cinfo.comp_info[i].v_samp_factor,
1440 dec->cinfo.comp_info[i].component_id);
1445 /* prepare for raw output */
1446 dec->cinfo.do_fancy_upsampling = FALSE;
1447 dec->cinfo.do_block_smoothing = FALSE;
1448 dec->cinfo.out_color_space = dec->cinfo.jpeg_color_space;
1449 dec->cinfo.dct_method = dec->idct_method;
1450 dec->cinfo.raw_data_out = TRUE;
1452 GST_LOG_OBJECT (dec, "starting decompress");
1453 guarantee_huff_tables (&dec->cinfo);
1454 if (!jpeg_start_decompress (&dec->cinfo)) {
1455 GST_WARNING_OBJECT (dec, "failed to start decompression cycle");
1458 /* sanity checks to get safe and reasonable output */
1459 switch (dec->cinfo.jpeg_color_space) {
1461 if (dec->cinfo.num_components != 1)
1462 goto invalid_yuvrgbgrayscale;
1465 if (dec->cinfo.num_components != 3 || dec->cinfo.max_v_samp_factor > 1 ||
1466 dec->cinfo.max_h_samp_factor > 1)
1467 goto invalid_yuvrgbgrayscale;
1470 if (dec->cinfo.num_components != 3 ||
1471 r_v > 2 || r_v < dec->cinfo.comp_info[0].v_samp_factor ||
1472 r_v < dec->cinfo.comp_info[1].v_samp_factor ||
1473 r_h < dec->cinfo.comp_info[0].h_samp_factor ||
1474 r_h < dec->cinfo.comp_info[1].h_samp_factor)
1475 goto invalid_yuvrgbgrayscale;
1478 g_assert_not_reached ();
1482 width = dec->cinfo.output_width;
1483 height = dec->cinfo.output_height;
1485 if (G_UNLIKELY (width < MIN_WIDTH || width > MAX_WIDTH ||
1486 height < MIN_HEIGHT || height > MAX_HEIGHT))
1489 gst_jpeg_dec_negotiate (dec, width, height, dec->cinfo.jpeg_color_space);
1491 ret = gst_buffer_pool_acquire_buffer (dec->pool, &outbuf, NULL);
1492 if (G_UNLIKELY (ret != GST_FLOW_OK))
1495 if (!gst_video_frame_map (&frame, &dec->info, outbuf, GST_MAP_READWRITE))
1498 GST_LOG_OBJECT (dec, "width %d, height %d", width, height);
1500 GST_BUFFER_TIMESTAMP (outbuf) = dec->next_ts;
1502 if (dec->packetized && GST_CLOCK_TIME_IS_VALID (dec->next_ts)) {
1503 if (GST_CLOCK_TIME_IS_VALID (duration)) {
1504 /* use duration from incoming buffer for outgoing buffer */
1505 dec->next_ts += duration;
1506 } else if (GST_CLOCK_TIME_IS_VALID (dec->duration)) {
1507 duration = dec->duration;
1508 dec->next_ts += dec->duration;
1510 duration = GST_CLOCK_TIME_NONE;
1511 dec->next_ts = GST_CLOCK_TIME_NONE;
1514 duration = GST_CLOCK_TIME_NONE;
1515 dec->next_ts = GST_CLOCK_TIME_NONE;
1517 GST_BUFFER_DURATION (outbuf) = duration;
1519 if (dec->cinfo.jpeg_color_space == JCS_RGB) {
1520 gst_jpeg_dec_decode_rgb (dec, &frame);
1521 } else if (dec->cinfo.jpeg_color_space == JCS_GRAYSCALE) {
1522 gst_jpeg_dec_decode_grayscale (dec, &frame);
1524 GST_LOG_OBJECT (dec, "decompressing (reqired scanline buffer height = %u)",
1525 dec->cinfo.rec_outbuf_height);
1527 /* For some widths jpeglib requires more horizontal padding than I420
1528 * provides. In those cases we need to decode into separate buffers and then
1529 * copy over the data into our final picture buffer, otherwise jpeglib might
1530 * write over the end of a line into the beginning of the next line,
1531 * resulting in blocky artifacts on the left side of the picture. */
1532 if (G_UNLIKELY (width % (dec->cinfo.max_h_samp_factor * DCTSIZE) != 0
1533 || dec->cinfo.comp_info[0].h_samp_factor != 2
1534 || dec->cinfo.comp_info[1].h_samp_factor != 1
1535 || dec->cinfo.comp_info[2].h_samp_factor != 1)) {
1536 GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, dec,
1537 "indirect decoding using extra buffer copy");
1538 gst_jpeg_dec_decode_indirect (dec, &frame, r_v, r_h,
1539 dec->cinfo.num_components);
1541 ret = gst_jpeg_dec_decode_direct (dec, &frame);
1542 if (G_UNLIKELY (ret != GST_FLOW_OK))
1543 goto decode_direct_failed;
1547 GST_LOG_OBJECT (dec, "decompressing finished");
1548 jpeg_finish_decompress (&dec->cinfo);
1550 gst_video_frame_unmap (&frame);
1553 if (dec->segment.format == GST_FORMAT_TIME) {
1554 guint64 start, stop, clip_start, clip_stop;
1556 GST_LOG_OBJECT (dec, "Attempting clipping");
1558 start = GST_BUFFER_TIMESTAMP (outbuf);
1559 if (GST_BUFFER_DURATION (outbuf) == GST_CLOCK_TIME_NONE)
1562 stop = start + GST_BUFFER_DURATION (outbuf);
1564 if (gst_segment_clip (&dec->segment, GST_FORMAT_TIME,
1565 start, stop, &clip_start, &clip_stop)) {
1566 GST_LOG_OBJECT (dec, "Clipping start to %" GST_TIME_FORMAT,
1567 GST_TIME_ARGS (clip_start));
1568 GST_BUFFER_TIMESTAMP (outbuf) = clip_start;
1569 if (GST_BUFFER_DURATION (outbuf) != GST_CLOCK_TIME_NONE) {
1570 GST_LOG_OBJECT (dec, "Clipping duration to %" GST_TIME_FORMAT,
1571 GST_TIME_ARGS (clip_stop - clip_start));
1572 GST_BUFFER_DURATION (outbuf) = clip_stop - clip_start;
1578 /* reset error count on successful decode */
1579 dec->error_count = 0;
1583 GST_LOG_OBJECT (dec, "pushing buffer (ts=%" GST_TIME_FORMAT ", dur=%"
1584 GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
1585 GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
1587 ret = gst_pad_push (dec->srcpad, outbuf);
1591 gst_adapter_flush (dec->adapter, dec->rem_img_len);
1595 if (G_UNLIKELY (ret == GST_FLOW_ERROR)) {
1596 jpeg_abort_decompress (&dec->cinfo);
1597 ret = gst_jpeg_dec_post_error_or_warning (dec);
1605 GST_LOG_OBJECT (dec, "we need more data");
1607 gst_buffer_unref (outbuf);
1616 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1617 "Picture is too small or too big (%ux%u)", width, height);
1618 ret = GST_FLOW_ERROR;
1623 gchar err_msg[JMSG_LENGTH_MAX];
1625 dec->jerr.pub.format_message ((j_common_ptr) (&dec->cinfo), err_msg);
1627 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1628 "Decode error #%u: %s", code, err_msg);
1631 gst_buffer_unref (outbuf);
1634 ret = GST_FLOW_ERROR;
1637 decode_direct_failed:
1639 /* already posted an error message */
1640 jpeg_abort_decompress (&dec->cinfo);
1641 gst_buffer_replace (&outbuf, NULL);
1646 const gchar *reason;
1648 reason = gst_flow_get_name (ret);
1650 GST_DEBUG_OBJECT (dec, "failed to alloc buffer, reason %s", reason);
1651 /* Reset for next time */
1652 jpeg_abort_decompress (&dec->cinfo);
1653 if (ret != GST_FLOW_UNEXPECTED && ret != GST_FLOW_WRONG_STATE &&
1654 ret != GST_FLOW_NOT_LINKED) {
1655 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1656 "Buffer allocation failed, reason: %s", reason);
1662 jpeg_abort_decompress (&dec->cinfo);
1663 gst_buffer_unref (outbuf);
1669 GST_WARNING_OBJECT (dec, "Outgoing buffer is outside configured segment");
1670 gst_buffer_unref (outbuf);
1674 components_not_supported:
1676 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1677 "number of components not supported: %d (max 3)",
1678 dec->cinfo.num_components);
1679 ret = GST_FLOW_ERROR;
1682 unsupported_colorspace:
1684 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1685 "Picture has unknown or unsupported colourspace");
1686 ret = GST_FLOW_ERROR;
1689 invalid_yuvrgbgrayscale:
1691 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1692 "Picture is corrupt or unhandled YUV/RGB/grayscale layout");
1693 ret = GST_FLOW_ERROR;
1699 gst_jpeg_dec_src_event (GstPad * pad, GstEvent * event)
1704 dec = GST_JPEG_DEC (gst_pad_get_parent (pad));
1705 if (G_UNLIKELY (dec == NULL)) {
1706 gst_event_unref (event);
1710 switch (GST_EVENT_TYPE (event)) {
1711 case GST_EVENT_QOS:{
1713 GstClockTimeDiff diff;
1714 GstClockTime timestamp;
1717 gst_event_parse_qos (event, &type, &proportion, &diff, ×tamp);
1718 gst_jpeg_dec_update_qos (dec, proportion, diff, timestamp);
1725 res = gst_pad_push_event (dec->sinkpad, event);
1727 gst_object_unref (dec);
1732 gst_jpeg_dec_sink_event (GstPad * pad, GstEvent * event)
1734 gboolean ret = TRUE, forward = TRUE;
1735 GstJpegDec *dec = GST_JPEG_DEC (GST_OBJECT_PARENT (pad));
1737 GST_DEBUG_OBJECT (dec, "event : %s", GST_EVENT_TYPE_NAME (event));
1739 switch (GST_EVENT_TYPE (event)) {
1740 case GST_EVENT_FLUSH_STOP:
1741 GST_DEBUG_OBJECT (dec, "Aborting decompress");
1742 jpeg_abort_decompress (&dec->cinfo);
1743 gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED);
1744 gst_adapter_clear (dec->adapter);
1745 g_free (dec->cur_buf);
1746 dec->cur_buf = NULL;
1747 dec->parse_offset = 0;
1748 dec->parse_entropy_len = 0;
1749 dec->parse_resync = FALSE;
1750 gst_jpeg_dec_reset_qos (dec);
1752 case GST_EVENT_SEGMENT:
1753 gst_event_copy_segment (event, &dec->segment);
1754 GST_DEBUG_OBJECT (dec, "Got NEWSEGMENT %" GST_SEGMENT_FORMAT,
1757 case GST_EVENT_CAPS:
1761 gst_event_parse_caps (event, &caps);
1762 ret = gst_jpeg_dec_setcaps (dec, caps);
1771 ret = gst_pad_push_event (dec->srcpad, event);
1773 gst_event_unref (event);
1779 gst_jpeg_dec_set_property (GObject * object, guint prop_id,
1780 const GValue * value, GParamSpec * pspec)
1784 dec = GST_JPEG_DEC (object);
1787 case PROP_IDCT_METHOD:
1788 dec->idct_method = g_value_get_enum (value);
1790 case PROP_MAX_ERRORS:
1791 g_atomic_int_set (&dec->max_errors, g_value_get_int (value));
1795 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1801 gst_jpeg_dec_get_property (GObject * object, guint prop_id, GValue * value,
1806 dec = GST_JPEG_DEC (object);
1809 case PROP_IDCT_METHOD:
1810 g_value_set_enum (value, dec->idct_method);
1812 case PROP_MAX_ERRORS:
1813 g_value_set_int (value, g_atomic_int_get (&dec->max_errors));
1817 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1822 static GstStateChangeReturn
1823 gst_jpeg_dec_change_state (GstElement * element, GstStateChange transition)
1825 GstStateChangeReturn ret;
1828 dec = GST_JPEG_DEC (element);
1830 switch (transition) {
1831 case GST_STATE_CHANGE_READY_TO_PAUSED:
1832 dec->error_count = 0;
1833 dec->good_count = 0;
1836 gst_video_info_init (&dec->info);
1838 dec->packetized = FALSE;
1840 dec->discont = TRUE;
1841 dec->parse_offset = 0;
1842 dec->parse_entropy_len = 0;
1843 dec->parse_resync = FALSE;
1844 dec->cur_buf = NULL;
1845 gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED);
1846 gst_jpeg_dec_reset_qos (dec);
1851 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1852 if (ret != GST_STATE_CHANGE_SUCCESS)
1855 switch (transition) {
1856 case GST_STATE_CHANGE_PAUSED_TO_READY:
1857 gst_adapter_clear (dec->adapter);
1858 g_free (dec->cur_buf);
1859 dec->cur_buf = NULL;
1860 gst_jpeg_dec_free_buffers (dec);
1862 gst_buffer_pool_set_active (dec->pool, FALSE);
1863 gst_object_unref (dec->pool);