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_query (GstPad * pad, GstObject * parent,
100 static gboolean gst_jpeg_dec_sink_event (GstPad * pad, GstEvent * event);
101 static gboolean gst_jpeg_dec_src_event (GstPad * pad, GstEvent * event);
102 static GstStateChangeReturn gst_jpeg_dec_change_state (GstElement * element,
103 GstStateChange transition);
104 static void gst_jpeg_dec_update_qos (GstJpegDec * dec, gdouble proportion,
105 GstClockTimeDiff diff, GstClockTime ts);
106 static void gst_jpeg_dec_reset_qos (GstJpegDec * dec);
107 static void gst_jpeg_dec_read_qos (GstJpegDec * dec, gdouble * proportion,
108 GstClockTime * time);
110 #define gst_jpeg_dec_parent_class parent_class
111 G_DEFINE_TYPE (GstJpegDec, gst_jpeg_dec, GST_TYPE_ELEMENT);
114 gst_jpeg_dec_finalize (GObject * object)
116 GstJpegDec *dec = GST_JPEG_DEC (object);
118 jpeg_destroy_decompress (&dec->cinfo);
120 g_object_unref (dec->adapter);
122 G_OBJECT_CLASS (parent_class)->finalize (object);
126 gst_jpeg_dec_class_init (GstJpegDecClass * klass)
128 GstElementClass *gstelement_class;
129 GObjectClass *gobject_class;
131 gstelement_class = (GstElementClass *) klass;
132 gobject_class = (GObjectClass *) klass;
134 parent_class = g_type_class_peek_parent (klass);
136 gobject_class->finalize = gst_jpeg_dec_finalize;
137 gobject_class->set_property = gst_jpeg_dec_set_property;
138 gobject_class->get_property = gst_jpeg_dec_get_property;
140 g_object_class_install_property (gobject_class, PROP_IDCT_METHOD,
141 g_param_spec_enum ("idct-method", "IDCT Method",
142 "The IDCT algorithm to use", GST_TYPE_IDCT_METHOD,
143 JPEG_DEFAULT_IDCT_METHOD,
144 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
147 * GstJpegDec:max-errors
149 * Error out after receiving N consecutive decoding errors
150 * (-1 = never error out, 0 = automatic, 1 = fail on first error, etc.)
154 g_object_class_install_property (gobject_class, PROP_MAX_ERRORS,
155 g_param_spec_int ("max-errors", "Maximum Consecutive Decoding Errors",
156 "Error out after receiving N consecutive decoding errors "
157 "(-1 = never fail, 0 = automatic, 1 = fail on first error)",
158 -1, G_MAXINT, JPEG_DEFAULT_MAX_ERRORS,
159 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
161 gst_element_class_add_pad_template (gstelement_class,
162 gst_static_pad_template_get (&gst_jpeg_dec_src_pad_template));
163 gst_element_class_add_pad_template (gstelement_class,
164 gst_static_pad_template_get (&gst_jpeg_dec_sink_pad_template));
165 gst_element_class_set_details_simple (gstelement_class, "JPEG image decoder",
166 "Codec/Decoder/Image",
167 "Decode images from JPEG format", "Wim Taymans <wim@fluendo.com>");
169 gstelement_class->change_state =
170 GST_DEBUG_FUNCPTR (gst_jpeg_dec_change_state);
172 GST_DEBUG_CATEGORY_INIT (jpeg_dec_debug, "jpegdec", 0, "JPEG decoder");
173 GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE");
177 gst_jpeg_dec_clear_error (GstJpegDec * dec)
179 g_free (dec->error_msg);
180 dec->error_msg = NULL;
182 dec->error_func = NULL;
186 gst_jpeg_dec_set_error_va (GstJpegDec * dec, const gchar * func, gint line,
187 const gchar * debug_msg_format, va_list args)
189 #ifndef GST_DISABLE_GST_DEBUG
190 gst_debug_log_valist (GST_CAT_DEFAULT, GST_LEVEL_WARNING, __FILE__, func,
191 line, (GObject *) dec, debug_msg_format, args);
194 g_free (dec->error_msg);
195 if (debug_msg_format)
196 dec->error_msg = g_strdup_vprintf (debug_msg_format, args);
198 dec->error_msg = NULL;
200 dec->error_line = line;
201 dec->error_func = func;
205 gst_jpeg_dec_set_error (GstJpegDec * dec, const gchar * func, gint line,
206 const gchar * debug_msg_format, ...)
210 va_start (va, debug_msg_format);
211 gst_jpeg_dec_set_error_va (dec, func, line, debug_msg_format, va);
216 gst_jpeg_dec_post_error_or_warning (GstJpegDec * dec)
222 max_errors = g_atomic_int_get (&dec->max_errors);
224 if (max_errors < 0) {
226 } else if (max_errors == 0) {
227 /* FIXME: do something more clever in "automatic mode" */
228 if (dec->packetized) {
229 ret = (dec->error_count < 3) ? GST_FLOW_OK : GST_FLOW_ERROR;
231 ret = GST_FLOW_ERROR;
234 ret = (dec->error_count < max_errors) ? GST_FLOW_OK : GST_FLOW_ERROR;
237 GST_INFO_OBJECT (dec, "decoding error %d/%d (%s)", dec->error_count,
238 max_errors, (ret == GST_FLOW_OK) ? "ignoring error" : "erroring out");
240 gst_element_message_full (GST_ELEMENT (dec),
241 (ret == GST_FLOW_OK) ? GST_MESSAGE_WARNING : GST_MESSAGE_ERROR,
242 GST_STREAM_ERROR, GST_STREAM_ERROR_DECODE,
243 g_strdup (_("Failed to decode JPEG image")), dec->error_msg,
244 __FILE__, dec->error_func, dec->error_line);
246 dec->error_msg = NULL;
247 gst_jpeg_dec_clear_error (dec);
252 gst_jpeg_dec_fill_input_buffer (j_decompress_ptr cinfo)
257 dec = CINFO_GET_JPEGDEC (cinfo);
258 g_return_val_if_fail (dec != NULL, FALSE);
260 av = gst_adapter_available_fast (dec->adapter);
261 GST_DEBUG_OBJECT (dec, "fill_input_buffer: fast av=%u, remaining=%u", av,
265 GST_DEBUG_OBJECT (dec, "Out of data");
269 if (dec->rem_img_len < av)
270 av = dec->rem_img_len;
271 dec->rem_img_len -= av;
273 g_free (dec->cur_buf);
274 dec->cur_buf = gst_adapter_take (dec->adapter, av);
276 cinfo->src->next_input_byte = dec->cur_buf;
277 cinfo->src->bytes_in_buffer = av;
283 gst_jpeg_dec_init_source (j_decompress_ptr cinfo)
285 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "init_source");
290 gst_jpeg_dec_skip_input_data (j_decompress_ptr cinfo, glong num_bytes)
292 GstJpegDec *dec = CINFO_GET_JPEGDEC (cinfo);
294 GST_DEBUG_OBJECT (dec, "skip %ld bytes", num_bytes);
296 if (num_bytes > 0 && cinfo->src->bytes_in_buffer >= num_bytes) {
297 cinfo->src->next_input_byte += (size_t) num_bytes;
298 cinfo->src->bytes_in_buffer -= (size_t) num_bytes;
299 } else if (num_bytes > 0) {
302 num_bytes -= cinfo->src->bytes_in_buffer;
303 cinfo->src->next_input_byte += (size_t) cinfo->src->bytes_in_buffer;
304 cinfo->src->bytes_in_buffer = 0;
306 available = gst_adapter_available (dec->adapter);
307 if (available < num_bytes || available < dec->rem_img_len) {
308 GST_WARNING_OBJECT (dec, "Less bytes to skip than available in the "
309 "adapter or the remaining image length %ld < %d or %u",
310 num_bytes, available, dec->rem_img_len);
312 num_bytes = MIN (MIN (num_bytes, available), dec->rem_img_len);
313 gst_adapter_flush (dec->adapter, num_bytes);
314 dec->rem_img_len -= num_bytes;
319 gst_jpeg_dec_resync_to_restart (j_decompress_ptr cinfo, gint desired)
321 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "resync_to_start");
326 gst_jpeg_dec_term_source (j_decompress_ptr cinfo)
328 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "term_source");
333 gst_jpeg_dec_my_output_message (j_common_ptr cinfo)
335 return; /* do nothing */
339 gst_jpeg_dec_my_emit_message (j_common_ptr cinfo, int msg_level)
341 /* GST_LOG_OBJECT (CINFO_GET_JPEGDEC (&cinfo), "msg_level=%d", msg_level); */
346 gst_jpeg_dec_my_error_exit (j_common_ptr cinfo)
348 struct GstJpegDecErrorMgr *err_mgr = (struct GstJpegDecErrorMgr *) cinfo->err;
350 (*cinfo->err->output_message) (cinfo);
351 longjmp (err_mgr->setjmp_buffer, 1);
355 gst_jpeg_dec_init (GstJpegDec * dec)
357 GST_DEBUG ("initializing");
359 /* create the sink and src pads */
361 gst_pad_new_from_static_template (&gst_jpeg_dec_sink_pad_template,
363 gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
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));
368 gst_pad_set_query_function (dec->sinkpad,
369 GST_DEBUG_FUNCPTR (gst_jpeg_dec_sink_query));
372 gst_pad_new_from_static_template (&gst_jpeg_dec_src_pad_template, "src");
373 gst_pad_set_event_function (dec->srcpad,
374 GST_DEBUG_FUNCPTR (gst_jpeg_dec_src_event));
375 gst_pad_use_fixed_caps (dec->srcpad);
376 gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
379 memset (&dec->cinfo, 0, sizeof (dec->cinfo));
380 memset (&dec->jerr, 0, sizeof (dec->jerr));
381 dec->cinfo.err = jpeg_std_error (&dec->jerr.pub);
382 dec->jerr.pub.output_message = gst_jpeg_dec_my_output_message;
383 dec->jerr.pub.emit_message = gst_jpeg_dec_my_emit_message;
384 dec->jerr.pub.error_exit = gst_jpeg_dec_my_error_exit;
386 jpeg_create_decompress (&dec->cinfo);
388 dec->cinfo.src = (struct jpeg_source_mgr *) &dec->jsrc;
389 dec->cinfo.src->init_source = gst_jpeg_dec_init_source;
390 dec->cinfo.src->fill_input_buffer = gst_jpeg_dec_fill_input_buffer;
391 dec->cinfo.src->skip_input_data = gst_jpeg_dec_skip_input_data;
392 dec->cinfo.src->resync_to_restart = gst_jpeg_dec_resync_to_restart;
393 dec->cinfo.src->term_source = gst_jpeg_dec_term_source;
396 /* init properties */
397 dec->idct_method = JPEG_DEFAULT_IDCT_METHOD;
398 dec->max_errors = JPEG_DEFAULT_MAX_ERRORS;
400 dec->adapter = gst_adapter_new ();
404 gst_jpeg_dec_ensure_header (GstJpegDec * dec)
409 av = gst_adapter_available (dec->adapter);
410 /* we expect at least 4 bytes, first of which start marker */
411 offset = gst_adapter_masked_scan_uint32 (dec->adapter, 0xffffff00, 0xffd8ff00,
413 if (G_UNLIKELY (offset < 0)) {
414 GST_DEBUG_OBJECT (dec, "No JPEG header in current buffer");
417 gst_adapter_flush (dec->adapter, av - 4);
422 GST_LOG_OBJECT (dec, "Skipping %u bytes.", offset);
423 gst_adapter_flush (dec->adapter, offset);
425 GST_DEBUG_OBJECT (dec, "Found JPEG header");
430 static inline gboolean
431 gst_jpeg_dec_parse_tag_has_entropy_segment (guint8 tag)
433 if (tag == 0xda || (tag >= 0xd0 && tag <= 0xd7))
438 /* returns image length in bytes if parsed successfully,
439 * otherwise 0 if more data needed,
440 * if < 0 the absolute value needs to be flushed */
442 gst_jpeg_dec_parse_image_data (GstJpegDec * dec)
446 GstAdapter *adapter = dec->adapter;
447 gint offset, noffset;
449 size = gst_adapter_available (adapter);
451 /* we expect at least 4 bytes, first of which start marker */
452 if (gst_adapter_masked_scan_uint32 (adapter, 0xffff0000, 0xffd80000, 0, 4))
455 GST_DEBUG ("Parsing jpeg image data (%u bytes)", size);
457 GST_DEBUG ("Parse state: offset=%d, resync=%d, entropy len=%d",
458 dec->parse_offset, dec->parse_resync, dec->parse_entropy_len);
460 /* offset is 2 less than actual offset;
461 * - adapter needs at least 4 bytes for scanning,
462 * - start and end marker ensure at least that much
464 /* resume from state offset */
465 offset = dec->parse_offset;
472 gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00, 0x0000ff00,
473 offset, size - offset, &value);
474 /* lost sync if 0xff marker not where expected */
475 if ((resync = (noffset != offset))) {
476 GST_DEBUG ("Lost sync at 0x%08x, resyncing", offset + 2);
478 /* may have marker, but could have been resyncng */
479 resync = resync || dec->parse_resync;
480 /* Skip over extra 0xff */
481 while ((noffset >= 0) && ((value & 0xff) == 0xff)) {
484 gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00, 0x0000ff00,
485 noffset, size - noffset, &value);
487 /* enough bytes left for marker? (we need 0xNN after the 0xff) */
489 GST_DEBUG ("at end of input and no EOI marker found, need more data");
493 /* now lock on the marker we found */
495 value = value & 0xff;
497 GST_DEBUG ("0x%08x: EOI marker", offset + 2);
498 /* clear parse state */
499 dec->parse_resync = FALSE;
500 dec->parse_offset = 0;
502 } else if (value == 0xd8) {
503 /* Skip this frame if we found another SOI marker */
504 GST_DEBUG ("0x%08x: SOI marker before EOI, skipping", offset + 2);
505 dec->parse_resync = FALSE;
506 dec->parse_offset = 0;
507 return -(offset + 2);
511 if (value >= 0xd0 && value <= 0xd7)
514 /* peek tag and subsequent length */
515 if (offset + 2 + 4 > size)
518 gst_adapter_masked_scan_uint32_peek (adapter, 0x0, 0x0, offset + 2, 4,
520 frame_len = frame_len & 0xffff;
522 GST_DEBUG ("0x%08x: tag %02x, frame_len=%u", offset + 2, value, frame_len);
523 /* the frame length includes the 2 bytes for the length; here we want at
524 * least 2 more bytes at the end for an end marker */
525 if (offset + 2 + 2 + frame_len + 2 > size) {
529 if (gst_jpeg_dec_parse_tag_has_entropy_segment (value)) {
530 guint eseglen = dec->parse_entropy_len;
532 GST_DEBUG ("0x%08x: finding entropy segment length", offset + 2);
533 noffset = offset + 2 + frame_len + dec->parse_entropy_len;
535 noffset = gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00,
536 0x0000ff00, noffset, size - noffset, &value);
539 dec->parse_entropy_len = size - offset - 4 - frame_len - 2;
542 if ((value & 0xff) != 0x00) {
543 eseglen = noffset - offset - frame_len - 2;
548 dec->parse_entropy_len = 0;
549 frame_len += eseglen;
550 GST_DEBUG ("entropy segment length=%u => frame_len=%u", eseglen,
554 /* check if we will still be in sync if we interpret
555 * this as a sync point and skip this frame */
556 noffset = offset + frame_len + 2;
557 noffset = gst_adapter_masked_scan_uint32 (adapter, 0x0000ff00, 0x0000ff00,
560 /* ignore and continue resyncing until we hit the end
561 * of our data or find a sync point that looks okay */
565 GST_DEBUG ("found sync at 0x%x", offset + 2);
568 offset += frame_len + 2;
574 dec->parse_offset = offset;
575 dec->parse_resync = resync;
580 /* shamelessly ripped from jpegutils.c in mjpegtools */
582 add_huff_table (j_decompress_ptr dinfo,
583 JHUFF_TBL ** htblptr, const UINT8 * bits, const UINT8 * val)
584 /* Define a Huffman table */
588 if (*htblptr == NULL)
589 *htblptr = jpeg_alloc_huff_table ((j_common_ptr) dinfo);
593 /* Copy the number-of-symbols-of-each-code-length counts */
594 memcpy ((*htblptr)->bits, bits, sizeof ((*htblptr)->bits));
596 /* Validate the counts. We do this here mainly so we can copy the right
597 * number of symbols from the val[] array, without risking marching off
598 * the end of memory. jchuff.c will do a more thorough test later.
601 for (len = 1; len <= 16; len++)
602 nsymbols += bits[len];
603 if (nsymbols < 1 || nsymbols > 256)
604 g_error ("jpegutils.c: add_huff_table failed badly. ");
606 memcpy ((*htblptr)->huffval, val, nsymbols * sizeof (UINT8));
612 std_huff_tables (j_decompress_ptr dinfo)
613 /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
614 /* IMPORTANT: these are only valid for 8-bit data precision! */
616 static const UINT8 bits_dc_luminance[17] =
617 { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
618 static const UINT8 val_dc_luminance[] =
619 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
621 static const UINT8 bits_dc_chrominance[17] =
622 { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
623 static const UINT8 val_dc_chrominance[] =
624 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
626 static const UINT8 bits_ac_luminance[17] =
627 { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
628 static const UINT8 val_ac_luminance[] =
629 { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
630 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
631 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
632 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
633 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
634 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
635 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
636 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
637 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
638 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
639 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
640 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
641 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
642 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
643 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
644 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
645 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
646 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
647 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
648 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
652 static const UINT8 bits_ac_chrominance[17] =
653 { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
654 static const UINT8 val_ac_chrominance[] =
655 { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
656 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
657 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
658 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
659 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
660 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
661 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
662 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
663 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
664 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
665 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
666 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
667 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
668 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
669 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
670 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
671 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
672 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
673 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
674 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
678 add_huff_table (dinfo, &dinfo->dc_huff_tbl_ptrs[0],
679 bits_dc_luminance, val_dc_luminance);
680 add_huff_table (dinfo, &dinfo->ac_huff_tbl_ptrs[0],
681 bits_ac_luminance, val_ac_luminance);
682 add_huff_table (dinfo, &dinfo->dc_huff_tbl_ptrs[1],
683 bits_dc_chrominance, val_dc_chrominance);
684 add_huff_table (dinfo, &dinfo->ac_huff_tbl_ptrs[1],
685 bits_ac_chrominance, val_ac_chrominance);
691 guarantee_huff_tables (j_decompress_ptr dinfo)
693 if ((dinfo->dc_huff_tbl_ptrs[0] == NULL) &&
694 (dinfo->dc_huff_tbl_ptrs[1] == NULL) &&
695 (dinfo->ac_huff_tbl_ptrs[0] == NULL) &&
696 (dinfo->ac_huff_tbl_ptrs[1] == NULL)) {
697 GST_DEBUG ("Generating standard Huffman tables for this frame.");
698 std_huff_tables (dinfo);
703 gst_jpeg_dec_setcaps (GstJpegDec * dec, GstCaps * caps)
706 const GValue *framerate;
708 s = gst_caps_get_structure (caps, 0);
710 if ((framerate = gst_structure_get_value (s, "framerate")) != NULL) {
711 dec->in_fps_n = gst_value_get_fraction_numerator (framerate);
712 dec->in_fps_d = gst_value_get_fraction_denominator (framerate);
713 dec->packetized = TRUE;
714 GST_DEBUG ("got framerate of %d/%d fps => packetized mode",
715 dec->in_fps_n, dec->in_fps_d);
718 /* do not extract width/height here. we do that in the chain
719 * function on a per-frame basis (including the line[] array
722 /* But we can take the framerate values and set them on the src pad */
728 gst_jpeg_dec_getcaps (GstPad * pad, GstCaps * filter)
734 dec = GST_JPEG_DEC (GST_OBJECT_PARENT (pad));
736 if (gst_pad_has_current_caps (pad))
737 return gst_pad_get_current_caps (pad);
739 peer = gst_pad_get_peer (dec->srcpad);
743 const GstCaps *templ_caps;
747 peer_caps = gst_pad_query_caps (peer, filter);
749 /* Translate peercaps to image/jpeg */
750 peer_caps = gst_caps_make_writable (peer_caps);
751 n = gst_caps_get_size (peer_caps);
752 for (i = 0; i < n; i++) {
753 s = gst_caps_get_structure (peer_caps, i);
755 gst_structure_set_name (s, "image/jpeg");
758 templ_caps = gst_pad_get_pad_template_caps (pad);
759 caps = gst_caps_intersect_full (peer_caps, templ_caps,
760 GST_CAPS_INTERSECT_FIRST);
762 gst_object_unref (peer);
764 caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
773 hresamplecpy1 (guint8 * dest, const guint8 * src, guint len)
777 for (i = 0; i < len; ++i) {
778 /* equivalent to: dest[i] = src[i << 1] */
787 gst_jpeg_dec_free_buffers (GstJpegDec * dec)
791 for (i = 0; i < 16; i++) {
792 g_free (dec->idr_y[i]);
793 g_free (dec->idr_u[i]);
794 g_free (dec->idr_v[i]);
795 dec->idr_y[i] = NULL;
796 dec->idr_u[i] = NULL;
797 dec->idr_v[i] = NULL;
800 dec->idr_width_allocated = 0;
803 static inline gboolean
804 gst_jpeg_dec_ensure_buffers (GstJpegDec * dec, guint maxrowbytes)
808 if (G_LIKELY (dec->idr_width_allocated >= maxrowbytes))
811 /* FIXME: maybe just alloc one or three blocks altogether? */
812 for (i = 0; i < 16; i++) {
813 dec->idr_y[i] = g_try_realloc (dec->idr_y[i], maxrowbytes);
814 dec->idr_u[i] = g_try_realloc (dec->idr_u[i], maxrowbytes);
815 dec->idr_v[i] = g_try_realloc (dec->idr_v[i], maxrowbytes);
817 if (G_UNLIKELY (!dec->idr_y[i] || !dec->idr_u[i] || !dec->idr_v[i])) {
818 GST_WARNING_OBJECT (dec, "out of memory, i=%d, bytes=%u", i, maxrowbytes);
823 dec->idr_width_allocated = maxrowbytes;
824 GST_LOG_OBJECT (dec, "allocated temp memory, %u bytes/row", maxrowbytes);
829 gst_jpeg_dec_decode_grayscale (GstJpegDec * dec, GstVideoFrame * frame)
832 guchar **scanarray[1] = { rows };
837 gint pstride, rstride;
839 GST_DEBUG_OBJECT (dec, "indirect decoding of grayscale");
841 width = GST_VIDEO_FRAME_WIDTH (frame);
842 height = GST_VIDEO_FRAME_HEIGHT (frame);
844 if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
847 base[0] = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
848 pstride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0);
849 rstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
851 memcpy (rows, dec->idr_y, 16 * sizeof (gpointer));
855 lines = jpeg_read_raw_data (&dec->cinfo, scanarray, DCTSIZE);
856 if (G_LIKELY (lines > 0)) {
857 for (j = 0; (j < DCTSIZE) && (i < height); j++, i++) {
861 for (k = 0; k < width; k++) {
862 base[0][p] = rows[j][k];
868 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
874 gst_jpeg_dec_decode_rgb (GstJpegDec * dec, GstVideoFrame * frame)
876 guchar *r_rows[16], *g_rows[16], *b_rows[16];
877 guchar **scanarray[3] = { r_rows, g_rows, b_rows };
881 guint pstride, rstride;
884 GST_DEBUG_OBJECT (dec, "indirect decoding of RGB");
886 width = GST_VIDEO_FRAME_WIDTH (frame);
887 height = GST_VIDEO_FRAME_HEIGHT (frame);
889 if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
892 for (i = 0; i < 3; i++)
893 base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
895 pstride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0);
896 rstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
898 memcpy (r_rows, dec->idr_y, 16 * sizeof (gpointer));
899 memcpy (g_rows, dec->idr_u, 16 * sizeof (gpointer));
900 memcpy (b_rows, dec->idr_v, 16 * sizeof (gpointer));
904 lines = jpeg_read_raw_data (&dec->cinfo, scanarray, DCTSIZE);
905 if (G_LIKELY (lines > 0)) {
906 for (j = 0; (j < DCTSIZE) && (i < height); j++, i++) {
910 for (k = 0; k < width; k++) {
911 base[0][p] = r_rows[j][k];
912 base[1][p] = g_rows[j][k];
913 base[2][p] = b_rows[j][k];
921 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
927 gst_jpeg_dec_decode_indirect (GstJpegDec * dec, GstVideoFrame * frame,
928 gint r_v, gint r_h, gint comp)
930 guchar *y_rows[16], *u_rows[16], *v_rows[16];
931 guchar **scanarray[3] = { y_rows, u_rows, v_rows };
934 guchar *base[3], *last[3];
938 GST_DEBUG_OBJECT (dec,
939 "unadvantageous width or r_h, taking slow route involving memcpy");
941 width = GST_VIDEO_FRAME_WIDTH (frame);
942 height = GST_VIDEO_FRAME_HEIGHT (frame);
944 if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
947 for (i = 0; i < 3; i++) {
948 base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
949 stride[i] = GST_VIDEO_FRAME_COMP_STRIDE (frame, i);
950 /* make sure we don't make jpeglib write beyond our buffer,
951 * which might happen if (height % (r_v*DCTSIZE)) != 0 */
952 last[i] = base[i] + (GST_VIDEO_FRAME_COMP_STRIDE (frame, i) *
953 (GST_VIDEO_FRAME_COMP_HEIGHT (frame, i) - 1));
956 memcpy (y_rows, dec->idr_y, 16 * sizeof (gpointer));
957 memcpy (u_rows, dec->idr_u, 16 * sizeof (gpointer));
958 memcpy (v_rows, dec->idr_v, 16 * sizeof (gpointer));
960 /* fill chroma components for grayscale */
962 GST_DEBUG_OBJECT (dec, "grayscale, filling chroma");
963 for (i = 0; i < 16; i++) {
964 memset (u_rows[i], GST_ROUND_UP_32 (width), 0x80);
965 memset (v_rows[i], GST_ROUND_UP_32 (width), 0x80);
969 for (i = 0; i < height; i += r_v * DCTSIZE) {
970 lines = jpeg_read_raw_data (&dec->cinfo, scanarray, r_v * DCTSIZE);
971 if (G_LIKELY (lines > 0)) {
972 for (j = 0, k = 0; j < (r_v * DCTSIZE); j += r_v, k++) {
973 if (G_LIKELY (base[0] <= last[0])) {
974 memcpy (base[0], y_rows[j], stride[0]);
975 base[0] += stride[0];
978 if (G_LIKELY (base[0] <= last[0])) {
979 memcpy (base[0], y_rows[j + 1], stride[0]);
980 base[0] += stride[0];
983 if (G_LIKELY (base[1] <= last[1] && base[2] <= last[2])) {
985 memcpy (base[1], u_rows[k], stride[1]);
986 memcpy (base[2], v_rows[k], stride[2]);
987 } else if (r_h == 1) {
988 hresamplecpy1 (base[1], u_rows[k], stride[1]);
989 hresamplecpy1 (base[2], v_rows[k], stride[2]);
991 /* FIXME: implement (at least we avoid crashing by doing nothing) */
995 if (r_v == 2 || (k & 1) != 0) {
996 base[1] += stride[1];
997 base[2] += stride[2];
1001 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
1006 static GstFlowReturn
1007 gst_jpeg_dec_decode_direct (GstJpegDec * dec, GstVideoFrame * frame)
1009 guchar **line[3]; /* the jpeg line buffer */
1010 guchar *y[4 * DCTSIZE] = { NULL, }; /* alloc enough for the lines */
1011 guchar *u[4 * DCTSIZE] = { NULL, }; /* r_v will be <4 */
1012 guchar *v[4 * DCTSIZE] = { NULL, };
1014 gint lines, v_samp[3];
1015 guchar *base[3], *last[3];
1023 v_samp[0] = dec->cinfo.comp_info[0].v_samp_factor;
1024 v_samp[1] = dec->cinfo.comp_info[1].v_samp_factor;
1025 v_samp[2] = dec->cinfo.comp_info[2].v_samp_factor;
1027 if (G_UNLIKELY (v_samp[0] > 2 || v_samp[1] > 2 || v_samp[2] > 2))
1028 goto format_not_supported;
1030 height = GST_VIDEO_FRAME_HEIGHT (frame);
1032 for (i = 0; i < 3; i++) {
1033 base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
1034 stride[i] = GST_VIDEO_FRAME_COMP_STRIDE (frame, i);
1035 /* make sure we don't make jpeglib write beyond our buffer,
1036 * which might happen if (height % (r_v*DCTSIZE)) != 0 */
1037 last[i] = base[i] + (GST_VIDEO_FRAME_COMP_STRIDE (frame, i) *
1038 (GST_VIDEO_FRAME_COMP_HEIGHT (frame, i) - 1));
1041 /* let jpeglib decode directly into our final buffer */
1042 GST_DEBUG_OBJECT (dec, "decoding directly into output buffer");
1044 for (i = 0; i < height; i += v_samp[0] * DCTSIZE) {
1045 for (j = 0; j < (v_samp[0] * DCTSIZE); ++j) {
1047 line[0][j] = base[0] + (i + j) * stride[0];
1048 if (G_UNLIKELY (line[0][j] > last[0]))
1049 line[0][j] = last[0];
1051 if (v_samp[1] == v_samp[0]) {
1052 line[1][j] = base[1] + ((i + j) / 2) * stride[1];
1053 } else if (j < (v_samp[1] * DCTSIZE)) {
1054 line[1][j] = base[1] + ((i / 2) + j) * stride[1];
1056 if (G_UNLIKELY (line[1][j] > last[1]))
1057 line[1][j] = last[1];
1059 if (v_samp[2] == v_samp[0]) {
1060 line[2][j] = base[2] + ((i + j) / 2) * stride[2];
1061 } else if (j < (v_samp[2] * DCTSIZE)) {
1062 line[2][j] = base[2] + ((i / 2) + j) * stride[2];
1064 if (G_UNLIKELY (line[2][j] > last[2]))
1065 line[2][j] = last[2];
1068 lines = jpeg_read_raw_data (&dec->cinfo, line, v_samp[0] * DCTSIZE);
1069 if (G_UNLIKELY (!lines)) {
1070 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
1075 format_not_supported:
1077 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1078 "Unsupported subsampling schema: v_samp factors: %u %u %u",
1079 v_samp[0], v_samp[1], v_samp[2]);
1080 return GST_FLOW_ERROR;
1085 gst_jpeg_dec_update_qos (GstJpegDec * dec, gdouble proportion,
1086 GstClockTimeDiff diff, GstClockTime ts)
1088 GST_OBJECT_LOCK (dec);
1089 dec->proportion = proportion;
1090 if (G_LIKELY (ts != GST_CLOCK_TIME_NONE)) {
1091 if (G_UNLIKELY (diff > dec->qos_duration))
1092 dec->earliest_time = ts + 2 * diff + dec->qos_duration;
1094 dec->earliest_time = ts + diff;
1096 dec->earliest_time = GST_CLOCK_TIME_NONE;
1098 GST_OBJECT_UNLOCK (dec);
1102 gst_jpeg_dec_reset_qos (GstJpegDec * dec)
1104 gst_jpeg_dec_update_qos (dec, 0.5, 0, GST_CLOCK_TIME_NONE);
1108 gst_jpeg_dec_read_qos (GstJpegDec * dec, gdouble * proportion,
1109 GstClockTime * time)
1111 GST_OBJECT_LOCK (dec);
1112 *proportion = dec->proportion;
1113 *time = dec->earliest_time;
1114 GST_OBJECT_UNLOCK (dec);
1117 /* Perform qos calculations before decoding the next frame. Returns TRUE if the
1118 * frame should be decoded, FALSE if the frame can be dropped entirely */
1120 gst_jpeg_dec_do_qos (GstJpegDec * dec, GstClockTime timestamp)
1122 GstClockTime qostime, earliest_time;
1125 /* no timestamp, can't do QoS => decode frame */
1126 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (timestamp))) {
1127 GST_LOG_OBJECT (dec, "invalid timestamp, can't do QoS, decode frame");
1131 /* get latest QoS observation values */
1132 gst_jpeg_dec_read_qos (dec, &proportion, &earliest_time);
1134 /* skip qos if we have no observation (yet) => decode frame */
1135 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (earliest_time))) {
1136 GST_LOG_OBJECT (dec, "no observation yet, decode frame");
1140 /* qos is done on running time */
1141 qostime = gst_segment_to_running_time (&dec->segment, GST_FORMAT_TIME,
1144 /* see how our next timestamp relates to the latest qos timestamp */
1145 GST_LOG_OBJECT (dec, "qostime %" GST_TIME_FORMAT ", earliest %"
1146 GST_TIME_FORMAT, GST_TIME_ARGS (qostime), GST_TIME_ARGS (earliest_time));
1148 if (qostime != GST_CLOCK_TIME_NONE && qostime <= earliest_time) {
1149 GST_DEBUG_OBJECT (dec, "we are late, drop frame");
1153 GST_LOG_OBJECT (dec, "decode frame");
1158 gst_jpeg_dec_buffer_pool (GstJpegDec * dec, GstCaps * caps)
1161 GstBufferPool *pool = NULL;
1162 guint size, min, max, prefix, alignment;
1163 GstStructure *config;
1165 GST_DEBUG_OBJECT (dec, "setting up bufferpool");
1167 /* find a pool for the negotiated caps now */
1168 query = gst_query_new_allocation (caps, TRUE);
1170 if (gst_pad_peer_query (dec->srcpad, query)) {
1171 /* we got configuration from our peer, parse them */
1172 gst_query_parse_allocation_params (query, &size, &min, &max, &prefix,
1174 size = MAX (size, dec->info.size);
1176 GST_DEBUG_OBJECT (dec, "peer query failed, using defaults");
1177 size = dec->info.size;
1182 gst_query_unref (query);
1185 /* we did not get a pool, make one ourselves then */
1186 pool = gst_buffer_pool_new ();
1189 config = gst_buffer_pool_get_config (pool);
1190 gst_buffer_pool_config_set (config, caps, size, min, max, prefix,
1193 gst_buffer_pool_set_config (pool, config);
1196 gst_buffer_pool_set_active (dec->pool, FALSE);
1197 gst_object_unref (dec->pool);
1202 gst_buffer_pool_set_active (pool, TRUE);
1208 gst_jpeg_dec_negotiate (GstJpegDec * dec, gint width, gint height, gint clrspc)
1211 GstVideoFormat format;
1214 if (G_UNLIKELY (width == dec->info.width && height == dec->info.height &&
1215 dec->in_fps_n == dec->info.fps_n && dec->in_fps_d == dec->info.fps_d
1216 && clrspc == dec->clrspc))
1219 gst_video_info_init (&info);
1221 /* framerate == 0/1 is a still frame */
1222 if (dec->in_fps_d == 0) {
1226 info.fps_n = dec->in_fps_n;
1227 info.fps_d = dec->in_fps_d;
1230 /* calculate or assume an average frame duration for QoS purposes */
1231 GST_OBJECT_LOCK (dec);
1232 if (info.fps_n != 0) {
1234 gst_util_uint64_scale (GST_SECOND, info.fps_d, info.fps_n);
1235 dec->duration = dec->qos_duration;
1237 /* if not set just use 25fps */
1238 dec->qos_duration = gst_util_uint64_scale (GST_SECOND, 1, 25);
1239 dec->duration = GST_CLOCK_TIME_NONE;
1241 GST_OBJECT_UNLOCK (dec);
1243 if (dec->cinfo.jpeg_color_space == JCS_RGB) {
1245 GstCaps *allowed_caps;
1246 GstVideoInfo tmpinfo;
1248 GST_DEBUG_OBJECT (dec, "selecting RGB format");
1249 /* retrieve allowed caps, and find the first one that reasonably maps
1250 * to the parameters of the colourspace */
1251 caps = gst_pad_get_allowed_caps (dec->srcpad);
1253 GST_DEBUG_OBJECT (dec, "... but no peer, using template caps");
1254 /* need to copy because get_allowed_caps returns a ref,
1255 * and get_pad_template_caps doesn't */
1256 caps = gst_caps_copy (gst_pad_get_pad_template_caps (dec->srcpad));
1258 /* avoid lists of formats, etc */
1259 allowed_caps = gst_caps_normalize (caps);
1260 gst_caps_unref (caps);
1262 GST_LOG_OBJECT (dec, "allowed source caps %" GST_PTR_FORMAT, allowed_caps);
1264 for (i = 0; i < gst_caps_get_size (allowed_caps); i++) {
1266 gst_caps_unref (caps);
1267 caps = gst_caps_copy_nth (allowed_caps, i);
1268 /* sigh, ds and _parse_caps need fixed caps for parsing, fixate */
1269 gst_caps_fixate (caps);
1270 GST_LOG_OBJECT (dec, "checking caps %" GST_PTR_FORMAT, caps);
1272 if (!gst_video_info_from_caps (&tmpinfo, caps))
1274 /* we'll settle for the first (preferred) downstream rgb format */
1275 if (GST_VIDEO_INFO_IS_RGB (&tmpinfo))
1277 /* default fall-back */
1278 format = GST_VIDEO_FORMAT_RGB;
1281 gst_caps_unref (caps);
1282 gst_caps_unref (allowed_caps);
1283 } else if (dec->cinfo.jpeg_color_space == JCS_GRAYSCALE) {
1284 /* TODO is anything else then 8bit supported in jpeg? */
1285 format = GST_VIDEO_FORMAT_GRAY8;
1287 /* go for plain and simple I420 */
1288 /* TODO other YUV cases ? */
1289 format = GST_VIDEO_FORMAT_I420;
1292 gst_video_info_set_format (&info, format, width, height);
1293 caps = gst_video_info_to_caps (&info);
1295 GST_DEBUG_OBJECT (dec, "setting caps %" GST_PTR_FORMAT, caps);
1296 GST_DEBUG_OBJECT (dec, "max_v_samp_factor=%d", dec->cinfo.max_v_samp_factor);
1297 GST_DEBUG_OBJECT (dec, "max_h_samp_factor=%d", dec->cinfo.max_h_samp_factor);
1299 gst_pad_set_caps (dec->srcpad, caps);
1302 dec->clrspc = clrspc;
1304 gst_jpeg_dec_buffer_pool (dec, caps);
1305 gst_caps_unref (caps);
1310 static GstFlowReturn
1311 gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf)
1313 GstFlowReturn ret = GST_FLOW_OK;
1315 GstBuffer *outbuf = NULL;
1320 GstClockTime timestamp, duration;
1321 GstVideoFrame frame;
1323 dec = GST_JPEG_DEC (GST_PAD_PARENT (pad));
1325 timestamp = GST_BUFFER_TIMESTAMP (buf);
1326 duration = GST_BUFFER_DURATION (buf);
1328 if (GST_CLOCK_TIME_IS_VALID (timestamp))
1329 dec->next_ts = timestamp;
1331 if (GST_BUFFER_IS_DISCONT (buf)) {
1332 GST_DEBUG_OBJECT (dec, "buffer has DISCONT flag set");
1333 dec->discont = TRUE;
1334 if (!dec->packetized && gst_adapter_available (dec->adapter)) {
1335 GST_WARNING_OBJECT (dec, "DISCONT buffer in non-packetized mode, bad");
1336 gst_adapter_clear (dec->adapter);
1340 gst_adapter_push (dec->adapter, buf);
1343 /* If we are non-packetized and know the total incoming size in bytes,
1344 * just wait until we have enough before doing any processing. */
1346 if (!dec->packetized && (dec->segment.format == GST_FORMAT_BYTES) &&
1347 (dec->segment.stop != -1) &&
1348 (gst_adapter_available (dec->adapter) < dec->segment.stop)) {
1349 /* We assume that non-packetized input in bytes is *one* single jpeg image */
1350 GST_DEBUG ("Non-packetized mode. Got %d bytes, need %" G_GINT64_FORMAT,
1351 gst_adapter_available (dec->adapter), dec->segment.stop);
1352 goto need_more_data;
1356 if (!gst_jpeg_dec_ensure_header (dec))
1357 goto need_more_data;
1359 /* If we know that each input buffer contains data
1360 * for a whole jpeg image (e.g. MJPEG streams), just
1361 * do some sanity checking instead of parsing all of
1363 if (dec->packetized) {
1364 img_len = gst_adapter_available (dec->adapter);
1366 /* Parse jpeg image to handle jpeg input that
1367 * is not aligned to buffer boundaries */
1368 img_len = gst_jpeg_dec_parse_image_data (dec);
1371 goto need_more_data;
1372 } else if (img_len < 0) {
1373 gst_adapter_flush (dec->adapter, -img_len);
1378 dec->rem_img_len = img_len;
1380 GST_LOG_OBJECT (dec, "image size = %u", img_len);
1382 /* QoS: if we're too late anyway, skip decoding */
1383 if (dec->packetized && !gst_jpeg_dec_do_qos (dec, timestamp))
1386 #ifndef GST_DISABLE_GST_DEBUG
1390 gst_adapter_copy (dec->adapter, data, 0, 4);
1391 GST_LOG_OBJECT (dec, "reading header %02x %02x %02x %02x", data[0], data[1],
1396 gst_jpeg_dec_fill_input_buffer (&dec->cinfo);
1398 if (setjmp (dec->jerr.setjmp_buffer)) {
1399 code = dec->jerr.pub.msg_code;
1401 if (code == JERR_INPUT_EOF) {
1402 GST_DEBUG ("jpeg input EOF error, we probably need more data");
1403 goto need_more_data;
1409 hdr_ok = jpeg_read_header (&dec->cinfo, TRUE);
1410 if (G_UNLIKELY (hdr_ok != JPEG_HEADER_OK)) {
1411 GST_WARNING_OBJECT (dec, "reading the header failed, %d", hdr_ok);
1414 GST_LOG_OBJECT (dec, "num_components=%d", dec->cinfo.num_components);
1415 GST_LOG_OBJECT (dec, "jpeg_color_space=%d", dec->cinfo.jpeg_color_space);
1417 if (!dec->cinfo.num_components || !dec->cinfo.comp_info)
1418 goto components_not_supported;
1420 r_h = dec->cinfo.comp_info[0].h_samp_factor;
1421 r_v = dec->cinfo.comp_info[0].v_samp_factor;
1423 GST_LOG_OBJECT (dec, "r_h = %d, r_v = %d", r_h, r_v);
1425 if (dec->cinfo.num_components > 3)
1426 goto components_not_supported;
1428 /* verify color space expectation to avoid going *boom* or bogus output */
1429 if (dec->cinfo.jpeg_color_space != JCS_YCbCr &&
1430 dec->cinfo.jpeg_color_space != JCS_GRAYSCALE &&
1431 dec->cinfo.jpeg_color_space != JCS_RGB)
1432 goto unsupported_colorspace;
1434 #ifndef GST_DISABLE_GST_DEBUG
1438 for (i = 0; i < dec->cinfo.num_components; ++i) {
1439 GST_LOG_OBJECT (dec, "[%d] h_samp_factor=%d, v_samp_factor=%d, cid=%d",
1440 i, dec->cinfo.comp_info[i].h_samp_factor,
1441 dec->cinfo.comp_info[i].v_samp_factor,
1442 dec->cinfo.comp_info[i].component_id);
1447 /* prepare for raw output */
1448 dec->cinfo.do_fancy_upsampling = FALSE;
1449 dec->cinfo.do_block_smoothing = FALSE;
1450 dec->cinfo.out_color_space = dec->cinfo.jpeg_color_space;
1451 dec->cinfo.dct_method = dec->idct_method;
1452 dec->cinfo.raw_data_out = TRUE;
1454 GST_LOG_OBJECT (dec, "starting decompress");
1455 guarantee_huff_tables (&dec->cinfo);
1456 if (!jpeg_start_decompress (&dec->cinfo)) {
1457 GST_WARNING_OBJECT (dec, "failed to start decompression cycle");
1460 /* sanity checks to get safe and reasonable output */
1461 switch (dec->cinfo.jpeg_color_space) {
1463 if (dec->cinfo.num_components != 1)
1464 goto invalid_yuvrgbgrayscale;
1467 if (dec->cinfo.num_components != 3 || dec->cinfo.max_v_samp_factor > 1 ||
1468 dec->cinfo.max_h_samp_factor > 1)
1469 goto invalid_yuvrgbgrayscale;
1472 if (dec->cinfo.num_components != 3 ||
1473 r_v > 2 || r_v < dec->cinfo.comp_info[0].v_samp_factor ||
1474 r_v < dec->cinfo.comp_info[1].v_samp_factor ||
1475 r_h < dec->cinfo.comp_info[0].h_samp_factor ||
1476 r_h < dec->cinfo.comp_info[1].h_samp_factor)
1477 goto invalid_yuvrgbgrayscale;
1480 g_assert_not_reached ();
1484 width = dec->cinfo.output_width;
1485 height = dec->cinfo.output_height;
1487 if (G_UNLIKELY (width < MIN_WIDTH || width > MAX_WIDTH ||
1488 height < MIN_HEIGHT || height > MAX_HEIGHT))
1491 gst_jpeg_dec_negotiate (dec, width, height, dec->cinfo.jpeg_color_space);
1493 ret = gst_buffer_pool_acquire_buffer (dec->pool, &outbuf, NULL);
1494 if (G_UNLIKELY (ret != GST_FLOW_OK))
1497 if (!gst_video_frame_map (&frame, &dec->info, outbuf, GST_MAP_READWRITE))
1500 GST_LOG_OBJECT (dec, "width %d, height %d", width, height);
1502 GST_BUFFER_TIMESTAMP (outbuf) = dec->next_ts;
1504 if (dec->packetized && GST_CLOCK_TIME_IS_VALID (dec->next_ts)) {
1505 if (GST_CLOCK_TIME_IS_VALID (duration)) {
1506 /* use duration from incoming buffer for outgoing buffer */
1507 dec->next_ts += duration;
1508 } else if (GST_CLOCK_TIME_IS_VALID (dec->duration)) {
1509 duration = dec->duration;
1510 dec->next_ts += dec->duration;
1512 duration = GST_CLOCK_TIME_NONE;
1513 dec->next_ts = GST_CLOCK_TIME_NONE;
1516 duration = GST_CLOCK_TIME_NONE;
1517 dec->next_ts = GST_CLOCK_TIME_NONE;
1519 GST_BUFFER_DURATION (outbuf) = duration;
1521 if (dec->cinfo.jpeg_color_space == JCS_RGB) {
1522 gst_jpeg_dec_decode_rgb (dec, &frame);
1523 } else if (dec->cinfo.jpeg_color_space == JCS_GRAYSCALE) {
1524 gst_jpeg_dec_decode_grayscale (dec, &frame);
1526 GST_LOG_OBJECT (dec, "decompressing (reqired scanline buffer height = %u)",
1527 dec->cinfo.rec_outbuf_height);
1529 /* For some widths jpeglib requires more horizontal padding than I420
1530 * provides. In those cases we need to decode into separate buffers and then
1531 * copy over the data into our final picture buffer, otherwise jpeglib might
1532 * write over the end of a line into the beginning of the next line,
1533 * resulting in blocky artifacts on the left side of the picture. */
1534 if (G_UNLIKELY (width % (dec->cinfo.max_h_samp_factor * DCTSIZE) != 0
1535 || dec->cinfo.comp_info[0].h_samp_factor != 2
1536 || dec->cinfo.comp_info[1].h_samp_factor != 1
1537 || dec->cinfo.comp_info[2].h_samp_factor != 1)) {
1538 GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, dec,
1539 "indirect decoding using extra buffer copy");
1540 gst_jpeg_dec_decode_indirect (dec, &frame, r_v, r_h,
1541 dec->cinfo.num_components);
1543 ret = gst_jpeg_dec_decode_direct (dec, &frame);
1544 if (G_UNLIKELY (ret != GST_FLOW_OK))
1545 goto decode_direct_failed;
1549 GST_LOG_OBJECT (dec, "decompressing finished");
1550 jpeg_finish_decompress (&dec->cinfo);
1552 gst_video_frame_unmap (&frame);
1555 if (dec->segment.format == GST_FORMAT_TIME) {
1556 guint64 start, stop, clip_start, clip_stop;
1558 GST_LOG_OBJECT (dec, "Attempting clipping");
1560 start = GST_BUFFER_TIMESTAMP (outbuf);
1561 if (GST_BUFFER_DURATION (outbuf) == GST_CLOCK_TIME_NONE)
1564 stop = start + GST_BUFFER_DURATION (outbuf);
1566 if (gst_segment_clip (&dec->segment, GST_FORMAT_TIME,
1567 start, stop, &clip_start, &clip_stop)) {
1568 GST_LOG_OBJECT (dec, "Clipping start to %" GST_TIME_FORMAT,
1569 GST_TIME_ARGS (clip_start));
1570 GST_BUFFER_TIMESTAMP (outbuf) = clip_start;
1571 if (GST_BUFFER_DURATION (outbuf) != GST_CLOCK_TIME_NONE) {
1572 GST_LOG_OBJECT (dec, "Clipping duration to %" GST_TIME_FORMAT,
1573 GST_TIME_ARGS (clip_stop - clip_start));
1574 GST_BUFFER_DURATION (outbuf) = clip_stop - clip_start;
1580 /* reset error count on successful decode */
1581 dec->error_count = 0;
1585 GST_LOG_OBJECT (dec, "pushing buffer (ts=%" GST_TIME_FORMAT ", dur=%"
1586 GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
1587 GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
1589 ret = gst_pad_push (dec->srcpad, outbuf);
1593 gst_adapter_flush (dec->adapter, dec->rem_img_len);
1597 if (G_UNLIKELY (ret == GST_FLOW_ERROR)) {
1598 jpeg_abort_decompress (&dec->cinfo);
1599 ret = gst_jpeg_dec_post_error_or_warning (dec);
1607 GST_LOG_OBJECT (dec, "we need more data");
1609 gst_buffer_unref (outbuf);
1618 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1619 "Picture is too small or too big (%ux%u)", width, height);
1620 ret = GST_FLOW_ERROR;
1625 gchar err_msg[JMSG_LENGTH_MAX];
1627 dec->jerr.pub.format_message ((j_common_ptr) (&dec->cinfo), err_msg);
1629 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1630 "Decode error #%u: %s", code, err_msg);
1633 gst_buffer_unref (outbuf);
1636 ret = GST_FLOW_ERROR;
1639 decode_direct_failed:
1641 /* already posted an error message */
1642 jpeg_abort_decompress (&dec->cinfo);
1643 gst_buffer_replace (&outbuf, NULL);
1648 const gchar *reason;
1650 reason = gst_flow_get_name (ret);
1652 GST_DEBUG_OBJECT (dec, "failed to alloc buffer, reason %s", reason);
1653 /* Reset for next time */
1654 jpeg_abort_decompress (&dec->cinfo);
1655 if (ret != GST_FLOW_UNEXPECTED && ret != GST_FLOW_WRONG_STATE &&
1656 ret != GST_FLOW_NOT_LINKED) {
1657 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1658 "Buffer allocation failed, reason: %s", reason);
1664 jpeg_abort_decompress (&dec->cinfo);
1665 gst_buffer_unref (outbuf);
1671 GST_WARNING_OBJECT (dec, "Outgoing buffer is outside configured segment");
1672 gst_buffer_unref (outbuf);
1676 components_not_supported:
1678 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1679 "number of components not supported: %d (max 3)",
1680 dec->cinfo.num_components);
1681 ret = GST_FLOW_ERROR;
1684 unsupported_colorspace:
1686 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1687 "Picture has unknown or unsupported colourspace");
1688 ret = GST_FLOW_ERROR;
1691 invalid_yuvrgbgrayscale:
1693 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1694 "Picture is corrupt or unhandled YUV/RGB/grayscale layout");
1695 ret = GST_FLOW_ERROR;
1701 gst_jpeg_dec_src_event (GstPad * pad, GstEvent * event)
1706 dec = GST_JPEG_DEC (gst_pad_get_parent (pad));
1707 if (G_UNLIKELY (dec == NULL)) {
1708 gst_event_unref (event);
1712 switch (GST_EVENT_TYPE (event)) {
1713 case GST_EVENT_QOS:{
1715 GstClockTimeDiff diff;
1716 GstClockTime timestamp;
1719 gst_event_parse_qos (event, &type, &proportion, &diff, ×tamp);
1720 gst_jpeg_dec_update_qos (dec, proportion, diff, timestamp);
1727 res = gst_pad_push_event (dec->sinkpad, event);
1729 gst_object_unref (dec);
1734 gst_jpeg_dec_sink_event (GstPad * pad, GstEvent * event)
1736 gboolean ret = TRUE, forward = TRUE;
1737 GstJpegDec *dec = GST_JPEG_DEC (GST_OBJECT_PARENT (pad));
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);