X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcodec%2Fogt%2Fcvd.c;h=46abe55ca2552dfe8e2f5b8cf87bf177f53927c7;hb=28ed0fc96153391a47fa4b480f716f0de1fbacae;hp=e48d8131f9fa40325dddfaece5726f5b68847987;hpb=f5d0873721cea2b31d473e90f77abbbcdec99bb7;p=vlc diff --git a/modules/codec/ogt/cvd.c b/modules/codec/ogt/cvd.c index e48d8131f9..46abe55ca2 100644 --- a/modules/codec/ogt/cvd.c +++ b/modules/codec/ogt/cvd.c @@ -1,8 +1,8 @@ /***************************************************************************** * cvd.c : CVD Subtitle decoder thread ***************************************************************************** - * Copyright (C) 2003 VideoLAN - * $Id: cvd.c,v 1.1 2003/12/28 04:51:52 rocky Exp $ + * Copyright (C) 2003, 2004 VideoLAN + * $Id$ * * Authors: Rocky Bernstein * based on code from: @@ -36,29 +36,33 @@ #include "cvd.h" #include "common.h" -#define DEBUG_LONGTEXT N_( \ - "This integer when viewed in binary is a debugging mask\n" \ - "external call 1\n" \ - "all calls 2\n" \ - "packet assembly info 4\n" \ - "image bitmaps 8\n" \ - "image transformations 16\n" \ - "misc info 32\n" ) - /***************************************************************************** * Module descriptor. *****************************************************************************/ -static int DecoderOpen ( vlc_object_t * ); +static int VCDSubOpen ( vlc_object_t * ); static int PacketizerOpen( vlc_object_t * ); vlc_module_begin(); set_description( _("CVD subtitle decoder") ); set_capability( "decoder", 50 ); - set_callbacks( DecoderOpen, VCDSubClose ); + set_callbacks( VCDSubOpen, VCDSubClose ); add_integer ( MODULE_STRING "-debug", 0, NULL, - N_("set debug mask for additional debugging."), - N_(DEBUG_LONGTEXT), VLC_TRUE ); + DEBUG_TEXT, DEBUG_LONGTEXT, VLC_TRUE ); + + add_integer ( MODULE_STRING "-horizontal-correct", 0, NULL, + HORIZONTAL_CORRECT, HORIZONTAL_CORRECT_LONGTEXT, VLC_FALSE ); + + add_integer ( MODULE_STRING "-vertical-correct", 0, NULL, + VERTICAL_CORRECT, VERTICAL_CORRECT_LONGTEXT, VLC_FALSE ); + + add_string( MODULE_STRING "-aspect-ratio", "", NULL, + SUB_ASPECT_RATIO_TEXT, SUB_ASPECT_RATIO_LONGTEXT, + VLC_TRUE ); + + add_integer( MODULE_STRING "-duration-scaling", 3, NULL, + DURATION_SCALE_TEXT, DURATION_SCALE_LONGTEXT, + VLC_TRUE ); add_submodule(); set_description( _("Chaoji VCD subtitle packetizer") ); @@ -71,18 +75,17 @@ vlc_module_end(); *****************************************************************************/ static block_t *Reassemble( decoder_t *, block_t ** ); -static void Decode ( decoder_t *, block_t ** ); +static subpicture_t *Decode( decoder_t *, block_t ** ); static block_t *Packetize( decoder_t *, block_t ** ); - /***************************************************************************** - * DecoderOpen + * VCDSubOpen ***************************************************************************** * Tries to launch a decoder and return score so that the interface is able * to chose. *****************************************************************************/ static int -DecoderOpen( vlc_object_t *p_this ) +VCDSubOpen( vlc_object_t *p_this ) { decoder_t *p_dec = (decoder_t*)p_this; decoder_sys_t *p_sys; @@ -124,7 +127,7 @@ static int PacketizerOpen( vlc_object_t *p_this ) { decoder_t *p_dec = (decoder_t*)p_this; - if( DecoderOpen( p_this ) ) + if( VCDSubOpen( p_this ) ) { return VLC_EGENERIC; } @@ -136,11 +139,12 @@ static int PacketizerOpen( vlc_object_t *p_this ) /***************************************************************************** * Decode: *****************************************************************************/ -static void +static subpicture_t * Decode ( decoder_t *p_dec, block_t **pp_block ) { decoder_sys_t *p_sys = p_dec->p_sys; block_t *p_spu = Reassemble( p_dec, pp_block ); + vout_thread_t *p_last_vout = p_dec->p_sys->p_vout; dbg_print( (DECODE_DBG_CALL) , ""); @@ -152,6 +156,12 @@ Decode ( decoder_t *p_dec, block_t **pp_block ) if( ( p_sys->p_vout = VCDSubFindVout( p_dec ) ) ) { + if( p_last_vout != p_sys->p_vout ) + { + spu_Control( p_sys->p_vout->p_spu, SPU_CHANNEL_REGISTER, + &p_sys->i_subpic_channel ); + } + /* Parse and decode */ E_(ParsePacket)( p_dec ); @@ -161,6 +171,7 @@ Decode ( decoder_t *p_dec, block_t **pp_block ) VCDSubInitSubtitleBlock ( p_sys ); } + return NULL; } /***************************************************************************** @@ -186,30 +197,20 @@ Packetize( decoder_t *p_dec, block_t **pp_block ) /* following functions are local */ -#define SPU_HEADER_LEN 5 +#define SPU_HEADER_LEN 1 /***************************************************************************** Reassemble: - The data for single screen subtitle may come in one of many - non-contiguous packets of a stream. This routine is called when the - next packet in the stream comes in. The job of this routine is to - parse the header, if this is the beginning, and combine the packets - into one complete subtitle unit. + Data for single screen subtitle may come in several non-contiguous + packets of a stream. This routine is called when the next packet in + the stream comes in. The job of this routine is to parse the header, + if this is the beginning, and combine the packets into one complete + subtitle unit. If everything is complete, we will return a block. Otherwise return NULL. - - The format of the beginning of the subtitle packet that is used here. - - size description - ------------------------------------------- - byte subtitle channel (0..7) in bits 0-3 - byte subtitle packet number of this subtitle image 0-N, - if the subtitle packet is complete, the top bit of the byte is 1. - uint16 subtitle image number - *****************************************************************************/ static block_t * Reassemble( decoder_t *p_dec, block_t **pp_block ) @@ -217,8 +218,6 @@ Reassemble( decoder_t *p_dec, block_t **pp_block ) decoder_sys_t *p_sys = p_dec->p_sys; block_t *p_block; uint8_t *p_buffer; - uint16_t i_expected_image; - uint8_t i_packet, i_expected_packet; if( pp_block == NULL || *pp_block == NULL ) { @@ -237,71 +236,72 @@ Reassemble( decoder_t *p_dec, block_t **pp_block ) p_buffer = p_block->p_buffer; - dbg_print( (DECODE_DBG_CALL|DECODE_DBG_PACKET), - "header: 0x%02x 0x%02x 0x%02x 0x%02x, size: %i", - p_buffer[1], p_buffer[2], p_buffer[3], p_buffer[4], - p_block->i_buffer); + dbg_print( (DECODE_DBG_CALL|DECODE_DBG_PACKET), + "header: 0x%02x 0x%02x 0x%02x 0x%02x, 0x%02x, 0x%02x, size: %i", + p_buffer[1], p_buffer[2], p_buffer[3], p_buffer[4], + p_buffer[5], p_buffer[6], + p_block->i_buffer); - if( config_GetInt( p_dec, "spu-channel" ) != p_buffer[1] ) - return NULL; - if ( p_sys->state == SUBTITLE_BLOCK_EMPTY ) { - i_expected_image = p_sys->i_image+1; - i_expected_packet = 0; - } else { - i_expected_image = p_sys->i_image; - i_expected_packet = p_sys->i_packet+1; - } + /* Attach to our input thread and see if subtitle is selected. */ + { + vlc_object_t * p_input; + vlc_value_t val; - p_buffer += 2; + p_input = vlc_object_find( p_dec, VLC_OBJECT_INPUT, FIND_PARENT ); - if ( *p_buffer & 0x80 ) { - p_sys->state = SUBTITLE_BLOCK_COMPLETE; - i_packet = ( *p_buffer++ & 0x7F ); - } else { - p_sys->state = SUBTITLE_BLOCK_PARTIAL; - i_packet = *p_buffer++; - } + if( !p_input ) return NULL; - p_sys->i_image = GETINT16(p_buffer); + if( var_Get( p_input, "spu-channel", &val ) ) + { + vlc_object_release( p_input ); + return NULL; + } - if ( p_sys->i_image != i_expected_image ) { - msg_Warn( p_dec, "expecting subtitle image %u but found %u", - i_expected_image, p_sys->i_image ); - } + vlc_object_release( p_input ); + + /* Number could be 0bd, 1bd, 2bd, 3bd for 0..3. If so + reduce it to 0..3. + */ + if ( (val.i_int & 0xff) == 0xbd ) val.i_int >>= 8; - if ( i_packet != i_expected_packet ) { - msg_Warn( p_dec, "expecting subtitle image packet %u but found %u", - i_expected_packet, i_packet); + if( val.i_int == -1 || val.i_int != p_buffer[0] ) + return NULL; } - p_sys->i_packet = i_packet; - if ( p_sys->i_packet == 0 ) { + /* From the scant data on the format, there is only only way known + to detect the first packet in a subtitle. The first packet + seems to have a valid PTS while later packets for the same + image don't. */ + + if ( p_sys->state == SUBTITLE_BLOCK_EMPTY && p_block->i_pts == 0 ) { + msg_Warn( p_dec, + "first packet expected but no PTS present -- skipped\n"); + return NULL; + } + + if ( p_sys->subtitle_data_pos == 0 ) { /* First packet in the subtitle block */ E_(ParseHeader)( p_dec, p_buffer, p_block ); VCDSubInitSubtitleData(p_sys); } /* FIXME - remove append_data and use chainappend */ - VCDSubAppendData( p_dec, p_buffer, p_block->i_buffer - 5 ); + VCDSubAppendData( p_dec, p_buffer + SPU_HEADER_LEN, + p_block->i_buffer - SPU_HEADER_LEN ); block_ChainAppend( &p_sys->p_block, p_block ); p_sys->i_spu += p_block->i_buffer - SPU_HEADER_LEN; - if (p_sys->state == SUBTITLE_BLOCK_COMPLETE) - { - if( p_sys->i_spu != p_sys->i_spu_size ) - { - msg_Warn( p_dec, "SPU packets size=%d should be %d", - p_sys->i_spu, p_sys->i_spu_size ); - } - - dbg_print( (DECODE_DBG_PACKET), - "subtitle packet complete, size=%d", p_sys->i_spu ); - + if ( p_sys->subtitle_data_pos == p_sys->i_spu_size ) { + E_(ParseMetaInfo)( p_dec ); return p_sys->p_block; + } else { + /* Not last block in subtitle, so wait for another. */ + p_sys->state = SUBTITLE_BLOCK_PARTIAL; } + return NULL; }