<commit_before>/*****************************************************************************
 * cmml.c : CMML annotations/metadata decoder
 *****************************************************************************
 * Copyright (C) 2003-2004 Commonwealth Scientific and Industrial Research
 *                         Organisation (CSIRO) Australia
 * Copyright (C) 2004 the VideoLAN team
 *
 * $Id$
 *
 * Author: <NAME> <<EMAIL>>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 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 General Public License for more details.
 *
 * You should have received a copy of the GNU 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
 *****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_input.h>
#include <vlc_codec.h>
#include <vlc_osd.h>
#include <vlc_charset.h>
#include <vlc_interface.h>
#include "xtag.h"

#undef  CMML_DEBUG

/*****************************************************************************
 * decoder_sys_t : decoder descriptor
 *****************************************************************************/
struct decoder_sys_t
{
    intf_thread_t *     p_intf;
};

/*****************************************************************************
 * Local prototypes
 *****************************************************************************/
static int           OpenDecoder   ( vlc_object_t * );
static void          CloseDecoder  ( vlc_object_t * );

static subpicture_t *DecodeBlock   ( decoder_t *, block_t ** );

static void          ParseText     ( decoder_t *, block_t * );

/*****************************************************************************
 * Exported prototypes
 *****************************************************************************/
int  OpenIntf  ( vlc_object_t * );
void CloseIntf ( vlc_object_t * );

/*****************************************************************************
 * Module descriptor.
 *****************************************************************************/
vlc_module_begin ()
    set_description( N_("CMML annotations decoder") )
    set_capability( "decoder", 50 )
    set_callbacks( OpenDecoder, CloseDecoder )
    add_shortcut( "cmml" )

    add_submodule ()
        set_capability( "interface", 0 )
        set_callbacks( OpenIntf, CloseIntf )
vlc_module_end ()

/*****************************************************************************
 * OpenDecoder: probe the decoder and return score
 *****************************************************************************
 * Tries to launch a decoder and return score so that the interface is able
 * to chose.
 *****************************************************************************/
