Changeset 85071f3419dec4837538a25f0ab8853cd6ddf531

Show
Ignore:
Timestamp:
11/06/02 22:48:24 (6 years ago)
Author:
Gildas Bazin <gbazin@videolan.org>
git-committer:
Gildas Bazin <gbazin@videolan.org> 1036619304 +0000
git-parent:

[8b09b55dd76c038d1363ff4827f49f131bd42429]

git-author:
Gildas Bazin <gbazin@videolan.org> 1036619304 +0000
Message:

* modules/codec/spudec/*: modified the spu decoder to handle text subtitles.

Only one format of text subtitles is supported right now but we should be able
to expand this by modifying modules/codec/spudec/text.c.
Most of this work comes from by Andrew Flintham ( thanks a bunch Andrew :).

* share/font-eutopiabold36.rle: new font for the text subtitler, courtesy of

Andrew Flintham.

* AUTHORS: added Andrew Flintham to the authors file.

* modules/demux/ogg.c: modified the ogg demuxer to handle subtitles.

* modules/codec/ffmpeg/*: modified the ffmpeg decoder to always keep the last decoded

frame linked.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • AUTHORS

    rbfc4f0f r85071f3  
    419419S: France 
    420420 
     421N: Andrew Flintham 
     422E: amf@cus.org.uk 
     423D: text subtitler and font scripts 
     424S: United Kingdom 
  • modules/codec/ffmpeg/video.c

    r3e017c2 r85071f3  
    33 ***************************************************************************** 
    44 * Copyright (C) 1999-2001 VideoLAN 
    5  * $Id: video.c,v 1.2 2002/11/05 10:07:56 gbazin Exp $ 
     5 * $Id: video.c,v 1.3 2002/11/06 21:48:24 gbazin Exp $ 
    66 * 
    77 * Authors: Laurent Aimar <fenrir@via.ecp.fr> 
     
    350350    p_vdec->b_hurry_up = config_GetInt(p_vdec->p_fifo, "ffmpeg-hurry-up"); 
    351351 
     352    p_vdec->p_lastpic = NULL; 
     353    p_vdec->p_secondlastpic = NULL; 
    352354    p_vdec->b_direct_rendering = 0; 
    353355#if LIBAVCODEC_BUILD > 4615 
     
    669671void E_( EndThread_Video )( vdec_thread_t *p_vdec ) 
    670672{ 
     673    if( p_vdec->p_secondlastpic ) 
     674        vout_UnlinkPicture( p_vdec->p_vout, p_vdec->p_secondlastpic ); 
     675    if( p_vdec->p_lastpic ) 
     676        vout_UnlinkPicture( p_vdec->p_vout, p_vdec->p_lastpic ); 
     677 
    671678    if( p_vdec->p_pp ) 
    672679    { 
     
    798805    } 
    799806 
    800     /* FIXME: we may have to use link/unlinkPicture to fully support streams 
    801      * with B FRAMES */ 
     807    /* FIXME: We keep the last picture linked until the current one is decoded, 
     808     * this trick won't work with streams with B frames though. */ 
     809    vout_LinkPicture( p_vdec->p_vout, p_pic ); 
     810    if( p_vdec->p_secondlastpic ) 
     811        vout_UnlinkPicture( p_vdec->p_vout, p_vdec->p_secondlastpic ); 
     812    p_vdec->p_secondlastpic = p_vdec->p_lastpic; 
     813    p_vdec->p_lastpic = p_pic; 
    802814 
    803815    avctx->draw_horiz_band= NULL; 
  • modules/codec/ffmpeg/video.h

    r3e017c2 r85071f3  
    33 ***************************************************************************** 
    44 * Copyright (C) 1999-2001 VideoLAN 
    5  * $Id: video.h,v 1.2 2002/11/05 10:07:56 gbazin Exp $ 
     5 * $Id: video.h,v 1.3 2002/11/06 21:48:24 gbazin Exp $ 
    66 * 
    77 * Authors: Laurent Aimar <fenrir@via.ecp.fr> 
     
    4242    /* for direct rendering */ 
    4343    int b_direct_rendering; 
    44  
     44    picture_t *p_lastpic; 
     45    picture_t *p_secondlastpic; 
    4546} vdec_thread_t; 
    4647 
  • modules/codec/spudec/Modules.am

    r8641281 r85071f3  
    22    modules/codec/spudec/spudec.c \ 
    33    modules/codec/spudec/parse.c \ 
    4     modules/codec/spudec/render.c 
     4    modules/codec/spudec/render.c \ 
     5    modules/codec/spudec/text.c \ 
     6    modules/codec/spudec/subtitler.c 
    57 
    68noinst_HEADERS += \ 
  • modules/codec/spudec/parse.c

    r8b09b55 r85071f3  
    33 ***************************************************************************** 
    44 * Copyright (C) 2000-2001 VideoLAN 
    5  * $Id: parse.c,v 1.4 2002/11/06 18:07:57 sam Exp $ 
     5 * $Id: parse.c,v 1.5 2002/11/06 21:48:24 gbazin Exp $ 
    66 * 
    77 * Authors: Samuel Hocevar <sam@zoy.org> 
     
    3131#include <vlc/vout.h> 
    3232#include <vlc/decoder.h> 
    33  
    34 #ifdef HAVE_UNISTD_H 
    35 #   include <unistd.h>                                           /* getpid() */ 
    36 #endif 
    37  
    38 #ifdef WIN32                   /* getpid() for win32 is located in process.h */ 
    39 #   include <process.h> 
    40 #endif 
    4133 
    4234#include "spudec.h" 
  • modules/codec/spudec/render.c

    r8b09b55 r85071f3  
    33 ***************************************************************************** 
    44 * Copyright (C) 2000-2001 VideoLAN 
    5  * $Id: render.c,v 1.3 2002/11/06 18:07:57 sam Exp $ 
     5 * $Id: render.c,v 1.4 2002/11/06 21:48:24 gbazin Exp $ 
    66 * 
    77 * Authors: Samuel Hocevar <sam@zoy.org> 
     
    3434#include <vlc/decoder.h> 
    3535 
    36 #ifdef HAVE_UNISTD_H 
    37 #   include <unistd.h>                                           /* getpid() */ 
    38 #endif 
    39  
    40 #ifdef WIN32                   /* getpid() for win32 is located in process.h */ 
    41 #   include <process.h> 
    42 #endif 
    43  
    4436#include "spudec.h" 
    4537 
  • modules/codec/spudec/spudec.c

    r8b09b55 r85071f3  
    33 ***************************************************************************** 
    44 * Copyright (C) 2000-2001 VideoLAN 
    5  * $Id: spudec.c,v 1.7 2002/11/06 18:07:57 sam Exp $ 
     5 * $Id: spudec.c,v 1.8 2002/11/06 21:48:24 gbazin Exp $ 
    66 * 
    77 * Authors: Samuel Hocevar <sam@zoy.org> 
     
    3232#include <vlc/decoder.h> 
    3333 
    34 #ifdef HAVE_UNISTD_H 
    35 #   include <unistd.h>                                           /* getpid() */ 
    36 #endif 
    37  
    38 #ifdef WIN32                   /* getpid() for win32 is located in process.h */ 
    39 #   include <process.h> 
    40 #endif 
    41  
    4234#include "spudec.h" 
    4335 
     
    5345 * Module descriptor. 
    5446 *****************************************************************************/ 
     47#define FONT_TEXT N_("Font used by the text subtitler") 
     48#define FONT_LONGTEXT N_(\ 
     49    "When the subtitles are coded in text form then, you can choose " \ 
     50    "which font will be used to display them.") 
     51 
    5552vlc_module_begin(); 
    56     set_description( _("DVD subtitles decoder module") ); 
     53    add_category_hint( N_("subtitles"), NULL ); 
     54    add_file( "spudec-font", "./share/font-eutopiabold36.rle", NULL, 
     55              FONT_TEXT, FONT_LONGTEXT ); 
     56    set_description( _("subtitles decoder module") ); 
    5757    set_capability( "decoder", 50 ); 
    5858    set_callbacks( OpenDecoder, NULL ); 
     
    7070 
    7171    if( p_fifo->i_fourcc != VLC_FOURCC('s','p','u',' ') 
    72          && p_fifo->i_fourcc != VLC_FOURCC('s','p','u','b') ) 
    73     {    
     72         && p_fifo->i_fourcc != VLC_FOURCC('s','p','u','b') 
     73         && p_fifo->i_fourcc != VLC_FOURCC('s','u','b','t') ) 
     74    { 
    7475        return VLC_EGENERIC; 
    7576    } 
    76      
     77 
    7778    p_fifo->pf_run = RunDecoder; 
    7879 
     
    8687{ 
    8788    spudec_thread_t *     p_spudec; 
     89    subtitler_font_t *    p_font; 
     90    char *                psz_font; 
    8891 
    8992    /* Allocate the memory needed to store the thread's structure */ 
     
    102105    p_spudec->p_vout = NULL; 
    103106    p_spudec->p_fifo = p_fifo; 
    104          
     107 
    105108    /* 
    106109     * Initialize thread and free configuration 
     
    112115     * initialization 
    113116     */ 
    114     while( (!p_spudec->p_fifo->b_die) && (!p_spudec->p_fifo->b_error) ) 
    115     { 
    116         if( E_(SyncPacket)( p_spudec ) ) 
    117         { 
    118             continue; 
    119         } 
    120  
    121         E_(ParsePacket)( p_spudec ); 
     117    if( p_fifo->i_fourcc == VLC_FOURCC('s','u','b','t') ) 
     118    { 
     119        /* Here we are dealing with text subtitles */ 
     120 
     121        if( (psz_font = config_GetPsz( p_fifo, "spudec-font" )) == NULL ) 
     122        { 
     123            msg_Err( p_fifo, "no default font selected" ); 
     124            p_font = NULL; 
     125            p_spudec->p_fifo->b_error; 
     126        } 
     127        else 
     128        { 
     129            p_font = subtitler_LoadFont( p_spudec->p_vout, psz_font ); 
     130            if ( p_font == NULL ) 
     131            { 
     132                msg_Err( p_fifo, "unable to load font: %s", psz_font ); 
     133                p_spudec->p_fifo->b_error; 
     134            } 
     135        } 
     136        if( psz_font ) free( psz_font ); 
     137 
     138        while( (!p_spudec->p_fifo->b_die) && (!p_spudec->p_fifo->b_error) ) 
     139        { 
     140            E_(ParseText)( p_spudec, p_font ); 
     141        } 
     142 
     143        if( p_font ) subtitler_UnloadFont( p_spudec->p_vout, p_font ); 
     144 
     145    } 
     146    else 
     147    { 
     148        /* Here we are dealing with sub-pictures subtitles*/ 
     149 
     150        while( (!p_spudec->p_fifo->b_die) && (!p_spudec->p_fifo->b_error) ) 
     151        { 
     152            if( E_(SyncPacket)( p_spudec ) ) 
     153            { 
     154                continue; 
     155            } 
     156 
     157            E_(ParsePacket)( p_spudec ); 
     158        } 
    122159    } 
    123160 
     
    155192        if( p_spudec->p_fifo->b_die || p_spudec->p_fifo->b_error ) 
    156193        { 
    157             /* Call InitBitstream anyway so p_spudec is in a known state 
    158              * before calling CloseBitstream */ 
     194            /* Call InitBitstream anyway so p_spudec->bit_stream is in a known 
     195             * state before calling CloseBitstream */ 
    159196            InitBitstream( &p_spudec->bit_stream, p_spudec->p_fifo, 
    160197                           NULL, NULL ); 
     
    210247    free( p_spudec ); 
    211248} 
    212  
  • modules/codec/spudec/spudec.h

    r8b09b55 r85071f3  
    33 ***************************************************************************** 
    44 * Copyright (C) 1999, 2000 VideoLAN 
    5  * $Id: spudec.h,v 1.3 2002/11/06 18:07:57 sam Exp $ 
     5 * $Id: spudec.h,v 1.4 2002/11/06 21:48:24 gbazin Exp $ 
    66 * 
    77 * Authors: Samuel Hocevar <sam@zoy.org> 
     
    4444    int          i_x_start, i_y_start, i_x_end, i_y_end; 
    4545}; 
     46 
     47/***************************************************************************** 
     48 * subtitler_font_t : proportional font 
     49 *****************************************************************************/ 
     50typedef struct subtitler_font_s 
     51{ 
     52    int                 i_height;              /* character height in pixels */ 
     53    int                 i_width[256];          /* character widths in pixels */ 
     54    int                 i_memory[256]; /* amount of memory used by character */ 
     55    int *               p_length[256];                   /* line byte widths */ 
     56    u16 **              p_offset[256];                /* pointer to RLE data */ 
     57} subtitler_font_t; 
    4658 
    4759/***************************************************************************** 
     
    100112                                const subpicture_t * ); 
    101113 
     114void E_(ParseText)            ( spudec_thread_t *, subtitler_font_t * ); 
     115 
     116subtitler_font_t *E_(subtitler_LoadFont) ( vout_thread_t *, const char * ); 
     117void E_(subtitler_UnloadFont)   ( vout_thread_t *, subtitler_font_t * ); 
     118void E_(subtitler_PlotSubtitle) ( vout_thread_t *, char *, subtitler_font_t *, 
     119                                  mtime_t, mtime_t ); 
  • modules/demux/ogg.c

    rbe822ed r85071f3  
    33 ***************************************************************************** 
    44 * Copyright (C) 2001 VideoLAN 
    5  * $Id: ogg.c,v 1.7 2002/11/05 21:57:41 gbazin Exp $ 
     5 * $Id: ogg.c,v 1.8 2002/11/06 21:48:23 gbazin Exp $ 
    66 * 
    77 * Authors: Gildas Bazin <gbazin@netcourrier.com> 
     
    8888    logical_stream_t *p_stream_video; 
    8989    logical_stream_t *p_stream_audio; 
     90    logical_stream_t *p_stream_spu; 
    9091 
    9192    /* stream we use as a time reference for demux reading speed */ 
     
    169170/* Stream managment */ 
    170171static int  Ogg_StreamStart  ( input_thread_t *, demux_sys_t *, int ); 
    171 static int  Ogg_StreamSeek   ( input_thread_t *, demux_sys_t *, int, mtime_t ); 
    172172static void Ogg_StreamStop   ( input_thread_t *, demux_sys_t *, int ); 
    173173 
     
    228228    } 
    229229 
    230     //Ogg_StreamSeek( p_input, p_ogg, i_stream, p_ogg->i_time ); 
    231  
    232230    return( p_stream->i_activated ); 
    233231#undef  p_stream 
     
    255253 
    256254#undef  p_stream 
    257 } 
    258  
    259 static int Ogg_StreamSeek( input_thread_t *p_input, demux_sys_t  *p_ogg, 
    260                            int i_stream, mtime_t i_date ) 
    261 { 
    262 #define p_stream    p_ogg->pp_stream[i_stream] 
    263  
    264     /* FIXME: todo */ 
    265  
    266     return 1; 
    267 #undef p_stream 
    268255} 
    269256 
     
    384371 
    385372    /* Convert the pcr into a pts */ 
    386     p_pes->i_pts = ( p_stream->i_pcr < 0 ) ? 0 : 
    387         input_ClockGetTS( p_input, p_input->stream.p_selected_program, 
    388                           p_stream->i_pcr ); 
     373    if( p_stream->i_cat != SPU_ES ) 
     374    { 
     375        p_pes->i_pts = ( p_stream->i_pcr < 0 ) ? 0 : 
     376            input_ClockGetTS( p_input, p_input->stream.p_selected_program, 
     377                              p_stream->i_pcr ); 
     378    } 
     379    else 
     380    { 
     381        /* Of course subtitles had to be different! */ 
     382        p_pes->i_pts = ( p_oggpacket->granulepos < 0 ) ? 0 : 
     383            input_ClockGetTS( p_input, p_input->stream.p_selected_program, 
     384                              p_oggpacket->granulepos * 90000 / 
     385                              p_stream->i_rate ); 
     386    } 
    389387 
    390388    /* Convert the next granule into a pcr */ 
     
    436434 
    437435    p_data->p_payload_end = p_data->p_payload_start + p_pes->i_pes_size; 
     436    p_data->b_discard_payload = 0; 
    438437 
    439438    input_DecodePES( p_stream->p_es->p_decoder_fifo, p_pes ); 
     
    650649                    else if( !strncmp(st->streamtype, "text", 4) ) 
    651650                    { 
     651                        /* We need to get rid of the header packet */ 
     652                        ogg_stream_packetout( &p_stream->os, &oggpacket ); 
     653 
    652654                        msg_Dbg( p_input, "found text subtitles header" ); 
    653655                        p_stream->i_cat = SPU_ES; 
    654656                        p_stream->i_fourcc = 
    655657                            VLC_FOURCC( 's', 'u', 'b', 't' ); 
     658                        p_stream->i_rate = 1000; /* granulepos is in milisec */ 
    656659                    } 
    657660                    else 
     
    773776        p_input->stream.i_mux_rate += (p_stream->i_bitrate / ( 8 * 50 )); 
    774777        vlc_mutex_unlock( &p_input->stream.stream_lock ); 
    775         p_stream->p_es->i_stream_id = i_stream; 
     778        p_stream->p_es->i_stream_id = p_stream->p_es->i_id = i_stream; 
    776779        p_stream->p_es->i_fourcc = p_stream->i_fourcc; 
    777780        p_stream->p_es->i_cat = p_stream->i_cat; 
     
    787790        { 
    788791            case( VIDEO_ES ): 
    789  
    790792                if( (p_ogg->p_stream_video == NULL) ) 
    791793                { 
     
    799801                if( (p_ogg->p_stream_audio == NULL) ) 
    800802                { 
    801                     p_ogg->p_stream_audio = p_stream; 
    802                     p_ogg->p_stream_timeref = p_stream; 
    803                     Ogg_StreamStart( p_input, p_ogg, i_stream ); 
     803                    int i_audio = config_GetInt( p_input, "audio-channel" ); 
     804                    if( i_audio == i_stream || i_audio <= 0 || 
     805                        i_audio >= p_ogg->i_streams || 
     806                        p_ogg->pp_stream[i_audio]->p_es->i_cat != AUDIO_ES ) 
     807                    { 
     808                        p_ogg->p_stream_audio = p_stream; 
     809                        p_ogg->p_stream_timeref = p_stream; 
     810                        Ogg_StreamStart( p_input, p_ogg, i_stream ); 
     811                    } 
     812                } 
     813                break; 
     814 
     815            case( SPU_ES ): 
     816                if( (p_ogg->p_stream_spu == NULL) ) 
     817                { 
     818                    /* for spu, default is none */ 
     819                    int i_spu = config_GetInt( p_input, "spu-channel" ); 
     820                    if( i_spu < 0 || i_spu >= p_ogg->i_streams || 
     821                        p_ogg->pp_stream[i_spu]->p_es->i_cat != SPU_ES ) 
     822                    { 
     823                        break; 
     824                    } 
     825                    else if( i_spu == i_stream ) 
     826                    { 
     827                        p_ogg->p_stream_spu = p_stream; 
     828                        Ogg_StreamStart( p_input, p_ogg, i_stream ); 
     829                    } 
    804830                } 
    805831                break;