@ -29,6 +29,7 @@
typedef struct ASSContext {
typedef struct ASSContext {
FFDemuxSubtitlesQueue q ;
FFDemuxSubtitlesQueue q ;
unsigned readorder ;
} ASSContext ;
} ASSContext ;
static int ass_probe ( AVProbeData * p )
static int ass_probe ( AVProbeData * p )
@ -52,18 +53,36 @@ static int ass_read_close(AVFormatContext *s)
return 0 ;
return 0 ;
}
}
static int read_ts ( const uint8_t * p , int64_t * start , int * duration )
static int read_dialogue ( ASSContext * ass , AVBPrint * dst , const uint8_t * p ,
int64_t * start , int * duration )
{
{
int pos ;
int64_t end ;
int64_t end ;
int hh1 , mm1 , ss1 , ms1 ;
int hh1 , mm1 , ss1 , ms1 ;
int hh2 , mm2 , ss2 , ms2 ;
int hh2 , mm2 , ss2 , ms2 ;
if ( sscanf ( p , " %*[^,],%d:%d:%d%*c%d,%d:%d:%d%*c%d " ,
if ( sscanf ( p , " Dialogue: %*[^,],%d:%d:%d%*c%d,%d:%d:%d%*c%d,%n " ,
& hh1 , & mm1 , & ss1 , & ms1 ,
& hh1 , & mm1 , & ss1 , & ms1 ,
& hh2 , & mm2 , & ss2 , & ms2 ) = = 8 ) {
& hh2 , & mm2 , & ss2 , & ms2 , & pos ) > = 8 ) {
/* This is not part of the sscanf itself in order to handle an actual
* number ( which would be the Layer ) or the form " Marked=N " ( which is
* the old SSA field , now replaced by Layer , and will be lead to Layer
* being 0 here ) . */
const int layer = atoi ( p + 10 ) ;
end = ( hh2 * 3600LL + mm2 * 60LL + ss2 ) * 100LL + ms2 ;
end = ( hh2 * 3600LL + mm2 * 60LL + ss2 ) * 100LL + ms2 ;
* start = ( hh1 * 3600LL + mm1 * 60LL + ss1 ) * 100LL + ms1 ;
* start = ( hh1 * 3600LL + mm1 * 60LL + ss1 ) * 100LL + ms1 ;
* duration = end - * start ;
* duration = end - * start ;
av_bprint_clear ( dst ) ;
av_bprintf ( dst , " %u,%d,%s " , ass - > readorder + + , layer , p + pos ) ;
/* right strip the buffer */
while ( dst - > len > 0 & &
dst - > str [ dst - > len - 1 ] = = ' \r ' | |
dst - > str [ dst - > len - 1 ] = = ' \n ' )
dst - > str [ - - dst - > len ] = 0 ;
return 0 ;
return 0 ;
}
}
return - 1 ;
return - 1 ;
@ -88,7 +107,7 @@ static int64_t get_line(AVBPrint *buf, FFTextReader *tr)
static int ass_read_header ( AVFormatContext * s )
static int ass_read_header ( AVFormatContext * s )
{
{
ASSContext * ass = s - > priv_data ;
ASSContext * ass = s - > priv_data ;
AVBPrint header , line ;
AVBPrint header , line , rline ;
int header_remaining , res = 0 ;
int header_remaining , res = 0 ;
AVStream * st ;
AVStream * st ;
FFTextReader tr ;
FFTextReader tr ;
@ -99,12 +118,13 @@ static int ass_read_header(AVFormatContext *s)
return AVERROR ( ENOMEM ) ;
return AVERROR ( ENOMEM ) ;
avpriv_set_pts_info ( st , 64 , 1 , 100 ) ;
avpriv_set_pts_info ( st , 64 , 1 , 100 ) ;
st - > codec - > codec_type = AVMEDIA_TYPE_SUBTITLE ;
st - > codec - > codec_type = AVMEDIA_TYPE_SUBTITLE ;
st - > codec - > codec_id = AV_CODEC_ID_SSA ;
st - > codec - > codec_id = AV_CODEC_ID_A SS ;
header_remaining = INT_MAX ;
header_remaining = INT_MAX ;
av_bprint_init ( & header , 0 , AV_BPRINT_SIZE_UNLIMITED ) ;
av_bprint_init ( & header , 0 , AV_BPRINT_SIZE_UNLIMITED ) ;
av_bprint_init ( & line , 0 , AV_BPRINT_SIZE_UNLIMITED ) ;
av_bprint_init ( & line , 0 , AV_BPRINT_SIZE_UNLIMITED ) ;
av_bprint_init ( & rline , 0 , AV_BPRINT_SIZE_UNLIMITED ) ;
for ( ; ; ) {
for ( ; ; ) {
int64_t pos = get_line ( & line , & tr ) ;
int64_t pos = get_line ( & line , & tr ) ;
@ -125,9 +145,9 @@ static int ass_read_header(AVFormatContext *s)
int duration = - 1 ;
int duration = - 1 ;
AVPacket * sub ;
AVPacket * sub ;
if ( read_ts ( line . str , & ts_start , & duration ) < 0 )
if ( read_dialogue ( ass , & rline , line . str , & ts_start , & duration ) < 0 )
continue ;
continue ;
sub = ff_subtitles_queue_insert ( & ass - > q , line . str , line . len , 0 ) ;
sub = ff_subtitles_queue_insert ( & ass - > q , r line. str , r line. len , 0 ) ;
if ( ! sub ) {
if ( ! sub ) {
res = AVERROR ( ENOMEM ) ;
res = AVERROR ( ENOMEM ) ;
goto end ;
goto end ;
@ -139,6 +159,7 @@ static int ass_read_header(AVFormatContext *s)
}
}
av_bprint_finalize ( & line , NULL ) ;
av_bprint_finalize ( & line , NULL ) ;
av_bprint_finalize ( & rline , NULL ) ;
res = avpriv_bprint_to_extradata ( st - > codec , & header ) ;
res = avpriv_bprint_to_extradata ( st - > codec , & header ) ;
if ( res < 0 )
if ( res < 0 )