2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
26 /*#define DEBUG_ENABLED*/
27 #include "gstjpegdec.h"
29 extern GstPadTemplate *jpegdec_src_template, *jpegdec_sink_template;
31 /* elementfactory information */
32 GstElementDetails gst_jpegdec_details = {
38 "Wim Taymans <wim.taymans@tvd.be>",
42 /* JpegDec signals and args */
53 static void gst_jpegdec_class_init (GstJpegDec *klass);
54 static void gst_jpegdec_init (GstJpegDec *jpegdec);
56 static void gst_jpegdec_chain (GstPad *pad, GstBuffer *buf);
57 static GstPadLinkReturn
58 gst_jpegdec_link (GstPad *pad, GstCaps *caps);
60 static GstElementClass *parent_class = NULL;
61 /*static guint gst_jpegdec_signals[LAST_SIGNAL] = { 0 }; */
64 gst_jpegdec_get_type(void) {
65 static GType jpegdec_type = 0;
68 static const GTypeInfo jpegdec_info = {
69 sizeof(GstJpegDec), NULL,
71 (GClassInitFunc)gst_jpegdec_class_init,
76 (GInstanceInitFunc)gst_jpegdec_init,
78 jpegdec_type = g_type_register_static(GST_TYPE_ELEMENT, "GstJpegDec", &jpegdec_info, 0);
84 gst_jpegdec_class_init (GstJpegDec *klass)
86 GstElementClass *gstelement_class;
88 gstelement_class = (GstElementClass*)klass;
90 parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
94 gst_jpegdec_init_source (j_decompress_ptr cinfo)
96 GST_DEBUG ("gst_jpegdec_chain: init_source");
99 gst_jpegdec_fill_input_buffer (j_decompress_ptr cinfo)
101 GST_DEBUG ("gst_jpegdec_chain: fill_input_buffer");
106 gst_jpegdec_skip_input_data (j_decompress_ptr cinfo, glong num_bytes)
108 GST_DEBUG ("gst_jpegdec_chain: skip_input_data");
112 gst_jpegdec_resync_to_restart (j_decompress_ptr cinfo, gint desired)
114 GST_DEBUG ("gst_jpegdec_chain: resync_to_start");
119 gst_jpegdec_term_source (j_decompress_ptr cinfo)
121 GST_DEBUG ("gst_jpegdec_chain: term_source");
125 gst_jpegdec_init (GstJpegDec *jpegdec)
127 GST_DEBUG ("gst_jpegdec_init: initializing");
128 /* create the sink and src pads */
129 jpegdec->sinkpad = gst_pad_new_from_template (jpegdec_sink_template, "sink");
130 gst_element_add_pad(GST_ELEMENT(jpegdec),jpegdec->sinkpad);
131 gst_pad_set_chain_function(jpegdec->sinkpad,gst_jpegdec_chain);
132 gst_pad_set_link_function(jpegdec->sinkpad, gst_jpegdec_link);
133 jpegdec->srcpad = gst_pad_new_from_template (jpegdec_src_template, "src");
134 gst_element_add_pad(GST_ELEMENT(jpegdec),jpegdec->srcpad);
136 /* initialize the jpegdec decoder state */
137 jpegdec->next_time = 0;
139 /* reset the initial video state */
140 jpegdec->format = -1;
142 jpegdec->height = -1;
144 jpegdec->line[0] = NULL;
145 jpegdec->line[1] = NULL;
146 jpegdec->line[2] = NULL;
149 memset(&jpegdec->cinfo, 0, sizeof(jpegdec->cinfo));
150 memset(&jpegdec->jerr, 0, sizeof(jpegdec->jerr));
151 jpegdec->cinfo.err = jpeg_std_error(&jpegdec->jerr);
152 jpeg_create_decompress(&jpegdec->cinfo);
154 jpegdec->jsrc.init_source = gst_jpegdec_init_source;
155 jpegdec->jsrc.fill_input_buffer = gst_jpegdec_fill_input_buffer;
156 jpegdec->jsrc.skip_input_data = gst_jpegdec_skip_input_data;
157 jpegdec->jsrc.resync_to_restart = gst_jpegdec_resync_to_restart;
158 jpegdec->jsrc.term_source = gst_jpegdec_term_source;
159 jpegdec->cinfo.src = &jpegdec->jsrc;
163 static GstPadLinkReturn
164 gst_jpegdec_link (GstPad *pad, GstCaps *caps)
166 GstJpegDec *jpegdec = GST_JPEGDEC (gst_pad_get_parent (pad));
168 if (!GST_CAPS_IS_FIXED (caps))
169 return GST_PAD_LINK_DELAYED;
172 "framerate", &jpegdec->fps,
173 "width", &jpegdec->width,
174 "height", &jpegdec->height,
177 caps = GST_CAPS_NEW ("jpegdec_srccaps",
179 "format", GST_PROPS_FOURCC (
180 GST_MAKE_FOURCC ('I','4','2','0')),
181 "width", GST_PROPS_INT (jpegdec->width),
182 "height", GST_PROPS_INT (jpegdec->height),
183 "framerate", GST_PROPS_FLOAT (jpegdec->fps));
185 return gst_pad_try_set_caps (jpegdec->srcpad, caps);
188 /* shamelessly ripped from jpegutils.c in mjpegtools */
189 static void add_huff_table (j_decompress_ptr dinfo,
191 const UINT8 *bits, const UINT8 *val)
192 /* Define a Huffman table */
196 if (*htblptr == NULL)
197 *htblptr = jpeg_alloc_huff_table((j_common_ptr) dinfo);
199 /* Copy the number-of-symbols-of-each-code-length counts */
200 memcpy((*htblptr)->bits, bits, sizeof((*htblptr)->bits));
202 /* Validate the counts. We do this here mainly so we can copy the right
203 * number of symbols from the val[] array, without risking marching off
204 * the end of memory. jchuff.c will do a more thorough test later.
207 for (len = 1; len <= 16; len++)
208 nsymbols += bits[len];
209 if (nsymbols < 1 || nsymbols > 256)
210 g_error("jpegutils.c: add_huff_table failed badly. ");
212 memcpy((*htblptr)->huffval, val, nsymbols * sizeof(UINT8));
217 static void std_huff_tables (j_decompress_ptr dinfo)
218 /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
219 /* IMPORTANT: these are only valid for 8-bit data precision! */
221 static const UINT8 bits_dc_luminance[17] =
222 { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
223 static const UINT8 val_dc_luminance[] =
224 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
226 static const UINT8 bits_dc_chrominance[17] =
227 { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
228 static const UINT8 val_dc_chrominance[] =
229 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
231 static const UINT8 bits_ac_luminance[17] =
232 { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
233 static const UINT8 val_ac_luminance[] =
234 { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
235 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
236 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
237 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
238 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
239 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
240 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
241 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
242 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
243 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
244 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
245 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
246 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
247 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
248 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
249 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
250 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
251 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
252 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
253 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
256 static const UINT8 bits_ac_chrominance[17] =
257 { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
258 static const UINT8 val_ac_chrominance[] =
259 { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
260 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
261 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
262 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
263 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
264 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
265 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
266 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
267 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
268 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
269 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
270 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
271 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
272 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
273 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
274 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
275 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
276 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
277 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
278 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
281 add_huff_table(dinfo, &dinfo->dc_huff_tbl_ptrs[0],
282 bits_dc_luminance, val_dc_luminance);
283 add_huff_table(dinfo, &dinfo->ac_huff_tbl_ptrs[0],
284 bits_ac_luminance, val_ac_luminance);
285 add_huff_table(dinfo, &dinfo->dc_huff_tbl_ptrs[1],
286 bits_dc_chrominance, val_dc_chrominance);
287 add_huff_table(dinfo, &dinfo->ac_huff_tbl_ptrs[1],
288 bits_ac_chrominance, val_ac_chrominance);
293 static void guarantee_huff_tables(j_decompress_ptr dinfo)
295 if ( (dinfo->dc_huff_tbl_ptrs[0] == NULL) &&
296 (dinfo->dc_huff_tbl_ptrs[1] == NULL) &&
297 (dinfo->ac_huff_tbl_ptrs[0] == NULL) &&
298 (dinfo->ac_huff_tbl_ptrs[1] == NULL) ) {
300 "Generating standard Huffman tables for this frame.");
301 std_huff_tables(dinfo);
306 gst_jpegdec_chain (GstPad *pad, GstBuffer *buf)
309 guchar *data, *outdata;
310 gulong size, outsize;
313 gint width, height, width2;
318 g_return_if_fail(pad != NULL);
319 g_return_if_fail(GST_IS_PAD(pad));
320 g_return_if_fail(buf != NULL);
321 /*g_return_if_fail(GST_IS_BUFFER(buf));*/
323 jpegdec = GST_JPEGDEC (GST_OBJECT_PARENT (pad));
325 if (!GST_PAD_IS_LINKED (jpegdec->srcpad)) {
326 gst_buffer_unref (buf);
330 data = (guchar *)GST_BUFFER_DATA(buf);
331 size = GST_BUFFER_SIZE(buf);
332 GST_DEBUG ("gst_jpegdec_chain: got buffer of %ld bytes in '%s'",size,
333 GST_OBJECT_NAME (jpegdec));
335 jpegdec->jsrc.next_input_byte = data;
336 jpegdec->jsrc.bytes_in_buffer = size;
339 GST_DEBUG ("gst_jpegdec_chain: reading header %08lx", *(gulong *)data);
340 jpeg_read_header(&jpegdec->cinfo, TRUE);
342 r_h = jpegdec->cinfo.cur_comp_info[0]->h_samp_factor;
343 r_v = jpegdec->cinfo.cur_comp_info[0]->v_samp_factor;
345 /*g_print ("%d %d\n", r_h, r_v);*/
346 /*g_print ("%d %d\n", jpegdec->cinfo.cur_comp_info[1]->h_samp_factor, jpegdec->cinfo.cur_comp_info[1]->v_samp_factor);*/
347 /*g_print ("%d %d\n", jpegdec->cinfo.cur_comp_info[2]->h_samp_factor, jpegdec->cinfo.cur_comp_info[2]->v_samp_factor);*/
349 jpegdec->cinfo.do_fancy_upsampling = FALSE;
350 jpegdec->cinfo.do_block_smoothing = FALSE;
351 jpegdec->cinfo.out_color_space = JCS_YCbCr;
352 jpegdec->cinfo.dct_method = JDCT_IFAST;
353 jpegdec->cinfo.raw_data_out = TRUE;
354 GST_DEBUG ("gst_jpegdec_chain: starting decompress");
355 guarantee_huff_tables(&jpegdec->cinfo);
356 jpeg_start_decompress(&jpegdec->cinfo);
357 width = jpegdec->cinfo.output_width;
358 height = jpegdec->cinfo.output_height;
359 GST_DEBUG ("gst_jpegdec_chain: width %d, height %d", width, height);
361 outbuf = gst_buffer_new();
362 outsize = GST_BUFFER_SIZE(outbuf) = width*height +
364 outdata = GST_BUFFER_DATA(outbuf) = g_malloc(outsize);
365 GST_BUFFER_TIMESTAMP(outbuf) = GST_BUFFER_TIMESTAMP(buf);
367 if (jpegdec->height != height) {
368 jpegdec->line[0] = g_realloc(jpegdec->line[0], height*sizeof(char*));
369 jpegdec->line[1] = g_realloc(jpegdec->line[1], height*sizeof(char*));
370 jpegdec->line[2] = g_realloc(jpegdec->line[2], height*sizeof(char*));
371 jpegdec->height = height;
373 gst_pad_try_set_caps (jpegdec->srcpad,
377 "format", GST_PROPS_FOURCC (
378 GST_MAKE_FOURCC ('I','4','2','0')),
379 "width", GST_PROPS_INT (width),
380 "height", GST_PROPS_INT (height),
381 "framerate", GST_PROPS_FLOAT (jpegdec->fps)
385 /* mind the swap, jpeglib outputs blue chroma first */
387 base[1] = base[0]+width*height;
388 base[2] = base[1]+width*height/4;
392 GST_DEBUG ("gst_jpegdec_chain: decompressing %u", jpegdec->cinfo.rec_outbuf_height);
393 for (i = 0; i < height; i += r_v*DCTSIZE) {
394 for (j=0, k=0; j< (r_v*DCTSIZE); j += r_v, k++) {
395 jpegdec->line[0][j] = base[0]; base[0] += width;
397 jpegdec->line[0][j+1] = base[0]; base[0] += width;
399 jpegdec->line[1][k] = base[1];
400 jpegdec->line[2][k] = base[2];
401 if (r_v == 2 || k&1) {
402 base[1] += width2; base[2] += width2;
405 /*g_print ("%d\n", jpegdec->cinfo.output_scanline);*/
406 jpeg_read_raw_data(&jpegdec->cinfo, jpegdec->line, r_v*DCTSIZE);
409 GST_DEBUG ("gst_jpegdec_chain: decompressing finished");
410 jpeg_finish_decompress(&jpegdec->cinfo);
412 GST_DEBUG ("gst_jpegdec_chain: sending buffer");
413 gst_pad_push(jpegdec->srcpad, outbuf);
415 gst_buffer_unref(buf);