/*****************************************************************************
* 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: cvd.c,v 1.14 2004/01/25 18:20:12 bigben Exp $
*
* Authors: Rocky Bernstein
* based on code from:
#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.
*****************************************************************************/
set_callbacks( DecoderOpen, VCDSubClose );
add_integer ( MODULE_STRING "-debug", 0, NULL,
- N_("set debug mask for additional debugging."),
+ N_("Set debug mask for additional debugging."),
N_(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", 9, NULL,
+ DURATION_SCALE_TEXT, DURATION_SCALE_LONGTEXT,
+ VLC_TRUE );
+
add_submodule();
set_description( _("Chaoji VCD subtitle packetizer") );
set_capability( "packetizer", 50 );
/* 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 )
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 )
{
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",
+ "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] )
+ if( config_GetInt( p_dec, "spu-channel" ) != p_buffer[0] )
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;
- }
-
- p_buffer += 2;
-
- 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++;
- }
-
- p_sys->i_image = GETINT16(p_buffer);
-
- 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 );
- }
+ /* 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 ( i_packet != i_expected_packet ) {
- msg_Warn( p_dec, "expecting subtitle image packet %u but found %u",
- i_expected_packet, i_packet);
+ 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;
}
- p_sys->i_packet = i_packet;
-
- if ( p_sys->i_packet == 0 ) {
+ 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;
}