[vlc-devel] [PATCH v2 1/3] lib: Add libvlc_picture API

Hugo Beauzée-Luyssen hugo at beauzee.fr
Tue Oct 16 10:52:46 CEST 2018


On Tue, Oct 16, 2018, at 10:42 AM, Thomas Guillem wrote:
> 
> 
> On Mon, Oct 15, 2018, at 16:32, Hugo Beauzée-Luyssen wrote:
> > This API is mostly meant to simplify thumbnailing management, by
> > exposing a simple picture type, that can be probed for its buffer or
> > saved to a file
> > ---
> >  include/vlc/libvlc_picture.h | 127 ++++++++++++++++++++++++++++++++
> >  lib/Makefile.am              |   5 +-
> >  lib/libvlc.sym               |   9 +++
> >  lib/picture.c                | 137 +++++++++++++++++++++++++++++++++++
> >  lib/picture_internal.h       |  46 ++++++++++++
> >  5 files changed, 323 insertions(+), 1 deletion(-)
> >  create mode 100644 include/vlc/libvlc_picture.h
> >  create mode 100644 lib/picture.c
> >  create mode 100644 lib/picture_internal.h
> > 
> > diff --git a/include/vlc/libvlc_picture.h b/include/vlc/libvlc_picture.h
> > new file mode 100644
> > index 0000000000..a421d30a92
> > --- /dev/null
> > +++ b/include/vlc/libvlc_picture.h
> > @@ -0,0 +1,127 @@
> > +/
> > *****************************************************************************
> > + * libvlc_picture.h:  libvlc external API
> > + 
> > *****************************************************************************
> > + * Copyright (C) 1998-2018 VLC authors and VideoLAN
> > + *
> > + * Authors: Hugo Beauzée-Luyssen <hugo at beauzee.fr>
> > + *
> > + * 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.
> > + 
> > *****************************************************************************/
> > +
> > +#ifndef VLC_LIBVLC_PICTURE_H
> > +#define VLC_LIBVLC_PICTURE_H 1
> > +
> > +# ifdef __cplusplus
> > +extern "C" {
> > +# endif
> > +
> > +typedef struct libvlc_picture_t libvlc_picture_t;
> > +
> > +typedef enum libvlc_picture_type_t
> > +{
> > +    libvlc_picture_Argb,
> > +    libvlc_picture_Png,
> > +    libvlc_picture_Jpg,
> > +} libvlc_picture_type_t;
> > +
> > +/**
> > + * Increment the reference count of this picture.
> > + *
> > + * \see libvlc_picture_release()
> > + * \param p_pic A picture object
> > + */
> > +LIBVLC_API void
> > +libvlc_picture_retain( libvlc_picture_t* p_pic );
> > +
> > +/**
> > + * Decrement the reference count of this picture.
> > + * When the reference count reaches 0, the picture will be released.
> > + * The picture must not be accessed after calling this function.
> > + *
> > + * \see libvlc_picture_retain
> > + * \param p_pic A picture object
> > + */
> > +LIBVLC_API void
> > +libvlc_picture_release( libvlc_picture_t* p_pic );
> > +
> > +/**
> > + * Saves this picture to a file. The image format is the same as the 
> > one
> > + * returned by \link libvlc_picture_type \endlink
> > + *
> > + * \param p_pic A picture object
> > + * \param psz_path The path to the generated file
> > + * \return 0 in case of success, -1 otherwise
> > + */
> > +LIBVLC_API int
> > +libvlc_picture_save( const libvlc_picture_t* p_pic, const char* 
> > psz_path );
> 
> As discussed with the player API, we prefer to never use const for 
> opaque pointers in C since it depends of the underlying implementation 
> (you'll have to remove the const if you use a lock in the futurue for 
> example).
> 

Agreed

> > +
> > +/**
> > + * Returns the image internal buffer, including potential padding.
> > + * The libvlc_picture_t owns the returned buffer, which must not be 
> > modified nor
> > + * freed.
> > + *
> > + * \param p_pic A picture object
> > + * \param p_size A pointer to a size_t that will hold the size of the 
> > buffer [required]
> > + * \return A pointer to the internal buffer.
> > + */
> > +LIBVLC_API const unsigned char*
> > +libvlc_picture_get_buffer( const libvlc_picture_t* p_pic, size_t 
> > *p_size );
> > +
> > +/**
> > + * Returns the picture type
> > + *
> > + * \param p_pic A picture object
> > + * \see libvlc_picture_type_t
> > + */
> > +LIBVLC_API libvlc_picture_type_t
> > +libvlc_picture_type( const libvlc_picture_t* p_pic );
> > +
> > +/**
> > + * Returns the image stride, ie. the number of bytes per line.
> > + * This can only be called on images of type libvlc_Argb
> > + *
> > + * \param p_pic A picture object
> > + */
> > +LIBVLC_API unsigned int
> > +libvlc_picture_get_stride( const libvlc_picture_t* p_pic );
> > +
> > +/**
> > + * Returns the width of the image in pixels
> > + *
> > + * \param p_pic A picture object
> > + */
> > +LIBVLC_API unsigned int
> > +libvlc_picture_get_width( const libvlc_picture_t* p_pic );
> > +
> > +/**
> > + * Returns the height of the image in pixels
> > + *
> > + * \param p_pic A picture object
> > + */
> > +LIBVLC_API unsigned int
> > +libvlc_picture_get_height( const libvlc_picture_t* p_pic );
> > +
> > +/**
> > + * Returns the time at which this picture was generated, in 
> > milliseconds
> > + * \param p_pic A picture object
> > + */
> > +LIBVLC_API libvlc_time_t
> > +libvlc_picture_get_time( const libvlc_picture_t* p_pic );
> > +
> > +# ifdef __cplusplus
> > +}
> > +# endif
> > +
> > +#endif // VLC_LIBVLC_PICTURE_H
> > diff --git a/lib/Makefile.am b/lib/Makefile.am
> > index b605cd6549..8dbbaf9d2a 100644
> > --- a/lib/Makefile.am
> > +++ b/lib/Makefile.am
> > @@ -19,6 +19,7 @@ pkginclude_HEADERS = \
> >  	../include/vlc/libvlc_media_list_player.h \
> >  	../include/vlc/libvlc_media_player.h \
> >  	../include/vlc/libvlc_renderer_discoverer.h \
> > +	../include/vlc/libvlc_picture.h \
> >  	../include/vlc/vlc.h
> >  
> >  nodist_pkginclude_HEADERS = ../include/vlc/libvlc_version.h
> > @@ -34,6 +35,7 @@ libvlc_la_SOURCES = \
> >  	media_internal.h \
> >  	media_list_internal.h \
> >  	media_player_internal.h \
> > +	picture_internal.h \
> >  	renderer_discoverer_internal.h \
> >  	core.c \
> >  	dialog.c \
> > @@ -50,7 +52,8 @@ libvlc_la_SOURCES = \
> >  	media_list_path.h \
> >  	media_list_player.c \
> >  	media_library.c \
> > -	media_discoverer.c
> > +	media_discoverer.c \
> > +	picture.c
> >  EXTRA_DIST = libvlc.pc.in libvlc.sym ../include/vlc/libvlc_version.h.in
> >  
> >  libvlc_la_LIBADD = ../src/libvlccore.la ../compat/libcompat.la $(LIBM)
> > diff --git a/lib/libvlc.sym b/lib/libvlc.sym
> > index 9a896ce7b2..67cd40b69c 100644
> > --- a/lib/libvlc.sym
> > +++ b/lib/libvlc.sym
> > @@ -262,3 +262,12 @@ libvlc_set_exit_handler
> >  libvlc_audio_filter_list_get
> >  libvlc_video_filter_list_get
> >  libvlc_module_description_list_release
> > +libvlc_picture_retain
> > +libvlc_picture_release
> > +libvlc_picture_save
> > +libvlc_picture_get_buffer
> > +libvlc_picture_type
> > +libvlc_picture_get_stride
> > +libvlc_picture_get_width
> > +libvlc_picture_get_height
> > +libvlc_picture_get_time
> > diff --git a/lib/picture.c b/lib/picture.c
> > new file mode 100644
> > index 0000000000..e8d7d4fd4a
> > --- /dev/null
> > +++ b/lib/picture.c
> > @@ -0,0 +1,137 @@
> > +/
> > *****************************************************************************
> > + * picture.c:  libvlc API picture management
> > + 
> > *****************************************************************************
> > + * Copyright (C) 1998-2018 VLC authors and VideoLAN
> > + *
> > + * Authors: Hugo Beauzée-Luyssen <hugo at beauzee.fr>
> > + *
> > + * 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/libvlc.h>
> > +#include <vlc/libvlc_picture.h>
> > +
> > +#include <vlc_atomic.h>
> > +#include <vlc_picture.h>
> > +#include <vlc_block.h>
> > +#include <vlc_fs.h>
> > +
> > +#include "picture_internal.h"
> > +
> > +struct libvlc_picture_t
> > +{
> > +    vlc_atomic_rc_t rc;
> > +    libvlc_picture_type_t i_type;
> > +    block_t* p_converted;
> > +    video_format_t fmt;
> > +    libvlc_time_t i_time;
> > +};
> > +
> > +libvlc_picture_t* libvlc_picture_new( vlc_object_t* p_obj, picture_t* 
> > p_input,
> 
> But here, I think you can put a const for picture_t ;)
> 