static int OpenDecoder( vlc_object_t *p_this )
{
    decoder_t *p_dec = (decoder_t*)p_this;
    input_thread_t * p_input;
    decoder_sys_t *p_sys;
    vlc_value_t val;

    if( p_dec->fmt_in.i_codec != VLC_FOURCC('c','m','m','l') )
    {
        return VLC_EGENERIC;
    }

    p_dec->pf_decode_sub = DecodeBlock;

#ifdef CMML_DEBUG
    msg_Dbg( p_dec, "i am at %p", p_dec );
#endif

    /* Allocate the memory needed to store the decoder's structure */
    if( ( p_dec->p_sys = p_sys =
          (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
    {
        return VLC_EGENERIC;
    }

    /* Let other interested modules know that we're a CMML decoder
     * We have to set this variable on the input thread, because there's
     * typically more than one decoder running so we can't find the CMML
     * decoder succesfully with vlc_object_find.  (Any hints on how to achieve
     * this would be rather appreciated ;) */
    p_input = vlc_object_find( p_dec, VLC_OBJECT_INPUT, FIND_ANYWHERE );
#ifdef CMML_DEBUG
    msg_Dbg( p_dec, "p_input is at %p", p_input );
#endif
    val.p_address = p_dec;
    var_Create( p_input, "has-cmml-decoder",
                VLC_VAR_ADDRESS|VLC_VAR_DOINHERIT );
    if( var_Set( p_input, "has-cmml-decoder", val ) != VLC_SUCCESS )
    {
        msg_Dbg( p_dec, "var_Set of has-cmml-decoder failed" );
    }
    vlc_object_release( p_input );

    /* initialise the CMML responder interface */
    p_sys->p_intf = intf_Create( p_dec, "cmml" );
    intf_RunThread( p_sys->p_intf );

    return VLC_SUCCESS;
}

/****************************************************************************
 * DecodeBlock: the whole thing
 ****************************************************************************
 * This function must be fed with complete subtitles units.
 ****************************************************************************/
static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
    subpicture_t *p_spu;

    if( !pp_block || *pp_block == NULL )
    {
        return NULL;
    }

    ParseText( p_dec, *pp_block );

    block_Release( *pp_block );
    *pp_block = NULL;

    /* allocate an empty subpicture to return.  the actual subpicture
     * displaying is done in the DisplayAnchor function in intf.c (called from
     * DisplayPendingAnchor, which in turn is called from the main RunIntf
     * loop). */
    p_spu = decoder_NewSubpicture( p_dec );
    if( !p_spu )
    {
        msg_Dbg( p_dec, "couldn't allocate new subpicture" );
        return NULL;
    }

    return p_spu;
}

/*****************************************************************************
 * CloseDecoder: clean up the decoder
 *****************************************************************************/
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;
    intf_thread_t *p_intf;

    /* Destroy the interface object/thread */
    p_intf = vlc_object_find( p_dec, VLC_OBJECT_INTF, FIND_CHILD );
    if( p_intf != NULL )
    {
#ifdef CMML_DEBUG
        msg_Dbg( p_dec, "CMML decoder is freeing interface thread" );
#endif
        intf_StopThread( p_intf );
        vlc_object_detach( p_intf );
        vlc_object_release( p_intf );
        vlc_object_release( p_intf );
    }

    p_sys->p_intf = NULL;

    free( p_sys );
}

/*****************************************************************************
 * ParseText: parse an text subtitle packet and send it to the video output<commit_msg>Remove silly use of vlc_object_find<commit_after>/*****************************************************************************
 * cmml.c : CMML annotations/metadata decoder
 *****************************************************************************
 * Copyright (C) 2003-2004 Commonwealth Scientific and Industrial Research
 *                         Organisation (CSIRO) Australia
 * Copyright (C) 2004 the VideoLAN team
 *
 * $Id$
 *
 * Author: <NAME> <<EMAIL>>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 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 General Public License for more details.
 *
 * You should have received a copy of the GNU 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
 *****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_input.h>
#include <vlc_codec.h>
#include <vlc_osd.h>
#include <vlc_charset.h>
#include <vlc_interface.h>
#include "xtag.h"

#undef  CMML_DEBUG

/*****************************************************************************
 * decoder_sys_t : decoder descriptor
 *****************************************************************************/
struct decoder_sys_t
{
    intf_thread_t *     p_intf;
};

/*****************************************************************************
 * Local prototypes
 *****************************************************************************/
static int           OpenDecoder   ( vlc_object_t * );
static void          CloseDecoder  ( vlc_object_t * );

static subpicture_t *DecodeBlock   ( decoder_t *, block_t ** );

static void          ParseText     ( decoder_t *, block_t * );

/*****************************************************************************
 * Exported prototypes
 *****************************************************************************/
int  OpenIntf  ( vlc_object_t * );
void CloseIntf ( vlc_object_t * );

/*****************************************************************************
 * Module descriptor.
 *****************************************************************************/
vlc_module_begin ()
    set_description( N_("CMML annotations decoder") )
    set_capability( "decoder", 50 )
    set_callbacks( OpenDecoder, CloseDecoder )
    add_shortcut( "cmml" )

    add_submodule ()
        set_capability( "interface", 0 )
        set_callbacks( OpenIntf, CloseIntf )
vlc_module_end ()

/*****************************************************************************
 * OpenDecoder: probe the decoder and return score
 *****************************************************************************
 * Tries to launch a decoder and return score so that the interface is able
 * to chose.
 *****************************************************************************/
static int OpenDecoder( vlc_object_t *p_this )
{
    decoder_t *p_dec = (decoder_t*)p_this;
    input_thread_t * p_input;
    decoder_sys_t *p_sys;
    vlc_value_t val;

    if( p_dec->fmt_in.i_codec != VLC_FOURCC('c','m','m','l') )
    {
        return VLC_EGENERIC;
    }

    p_dec->pf_decode_sub = DecodeBlock;

#ifdef CMML_DEBUG
    msg_Dbg( p_dec, "i am at %p", p_dec );
#endif

    /* Allocate the memory needed to store the decoder's structure */
    if( ( p_dec->p_sys = p_sys =
          (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
    {
        return VLC_EGENERIC;
    }

    /* Let other interested modules know that we're a CMML decoder
     * We have to set this variable on the input thread, because there's
     * typically more than one decoder running so we can't find the CMML
     * decoder succesfully with vlc_object_find.  (Any hints on how to achieve
     * this would be rather appreciated ;) */
    p_input = vlc_object_find( p_dec, VLC_OBJECT_INPUT, FIND_ANYWHERE );
#ifdef CMML_DEBUG
    msg_Dbg( p_dec, "p_input is at %p", p_input );
#endif
    val.p_address = p_dec;
    var_Create( p_input, "has-cmml-decoder",
                VLC_VAR_ADDRESS|VLC_VAR_DOINHERIT );
    if( var_Set( p_input, "has-cmml-decoder", val ) != VLC_SUCCESS )
    {
        msg_Dbg( p_dec, "var_Set of has-cmml-decoder failed" );
    }
    vlc_object_release( p_input );

    /* initialise the CMML responder interface */
    p_sys->p_intf = intf_Create( p_dec, "cmml" );
    intf_RunThread( p_sys->p_intf );

    return VLC_SUCCESS;
}

/****************************************************************************
 * DecodeBlock: the whole thing
 ****************************************************************************
 * This function must be fed with complete subtitles units.
 ****************************************************************************/
static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
    subpicture_t *p_spu;

    if( !pp_block || *pp_block == NULL )
    {
        return NULL;
    }

    ParseText( p_dec, *pp_block );

    block_Release( *pp_block );
    *pp_block = NULL;

    /* allocate an empty subpicture to return.  the actual subpicture
     * displaying is done in the DisplayAnchor function in intf.c (called from
     * DisplayPendingAnchor, which in turn is called from the main RunIntf
     * loop). */
    p_spu = decoder_NewSubpicture( p_dec );
    if( !p_spu )
    {
        msg_Dbg( p_dec, "couldn't allocate new subpicture" );
        return NULL;
    }

    return p_spu;
}

/*****************************************************************************
 * CloseDecoder: clean up the decoder
 *****************************************************************************/
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;
    intf_thread_t *p_intf;

    /* Destroy the interface object/thread */
    if( p_sys->p_intf != NULL )
    {
#ifdef CMML_DEBUG
        msg_Dbg( p_dec, "CMML decoder is freeing interface thread" );
#endif
        intf_StopThread( p_intf );
        vlc_object_detach( p_intf );
        vlc_object_release( p_intf );
    }

    free( p_sys );
}

/*****************************************************************************
 * ParseText: parse an text subtitle packet and send it to the video output
{'fraction_non_alphanumeric': 0.3150813066628292, 'fraction_numerical': 0.0038854511440495035, 'mean_word_length': 4.335508637236084, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5598023', 'n_tokens_mistral': 3976, 'n_tokens_neox': 3603, 'n_words': 1068}