gst_plugins_good/ext/jpeg/gstjpegdec.c
changeset 27 d43ce56a1534
parent 23 29ecd5cb86b3
child 31 aec498aab1d3
equal deleted inserted replaced
23:29ecd5cb86b3 27:d43ce56a1534
     1 /* GStreamer
       
     2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
       
     3  *
       
     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.
       
     8  *
       
     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.
       
    13  *
       
    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.
       
    18  */
       
    19 
       
    20 
       
    21 #ifdef HAVE_CONFIG_H
       
    22 #include "config.h"
       
    23 #endif
       
    24 #include <string.h>
       
    25 
       
    26 #include "gstjpegdec.h"
       
    27 #include <gst/video/video.h>
       
    28 #include "gst/gst-i18n-plugin.h"
       
    29 #include <jerror.h>
       
    30 
       
    31 static const GstElementDetails gst_jpeg_dec_details =
       
    32 GST_ELEMENT_DETAILS ("JPEG image decoder",
       
    33     "Codec/Decoder/Image",
       
    34     "Decode images from JPEG format",
       
    35     "Wim Taymans <wim.taymans@tvd.be>");
       
    36 
       
    37 #define MIN_WIDTH  16
       
    38 #define MAX_WIDTH  4096
       
    39 #define MIN_HEIGHT 16
       
    40 #define MAX_HEIGHT 4096
       
    41 
       
    42 static GstStaticPadTemplate gst_jpeg_dec_src_pad_template =
       
    43 GST_STATIC_PAD_TEMPLATE ("src",
       
    44     GST_PAD_SRC,
       
    45     GST_PAD_ALWAYS,
       
    46     GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420"))
       
    47     );
       
    48 
       
    49 static GstStaticPadTemplate gst_jpeg_dec_sink_pad_template =
       
    50 GST_STATIC_PAD_TEMPLATE ("sink",
       
    51     GST_PAD_SINK,
       
    52     GST_PAD_ALWAYS,
       
    53     GST_STATIC_CAPS ("image/jpeg, "
       
    54         "width = (int) [ " G_STRINGIFY (MIN_WIDTH) ", " G_STRINGIFY (MAX_WIDTH)
       
    55         " ], " "height = (int) [ " G_STRINGIFY (MIN_HEIGHT) ", "
       
    56         G_STRINGIFY (MAX_HEIGHT) " ], " "framerate = (fraction) [ 0/1, MAX ]")
       
    57     );
       
    58 
       
    59 GST_DEBUG_CATEGORY_STATIC (jpeg_dec_debug);
       
    60 #define GST_CAT_DEFAULT jpeg_dec_debug
       
    61 
       
    62 /* These macros are adapted from videotestsrc.c 
       
    63  *  and/or gst-plugins/gst/games/gstvideoimage.c */
       
    64 #define I420_Y_ROWSTRIDE(width) (GST_ROUND_UP_4(width))
       
    65 #define I420_U_ROWSTRIDE(width) (GST_ROUND_UP_8(width)/2)
       
    66 #define I420_V_ROWSTRIDE(width) ((GST_ROUND_UP_8(I420_Y_ROWSTRIDE(width)))/2)
       
    67 
       
    68 #define I420_Y_OFFSET(w,h) (0)
       
    69 #define I420_U_OFFSET(w,h) (I420_Y_OFFSET(w,h)+(I420_Y_ROWSTRIDE(w)*GST_ROUND_UP_2(h)))
       
    70 #define I420_V_OFFSET(w,h) (I420_U_OFFSET(w,h)+(I420_U_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2))
       
    71 
       
    72 #define I420_SIZE(w,h)     (I420_V_OFFSET(w,h)+(I420_V_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2))
       
    73 
       
    74 static GstElementClass *parent_class;   /* NULL */
       
    75 
       
    76 static void gst_jpeg_dec_base_init (gpointer g_class);
       
    77 static void gst_jpeg_dec_class_init (GstJpegDecClass * klass);
       
    78 static void gst_jpeg_dec_init (GstJpegDec * jpegdec);
       
    79 
       
    80 static GstFlowReturn gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buffer);
       
    81 static gboolean gst_jpeg_dec_setcaps (GstPad * pad, GstCaps * caps);
       
    82 static GstStateChangeReturn gst_jpeg_dec_change_state (GstElement * element,
       
    83     GstStateChange transition);
       
    84 
       
    85 GType
       
    86 gst_jpeg_dec_get_type (void)
       
    87 {
       
    88   static GType type = 0;
       
    89 
       
    90   if (!type) {
       
    91     static const GTypeInfo jpeg_dec_info = {
       
    92       sizeof (GstJpegDecClass),
       
    93       (GBaseInitFunc) gst_jpeg_dec_base_init,
       
    94       NULL,
       
    95       (GClassInitFunc) gst_jpeg_dec_class_init,
       
    96       NULL,
       
    97       NULL,
       
    98       sizeof (GstJpegDec),
       
    99       0,
       
   100       (GInstanceInitFunc) gst_jpeg_dec_init,
       
   101     };
       
   102 
       
   103     type = g_type_register_static (GST_TYPE_ELEMENT, "GstJpegDec",
       
   104         &jpeg_dec_info, 0);
       
   105   }
       
   106   return type;
       
   107 }
       
   108 
       
   109 static void
       
   110 gst_jpeg_dec_finalize (GObject * object)
       
   111 {
       
   112   GstJpegDec *dec = GST_JPEG_DEC (object);
       
   113 
       
   114   jpeg_destroy_decompress (&dec->cinfo);
       
   115 
       
   116   if (dec->tempbuf)
       
   117     gst_buffer_unref (dec->tempbuf);
       
   118 
       
   119   G_OBJECT_CLASS (parent_class)->finalize (object);
       
   120 }
       
   121 
       
   122 static void
       
   123 gst_jpeg_dec_base_init (gpointer g_class)
       
   124 {
       
   125   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
       
   126 
       
   127   gst_element_class_add_pad_template (element_class,
       
   128       gst_static_pad_template_get (&gst_jpeg_dec_src_pad_template));
       
   129   gst_element_class_add_pad_template (element_class,
       
   130       gst_static_pad_template_get (&gst_jpeg_dec_sink_pad_template));
       
   131   gst_element_class_set_details (element_class, &gst_jpeg_dec_details);
       
   132 }
       
   133 
       
   134 static void
       
   135 gst_jpeg_dec_class_init (GstJpegDecClass * klass)
       
   136 {
       
   137   GstElementClass *gstelement_class;
       
   138   GObjectClass *gobject_class;
       
   139 
       
   140   gstelement_class = (GstElementClass *) klass;
       
   141   gobject_class = (GObjectClass *) klass;
       
   142 
       
   143   parent_class = g_type_class_peek_parent (klass);
       
   144 
       
   145   gobject_class->finalize = gst_jpeg_dec_finalize;
       
   146 
       
   147   gstelement_class->change_state =
       
   148       GST_DEBUG_FUNCPTR (gst_jpeg_dec_change_state);
       
   149 
       
   150   GST_DEBUG_CATEGORY_INIT (jpeg_dec_debug, "jpegdec", 0, "JPEG decoder");
       
   151 }
       
   152 
       
   153 static gboolean
       
   154 gst_jpeg_dec_fill_input_buffer (j_decompress_ptr cinfo)
       
   155 {
       
   156 /*
       
   157   struct GstJpegDecSourceMgr *src_mgr;
       
   158   GstJpegDec *dec;
       
   159 
       
   160   src_mgr = (struct GstJpegDecSourceMgr*) &cinfo->src;
       
   161   dec = GST_JPEG_DEC (src_mgr->dec);
       
   162 */
       
   163   GST_DEBUG ("fill_input_buffer");
       
   164 /*
       
   165   g_return_val_if_fail (dec != NULL, TRUE);
       
   166 
       
   167   src_mgr->pub.next_input_byte = GST_BUFFER_DATA (dec->tempbuf);
       
   168   src_mgr->pub.bytes_in_buffer = GST_BUFFER_SIZE (dec->tempbuf);
       
   169 */
       
   170   return TRUE;
       
   171 }
       
   172 
       
   173 static void
       
   174 gst_jpeg_dec_init_source (j_decompress_ptr cinfo)
       
   175 {
       
   176   GST_DEBUG ("init_source");
       
   177 }
       
   178 
       
   179 
       
   180 static void
       
   181 gst_jpeg_dec_skip_input_data (j_decompress_ptr cinfo, glong num_bytes)
       
   182 {
       
   183   GST_DEBUG ("skip_input_data: %ld bytes", num_bytes);
       
   184 
       
   185   if (num_bytes > 0 && cinfo->src->bytes_in_buffer >= num_bytes) {
       
   186     cinfo->src->next_input_byte += (size_t) num_bytes;
       
   187     cinfo->src->bytes_in_buffer -= (size_t) num_bytes;
       
   188   }
       
   189 }
       
   190 
       
   191 static gboolean
       
   192 gst_jpeg_dec_resync_to_restart (j_decompress_ptr cinfo, gint desired)
       
   193 {
       
   194   GST_DEBUG ("resync_to_start");
       
   195   return TRUE;
       
   196 }
       
   197 
       
   198 static void
       
   199 gst_jpeg_dec_term_source (j_decompress_ptr cinfo)
       
   200 {
       
   201   GST_DEBUG ("term_source");
       
   202   return;
       
   203 }
       
   204 
       
   205 METHODDEF (void)
       
   206     gst_jpeg_dec_my_output_message (j_common_ptr cinfo)
       
   207 {
       
   208   return;                       /* do nothing */
       
   209 }
       
   210 
       
   211 METHODDEF (void)
       
   212     gst_jpeg_dec_my_emit_message (j_common_ptr cinfo, int msg_level)
       
   213 {
       
   214   /* GST_DEBUG ("emit_message: msg_level = %d", msg_level); */
       
   215   return;
       
   216 }
       
   217 
       
   218 METHODDEF (void)
       
   219     gst_jpeg_dec_my_error_exit (j_common_ptr cinfo)
       
   220 {
       
   221   struct GstJpegDecErrorMgr *err_mgr = (struct GstJpegDecErrorMgr *) cinfo->err;
       
   222 
       
   223   (*cinfo->err->output_message) (cinfo);
       
   224   longjmp (err_mgr->setjmp_buffer, 1);
       
   225 }
       
   226 
       
   227 static void
       
   228 gst_jpeg_dec_init (GstJpegDec * dec)
       
   229 {
       
   230   GST_DEBUG ("initializing");
       
   231 
       
   232   /* create the sink and src pads */
       
   233   dec->sinkpad =
       
   234       gst_pad_new_from_static_template (&gst_jpeg_dec_sink_pad_template,
       
   235       "sink");
       
   236   gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
       
   237   gst_pad_set_setcaps_function (dec->sinkpad,
       
   238       GST_DEBUG_FUNCPTR (gst_jpeg_dec_setcaps));
       
   239   gst_pad_set_chain_function (dec->sinkpad,
       
   240       GST_DEBUG_FUNCPTR (gst_jpeg_dec_chain));
       
   241 
       
   242   dec->srcpad =
       
   243       gst_pad_new_from_static_template (&gst_jpeg_dec_src_pad_template, "src");
       
   244   gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
       
   245 
       
   246   /* setup jpeglib */
       
   247   memset (&dec->cinfo, 0, sizeof (dec->cinfo));
       
   248   memset (&dec->jerr, 0, sizeof (dec->jerr));
       
   249   dec->cinfo.err = jpeg_std_error (&dec->jerr.pub);
       
   250   dec->jerr.pub.output_message = gst_jpeg_dec_my_output_message;
       
   251   dec->jerr.pub.emit_message = gst_jpeg_dec_my_emit_message;
       
   252   dec->jerr.pub.error_exit = gst_jpeg_dec_my_error_exit;
       
   253 
       
   254   jpeg_create_decompress (&dec->cinfo);
       
   255 
       
   256   dec->cinfo.src = (struct jpeg_source_mgr *) &dec->jsrc;
       
   257   dec->cinfo.src->init_source = gst_jpeg_dec_init_source;
       
   258   dec->cinfo.src->fill_input_buffer = gst_jpeg_dec_fill_input_buffer;
       
   259   dec->cinfo.src->skip_input_data = gst_jpeg_dec_skip_input_data;
       
   260   dec->cinfo.src->resync_to_restart = gst_jpeg_dec_resync_to_restart;
       
   261   dec->cinfo.src->term_source = gst_jpeg_dec_term_source;
       
   262   dec->jsrc.dec = dec;
       
   263 }
       
   264 
       
   265 static inline gboolean
       
   266 is_jpeg_start_marker (const guint8 * data)
       
   267 {
       
   268   return (data[0] == 0xff && data[1] == 0xd8);
       
   269 }
       
   270 
       
   271 static inline gboolean
       
   272 is_jpeg_end_marker (const guint8 * data)
       
   273 {
       
   274   return (data[0] == 0xff && data[1] == 0xd9);
       
   275 }
       
   276 
       
   277 static gboolean
       
   278 gst_jpeg_dec_find_jpeg_header (GstJpegDec * dec)
       
   279 {
       
   280   const guint8 *data;
       
   281   guint size;
       
   282 
       
   283   data = GST_BUFFER_DATA (dec->tempbuf);
       
   284   size = GST_BUFFER_SIZE (dec->tempbuf);
       
   285 
       
   286   g_return_val_if_fail (size >= 2, FALSE);
       
   287 
       
   288   while (!is_jpeg_start_marker (data) || data[2] != 0xff) {
       
   289     const guint8 *marker;
       
   290     GstBuffer *tmp;
       
   291     guint off;
       
   292 
       
   293     marker = memchr (data + 1, 0xff, size - 1 - 2);
       
   294     if (marker == NULL) {
       
   295       off = size - 1;           /* keep last byte */
       
   296     } else {
       
   297       off = marker - data;
       
   298     }
       
   299 
       
   300     tmp = gst_buffer_create_sub (dec->tempbuf, off, size - off);
       
   301     gst_buffer_unref (dec->tempbuf);
       
   302     dec->tempbuf = tmp;
       
   303 
       
   304     data = GST_BUFFER_DATA (dec->tempbuf);
       
   305     size = GST_BUFFER_SIZE (dec->tempbuf);
       
   306 
       
   307     if (size < 2)
       
   308       return FALSE;             /* wait for more data */
       
   309   }
       
   310 
       
   311   return TRUE;                  /* got header */
       
   312 }
       
   313 
       
   314 static gboolean
       
   315 gst_jpeg_dec_ensure_header (GstJpegDec * dec)
       
   316 {
       
   317   g_return_val_if_fail (dec->tempbuf != NULL, FALSE);
       
   318 
       
   319 check_header:
       
   320 
       
   321   /* we need at least a start marker (0xff 0xd8)
       
   322    *   and an end marker (0xff 0xd9) */
       
   323   if (GST_BUFFER_SIZE (dec->tempbuf) <= 4) {
       
   324     GST_DEBUG ("Not enough data");
       
   325     return FALSE;               /* we need more data */
       
   326   }
       
   327 
       
   328   if (!is_jpeg_start_marker (GST_BUFFER_DATA (dec->tempbuf))) {
       
   329     GST_DEBUG ("Not a JPEG header, resyncing to header...");
       
   330     if (!gst_jpeg_dec_find_jpeg_header (dec)) {
       
   331       GST_DEBUG ("No JPEG header in current buffer");
       
   332       return FALSE;             /* we need more data */
       
   333     }
       
   334     GST_DEBUG ("Found JPEG header");
       
   335     goto check_header;          /* buffer might have changed */
       
   336   }
       
   337 
       
   338   return TRUE;
       
   339 }
       
   340 
       
   341 #if 0
       
   342 static gboolean
       
   343 gst_jpeg_dec_have_end_marker (GstJpegDec * dec)
       
   344 {
       
   345   guint8 *data = GST_BUFFER_DATA (dec->tempbuf);
       
   346   guint size = GST_BUFFER_SIZE (dec->tempbuf);
       
   347 
       
   348   return (size > 2 && data && is_jpeg_end_marker (data + size - 2));
       
   349 }
       
   350 #endif
       
   351 
       
   352 static inline gboolean
       
   353 gst_jpeg_dec_parse_tag_has_entropy_segment (guint8 tag)
       
   354 {
       
   355   if (tag == 0xda || (tag >= 0xd0 && tag <= 0xd7))
       
   356     return TRUE;
       
   357   return FALSE;
       
   358 }
       
   359 
       
   360 /* returns image length in bytes if parsed 
       
   361  * successfully, otherwise 0 */
       
   362 static guint
       
   363 gst_jpeg_dec_parse_image_data (GstJpegDec * dec)
       
   364 {
       
   365   guint8 *start, *data, *end;
       
   366   guint size;
       
   367 
       
   368   size = GST_BUFFER_SIZE (dec->tempbuf);
       
   369   start = GST_BUFFER_DATA (dec->tempbuf);
       
   370   end = start + size;
       
   371   data = start;
       
   372 
       
   373   g_return_val_if_fail (is_jpeg_start_marker (data), 0);
       
   374 
       
   375   GST_DEBUG ("Parsing jpeg image data (%u bytes)", size);
       
   376 
       
   377   /* skip start marker */
       
   378   data += 2;
       
   379 
       
   380   while (1) {
       
   381     guint frame_len;
       
   382 
       
   383     /* enough bytes left for EOI marker? (we need 0xff 0xNN, thus end-1) */
       
   384     if (data >= end - 1) {
       
   385       GST_DEBUG ("at end of input and no EOI marker found, need more data");
       
   386       return 0;
       
   387     }
       
   388 
       
   389     if (is_jpeg_end_marker (data)) {
       
   390       GST_DEBUG ("0x%08x: end marker", data - start);
       
   391       goto found_eoi;
       
   392     }
       
   393 
       
   394     /* do we need to resync? */
       
   395     if (*data != 0xff) {
       
   396       GST_DEBUG ("Lost sync at 0x%08x, resyncing", data - start);
       
   397       /* at the very least we expect 0xff 0xNN, thus end-1 */
       
   398       while (*data != 0xff && data < end - 1)
       
   399         ++data;
       
   400       if (is_jpeg_end_marker (data)) {
       
   401         GST_DEBUG ("resynced to end marker");
       
   402         goto found_eoi;
       
   403       }
       
   404       /* we need 0xFF 0xNN 0xLL 0xLL */
       
   405       if (data >= end - 1 - 2) {
       
   406         GST_DEBUG ("at end of input, without new sync, need more data");
       
   407         return 0;
       
   408       }
       
   409       /* check if we will still be in sync if we interpret
       
   410        * this as a sync point and skip this frame */
       
   411       frame_len = GST_READ_UINT16_BE (data + 2);
       
   412       GST_DEBUG ("possible sync at 0x%08x, frame_len=%u", data - start,
       
   413           frame_len);
       
   414       if (data + 2 + frame_len >= end - 1 || data[2 + frame_len] != 0xff) {
       
   415         /* ignore and continue resyncing until we hit the end
       
   416          * of our data or find a sync point that looks okay */
       
   417         ++data;
       
   418         continue;
       
   419       }
       
   420       GST_DEBUG ("found sync at 0x%08x", data - size);
       
   421     }
       
   422     while (*data == 0xff)
       
   423       ++data;
       
   424     if (data + 2 >= end)
       
   425       return 0;
       
   426     if (*data >= 0xd0 && *data <= 0xd7)
       
   427       frame_len = 0;
       
   428     else
       
   429       frame_len = GST_READ_UINT16_BE (data + 1);
       
   430     GST_DEBUG ("0x%08x: tag %02x, frame_len=%u", data - start - 1, *data,
       
   431         frame_len);
       
   432     /* the frame length includes the 2 bytes for the length; here we want at
       
   433      * least 2 more bytes at the end for an end marker, thus end-2 */
       
   434     if (data + 1 + frame_len >= end - 2) {
       
   435       /* theoretically we could have lost sync and not really need more
       
   436        * data, but that's just tough luck and a broken image then */
       
   437       GST_DEBUG ("at end of input and no EOI marker found, need more data");
       
   438       return 0;
       
   439     }
       
   440     if (gst_jpeg_dec_parse_tag_has_entropy_segment (*data)) {
       
   441       guint8 *d2 = data + 1 + frame_len;
       
   442       guint eseglen = 0;
       
   443 
       
   444       GST_DEBUG ("0x%08x: finding entropy segment length", data - start - 1);
       
   445       while (1) {
       
   446         if (d2[eseglen] == 0xff && d2[eseglen + 1] != 0x00)
       
   447           break;
       
   448         if (d2 + eseglen >= end - 1)
       
   449           return 0;             /* need more data */
       
   450         ++eseglen;
       
   451       }
       
   452       frame_len += eseglen;
       
   453       GST_DEBUG ("entropy segment length=%u => frame_len=%u", eseglen,
       
   454           frame_len);
       
   455     }
       
   456     data += 1 + frame_len;
       
   457   }
       
   458 
       
   459 found_eoi:
       
   460   /* data is assumed to point to the 0xff sync point of the
       
   461    *  EOI marker (so there is one more byte after that) */
       
   462   g_assert (is_jpeg_end_marker (data));
       
   463   return ((data + 1) - start + 1);
       
   464 }
       
   465 
       
   466 /* shamelessly ripped from jpegutils.c in mjpegtools */
       
   467 static void
       
   468 add_huff_table (j_decompress_ptr dinfo,
       
   469     JHUFF_TBL ** htblptr, const UINT8 * bits, const UINT8 * val)
       
   470 /* Define a Huffman table */
       
   471 {
       
   472   int nsymbols, len;
       
   473 
       
   474   if (*htblptr == NULL)
       
   475     *htblptr = jpeg_alloc_huff_table ((j_common_ptr) dinfo);
       
   476 
       
   477   /* Copy the number-of-symbols-of-each-code-length counts */
       
   478   memcpy ((*htblptr)->bits, bits, sizeof ((*htblptr)->bits));
       
   479 
       
   480   /* Validate the counts.  We do this here mainly so we can copy the right
       
   481    * number of symbols from the val[] array, without risking marching off
       
   482    * the end of memory.  jchuff.c will do a more thorough test later.
       
   483    */
       
   484   nsymbols = 0;
       
   485   for (len = 1; len <= 16; len++)
       
   486     nsymbols += bits[len];
       
   487   if (nsymbols < 1 || nsymbols > 256)
       
   488     g_error ("jpegutils.c:  add_huff_table failed badly. ");
       
   489 
       
   490   memcpy ((*htblptr)->huffval, val, nsymbols * sizeof (UINT8));
       
   491 }
       
   492 
       
   493 
       
   494 
       
   495 static void
       
   496 std_huff_tables (j_decompress_ptr dinfo)
       
   497 /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
       
   498 /* IMPORTANT: these are only valid for 8-bit data precision! */
       
   499 {
       
   500   static const UINT8 bits_dc_luminance[17] =
       
   501       { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
       
   502   static const UINT8 val_dc_luminance[] =
       
   503       { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
       
   504 
       
   505   static const UINT8 bits_dc_chrominance[17] =
       
   506       { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
       
   507   static const UINT8 val_dc_chrominance[] =
       
   508       { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
       
   509 
       
   510   static const UINT8 bits_ac_luminance[17] =
       
   511       { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
       
   512   static const UINT8 val_ac_luminance[] =
       
   513       { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
       
   514     0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
       
   515     0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
       
   516     0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
       
   517     0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
       
   518     0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
       
   519     0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
       
   520     0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
       
   521     0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
       
   522     0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
       
   523     0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
       
   524     0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
       
   525     0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
       
   526     0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
       
   527     0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
       
   528     0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
       
   529     0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
       
   530     0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
       
   531     0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
       
   532     0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
       
   533     0xf9, 0xfa
       
   534   };
       
   535 
       
   536   static const UINT8 bits_ac_chrominance[17] =
       
   537       { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
       
   538   static const UINT8 val_ac_chrominance[] =
       
   539       { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
       
   540     0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
       
   541     0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
       
   542     0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
       
   543     0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
       
   544     0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
       
   545     0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
       
   546     0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
       
   547     0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
       
   548     0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
       
   549     0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
       
   550     0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
       
   551     0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
       
   552     0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
       
   553     0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
       
   554     0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
       
   555     0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
       
   556     0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
       
   557     0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
       
   558     0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
       
   559     0xf9, 0xfa
       
   560   };
       
   561 
       
   562   add_huff_table (dinfo, &dinfo->dc_huff_tbl_ptrs[0],
       
   563       bits_dc_luminance, val_dc_luminance);
       
   564   add_huff_table (dinfo, &dinfo->ac_huff_tbl_ptrs[0],
       
   565       bits_ac_luminance, val_ac_luminance);
       
   566   add_huff_table (dinfo, &dinfo->dc_huff_tbl_ptrs[1],
       
   567       bits_dc_chrominance, val_dc_chrominance);
       
   568   add_huff_table (dinfo, &dinfo->ac_huff_tbl_ptrs[1],
       
   569       bits_ac_chrominance, val_ac_chrominance);
       
   570 }
       
   571 
       
   572 
       
   573 
       
   574 static void
       
   575 guarantee_huff_tables (j_decompress_ptr dinfo)
       
   576 {
       
   577   if ((dinfo->dc_huff_tbl_ptrs[0] == NULL) &&
       
   578       (dinfo->dc_huff_tbl_ptrs[1] == NULL) &&
       
   579       (dinfo->ac_huff_tbl_ptrs[0] == NULL) &&
       
   580       (dinfo->ac_huff_tbl_ptrs[1] == NULL)) {
       
   581     GST_DEBUG ("Generating standard Huffman tables for this frame.");
       
   582     std_huff_tables (dinfo);
       
   583   }
       
   584 }
       
   585 
       
   586 static gboolean
       
   587 gst_jpeg_dec_setcaps (GstPad * pad, GstCaps * caps)
       
   588 {
       
   589   GstStructure *s;
       
   590   GstJpegDec *dec;
       
   591   const GValue *framerate;
       
   592 
       
   593   dec = GST_JPEG_DEC (GST_OBJECT_PARENT (pad));
       
   594   s = gst_caps_get_structure (caps, 0);
       
   595 
       
   596   if ((framerate = gst_structure_get_value (s, "framerate")) != NULL) {
       
   597     dec->framerate_numerator = gst_value_get_fraction_numerator (framerate);
       
   598     dec->framerate_denominator = gst_value_get_fraction_denominator (framerate);
       
   599     dec->packetized = TRUE;
       
   600     GST_DEBUG ("got framerate of %d/%d fps => packetized mode",
       
   601         dec->framerate_numerator, dec->framerate_denominator);
       
   602   }
       
   603 
       
   604   /* do not extract width/height here. we do that in the chain
       
   605    * function on a per-frame basis (including the line[] array
       
   606    * setup) */
       
   607 
       
   608   /* But we can take the framerate values and set them on the src pad */
       
   609 
       
   610   return TRUE;
       
   611 }
       
   612 
       
   613 static void
       
   614 gst_jpeg_dec_decode_indirect (GstJpegDec * dec, guchar * base[3],
       
   615     guchar * last[3], guint width, guint height, gint r_v)
       
   616 {
       
   617 #ifdef SYMBIAN
       
   618   static guchar y[16][MAX_WIDTH];
       
   619   static guchar u[8][MAX_WIDTH / 2];
       
   620   static guchar v[8][MAX_WIDTH / 2];
       
   621   static guchar *y_rows[16] = { y[0], y[1], y[2], y[3], y[4], y[5], y[6], y[7],
       
   622     y[8], y[9], y[10], y[11], y[12], y[13], y[14], y[15]
       
   623   };
       
   624   static guchar *u_rows[8] = { u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7] };
       
   625   static guchar *v_rows[8] = { v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7] };
       
   626   static guchar **scanarray[3] = { y_rows, u_rows, v_rows };
       
   627 #else // SYMBIAN
       
   628   guchar y[16][MAX_WIDTH];
       
   629   guchar u[8][MAX_WIDTH / 2];
       
   630   guchar v[8][MAX_WIDTH / 2];
       
   631   guchar *y_rows[16] = { y[0], y[1], y[2], y[3], y[4], y[5], y[6], y[7],
       
   632     y[8], y[9], y[10], y[11], y[12], y[13], y[14], y[15]
       
   633   };
       
   634   guchar *u_rows[8] = { u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7] };
       
   635   guchar *v_rows[8] = { v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7] };
       
   636   guchar **scanarray[3] = { y_rows, u_rows, v_rows };
       
   637 #endif // SYMBIAN
       
   638   gint i, j, k;
       
   639 
       
   640   GST_DEBUG_OBJECT (dec,
       
   641       "unadvantageous width, taking slow route involving memcpy");
       
   642 
       
   643   for (i = 0; i < height; i += r_v * DCTSIZE) {
       
   644     jpeg_read_raw_data (&dec->cinfo, scanarray, r_v * DCTSIZE);
       
   645     for (j = 0, k = 0; j < (r_v * DCTSIZE); j += r_v, k++) {
       
   646       memcpy (base[0], y_rows[j], I420_Y_ROWSTRIDE (width));
       
   647       if (base[0] < last[0])
       
   648         base[0] += I420_Y_ROWSTRIDE (width);
       
   649       if (r_v == 2) {
       
   650         memcpy (base[0], y_rows[j + 1], I420_Y_ROWSTRIDE (width));
       
   651         if (base[0] < last[0])
       
   652           base[0] += I420_Y_ROWSTRIDE (width);
       
   653       }
       
   654       memcpy (base[1], u_rows[k], I420_U_ROWSTRIDE (width));
       
   655       memcpy (base[2], v_rows[k], I420_V_ROWSTRIDE (width));
       
   656       if (r_v == 2 || (k & 1) != 0) {
       
   657         if (base[1] < last[1] && base[2] < last[2]) {
       
   658           base[1] += I420_U_ROWSTRIDE (width);
       
   659           base[2] += I420_V_ROWSTRIDE (width);
       
   660         }
       
   661       }
       
   662     }
       
   663   }
       
   664 }
       
   665 
       
   666 static void
       
   667 gst_jpeg_dec_decode_direct (GstJpegDec * dec, guchar * base[3],
       
   668     guchar * last[3], guint width, guint height, gint r_v)
       
   669 {
       
   670   guchar **line[3];             /* the jpeg line buffer */
       
   671   gint i, j, k;
       
   672 
       
   673   line[0] = g_new0 (guchar *, (r_v * DCTSIZE));
       
   674   line[1] = g_new0 (guchar *, (r_v * DCTSIZE));
       
   675   line[2] = g_new0 (guchar *, (r_v * DCTSIZE));
       
   676 
       
   677   /* let jpeglib decode directly into our final buffer */
       
   678   GST_DEBUG_OBJECT (dec, "decoding directly into output buffer");
       
   679   for (i = 0; i < height; i += r_v * DCTSIZE) {
       
   680     for (j = 0, k = 0; j < (r_v * DCTSIZE); j += r_v, k++) {
       
   681       line[0][j] = base[0];
       
   682       if (base[0] < last[0])
       
   683         base[0] += I420_Y_ROWSTRIDE (width);
       
   684       if (r_v == 2) {
       
   685         line[0][j + 1] = base[0];
       
   686         if (base[0] < last[0])
       
   687           base[0] += I420_Y_ROWSTRIDE (width);
       
   688       }
       
   689       line[1][k] = base[1];
       
   690       line[2][k] = base[2];
       
   691       if (r_v == 2 || (k & 1) != 0) {
       
   692         if (base[1] < last[1] && base[2] < last[2]) {
       
   693           base[1] += I420_U_ROWSTRIDE (width);
       
   694           base[2] += I420_V_ROWSTRIDE (width);
       
   695         }
       
   696       }
       
   697     }
       
   698     jpeg_read_raw_data (&dec->cinfo, line, r_v * DCTSIZE);
       
   699   }
       
   700 
       
   701   g_free (line[0]);
       
   702   g_free (line[1]);
       
   703   g_free (line[2]);
       
   704 }
       
   705 
       
   706 
       
   707 static GstFlowReturn
       
   708 gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf)
       
   709 {
       
   710   GstFlowReturn ret;
       
   711   GstJpegDec *dec;
       
   712   GstBuffer *outbuf;
       
   713   gulong size;
       
   714   guchar *data, *outdata;
       
   715   guchar *base[3], *last[3];
       
   716   guint img_len;
       
   717   gint width, height;
       
   718   gint r_h, r_v;
       
   719   gint i;
       
   720   guint code;
       
   721   GstClockTime timestamp, duration;
       
   722 
       
   723   dec = GST_JPEG_DEC (GST_OBJECT_PARENT (pad));
       
   724 
       
   725   timestamp = GST_BUFFER_TIMESTAMP (buf);
       
   726   duration = GST_BUFFER_DURATION (buf);
       
   727 
       
   728 /*
       
   729   GST_LOG_OBJECT (dec, "Received buffer: %d bytes, ts=%" GST_TIME_FORMAT
       
   730       ", dur=%" GST_TIME_FORMAT, GST_BUFFER_SIZE (buf),
       
   731       GST_TIME_ARGS (timestamp), GST_TIME_ARGS (duration));
       
   732 */
       
   733 
       
   734   if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
       
   735     dec->next_ts = timestamp;
       
   736   }
       
   737 
       
   738   if (dec->tempbuf) {
       
   739     dec->tempbuf = gst_buffer_join (dec->tempbuf, buf);
       
   740   } else {
       
   741     dec->tempbuf = buf;
       
   742   }
       
   743   buf = NULL;
       
   744 
       
   745   if (!gst_jpeg_dec_ensure_header (dec))
       
   746     goto need_more_data;
       
   747 
       
   748   /* If we know that each input buffer contains data
       
   749    * for a whole jpeg image (e.g. MJPEG streams), just 
       
   750    * do some sanity checking instead of parsing all of 
       
   751    * the jpeg data */
       
   752   if (dec->packetized) {
       
   753     img_len = GST_BUFFER_SIZE (dec->tempbuf);
       
   754   } else {
       
   755     /* Parse jpeg image to handle jpeg input that
       
   756      * is not aligned to buffer boundaries */
       
   757     img_len = gst_jpeg_dec_parse_image_data (dec);
       
   758 
       
   759     if (img_len == 0)
       
   760       goto need_more_data;
       
   761   }
       
   762 
       
   763   data = (guchar *) GST_BUFFER_DATA (dec->tempbuf);
       
   764   size = img_len;
       
   765   GST_LOG_OBJECT (dec, "image size = %u", img_len);
       
   766 
       
   767   dec->jsrc.pub.next_input_byte = data;
       
   768   dec->jsrc.pub.bytes_in_buffer = size;
       
   769 
       
   770   if (setjmp (dec->jerr.setjmp_buffer)) {
       
   771     code = dec->jerr.pub.msg_code;
       
   772 
       
   773     if (code == JERR_INPUT_EOF) {
       
   774       GST_DEBUG ("jpeg input EOF error, we probably need more data");
       
   775       goto need_more_data;
       
   776     }
       
   777     goto decode_error;
       
   778   }
       
   779 
       
   780   GST_LOG_OBJECT (dec, "reading header %02x %02x %02x %02x", data[0], data[1],
       
   781       data[2], data[3]);
       
   782   jpeg_read_header (&dec->cinfo, TRUE);
       
   783 
       
   784   r_h = dec->cinfo.cur_comp_info[0]->h_samp_factor;
       
   785   r_v = dec->cinfo.cur_comp_info[0]->v_samp_factor;
       
   786 
       
   787   GST_DEBUG ("num_components=%d, comps_in_scan=%d\n",
       
   788       dec->cinfo.num_components, dec->cinfo.comps_in_scan);
       
   789   for (i = 0; i < dec->cinfo.num_components; ++i) {
       
   790     GST_DEBUG ("[%d] h_samp_factor=%d, v_samp_factor=%d\n", i,
       
   791         dec->cinfo.cur_comp_info[i]->h_samp_factor,
       
   792         dec->cinfo.cur_comp_info[i]->v_samp_factor);
       
   793   }
       
   794 
       
   795   dec->cinfo.do_fancy_upsampling = FALSE;
       
   796   dec->cinfo.do_block_smoothing = FALSE;
       
   797   dec->cinfo.out_color_space = JCS_YCbCr;
       
   798   dec->cinfo.dct_method = JDCT_IFAST;
       
   799   dec->cinfo.raw_data_out = TRUE;
       
   800   GST_LOG_OBJECT (dec, "starting decompress");
       
   801   guarantee_huff_tables (&dec->cinfo);
       
   802   jpeg_start_decompress (&dec->cinfo);
       
   803   width = dec->cinfo.output_width;
       
   804   height = dec->cinfo.output_height;
       
   805 
       
   806   if (width < MIN_WIDTH || width > MAX_WIDTH ||
       
   807       height < MIN_HEIGHT || height > MAX_HEIGHT)
       
   808     goto wrong_size;
       
   809 
       
   810   if (width != dec->caps_width || height != dec->caps_height ||
       
   811       dec->framerate_numerator != dec->caps_framerate_numerator ||
       
   812       dec->framerate_denominator != dec->caps_framerate_denominator) {
       
   813     GstCaps *caps;
       
   814 
       
   815     /* framerate == 0/1 is a still frame */
       
   816     if (dec->framerate_denominator == 0) {
       
   817       dec->framerate_numerator = 0;
       
   818       dec->framerate_denominator = 1;
       
   819     }
       
   820 
       
   821     caps = gst_caps_new_simple ("video/x-raw-yuv",
       
   822         "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
       
   823         "width", G_TYPE_INT, width,
       
   824         "height", G_TYPE_INT, height,
       
   825         "framerate", GST_TYPE_FRACTION, dec->framerate_numerator,
       
   826         dec->framerate_denominator, NULL);
       
   827 
       
   828     GST_DEBUG_OBJECT (dec, "setting caps %" GST_PTR_FORMAT, caps);
       
   829     GST_DEBUG_OBJECT (dec, "max_v_samp_factor=%d",
       
   830         dec->cinfo.max_v_samp_factor);
       
   831 
       
   832     gst_pad_use_fixed_caps (dec->srcpad);
       
   833     gst_pad_set_caps (dec->srcpad, caps);
       
   834     gst_caps_unref (caps);
       
   835 
       
   836     dec->caps_width = width;
       
   837     dec->caps_height = height;
       
   838     dec->caps_framerate_numerator = dec->framerate_numerator;
       
   839     dec->caps_framerate_denominator = dec->framerate_denominator;
       
   840   }
       
   841 
       
   842   ret = gst_pad_alloc_buffer_and_set_caps (dec->srcpad, GST_BUFFER_OFFSET_NONE,
       
   843       I420_SIZE (width, height), GST_PAD_CAPS (dec->srcpad), &outbuf);
       
   844   if (ret != GST_FLOW_OK)
       
   845     goto alloc_failed;
       
   846 
       
   847   outdata = GST_BUFFER_DATA (outbuf);
       
   848   GST_BUFFER_TIMESTAMP (outbuf) = dec->next_ts;
       
   849 
       
   850   if (dec->packetized && GST_CLOCK_TIME_IS_VALID (dec->next_ts)) {
       
   851     if (GST_CLOCK_TIME_IS_VALID (duration)) {
       
   852       /* use duration from incoming buffer for outgoing buffer */
       
   853       dec->next_ts += duration;
       
   854     } else if (dec->framerate_numerator != 0) {
       
   855       duration = gst_util_uint64_scale (GST_SECOND,
       
   856           dec->framerate_denominator, dec->framerate_numerator);
       
   857       dec->next_ts += duration;
       
   858     } else {
       
   859       duration = GST_CLOCK_TIME_NONE;
       
   860       dec->next_ts = GST_CLOCK_TIME_NONE;
       
   861     }
       
   862   } else {
       
   863     duration = GST_CLOCK_TIME_NONE;
       
   864     dec->next_ts = GST_CLOCK_TIME_NONE;
       
   865   }
       
   866   GST_BUFFER_DURATION (outbuf) = duration;
       
   867 
       
   868   GST_LOG_OBJECT (dec, "width %d, height %d, buffer size %d, required size %d",
       
   869       width, height, GST_BUFFER_SIZE (outbuf), I420_SIZE (width, height));
       
   870 
       
   871   /* mind the swap, jpeglib outputs blue chroma first */
       
   872   base[0] = outdata + I420_Y_OFFSET (width, height);
       
   873   base[1] = outdata + I420_U_OFFSET (width, height);
       
   874   base[2] = outdata + I420_V_OFFSET (width, height);
       
   875 
       
   876   /* make sure we don't make jpeglib write beyond our buffer,
       
   877    * which might happen if (height % (r_v*DCTSIZE)) != 0 */
       
   878   last[0] = base[0] + (I420_Y_ROWSTRIDE (width) * (height - 1));
       
   879   last[1] =
       
   880       base[1] + (I420_U_ROWSTRIDE (width) * ((GST_ROUND_UP_2 (height) / 2) -
       
   881           1));
       
   882   last[2] =
       
   883       base[2] + (I420_V_ROWSTRIDE (width) * ((GST_ROUND_UP_2 (height) / 2) -
       
   884           1));
       
   885 
       
   886   GST_LOG_OBJECT (dec, "decompressing %u", dec->cinfo.rec_outbuf_height);
       
   887   GST_LOG_OBJECT (dec, "max_h_samp_factor=%u", dec->cinfo.max_h_samp_factor);
       
   888 
       
   889   /* For some widths jpeglib requires more horizontal padding than I420 
       
   890    * provides. In those cases we need to decode into separate buffers and then
       
   891    * copy over the data into our final picture buffer, otherwise jpeglib might
       
   892    * write over the end of a line into the beginning of the next line,
       
   893    * resulting in blocky artifacts on the left side of the picture. */
       
   894   if (width % (dec->cinfo.max_h_samp_factor * DCTSIZE) != 0) {
       
   895     gst_jpeg_dec_decode_indirect (dec, base, last, width, height, r_v);
       
   896   } else {
       
   897     gst_jpeg_dec_decode_direct (dec, base, last, width, height, r_v);
       
   898   }
       
   899 
       
   900   GST_LOG_OBJECT (dec, "decompressing finished");
       
   901   jpeg_finish_decompress (&dec->cinfo);
       
   902 
       
   903   GST_LOG_OBJECT (dec, "pushing buffer (ts=%" GST_TIME_FORMAT ", dur=%"
       
   904       GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
       
   905       GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
       
   906 
       
   907   ret = gst_pad_push (dec->srcpad, outbuf);
       
   908 
       
   909 done:
       
   910   if (GST_BUFFER_SIZE (dec->tempbuf) == img_len) {
       
   911     gst_buffer_unref (dec->tempbuf);
       
   912     dec->tempbuf = NULL;
       
   913   } else {
       
   914     GstBuffer *buf = gst_buffer_create_sub (dec->tempbuf, img_len,
       
   915         GST_BUFFER_SIZE (dec->tempbuf) - img_len);
       
   916 
       
   917     gst_buffer_unref (dec->tempbuf);
       
   918     dec->tempbuf = buf;
       
   919   }
       
   920   return ret;
       
   921 
       
   922   /* special cases */
       
   923 need_more_data:
       
   924   {
       
   925     GST_LOG_OBJECT (dec, "we need more data");
       
   926     return GST_FLOW_OK;
       
   927   }
       
   928   /* ERRORS */
       
   929 wrong_size:
       
   930   {
       
   931     GST_ELEMENT_ERROR (dec, STREAM, DECODE,
       
   932         ("Picture is too small or too big (%ux%u)", width, height),
       
   933         ("Picture is too small or too big (%ux%u)", width, height));
       
   934     ret = GST_FLOW_ERROR;
       
   935     goto done;
       
   936   }
       
   937 decode_error:
       
   938   {
       
   939     GST_ELEMENT_ERROR (dec, STREAM, DECODE,
       
   940         (_("Failed to decode JPEG image")),
       
   941         ("Error #%u: %s", code, dec->jerr.pub.jpeg_message_table[code]));
       
   942     ret = GST_FLOW_ERROR;
       
   943     goto done;
       
   944   }
       
   945 alloc_failed:
       
   946   {
       
   947     const gchar *reason;
       
   948 
       
   949     reason = gst_flow_get_name (ret);
       
   950 
       
   951     GST_DEBUG_OBJECT (dec, "failed to alloc buffer, reason %s", reason);
       
   952     if (GST_FLOW_IS_FATAL (ret)) {
       
   953       GST_ELEMENT_ERROR (dec, STREAM, DECODE,
       
   954           ("Buffer allocation failed, reason: %s", reason),
       
   955           ("Buffer allocation failed, reason: %s", reason));
       
   956     }
       
   957     return ret;
       
   958   }
       
   959 }
       
   960 
       
   961 static GstStateChangeReturn
       
   962 gst_jpeg_dec_change_state (GstElement * element, GstStateChange transition)
       
   963 {
       
   964   GstStateChangeReturn ret;
       
   965   GstJpegDec *dec;
       
   966 
       
   967   dec = GST_JPEG_DEC (element);
       
   968 
       
   969   switch (transition) {
       
   970     case GST_STATE_CHANGE_READY_TO_PAUSED:
       
   971       dec->framerate_numerator = 0;
       
   972       dec->framerate_denominator = 1;
       
   973       dec->caps_framerate_numerator = dec->caps_framerate_denominator = 0;
       
   974       dec->caps_width = -1;
       
   975       dec->caps_height = -1;
       
   976       dec->packetized = FALSE;
       
   977       dec->next_ts = 0;
       
   978     default:
       
   979       break;
       
   980   }
       
   981 
       
   982   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
       
   983   if (ret != GST_STATE_CHANGE_SUCCESS)
       
   984     return ret;
       
   985 
       
   986   switch (transition) {
       
   987     case GST_STATE_CHANGE_PAUSED_TO_READY:
       
   988       if (dec->tempbuf) {
       
   989         gst_buffer_unref (dec->tempbuf);
       
   990         dec->tempbuf = NULL;
       
   991       }
       
   992       break;
       
   993     default:
       
   994       break;
       
   995   }
       
   996 
       
   997   return ret;
       
   998 }