I wanted to, but given picture_Export takes a non-const, I assumed it wouldn't work

> > +                                      libvlc_picture_type_t i_type,
> > +                                      unsigned int i_width, unsigned 
> > int i_height )
> > +{
> > +    libvlc_picture_t *p_pic = malloc( sizeof( *p_pic ) );
> > +    if ( unlikely( p_pic == NULL ) )
> > +        return NULL;
> > +    vlc_atomic_rc_init( &p_pic->rc );
> > +    p_pic->i_type = i_type;
> > +    p_pic->i_time = MS_FROM_VLC_TICK( p_input->date );
> > +    vlc_fourcc_t format;
> > +    switch ( i_type )
> > +    {
> > +        case libvlc_picture_Argb:
> > +            format = VLC_CODEC_ARGB;
> > +            break;
> > +        case libvlc_picture_Jpg:
> > +            format = VLC_CODEC_JPEG;
> > +            break;
> > +        case libvlc_picture_Png:
> > +            format = VLC_CODEC_PNG;
> > +            break;
> default case ? assert/return NULL ?

Good point, I'll add an assert_unreachable here

> > +    }
> > +    if ( picture_Export( p_obj, &p_pic->p_converted, &p_pic->fmt,
> > +                         p_input, format, i_width, i_height ) != 
> > VLC_SUCCESS )
> > +    {
> > +        free( p_pic );
> > +        return NULL;
> > +    }
> > +
> > +    return p_pic;
> > +}
> > +
> > +void libvlc_picture_retain( libvlc_picture_t* p_pic )
> > +{
> > +    vlc_atomic_rc_inc( &p_pic->rc );
> > +}
> > +
> > +void libvlc_picture_release( libvlc_picture_t* p_pic )
> > +{
> > +    if ( vlc_atomic_rc_dec( &p_pic->rc ) == false )
> > +        return;
> > +    video_format_Clean( &p_pic->fmt );
> > +    if ( p_pic->p_converted )
> > +        block_Release( p_pic->p_converted );
> > +    free( p_pic );
> > +}
> > +
> > +int libvlc_picture_save( const libvlc_picture_t* p_pic, const char* 
> > psz_path )
> > +{
> > +    FILE* p_file = vlc_fopen( psz_path, "wb" );
> > +    if ( !p_file )
> > +        return -1;
> > +    size_t res = fwrite( p_pic->p_converted->p_buffer,
> > +                         p_pic->p_converted->i_buffer, 1, p_file );
> > +    fclose( p_file );
> > +    return res == 1 ? 0 : -1;
> > +}
> > +
> > +const unsigned char* libvlc_picture_get_buffer( const libvlc_picture_t* 
> > p_pic,
> > +                                                size_t *p_size )
> > +{
> > +    assert( p_size != NULL );
> > +    *p_size = p_pic->p_converted->i_buffer;
> > +    return p_pic->p_converted->p_buffer;
> > +}
> > +
> > +libvlc_picture_type_t libvlc_picture_type( const libvlc_picture_t* 
> > p_pic )
> > +{
> > +    return p_pic->i_type;
> > +}
> > +
> > +unsigned int libvlc_picture_get_stride( const libvlc_picture_t *p_pic )
> > +{
> > +    assert( p_pic->i_type == libvlc_picture_Argb );
> > +    return p_pic->fmt.i_width * p_pic->fmt.i_bits_per_pixel / 8;
> > +}
> > +
> > +unsigned int libvlc_picture_get_width( const libvlc_picture_t* p_pic )
> > +{
> > +    return p_pic->fmt.i_visible_width;
> > +}
> > +
> > +unsigned int libvlc_picture_get_height( const libvlc_picture_t* p_pic )
> > +{
> > +    return p_pic->fmt.i_visible_height;
> > +}
> > +
> > +libvlc_time_t libvlc_picture_get_time( const libvlc_picture_t* p_pic )
> > +{
> > +    return p_pic->i_time;
> > +}
> > diff --git a/lib/picture_internal.h b/lib/picture_internal.h
> > new file mode 100644
> > index 0000000000..3ad68b46f5
> > --- /dev/null
> > +++ b/lib/picture_internal.h
> > @@ -0,0 +1,46 @@
> > +/
> > *****************************************************************************
> > + * picture_internal.h:  libvlc API picture management
> > + 
> > *****************************************************************************
> > + * Copyright (C) 1998-2018 VLC authors and VideoLAN
> > + *
> > + * Authors: Hugo Beauzée-Luyssen <hugo at beauzee.fr>
> > + *
> > + * 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.
> > + 
> > *****************************************************************************/
> > +
> > +#ifndef PICTURE_INTERNAL_H
> > +#define PICTURE_INTERNAL_H
> > +
> > +#include <vlc_picture.h>
> > +
> > +
> > +/**
> > + * \brief libvlc_picture_new Wraps a libvlccore's picture_t to a 
> > libvlc_picture_t
> > + * \param p_obj A vlc object
> > + * \param p_input Input picture
> > + * \param i_type Desired converted picture type
> > + * \param i_width Converted picture width
> > + * \param i_height Converted picture height
> > + * \return An opaque libvlc_picture_t
> > + *
> > + * The picture refcount is left untouched by this function, but is 
> > converted to
> > + * the required format and stored as a block_t
> > + * The returned picture must be released through libvlc_picture_release
> > + */
> > +libvlc_picture_t* libvlc_picture_new( vlc_object_t* p_obj, picture_t* 
> > p_pic,
> > +                                      libvlc_picture_type_t i_format,
> > +                                      unsigned int i_width, unsigned 
> > int i_height );
> > +
> > +#endif // PICTURE_INTERNAL_H
> > -- 
> > 2.19.1
> > 
> > _______________________________________________
> > vlc-devel mailing list
> > To unsubscribe or modify your subscription options:
> > https://mailman.videolan.org/listinfo/vlc-devel
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel


-- 
  Hugo Beauzée-Luyssen
  hugo at beauzee.fr


More information about the vlc-devel mailing list