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, GstQuery * query);
99 static gboolean gst_jpeg_dec_sink_event (GstPad * pad, GstEvent * event);
100 static gboolean gst_jpeg_dec_src_event (GstPad * pad, GstEvent * event);
101 static GstStateChangeReturn gst_jpeg_dec_change_state (GstElement * element,
102 GstStateChange transition);
103 static void gst_jpeg_dec_update_qos (GstJpegDec * dec, gdouble proportion,
104 GstClockTimeDiff diff, GstClockTime ts);
105 static void gst_jpeg_dec_reset_qos (GstJpegDec * dec);
106 static void gst_jpeg_dec_read_qos (GstJpegDec * dec, gdouble * proportion,
107 GstClockTime * time);
109 #define gst_jpeg_dec_parent_class parent_class
110 G_DEFINE_TYPE (GstJpegDec, gst_jpeg_dec, GST_TYPE_ELEMENT);
113 gst_jpeg_dec_finalize (GObject * object)
115 GstJpegDec *dec = GST_JPEG_DEC (object);
117 jpeg_destroy_decompress (&dec->cinfo);
119 g_object_unref (dec->adapter);
121 G_OBJECT_CLASS (parent_class)->finalize (object);
125 gst_jpeg_dec_class_init (GstJpegDecClass * klass)
127 GstElementClass *gstelement_class;
128 GObjectClass *gobject_class;
130 gstelement_class = (GstElementClass *) klass;
131 gobject_class = (GObjectClass *) klass;
133 parent_class = g_type_class_peek_parent (klass);
135 gobject_class->finalize = gst_jpeg_dec_finalize;
136 gobject_class->set_property = gst_jpeg_dec_set_property;
137 gobject_class->get_property = gst_jpeg_dec_get_property;
139 g_object_class_install_property (gobject_class, PROP_IDCT_METHOD,
140 g_param_spec_enum ("idct-method", "IDCT Method",
141 "The IDCT algorithm to use", GST_TYPE_IDCT_METHOD,
142 JPEG_DEFAULT_IDCT_METHOD,
143 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
146 * GstJpegDec:max-errors
148 * Error out after receiving N consecutive decoding errors
149 * (-1 = never error out, 0 = automatic, 1 = fail on first error, etc.)
153 g_object_class_install_property (gobject_class, PROP_MAX_ERRORS,
154 g_param_spec_int ("max-errors", "Maximum Consecutive Decoding Errors",
155 "Error out after receiving N consecutive decoding errors "
156 "(-1 = never fail, 0 = automatic, 1 = fail on first error)",
157 -1, G_MAXINT, JPEG_DEFAULT_MAX_ERRORS,
158 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
160 gst_element_class_add_pad_template (gstelement_class,
161 gst_static_pad_template_get (&gst_jpeg_dec_src_pad_template));
162 gst_element_class_add_pad_template (gstelement_class,
163 gst_static_pad_template_get (&gst_jpeg_dec_sink_pad_template));
164 gst_element_class_set_details_simple (gstelement_class, "JPEG image decoder",
165 "Codec/Decoder/Image",
166 "Decode images from JPEG format", "Wim Taymans <wim@fluendo.com>");
168 gstelement_class->change_state =
169 GST_DEBUG_FUNCPTR (gst_jpeg_dec_change_state);
171 GST_DEBUG_CATEGORY_INIT (jpeg_dec_debug, "jpegdec", 0, "JPEG decoder");
172 GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE");
176 gst_jpeg_dec_clear_error (GstJpegDec * dec)
178 g_free (dec->error_msg);
179 dec->error_msg = NULL;
181 dec->error_func = NULL;
185 gst_jpeg_dec_set_error_va (GstJpegDec * dec, const gchar * func, gint line,
186 const gchar * debug_msg_format, va_list args)
188 #ifndef GST_DISABLE_GST_DEBUG
189 gst_debug_log_valist (GST_CAT_DEFAULT, GST_LEVEL_WARNING, __FILE__, func,
190 line, (GObject *) dec, debug_msg_format, args);
193 g_free (dec->error_msg);
194 if (debug_msg_format)
195 dec->error_msg = g_strdup_vprintf (debug_msg_format, args);
197 dec->error_msg = NULL;
199 dec->error_line = line;
200 dec->error_func = func;
204 gst_jpeg_dec_set_error (GstJpegDec * dec, const gchar * func, gint line,
205 const gchar * debug_msg_format, ...)
209 va_start (va, debug_msg_format);
210 gst_jpeg_dec_set_error_va (dec, func, line, debug_msg_format, va);
215 gst_jpeg_dec_post_error_or_warning (GstJpegDec * dec)
221 max_errors = g_atomic_int_get (&dec->max_errors);
223 if (max_errors < 0) {
225 } else if (max_errors == 0) {
226 /* FIXME: do something more clever in "automatic mode" */
227 if (dec->packetized) {
228 ret = (dec->error_count < 3) ? GST_FLOW_OK : GST_FLOW_ERROR;
230 ret = GST_FLOW_ERROR;
233 ret = (dec->error_count < max_errors) ? GST_FLOW_OK : GST_FLOW_ERROR;
236 GST_INFO_OBJECT (dec, "decoding error %d/%d (%s)", dec->error_count,
237 max_errors, (ret == GST_FLOW_OK) ? "ignoring error" : "erroring out");
239 gst_element_message_full (GST_ELEMENT (dec),
240 (ret == GST_FLOW_OK) ? GST_MESSAGE_WARNING : GST_MESSAGE_ERROR,
241 GST_STREAM_ERROR, GST_STREAM_ERROR_DECODE,
242 g_strdup (_("Failed to decode JPEG image")), dec->error_msg,
243 __FILE__, dec->error_func, dec->error_line);
245 dec->error_msg = NULL;
246 gst_jpeg_dec_clear_error (dec);
251 gst_jpeg_dec_fill_input_buffer (j_decompress_ptr cinfo)
256 dec = CINFO_GET_JPEGDEC (cinfo);
257 g_return_val_if_fail (dec != NULL, FALSE);
259 av = gst_adapter_available_fast (dec->adapter);
260 GST_DEBUG_OBJECT (dec, "fill_input_buffer: fast av=%u, remaining=%u", av,
264 GST_DEBUG_OBJECT (dec, "Out of data");
268 if (dec->rem_img_len < av)
269 av = dec->rem_img_len;
270 dec->rem_img_len -= av;
272 g_free (dec->cur_buf);
273 dec->cur_buf = gst_adapter_take (dec->adapter, av);
275 cinfo->src->next_input_byte = dec->cur_buf;
276 cinfo->src->bytes_in_buffer = av;
282 gst_jpeg_dec_init_source (j_decompress_ptr cinfo)
284 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "init_source");
289 gst_jpeg_dec_skip_input_data (j_decompress_ptr cinfo, glong num_bytes)
291 GstJpegDec *dec = CINFO_GET_JPEGDEC (cinfo);
293 GST_DEBUG_OBJECT (dec, "skip %ld bytes", num_bytes);
295 if (num_bytes > 0 && cinfo->src->bytes_in_buffer >= num_bytes) {
296 cinfo->src->next_input_byte += (size_t) num_bytes;
297 cinfo->src->bytes_in_buffer -= (size_t) num_bytes;
298 } else if (num_bytes > 0) {
301 num_bytes -= cinfo->src->bytes_in_buffer;
302 cinfo->src->next_input_byte += (size_t) cinfo->src->bytes_in_buffer;
303 cinfo->src->bytes_in_buffer = 0;
305 available = gst_adapter_available (dec->adapter);
306 if (available < num_bytes || available < dec->rem_img_len) {
307 GST_WARNING_OBJECT (dec, "Less bytes to skip than available in the "
308 "adapter or the remaining image length %ld < %d or %u",
309 num_bytes, available, dec->rem_img_len);
311 num_bytes = MIN (MIN (num_bytes, available), dec->rem_img_len);
312 gst_adapter_flush (dec->adapter, num_bytes);
313 dec->rem_img_len -= num_bytes;
318 gst_jpeg_dec_resync_to_restart (j_decompress_ptr cinfo, gint desired)
320 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "resync_to_start");
325 gst_jpeg_dec_term_source (j_decompress_ptr cinfo)
327 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "term_source");
332 gst_jpeg_dec_my_output_message (j_common_ptr cinfo)
334 return; /* do nothing */
338 gst_jpeg_dec_my_emit_message (j_common_ptr cinfo, int msg_level)
340 /* GST_LOG_OBJECT (CINFO_GET_JPEGDEC (&cinfo), "msg_level=%d", msg_level); */
345 gst_jpeg_dec_my_error_exit (j_common_ptr cinfo)
347 struct GstJpegDecErrorMgr *err_mgr = (struct GstJpegDecErrorMgr *) cinfo->err;
349 (*cinfo->err->output_message) (cinfo);
350 longjmp (err_mgr->setjmp_buffer, 1);
354 gst_jpeg_dec_init (GstJpegDec * dec)
356 GST_DEBUG ("initializing");
358 /* create the sink and src pads */
360 gst_pad_new_from_static_template (&gst_jpeg_dec_sink_pad_template,
362 gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
363 gst_pad_set_chain_function (dec->sinkpad,
364 GST_DEBUG_FUNCPTR (gst_jpeg_dec_chain));
365 gst_pad_set_event_function (dec->sinkpad,
366 GST_DEBUG_FUNCPTR (gst_jpeg_dec_sink_event));
367 gst_pad_set_query_function (dec->sinkpad,
368 GST_DEBUG_FUNCPTR (gst_jpeg_dec_sink_query));
371 gst_pad_new_from_static_template (&gst_jpeg_dec_src_pad_template, "src");
372 gst_pad_set_event_function (dec->srcpad,
373 GST_DEBUG_FUNCPTR (gst_jpeg_dec_src_event));
374 gst_pad_use_fixed_caps (dec->srcpad);
375 gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
378 memset (&dec->cinfo, 0, sizeof (dec->cinfo));
379 memset (&dec->jerr, 0, sizeof (dec->jerr));
380 dec->cinfo.err = jpeg_std_error (&dec->jerr.pub);
381 dec->jerr.pub.output_message = gst_jpeg_dec_my_output_message;
382 dec->jerr.pub.emit_message = gst_jpeg_dec_my_emit_message;
383 dec->jerr.pub.error_exit = gst_jpeg_dec_my_error_exit;
385 jpeg_create_decompress (&dec->cinfo);
387 dec->cinfo.src = (struct jpeg_source_mgr *) &dec->jsrc;
388 dec->cinfo.src->init_source = gst_jpeg_dec_init_source;
389 dec->cinfo.src->fill_input_buffer = gst_jpeg_dec_fill_input_buffer;
390 dec->cinfo.src->skip_input_data = gst_jpeg_dec_skip_input_data;
391 dec->cinfo.src->resync_to_restart = gst_jpeg_dec_resync_to_restart;
392 dec->cinfo.src->term_source = gst_jpeg_dec_term_source;
395 /* init properties */
396 dec->idct_method = JPEG_DEFAULT_IDCT_METHOD;
397 dec->max_errors = JPEG_DEFAULT_MAX_ERRORS;
399 dec->adapter = gst_adapter_new ();
403 gst_jpeg_dec_ensure_header (GstJpegDec * dec)
408 av = gst_adapter_available (dec->adapter);
409 /* we expect at least 4 bytes, first of which start marker */
410 offset = gst_adapter_masked_scan_uint32 (dec->adapter, 0xffffff00, 0xffd8ff00,
412 if (G_UNLIKELY (offset < 0)) {
413 GST_DEBUG_OBJECT (dec, "No JPEG header in current buffer");
416 gst_adapter_flush (dec->adapter, av - 4);
421 GST_LOG_OBJECT (dec, "Skipping %u bytes.", offset);
422 gst_adapter_flush (dec->adapter, offset);
424 GST_DEBUG_OBJECT (dec, "Found JPEG header");
429 static inline gboolean
430 gst_jpeg_dec_parse_tag_has_entropy_segment (guint8 tag)
432 if (tag == 0xda || (tag >= 0xd0 && tag <= 0xd7))
437 /* returns image length in bytes if parsed successfully,
438 * otherwise 0 if more data needed,
439 * if < 0 the absolute value needs to be flushed */
441 gst_jpeg_dec_parse_image_data (GstJpegDec * dec)
445 GstAdapter *adapter = dec->adapter;
446 gint offset, noffset;
448 size = gst_adapter_available (adapter);
450 /* we expect at least 4 bytes, first of which start marker */
451 if (gst_adapter_masked_scan_uint32 (adapter, 0xffff0000, 0xffd80000, 0, 4))
454 GST_DEBUG ("Parsing jpeg image data (%u bytes)", size);
456 GST_DEBUG ("Parse state: offset=%d, resync=%d, entropy len=%d",
457 dec->parse_offset, dec->parse_resync, dec->parse_entropy_len);
459 /* offset is 2 less than actual offset;
460 * - adapter needs at least 4 bytes for scanning,
461 * - start and end marker ensure at least that much
463 /* resume from state offset */
464 offset = dec->parse_offset;
471 gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00, 0x0000ff00,
472 offset, size - offset, &value);
473 /* lost sync if 0xff marker not where expected */
474 if ((resync = (noffset != offset))) {
475 GST_DEBUG ("Lost sync at 0x%08x, resyncing", offset + 2);
477 /* may have marker, but could have been resyncng */
478 resync = resync || dec->parse_resync;
479 /* Skip over extra 0xff */
480 while ((noffset >= 0) && ((value & 0xff) == 0xff)) {
483 gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00, 0x0000ff00,
484 noffset, size - noffset, &value);
486 /* enough bytes left for marker? (we need 0xNN after the 0xff) */
488 GST_DEBUG ("at end of input and no EOI marker found, need more data");
492 /* now lock on the marker we found */
494 value = value & 0xff;
496 GST_DEBUG ("0x%08x: EOI marker", offset + 2);
497 /* clear parse state */
498 dec->parse_resync = FALSE;
499 dec->parse_offset = 0;
501 } else if (value == 0xd8) {
502 /* Skip this frame if we found another SOI marker */
503 GST_DEBUG ("0x%08x: SOI marker before EOI, skipping", offset + 2);
504 dec->parse_resync = FALSE;
505 dec->parse_offset = 0;
506 return -(offset + 2);
510 if (value >= 0xd0 && value <= 0xd7)
513 /* peek tag and subsequent length */
514 if (offset + 2 + 4 > size)
517 gst_adapter_masked_scan_uint32_peek (adapter, 0x0, 0x0, offset + 2, 4,
519 frame_len = frame_len & 0xffff;
521 GST_DEBUG ("0x%08x: tag %02x, frame_len=%u", offset + 2, value, frame_len);
522 /* the frame length includes the 2 bytes for the length; here we want at
523 * least 2 more bytes at the end for an end marker */
524 if (offset + 2 + 2 + frame_len + 2 > size) {
528 if (gst_jpeg_dec_parse_tag_has_entropy_segment (value)) {
529 guint eseglen = dec->parse_entropy_len;
531 GST_DEBUG ("0x%08x: finding entropy segment length", offset + 2);
532 noffset = offset + 2 + frame_len + dec->parse_entropy_len;
534 noffset = gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00,
535 0x0000ff00, noffset, size - noffset, &value);
538 dec->parse_entropy_len = size - offset - 4 - frame_len - 2;
541 if ((value & 0xff) != 0x00) {
542 eseglen = noffset - offset - frame_len - 2;
547 dec->parse_entropy_len = 0;
548 frame_len += eseglen;
549 GST_DEBUG ("entropy segment length=%u => frame_len=%u", eseglen,
553 /* check if we will still be in sync if we interpret
554 * this as a sync point and skip this frame */
555 noffset = offset + frame_len + 2;
556 noffset = gst_adapter_masked_scan_uint32 (adapter, 0x0000ff00, 0x0000ff00,
559 /* ignore and continue resyncing until we hit the end
560 * of our data or find a sync point that looks okay */
564 GST_DEBUG ("found sync at 0x%x", offset + 2);
567 offset += frame_len + 2;
573 dec->parse_offset = offset;
574 dec->parse_resync = resync;
579 /* shamelessly ripped from jpegutils.c in mjpegtools */
581 add_huff_table (j_decompress_ptr dinfo,
582 JHUFF_TBL ** htblptr, const UINT8 * bits, const UINT8 * val)
583 /* Define a Huffman table */
587 if (*htblptr == NULL)
588 *htblptr = jpeg_alloc_huff_table ((j_common_ptr) dinfo);
592 /* Copy the number-of-symbols-of-each-code-length counts */
593 memcpy ((*htblptr)->bits, bits, sizeof ((*htblptr)->bits));
595 /* Validate the counts. We do this here mainly so we can copy the right
596 * number of symbols from the val[] array, without risking marching off
597 * the end of memory. jchuff.c will do a more thorough test later.
600 for (len = 1; len <= 16; len++)
601 nsymbols += bits[len];
602 if (nsymbols < 1 || nsymbols > 256)
603 g_error ("jpegutils.c: add_huff_table failed badly. ");
605 memcpy ((*htblptr)->huffval, val, nsymbols * sizeof (UINT8));
611 std_huff_tables (j_decompress_ptr dinfo)
612 /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
613 /* IMPORTANT: these are only valid for 8-bit data precision! */
615 static const UINT8 bits_dc_luminance[17] =
616 { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
617 static const UINT8 val_dc_luminance[] =
618 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
620 static const UINT8 bits_dc_chrominance[17] =
621 { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
622 static const UINT8 val_dc_chrominance[] =
623 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
625 static const UINT8 bits_ac_luminance[17] =
626 { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
627 static const UINT8 val_ac_luminance[] =
628 { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
629 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
630 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
631 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
632 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
633 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
634 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
635 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
636 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
637 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
638 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
639 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
640 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
641 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
642 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
643 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
644 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
645 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
646 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
647 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
651 static const UINT8 bits_ac_chrominance[17] =
652 { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
653 static const UINT8 val_ac_chrominance[] =
654 { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
655 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
656 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
657 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
658 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
659 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
660 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
661 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
662 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
663 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
664 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
665 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
666 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
667 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
668 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
669 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
670 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
671 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
672 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
673 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
677 add_huff_table (dinfo, &dinfo->dc_huff_tbl_ptrs[0],
678 bits_dc_luminance, val_dc_luminance);
679 add_huff_table (dinfo, &dinfo->ac_huff_tbl_ptrs[0],
680 bits_ac_luminance, val_ac_luminance);
681 add_huff_table (dinfo, &dinfo->dc_huff_tbl_ptrs[1],
682 bits_dc_chrominance, val_dc_chrominance);
683 add_huff_table (dinfo, &dinfo->ac_huff_tbl_ptrs[1],
684 bits_ac_chrominance, val_ac_chrominance);
690 guarantee_huff_tables (j_decompress_ptr dinfo)
692 if ((dinfo->dc_huff_tbl_ptrs[0] == NULL) &&
693 (dinfo->dc_huff_tbl_ptrs[1] == NULL) &&
694 (dinfo->ac_huff_tbl_ptrs[0] == NULL) &&
695 (dinfo->ac_huff_tbl_ptrs[1] == NULL)) {
696 GST_DEBUG ("Generating standard Huffman tables for this frame.");
697 std_huff_tables (dinfo);
702 gst_jpeg_dec_setcaps (GstJpegDec * dec, GstCaps * caps)
705 const GValue *framerate;
707 s = gst_caps_get_structure (caps, 0);
709 if ((framerate = gst_structure_get_value (s, "framerate")) != NULL) {
710 dec->in_fps_n = gst_value_get_fraction_numerator (framerate);
711 dec->in_fps_d = gst_value_get_fraction_denominator (framerate);
712 dec->packetized = TRUE;
713 GST_DEBUG ("got framerate of %d/%d fps => packetized mode",
714 dec->in_fps_n, dec->in_fps_d);
717 /* do not extract width/height here. we do that in the chain
718 * function on a per-frame basis (including the line[] array
721 /* But we can take the framerate values and set them on the src pad */
727 gst_jpeg_dec_getcaps (GstPad * pad, GstCaps * filter)
733 dec = GST_JPEG_DEC (GST_OBJECT_PARENT (pad));
735 if (gst_pad_has_current_caps (pad))
736 return gst_pad_get_current_caps (pad);
738 peer = gst_pad_get_peer (dec->srcpad);
742 const GstCaps *templ_caps;
746 peer_caps = gst_pad_get_caps (peer, filter);
748 /* Translate peercaps to image/jpeg */
749 peer_caps = gst_caps_make_writable (peer_caps);
750 n = gst_caps_get_size (peer_caps);
751 for (i = 0; i < n; i++) {
752 s = gst_caps_get_structure (peer_caps, i);
754 gst_structure_set_name (s, "image/jpeg");
757 templ_caps = gst_pad_get_pad_template_caps (pad);
758 caps = gst_caps_intersect_full (peer_caps, templ_caps,
759 GST_CAPS_INTERSECT_FIRST);
761 gst_object_unref (peer);
763 caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
772 hresamplecpy1 (guint8 * dest, const guint8 * src, guint len)
776 for (i = 0; i < len; ++i) {
777 /* equivalent to: dest[i] = src[i << 1] */
786 gst_jpeg_dec_free_buffers (GstJpegDec * dec)
790 for (i = 0; i < 16; i++) {
791 g_free (dec->idr_y[i]);
792 g_free (dec->idr_u[i]);
793 g_free (dec->idr_v[i]);
794 dec->idr_y[i] = NULL;
795 dec->idr_u[i] = NULL;
796 dec->idr_v[i] = NULL;
799 dec->idr_width_allocated = 0;
802 static inline gboolean
803 gst_jpeg_dec_ensure_buffers (GstJpegDec * dec, guint maxrowbytes)
807 if (G_LIKELY (dec->idr_width_allocated >= maxrowbytes))
810 /* FIXME: maybe just alloc one or three blocks altogether? */
811 for (i = 0; i < 16; i++) {
812 dec->idr_y[i] = g_try_realloc (dec->idr_y[i], maxrowbytes);
813 dec->idr_u[i] = g_try_realloc (dec->idr_u[i], maxrowbytes);
814 dec->idr_v[i] = g_try_realloc (dec->idr_v[i], maxrowbytes);
816 if (G_UNLIKELY (!dec->idr_y[i] || !dec->idr_u[i] || !dec->idr_v[i])) {
817 GST_WARNING_OBJECT (dec, "out of memory, i=%d, bytes=%u", i, maxrowbytes);
822 dec->idr_width_allocated = maxrowbytes;
823 GST_LOG_OBJECT (dec, "allocated temp memory, %u bytes/row", maxrowbytes);
828 gst_jpeg_dec_decode_grayscale (GstJpegDec * dec, GstVideoFrame * frame)
831 guchar **scanarray[1] = { rows };
836 gint pstride, rstride;
838 GST_DEBUG_OBJECT (dec, "indirect decoding of grayscale");
840 width = GST_VIDEO_FRAME_WIDTH (frame);
841 height = GST_VIDEO_FRAME_HEIGHT (frame);
843 if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
846 base[0] = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
847 pstride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0);
848 rstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
850 memcpy (rows, dec->idr_y, 16 * sizeof (gpointer));
854 lines = jpeg_read_raw_data (&dec->cinfo, scanarray, DCTSIZE);
855 if (G_LIKELY (lines > 0)) {
856 for (j = 0; (j < DCTSIZE) && (i < height); j++, i++) {
860 for (k = 0; k < width; k++) {
861 base[0][p] = rows[j][k];
867 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
873 gst_jpeg_dec_decode_rgb (GstJpegDec * dec, GstVideoFrame * frame)
875 guchar *r_rows[16], *g_rows[16], *b_rows[16];
876 guchar **scanarray[3] = { r_rows, g_rows, b_rows };
880 guint pstride, rstride;
883 GST_DEBUG_OBJECT (dec, "indirect decoding of RGB");
885 width = GST_VIDEO_FRAME_WIDTH (frame);
886 height = GST_VIDEO_FRAME_HEIGHT (frame);
888 if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
891 for (i = 0; i < 3; i++)
892 base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
894 pstride = GST_VIDEO_FRAME_COMP_PSTRIDE (frame, 0);
895 rstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
897 memcpy (r_rows, dec->idr_y, 16 * sizeof (gpointer));
898 memcpy (g_rows, dec->idr_u, 16 * sizeof (gpointer));
899 memcpy (b_rows, dec->idr_v, 16 * sizeof (gpointer));
903 lines = jpeg_read_raw_data (&dec->cinfo, scanarray, DCTSIZE);
904 if (G_LIKELY (lines > 0)) {
905 for (j = 0; (j < DCTSIZE) && (i < height); j++, i++) {
909 for (k = 0; k < width; k++) {
910 base[0][p] = r_rows[j][k];
911 base[1][p] = g_rows[j][k];
912 base[2][p] = b_rows[j][k];
920 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
926 gst_jpeg_dec_decode_indirect (GstJpegDec * dec, GstVideoFrame * frame,
927 gint r_v, gint r_h, gint comp)
929 guchar *y_rows[16], *u_rows[16], *v_rows[16];
930 guchar **scanarray[3] = { y_rows, u_rows, v_rows };
933 guchar *base[3], *last[3];
937 GST_DEBUG_OBJECT (dec,
938 "unadvantageous width or r_h, taking slow route involving memcpy");
940 width = GST_VIDEO_FRAME_WIDTH (frame);
941 height = GST_VIDEO_FRAME_HEIGHT (frame);
943 if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
946 for (i = 0; i < 3; i++) {
947 base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
948 stride[i] = GST_VIDEO_FRAME_COMP_STRIDE (frame, i);
949 /* make sure we don't make jpeglib write beyond our buffer,
950 * which might happen if (height % (r_v*DCTSIZE)) != 0 */
951 last[i] = base[i] + (GST_VIDEO_FRAME_COMP_STRIDE (frame, i) *
952 (GST_VIDEO_FRAME_COMP_HEIGHT (frame, i) - 1));
955 memcpy (y_rows, dec->idr_y, 16 * sizeof (gpointer));
956 memcpy (u_rows, dec->idr_u, 16 * sizeof (gpointer));
957 memcpy (v_rows, dec->idr_v, 16 * sizeof (gpointer));
959 /* fill chroma components for grayscale */
961 GST_DEBUG_OBJECT (dec, "grayscale, filling chroma");
962 for (i = 0; i < 16; i++) {
963 memset (u_rows[i], GST_ROUND_UP_32 (width), 0x80);
964 memset (v_rows[i], GST_ROUND_UP_32 (width), 0x80);
968 for (i = 0; i < height; i += r_v * DCTSIZE) {
969 lines = jpeg_read_raw_data (&dec->cinfo, scanarray, r_v * DCTSIZE);
970 if (G_LIKELY (lines > 0)) {
971 for (j = 0, k = 0; j < (r_v * DCTSIZE); j += r_v, k++) {
972 if (G_LIKELY (base[0] <= last[0])) {
973 memcpy (base[0], y_rows[j], stride[0]);
974 base[0] += stride[0];
977 if (G_LIKELY (base[0] <= last[0])) {
978 memcpy (base[0], y_rows[j + 1], stride[0]);
979 base[0] += stride[0];
982 if (G_LIKELY (base[1] <= last[1] && base[2] <= last[2])) {
984 memcpy (base[1], u_rows[k], stride[1]);
985 memcpy (base[2], v_rows[k], stride[2]);
986 } else if (r_h == 1) {
987 hresamplecpy1 (base[1], u_rows[k], stride[1]);
988 hresamplecpy1 (base[2], v_rows[k], stride[2]);
990 /* FIXME: implement (at least we avoid crashing by doing nothing) */
994 if (r_v == 2 || (k & 1) != 0) {
995 base[1] += stride[1];
996 base[2] += stride[2];
1000 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
1005 static GstFlowReturn
1006 gst_jpeg_dec_decode_direct (GstJpegDec * dec, GstVideoFrame * frame)
1008 guchar **line[3]; /* the jpeg line buffer */
1009 guchar *y[4 * DCTSIZE] = { NULL, }; /* alloc enough for the lines */
1010 guchar *u[4 * DCTSIZE] = { NULL, }; /* r_v will be <4 */
1011 guchar *v[4 * DCTSIZE] = { NULL, };
1013 gint lines, v_samp[3];
1014 guchar *base[3], *last[3];
1022 v_samp[0] = dec->cinfo.comp_info[0].v_samp_factor;
1023 v_samp[1] = dec->cinfo.comp_info[1].v_samp_factor;
1024 v_samp[2] = dec->cinfo.comp_info[2].v_samp_factor;
1026 if (G_UNLIKELY (v_samp[0] > 2 || v_samp[1] > 2 || v_samp[2] > 2))
1027 goto format_not_supported;
1029 height = GST_VIDEO_FRAME_HEIGHT (frame);
1031 for (i = 0; i < 3; i++) {
1032 base[i] = GST_VIDEO_FRAME_COMP_DATA (frame, i);
1033 stride[i] = GST_VIDEO_FRAME_COMP_STRIDE (frame, i);
1034 /* make sure we don't make jpeglib write beyond our buffer,
1035 * which might happen if (height % (r_v*DCTSIZE)) != 0 */
1036 last[i] = base[i] + (GST_VIDEO_FRAME_COMP_STRIDE (frame, i) *
1037 (GST_VIDEO_FRAME_COMP_HEIGHT (frame, i) - 1));
1040 /* let jpeglib decode directly into our final buffer */
1041 GST_DEBUG_OBJECT (dec, "decoding directly into output buffer");
1043 for (i = 0; i < height; i += v_samp[0] * DCTSIZE) {
1044 for (j = 0; j < (v_samp[0] * DCTSIZE); ++j) {
1046 line[0][j] = base[0] + (i + j) * stride[0];
1047 if (G_UNLIKELY (line[0][j] > last[0]))
1048 line[0][j] = last[0];
1050 if (v_samp[1] == v_samp[0]) {
1051 line[1][j] = base[1] + ((i + j) / 2) * stride[1];
1052 } else if (j < (v_samp[1] * DCTSIZE)) {
1053 line[1][j] = base[1] + ((i / 2) + j) * stride[1];
1055 if (G_UNLIKELY (line[1][j] > last[1]))
1056 line[1][j] = last[1];
1058 if (v_samp[2] == v_samp[0]) {
1059 line[2][j] = base[2] + ((i + j) / 2) * stride[2];
1060 } else if (j < (v_samp[2] * DCTSIZE)) {
1061 line[2][j] = base[2] + ((i / 2) + j) * stride[2];
1063 if (G_UNLIKELY (line[2][j] > last[2]))
1064 line[2][j] = last[2];
1067 lines = jpeg_read_raw_data (&dec->cinfo, line, v_samp[0] * DCTSIZE);
1068 if (G_UNLIKELY (!lines)) {
1069 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
1074 format_not_supported:
1076 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1077 "Unsupported subsampling schema: v_samp factors: %u %u %u",
1078 v_samp[0], v_samp[1], v_samp[2]);
1079 return GST_FLOW_ERROR;
1084 gst_jpeg_dec_update_qos (GstJpegDec * dec, gdouble proportion,
1085 GstClockTimeDiff diff, GstClockTime ts)
1087 GST_OBJECT_LOCK (dec);
1088 dec->proportion = proportion;
1089 if (G_LIKELY (ts != GST_CLOCK_TIME_NONE)) {
1090 if (G_UNLIKELY (diff > dec->qos_duration))
1091 dec->earliest_time = ts + 2 * diff + dec->qos_duration;
1093 dec->earliest_time = ts + diff;
1095 dec->earliest_time = GST_CLOCK_TIME_NONE;
1097 GST_OBJECT_UNLOCK (dec);
1101 gst_jpeg_dec_reset_qos (GstJpegDec * dec)
1103 gst_jpeg_dec_update_qos (dec, 0.5, 0, GST_CLOCK_TIME_NONE);
1107 gst_jpeg_dec_read_qos (GstJpegDec * dec, gdouble * proportion,
1108 GstClockTime * time)
1110 GST_OBJECT_LOCK (dec);
1111 *proportion = dec->proportion;
1112 *time = dec->earliest_time;
1113 GST_OBJECT_UNLOCK (dec);
1116 /* Perform qos calculations before decoding the next frame. Returns TRUE if the
1117 * frame should be decoded, FALSE if the frame can be dropped entirely */
1119 gst_jpeg_dec_do_qos (GstJpegDec * dec, GstClockTime timestamp)
1121 GstClockTime qostime, earliest_time;
1124 /* no timestamp, can't do QoS => decode frame */
1125 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (timestamp))) {
1126 GST_LOG_OBJECT (dec, "invalid timestamp, can't do QoS, decode frame");
1130 /* get latest QoS observation values */
1131 gst_jpeg_dec_read_qos (dec, &proportion, &earliest_time);
1133 /* skip qos if we have no observation (yet) => decode frame */
1134 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (earliest_time))) {
1135 GST_LOG_OBJECT (dec, "no observation yet, decode frame");
1139 /* qos is done on running time */
1140 qostime = gst_segment_to_running_time (&dec->segment, GST_FORMAT_TIME,
1143 /* see how our next timestamp relates to the latest qos timestamp */
1144 GST_LOG_OBJECT (dec, "qostime %" GST_TIME_FORMAT ", earliest %"
1145 GST_TIME_FORMAT, GST_TIME_ARGS (qostime), GST_TIME_ARGS (earliest_time));
1147 if (qostime != GST_CLOCK_TIME_NONE && qostime <= earliest_time) {
1148 GST_DEBUG_OBJECT (dec, "we are late, drop frame");
1152 GST_LOG_OBJECT (dec, "decode frame");
1157 gst_jpeg_dec_buffer_pool (GstJpegDec * dec, GstCaps * caps)
1160 GstBufferPool *pool = NULL;
1161 guint size, min, max, prefix, alignment;
1162 GstStructure *config;
1164 GST_DEBUG_OBJECT (dec, "setting up bufferpool");
1166 /* find a pool for the negotiated caps now */
1167 query = gst_query_new_allocation (caps, TRUE);
1169 if (gst_pad_peer_query (dec->srcpad, query)) {
1170 /* we got configuration from our peer, parse them */
1171 gst_query_parse_allocation_params (query, &size, &min, &max, &prefix,
1173 size = MAX (size, dec->info.size);
1175 GST_DEBUG_OBJECT (dec, "peer query failed, using defaults");
1176 size = dec->info.size;
1181 gst_query_unref (query);
1184 /* we did not get a pool, make one ourselves then */
1185 pool = gst_buffer_pool_new ();
1188 config = gst_buffer_pool_get_config (pool);
1189 gst_buffer_pool_config_set (config, caps, size, min, max, prefix,
1192 gst_buffer_pool_set_config (pool, config);
1195 gst_buffer_pool_set_active (dec->pool, FALSE);
1196 gst_object_unref (dec->pool);
1201 gst_buffer_pool_set_active (pool, TRUE);
1207 gst_jpeg_dec_negotiate (GstJpegDec * dec, gint width, gint height, gint clrspc)
1210 GstVideoFormat format;
1213 if (G_UNLIKELY (width == dec->info.width && height == dec->info.height &&
1214 dec->in_fps_n == dec->info.fps_n && dec->in_fps_d == dec->info.fps_d
1215 && clrspc == dec->clrspc))
1218 gst_video_info_init (&info);
1220 /* framerate == 0/1 is a still frame */
1221 if (dec->in_fps_d == 0) {
1225 info.fps_n = dec->in_fps_n;
1226 info.fps_d = dec->in_fps_d;
1229 /* calculate or assume an average frame duration for QoS purposes */
1230 GST_OBJECT_LOCK (dec);
1231 if (info.fps_n != 0) {
1233 gst_util_uint64_scale (GST_SECOND, info.fps_d, info.fps_n);
1234 dec->duration = dec->qos_duration;
1236 /* if not set just use 25fps */
1237 dec->qos_duration = gst_util_uint64_scale (GST_SECOND, 1, 25);
1238 dec->duration = GST_CLOCK_TIME_NONE;
1240 GST_OBJECT_UNLOCK (dec);
1242 if (dec->cinfo.jpeg_color_space == JCS_RGB) {
1244 GstCaps *allowed_caps;
1245 GstVideoInfo tmpinfo;
1247 GST_DEBUG_OBJECT (dec, "selecting RGB format");
1248 /* retrieve allowed caps, and find the first one that reasonably maps
1249 * to the parameters of the colourspace */
1250 caps = gst_pad_get_allowed_caps (dec->srcpad);
1252 GST_DEBUG_OBJECT (dec, "... but no peer, using template caps");
1253 /* need to copy because get_allowed_caps returns a ref,
1254 * and get_pad_template_caps doesn't */
1255 caps = gst_caps_copy (gst_pad_get_pad_template_caps (dec->srcpad));
1257 /* avoid lists of formats, etc */
1258 allowed_caps = gst_caps_normalize (caps);
1259 gst_caps_unref (caps);
1261 GST_LOG_OBJECT (dec, "allowed source caps %" GST_PTR_FORMAT, allowed_caps);
1263 for (i = 0; i < gst_caps_get_size (allowed_caps); i++) {
1265 gst_caps_unref (caps);
1266 caps = gst_caps_copy_nth (allowed_caps, i);
1267 /* sigh, ds and _parse_caps need fixed caps for parsing, fixate */
1268 gst_caps_fixate (caps);
1269 GST_LOG_OBJECT (dec, "checking caps %" GST_PTR_FORMAT, caps);
1271 if (!gst_video_info_from_caps (&tmpinfo, caps))
1273 /* we'll settle for the first (preferred) downstream rgb format */
1274 if (GST_VIDEO_INFO_IS_RGB (&tmpinfo))
1276 /* default fall-back */
1277 format = GST_VIDEO_FORMAT_RGB;
1280 gst_caps_unref (caps);
1281 gst_caps_unref (allowed_caps);
1282 } else if (dec->cinfo.jpeg_color_space == JCS_GRAYSCALE) {
1283 /* TODO is anything else then 8bit supported in jpeg? */
1284 format = GST_VIDEO_FORMAT_GRAY8;
1286 /* go for plain and simple I420 */
1287 /* TODO other YUV cases ? */
1288 format = GST_VIDEO_FORMAT_I420;
1291 gst_video_info_set_format (&info, format, width, height);
1292 caps = gst_video_info_to_caps (&info);
1294 GST_DEBUG_OBJECT (dec, "setting caps %" GST_PTR_FORMAT, caps);
1295 GST_DEBUG_OBJECT (dec, "max_v_samp_factor=%d", dec->cinfo.max_v_samp_factor);
1296 GST_DEBUG_OBJECT (dec, "max_h_samp_factor=%d", dec->cinfo.max_h_samp_factor);
1298 gst_pad_set_caps (dec->srcpad, caps);
1301 dec->clrspc = clrspc;
1303 gst_jpeg_dec_buffer_pool (dec, caps);
1304 gst_caps_unref (caps);
1309 static GstFlowReturn
1310 gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf)
1312 GstFlowReturn ret = GST_FLOW_OK;
1314 GstBuffer *outbuf = NULL;
1319 GstClockTime timestamp, duration;
1320 GstVideoFrame frame;
1322 dec = GST_JPEG_DEC (GST_PAD_PARENT (pad));
1324 timestamp = GST_BUFFER_TIMESTAMP (buf);
1325 duration = GST_BUFFER_DURATION (buf);
1327 if (GST_CLOCK_TIME_IS_VALID (timestamp))
1328 dec->next_ts = timestamp;
1330 if (GST_BUFFER_IS_DISCONT (buf)) {
1331 GST_DEBUG_OBJECT (dec, "buffer has DISCONT flag set");
1332 dec->discont = TRUE;
1333 if (!dec->packetized && gst_adapter_available (dec->adapter)) {
1334 GST_WARNING_OBJECT (dec, "DISCONT buffer in non-packetized mode, bad");
1335 gst_adapter_clear (dec->adapter);
1339 gst_adapter_push (dec->adapter, buf);
1342 /* If we are non-packetized and know the total incoming size in bytes,
1343 * just wait until we have enough before doing any processing. */
1345 if (!dec->packetized && (dec->segment.format == GST_FORMAT_BYTES) &&
1346 (dec->segment.stop != -1) &&
1347 (gst_adapter_available (dec->adapter) < dec->segment.stop)) {
1348 /* We assume that non-packetized input in bytes is *one* single jpeg image */
1349 GST_DEBUG ("Non-packetized mode. Got %d bytes, need %" G_GINT64_FORMAT,
1350 gst_adapter_available (dec->adapter), dec->segment.stop);
1351 goto need_more_data;
1355 if (!gst_jpeg_dec_ensure_header (dec))
1356 goto need_more_data;
1358 /* If we know that each input buffer contains data
1359 * for a whole jpeg image (e.g. MJPEG streams), just
1360 * do some sanity checking instead of parsing all of
1362 if (dec->packetized) {
1363 img_len = gst_adapter_available (dec->adapter);
1365 /* Parse jpeg image to handle jpeg input that
1366 * is not aligned to buffer boundaries */
1367 img_len = gst_jpeg_dec_parse_image_data (dec);
1370 goto need_more_data;
1371 } else if (img_len < 0) {
1372 gst_adapter_flush (dec->adapter, -img_len);
1377 dec->rem_img_len = img_len;
1379 GST_LOG_OBJECT (dec, "image size = %u", img_len);
1381 /* QoS: if we're too late anyway, skip decoding */
1382 if (dec->packetized && !gst_jpeg_dec_do_qos (dec, timestamp))
1385 #ifndef GST_DISABLE_GST_DEBUG
1389 gst_adapter_copy (dec->adapter, data, 0, 4);
1390 GST_LOG_OBJECT (dec, "reading header %02x %02x %02x %02x", data[0], data[1],
1395 gst_jpeg_dec_fill_input_buffer (&dec->cinfo);
1397 if (setjmp (dec->jerr.setjmp_buffer)) {
1398 code = dec->jerr.pub.msg_code;
1400 if (code == JERR_INPUT_EOF) {
1401 GST_DEBUG ("jpeg input EOF error, we probably need more data");
1402 goto need_more_data;
1408 hdr_ok = jpeg_read_header (&dec->cinfo, TRUE);
1409 if (G_UNLIKELY (hdr_ok != JPEG_HEADER_OK)) {
1410 GST_WARNING_OBJECT (dec, "reading the header failed, %d", hdr_ok);
1413 GST_LOG_OBJECT (dec, "num_components=%d", dec->cinfo.num_components);
1414 GST_LOG_OBJECT (dec, "jpeg_color_space=%d", dec->cinfo.jpeg_color_space);
1416 if (!dec->cinfo.num_components || !dec->cinfo.comp_info)
1417 goto components_not_supported;
1419 r_h = dec->cinfo.comp_info[0].h_samp_factor;
1420 r_v = dec->cinfo.comp_info[0].v_samp_factor;
1422 GST_LOG_OBJECT (dec, "r_h = %d, r_v = %d", r_h, r_v);
1424 if (dec->cinfo.num_components > 3)
1425 goto components_not_supported;
1427 /* verify color space expectation to avoid going *boom* or bogus output */
1428 if (dec->cinfo.jpeg_color_space != JCS_YCbCr &&
1429 dec->cinfo.jpeg_color_space != JCS_GRAYSCALE &&
1430 dec->cinfo.jpeg_color_space != JCS_RGB)
1431 goto unsupported_colorspace;
1433 #ifndef GST_DISABLE_GST_DEBUG
1437 for (i = 0; i < dec->cinfo.num_components; ++i) {
1438 GST_LOG_OBJECT (dec, "[%d] h_samp_factor=%d, v_samp_factor=%d, cid=%d",
1439 i, dec->cinfo.comp_info[i].h_samp_factor,
1440 dec->cinfo.comp_info[i].v_samp_factor,
1441 dec->cinfo.comp_info[i].component_id);
1446 /* prepare for raw output */
1447 dec->cinfo.do_fancy_upsampling = FALSE;
1448 dec->cinfo.do_block_smoothing = FALSE;
1449 dec->cinfo.out_color_space = dec->cinfo.jpeg_color_space;
1450 dec->cinfo.dct_method = dec->idct_method;
1451 dec->cinfo.raw_data_out = TRUE;
1453 GST_LOG_OBJECT (dec, "starting decompress");
1454 guarantee_huff_tables (&dec->cinfo);
1455 if (!jpeg_start_decompress (&dec->cinfo)) {
1456 GST_WARNING_OBJECT (dec, "failed to start decompression cycle");
1459 /* sanity checks to get safe and reasonable output */
1460 switch (dec->cinfo.jpeg_color_space) {
1462 if (dec->cinfo.num_components != 1)
1463 goto invalid_yuvrgbgrayscale;
1466 if (dec->cinfo.num_components != 3 || dec->cinfo.max_v_samp_factor > 1 ||
1467 dec->cinfo.max_h_samp_factor > 1)
1468 goto invalid_yuvrgbgrayscale;
1471 if (dec->cinfo.num_components != 3 ||
1472 r_v > 2 || r_v < dec->cinfo.comp_info[0].v_samp_factor ||
1473 r_v < dec->cinfo.comp_info[1].v_samp_factor ||
1474 r_h < dec->cinfo.comp_info[0].h_samp_factor ||
1475 r_h < dec->cinfo.comp_info[1].h_samp_factor)
1476 goto invalid_yuvrgbgrayscale;
1479 g_assert_not_reached ();
1483 width = dec->cinfo.output_width;
1484 height = dec->cinfo.output_height;
1486 if (G_UNLIKELY (width < MIN_WIDTH || width > MAX_WIDTH ||
1487 height < MIN_HEIGHT || height > MAX_HEIGHT))
1490 gst_jpeg_dec_negotiate (dec, width, height, dec->cinfo.jpeg_color_space);
1492 ret = gst_buffer_pool_acquire_buffer (dec->pool, &outbuf, NULL);
1493 if (G_UNLIKELY (ret != GST_FLOW_OK))
1496 if (!gst_video_frame_map (&frame, &dec->info, outbuf, GST_MAP_READWRITE))
1499 GST_LOG_OBJECT (dec, "width %d, height %d", width, height);
1501 GST_BUFFER_TIMESTAMP (outbuf) = dec->next_ts;
1503 if (dec->packetized && GST_CLOCK_TIME_IS_VALID (dec->next_ts)) {
1504 if (GST_CLOCK_TIME_IS_VALID (duration)) {
1505 /* use duration from incoming buffer for outgoing buffer */
1506 dec->next_ts += duration;
1507 } else if (GST_CLOCK_TIME_IS_VALID (dec->duration)) {
1508 duration = dec->duration;
1509 dec->next_ts += dec->duration;
1511 duration = GST_CLOCK_TIME_NONE;
1512 dec->next_ts = GST_CLOCK_TIME_NONE;
1515 duration = GST_CLOCK_TIME_NONE;
1516 dec->next_ts = GST_CLOCK_TIME_NONE;
1518 GST_BUFFER_DURATION (outbuf) = duration;
1520 if (dec->cinfo.jpeg_color_space == JCS_RGB) {
1521 gst_jpeg_dec_decode_rgb (dec, &frame);
1522 } else if (dec->cinfo.jpeg_color_space == JCS_GRAYSCALE) {
1523 gst_jpeg_dec_decode_grayscale (dec, &frame);
1525 GST_LOG_OBJECT (dec, "decompressing (reqired scanline buffer height = %u)",
1526 dec->cinfo.rec_outbuf_height);
1528 /* For some widths jpeglib requires more horizontal padding than I420
1529 * provides. In those cases we need to decode into separate buffers and then
1530 * copy over the data into our final picture buffer, otherwise jpeglib might
1531 * write over the end of a line into the beginning of the next line,
1532 * resulting in blocky artifacts on the left side of the picture. */
1533 if (G_UNLIKELY (width % (dec->cinfo.max_h_samp_factor * DCTSIZE) != 0
1534 || dec->cinfo.comp_info[0].h_samp_factor != 2
1535 || dec->cinfo.comp_info[1].h_samp_factor != 1
1536 || dec->cinfo.comp_info[2].h_samp_factor != 1)) {
1537 GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, dec,
1538 "indirect decoding using extra buffer copy");
1539 gst_jpeg_dec_decode_indirect (dec, &frame, r_v, r_h,
1540 dec->cinfo.num_components);
1542 ret = gst_jpeg_dec_decode_direct (dec, &frame);
1543 if (G_UNLIKELY (ret != GST_FLOW_OK))
1544 goto decode_direct_failed;
1548 GST_LOG_OBJECT (dec, "decompressing finished");
1549 jpeg_finish_decompress (&dec->cinfo);
1551 gst_video_frame_unmap (&frame);
1554 if (dec->segment.format == GST_FORMAT_TIME) {
1555 guint64 start, stop, clip_start, clip_stop;
1557 GST_LOG_OBJECT (dec, "Attempting clipping");
1559 start = GST_BUFFER_TIMESTAMP (outbuf);
1560 if (GST_BUFFER_DURATION (outbuf) == GST_CLOCK_TIME_NONE)
1563 stop = start + GST_BUFFER_DURATION (outbuf);
1565 if (gst_segment_clip (&dec->segment, GST_FORMAT_TIME,
1566 start, stop, &clip_start, &clip_stop)) {
1567 GST_LOG_OBJECT (dec, "Clipping start to %" GST_TIME_FORMAT,
1568 GST_TIME_ARGS (clip_start));
1569 GST_BUFFER_TIMESTAMP (outbuf) = clip_start;
1570 if (GST_BUFFER_DURATION (outbuf) != GST_CLOCK_TIME_NONE) {
1571 GST_LOG_OBJECT (dec, "Clipping duration to %" GST_TIME_FORMAT,
1572 GST_TIME_ARGS (clip_stop - clip_start));
1573 GST_BUFFER_DURATION (outbuf) = clip_stop - clip_start;
1579 /* reset error count on successful decode */
1580 dec->error_count = 0;
1584 GST_LOG_OBJECT (dec, "pushing buffer (ts=%" GST_TIME_FORMAT ", dur=%"
1585 GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
1586 GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
1588 ret = gst_pad_push (dec->srcpad, outbuf);
1592 gst_adapter_flush (dec->adapter, dec->rem_img_len);
1596 if (G_UNLIKELY (ret == GST_FLOW_ERROR)) {
1597 jpeg_abort_decompress (&dec->cinfo);
1598 ret = gst_jpeg_dec_post_error_or_warning (dec);
1606 GST_LOG_OBJECT (dec, "we need more data");
1608 gst_buffer_unref (outbuf);
1617 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1618 "Picture is too small or too big (%ux%u)", width, height);
1619 ret = GST_FLOW_ERROR;
1624 gchar err_msg[JMSG_LENGTH_MAX];
1626 dec->jerr.pub.format_message ((j_common_ptr) (&dec->cinfo), err_msg);
1628 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1629 "Decode error #%u: %s", code, err_msg);
1632 gst_buffer_unref (outbuf);
1635 ret = GST_FLOW_ERROR;
1638 decode_direct_failed:
1640 /* already posted an error message */
1641 jpeg_abort_decompress (&dec->cinfo);
1642 gst_buffer_replace (&outbuf, NULL);
1647 const gchar *reason;
1649 reason = gst_flow_get_name (ret);
1651 GST_DEBUG_OBJECT (dec, "failed to alloc buffer, reason %s", reason);
1652 /* Reset for next time */
1653 jpeg_abort_decompress (&dec->cinfo);
1654 if (ret != GST_FLOW_UNEXPECTED && ret != GST_FLOW_WRONG_STATE &&
1655 ret != GST_FLOW_NOT_LINKED) {
1656 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1657 "Buffer allocation failed, reason: %s", reason);
1663 jpeg_abort_decompress (&dec->cinfo);
1664 gst_buffer_unref (outbuf);
1670 GST_WARNING_OBJECT (dec, "Outgoing buffer is outside configured segment");
1671 gst_buffer_unref (outbuf);
1675 components_not_supported:
1677 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1678 "number of components not supported: %d (max 3)",
1679 dec->cinfo.num_components);
1680 ret = GST_FLOW_ERROR;
1683 unsupported_colorspace:
1685 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1686 "Picture has unknown or unsupported colourspace");
1687 ret = GST_FLOW_ERROR;
1690 invalid_yuvrgbgrayscale:
1692 gst_jpeg_dec_set_error (dec, GST_FUNCTION, __LINE__,
1693 "Picture is corrupt or unhandled YUV/RGB/grayscale layout");
1694 ret = GST_FLOW_ERROR;
1700 gst_jpeg_dec_src_event (GstPad * pad, GstEvent * event)
1705 dec = GST_JPEG_DEC (gst_pad_get_parent (pad));
1706 if (G_UNLIKELY (dec == NULL)) {
1707 gst_event_unref (event);
1711 switch (GST_EVENT_TYPE (event)) {
1712 case GST_EVENT_QOS:{
1714 GstClockTimeDiff diff;
1715 GstClockTime timestamp;
1718 gst_event_parse_qos (event, &type, &proportion, &diff, ×tamp);
1719 gst_jpeg_dec_update_qos (dec, proportion, diff, timestamp);
1726 res = gst_pad_push_event (dec->sinkpad, event);
1728 gst_object_unref (dec);
1733 gst_jpeg_dec_sink_event (GstPad * pad, GstEvent * event)
1735 gboolean ret = TRUE, forward = TRUE;
1736 GstJpegDec *dec = GST_JPEG_DEC (GST_OBJECT_PARENT (pad));
1738 GST_DEBUG_OBJECT (dec, "event : %s", GST_EVENT_TYPE_NAME (event));
1740 switch (GST_EVENT_TYPE (event)) {
1741 case GST_EVENT_FLUSH_STOP:
1742 GST_DEBUG_OBJECT (dec, "Aborting decompress");
1743 jpeg_abort_decompress (&dec->cinfo);
1744 gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED);
1745 gst_adapter_clear (dec->adapter);
1746 g_free (dec->cur_buf);
1747 dec->cur_buf = NULL;
1748 dec->parse_offset = 0;
1749 dec->parse_entropy_len = 0;
1750 dec->parse_resync = FALSE;
1751 gst_jpeg_dec_reset_qos (dec);
1753 case GST_EVENT_SEGMENT:
1754 gst_event_copy_segment (event, &dec->segment);
1755 GST_DEBUG_OBJECT (dec, "Got NEWSEGMENT %" GST_SEGMENT_FORMAT,
1758 case GST_EVENT_CAPS:
1762 gst_event_parse_caps (event, &caps);
1763 ret = gst_jpeg_dec_setcaps (dec, caps);
1772 ret = gst_pad_push_event (dec->srcpad, event);
1774 gst_event_unref (event);
1780 gst_jpeg_dec_sink_query (GstPad * pad, GstQuery * query)
1782 gboolean res = FALSE;
1784 switch (GST_QUERY_TYPE (query)) {
1785 case GST_QUERY_CAPS:
1787 GstCaps *filter, *caps;
1789 gst_query_parse_caps (query, &filter);
1790 caps = gst_jpeg_dec_getcaps (pad, filter);
1791 gst_query_set_caps_result (query, caps);
1792 gst_caps_unref (caps);
1797 res = gst_pad_query_default (pad, query);
1804 gst_jpeg_dec_set_property (GObject * object, guint prop_id,
1805 const GValue * value, GParamSpec * pspec)
1809 dec = GST_JPEG_DEC (object);
1812 case PROP_IDCT_METHOD:
1813 dec->idct_method = g_value_get_enum (value);
1815 case PROP_MAX_ERRORS:
1816 g_atomic_int_set (&dec->max_errors, g_value_get_int (value));
1820 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1826 gst_jpeg_dec_get_property (GObject * object, guint prop_id, GValue * value,
1831 dec = GST_JPEG_DEC (object);
1834 case PROP_IDCT_METHOD:
1835 g_value_set_enum (value, dec->idct_method);
1837 case PROP_MAX_ERRORS:
1838 g_value_set_int (value, g_atomic_int_get (&dec->max_errors));
1842 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1847 static GstStateChangeReturn
1848 gst_jpeg_dec_change_state (GstElement * element, GstStateChange transition)
1850 GstStateChangeReturn ret;
1853 dec = GST_JPEG_DEC (element);
1855 switch (transition) {
1856 case GST_STATE_CHANGE_READY_TO_PAUSED:
1857 dec->error_count = 0;
1858 dec->good_count = 0;
1861 gst_video_info_init (&dec->info);
1863 dec->packetized = FALSE;
1865 dec->discont = TRUE;
1866 dec->parse_offset = 0;
1867 dec->parse_entropy_len = 0;
1868 dec->parse_resync = FALSE;
1869 dec->cur_buf = NULL;
1870 gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED);
1871 gst_jpeg_dec_reset_qos (dec);
1876 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1877 if (ret != GST_STATE_CHANGE_SUCCESS)
1880 switch (transition) {
1881 case GST_STATE_CHANGE_PAUSED_TO_READY:
1882 gst_adapter_clear (dec->adapter);
1883 g_free (dec->cur_buf);
1884 dec->cur_buf = NULL;
1885 gst_jpeg_dec_free_buffers (dec);
1887 gst_buffer_pool_set_active (dec->pool, FALSE);
1888 gst_object_unref (dec->pool);