[vlc-devel] [PATCH] codec: implemented libjpeg module
Jean-Baptiste Kempf
jb at videolan.org
Wed Dec 25 20:20:59 CET 2013
Applied.
Thanks.
On 19 Dec, Maxim Bublis wrote :
> ---
> configure.ac | 11 ++
> modules/codec/Makefile.am | 6 ++
> modules/codec/jpeg.c | 250 ++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 267 insertions(+)
> create mode 100644 modules/codec/jpeg.c
>
> diff --git a/configure.ac b/configure.ac
> index 08fb0eb..d60eae3 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -2694,6 +2694,17 @@ AC_CHECK_HEADERS(png.h, [
> ])
>
> dnl
> +dnl JPEG decoder module
> +dnl
> +AC_ARG_ENABLE(jpeg,
> + [ --enable-jpeg JPEG support (default enabled)])
> +AS_IF([test "${enable_jpeg}" != "no"], [
> +AC_CHECK_HEADERS(jpeglib.h, [
> + VLC_ADD_PLUGIN([jpeg])
> + ])
> +])
> +
> +dnl
> dnl H262 encoder plugin (lib262)
> dnl
> AC_ARG_ENABLE(x262,
> diff --git a/modules/codec/Makefile.am b/modules/codec/Makefile.am
> index 05a0b00..9673d04 100644
> --- a/modules/codec/Makefile.am
> +++ b/modules/codec/Makefile.am
> @@ -103,6 +103,12 @@ libpng_plugin_la_LIBADD = -lpng -lz $(LIBM)
> EXTRA_LTLIBRARIES += libpng_plugin.la
> codec_LTLIBRARIES += $(LTLIBpng)
>
> +libjpeg_plugin_la_SOURCES = codec/jpeg.c
> +libjpeg_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(codecdir)'
> +libjpeg_plugin_la_LIBADD = -ljpeg
> +EXTRA_LTLIBRARIES += libjpeg_plugin.la
> +codec_LTLIBRARIES += $(LTLIBjpeg)
> +
> libsdl_image_plugin_la_SOURCES = codec/sdl_image.c
> libsdl_image_plugin_la_CFLAGS = $(AM_CFLAGS) $(SDL_IMAGE_CFLAGS)
> libsdl_image_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(codecdir)'
> diff --git a/modules/codec/jpeg.c b/modules/codec/jpeg.c
> new file mode 100644
> index 0000000..3283574
> --- /dev/null
> +++ b/modules/codec/jpeg.c
> @@ -0,0 +1,250 @@
> +/*****************************************************************************
> + * jpeg.c: jpeg decoder module making use of libjpeg.
> + *****************************************************************************
> + * Copyright (C) 2013 VLC authors and VideoLAN
> + *
> + * Authors: Maxim Bublis <b at codemonkey.ru>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License as published by
> + * the Free Software Foundation; either version 2.1 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program; if not, write to the Free Software Foundation,
> + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> + *****************************************************************************/
> +
> +#ifdef HAVE_CONFIG_H
> +# include "config.h"
> +#endif
> +
> +#include <vlc_common.h>
> +#include <vlc_plugin.h>
> +#include <vlc_codec.h>
> +#include <jpeglib.h>
> +#include <setjmp.h>
> +
> +/*
> + * jpeg decoder descriptor
> + */
> +struct decoder_sys_t
> +{
> + /* libjpeg error handler manager */
> + struct jpeg_error_mgr err;
> +
> + /* setjmp buffer for internal libjpeg error handling */
> + jmp_buf setjmp_buffer;
> +
> + bool b_error;
> +
> + decoder_t *p_dec;
> +};
> +
> +static int OpenDecoder(vlc_object_t *);
> +static void CloseDecoder(vlc_object_t *);
> +
> +static picture_t *DecodeBlock(decoder_t *, block_t **);
> +
> +/*
> + * Module descriptor
> + */
> +vlc_module_begin()
> + set_category(CAT_INPUT)
> + set_subcategory(SUBCAT_INPUT_VCODEC)
> + set_description(N_("JPEG image decoder"))
> + set_capability("decoder", 1000)
> + set_callbacks(OpenDecoder, CloseDecoder)
> + add_shortcut("jpeg")
> +vlc_module_end()
> +
> +/*
> + * Probe the decoder and return score
> + */
> +static int OpenDecoder(vlc_object_t *p_this)
> +{
> + decoder_t *p_dec = (decoder_t *)p_this;
> +
> + if (p_dec->fmt_in.i_codec != VLC_CODEC_JPEG)
> + {
> + return VLC_EGENERIC;
> + }
> +
> + /* Allocate the memory needed to store the decoder's structure */
> + p_dec->p_sys = malloc(sizeof(decoder_sys_t));
> + if (p_dec->p_sys == NULL)
> + {
> + return VLC_ENOMEM;
> + }
> +
> + p_dec->p_sys->p_dec = p_dec;
> +
> + /* Set output properties */
> + p_dec->fmt_out.i_cat = VIDEO_ES;
> +
> + /* Set callbacks */
> + p_dec->pf_decode_video = DecodeBlock;
> +
> + return VLC_SUCCESS;
> +}
> +
> +/*
> + * Exit error handler for libjpeg
> + */
> +static void user_error_exit(j_common_ptr p_jpeg)
> +{
> + decoder_sys_t *p_sys = (decoder_sys_t *)p_jpeg->err;
> + p_sys->b_error = true;
> + p_sys->err.output_message(p_jpeg);
> + longjmp(p_sys->setjmp_buffer, 1);
> +}
> +
> +/*
> + * Emit message error handler for libjpeg
> + */
> +static void user_error_message(j_common_ptr p_jpeg)
> +{
> + char error_msg[JMSG_LENGTH_MAX];
> +
> + decoder_sys_t *p_sys = (decoder_sys_t *)p_jpeg->err;
> + p_sys->err.format_message(p_jpeg, error_msg);
> + msg_Err(p_sys->p_dec, "%s", error_msg);
> +}
> +
> +/*
> + * This function must be fed with a complete compressed frame.
> + */
> +static picture_t *DecodeBlock(decoder_t *p_dec, block_t **pp_block)
> +{
> + decoder_sys_t *p_sys = p_dec->p_sys;
> + block_t *p_block;
> + picture_t *p_pic = 0;
> +
> + struct jpeg_decompress_struct p_jpeg;
> + JSAMPARRAY p_row_pointers = NULL;
> +
> + if (!pp_block || !*pp_block)
> + {
> + return NULL;
> + }
> +
> + p_block = *pp_block;
> + p_sys->b_error = false;
> +
> + if (p_block->i_flags & BLOCK_FLAG_DISCONTINUITY)
> + {
> + block_Release(p_block);
> + *pp_block = NULL;
> + return NULL;
> + }
> +
> + p_jpeg.err = jpeg_std_error(&p_sys->err);
> + p_sys->err.error_exit = user_error_exit;
> + p_sys->err.output_message = user_error_message;
> +
> + /* libjpeg longjmp's there in case of error */
> + if (setjmp(p_sys->setjmp_buffer))
> + {
> + goto error;
> + }
> +
> + jpeg_create_decompress(&p_jpeg);
> + if (p_sys->b_error)
> + {
> + goto error;
> + }
> +
> + jpeg_mem_src(&p_jpeg, p_block->p_buffer, p_block->i_buffer);
> + if (p_sys->b_error)
> + {
> + goto error;
> + }
> +
> + jpeg_read_header(&p_jpeg, TRUE);
> + if (p_sys->b_error)
> + {
> + goto error;
> + }
> +
> + p_jpeg.out_color_space = JCS_RGB;
> +
> + jpeg_start_decompress(&p_jpeg);
> + if (p_sys->b_error)
> + {
> + goto error;
> + }
> +
> + /* Set output properties */
> + p_dec->fmt_out.i_codec = VLC_CODEC_RGB24;
> + p_dec->fmt_out.video.i_width = p_jpeg.output_width;
> + p_dec->fmt_out.video.i_height = p_jpeg.output_height;
> + p_dec->fmt_out.video.i_sar_num = 1;
> + p_dec->fmt_out.video.i_sar_den = 1;
> + p_dec->fmt_out.video.i_rmask = 0x000000ff;
> + p_dec->fmt_out.video.i_gmask = 0x0000ff00;
> + p_dec->fmt_out.video.i_bmask = 0x00ff0000;
> +
> + /* Get a new picture */
> + p_pic = decoder_NewPicture(p_dec);
> + if (!p_pic)
> + {
> + goto error;
> + }
> +
> + /* Decode picture */
> + p_row_pointers = malloc(sizeof(JSAMPROW) * p_jpeg.output_height);
> + if (!p_row_pointers)
> + {
> + goto error;
> + }
> + for (int i = 0; i < (int)p_jpeg.output_height; i++) {
> + p_row_pointers[i] = p_pic->p->p_pixels + p_pic->p->i_pitch * i;
> + }
> +
> + while (p_jpeg.output_scanline < p_jpeg.output_height)
> + {
> + jpeg_read_scanlines(&p_jpeg, p_row_pointers + p_jpeg.output_scanline,
> + p_jpeg.output_height - p_jpeg.output_scanline);
> + if (p_sys->b_error)
> + {
> + goto error;
> + }
> + }
> +
> + jpeg_finish_decompress(&p_jpeg);
> + jpeg_destroy_decompress(&p_jpeg);
> + free(p_row_pointers);
> +
> + p_pic->date = p_block->i_pts > VLC_TS_INVALID ? p_block->i_pts : p_block->i_dts;
> +
> + block_Release(p_block);
> + *pp_block = NULL;
> +
> + return p_pic;
> +
> +error:
> +
> + jpeg_destroy_decompress(&p_jpeg);
> + free(p_row_pointers);
> +
> + block_Release(p_block);
> + *pp_block = NULL;
> +
> + return NULL;
> +}
> +
> +/*
> + * jpeg decoder destruction
> + */
> +static void CloseDecoder(vlc_object_t *p_this)
> +{
> + decoder_t *p_dec = (decoder_t *)p_this;
> + decoder_sys_t *p_sys = p_dec->p_sys;
> +
> + free(p_sys);
> +}
> --
> 1.8.3.4 (Apple Git-47)
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
--
With my kindest regards,
--
Jean-Baptiste Kempf
http://www.jbkempf.com/ - +33 672 704 734
Sent from my Electronic Device
More information about the vlc-devel
mailing list