Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-gpu
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-gpu
Commits
0981604c
Commit
0981604c
authored
Nov 24, 2003
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* all: ported/cleaned up/renabled dvb subtitle decoder. But it is untested.
(I have no sample at all)
parent
5bab317b
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
564 additions
and
578 deletions
+564
-578
configure.ac
configure.ac
+2
-2
include/vlc_es.h
include/vlc_es.h
+6
-1
modules/codec/Modules.am
modules/codec/Modules.am
+1
-0
modules/codec/dvbsub.c
modules/codec/dvbsub.c
+538
-564
src/input/input_dec.c
src/input/input_dec.c
+17
-11
No files found.
configure.ac
View file @
0981604c
dnl Autoconf settings for vlc
dnl Autoconf settings for vlc
dnl $Id: configure.ac,v 1.1
19 2003/11/23 18:40:09
fenrir Exp $
dnl $Id: configure.ac,v 1.1
20 2003/11/24 02:35:50
fenrir Exp $
AC_INIT(vlc,0.6.3-cvs)
AC_INIT(vlc,0.6.3-cvs)
...
@@ -867,7 +867,7 @@ dnl default modules
...
@@ -867,7 +867,7 @@ dnl default modules
dnl
dnl
AX_ADD_PLUGINS([dummy rc logger gestures memcpy hotkeys])
AX_ADD_PLUGINS([dummy rc logger gestures memcpy hotkeys])
AX_ADD_PLUGINS([mpgv mpga m4v mpeg_system ps ts avi asf aac mp4 rawdv])
AX_ADD_PLUGINS([mpgv mpga m4v mpeg_system ps ts avi asf aac mp4 rawdv])
AX_ADD_PLUGINS([spudec mpeg_audio lpcm a52 dts cinepak])
AX_ADD_PLUGINS([spudec
dvbsub
mpeg_audio lpcm a52 dts cinepak])
AX_ADD_PLUGINS([deinterlace invert adjust wall transform distort clone crop motionblur])
AX_ADD_PLUGINS([deinterlace invert adjust wall transform distort clone crop motionblur])
AX_ADD_PLUGINS([float32tos16 float32tos8 float32tou16 float32tou8 a52tospdif dtstospdif fixed32tofloat32 fixed32tos16 s16tofixed32 s16tofloat32 s16tofloat32swab s8tofloat32 u8tofixed32 u8tofloat32])
AX_ADD_PLUGINS([float32tos16 float32tos8 float32tou16 float32tou8 a52tospdif dtstospdif fixed32tofloat32 fixed32tos16 s16tofixed32 s16tofloat32 s16tofloat32swab s8tofloat32 u8tofixed32 u8tofloat32])
AX_ADD_PLUGINS([trivial_resampler ugly_resampler linear_resampler bandlimited_resampler])
AX_ADD_PLUGINS([trivial_resampler ugly_resampler linear_resampler bandlimited_resampler])
...
...
include/vlc_es.h
View file @
0981604c
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* vlc_es.h
* vlc_es.h
*****************************************************************************
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* Copyright (C) 1999-2001 VideoLAN
* $Id: vlc_es.h,v 1.
4 2003/11/24 00:39:0
0 fenrir Exp $
* $Id: vlc_es.h,v 1.
5 2003/11/24 02:35:5
0 fenrir Exp $
*
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
*
...
@@ -92,6 +92,11 @@ struct subs_format_t
...
@@ -92,6 +92,11 @@ struct subs_format_t
/* FIXME */
/* FIXME */
uint32_t
palette
[
16
+
1
];
uint32_t
palette
[
16
+
1
];
}
spu
;
}
spu
;
struct
{
int
i_id
;
}
dvb
;
};
};
/**
/**
...
...
modules/codec/Modules.am
View file @
0981604c
...
@@ -16,3 +16,4 @@ SOURCES_rawvideo = rawvideo.c
...
@@ -16,3 +16,4 @@ SOURCES_rawvideo = rawvideo.c
SOURCES_quicktime = quicktime.c
SOURCES_quicktime = quicktime.c
SOURCES_subsdec = subsdec.c
SOURCES_subsdec = subsdec.c
SOURCES_faad = faad.c
SOURCES_faad = faad.c
SOURCES_dvbsub = dvbsub.c
modules/codec/dvbsub.c
View file @
0981604c
...
@@ -3,9 +3,10 @@
...
@@ -3,9 +3,10 @@
*****************************************************************************
*****************************************************************************
* Copyright (C) 2003 ANEVIA
* Copyright (C) 2003 ANEVIA
* Copyright (C) 2003 VideoLAN
* Copyright (C) 2003 VideoLAN
* $Id: dvbsub.c,v 1.
5 2003/11/24 00:39:01
fenrir Exp $
* $Id: dvbsub.c,v 1.
6 2003/11/24 02:35:50
fenrir Exp $
*
*
* Authors: Damien LUCAS <damien.lucas@anevia.com>
* Authors: Damien LUCAS <damien.lucas@anevia.com>
* Laurent Aimar <fenrir@via.ecp.fr>
*
*
* This program is free software; you can redistribute it and/or modify
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* it under the terms of the GNU General Public License as published by
...
@@ -185,6 +186,10 @@ typedef struct
...
@@ -185,6 +186,10 @@ typedef struct
typedef
struct
typedef
struct
{
{
int
i_id
;
mtime_t
i_pts
;
dvbsub_clut_t
*
p_clut
[
0xff
];
dvbsub_clut_t
*
p_clut
[
0xff
];
dvbsub_page_t
*
p_page
;
dvbsub_page_t
*
p_page
;
dvbsub_object_t
*
p_objects
;
dvbsub_object_t
*
p_objects
;
...
@@ -202,9 +207,10 @@ struct subpicture_sys_t
...
@@ -202,9 +207,10 @@ struct subpicture_sys_t
struct
decoder_sys_t
struct
decoder_sys_t
{
{
vout_thread_t
*
p_vout
;
vout_thread_t
*
p_vout
;
mtime_t
i_pts
;
bs_t
bs
;
bs_t
bs
;
dvbsub_all_t
dvbsub
;
};
};
...
@@ -238,36 +244,10 @@ static void Decode ( decoder_t *, block_t ** );
...
@@ -238,36 +244,10 @@ static void Decode ( decoder_t *, block_t ** );
static
vout_thread_t
*
FindVout
(
decoder_t
*
);
static
vout_thread_t
*
FindVout
(
decoder_t
*
);
static
void
RenderI42x
(
vout_thread_t
*
,
picture_t
*
,
const
subpicture_t
*
,
static
int
dvbsub_init
(
dvbsub_all_t
*
,
int
);
vlc_bool_t
);
static
void
dvbsub_decode_segment
(
dvbsub_all_t
*
p_dvbsub
,
bs_t
*
s
);
static
void
RenderYUY2
(
vout_thread_t
*
,
picture_t
*
,
const
subpicture_t
*
,
static
void
dvbsub_render
(
dvbsub_all_t
*
,
vout_thread_t
*
);
vlc_bool_t
);
static
void
dvbsub_clean
(
dvbsub_all_t
*
);
static
void
dvbsub_clut_add_entry
(
dvbsub_clut_t
*
clut
,
uint8_t
type
,
uint8_t
id
,
uint8_t
y
,
uint8_t
cr
,
uint8_t
cb
,
uint8_t
t
);
static
void
dvbsub_add_objectdef_to_region
(
dvbsub_objectdef_t
*
p_obj
,
dvbsub_region_t
*
p_region
);
static
dvbsub_image_t
*
dvbsub_parse_pdata
(
dvbsub_thread_t
*
,
uint16_t
);
static
uint16_t
dvbsub_count0x11
(
dvbsub_thread_t
*
p_spudec
,
uint16_t
*
p
,
dvbsub_image_t
*
p_image
);
static
void
dvbsub_decode_segment
(
dvbsub_thread_t
*
,
dvbsub_all_t
*
);
static
void
dvbsub_decode_page_composition
(
dvbsub_thread_t
*
,
dvbsub_all_t
*
);
static
void
dvbsub_decode_region_composition
(
dvbsub_thread_t
*
,
dvbsub_all_t
*
);
static
void
dvbsub_decode_object
(
dvbsub_thread_t
*
,
dvbsub_all_t
*
);
static
vlc_bool_t
dvbsub_check_page
(
dvbsub_all_t
*
);
static
void
dvbsub_render
(
dvbsub_thread_t
*
p_spudec
,
dvbsub_all_t
*
);
static
int
dvbsub_parse
(
dvbsub_thread_t
*
p_spudec
,
dvbsub_all_t
*
dvbsub
);
static
void
dvbsub_decode_clut
(
dvbsub_thread_t
*
,
dvbsub_all_t
*
);
static
void
dvbsub_stop_display
(
dvbsub_thread_t
*
p_dec
,
dvbsub_all_t
*
dvbsub
);
static
void
free_image
(
dvbsub_image_t
*
p_i
);
static
void
free_object
(
dvbsub_object_t
*
p_o
);
static
void
free_regions
(
dvbsub_region_t
*
p_r
,
uint8_t
nb
);
static
void
free_objects
(
dvbsub_object_t
*
p_o
);
static
void
free_clut
(
dvbsub_clut_t
*
p_c
);
static
void
free_page
(
dvbsub_page_t
*
p_p
);
static
void
free_all
(
dvbsub_all_t
*
p_a
);
/*****************************************************************************
/*****************************************************************************
...
@@ -286,11 +266,12 @@ static int Open( vlc_object_t *p_this )
...
@@ -286,11 +266,12 @@ static int Open( vlc_object_t *p_this )
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
p_dec
->
pf_decode_sub
s
=
Decode
;
p_dec
->
pf_decode_sub
=
Decode
;
p_sys
=
p_dec
->
p_sys
=
malloc
(
sizeof
(
decoder_sys_t
)
);
p_sys
=
p_dec
->
p_sys
=
malloc
(
sizeof
(
decoder_sys_t
)
);
p_sys
->
p_vout
=
NULL
;
p_sys
->
p_vout
=
NULL
;
p_sys
->
i_pts
=
0
;
dvbsub_init
(
&
p_sys
->
dvbsub
,
p_dec
->
fmt_in
.
subs
.
dvb
.
i_id
);
es_format_Init
(
&
p_dec
->
fmt_out
,
SPU_ES
,
VLC_FOURCC
(
'd'
,
'v'
,
'b'
,
's'
)
);
es_format_Init
(
&
p_dec
->
fmt_out
,
SPU_ES
,
VLC_FOURCC
(
'd'
,
'v'
,
'b'
,
's'
)
);
...
@@ -313,86 +294,73 @@ static void Close( vlc_object_t *p_this )
...
@@ -313,86 +294,73 @@ static void Close( vlc_object_t *p_this )
{
{
p_subpic
=
&
p_sys
->
p_vout
->
p_subpicture
[
i_subpic
];
p_subpic
=
&
p_sys
->
p_vout
->
p_subpicture
[
i_subpic
];
if
(
p_subpic
!=
NULL
&&
if
(
p_subpic
!=
NULL
&&
(
(
p_subpic
->
i_status
==
RESERVED_SUBPICTURE
)
(
(
p_subpic
->
i_status
==
RESERVED_SUBPICTURE
)
||
||
(
p_subpic
->
i_status
==
READY_SUBPICTURE
)
)
)
(
p_subpic
->
i_status
==
READY_SUBPICTURE
)
)
)
{
{
vout_DestroySubPicture
(
p_sys
->
p_vout
,
p_subpic
);
vout_DestroySubPicture
(
p_sys
->
p_vout
,
p_subpic
);
}
}
}
}
}
}
trox_call
();
dvbsub_clean
(
&
p_sys
->
dvbsub
);
free
(
p_sys
);
}
}
/*****************************************************************************
/*****************************************************************************
*
RunDecoder: this function is called just after the thread is created
*
Decode:
*****************************************************************************/
*****************************************************************************/
static
int
RunDecoder
(
decoder_fifo_t
*
p_fifo
)
static
void
Decode
(
decoder_t
*
p_dec
,
block_t
**
pp_block
)
{
{
dvbsub_thread_t
*
p_dvbsubdec
;
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
// vout_thread_t * p_vout_backup = NULL;
block_t
*
p_block
;
dvbsub_all_t
dvbsub
;
unsigned
int
k
;
if
(
pp_block
==
NULL
||
*
pp_block
==
NULL
)
/* Allocate the memory needed to store the thread's structure */
{
p_dvbsubdec
=
(
dvbsub_thread_t
*
)
trox_malloc
(
sizeof
(
dvbsub_thread_t
)
);
return
;
if
(
p_dvbsubdec
==
NULL
)
}
{
p_block
=
*
pp_block
;
msg_Err
(
p_fifo
,
"out of memory"
);
*
pp_block
=
NULL
;
DecoderError
(
p_fifo
);
return
(
-
1
);
p_sys
->
dvbsub
.
i_pts
=
p_block
->
i_pts
;
}
if
(
p_sys
->
dvbsub
.
i_pts
<=
0
)
/*
{
* Initialize the thread properties
msg_Warn
(
p_dec
,
"non dated subtitle"
);
*/
block_Release
(
p_block
);
p_dvbsubdec
->
p_vout
=
NULL
;
return
;
p_dvbsubdec
->
p_fifo
=
p_fifo
;
}
/*
* Initialize thread and free configuration
if
(
(
p_sys
->
p_vout
=
FindVout
(
p_dec
)
)
)
*/
{
p_dvbsubdec
->
p_fifo
->
b_error
=
InitThread
(
p_dvbsubdec
);
int
i_data_identifier
;
dvbsub
.
p_page
=
NULL
;
int
i_subtitle_stream_id
;
dvbsub
.
p_objects
=
NULL
;
int
i_end_data_marker
;
for
(
k
=
0
;
k
<
0xff
;
k
++
)
dvbsub
.
p_clut
[
k
]
=
NULL
;
for
(
k
=
0
;
k
<
16
;
k
++
)
dvbsub
.
p_spu
[
k
]
=
NULL
;
bs_init
(
&
p_sys
->
bs
,
p_block
->
p_buffer
,
p_block
->
i_buffer
);
/*
i_data_identifier
=
bs_read
(
&
p_sys
->
bs
,
8
);
* Main loop - it is not executed if an error occured during
i_subtitle_stream_id
=
bs_read
(
&
p_sys
->
bs
,
8
);
* initialization
*/
for
(
;;
)
while
(
(
!
p_dvbsubdec
->
p_fifo
->
b_die
)
&&
(
!
p_dvbsubdec
->
p_fifo
->
b_error
)
)
{
{
if
(
bs_show
(
&
p_sys
->
bs
,
8
)
!=
0x0f
)
dvbsub_parse
(
p_dvbsubdec
,
&
dvbsub
);
{
p_dvbsubdec
->
p_vout
=
FindVout
(
p_dvbsubdec
);
break
;
if
(
p_dvbsubdec
->
p_vout
)
}
{
dvbsub_decode_segment
(
&
p_sys
->
dvbsub
,
&
p_sys
->
bs
);
// Check if the page is to be displayed
}
if
(
dvbsub_check_page
(
&
dvbsub
))
i_end_data_marker
=
bs_read
(
&
p_sys
->
bs
,
8
);
{
dvbsub_render
(
p_dvbsubdec
,
&
dvbsub
);
/* Check if the page is to be displayed */
}
if
(
p_sys
->
dvbsub
.
p_page
&&
p_sys
->
dvbsub
.
p_objects
)
vlc_object_release
(
p_dvbsubdec
->
p_vout
);
{
}
dvbsub_render
(
&
p_sys
->
dvbsub
,
p_sys
->
p_vout
);
}
}
// Free all structures
//dvbsub.p_objects=NULL;
vlc_object_release
(
p_sys
->
p_vout
);
//for(k=0; k<16; k++)
}
// if(dvbsub.p_spu[k] != NULL)
// dvbsub.p_spu[k]->p_sys->b_obsolete = 1;
block_Release
(
p_block
);
/*
* Error loop
*/
if
(
p_dvbsubdec
->
p_fifo
->
b_error
)
{
DecoderError
(
p_dvbsubdec
->
p_fifo
);
/* End of thread */
EndThread
(
p_dvbsubdec
,
&
dvbsub
);
return
-
1
;
}
/* End of thread */
EndThread
(
p_dvbsubdec
,
&
dvbsub
);
free_all
(
&
dvbsub
);
return
0
;
}
}
/* following functions are local */
/* following functions are local */
...
@@ -418,416 +386,414 @@ static vout_thread_t *FindVout( decoder_t *p_dec )
...
@@ -418,416 +386,414 @@ static vout_thread_t *FindVout( decoder_t *p_dec )
}
}
}
}
/*****************************************************************************
* EndThread: thread destruction
static
int
dvbsub_init
(
dvbsub_all_t
*
p_dvbsub
,
int
i_id
)
*****************************************************************************
* This function is called when the thread ends after a sucessful
* initialization.
*****************************************************************************/
static
void
EndThread
(
dvbsub_thread_t
*
p_dvbsubdec
,
dvbsub_all_t
*
p_dvbsub
)
{
{
if
(
p_dvbsubdec
->
p_vout
!=
NULL
int
i
;
&&
p_dvbsubdec
->
p_vout
->
p_subpicture
!=
NULL
)
{
memset
(
p_dvbsub
,
0
,
sizeof
(
dvbsub_all_t
)
);
subpicture_t
*
p_subpic
;
int
i_subpic
;
p_dvbsub
->
i_pts
=
0
;
for
(
i_subpic
=
0
;
i_subpic
<
VOUT_MAX_SUBPICTURES
;
i_subpic
++
)
p_dvbsub
->
i_id
=
i_id
;
{
p_dvbsub
->
p_page
=
NULL
;
p_subpic
=
&
p_dvbsubdec
->
p_vout
->
p_subpicture
[
i_subpic
];
p_dvbsub
->
p_objects
=
NULL
;
if
(
p_subpic
!=
NULL
&&
for
(
i
=
0
;
i
<
255
;
i
++
)
(
(
p_subpic
->
i_status
==
RESERVED_SUBPICTURE
)
||
(
p_subpic
->
i_status
==
READY_SUBPICTURE
)
)
)
{
{
vout_DestroySubPicture
(
p_dvbsubdec
->
p_vout
,
p_subpic
);
p_dvbsub
->
p_clut
[
i
]
=
NULL
;
}
}
}
for
(
i
=
0
;
i
<
16
;
i
++
)
{
p_dvbsub
->
p_spu
[
i
]
=
NULL
;
}
}
CloseBitstream
(
&
p_dvbsubdec
->
bit_stream
);
return
0
;
trox_free
(
p_dvbsubdec
);
trox_call
();
}
}
static
void
free_all
(
dvbsub_all_t
*
);
static
int
dvbsub_parse
(
dvbsub_thread_t
*
p_spudec
,
static
void
dvbsub_clean
(
dvbsub_all_t
*
p_dvbsub
)
dvbsub_all_t
*
dvbsub
)
{
{
unsigned
int
data_identifier
;
free_all
(
p_dvbsub
);
unsigned
int
subtitle_stream_id
;
trox_call
()
;
unsigned
int
nextbits
;
uint32_t
end_data_marker
;
/* Re-align the buffer on an 8-bit boundary */
RealignBits
(
&
p_spudec
->
bit_stream
);
data_identifier
=
GetBits
(
&
p_spudec
->
bit_stream
,
8
);
subtitle_stream_id
=
GetBits
(
&
p_spudec
->
bit_stream
,
8
);
nextbits
=
ShowBits
(
&
p_spudec
->
bit_stream
,
8
);
while
(
nextbits
==
0x0f
)
{
dvbsub_decode_segment
(
p_spudec
,
dvbsub
);
nextbits
=
ShowBits
(
&
p_spudec
->
bit_stream
,
8
);
}
end_data_marker
=
GetBits
(
&
p_spudec
->
bit_stream
,
8
);
return
0
;
}
}
static
void
dvbsub_decode_clut
(
dvbsub_all_t
*
p_dvbsub
,
bs_t
*
s
);
static
void
dvbsub_decode_page_composition
(
dvbsub_all_t
*
p_dvbsub
,
bs_t
*
s
);
static
void
dvbsub_decode_region_composition
(
dvbsub_all_t
*
p_dvbsub
,
bs_t
*
s
);
static
void
dvbsub_stop_display
(
dvbsub_all_t
*
p_dvbsub
);
static
void
dvbsub_decode_object
(
dvbsub_all_t
*
p_dvbsub
,
bs_t
*
s
);
static
void
free_page
(
dvbsub_page_t
*
p_p
);
static
void
dvbsub_decode_segment
(
dvbsub_thread_t
*
p_spudec
,
static
void
dvbsub_decode_segment
(
dvbsub_all_t
*
p_dvbspu
,
bs_t
*
s
)
dvbsub_all_t
*
dvbsub
)
{
{
unsigned
int
sync_byte
;
int
i_type
;
unsigned
int
segment_type
;
int
i_page_id
;
uint16_t
page_id
;
int
i_size
;
uint16_t
segment_length
;
int
k
;
/* sync_byte */
sync_byte
=
GetBits
(
&
p_spudec
->
bit_stream
,
8
);
bs_skip
(
s
,
8
);
segment_type
=
GetBits
(
&
p_spudec
->
bit_stream
,
8
);
page_id
=
GetBits
(
&
p_spudec
->
bit_stream
,
16
);
/* segment type */
segment_length
=
ShowBits
(
&
p_spudec
->
bit_stream
,
16
);
i_type
=
bs_read
(
s
,
8
);
if
(
page_id
!=
((
dvb_spuinfo_t
*
)
p_spudec
->
p_fifo
->
p_spuinfo
)
->
i_id
)
{
/* page id */
//TODO should use GetChunk
i_page_id
=
bs_read
(
s
,
16
);
for
(
k
=
0
;
k
<
segment_length
+
2
;
k
++
)
GetBits
(
&
p_spudec
->
bit_stream
,
8
);
/* segment size */
i_size
=
bs_show
(
s
,
16
);
if
(
i_page_id
!=
p_dvbspu
->
i_id
)
{
bs_skip
(
s
,
8
*
(
2
+
i_size
)
);
return
;
return
;
}
}
switch
(
segment_type
)
switch
(
i_type
)
{
{
case
DVBSUB_ST_CLUT_DEFINITION
:
case
DVBSUB_ST_CLUT_DEFINITION
:
dvbsub_decode_clut
(
p_spudec
,
dvbsub
);
dvbsub_decode_clut
(
p_dvbspu
,
s
);
break
;
break
;
case
DVBSUB_ST_PAGE_COMPOSITION
:
case
DVBSUB_ST_PAGE_COMPOSITION
:
dvbsub_decode_page_composition
(
p_spudec
,
dvbsub
);
dvbsub_decode_page_composition
(
p_dvbspu
,
s
);
break
;
break
;
case
DVBSUB_ST_REGION_COMPOSITION
:
case
DVBSUB_ST_REGION_COMPOSITION
:
dvbsub_decode_region_composition
(
p_spudec
,
dvbsub
);
dvbsub_decode_region_composition
(
p_dvbspu
,
s
);
break
;
break
;
case
DVBSUB_ST_OBJECT_DATA
:
case
DVBSUB_ST_OBJECT_DATA
:
dvbsub_decode_object
(
p_spudec
,
dvbsub
);
dvbsub_decode_object
(
p_dvbspu
,
s
);
break
;
break
;
case
DVBSUB_ST_ENDOFDISPLAY
:
case
DVBSUB_ST_ENDOFDISPLAY
:
dvbsub_stop_display
(
p_spudec
,
dvbsub
);
dvbsub_stop_display
(
p_dvbspu
);
break
;
break
;
case
DVBSUB_ST_STUFFING
:
case
DVBSUB_ST_STUFFING
:
default:
default:
fprintf
(
stderr
,
"*** DVBSUB - Unsupported segment type ! (%04x)
\n
"
,
fprintf
(
stderr
,
"*** DVBSUB - Unsupported segment type ! (%04x)"
,
segment_type
);
i_type
);
GetBits
(
&
p_spudec
->
bit_stream
,
16
);
bs_skip
(
s
,
8
*
(
2
+
i_size
)
);
for
(
k
=
0
;
k
<
segment_length
;
k
++
)
GetBits
(
&
p_spudec
->
bit_stream
,
8
);
break
;
break
;
}
}
return
;
}
static
void
dvbsub_decode_page_composition
(
dvbsub_thread_t
*
p_spudec
,
dvbsub_all_t
*
dvbsub
)
{
unsigned
int
i_version_number
;
unsigned
int
i_state
;
unsigned
int
i_segment_length
;
uint8_t
i_timeout
;
unsigned
int
k
;
i_segment_length
=
GetBits
(
&
p_spudec
->
bit_stream
,
16
);
//A page is composed by one or more region:
i_timeout
=
GetBits
(
&
p_spudec
->
bit_stream
,
8
);
i_version_number
=
GetBits
(
&
p_spudec
->
bit_stream
,
4
);
i_state
=
GetBits
(
&
p_spudec
->
bit_stream
,
2
);
// TODO We assume it is a new page (i_state)
if
(
dvbsub
->
p_page
)
free_page
(
dvbsub
->
p_page
);
GetBits
(
&
p_spudec
->
bit_stream
,
2
);
/* Reserved */
//Allocate a new page
dvbsub
->
p_page
=
trox_malloc
(
sizeof
(
dvbsub_page_t
));
dvbsub
->
p_page
->
i_timeout
=
i_timeout
;
// Number of regions:
dvbsub
->
p_page
->
i_regions_number
=
(
i_segment_length
-
2
)
/
6
;
/* Special workaround for CAVENA encoders
* a page with no regions is sent instead of a 0x80 packet (End Of Display) */
if
(
dvbsub
->
p_page
->
i_regions_number
==
0
)
{
dvbsub_stop_display
(
p_spudec
,
dvbsub
);
}
/* /Special workaround */
dvbsub
->
p_page
->
regions
=
trox_malloc
(
dvbsub
->
p_page
->
i_regions_number
*
sizeof
(
dvbsub_region_t
));
for
(
k
=
0
;
k
<
dvbsub
->
p_page
->
i_regions_number
;
k
++
)
{
dvbsub
->
p_page
->
regions
[
k
].
i_id
=
GetBits
(
&
p_spudec
->
bit_stream
,
8
);
GetBits
(
&
p_spudec
->
bit_stream
,
8
);
/* Reserved */
dvbsub
->
p_page
->
regions
[
k
].
i_x
=
GetBits
(
&
p_spudec
->
bit_stream
,
16
);
dvbsub
->
p_page
->
regions
[
k
].
i_y
=
GetBits
(
&
p_spudec
->
bit_stream
,
16
);
dvbsub
->
p_page
->
regions
[
k
].
p_object
=
NULL
;
}
}
}
static
void
dvbsub_stop_display
(
dvbsub_all_t
*
p_dvbsub
)
static
void
dvbsub_decode_region_composition
(
dvbsub_thread_t
*
p_spudec
,
dvbsub_all_t
*
dvbsub
)
{
{
unsigned
int
i_segment_length
;
int
i
;
unsigned
int
i_processed_length
;
unsigned
int
i_region_id
;
dvbsub_region_t
*
p_region
;
unsigned
int
k
;
p_region
=
NULL
;
i_segment_length
=
GetBits
(
&
p_spudec
->
bit_stream
,
16
);
// Get region id:
i_region_id
=
GetBits
(
&
p_spudec
->
bit_stream
,
8
);
for
(
k
=
0
;
k
<
dvbsub
->
p_page
->
i_regions_number
;
k
++
)
{
if
(
dvbsub
->
p_page
->
regions
[
k
].
i_id
==
i_region_id
)
p_region
=
&
(
dvbsub
->
p_page
->
regions
[
k
]);
}
if
(
p_region
==
NULL
)
{
// TODO
// The region has never been declared before
// Internal error
fprintf
(
stderr
,
"Decoding of undeclared region N/A...
\n
"
);
return
;
}
// Skip version number and fill flag
if
(
ShowBits
(
&
p_spudec
->
bit_stream
,
4
)
==
p_region
->
i_version_number
)
{
fprintf
(
stderr
,
"Skipping already known region N/A ...
\n
"
);
// TODO Skip the right number of bits
}
// Region attributes
p_region
->
i_version_number
=
GetBits
(
&
p_spudec
->
bit_stream
,
4
);
p_region
->
b_fill
=
GetBits
(
&
p_spudec
->
bit_stream
,
1
);
GetBits
(
&
p_spudec
->
bit_stream
,
3
);
/* Reserved */
p_region
->
i_width
=
GetBits
(
&
p_spudec
->
bit_stream
,
16
);
p_region
->
i_height
=
GetBits
(
&
p_spudec
->
bit_stream
,
16
);
p_region
->
i_level_comp
=
GetBits
(
&
p_spudec
->
bit_stream
,
3
);
p_region
->
i_depth
=
GetBits
(
&
p_spudec
->
bit_stream
,
3
);
GetBits
(
&
p_spudec
->
bit_stream
,
2
);
/* Reserved */
p_region
->
i_clut
=
GetBits
(
&
p_spudec
->
bit_stream
,
8
);
p_region
->
i_8bp_code
=
GetBits
(
&
p_spudec
->
bit_stream
,
8
);
p_region
->
i_4bp_code
=
GetBits
(
&
p_spudec
->
bit_stream
,
4
);
p_region
->
i_2bp_code
=
GetBits
(
&
p_spudec
->
bit_stream
,
2
);
GetBits
(
&
p_spudec
->
bit_stream
,
2
);
/* Reserved */
// List of objects in the region:
// We already skipped 10 bytes
i_processed_length
=
10
;
while
(
i_processed_length
<
i_segment_length
)
{
// We create a new object
dvbsub_objectdef_t
*
p_obj
;
p_obj
=
trox_malloc
(
sizeof
(
dvbsub_objectdef_t
));
// We parse object properties
p_obj
->
i_id
=
GetBits
(
&
p_spudec
->
bit_stream
,
16
);
p_obj
->
i_type
=
GetBits
(
&
p_spudec
->
bit_stream
,
2
);
p_obj
->
i_provider
=
GetBits
(
&
p_spudec
->
bit_stream
,
2
);
p_obj
->
i_xoffset
=
GetBits
(
&
p_spudec
->
bit_stream
,
12
);
GetBits
(
&
p_spudec
->
bit_stream
,
4
);
/* Reserved */
p_obj
->
i_yoffset
=
GetBits
(
&
p_spudec
->
bit_stream
,
12
);
i_processed_length
+=
6
;
if
(
p_obj
->
i_type
==
DVBSUB_OT_BASIC_CHAR
||
p_obj
->
i_type
==
DVBSUB_OT_COMPOSITE_STRING
)
{
p_obj
->
i_fg_pc
=
GetBits
(
&
p_spudec
->
bit_stream
,
8
);
p_obj
->
i_bg_pc
=
GetBits
(
&
p_spudec
->
bit_stream
,
8
);
i_processed_length
+=
2
;
}
p_obj
->
p_next
=
NULL
;
dvbsub_add_objectdef_to_region
(
p_obj
,
p_region
);
}
}
static
void
dvbsub_decode_object
(
dvbsub_thread_t
*
p_spudec
,
for
(
i
=
0
;
p_dvbsub
->
p_spu
[
i
]
!=
NULL
;
i
++
)
dvbsub_all_t
*
dvbsub
)
{
dvbsub_object_t
*
p_obj
;
dvbsub_object_t
*
p_o
;
uint16_t
i_segment_length
;
uint16_t
i_topfield_length
;
uint16_t
i_bottomfield_length
;
// Memory Allocation
p_obj
=
trox_malloc
(
sizeof
(
dvbsub_object_t
)
);
p_obj
->
p_next
=
NULL
;
i_segment_length
=
GetBits
(
&
p_spudec
->
bit_stream
,
16
);
p_obj
->
i_id
=
GetBits
(
&
p_spudec
->
bit_stream
,
16
);
p_obj
->
i_version_number
=
GetBits
(
&
p_spudec
->
bit_stream
,
4
);
// TODO Check we don't already have this object / this version
p_obj
->
i_coding_method
=
GetBits
(
&
p_spudec
->
bit_stream
,
2
);
p_obj
->
b_non_modify_color
=
GetBits
(
&
p_spudec
->
bit_stream
,
1
);
GetBits
(
&
p_spudec
->
bit_stream
,
1
);
/* Reserved */
if
(
p_obj
->
i_coding_method
==
0x00
)
{
i_topfield_length
=
GetBits
(
&
p_spudec
->
bit_stream
,
16
);
i_bottomfield_length
=
GetBits
(
&
p_spudec
->
bit_stream
,
16
);
p_obj
->
topfield
=
dvbsub_parse_pdata
(
p_spudec
,
i_topfield_length
);
p_obj
->
bottomfield
=
dvbsub_parse_pdata
(
p_spudec
,
i_bottomfield_length
);
}
else
{
{
GetBits
(
&
p_spudec
->
bit_stream
,
(
i_segment_length
-
3
)
*
8
);
p_dvbsub
->
p_spu
[
i
]
->
i_stop
=
p_dvbsub
->
i_pts
;
//TODO
// DVB subtitling as characters
}
}
// Add this object to the list of the page
p_o
=
dvbsub
->
p_objects
;
dvbsub
->
p_objects
=
p_obj
;
p_obj
->
p_next
=
p_o
;
return
;
}
}
static
void
dvbsub_stop_display
(
dvbsub_thread_t
*
p_dec
,
static
void
dvbsub_decode_clut
(
dvbsub_all_t
*
p_dvbsub
,
bs_t
*
s
)
dvbsub_all_t
*
dvbsub
)
{
unsigned
int
j
;
for
(
j
=
0
;
dvbsub
->
p_spu
[
j
]
!=
NULL
;
j
++
)
dvbsub
->
p_spu
[
j
]
->
i_stop
=
p_dec
->
bit_stream
.
p_pes
->
i_pts
;
return
;
}
static
void
dvbsub_decode_clut
(
dvbsub_thread_t
*
p_dec
,
dvbsub_all_t
*
dvbsub
)
{
{
uint16_t
i_segment_length
;
uint16_t
i_segment_length
;
uint16_t
i_processed_length
;
uint16_t
i_processed_length
;
uint8_t
i_entry_id
;
uint8_t
i_entry_type
;
dvbsub_clut_t
*
clut
;
dvbsub_clut_t
*
clut
;
uint8_t
i_clut_id
;
uint8_t
i_clut_id
;
uint8_t
i_version_number
;
uint8_t
i_version_number
;
uint8_t
y
;
uint8_t
cr
;
i_segment_length
=
bs_read
(
s
,
16
);
uint8_t
cb
;
i_clut_id
=
bs_read
(
s
,
8
);
uint8_t
t
;
i_version_number
=
bs_read
(
s
,
4
);
i_segment_length
=
GetBits
(
&
p_dec
->
bit_stream
,
16
);
i_clut_id
=
GetBits
(
&
p_dec
->
bit_stream
,
8
);
i_version_number
=
GetBits
(
&
p_dec
->
bit_stream
,
4
);
// Check that this id doesn't not already exist
// Check that this id doesn't not already exist
// with the same version number
// with the same version number
// And allocate memory if necessary
// And allocate memory if necessary
if
(
dvbsub
->
p_clut
[
i_clut_id
]
!=
NULL
)
if
(
p_
dvbsub
->
p_clut
[
i_clut_id
]
!=
NULL
)
{
{
if
(
dvbsub
->
p_clut
[
i_clut_id
]
->
i_version_number
==
i_version_number
)
if
(
p_
dvbsub
->
p_clut
[
i_clut_id
]
->
i_version_number
==
i_version_number
)
{
{
//TODO skip the right number of bits
//TODO skip the right number of bits
return
;
return
;
}
}
else
else
{
{
memset
(
dvbsub
->
p_clut
[
i_clut_id
],
0
,
sizeof
(
dvbsub_clut_t
)
);
memset
(
p_dvbsub
->
p_clut
[
i_clut_id
],
0
,
sizeof
(
dvbsub_clut_t
)
);
}
}
}
}
else
else
{
{
dvbsub
->
p_clut
[
i_clut_id
]
=
trox_malloc
(
sizeof
(
dvbsub_clut_t
)
);
p_dvbsub
->
p_clut
[
i_clut_id
]
=
trox_malloc
(
sizeof
(
dvbsub_clut_t
)
);
}
}
clut
=
dvbsub
->
p_clut
[
i_clut_id
];
clut
=
p_dvbsub
->
p_clut
[
i_clut_id
];
/* We don't have this version of the CLUT:
/* We don't have this version of the CLUT:
* Parse it */
* Parse it */
clut
->
i_version_number
=
i_version_number
;
clut
->
i_version_number
=
i_version_number
;
GetBits
(
&
p_dec
->
bit_stream
,
4
);
/* Reserved bits */
bs_skip
(
s
,
4
);
/* Reserved bits */
i_processed_length
=
2
;
i_processed_length
=
2
;
while
(
i_processed_length
<
i_segment_length
)
while
(
i_processed_length
<
i_segment_length
)
{
{
i_entry_id
=
GetBits
(
&
p_dec
->
bit_stream
,
8
);
uint8_t
y
,
cb
,
cr
,
t
;
i_entry_type
=
GetBits
(
&
p_dec
->
bit_stream
,
3
);
uint8_t
i_id
;
GetBits
(
&
p_dec
->
bit_stream
,
4
);
uint8_t
i_type
;
if
(
GetBits
(
&
p_dec
->
bit_stream
,
1
)
==
0x01
)
{
i_id
=
bs_read
(
s
,
8
);
y
=
GetBits
(
&
p_dec
->
bit_stream
,
8
);
i_type
=
bs_read
(
s
,
3
);
cr
=
GetBits
(
&
p_dec
->
bit_stream
,
8
);
cb
=
GetBits
(
&
p_dec
->
bit_stream
,
8
);
bs_skip
(
s
,
4
);
t
=
GetBits
(
&
p_dec
->
bit_stream
,
8
);
if
(
bs_read
(
s
,
1
)
)
{
y
=
bs_read
(
s
,
8
);
cr
=
bs_read
(
s
,
8
);
cb
=
bs_read
(
s
,
8
);
t
=
bs_read
(
s
,
8
);
i_processed_length
+=
6
;
i_processed_length
+=
6
;
}
}
else
else
{
{
y
=
GetBits
(
&
p_dec
->
bit_stream
,
6
);
y
=
bs_read
(
s
,
6
);
cr
=
GetBits
(
&
p_dec
->
bit_stream
,
4
);
cr
=
bs_read
(
s
,
4
);
cb
=
GetBits
(
&
p_dec
->
bit_stream
,
4
);
cb
=
bs_read
(
s
,
4
);
t
=
GetBits
(
&
p_dec
->
bit_stream
,
2
);
t
=
bs_read
(
s
,
2
);
i_processed_length
+=
4
;
i_processed_length
+=
4
;
}
}
dvbsub_clut_add_entry
(
clut
,
i_entry_type
,
i_entry_id
,
y
,
cr
,
cb
,
t
);
}
}
static
void
dvbsub_clut_add_entry
(
dvbsub_clut_t
*
clut
,
uint8_t
type
,
uint8_t
id
,
uint8_t
y
,
uint8_t
cr
,
uint8_t
cb
,
uint8_t
t
)
{
/* According to EN 300-743 section 7.2.3 note 1, type should
/* According to EN 300-743 section 7.2.3 note 1, type should
* not have more than 1 bit set to one
* not have more than 1 bit set to one
But, some strams don't respect this note. */
But, some strams don't respect this note. */
if
(
type
&
0x04
)
if
(
i_type
&
0x04
)
{
{
clut
->
c_2b
[
id
].
Y
=
y
;
clut
->
c_2b
[
i_
id
].
Y
=
y
;
clut
->
c_2b
[
id
].
Cr
=
cr
;
clut
->
c_2b
[
i_
id
].
Cr
=
cr
;
clut
->
c_2b
[
id
].
Cb
=
cb
;
clut
->
c_2b
[
i_
id
].
Cb
=
cb
;
clut
->
c_2b
[
id
].
T
=
t
;
clut
->
c_2b
[
i_
id
].
T
=
t
;
}
}
if
(
type
&
0x02
)
if
(
i_type
&
0x02
)
{
{
clut
->
c_4b
[
id
].
Y
=
y
;
clut
->
c_4b
[
i_
id
].
Y
=
y
;
clut
->
c_4b
[
id
].
Cr
=
cr
;
clut
->
c_4b
[
i_
id
].
Cr
=
cr
;
clut
->
c_4b
[
id
].
Cb
=
cb
;
clut
->
c_4b
[
i_
id
].
Cb
=
cb
;
clut
->
c_4b
[
id
].
T
=
t
;
clut
->
c_4b
[
i_
id
].
T
=
t
;
}
}
if
(
type
&
0x01
)
if
(
i_
type
&
0x01
)
{
{
clut
->
c_8b
[
id
].
Y
=
y
;
clut
->
c_8b
[
i_id
].
Y
=
y
;
clut
->
c_8b
[
id
].
Cr
=
cr
;
clut
->
c_8b
[
i_id
].
Cr
=
cr
;
clut
->
c_8b
[
id
].
Cb
=
cb
;
clut
->
c_8b
[
i_id
].
Cb
=
cb
;
clut
->
c_8b
[
id
].
T
=
t
;
clut
->
c_8b
[
i_id
].
T
=
t
;
}
}
}
static
void
dvbsub_decode_page_composition
(
dvbsub_all_t
*
p_dvbsub
,
bs_t
*
s
)
{
unsigned
int
i_version_number
;
unsigned
int
i_state
;
unsigned
int
i_segment_length
;
uint8_t
i_timeout
;
unsigned
int
i
;
i_segment_length
=
bs_read
(
s
,
16
);
/* A page is composed by one or more region: */
i_timeout
=
bs_read
(
s
,
8
);
i_version_number
=
bs_read
(
s
,
4
);
i_state
=
bs_read
(
s
,
2
);
/* TODO We assume it is a new page (i_state) */
if
(
p_dvbsub
->
p_page
)
free_page
(
p_dvbsub
->
p_page
);
bs_skip
(
s
,
2
);
/* Reserved */
/* Allocate a new page */
p_dvbsub
->
p_page
=
trox_malloc
(
sizeof
(
dvbsub_page_t
)
);
p_dvbsub
->
p_page
->
i_timeout
=
i_timeout
;
/* Number of regions: */
p_dvbsub
->
p_page
->
i_regions_number
=
(
i_segment_length
-
2
)
/
6
;
/* Special workaround for CAVENA encoders
* a page with no regions is sent instead of a 0x80 packet (End Of Display) */
if
(
p_dvbsub
->
p_page
->
i_regions_number
==
0
)
{
dvbsub_stop_display
(
p_dvbsub
);
}
/* /Special workaround */
p_dvbsub
->
p_page
->
regions
=
trox_malloc
(
p_dvbsub
->
p_page
->
i_regions_number
*
sizeof
(
dvbsub_region_t
));
for
(
i
=
0
;
i
<
p_dvbsub
->
p_page
->
i_regions_number
;
i
++
)
{
p_dvbsub
->
p_page
->
regions
[
i
].
i_id
=
bs_read
(
s
,
8
);
bs_skip
(
s
,
8
);
/* Reserved */
p_dvbsub
->
p_page
->
regions
[
i
].
i_x
=
bs_read
(
s
,
16
);
p_dvbsub
->
p_page
->
regions
[
i
].
i_y
=
bs_read
(
s
,
16
);
p_dvbsub
->
p_page
->
regions
[
i
].
p_object
=
NULL
;
}
}
return
;
}
}
static
void
dvbsub_add_objectdef_to_region
(
dvbsub_objectdef_t
*
p_obj
,
static
void
dvbsub_decode_region_composition
(
dvbsub_all_t
*
p_dvbsub
,
bs_t
*
s
)
dvbsub_region_t
*
p_region
)
{
{
dvbsub_objectdef_t
*
p_o
=
p_region
->
p_object
;
dvbsub_region_t
*
p_region
=
NULL
;
// Seek to the last non null element
unsigned
int
i_segment_length
;
if
(
p_o
!=
NULL
)
unsigned
int
i_processed_length
;
unsigned
int
i_region_id
;
unsigned
int
i
;
i_segment_length
=
bs_read
(
s
,
16
);
/* Get region id: */
i_region_id
=
bs_read
(
s
,
8
);
for
(
i
=
0
;
i
<
p_dvbsub
->
p_page
->
i_regions_number
;
i
++
)
{
if
(
p_dvbsub
->
p_page
->
regions
[
i
].
i_id
==
i_region_id
)
{
{
for
(;
p_o
->
p_next
!=
NULL
;
p_o
=
p_o
->
p_next
);
p_region
=
&
(
p_dvbsub
->
p_page
->
regions
[
i
]);
}
}
if
(
p_region
==
NULL
)
{
/* TODO
* The region has never been declared before
* Internal error */
fprintf
(
stderr
,
"Decoding of undeclared region N/A...
\n
"
);
return
;
}
/* Skip version number and fill flag */
if
(
bs_show
(
s
,
4
)
==
p_region
->
i_version_number
)
{
fprintf
(
stderr
,
"Skipping already known region N/A ...
\n
"
);
/* TODO Skip the right number of bits */
}
/* Region attributes */
p_region
->
i_version_number
=
bs_read
(
s
,
4
);
p_region
->
b_fill
=
bs_read
(
s
,
1
);
bs_skip
(
s
,
3
);
/* Reserved */
p_region
->
i_width
=
bs_read
(
s
,
16
);
p_region
->
i_height
=
bs_read
(
s
,
16
);
p_region
->
i_level_comp
=
bs_read
(
s
,
3
);
p_region
->
i_depth
=
bs_read
(
s
,
3
);
bs_skip
(
s
,
2
);
/* Reserved */
p_region
->
i_clut
=
bs_read
(
s
,
8
);
p_region
->
i_8bp_code
=
bs_read
(
s
,
8
);
p_region
->
i_4bp_code
=
bs_read
(
s
,
4
);
p_region
->
i_2bp_code
=
bs_read
(
s
,
2
);
bs_skip
(
s
,
2
);
/* Reserved */
/* List of objects in the region: */
/* We already skipped 10 bytes */
i_processed_length
=
10
;
while
(
i_processed_length
<
i_segment_length
)
{
/* We create a new object */
dvbsub_objectdef_t
*
p_obj
=
trox_malloc
(
sizeof
(
dvbsub_objectdef_t
));
/* We parse object properties */
p_obj
->
p_next
=
NULL
;
p_obj
->
i_id
=
bs_read
(
s
,
16
);
p_obj
->
i_type
=
bs_read
(
s
,
2
);
p_obj
->
i_provider
=
bs_read
(
s
,
2
);
p_obj
->
i_xoffset
=
bs_read
(
s
,
12
);
bs_skip
(
s
,
4
);
/* Reserved */
p_obj
->
i_yoffset
=
bs_read
(
s
,
12
);
i_processed_length
+=
6
;
if
(
p_obj
->
i_type
==
DVBSUB_OT_BASIC_CHAR
||
p_obj
->
i_type
==
DVBSUB_OT_COMPOSITE_STRING
)
{
p_obj
->
i_fg_pc
=
bs_read
(
s
,
8
);
p_obj
->
i_bg_pc
=
bs_read
(
s
,
8
);
i_processed_length
+=
2
;
}
/* we append it */
if
(
p_region
->
p_object
)
{
dvbsub_objectdef_t
*
p_o
;
for
(
p_o
=
p_region
->
p_object
;
;
p_o
=
p_o
->
p_next
)
{
if
(
p_o
->
p_next
==
NULL
)
{
break
;
}
}
p_o
->
p_next
=
p_obj
;
p_o
->
p_next
=
p_obj
;
p_o
->
p_next
->
p_next
=
NULL
;
}
}
else
else
{
{
p_region
->
p_object
=
p_obj
;
p_region
->
p_object
=
p_obj
;
p_region
->
p_object
->
p_next
=
NULL
;
}
}
return
;
}
}
}
static
dvbsub_image_t
*
dvbsub_parse_pdata
(
dvbsub_all_t
*
p_dvbsub
,
bs_t
*
s
,
uint16_t
length
);
static
uint16_t
dvbsub_count0x11
(
bs_t
*
s
,
uint16_t
*
p
,
dvbsub_image_t
*
p_image
);
static
dvbsub_image_t
*
dvbsub_parse_pdata
(
dvbsub_thread_t
*
p_spudec
,
static
void
dvbsub_decode_object
(
dvbsub_all_t
*
p_dvbsub
,
bs_t
*
s
)
uint16_t
length
)
{
dvbsub_object_t
*
p_obj
;
uint16_t
i_segment_length
;
/* Memory Allocation */
p_obj
=
trox_malloc
(
sizeof
(
dvbsub_object_t
)
);
p_obj
->
p_next
=
NULL
;
i_segment_length
=
bs_read
(
s
,
16
);
/* TODO Check we don't already have this object / this version */
p_obj
->
i_id
=
bs_read
(
s
,
16
);
p_obj
->
i_version_number
=
bs_read
(
s
,
4
);
p_obj
->
i_coding_method
=
bs_read
(
s
,
2
);
p_obj
->
b_non_modify_color
=
bs_read
(
s
,
1
);
bs_skip
(
s
,
1
);
/* Reserved */
if
(
p_obj
->
i_coding_method
==
0x00
)
{
uint16_t
i_topfield_length
;
uint16_t
i_bottomfield_length
;
i_topfield_length
=
bs_read
(
s
,
16
);
i_bottomfield_length
=
bs_read
(
s
,
16
);
p_obj
->
topfield
=
dvbsub_parse_pdata
(
p_dvbsub
,
s
,
i_topfield_length
);
p_obj
->
bottomfield
=
dvbsub_parse_pdata
(
p_dvbsub
,
s
,
i_bottomfield_length
);
}
else
{
bs_skip
(
s
,
(
i_segment_length
-
3
)
*
8
);
/*TODO
* DVB subtitling as characters */
}
/* Add this object to the list of the page */
p_obj
->
p_next
=
p_dvbsub
->
p_objects
;
p_dvbsub
->
p_objects
=
p_obj
;
}
static
dvbsub_image_t
*
dvbsub_parse_pdata
(
dvbsub_all_t
*
p_dvbsub
,
bs_t
*
s
,
uint16_t
length
)
{
{
dvbsub_image_t
*
p_image
;
dvbsub_image_t
*
p_image
;
uint16_t
i_processed_length
=
0
;
uint16_t
i_processed_length
=
0
;
uint16_t
i_lines
=
0
;
uint16_t
i_lines
=
0
;
uint16_t
i_cols_last
=
0
;
uint16_t
i_cols_last
=
0
;
p_image
=
trox_malloc
(
sizeof
(
dvbsub_image_t
)
);
p_image
=
trox_malloc
(
sizeof
(
dvbsub_image_t
)
);
p_image
->
p_last
=
NULL
;
p_image
->
p_last
=
NULL
;
memset
(
p_image
->
i_cols
,
0
,
576
*
sizeof
(
uint16_t
));
memset
(
p_image
->
i_cols
,
0
,
576
*
sizeof
(
uint16_t
));
/* Let's parse it a first time to determine the size of the buffer */
/* Let's parse it a first time to determine the size of the buffer */
while
(
i_processed_length
<
length
)
while
(
i_processed_length
<
length
)
{
{
switch
(
GetBits
(
&
p_spudec
->
bit_stream
,
8
)
)
switch
(
bs_read
(
s
,
8
)
)
{
{
case
0x10
:
case
0x10
:
fprintf
(
stderr
,
"0x10 N/A
\n
"
);
fprintf
(
stderr
,
"0x10 N/A
\n
"
);
break
;
break
;
case
0x11
:
case
0x11
:
i_processed_length
+=
1
+
dvbsub_count0x11
(
p_spudec
,
i_processed_length
+=
&
(
p_image
->
i_cols
[
i_lines
]),
1
+
dvbsub_count0x11
(
s
,
&
(
p_image
->
i_cols
[
i_lines
]),
p_image
);
p_image
);
break
;
break
;
case
0x12
:
case
0x12
:
fprintf
(
stderr
,
"0x12 N/A
\n
"
);
fprintf
(
stderr
,
"0x12 N/A
\n
"
);
...
@@ -847,17 +813,22 @@ static dvbsub_image_t* dvbsub_parse_pdata ( dvbsub_thread_t* p_spudec,
...
@@ -847,17 +813,22 @@ static dvbsub_image_t* dvbsub_parse_pdata ( dvbsub_thread_t* p_spudec,
break
;
break
;
}
}
}
}
p_image
->
i_rows
=
i_lines
;
p_image
->
i_rows
=
i_lines
;
p_image
->
i_cols
[
i_lines
]
=
i_cols_last
;
p_image
->
i_cols
[
i_lines
]
=
i_cols_last
;
// Check word-aligned bits
if
(
ShowBits
(
&
p_spudec
->
bit_stream
,
8
)
==
0x00
)
/* Check word-aligned bits */
GetBits
(
&
p_spudec
->
bit_stream
,
8
);
if
(
bs_show
(
s
,
8
)
==
0x00
)
{
bs_skip
(
s
,
8
);
}
return
p_image
;
return
p_image
;
}
}
static
void
add_rle_code
(
dvbsub_image_t
*
p
,
uint16_t
num
,
uint8_t
color
)
static
void
add_rle_code
(
dvbsub_image_t
*
p
,
uint16_t
num
,
uint8_t
color
)
{
{
if
(
p
->
p_last
!=
NULL
)
if
(
p
->
p_last
!=
NULL
)
{
{
...
@@ -872,97 +843,90 @@ static void add_rle_code (dvbsub_image_t* p, uint16_t num, uint8_t color)
...
@@ -872,97 +843,90 @@ static void add_rle_code (dvbsub_image_t* p, uint16_t num, uint8_t color)
p
->
p_last
->
i_num
=
num
;
p
->
p_last
->
i_num
=
num
;
p
->
p_last
->
i_color_code
=
color
;
p
->
p_last
->
i_color_code
=
color
;
p
->
p_last
->
p_next
=
NULL
;
p
->
p_last
->
p_next
=
NULL
;
return
;
}
}
static
uint16_t
dvbsub_count0x11
(
dvbsub_thread_t
*
p_spudec
,
uint16_t
*
p
,
dvbsub_image_t
*
p_image
)
static
uint16_t
dvbsub_count0x11
(
bs_t
*
s
,
uint16_t
*
p
,
dvbsub_image_t
*
p_image
)
{
{
uint16_t
i_processed
=
0
;
uint16_t
i_processed
=
0
;
vlc_bool_t
b_stop
=
0
;
vlc_bool_t
b_stop
=
0
;
uint16_t
i_count
=
0
;
uint16_t
i_count
=
0
;
uint8_t
i_color
=
0
;
uint8_t
i_color
=
0
;
while
(
!
b_stop
)
while
(
!
b_stop
)
{
{
if
(
(
i_color
=
GetBits
(
&
p_spudec
->
bit_stream
,
4
))
!=
0x00
)
if
(
(
i_color
=
bs_read
(
s
,
4
))
!=
0x00
)
{
{
(
*
p
)
++
;
(
*
p
)
++
;
i_processed
+=
4
;
i_processed
+=
4
;
// 1 pixel of color code '0000'
add_rle_code
(
p_image
,
1
,
i_color
);
/* 1 pixel of color code '0000' */
add_rle_code
(
p_image
,
1
,
i_color
);
}
}
else
else
{
{
if
(
GetBits
(
&
p_spudec
->
bit_stream
,
1
)
==
0x00
)
// Switch1
if
(
bs_read
(
s
,
1
)
==
0x00
)
// Switch1
{
{
if
(
ShowBits
(
&
p_spudec
->
bit_stream
,
3
)
!=
0x00
)
if
(
bs_show
(
s
,
3
)
!=
0x00
)
{
{
i_count
=
2
+
GetBits
(
&
p_spudec
->
bit_stream
,
3
);
i_count
=
2
+
bs_read
(
s
,
3
);
(
*
p
)
+=
i_count
;
(
*
p
)
+=
i_count
;
add_rle_code
(
p_image
,
i_count
,
0x00
);
add_rle_code
(
p_image
,
i_count
,
0x00
);
}
}
else
else
{
{
GetBits
(
&
p_spudec
->
bit_stream
,
3
);
bs_skip
(
s
,
3
);
b_stop
=
1
;
b_stop
=
1
;
}
}
i_processed
+=
8
;
i_processed
+=
8
;
}
}
else
else
{
{
if
(
GetBits
(
&
p_spudec
->
bit_stream
,
1
)
==
0x00
)
//Switch2
if
(
bs_read
(
s
,
1
)
==
0x00
)
//Switch2
{
{
i_count
=
4
+
GetBits
(
&
p_spudec
->
bit_stream
,
2
);
i_count
=
4
+
bs_read
(
s
,
2
);
i_color
=
GetBits
(
&
p_spudec
->
bit_stream
,
4
);
i_color
=
bs_read
(
s
,
4
);
(
*
p
)
+=
i_count
;
(
*
p
)
+=
i_count
;
i_processed
+=
12
;
i_processed
+=
12
;
add_rle_code
(
p_image
,
i_count
,
i_color
);
add_rle_code
(
p_image
,
i_count
,
i_color
);
}
}
else
else
{
{
switch
(
GetBits
(
&
p_spudec
->
bit_stream
,
2
)
)
//Switch3
switch
(
bs_read
(
s
,
2
)
)
//Switch3
{
{
case
0x0
:
case
0x0
:
(
*
p
)
++
;
(
*
p
)
++
;
i_processed
+=
8
;
i_processed
+=
8
;
add_rle_code
(
p_image
,
1
,
0x00
);
add_rle_code
(
p_image
,
1
,
0x00
);
break
;
break
;
case
0x1
:
case
0x1
:
(
*
p
)
+=
2
;
(
*
p
)
+=
2
;
i_processed
+=
8
;
i_processed
+=
8
;
add_rle_code
(
p_image
,
2
,
0x00
);
add_rle_code
(
p_image
,
2
,
0x00
);
break
;
break
;
case
0x2
:
case
0x2
:
i_count
=
9
+
GetBits
(
&
p_spudec
->
bit_stream
,
4
);
i_count
=
9
+
bs_read
(
s
,
4
);
i_color
=
GetBits
(
&
p_spudec
->
bit_stream
,
4
);
i_color
=
bs_read
(
s
,
4
);
(
*
p
)
+=
i_count
;
(
*
p
)
+=
i_count
;
i_processed
+=
16
;
i_processed
+=
16
;
add_rle_code
(
p_image
,
i_count
,
i_color
);
add_rle_code
(
p_image
,
i_count
,
i_color
);
break
;
break
;
case
0x3
:
case
0x3
:
i_count
=
25
+
GetBits
(
&
p_spudec
->
bit_stream
,
8
);
i_count
=
25
+
bs_read
(
s
,
8
);
i_color
=
GetBits
(
&
p_spudec
->
bit_stream
,
4
);
i_color
=
bs_read
(
s
,
4
);
(
*
p
)
+=
i_count
;
(
*
p
)
+=
i_count
;
i_processed
+=
20
;
i_processed
+=
20
;
add_rle_code
(
p_image
,
i_count
,
i_color
);
add_rle_code
(
p_image
,
i_count
,
i_color
);
break
;
break
;
}
}
}
}
}
}
}
}
}
}
RealignBits
(
&
p_spudec
->
bit_stream
);
return
(
i_processed
+
7
)
/
8
;
}
static
vlc_bool_t
dvbsub_check_page
(
dvbsub_all_t
*
dvbsub
)
bs_align
(
s
);
{
if
(
dvbsub
->
p_page
!=
NULL
)
return
(
i_processed
+
7
)
/
8
;
{
if
(
dvbsub
->
p_objects
!=
NULL
)
return
VLC_TRUE
;
}
return
VLC_FALSE
;
}
}
static
void
free_image
(
dvbsub_image_t
*
p_i
)
static
void
free_image
(
dvbsub_image_t
*
p_i
)
...
@@ -1021,7 +985,10 @@ static void free_objects (dvbsub_object_t* p_o)
...
@@ -1021,7 +985,10 @@ static void free_objects (dvbsub_object_t* p_o)
}
}
}
}
static
void
free_clut
(
dvbsub_clut_t
*
p_c
)
{
trox_free
(
p_c
);
}
static
void
free_clut
(
dvbsub_clut_t
*
p_c
)
{
trox_free
(
p_c
);
}
static
void
free_page
(
dvbsub_page_t
*
p_p
)
static
void
free_page
(
dvbsub_page_t
*
p_p
)
{
{
...
@@ -1050,53 +1017,10 @@ static void free_all ( dvbsub_all_t* p_a )
...
@@ -1050,53 +1017,10 @@ static void free_all ( dvbsub_all_t* p_a )
for
(
i
=
0
;
i
<
16
;
i
++
)
if
(
p_a
->
p_spu
[
i
])
free_spu
(
p_a
->
p_spu
[
i
]
);
for
(
i
=
0
;
i
<
16
;
i
++
)
if
(
p_a
->
p_spu
[
i
])
free_spu
(
p_a
->
p_spu
[
i
]
);
if
(
p_a
->
p_page
)
free_page
(
p_a
->
p_page
);
if
(
p_a
->
p_page
)
free_page
(
p_a
->
p_page
);
free_objects
(
p_a
->
p_objects
);
free_objects
(
p_a
->
p_objects
);
}
}
static
void
dvbsub_RenderDVBSUB
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
,
static
void
RenderYUY2
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
,
const
subpicture_t
*
p_spu
,
vlc_bool_t
b_crop
)
const
subpicture_t
*
p_spu
)
{
// If we have changed the language on the fly,
if
(
!
p_spu
->
p_sys
)
return
;
if
(
p_spu
->
p_sys
->
b_obsolete
)
return
;
switch
(
p_vout
->
output
.
i_chroma
)
{
/* I420 target, no scaling */
case
VLC_FOURCC
(
'I'
,
'4'
,
'2'
,
'2'
):
case
VLC_FOURCC
(
'I'
,
'4'
,
'2'
,
'0'
):
case
VLC_FOURCC
(
'I'
,
'Y'
,
'U'
,
'V'
):
case
VLC_FOURCC
(
'Y'
,
'V'
,
'1'
,
'2'
):
// As long as we just use Y info, I422 and YV12 are just equivalent
// to I420. Remember to change it the day we'll take into account
// U and V info.
RenderI42x
(
p_vout
,
p_pic
,
p_spu
,
VLC_FALSE
);
break
;
/* RV16 target, scaling */
case
VLC_FOURCC
(
'R'
,
'V'
,
'1'
,
'6'
):
fprintf
(
stderr
,
"Not implemented chroma ! RV16)
\n
"
);
//RenderRV16( p_vout, p_pic, p_spu, p_spu->p_sys->b_crop );
break
;
/* RV32 target, scaling */
case
VLC_FOURCC
(
'R'
,
'V'
,
'2'
,
'4'
):
case
VLC_FOURCC
(
'R'
,
'V'
,
'3'
,
'2'
):
fprintf
(
stderr
,
"Not implemented chroma ! RV32
\n
"
);
//RenderRV32( p_vout, p_pic, p_spu, p_spu->p_sys->b_crop );
break
;
/* NVidia overlay, no scaling */
case
VLC_FOURCC
(
'Y'
,
'U'
,
'Y'
,
'2'
):
RenderYUY2
(
p_vout
,
p_pic
,
p_spu
,
VLC_FALSE
);
break
;
default:
msg_Err
(
p_vout
,
"unknown chroma, can't render SPU"
);
break
;
}
}
static
void
RenderYUY2
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
,
const
subpicture_t
*
p_spu
,
vlc_bool_t
b_crop
)
{
{
/* Common variables */
/* Common variables */
uint8_t
*
p_desty
;
uint8_t
*
p_desty
;
...
@@ -1162,8 +1086,8 @@ static void RenderYUY2 ( vout_thread_t *p_vout, picture_t *p_pic,
...
@@ -1162,8 +1086,8 @@ static void RenderYUY2 ( vout_thread_t *p_vout, picture_t *p_pic,
}
}
static
void
RenderI42x
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
,
static
void
RenderI42x
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
,
const
subpicture_t
*
p_spu
,
vlc_bool_t
b_crop
)
const
subpicture_t
*
p_spu
)
{
{
/* Common variables */
/* Common variables */
uint8_t
*
p_desty
;
uint8_t
*
p_desty
;
...
@@ -1224,12 +1148,59 @@ static void RenderI42x ( vout_thread_t *p_vout, picture_t *p_pic,
...
@@ -1224,12 +1148,59 @@ static void RenderI42x ( vout_thread_t *p_vout, picture_t *p_pic,
}
}
}
}
static
void
dvbsub_RenderDVBSUB
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
,
const
subpicture_t
*
p_spu
)
{
/* If we have changed the language on the fly */
if
(
p_spu
->
p_sys
==
NULL
||
p_spu
->
p_sys
->
b_obsolete
)
{
return
;
}
switch
(
p_vout
->
output
.
i_chroma
)
{
/* I420 target, no scaling */
case
VLC_FOURCC
(
'I'
,
'4'
,
'2'
,
'2'
):
case
VLC_FOURCC
(
'I'
,
'4'
,
'2'
,
'0'
):
case
VLC_FOURCC
(
'I'
,
'Y'
,
'U'
,
'V'
):
case
VLC_FOURCC
(
'Y'
,
'V'
,
'1'
,
'2'
):
/* As long as we just use Y info, I422 and YV12 are just equivalent
* to I420. Remember to change it the day we'll take into account
* U and V info. */
RenderI42x
(
p_vout
,
p_pic
,
p_spu
);
break
;
/* RV16 target, scaling */
case
VLC_FOURCC
(
'R'
,
'V'
,
'1'
,
'6'
):
fprintf
(
stderr
,
"Not implemented chroma ! RV16)
\n
"
);
/* RenderRV16( p_vout, p_pic, p_spu ); */
break
;
/* RV32 target, scaling */
case
VLC_FOURCC
(
'R'
,
'V'
,
'2'
,
'4'
):
case
VLC_FOURCC
(
'R'
,
'V'
,
'3'
,
'2'
):
fprintf
(
stderr
,
"Not implemented chroma ! RV32
\n
"
);
/* RenderRV32( p_vout, p_pic, p_spu ); */
break
;
/* NVidia overlay, no scaling */
case
VLC_FOURCC
(
'Y'
,
'U'
,
'Y'
,
'2'
):
RenderYUY2
(
p_vout
,
p_pic
,
p_spu
);
break
;
default:
msg_Err
(
p_vout
,
"unknown chroma, can't render SPU"
);
break
;
}
}
static
void
dvbsub_Destroy
(
subpicture_t
*
p_spu
)
static
void
dvbsub_Destroy
(
subpicture_t
*
p_spu
)
{
{
free_spu
(
p_spu
);
free_spu
(
p_spu
);
}
}
static
void
dvbsub_render
(
dvbsub_
thread_t
*
p_dec
,
dvbsub_all_t
*
dvbsub
)
static
void
dvbsub_render
(
dvbsub_
all_t
*
dvbsub
,
vout_thread_t
*
p_vout
)
{
{
dvbsub_region_t
*
p_region
;
dvbsub_region_t
*
p_region
;
dvbsub_objectdef_t
*
p_objectdef
;
dvbsub_objectdef_t
*
p_objectdef
;
...
@@ -1240,14 +1211,14 @@ static void dvbsub_render( dvbsub_thread_t *p_dec, dvbsub_all_t* dvbsub)
...
@@ -1240,14 +1211,14 @@ static void dvbsub_render( dvbsub_thread_t *p_dec, dvbsub_all_t* dvbsub)
dvbsub_rle_t
*
p_c
;
dvbsub_rle_t
*
p_c
;
uint8_t
i
,
j
;
uint8_t
i
,
j
;
j
=
0
;
j
=
0
;
/* loop on regions */
/* loop on regions */
for
(
i
=
0
;
i
<
dvbsub
->
p_page
->
i_regions_number
;
i
++
)
for
(
i
=
0
;
i
<
dvbsub
->
p_page
->
i_regions_number
;
i
++
)
{
{
p_region
=
&
(
dvbsub
->
p_page
->
regions
[
i
]);
p_region
=
&
(
dvbsub
->
p_page
->
regions
[
i
]);
/* loop on objects */
/* loop on objects */
for
(
p_objectdef
=
p_region
->
p_object
;
for
(
p_objectdef
=
p_region
->
p_object
;
p_objectdef
!=
NULL
;
p_objectdef
=
p_objectdef
->
p_next
)
p_objectdef
!=
NULL
;
p_objectdef
=
p_objectdef
->
p_next
)
{
{
/* Look for the right object */
/* Look for the right object */
p_object
=
dvbsub
->
p_objects
;
p_object
=
dvbsub
->
p_objects
;
...
@@ -1255,11 +1226,13 @@ static void dvbsub_render( dvbsub_thread_t *p_dec, dvbsub_all_t* dvbsub)
...
@@ -1255,11 +1226,13 @@ static void dvbsub_render( dvbsub_thread_t *p_dec, dvbsub_all_t* dvbsub)
{
{
p_object
=
p_object
->
p_next
;
p_object
=
p_object
->
p_next
;
}
}
if
(
p_object
==
NULL
)
if
(
p_object
==
NULL
)
{
{
fprintf
(
stderr
,
"Internal DvbSub decoder error
\n
"
);
fprintf
(
stderr
,
"Internal DvbSub decoder error
\n
"
);
return
;
return
;
}
}
/* Allocate the render structure */
/* Allocate the render structure */
p_render
=
trox_malloc
(
sizeof
(
dvbsub_render_t
));
p_render
=
trox_malloc
(
sizeof
(
dvbsub_render_t
));
p_render
->
i_x
=
p_region
->
i_x
+
p_objectdef
->
i_xoffset
;
p_render
->
i_x
=
p_region
->
i_x
+
p_objectdef
->
i_xoffset
;
...
@@ -1290,8 +1263,7 @@ static void dvbsub_render( dvbsub_thread_t *p_dec, dvbsub_all_t* dvbsub)
...
@@ -1290,8 +1263,7 @@ static void dvbsub_render( dvbsub_thread_t *p_dec, dvbsub_all_t* dvbsub)
/* Allocate the subpicture internal data. */
/* Allocate the subpicture internal data. */
dvbsub
->
p_spu
[
j
]
=
vout_CreateSubPicture
(
p_dec
->
p_vout
,
dvbsub
->
p_spu
[
j
]
=
vout_CreateSubPicture
(
p_vout
,
MEMORY_SUBPICTURE
);
MEMORY_SUBPICTURE
);
if
(
dvbsub
->
p_spu
[
j
]
==
NULL
)
if
(
dvbsub
->
p_spu
[
j
]
==
NULL
)
{
{
fprintf
(
stderr
,
"Unable to allocate memory ... skipping
\n
"
);
fprintf
(
stderr
,
"Unable to allocate memory ... skipping
\n
"
);
...
@@ -1303,7 +1275,7 @@ static void dvbsub_render( dvbsub_thread_t *p_dec, dvbsub_all_t* dvbsub)
...
@@ -1303,7 +1275,7 @@ static void dvbsub_render( dvbsub_thread_t *p_dec, dvbsub_all_t* dvbsub)
dvbsub
->
p_spu
[
j
]
->
p_sys
->
p_data
=
p_render
;
dvbsub
->
p_spu
[
j
]
->
p_sys
->
p_data
=
p_render
;
dvbsub
->
p_spu
[
j
]
->
p_sys
->
b_obsolete
=
0
;
dvbsub
->
p_spu
[
j
]
->
p_sys
->
b_obsolete
=
0
;
dvbsub
->
p_spu
[
j
]
->
pf_destroy
=
dvbsub_Destroy
;
dvbsub
->
p_spu
[
j
]
->
pf_destroy
=
dvbsub_Destroy
;
dvbsub
->
p_spu
[
j
]
->
i_start
=
p_dec
->
bit_stream
.
p_pes
->
i_pts
;
dvbsub
->
p_spu
[
j
]
->
i_start
=
dvbsub
->
i_pts
;
dvbsub
->
p_spu
[
j
]
->
i_stop
=
dvbsub
->
p_spu
[
j
]
->
i_start
+
dvbsub
->
p_page
->
i_timeout
*
1000000
;
dvbsub
->
p_spu
[
j
]
->
i_stop
=
dvbsub
->
p_spu
[
j
]
->
i_start
+
dvbsub
->
p_page
->
i_timeout
*
1000000
;
dvbsub
->
p_spu
[
j
]
->
b_ephemer
=
VLC_FALSE
;
dvbsub
->
p_spu
[
j
]
->
b_ephemer
=
VLC_FALSE
;
...
@@ -1320,8 +1292,10 @@ static void dvbsub_render( dvbsub_thread_t *p_dec, dvbsub_all_t* dvbsub)
...
@@ -1320,8 +1292,10 @@ static void dvbsub_render( dvbsub_thread_t *p_dec, dvbsub_all_t* dvbsub)
}
}
free_object
(
p_object_old
);
free_object
(
p_object_old
);
vout_DisplaySubPicture
(
p_dec
->
p_vout
,
dvbsub
->
p_spu
[
j
]
);
vout_DisplaySubPicture
(
p_vout
,
dvbsub
->
p_spu
[
j
]
);
j
++
;
j
++
;
}
}
}
}
}
}
src/input/input_dec.c
View file @
0981604c
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* input_dec.c: Functions for the management of decoders
* input_dec.c: Functions for the management of decoders
*****************************************************************************
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* Copyright (C) 1999-2001 VideoLAN
* $Id: input_dec.c,v 1.7
6 2003/11/24 00:39:02
fenrir Exp $
* $Id: input_dec.c,v 1.7
7 2003/11/24 02:35:50
fenrir Exp $
*
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Gildas Bazin <gbazin@netcourrier.com>
* Gildas Bazin <gbazin@netcourrier.com>
...
@@ -407,18 +407,26 @@ static decoder_t * CreateDecoder( input_thread_t * p_input,
...
@@ -407,18 +407,26 @@ static decoder_t * CreateDecoder( input_thread_t * p_input,
p_dec
->
fmt_in
.
video
.
i_width
=
p_bih
->
biWidth
;
p_dec
->
fmt_in
.
video
.
i_width
=
p_bih
->
biWidth
;
p_dec
->
fmt_in
.
video
.
i_height
=
p_bih
->
biHeight
;
p_dec
->
fmt_in
.
video
.
i_height
=
p_bih
->
biHeight
;
}
}
/* FIXME
/* FIXME
* - 1: beurk
* - 1: beurk
* - 2: I'm not sure there isn't any endian problem here ... */
* - 2: I'm not sure there isn't any endian problem here (spu)... */
if
(
p_es
->
i_cat
==
SPU_ES
&&
if
(
p_es
->
i_cat
==
SPU_ES
&&
p_es
->
p_demux_data
)
(
p_es
->
i_fourcc
==
VLC_FOURCC
(
's'
,
'p'
,
'u'
,
' '
)
||
{
if
(
(
p_es
->
i_fourcc
==
VLC_FOURCC
(
's'
,
'p'
,
'u'
,
' '
)
||
p_es
->
i_fourcc
==
VLC_FOURCC
(
's'
,
'p'
,
'u'
,
'b'
)
)
&&
p_es
->
i_fourcc
==
VLC_FOURCC
(
's'
,
'p'
,
'u'
,
'b'
)
)
&&
p_es
->
p_demux_data
&&
*
((
uint32_t
*
)
p_es
->
p_demux_data
)
==
0xBeef
)
*
((
uint32_t
*
)
p_es
->
p_demux_data
)
==
0xBeef
)
{
{
memcpy
(
p_dec
->
fmt_in
.
subs
.
spu
.
palette
,
memcpy
(
p_dec
->
fmt_in
.
subs
.
spu
.
palette
,
p_es
->
p_demux_data
,
17
*
4
);
p_es
->
p_demux_data
,
17
*
4
);
}
}
else
if
(
p_es
->
i_fourcc
==
VLC_FOURCC
(
'd'
,
'v'
,
'b'
,
's'
)
)
{
dvb_spuinfo_t
*
p_dvbs
=
(
dvb_spuinfo_t
*
)
p_es
->
p_demux_data
;
p_dec
->
fmt_in
.
subs
.
dvb
.
i_id
=
p_dvbs
->
i_id
;
}
}
p_dec
->
fmt_in
.
i_cat
=
p_es
->
i_cat
;
p_dec
->
fmt_in
.
i_cat
=
p_es
->
i_cat
;
p_dec
->
fmt_in
.
i_codec
=
p_es
->
i_fourcc
;
p_dec
->
fmt_in
.
i_codec
=
p_es
->
i_fourcc
;
...
@@ -464,8 +472,6 @@ static int DecoderThread( decoder_t * p_dec )
...
@@ -464,8 +472,6 @@ static int DecoderThread( decoder_t * p_dec )
/* The decoder's main loop */
/* The decoder's main loop */
while
(
!
p_dec
->
b_die
&&
!
p_dec
->
b_error
)
while
(
!
p_dec
->
b_die
&&
!
p_dec
->
b_error
)
{
{
int
i_size
;
if
(
(
p_block
=
block_FifoGet
(
p_dec
->
p_owner
->
p_fifo
)
)
==
NULL
)
if
(
(
p_block
=
block_FifoGet
(
p_dec
->
p_owner
->
p_fifo
)
)
==
NULL
)
{
{
p_dec
->
b_error
=
1
;
p_dec
->
b_error
=
1
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment