Commit a57bfee7 authored by Sam Hocevar's avatar Sam Hocevar

. le d�codeur de sous-titres s'appelle maintenant spu_decoder

 . auto spawn du spu_decoder (pour le moment �a chie)
parent b25b4229
...@@ -213,7 +213,7 @@ ac3_decoder_obj = ac3_decoder/ac3_decoder.o \ ...@@ -213,7 +213,7 @@ ac3_decoder_obj = ac3_decoder/ac3_decoder.o \
audio_decoder_obj = audio_decoder/audio_decoder.o \ audio_decoder_obj = audio_decoder/audio_decoder.o \
audio_decoder/audio_math.o audio_decoder/audio_math.o
subtitle_decoder_obj = subtitle_decoder/subtitle_decoder.o spu_decoder_obj = spu_decoder/spu_decoder.o
#??generic_decoder_obj = generic_decoder/generic_decoder.o #??generic_decoder_obj = generic_decoder/generic_decoder.o
# remeber to add it to OBJ # remeber to add it to OBJ
...@@ -253,7 +253,7 @@ C_OBJ = $(interface_obj) \ ...@@ -253,7 +253,7 @@ C_OBJ = $(interface_obj) \
$(video_output_obj) \ $(video_output_obj) \
$(ac3_decoder_obj) \ $(ac3_decoder_obj) \
$(audio_decoder_obj) \ $(audio_decoder_obj) \
$(subtitle_decoder_obj) \ $(spu_decoder_obj) \
$(generic_decoder_obj) \ $(generic_decoder_obj) \
$(video_parser_obj) \ $(video_parser_obj) \
$(video_decoder_obj) \ $(video_decoder_obj) \
......
...@@ -148,6 +148,7 @@ typedef struct es_descriptor_t ...@@ -148,6 +148,7 @@ typedef struct es_descriptor_t
#define MPEG1_AUDIO_ES 0x03 #define MPEG1_AUDIO_ES 0x03
#define MPEG2_AUDIO_ES 0x04 #define MPEG2_AUDIO_ES 0x04
#define AC3_AUDIO_ES 0x81 #define AC3_AUDIO_ES 0x81
#define DVD_SPU_ES 0x82 /* 0x82 might violate the norm */
/****************************************************************************** /******************************************************************************
* program_descriptor_t * program_descriptor_t
......
/****************************************************************************** /******************************************************************************
* subtitle_decoder.h : subtitle decoder thread interface * spu_decoder.h : sub picture unit decoder thread interface
* (c)1999 VideoLAN * (c)1999 VideoLAN
******************************************************************************/ ******************************************************************************/
/****************************************************************************** /******************************************************************************
* subtdec_thread_t : subtitle decoder thread descriptor * spudec_thread_t : sub picture unit decoder thread descriptor
******************************************************************************/ ******************************************************************************/
typedef struct subtdec_thread_s typedef struct spudec_thread_s
{ {
/* /*
* Thread properties and locks * Thread properties and locks
...@@ -30,10 +30,10 @@ typedef struct subtdec_thread_s ...@@ -30,10 +30,10 @@ typedef struct subtdec_thread_s
unsigned int total_bits_read; unsigned int total_bits_read;
/* ... */ /* ... */
} subtdec_thread_t; } spudec_thread_t;
/****************************************************************************** /******************************************************************************
* Prototypes * Prototypes
******************************************************************************/ ******************************************************************************/
subtdec_thread_t * subtdec_CreateThread( input_thread_t * p_input ); spudec_thread_t * spudec_CreateThread( input_thread_t * p_input );
void subtdec_DestroyThread( subtdec_thread_t * p_subtdec ); void spudec_DestroyThread( spudec_thread_t * p_spudec );
...@@ -87,35 +87,35 @@ typedef struct picture_s ...@@ -87,35 +87,35 @@ typedef struct picture_s
#define AR_221_1_PICTURE 4 /* 2.21:1 picture (movie) */ #define AR_221_1_PICTURE 4 /* 2.21:1 picture (movie) */
/******************************************************************************* /*******************************************************************************
* subtitle_t: video subtitle * spu_t: video sub picture unit
******************************************************************************* *******************************************************************************
* Any subtitle destined to be displayed by a video output thread should be * Any sub picture unit destined to be displayed by a video output thread should
* stored in this structure from it's creation to it's effective display. * be stored in this structure from it's creation to it's effective display.
* Subtitle type and flags should only be modified by the output thread. Note * Subtitle type and flags should only be modified by the output thread. Note
* that an empty subtitle MUST have its flags set to 0. * that an empty subtitle MUST have its flags set to 0.
*******************************************************************************/ *******************************************************************************/
typedef struct subtitle_s typedef struct spu_s
{ {
/* Type and flags - should NOT be modified except by the vout thread */ /* Type and flags - should NOT be modified except by the vout thread */
int i_type; /* subtitle type */ int i_type; /* spu type */
int i_status; /* subtitle flags */ int i_status; /* spu flags */
/* Other properties */ /* Other properties */
mtime_t begin_date; /* beginning of display date */ mtime_t begin_date; /* beginning of display date */
mtime_t end_date; /* end of display date */ mtime_t end_date; /* end of display date */
/* Subtitle data - data can always be freely modified. p_data itself /* Sub picture unit data - data can always be freely modified. p_data itself
* (the pointer) should NEVER be modified. */ * (the pointer) should NEVER be modified. */
void * p_data; /* subtitle data */ void * p_data; /* spu data */
} subtitle_t; } spu_t;
/* Subtitle types */ /* SPU types */
#define EMPTY_SUBTITLE 0 /* subtitle slot is empty and available */ #define EMPTY_SPU 0 /* subtitle slot is empty and available */
#define RLE_SUBTITLE 100 /* RLE encoded subtitle */ #define RLE_SPU 100 /* RLE encoded subtitle */
/* Subtitle status */ /* Subpicture status */
#define FREE_SUBTITLE 0 /* subtitle is free and not allocated */ #define FREE_SPU 0 /* subtitle is free and not allocated */
#define RESERVED_SUBTITLE 1 /* subtitle is allocated and reserved */ #define RESERVED_SPU 1 /* subtitle is allocated and reserved */
#define READY_SUBTITLE 2 /* subtitle is ready for display */ #define READY_SPU 2 /* subtitle is ready for display */
#define DESTROYED_SUBTITLE 3 /* subtitle is allocated but no more used */ #define DESTROYED_SPU 3 /* subtitle is allocated but no more used */
...@@ -85,7 +85,7 @@ typedef struct vout_thread_s ...@@ -85,7 +85,7 @@ typedef struct vout_thread_s
boolean_t b_active; /* `active' flag */ boolean_t b_active; /* `active' flag */
vlc_thread_t thread_id; /* id for pthread functions */ vlc_thread_t thread_id; /* id for pthread functions */
vlc_mutex_t picture_lock; /* picture heap lock */ vlc_mutex_t picture_lock; /* picture heap lock */
vlc_mutex_t subtitle_lock; /* subtitle heap lock */ vlc_mutex_t spu_lock; /* subtitle heap lock */
vlc_mutex_t change_lock; /* thread change lock */ vlc_mutex_t change_lock; /* thread change lock */
int * pi_status; /* temporary status flag */ int * pi_status; /* temporary status flag */
p_vout_sys_t p_sys; /* system output method */ p_vout_sys_t p_sys; /* system output method */
...@@ -123,7 +123,7 @@ typedef struct vout_thread_s ...@@ -123,7 +123,7 @@ typedef struct vout_thread_s
/* Videos heap and translation tables */ /* Videos heap and translation tables */
picture_t p_picture[VOUT_MAX_PICTURES]; /* pictures */ picture_t p_picture[VOUT_MAX_PICTURES]; /* pictures */
subtitle_t p_subtitle[VOUT_MAX_PICTURES]; /* subtitles */ spu_t p_spu[VOUT_MAX_PICTURES]; /* subtitles */
vout_tables_t tables; /* translation tables */ vout_tables_t tables; /* translation tables */
vout_convert_t * p_ConvertYUV420; /* YUV 4:2:0 converter */ vout_convert_t * p_ConvertYUV420; /* YUV 4:2:0 converter */
vout_convert_t * p_ConvertYUV422; /* YUV 4:2:2 converter */ vout_convert_t * p_ConvertYUV422; /* YUV 4:2:2 converter */
...@@ -158,9 +158,9 @@ void vout_DisplayPicture ( vout_thread_t *p_vout, picture_t *p_pi ...@@ -158,9 +158,9 @@ void vout_DisplayPicture ( vout_thread_t *p_vout, picture_t *p_pi
void vout_DatePicture ( vout_thread_t *p_vout, picture_t *p_pic, mtime_t date ); void vout_DatePicture ( vout_thread_t *p_vout, picture_t *p_pic, mtime_t date );
void vout_LinkPicture ( vout_thread_t *p_vout, picture_t *p_pic ); void vout_LinkPicture ( vout_thread_t *p_vout, picture_t *p_pic );
void vout_UnlinkPicture ( vout_thread_t *p_vout, picture_t *p_pic ); void vout_UnlinkPicture ( vout_thread_t *p_vout, picture_t *p_pic );
subtitle_t * vout_CreateSubtitle ( vout_thread_t *p_vout, int i_type, int i_size ); spu_t * vout_CreateSubPictureUnit ( vout_thread_t *p_vout, int i_type, int i_size );
void vout_DestroySubtitle ( vout_thread_t *p_vout, subtitle_t *p_sub ); void vout_DestroySubPictureUnit ( vout_thread_t *p_vout, spu_t *p_spu );
void vout_DisplaySubtitle ( vout_thread_t *p_vout, subtitle_t *p_sub ); void vout_DisplaySubPictureUnit ( vout_thread_t *p_vout, spu_t *p_spu );
void vout_ClearBuffer ( vout_thread_t *p_vout, vout_buffer_t *p_buffer ); void vout_ClearBuffer ( vout_thread_t *p_vout, vout_buffer_t *p_buffer );
......
...@@ -68,6 +68,9 @@ ...@@ -68,6 +68,9 @@
#include "audio_decoder.h" #include "audio_decoder.h"
#include "ac3_decoder.h" #include "ac3_decoder.h"
/* Subtitles */
#include "spu_decoder.h"
/* Video */ /* Video */
#include "video.h" #include "video.h"
#include "video_output.h" #include "video_output.h"
......
...@@ -412,6 +412,10 @@ static void EndThread( input_thread_t * p_input ) ...@@ -412,6 +412,10 @@ static void EndThread( input_thread_t * p_input )
case AC3_AUDIO_ES: case AC3_AUDIO_ES:
ac3dec_DestroyThread( (ac3dec_thread_t *)(p_input->pp_selected_es[i_es_loop]->p_dec) ); ac3dec_DestroyThread( (ac3dec_thread_t *)(p_input->pp_selected_es[i_es_loop]->p_dec) );
break; break;
case DVD_SPU_ES:
fprintf(stderr, "input.h : destroying spudec\n");
spudec_DestroyThread( (spudec_thread_t *)(p_input->pp_selected_es[i_es_loop]->p_dec) );
break;
case 0: case 0:
/* Special streams for the PSI decoder, PID 0 and 1 */ /* Special streams for the PSI decoder, PID 0 and 1 */
break; break;
...@@ -1064,6 +1068,13 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input, ...@@ -1064,6 +1068,13 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
p_fifo = &(((ac3dec_thread_t *)(p_es_descriptor->p_dec))->fifo); p_fifo = &(((ac3dec_thread_t *)(p_es_descriptor->p_dec))->fifo);
break; break;
case DVD_SPU_ES:
/* we skip 4 bytes at the beginning of the subpicture payload */
p_ts->i_payload_start += 4;
fprintf(stderr, "input.h : launching spudec\n");
p_fifo = &(((spudec_thread_t *)(p_es_descriptor->p_dec))->fifo);
break;
default: default:
/* This should never happen */ /* This should never happen */
intf_DbgMsg("Unknown stream type (%d, %d): PES trashed\n", intf_DbgMsg("Unknown stream type (%d, %d): PES trashed\n",
......
...@@ -112,6 +112,17 @@ int input_AddPgrmElem( input_thread_t *p_input, int i_current_id ) ...@@ -112,6 +112,17 @@ int input_AddPgrmElem( input_thread_t *p_input, int i_current_id )
} }
break; break;
case DVD_SPU_ES:
/* Spawn spu thread */
if ( ((spudec_thread_t *)(p_input->p_es[i_es_loop].p_dec) =
spudec_CreateThread(p_input)) == NULL )
{
intf_ErrMsg( "Could not start subtitle decoder\n" );
vlc_mutex_unlock( &p_input->es_lock );
return( -1 );
}
break;
case MPEG1_AUDIO_ES: case MPEG1_AUDIO_ES:
case MPEG2_AUDIO_ES: case MPEG2_AUDIO_ES:
/* Spawn audio thread. */ /* Spawn audio thread. */
...@@ -156,7 +167,7 @@ int input_AddPgrmElem( input_thread_t *p_input, int i_current_id ) ...@@ -156,7 +167,7 @@ int input_AddPgrmElem( input_thread_t *p_input, int i_current_id )
/* Initialise the demux */ /* Initialise the demux */
p_input->p_es[i_es_loop].p_pes_packet = NULL; p_input->p_es[i_es_loop].p_pes_packet = NULL;
p_input->p_es[i_es_loop].i_continuity_counter = 0xFF; p_input->p_es[i_es_loop].i_continuity_counter = 0xff;
p_input->p_es[i_es_loop].b_random = 0; p_input->p_es[i_es_loop].b_random = 0;
/* Mark stream to be demultiplexed. */ /* Mark stream to be demultiplexed. */
...@@ -217,6 +228,10 @@ int input_DelPgrmElem( input_thread_t *p_input, int i_current_id ) ...@@ -217,6 +228,10 @@ int input_DelPgrmElem( input_thread_t *p_input, int i_current_id )
ac3dec_DestroyThread( (ac3dec_thread_t *)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) ); ac3dec_DestroyThread( (ac3dec_thread_t *)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
break; break;
case DVD_SPU_ES:
spudec_DestroyThread( (spudec_thread_t *)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
break;
case MPEG1_AUDIO_ES: case MPEG1_AUDIO_ES:
case MPEG2_AUDIO_ES: case MPEG2_AUDIO_ES:
adec_DestroyThread( (adec_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) ); adec_DestroyThread( (adec_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
......
...@@ -649,6 +649,15 @@ static void DecodePgrmMapSection( u8* p_pms, input_thread_t* p_input ) ...@@ -649,6 +649,15 @@ static void DecodePgrmMapSection( u8* p_pms, input_thread_t* p_input )
} }
break; break;
case DVD_SPU_ES:
if ( p_main->b_audio )
{
/* Spawn a spu decoder thread */
input_AddPgrmElem( p_input,
p_input->p_es[i_es_loop].i_id );
}
break;
case MPEG1_AUDIO_ES: case MPEG1_AUDIO_ES:
case MPEG2_AUDIO_ES: case MPEG2_AUDIO_ES:
if( p_main->b_audio ) if( p_main->b_audio )
......
/*******************************************************************************
* spu_decoder.c : spu decoder thread
* (c)2000 VideoLAN
*******************************************************************************/
/* repomp sur video_decoder.c
* ?? passer en terminate/destroy avec les signaux supplmentaires */
/*******************************************************************************
* Preamble
*******************************************************************************/
//#include "vlc.h"
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/uio.h>
#include "config.h"
#include "common.h"
#include "mtime.h"
#include "vlc_thread.h"
#include "intf_msg.h"
#include "debug.h" /* ?? temporaire, requis par netlist.h */
#include "input.h"
#include "input_netlist.h"
#include "decoder_fifo.h"
#include "spu_decoder.h"
/*
* Local prototypes
*/
static int InitThread ( spudec_thread_t *p_spudec );
static void RunThread ( spudec_thread_t *p_spudec );
static void ErrorThread ( spudec_thread_t *p_spudec );
static void EndThread ( spudec_thread_t *p_spudec );
/******************************************************************************
* spudec_CreateThread: create a spu decoder thread
******************************************************************************/
spudec_thread_t * spudec_CreateThread( input_thread_t * p_input )
{
spudec_thread_t * p_spudec;
intf_DbgMsg("spudec debug: creating spu decoder thread\n");
fprintf(stderr, "spudec debug: creating spu decoder thread\n");
/* Allocate the memory needed to store the thread's structure */
if ( (p_spudec = (spudec_thread_t *)malloc( sizeof(spudec_thread_t) )) == NULL )
{
intf_ErrMsg("spudec error: not enough memory for spudec_CreateThread() to create the new thread\n");
return( NULL );
}
/*
* Initialize the thread properties
*/
p_spudec->b_die = 0;
p_spudec->b_error = 0;
/* Spawn the spu decoder thread */
if ( vlc_thread_create(&p_spudec->thread_id, "spu decoder",
(vlc_thread_func_t)RunThread, (void *)p_spudec) )
{
intf_ErrMsg("spudec error: can't spawn spu decoder thread\n");
free( p_spudec );
return( NULL );
}
intf_DbgMsg("spudec debug: spu decoder thread (%p) created\n", p_spudec);
return( p_spudec );
}
/*******************************************************************************
* spudec_DestroyThread: destroy a spu decoder thread
*******************************************************************************
* Destroy and terminate thread. This function will return 0 if the thread could
* be destroyed, and non 0 else. The last case probably means that the thread
* was still active, and another try may succeed.
*******************************************************************************/
void spudec_DestroyThread( spudec_thread_t *p_spudec )
{
intf_DbgMsg("spudec debug: requesting termination of spu decoder thread %p\n", p_spudec);
fprintf(stderr, "spudec debug: requesting termination of spu decoder thread %p\n", p_spudec);
/* Ask thread to kill itself */
p_spudec->b_die = 1;
/* Waiting for the decoder thread to exit */
/* Remove this as soon as the "status" flag is implemented */
vlc_thread_join( p_spudec->thread_id );
}
/* following functions are local */
/*******************************************************************************
* InitThread: initialize spu decoder thread
*******************************************************************************
* This function is called from RunThread and performs the second step of the
* initialization. It returns 0 on success. Note that the thread's flag are not
* modified inside this function.
*******************************************************************************/
static int InitThread( spudec_thread_t *p_spudec )
{
intf_DbgMsg("spudec debug: initializing spu decoder thread %p\n", p_spudec);
/* Mark thread as running and return */
intf_DbgMsg("spudec debug: InitThread(%p) succeeded\n", p_spudec);
return( 0 );
}
/*******************************************************************************
* RunThread: spu decoder thread
*******************************************************************************
* spu decoder thread. This function does only return when the thread is
* terminated.
*******************************************************************************/
static void RunThread( spudec_thread_t *p_spudec )
{
intf_DbgMsg("spudec debug: running spu decoder thread (%p) (pid == %i)\n",
p_spudec, getpid());
/*
* Initialize thread and free configuration
*/
p_spudec->b_error = InitThread( p_spudec );
if( p_spudec->b_error )
{
return;
}
p_spudec->b_run = 1;
/*
* Main loop - it is not executed if an error occured during
* initialization
*/
while( (!p_spudec->b_die) && (!p_spudec->b_error) )
{
fprintf(stderr, "I'm a spu decoder !\n");
sleep(1);
}
/*
* Error loop
*/
if( p_spudec->b_error )
{
ErrorThread( p_spudec );
}
/* End of thread */
EndThread( p_spudec );
p_spudec->b_run = 0;
}
/*******************************************************************************
* ErrorThread: RunThread() error loop
*******************************************************************************
* This function is called when an error occured during thread main's loop. The
* thread can still receive feed, but must be ready to terminate as soon as
* possible.
*******************************************************************************/
static void ErrorThread( spudec_thread_t *p_spudec )
{
/* Wait until a `die' order */
while( !p_spudec->b_die )
{
// foo();
}
}
/*******************************************************************************
* EndThread: thread destruction
*******************************************************************************
* This function is called when the thread ends after a sucessfull
* initialization.
*******************************************************************************/
static void EndThread( spudec_thread_t *p_spudec )
{
intf_DbgMsg("spudec debug: EndThread(%p)\n", p_spudec);
}
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment