[vlc-devel] [PATCH 2/3] codec: add SMPTE-436m decoder

Hugo Beauzée-Luyssen hugo at beauzee.fr
Tue Mar 6 11:58:48 CET 2018


On Tue, Mar 6, 2018, at 11:39 AM, Francois Cartegnie wrote:
> ---
>  include/vlc_fourcc.h      |   2 +
>  modules/codec/Makefile.am |   3 +
>  modules/codec/s436m.c     | 210 ++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 215 insertions(+)
>  create mode 100644 modules/codec/s436m.c
> 
> diff --git a/include/vlc_fourcc.h b/include/vlc_fourcc.h
> index 76d0e5a3aa..316633c6d7 100644
> --- a/include/vlc_fourcc.h
> +++ b/include/vlc_fourcc.h
> @@ -563,6 +563,8 @@
>  /* XYZ colorspace 12 bits packed in 16 bits, organisation |XXX0|YYY0|ZZZ0| */
>  #define VLC_CODEC_XYZ12     VLC_FOURCC('X','Y','1','2')
>  
> +/* Data, Ancillary */
> +#define VLC_CODEC_SMPTE_436M    VLC_FOURCC('s','4','3','6')
>  
>  /* Special endian dependent values
>   * The suffic N means Native
> diff --git a/modules/codec/Makefile.am b/modules/codec/Makefile.am
> index 99f9bfa949..4fe10f1103 100644
> --- a/modules/codec/Makefile.am
> +++ b/modules/codec/Makefile.am
> @@ -500,6 +500,9 @@ if HAVE_ANDROID
>  codec_LTLIBRARIES += libmediacodec_plugin.la
>  endif
>  
> +### DATA decoders ###
> +libs436m_plugin_la_SOURCES = codec/s436m.c
> +codec_LTLIBRARIES += libs436m_plugin.la
>  
>  ### X26x encoders ###
>  
> diff --git a/modules/codec/s436m.c b/modules/codec/s436m.c
> new file mode 100644
> index 0000000000..2d7e0837c6
> --- /dev/null
> +++ b/modules/codec/s436m.c
> @@ -0,0 +1,210 @@
> +/
> *****************************************************************************
> + * s436m.c : SMPTE-436m data decoder
> + 
> *****************************************************************************
> + * Copyright © 2017 VideoLabs, VLC authors and VideoLAN
> + *
> + * 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.
> + 
> *****************************************************************************/
> +
> +/
> *****************************************************************************
> + * Preamble
> + 
> *****************************************************************************/
> +

Seems unrequired for now but I'd still include config.h

> +#include <assert.h>
> +
> +#include <vlc_common.h>
> +#include <vlc_plugin.h>
> +#include <vlc_codec.h>
> +
> +#include "cc.h"
> +
> +/
> *****************************************************************************
> + * Module descriptor.
> + 
> *****************************************************************************/
> +static int  Open ( vlc_object_t * );
> +static void Close( vlc_object_t * );
> +
> +vlc_module_begin ()
> +    set_shortname( "S436m" )
> +    set_description( "S436m" )
> +    set_capability( "data decoder", 50 )
> +    set_category( CAT_INPUT )
> +        set_subcategory( SUBCAT_INPUT_SCODEC )
> +    set_callbacks( Open, Close )

Why not using NULL as close callback?

