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 ! jpegddec ! 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 JPEG_DEFAULT_IDCT_METHOD JDCT_FASTEST
59 static GstStaticPadTemplate gst_jpeg_dec_src_pad_template =
60 GST_STATIC_PAD_TEMPLATE ("src",
63 GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420"))
66 static GstStaticPadTemplate gst_jpeg_dec_sink_pad_template =
67 GST_STATIC_PAD_TEMPLATE ("sink",
70 GST_STATIC_CAPS ("image/jpeg, "
71 "width = (int) [ " G_STRINGIFY (MIN_WIDTH) ", " G_STRINGIFY (MAX_WIDTH)
72 " ], " "height = (int) [ " G_STRINGIFY (MIN_HEIGHT) ", "
73 G_STRINGIFY (MAX_HEIGHT) " ], " "framerate = (fraction) [ 0/1, MAX ]")
76 GST_DEBUG_CATEGORY_STATIC (jpeg_dec_debug);
77 #define GST_CAT_DEFAULT jpeg_dec_debug
78 GST_DEBUG_CATEGORY_STATIC (GST_CAT_PERFORMANCE);
80 /* These macros are adapted from videotestsrc.c
81 * and/or gst-plugins/gst/games/gstvideoimage.c */
82 #define I420_Y_ROWSTRIDE(width) (GST_ROUND_UP_4(width))
83 #define I420_U_ROWSTRIDE(width) (GST_ROUND_UP_8(width)/2)
84 #define I420_V_ROWSTRIDE(width) ((GST_ROUND_UP_8(I420_Y_ROWSTRIDE(width)))/2)
86 #define I420_Y_OFFSET(w,h) (0)
87 #define I420_U_OFFSET(w,h) (I420_Y_OFFSET(w,h)+(I420_Y_ROWSTRIDE(w)*GST_ROUND_UP_2(h)))
88 #define I420_V_OFFSET(w,h) (I420_U_OFFSET(w,h)+(I420_U_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2))
90 #define I420_SIZE(w,h) (I420_V_OFFSET(w,h)+(I420_V_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2))
92 static GstElementClass *parent_class; /* NULL */
94 static void gst_jpeg_dec_base_init (gpointer g_class);
95 static void gst_jpeg_dec_class_init (GstJpegDecClass * klass);
96 static void gst_jpeg_dec_init (GstJpegDec * jpegdec);
98 static void gst_jpeg_dec_set_property (GObject * object, guint prop_id,
99 const GValue * value, GParamSpec * pspec);
100 static void gst_jpeg_dec_get_property (GObject * object, guint prop_id,
101 GValue * value, GParamSpec * pspec);
103 static GstFlowReturn gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buffer);
104 static gboolean gst_jpeg_dec_setcaps (GstPad * pad, GstCaps * caps);
105 static gboolean gst_jpeg_dec_sink_event (GstPad * pad, GstEvent * event);
106 static gboolean gst_jpeg_dec_src_event (GstPad * pad, GstEvent * event);
107 static GstStateChangeReturn gst_jpeg_dec_change_state (GstElement * element,
108 GstStateChange transition);
109 static void gst_jpeg_dec_update_qos (GstJpegDec * dec, gdouble proportion,
110 GstClockTimeDiff diff, GstClockTime ts);
111 static void gst_jpeg_dec_reset_qos (GstJpegDec * dec);
112 static void gst_jpeg_dec_read_qos (GstJpegDec * dec, gdouble * proportion,
113 GstClockTime * time);
116 gst_jpeg_dec_get_type (void)
118 static GType type = 0;
121 static const GTypeInfo jpeg_dec_info = {
122 sizeof (GstJpegDecClass),
123 (GBaseInitFunc) gst_jpeg_dec_base_init,
125 (GClassInitFunc) gst_jpeg_dec_class_init,
130 (GInstanceInitFunc) gst_jpeg_dec_init,
133 type = g_type_register_static (GST_TYPE_ELEMENT, "GstJpegDec",
140 gst_jpeg_dec_finalize (GObject * object)
142 GstJpegDec *dec = GST_JPEG_DEC (object);
144 jpeg_destroy_decompress (&dec->cinfo);
147 gst_buffer_unref (dec->tempbuf);
149 G_OBJECT_CLASS (parent_class)->finalize (object);
153 gst_jpeg_dec_base_init (gpointer g_class)
155 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
157 gst_element_class_add_pad_template (element_class,
158 gst_static_pad_template_get (&gst_jpeg_dec_src_pad_template));
159 gst_element_class_add_pad_template (element_class,
160 gst_static_pad_template_get (&gst_jpeg_dec_sink_pad_template));
161 gst_element_class_set_details_simple (element_class, "JPEG image decoder",
162 "Codec/Decoder/Image",
163 "Decode images from JPEG format", "Wim Taymans <wim@fluendo.com>");
167 gst_jpeg_dec_class_init (GstJpegDecClass * klass)
169 GstElementClass *gstelement_class;
170 GObjectClass *gobject_class;
172 gstelement_class = (GstElementClass *) klass;
173 gobject_class = (GObjectClass *) klass;
175 parent_class = g_type_class_peek_parent (klass);
177 gobject_class->finalize = gst_jpeg_dec_finalize;
178 gobject_class->set_property = gst_jpeg_dec_set_property;
179 gobject_class->get_property = gst_jpeg_dec_get_property;
181 g_object_class_install_property (gobject_class, PROP_IDCT_METHOD,
182 g_param_spec_enum ("idct-method", "IDCT Method",
183 "The IDCT algorithm to use", GST_TYPE_IDCT_METHOD,
184 JPEG_DEFAULT_IDCT_METHOD, G_PARAM_READWRITE));
186 gstelement_class->change_state =
187 GST_DEBUG_FUNCPTR (gst_jpeg_dec_change_state);
189 GST_DEBUG_CATEGORY_INIT (jpeg_dec_debug, "jpegdec", 0, "JPEG decoder");
190 GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE");
194 gst_jpeg_dec_fill_input_buffer (j_decompress_ptr cinfo)
197 struct GstJpegDecSourceMgr *src_mgr;
200 src_mgr = (struct GstJpegDecSourceMgr*) &cinfo->src;
201 dec = GST_JPEG_DEC (src_mgr->dec);
203 GST_DEBUG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "fill_input_buffer");
205 g_return_val_if_fail (dec != NULL, TRUE);
207 src_mgr->pub.next_input_byte = GST_BUFFER_DATA (dec->tempbuf);
208 src_mgr->pub.bytes_in_buffer = GST_BUFFER_SIZE (dec->tempbuf);
214 gst_jpeg_dec_init_source (j_decompress_ptr cinfo)
216 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "init_source");
221 gst_jpeg_dec_skip_input_data (j_decompress_ptr cinfo, glong num_bytes)
223 GST_DEBUG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "skip %ld bytes", num_bytes);
225 if (num_bytes > 0 && cinfo->src->bytes_in_buffer >= num_bytes) {
226 cinfo->src->next_input_byte += (size_t) num_bytes;
227 cinfo->src->bytes_in_buffer -= (size_t) num_bytes;
232 gst_jpeg_dec_resync_to_restart (j_decompress_ptr cinfo, gint desired)
234 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "resync_to_start");
239 gst_jpeg_dec_term_source (j_decompress_ptr cinfo)
241 GST_LOG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "term_source");
246 gst_jpeg_dec_my_output_message (j_common_ptr cinfo)
248 return; /* do nothing */
252 gst_jpeg_dec_my_emit_message (j_common_ptr cinfo, int msg_level)
254 /* GST_LOG_OBJECT (CINFO_GET_JPEGDEC (&cinfo), "msg_level=%d", msg_level); */
259 gst_jpeg_dec_my_error_exit (j_common_ptr cinfo)
261 struct GstJpegDecErrorMgr *err_mgr = (struct GstJpegDecErrorMgr *) cinfo->err;
263 (*cinfo->err->output_message) (cinfo);
264 longjmp (err_mgr->setjmp_buffer, 1);
268 gst_jpeg_dec_init (GstJpegDec * dec)
270 GST_DEBUG ("initializing");
272 /* create the sink and src pads */
274 gst_pad_new_from_static_template (&gst_jpeg_dec_sink_pad_template,
276 gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
277 gst_pad_set_setcaps_function (dec->sinkpad,
278 GST_DEBUG_FUNCPTR (gst_jpeg_dec_setcaps));
279 gst_pad_set_chain_function (dec->sinkpad,
280 GST_DEBUG_FUNCPTR (gst_jpeg_dec_chain));
281 gst_pad_set_event_function (dec->sinkpad,
282 GST_DEBUG_FUNCPTR (gst_jpeg_dec_sink_event));
285 gst_pad_new_from_static_template (&gst_jpeg_dec_src_pad_template, "src");
286 gst_pad_set_event_function (dec->srcpad,
287 GST_DEBUG_FUNCPTR (gst_jpeg_dec_src_event));
288 gst_pad_use_fixed_caps (dec->srcpad);
289 gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
292 memset (&dec->cinfo, 0, sizeof (dec->cinfo));
293 memset (&dec->jerr, 0, sizeof (dec->jerr));
294 dec->cinfo.err = jpeg_std_error (&dec->jerr.pub);
295 dec->jerr.pub.output_message = gst_jpeg_dec_my_output_message;
296 dec->jerr.pub.emit_message = gst_jpeg_dec_my_emit_message;
297 dec->jerr.pub.error_exit = gst_jpeg_dec_my_error_exit;
299 jpeg_create_decompress (&dec->cinfo);
301 dec->cinfo.src = (struct jpeg_source_mgr *) &dec->jsrc;
302 dec->cinfo.src->init_source = gst_jpeg_dec_init_source;
303 dec->cinfo.src->fill_input_buffer = gst_jpeg_dec_fill_input_buffer;
304 dec->cinfo.src->skip_input_data = gst_jpeg_dec_skip_input_data;
305 dec->cinfo.src->resync_to_restart = gst_jpeg_dec_resync_to_restart;
306 dec->cinfo.src->term_source = gst_jpeg_dec_term_source;
309 /* init properties */
310 dec->idct_method = JPEG_DEFAULT_IDCT_METHOD;
313 static inline gboolean
314 is_jpeg_start_marker (const guint8 * data)
316 return (data[0] == 0xff && data[1] == 0xd8);
320 gst_jpeg_dec_find_jpeg_header (GstJpegDec * dec)
325 data = GST_BUFFER_DATA (dec->tempbuf);
326 size = GST_BUFFER_SIZE (dec->tempbuf);
328 g_return_val_if_fail (size >= 2, FALSE);
330 while (!is_jpeg_start_marker (data) || data[2] != 0xff) {
331 const guint8 *marker;
335 marker = memchr (data + 1, 0xff, size - 1 - 2);
336 if (marker == NULL) {
337 off = size - 1; /* keep last byte */
342 tmp = gst_buffer_create_sub (dec->tempbuf, off, size - off);
343 gst_buffer_unref (dec->tempbuf);
346 data = GST_BUFFER_DATA (dec->tempbuf);
347 size = GST_BUFFER_SIZE (dec->tempbuf);
350 return FALSE; /* wait for more data */
353 return TRUE; /* got header */
357 gst_jpeg_dec_ensure_header (GstJpegDec * dec)
359 g_return_val_if_fail (dec->tempbuf != NULL, FALSE);
363 /* we need at least a start marker (0xff 0xd8)
364 * and an end marker (0xff 0xd9) */
365 if (GST_BUFFER_SIZE (dec->tempbuf) <= 4) {
366 GST_DEBUG ("Not enough data");
367 return FALSE; /* we need more data */
370 if (!is_jpeg_start_marker (GST_BUFFER_DATA (dec->tempbuf))) {
371 GST_DEBUG ("Not a JPEG header, resyncing to header...");
372 if (!gst_jpeg_dec_find_jpeg_header (dec)) {
373 GST_DEBUG ("No JPEG header in current buffer");
374 return FALSE; /* we need more data */
376 GST_DEBUG ("Found JPEG header");
377 goto check_header; /* buffer might have changed */
385 gst_jpeg_dec_have_end_marker (GstJpegDec * dec)
387 guint8 *data = GST_BUFFER_DATA (dec->tempbuf);
388 guint size = GST_BUFFER_SIZE (dec->tempbuf);
390 return (size > 2 && data && is_jpeg_end_marker (data + size - 2));
394 static inline gboolean
395 gst_jpeg_dec_parse_tag_has_entropy_segment (guint8 tag)
397 if (tag == 0xda || (tag >= 0xd0 && tag <= 0xd7))
402 /* returns image length in bytes if parsed
403 * successfully, otherwise 0 */
405 gst_jpeg_dec_parse_image_data (GstJpegDec * dec)
407 guint8 *start, *data, *end;
410 size = GST_BUFFER_SIZE (dec->tempbuf);
411 start = GST_BUFFER_DATA (dec->tempbuf);
415 g_return_val_if_fail (is_jpeg_start_marker (data), 0);
417 GST_DEBUG ("Parsing jpeg image data (%u bytes)", size);
419 /* skip start marker */
426 /* do we need to resync? */
427 resync = (*data != 0xff);
429 GST_DEBUG ("Lost sync at 0x%08" G_GINT64_MODIFIER "x, resyncing",
430 (gint64) (data - start));
431 /* at the very least we expect 0xff 0xNN, thus end-1 */
432 while (*data != 0xff && data < end - 1)
434 if (G_UNLIKELY (*data != 0xff)) {
435 GST_DEBUG ("at end of input and no next marker found, need more data");
439 /* Skip over extra 0xff */
440 while (*data == 0xff && data < end)
442 /* enough bytes left for marker? (we need 0xNN after the 0xff) */
444 GST_DEBUG ("at end of input and no EOI marker found, need more data");
449 GST_DEBUG ("0x%08" G_GINT64_MODIFIER "x: EOI marker",
450 (gint64) (data - start));
451 return (data - start + 1);
454 if (*data >= 0xd0 && *data <= 0xd7)
456 else if (data >= end - 2)
459 frame_len = GST_READ_UINT16_BE (data + 1);
460 GST_DEBUG ("0x%08" G_GINT64_MODIFIER "x: tag %02x, frame_len=%u",
461 (gint64) (data - start - 1), *data, frame_len);
462 /* the frame length includes the 2 bytes for the length; here we want at
463 * least 2 more bytes at the end for an end marker, thus end-2 */
464 if (data + 1 + frame_len >= end - 2) {
466 GST_DEBUG ("not a valid sync (not enough data).");
467 /* Since *data != 0xff, the next iteration will go into resync again. */
470 /* theoretically we could have lost sync and not really need more
471 * data, but that's just tough luck and a broken image then */
472 GST_DEBUG ("at end of input and no EOI marker found, need more data");
476 if (gst_jpeg_dec_parse_tag_has_entropy_segment (*data)) {
477 guint8 *d2 = data + 1 + frame_len;
480 GST_DEBUG ("0x%08" G_GINT64_MODIFIER "x: finding entropy segment length",
481 (gint64) (data - start - 1));
483 if (d2 + eseglen >= end - 1)
484 return 0; /* need more data */
485 if (d2[eseglen] == 0xff && d2[eseglen + 1] != 0x00)
489 frame_len += eseglen;
490 GST_DEBUG ("entropy segment length=%u => frame_len=%u", eseglen,
494 /* check if we will still be in sync if we interpret
495 * this as a sync point and skip this frame */
496 if (data[2 + frame_len] != 0xff) {
497 /* ignore and continue resyncing until we hit the end
498 * of our data or find a sync point that looks okay */
501 GST_DEBUG ("found sync at %p", data - size);
504 data += 1 + frame_len;
508 /* shamelessly ripped from jpegutils.c in mjpegtools */
510 add_huff_table (j_decompress_ptr dinfo,
511 JHUFF_TBL ** htblptr, const UINT8 * bits, const UINT8 * val)
512 /* Define a Huffman table */
516 if (*htblptr == NULL)
517 *htblptr = jpeg_alloc_huff_table ((j_common_ptr) dinfo);
521 /* Copy the number-of-symbols-of-each-code-length counts */
522 memcpy ((*htblptr)->bits, bits, sizeof ((*htblptr)->bits));
524 /* Validate the counts. We do this here mainly so we can copy the right
525 * number of symbols from the val[] array, without risking marching off
526 * the end of memory. jchuff.c will do a more thorough test later.
529 for (len = 1; len <= 16; len++)
530 nsymbols += bits[len];
531 if (nsymbols < 1 || nsymbols > 256)
532 g_error ("jpegutils.c: add_huff_table failed badly. ");
534 memcpy ((*htblptr)->huffval, val, nsymbols * sizeof (UINT8));
540 std_huff_tables (j_decompress_ptr dinfo)
541 /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
542 /* IMPORTANT: these are only valid for 8-bit data precision! */
544 static const UINT8 bits_dc_luminance[17] =
545 { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
546 static const UINT8 val_dc_luminance[] =
547 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
549 static const UINT8 bits_dc_chrominance[17] =
550 { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
551 static const UINT8 val_dc_chrominance[] =
552 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
554 static const UINT8 bits_ac_luminance[17] =
555 { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
556 static const UINT8 val_ac_luminance[] =
557 { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
558 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
559 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
560 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
561 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
562 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
563 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
564 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
565 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
566 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
567 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
568 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
569 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
570 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
571 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
572 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
573 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
574 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
575 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
576 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
580 static const UINT8 bits_ac_chrominance[17] =
581 { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
582 static const UINT8 val_ac_chrominance[] =
583 { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
584 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
585 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
586 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
587 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
588 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
589 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
590 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
591 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
592 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
593 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
594 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
595 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
596 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
597 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
598 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
599 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
600 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
601 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
602 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
606 add_huff_table (dinfo, &dinfo->dc_huff_tbl_ptrs[0],
607 bits_dc_luminance, val_dc_luminance);
608 add_huff_table (dinfo, &dinfo->ac_huff_tbl_ptrs[0],
609 bits_ac_luminance, val_ac_luminance);
610 add_huff_table (dinfo, &dinfo->dc_huff_tbl_ptrs[1],
611 bits_dc_chrominance, val_dc_chrominance);
612 add_huff_table (dinfo, &dinfo->ac_huff_tbl_ptrs[1],
613 bits_ac_chrominance, val_ac_chrominance);
619 guarantee_huff_tables (j_decompress_ptr dinfo)
621 if ((dinfo->dc_huff_tbl_ptrs[0] == NULL) &&
622 (dinfo->dc_huff_tbl_ptrs[1] == NULL) &&
623 (dinfo->ac_huff_tbl_ptrs[0] == NULL) &&
624 (dinfo->ac_huff_tbl_ptrs[1] == NULL)) {
625 GST_DEBUG ("Generating standard Huffman tables for this frame.");
626 std_huff_tables (dinfo);
631 gst_jpeg_dec_setcaps (GstPad * pad, GstCaps * caps)
635 const GValue *framerate;
637 dec = GST_JPEG_DEC (GST_OBJECT_PARENT (pad));
638 s = gst_caps_get_structure (caps, 0);
640 if ((framerate = gst_structure_get_value (s, "framerate")) != NULL) {
641 dec->framerate_numerator = gst_value_get_fraction_numerator (framerate);
642 dec->framerate_denominator = gst_value_get_fraction_denominator (framerate);
643 dec->packetized = TRUE;
644 GST_DEBUG ("got framerate of %d/%d fps => packetized mode",
645 dec->framerate_numerator, dec->framerate_denominator);
648 /* do not extract width/height here. we do that in the chain
649 * function on a per-frame basis (including the line[] array
652 /* But we can take the framerate values and set them on the src pad */
659 hresamplecpy1 (guint8 * dest, const guint8 * src, guint len)
663 for (i = 0; i < len; ++i) {
664 /* equivalent to: dest[i] = src[i << 1] */
673 gst_jpeg_dec_free_buffers (GstJpegDec * dec)
677 for (i = 0; i < 16; i++) {
678 g_free (dec->idr_y[i]);
679 g_free (dec->idr_u[i]);
680 g_free (dec->idr_v[i]);
681 dec->idr_y[i] = NULL;
682 dec->idr_u[i] = NULL;
683 dec->idr_v[i] = NULL;
686 dec->idr_width_allocated = 0;
689 static inline gboolean
690 gst_jpeg_dec_ensure_buffers (GstJpegDec * dec, guint maxrowbytes)
694 if (G_LIKELY (dec->idr_width_allocated == maxrowbytes))
697 /* FIXME: maybe just alloc one or three blocks altogether? */
698 for (i = 0; i < 16; i++) {
699 dec->idr_y[i] = g_try_realloc (dec->idr_y[i], maxrowbytes);
700 dec->idr_u[i] = g_try_realloc (dec->idr_u[i], maxrowbytes);
701 dec->idr_v[i] = g_try_realloc (dec->idr_v[i], maxrowbytes);
703 if (G_UNLIKELY (!dec->idr_y[i] || !dec->idr_u[i] || !dec->idr_v[i])) {
704 GST_WARNING_OBJECT (dec, "out of memory, i=%d, bytes=%u", i, maxrowbytes);
709 dec->idr_width_allocated = maxrowbytes;
710 GST_LOG_OBJECT (dec, "allocated temp memory, %u bytes/row", maxrowbytes);
715 gst_jpeg_dec_decode_indirect (GstJpegDec * dec, guchar * base[3],
716 guchar * last[3], guint width, guint height, gint r_v, gint r_h)
718 guchar *y_rows[16], *u_rows[16], *v_rows[16];
719 guchar **scanarray[3] = { y_rows, u_rows, v_rows };
723 GST_DEBUG_OBJECT (dec,
724 "unadvantageous width or r_h, taking slow route involving memcpy");
726 if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
729 memcpy (y_rows, dec->idr_y, 16 * sizeof (gpointer));
730 memcpy (u_rows, dec->idr_u, 16 * sizeof (gpointer));
731 memcpy (v_rows, dec->idr_v, 16 * sizeof (gpointer));
733 for (i = 0; i < height; i += r_v * DCTSIZE) {
734 lines = jpeg_read_raw_data (&dec->cinfo, scanarray, r_v * DCTSIZE);
735 if (G_LIKELY (lines > 0)) {
736 for (j = 0, k = 0; j < (r_v * DCTSIZE); j += r_v, k++) {
737 memcpy (base[0], y_rows[j], I420_Y_ROWSTRIDE (width));
738 if (G_LIKELY (base[0] < last[0]))
739 base[0] += I420_Y_ROWSTRIDE (width);
741 memcpy (base[0], y_rows[j + 1], I420_Y_ROWSTRIDE (width));
742 if (G_LIKELY (base[0] < last[0]))
743 base[0] += I420_Y_ROWSTRIDE (width);
746 memcpy (base[1], u_rows[k], I420_U_ROWSTRIDE (width));
747 memcpy (base[2], v_rows[k], I420_V_ROWSTRIDE (width));
748 } else if (r_h == 1) {
749 hresamplecpy1 (base[1], u_rows[k], I420_U_ROWSTRIDE (width));
750 hresamplecpy1 (base[2], v_rows[k], I420_V_ROWSTRIDE (width));
752 /* FIXME: implement (at least we avoid crashing by doing nothing) */
755 if (r_v == 2 || (k & 1) != 0) {
756 if (G_LIKELY (base[1] < last[1] && base[2] < last[2])) {
757 base[1] += I420_U_ROWSTRIDE (width);
758 base[2] += I420_V_ROWSTRIDE (width);
763 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
768 #ifndef GST_DISABLE_GST_DEBUG
770 dump_lines (guchar * base[3], guchar ** line[3], int v_samp0, int width)
774 for (j = 0; j < (v_samp0 * DCTSIZE); ++j) {
775 GST_LOG ("[%02d] %5d %5d %5d", j,
776 (line[0][j] >= base[0]) ?
777 (int) (line[0][j] - base[0]) / I420_Y_ROWSTRIDE (width) : -1,
778 (line[1][j] >= base[1]) ?
779 (int) (line[1][j] - base[1]) / I420_U_ROWSTRIDE (width) : -1,
780 (line[2][j] >= base[2]) ?
781 (int) (line[2][j] - base[2]) / I420_V_ROWSTRIDE (width) : -1);
787 gst_jpeg_dec_decode_direct (GstJpegDec * dec, guchar * base[3],
788 guchar * last[3], guint width, guint height)
790 guchar **line[3]; /* the jpeg line buffer */
791 guchar *y[4 * DCTSIZE] = { NULL, }; /* alloc enough for the lines */
792 guchar *u[4 * DCTSIZE] = { NULL, }; /* r_v will be <4 */
793 guchar *v[4 * DCTSIZE] = { NULL, };
795 gint lines, v_samp[3];
801 v_samp[0] = dec->cinfo.comp_info[0].v_samp_factor;
802 v_samp[1] = dec->cinfo.comp_info[1].v_samp_factor;
803 v_samp[2] = dec->cinfo.comp_info[2].v_samp_factor;
805 if (G_UNLIKELY (v_samp[0] > 2 || v_samp[1] > 2 || v_samp[2] > 2))
806 goto format_not_supported;
808 /* let jpeglib decode directly into our final buffer */
809 GST_DEBUG_OBJECT (dec, "decoding directly into output buffer");
811 for (i = 0; i < height; i += v_samp[0] * DCTSIZE) {
812 for (j = 0; j < (v_samp[0] * DCTSIZE); ++j) {
814 line[0][j] = base[0] + (i + j) * I420_Y_ROWSTRIDE (width);
815 if (G_UNLIKELY (line[0][j] > last[0]))
816 line[0][j] = last[0];
818 if (v_samp[1] == v_samp[0]) {
819 line[1][j] = base[1] + ((i + j) / 2) * I420_U_ROWSTRIDE (width);
820 } else if (j < (v_samp[1] * DCTSIZE)) {
821 line[1][j] = base[1] + ((i / 2) + j) * I420_U_ROWSTRIDE (width);
823 if (G_UNLIKELY (line[1][j] > last[1]))
824 line[1][j] = last[1];
826 if (v_samp[2] == v_samp[0]) {
827 line[2][j] = base[2] + ((i + j) / 2) * I420_V_ROWSTRIDE (width);
828 } else if (j < (v_samp[2] * DCTSIZE)) {
829 line[2][j] = base[2] + ((i / 2) + j) * I420_V_ROWSTRIDE (width);
831 if (G_UNLIKELY (line[2][j] > last[2]))
832 line[2][j] = last[2];
835 /* dump_lines (base, line, v_samp[0], width); */
837 lines = jpeg_read_raw_data (&dec->cinfo, line, v_samp[0] * DCTSIZE);
838 if (G_UNLIKELY (!lines)) {
839 GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
844 format_not_supported:
846 GST_ELEMENT_ERROR (dec, STREAM, DECODE,
847 (_("Failed to decode JPEG image")),
848 ("Unsupported subsampling schema: v_samp factors: %u %u %u",
849 v_samp[0], v_samp[1], v_samp[2]));
850 return GST_FLOW_ERROR;
855 gst_jpeg_dec_update_qos (GstJpegDec * dec, gdouble proportion,
856 GstClockTimeDiff diff, GstClockTime ts)
858 GST_OBJECT_LOCK (dec);
859 dec->proportion = proportion;
860 if (G_LIKELY (ts != GST_CLOCK_TIME_NONE)) {
861 if (G_UNLIKELY (diff > 0))
862 dec->earliest_time = ts + 2 * diff + dec->qos_duration;
864 dec->earliest_time = ts + diff;
866 dec->earliest_time = GST_CLOCK_TIME_NONE;
868 GST_OBJECT_UNLOCK (dec);
872 gst_jpeg_dec_reset_qos (GstJpegDec * dec)
874 gst_jpeg_dec_update_qos (dec, 0.5, 0, GST_CLOCK_TIME_NONE);
878 gst_jpeg_dec_read_qos (GstJpegDec * dec, gdouble * proportion,
881 GST_OBJECT_LOCK (dec);
882 *proportion = dec->proportion;
883 *time = dec->earliest_time;
884 GST_OBJECT_UNLOCK (dec);
887 /* Perform qos calculations before decoding the next frame. Returns TRUE if the
888 * frame should be decoded, FALSE if the frame can be dropped entirely */
890 gst_jpeg_dec_do_qos (GstJpegDec * dec, GstClockTime timestamp)
892 GstClockTime qostime, earliest_time;
895 /* no timestamp, can't do QoS => decode frame */
896 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (timestamp))) {
897 GST_LOG_OBJECT (dec, "invalid timestamp, can't do QoS, decode frame");
901 /* get latest QoS observation values */
902 gst_jpeg_dec_read_qos (dec, &proportion, &earliest_time);
904 /* skip qos if we have no observation (yet) => decode frame */
905 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (earliest_time))) {
906 GST_LOG_OBJECT (dec, "no observation yet, decode frame");
910 /* qos is done on running time */
911 qostime = gst_segment_to_running_time (&dec->segment, GST_FORMAT_TIME,
914 /* see how our next timestamp relates to the latest qos timestamp */
915 GST_LOG_OBJECT (dec, "qostime %" GST_TIME_FORMAT ", earliest %"
916 GST_TIME_FORMAT, GST_TIME_ARGS (qostime), GST_TIME_ARGS (earliest_time));
918 if (qostime != GST_CLOCK_TIME_NONE && qostime <= earliest_time) {
919 GST_DEBUG_OBJECT (dec, "we are late, drop frame");
923 GST_LOG_OBJECT (dec, "decode frame");
928 gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf)
930 GstFlowReturn ret = GST_FLOW_OK;
932 GstBuffer *outbuf = NULL;
933 guchar *data, *outdata;
934 guchar *base[3], *last[3];
935 guint img_len, outsize;
939 GstClockTime timestamp, duration;
941 dec = GST_JPEG_DEC (GST_PAD_PARENT (pad));
943 timestamp = GST_BUFFER_TIMESTAMP (buf);
944 duration = GST_BUFFER_DURATION (buf);
946 if (GST_CLOCK_TIME_IS_VALID (timestamp))
947 dec->next_ts = timestamp;
949 if (GST_BUFFER_IS_DISCONT (buf)) {
950 GST_DEBUG_OBJECT (dec, "buffer has DISCONT flag set");
952 if (!dec->packetized && dec->tempbuf != NULL) {
953 GST_WARNING_OBJECT (dec, "DISCONT buffer in non-packetized mode, bad");
954 gst_buffer_replace (&dec->tempbuf, NULL);
959 dec->tempbuf = gst_buffer_join (dec->tempbuf, buf);
965 /* If we are non-packetized and know the total incoming size in bytes,
966 * just wait until we have enough before doing any processing. */
968 if (!dec->packetized && (dec->segment.format == GST_FORMAT_BYTES) &&
969 (dec->segment.stop != -1) &&
970 (GST_BUFFER_SIZE (dec->tempbuf) < dec->segment.stop)) {
971 /* We assume that non-packetized input in bytes is *one* single jpeg image */
972 GST_DEBUG ("Non-packetized mode. Got %d bytes, need %" G_GINT64_FORMAT,
973 GST_BUFFER_SIZE (dec->tempbuf), dec->segment.stop);
977 if (!gst_jpeg_dec_ensure_header (dec))
980 /* If we know that each input buffer contains data
981 * for a whole jpeg image (e.g. MJPEG streams), just
982 * do some sanity checking instead of parsing all of
984 if (dec->packetized) {
985 img_len = GST_BUFFER_SIZE (dec->tempbuf);
987 /* Parse jpeg image to handle jpeg input that
988 * is not aligned to buffer boundaries */
989 img_len = gst_jpeg_dec_parse_image_data (dec);
995 /* QoS: if we're too late anyway, skip decoding */
996 if (dec->packetized && !gst_jpeg_dec_do_qos (dec, timestamp))
999 data = (guchar *) GST_BUFFER_DATA (dec->tempbuf);
1000 GST_LOG_OBJECT (dec, "image size = %u", img_len);
1002 dec->jsrc.pub.next_input_byte = data;
1003 dec->jsrc.pub.bytes_in_buffer = img_len;
1005 if (setjmp (dec->jerr.setjmp_buffer)) {
1006 code = dec->jerr.pub.msg_code;
1008 if (code == JERR_INPUT_EOF) {
1009 GST_DEBUG ("jpeg input EOF error, we probably need more data");
1010 goto need_more_data;
1015 GST_LOG_OBJECT (dec, "reading header %02x %02x %02x %02x", data[0], data[1],
1019 hdr_ok = jpeg_read_header (&dec->cinfo, TRUE);
1020 if (G_UNLIKELY (hdr_ok != JPEG_HEADER_OK)) {
1021 GST_WARNING_OBJECT (dec, "reading the header failed, %d", hdr_ok);
1024 r_h = dec->cinfo.comp_info[0].h_samp_factor;
1025 r_v = dec->cinfo.comp_info[0].v_samp_factor;
1027 GST_LOG_OBJECT (dec, "r_h = %d, r_v = %d", r_h, r_v);
1028 GST_LOG_OBJECT (dec, "num_components=%d", dec->cinfo.num_components);
1029 GST_LOG_OBJECT (dec, "jpeg_color_space=%d", dec->cinfo.jpeg_color_space);
1031 #ifndef GST_DISABLE_GST_DEBUG
1035 for (i = 0; i < dec->cinfo.num_components; ++i) {
1036 GST_LOG_OBJECT (dec, "[%d] h_samp_factor=%d, v_samp_factor=%d, cid=%d",
1037 i, dec->cinfo.comp_info[i].h_samp_factor,
1038 dec->cinfo.comp_info[i].v_samp_factor,
1039 dec->cinfo.comp_info[i].component_id);
1044 /* prepare for raw output */
1045 dec->cinfo.do_fancy_upsampling = FALSE;
1046 dec->cinfo.do_block_smoothing = FALSE;
1047 dec->cinfo.out_color_space = JCS_YCbCr;
1048 dec->cinfo.dct_method = dec->idct_method;
1049 dec->cinfo.raw_data_out = TRUE;
1051 GST_LOG_OBJECT (dec, "starting decompress");
1052 guarantee_huff_tables (&dec->cinfo);
1053 if (!jpeg_start_decompress (&dec->cinfo)) {
1054 GST_WARNING_OBJECT (dec, "failed to start decompression cycle");
1057 width = dec->cinfo.output_width;
1058 height = dec->cinfo.output_height;
1060 if (G_UNLIKELY (width < MIN_WIDTH || width > MAX_WIDTH ||
1061 height < MIN_HEIGHT || height > MAX_HEIGHT))
1064 if (G_UNLIKELY (width != dec->caps_width || height != dec->caps_height ||
1065 dec->framerate_numerator != dec->caps_framerate_numerator ||
1066 dec->framerate_denominator != dec->caps_framerate_denominator)) {
1069 /* framerate == 0/1 is a still frame */
1070 if (dec->framerate_denominator == 0) {
1071 dec->framerate_numerator = 0;
1072 dec->framerate_denominator = 1;
1075 /* calculate or assume an average frame duration for QoS purposes */
1076 GST_OBJECT_LOCK (dec);
1077 if (dec->framerate_numerator != 0) {
1078 dec->qos_duration = gst_util_uint64_scale (GST_SECOND,
1079 dec->framerate_denominator, dec->framerate_numerator);
1081 /* if not set just use 25fps */
1082 dec->qos_duration = gst_util_uint64_scale (GST_SECOND, 1, 25);
1084 GST_OBJECT_UNLOCK (dec);
1086 caps = gst_caps_new_simple ("video/x-raw-yuv",
1087 "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
1088 "width", G_TYPE_INT, width,
1089 "height", G_TYPE_INT, height,
1090 "framerate", GST_TYPE_FRACTION, dec->framerate_numerator,
1091 dec->framerate_denominator, NULL);
1093 GST_DEBUG_OBJECT (dec, "setting caps %" GST_PTR_FORMAT, caps);
1094 GST_DEBUG_OBJECT (dec, "max_v_samp_factor=%d",
1095 dec->cinfo.max_v_samp_factor);
1096 GST_DEBUG_OBJECT (dec, "max_h_samp_factor=%d",
1097 dec->cinfo.max_h_samp_factor);
1099 gst_pad_set_caps (dec->srcpad, caps);
1100 gst_caps_unref (caps);
1102 dec->caps_width = width;
1103 dec->caps_height = height;
1104 dec->caps_framerate_numerator = dec->framerate_numerator;
1105 dec->caps_framerate_denominator = dec->framerate_denominator;
1106 dec->outsize = I420_SIZE (width, height);
1109 ret = gst_pad_alloc_buffer_and_set_caps (dec->srcpad, GST_BUFFER_OFFSET_NONE,
1110 dec->outsize, GST_PAD_CAPS (dec->srcpad), &outbuf);
1111 if (G_UNLIKELY (ret != GST_FLOW_OK))
1114 outdata = GST_BUFFER_DATA (outbuf);
1115 outsize = GST_BUFFER_SIZE (outbuf);
1117 GST_LOG_OBJECT (dec, "width %d, height %d, buffer size %d, required size %d",
1118 width, height, outsize, dec->outsize);
1120 GST_BUFFER_TIMESTAMP (outbuf) = dec->next_ts;
1122 if (dec->packetized && GST_CLOCK_TIME_IS_VALID (dec->next_ts)) {
1123 if (GST_CLOCK_TIME_IS_VALID (duration)) {
1124 /* use duration from incoming buffer for outgoing buffer */
1125 dec->next_ts += duration;
1126 } else if (dec->framerate_numerator != 0) {
1127 duration = gst_util_uint64_scale (GST_SECOND,
1128 dec->framerate_denominator, dec->framerate_numerator);
1129 dec->next_ts += duration;
1131 duration = GST_CLOCK_TIME_NONE;
1132 dec->next_ts = GST_CLOCK_TIME_NONE;
1135 duration = GST_CLOCK_TIME_NONE;
1136 dec->next_ts = GST_CLOCK_TIME_NONE;
1138 GST_BUFFER_DURATION (outbuf) = duration;
1140 /* mind the swap, jpeglib outputs blue chroma first
1141 * ensonic: I see no swap?
1143 base[0] = outdata + I420_Y_OFFSET (width, height);
1144 base[1] = outdata + I420_U_OFFSET (width, height);
1145 base[2] = outdata + I420_V_OFFSET (width, height);
1147 /* make sure we don't make jpeglib write beyond our buffer,
1148 * which might happen if (height % (r_v*DCTSIZE)) != 0 */
1149 last[0] = base[0] + (I420_Y_ROWSTRIDE (width) * (height - 1));
1151 base[1] + (I420_U_ROWSTRIDE (width) * ((GST_ROUND_UP_2 (height) / 2) -
1154 base[2] + (I420_V_ROWSTRIDE (width) * ((GST_ROUND_UP_2 (height) / 2) -
1157 GST_LOG_OBJECT (dec, "decompressing (reqired scanline buffer height = %u)",
1158 dec->cinfo.rec_outbuf_height);
1160 /* For some widths jpeglib requires more horizontal padding than I420
1161 * provides. In those cases we need to decode into separate buffers and then
1162 * copy over the data into our final picture buffer, otherwise jpeglib might
1163 * write over the end of a line into the beginning of the next line,
1164 * resulting in blocky artifacts on the left side of the picture. */
1165 if (G_UNLIKELY (width % (dec->cinfo.max_h_samp_factor * DCTSIZE) != 0
1166 || dec->cinfo.comp_info[0].h_samp_factor != 2
1167 || dec->cinfo.comp_info[1].h_samp_factor != 1
1168 || dec->cinfo.comp_info[2].h_samp_factor != 1)) {
1169 GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, dec,
1170 "indirect decoding using extra buffer copy");
1171 gst_jpeg_dec_decode_indirect (dec, base, last, width, height, r_v, r_h);
1173 ret = gst_jpeg_dec_decode_direct (dec, base, last, width, height);
1175 if (G_UNLIKELY (ret != GST_FLOW_OK))
1176 goto decode_direct_failed;
1179 GST_LOG_OBJECT (dec, "decompressing finished");
1180 jpeg_finish_decompress (&dec->cinfo);
1183 if (dec->segment.format == GST_FORMAT_TIME) {
1184 gint64 start, stop, clip_start, clip_stop;
1186 GST_LOG_OBJECT (dec, "Attempting clipping");
1188 start = GST_BUFFER_TIMESTAMP (outbuf);
1189 if (GST_BUFFER_DURATION (outbuf) == GST_CLOCK_TIME_NONE)
1192 stop = start + GST_BUFFER_DURATION (outbuf);
1194 if (gst_segment_clip (&dec->segment, GST_FORMAT_TIME,
1195 start, stop, &clip_start, &clip_stop)) {
1196 GST_LOG_OBJECT (dec, "Clipping start to %" GST_TIME_FORMAT,
1197 GST_TIME_ARGS (clip_start));
1198 GST_BUFFER_TIMESTAMP (outbuf) = clip_start;
1199 if (GST_BUFFER_DURATION (outbuf) != GST_CLOCK_TIME_NONE) {
1200 GST_LOG_OBJECT (dec, "Clipping duration to %" GST_TIME_FORMAT,
1201 GST_TIME_ARGS (clip_stop - clip_start));
1202 GST_BUFFER_DURATION (outbuf) = clip_stop - clip_start;
1208 GST_LOG_OBJECT (dec, "pushing buffer (ts=%" GST_TIME_FORMAT ", dur=%"
1209 GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
1210 GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
1212 ret = gst_pad_push (dec->srcpad, outbuf);
1216 if (GST_BUFFER_SIZE (dec->tempbuf) == img_len) {
1217 gst_buffer_unref (dec->tempbuf);
1218 dec->tempbuf = NULL;
1220 GstBuffer *buf = gst_buffer_create_sub (dec->tempbuf, img_len,
1221 GST_BUFFER_SIZE (dec->tempbuf) - img_len);
1223 gst_buffer_unref (dec->tempbuf);
1234 GST_LOG_OBJECT (dec, "we need more data");
1236 gst_buffer_unref (outbuf);
1245 GST_ELEMENT_ERROR (dec, STREAM, DECODE,
1246 ("Picture is too small or too big (%ux%u)", width, height),
1247 ("Picture is too small or too big (%ux%u)", width, height));
1248 ret = GST_FLOW_ERROR;
1253 gchar err_msg[JMSG_LENGTH_MAX];
1255 dec->jerr.pub.format_message ((j_common_ptr) (&dec->cinfo), err_msg);
1257 GST_ELEMENT_ERROR (dec, STREAM, DECODE,
1258 (_("Failed to decode JPEG image")), ("Error #%u: %s", code, err_msg));
1260 gst_buffer_unref (outbuf);
1263 ret = GST_FLOW_ERROR;
1266 decode_direct_failed:
1268 /* already posted an error message */
1269 jpeg_abort_decompress (&dec->cinfo);
1270 gst_buffer_replace (&outbuf, NULL);
1275 const gchar *reason;
1277 reason = gst_flow_get_name (ret);
1279 GST_DEBUG_OBJECT (dec, "failed to alloc buffer, reason %s", reason);
1280 /* Reset for next time */
1281 jpeg_abort_decompress (&dec->cinfo);
1282 if (GST_FLOW_IS_FATAL (ret)) {
1283 GST_ELEMENT_ERROR (dec, STREAM, DECODE,
1284 ("Buffer allocation failed, reason: %s", reason),
1285 ("Buffer allocation failed, reason: %s", reason));
1291 GST_WARNING_OBJECT (dec, "Outgoing buffer is outside configured segment");
1292 gst_buffer_unref (outbuf);
1299 gst_jpeg_dec_src_event (GstPad * pad, GstEvent * event)
1304 dec = GST_JPEG_DEC (gst_pad_get_parent (pad));
1306 switch (GST_EVENT_TYPE (event)) {
1307 case GST_EVENT_QOS:{
1308 GstClockTimeDiff diff;
1309 GstClockTime timestamp;
1312 gst_event_parse_qos (event, &proportion, &diff, ×tamp);
1313 gst_jpeg_dec_update_qos (dec, proportion, diff, timestamp);
1320 res = gst_pad_push_event (dec->sinkpad, event);
1322 gst_object_unref (dec);
1327 gst_jpeg_dec_sink_event (GstPad * pad, GstEvent * event)
1329 gboolean ret = TRUE;
1330 GstJpegDec *dec = GST_JPEG_DEC (GST_OBJECT_PARENT (pad));
1332 GST_DEBUG_OBJECT (dec, "event : %s", GST_EVENT_TYPE_NAME (event));
1334 switch (GST_EVENT_TYPE (event)) {
1335 case GST_EVENT_FLUSH_STOP:
1336 GST_DEBUG_OBJECT (dec, "Aborting decompress");
1337 jpeg_abort_decompress (&dec->cinfo);
1338 gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED);
1339 gst_jpeg_dec_reset_qos (dec);
1341 case GST_EVENT_NEWSEGMENT:{
1343 gdouble rate, applied_rate;
1345 gint64 start, stop, position;
1347 gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
1348 &format, &start, &stop, &position);
1350 GST_DEBUG_OBJECT (dec, "Got NEWSEGMENT [%" GST_TIME_FORMAT
1351 " - %" GST_TIME_FORMAT " / %" GST_TIME_FORMAT "]",
1352 GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
1353 GST_TIME_ARGS (position));
1355 gst_segment_set_newsegment_full (&dec->segment, update, rate,
1356 applied_rate, format, start, stop, position);
1364 ret = gst_pad_push_event (dec->srcpad, event);
1370 gst_jpeg_dec_set_property (GObject * object, guint prop_id,
1371 const GValue * value, GParamSpec * pspec)
1375 dec = GST_JPEG_DEC (object);
1378 case PROP_IDCT_METHOD:
1379 dec->idct_method = g_value_get_enum (value);
1383 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1389 gst_jpeg_dec_get_property (GObject * object, guint prop_id, GValue * value,
1394 dec = GST_JPEG_DEC (object);
1397 case PROP_IDCT_METHOD:
1398 g_value_set_enum (value, dec->idct_method);
1402 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1407 static GstStateChangeReturn
1408 gst_jpeg_dec_change_state (GstElement * element, GstStateChange transition)
1410 GstStateChangeReturn ret;
1413 dec = GST_JPEG_DEC (element);
1415 switch (transition) {
1416 case GST_STATE_CHANGE_READY_TO_PAUSED:
1417 dec->framerate_numerator = 0;
1418 dec->framerate_denominator = 1;
1419 dec->caps_framerate_numerator = dec->caps_framerate_denominator = 0;
1420 dec->caps_width = -1;
1421 dec->caps_height = -1;
1422 dec->packetized = FALSE;
1424 dec->discont = TRUE;
1425 gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED);
1426 gst_jpeg_dec_reset_qos (dec);
1431 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1432 if (ret != GST_STATE_CHANGE_SUCCESS)
1435 switch (transition) {
1436 case GST_STATE_CHANGE_PAUSED_TO_READY:
1438 gst_buffer_unref (dec->tempbuf);
1439 dec->tempbuf = NULL;
1441 gst_jpeg_dec_free_buffers (dec);