> +
> +vlc_module_end ()
> +
> +/
> *****************************************************************************
> + * Local
> + 
> *****************************************************************************/
> +static void ParseCC( decoder_t *p_dec, const uint8_t *p_data, size_t 
> i_data,
> +                     uint8_t i_count, mtime_t i_dts,  mtime_t i_pts )
> +{
> +    cc_data_t cc;
> +    cc_Init( &cc );
> +    while( i_count-- > 0 && i_data > 2 )
> +    {
> +        cc_AppendData( &cc, p_data[0], &p_data[1] );
> +        p_data += 3;
> +        i_data -= 3;
> +    }
> +
> +    if( cc.i_data > 0 )
> +    {
> +        block_t *p_block = block_Alloc( cc.i_data );
> +        if( p_block )
> +        {
> +            p_block->i_dts = i_dts;
> +            p_block->i_pts = i_pts;
> +            memcpy( p_block->p_buffer, cc.p_data, cc.i_data );
> +            decoder_cc_desc_t desc;
> +            desc.i_608_channels = cc.i_608channels;
> +            desc.i_708_channels = cc.i_708channels;
> +            desc.i_reorder_depth = -1;
> +            decoder_QueueCc( p_dec, p_block, &desc );
> +        }
> +        cc_Flush( &cc );

This seems unneeded

> +    }
> +}
> +
> +static void ParseVANC( decoder_t *p_dec, const uint8_t *p_data, size_t 
> i_data,
> +                       mtime_t i_dts,  mtime_t i_pts )
> +{
> +    if( i_data < 9 )
> +        return;
> +
> +    const uint8_t i_did = p_data[0];
> +    const uint8_t i_sdid = p_data[1];
> +    const uint8_t i_datacount = p_data[2];
> +
> +    if( i_datacount > i_data )
> +        return;
> +
> +    if( i_did == 0x61 ) /* EIA 608/708 */
> +    {
> +        if( i_sdid == 0x01 || /* EIA 708 */
> +            i_sdid == 0x02 )  /* EIA 608 */
> +        {
> +            if( i_data < 12 )
> +                return;
> +
> +            ParseCC( p_dec, &p_data[12], i_datacount - 12, p_data[11] & 
> 0x1F, i_dts, i_pts );
> +        }
> +    }
> +}
> +
> +static void ParseSMPTE436m( decoder_t *p_dec, const uint8_t *p_data, 
> size_t i_data,
> +                            mtime_t i_dts,  mtime_t i_pts )
> +{
> +    if( i_data < 16 )
> +        return;
> +
> +    uint16_t i_pkt = GetWBE(p_data);
> +    p_data += 2; i_data -= 2;
> +
> +    while( i_pkt-- > 0 )
> +    {
> +        if( i_data < 14 )
> +            break;
> +
> +        const uint16_t i_samples = GetWBE(&p_data[4]);
> +        const uint32_t i_payload = GetDWBE(&p_data[6]); /* MXF array 
> data */
> +        assert(GetDWBE(&p_data[10]) == 1);
> +
> +        if( i_payload > i_data - 14 )
> +            break;
> +
> +        const uint8_t *p_vanc = NULL;
> +        uint8_t *p_vanc_alloc = NULL;
> +        size_t i_vanc = 0;
> +
> +        switch ( p_data[3] )
> +        {
> +            case 4: case 5: case 6:
> +                p_vanc = &p_data[14];
> +                if( i_samples <= i_payload )
> +                    i_vanc = i_samples;
> +                break;
> +            case 7: case 8: case 9:
> +                if( i_samples <= i_payload / 4 )
> +                {
> +                    p_vanc = p_vanc_alloc = malloc( i_payload * 3 / 
> 4 );
> +                    if( p_vanc_alloc )
> +                    {
> +                        /* Do 10bits VANC -> 8 bits VANC conversion for 
> parsing */
> +                        for( size_t i=0; i + 3 < i_payload; i+=4 )
> +                        {
> +                            /* Strip the 2 higher bits from 10 bits 
> encoding */
> +                            p_vanc_alloc[i_vanc + 0] = p_data[i + 0] << 
> 2 |
> +                                                       p_data[i + 1] >> 
> 6;
> +                            p_vanc_alloc[i_vanc + 1] = p_data[i + 1] << 
> 4 |
> +                                                       p_data[i + 2] >> 
> 4;
> +                            p_vanc_alloc[i_vanc + 2] = p_data[i + 2] << 
> 6 |
> +                                                       p_data[i + 3] >> 
> 2;
> +                            i_vanc += 3;
> +                        }
> +                        assert(i_vanc <= i_samples);
> +                    }
> +                }
> +                break;
> +            default:
> +                /* Unsupported coding */
> +                break;
> +        }
> +
> +        if( p_vanc )
> +        {
> +            ParseVANC( p_dec, p_vanc, i_vanc, i_dts, i_pts );
> +            free( p_vanc_alloc );
> +        }
> +
> +        p_data += 14 + i_payload;
> +        i_data -= 14 + i_payload;
> +    }
> +}
> +
> +static int Decode( decoder_t *p_dec, block_t *p_block )
> +{
> +    if( p_block )
> +    {
> +        ParseSMPTE436m( p_dec, p_block->p_buffer, p_block->i_buffer,
> +                        p_block->i_dts, p_block->i_pts );
> +        block_Release( p_block );
> +    }
> +
> +    return VLCDEC_SUCCESS;
> +}
> +
> +/
> *****************************************************************************
> + * Open:
> + 
> *****************************************************************************/
> +static int Open( vlc_object_t *p_this )
> +{
> +    decoder_t     *p_dec = (decoder_t*)p_this;
> +
> +    if( p_dec->fmt_in.i_cat != DATA_ES ||
> +        p_dec->fmt_in.i_codec != VLC_CODEC_SMPTE_436M )
> +        return VLC_EGENERIC;
> +
> +    p_dec->pf_decode = Decode;
> +    p_dec->pf_flush  = NULL;
> +
> +    return VLC_SUCCESS;
> +}
> +
> +static void Close( vlc_object_t *p_this )
> +{
> +    VLC_UNUSED(p_this);
> +}
> -- 
> 2.14.3
> 
> _______________________________________________
> 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