Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
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
Commits
82ca25cb
Commit
82ca25cb
authored
Nov 22, 2003
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* all: ported to new API.
-> i_rate isn't used for now : it will need to be fixed.
parent
1a80449a
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
306 additions
and
354 deletions
+306
-354
modules/codec/spudec/parse.c
modules/codec/spudec/parse.c
+100
-190
modules/codec/spudec/render.c
modules/codec/spudec/render.c
+1
-2
modules/codec/spudec/spudec.c
modules/codec/spudec/spudec.c
+187
-127
modules/codec/spudec/spudec.h
modules/codec/spudec/spudec.h
+18
-35
No files found.
modules/codec/spudec/parse.c
View file @
82ca25cb
...
@@ -2,15 +2,16 @@
...
@@ -2,15 +2,16 @@
* parse.c: SPU parser
* parse.c: SPU parser
*****************************************************************************
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
* Copyright (C) 2000-2001 VideoLAN
* $Id: parse.c,v 1.1
3 2003/07/29 22:25:40 gbazin
Exp $
* $Id: parse.c,v 1.1
4 2003/11/22 19:55:47 fenrir
Exp $
*
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Authors: Samuel Hocevar <sam@zoy.org>
* 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
* the Free Software Foundation; either version 2 of the License, or
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
...
@@ -25,19 +26,19 @@
...
@@ -25,19 +26,19 @@
* Preamble
* Preamble
*****************************************************************************/
*****************************************************************************/
#include <stdlib.h>
/* malloc(), free() */
#include <stdlib.h>
/* malloc(), free() */
#include <string.h>
/* memcpy(), memset() */
#include <vlc/vlc.h>
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include <vlc/vout.h>
#include <vlc/decoder.h>
#include <vlc/decoder.h>
#include <vlc/input.h>
#include "spudec.h"
#include "spudec.h"
/*****************************************************************************
/*****************************************************************************
* Local prototypes.
* Local prototypes.
*****************************************************************************/
*****************************************************************************/
static
int
ParseControlSeq
(
spudec_thread
_t
*
,
subpicture_t
*
);
static
int
ParseControlSeq
(
decoder
_t
*
,
subpicture_t
*
);
static
int
ParseRLE
(
spudec_thread_t
*
,
subpicture_t
*
,
uint8
_t
*
);
static
int
ParseRLE
(
decoder_t
*
,
subpicture
_t
*
);
static
void
DestroySPU
(
subpicture_t
*
);
static
void
DestroySPU
(
subpicture_t
*
);
...
@@ -61,62 +62,20 @@ static inline unsigned int AddNibble( unsigned int i_code,
...
@@ -61,62 +62,20 @@ static inline unsigned int AddNibble( unsigned int i_code,
}
}
}
}
/*****************************************************************************
* SyncPacket: get in sync with the stream
*****************************************************************************
* This function makes a few sanity checks and returns 0 if it looks like we
* are at the beginning of a subpicture packet.
*****************************************************************************/
int
E_
(
SyncPacket
)(
spudec_thread_t
*
p_spudec
)
{
/* Re-align the buffer on an 8-bit boundary */
RealignBits
(
&
p_spudec
->
bit_stream
);
/* The total SPU packet size, often bigger than a PS packet */
p_spudec
->
i_spu_size
=
GetBits
(
&
p_spudec
->
bit_stream
,
16
);
/* The RLE stuff size (remove 4 because we just read 32 bits) */
p_spudec
->
i_rle_size
=
ShowBits
(
&
p_spudec
->
bit_stream
,
16
)
-
4
;
/* If the values we got are a bit strange, skip packet */
if
(
!
p_spudec
->
i_spu_size
||
(
p_spudec
->
i_rle_size
>=
p_spudec
->
i_spu_size
)
)
{
return
VLC_EGENERIC
;
}
RemoveBits
(
&
p_spudec
->
bit_stream
,
16
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
/*****************************************************************************
* ParsePacket: parse an SPU packet and send it to the video output
* ParsePacket: parse an SPU packet and send it to the video output
*****************************************************************************
*****************************************************************************
* This function parses the SPU packet and, if valid, sends it to the
* This function parses the SPU packet and, if valid, sends it to the
* video output.
* video output.
*****************************************************************************/
*****************************************************************************/
void
E_
(
ParsePacket
)(
spudec_thread_t
*
p_spudec
)
void
E_
(
ParsePacket
)(
decoder_t
*
p_dec
)
{
{
subpicture_t
*
p_spu
;
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
uint8_t
*
p_src
;
unsigned
int
i_offset
;
mtime_t
i_pts
;
msg_Dbg
(
p_spudec
->
p_fifo
,
"trying to gather a 0x%.2x long subtitle"
,
subpicture_t
*
p_spu
;
p_spudec
->
i_spu_size
);
/* We cannot display a subpicture with no date */
NextPTS
(
&
p_spudec
->
bit_stream
,
&
i_pts
,
NULL
);
if
(
i_pts
==
0
)
{
msg_Warn
(
p_spudec
->
p_fifo
,
"subtitle without a date"
);
return
;
}
/* Allocate the subpicture internal data. */
/* Allocate the subpicture internal data. */
p_spu
=
vout_CreateSubPicture
(
p_spudec
->
p_vout
,
MEMORY_SUBPICTURE
);
p_spu
=
vout_CreateSubPicture
(
p_sys
->
p_vout
,
MEMORY_SUBPICTURE
);
if
(
p_spu
==
NULL
)
if
(
p_spu
==
NULL
)
{
{
return
;
return
;
...
@@ -126,17 +85,10 @@ void E_(ParsePacket)( spudec_thread_t *p_spudec )
...
@@ -126,17 +85,10 @@ void E_(ParsePacket)( spudec_thread_t *p_spudec )
* expand the RLE stuff so that we won't need to read nibbles later
* expand the RLE stuff so that we won't need to read nibbles later
* on. This will speed things up a lot. Plus, we'll only need to do
* on. This will speed things up a lot. Plus, we'll only need to do
* this stupid interlacing stuff once. */
* this stupid interlacing stuff once. */
p_spu
->
p_sys
=
malloc
(
sizeof
(
subpicture_sys_t
)
p_spu
->
p_sys
=
malloc
(
sizeof
(
subpicture_sys_t
)
+
4
*
p_sys
->
i_rle_size
);
+
p_spudec
->
i_rle_size
*
4
);
if
(
p_spu
->
p_sys
==
NULL
)
{
vout_DestroySubPicture
(
p_spudec
->
p_vout
,
p_spu
);
return
;
}
/* Fill the p_spu structure */
/* Fill the p_spu structure */
vlc_mutex_init
(
p_
spudec
->
p_fifo
,
&
p_spu
->
p_sys
->
lock
);
vlc_mutex_init
(
p_
dec
,
&
p_spu
->
p_sys
->
lock
);
p_spu
->
pf_render
=
E_
(
RenderSPU
);
p_spu
->
pf_render
=
E_
(
RenderSPU
);
p_spu
->
pf_destroy
=
DestroySPU
;
p_spu
->
pf_destroy
=
DestroySPU
;
...
@@ -151,10 +103,10 @@ void E_(ParsePacket)( spudec_thread_t *p_spudec )
...
@@ -151,10 +103,10 @@ void E_(ParsePacket)( spudec_thread_t *p_spudec )
p_spu
->
p_sys
->
b_crop
=
VLC_FALSE
;
p_spu
->
p_sys
->
b_crop
=
VLC_FALSE
;
/* Get display time now. If we do it later, we may miss the PTS. */
/* Get display time now. If we do it later, we may miss the PTS. */
p_spu
->
p_sys
->
i_pts
=
i_pts
;
p_spu
->
p_sys
->
i_pts
=
p_sys
->
i_pts
;
/* Attach to our input thread */
/* Attach to our input thread */
p_spu
->
p_sys
->
p_input
=
vlc_object_find
(
p_
spudec
->
p_fifo
,
p_spu
->
p_sys
->
p_input
=
vlc_object_find
(
p_
dec
,
VLC_OBJECT_INPUT
,
FIND_PARENT
);
VLC_OBJECT_INPUT
,
FIND_PARENT
);
if
(
p_spu
->
p_sys
->
p_input
)
if
(
p_spu
->
p_sys
->
p_input
)
{
{
...
@@ -173,70 +125,30 @@ void E_(ParsePacket)( spudec_thread_t *p_spudec )
...
@@ -173,70 +125,30 @@ void E_(ParsePacket)( spudec_thread_t *p_spudec )
}
}
}
}
/* Allocate the temporary buffer we will parse */
p_src
=
malloc
(
p_spudec
->
i_rle_size
);
if
(
p_src
==
NULL
)
{
msg_Err
(
p_spudec
->
p_fifo
,
"out of memory"
);
vout_DestroySubPicture
(
p_spudec
->
p_vout
,
p_spu
);
return
;
}
/* Get RLE data */
for
(
i_offset
=
0
;
i_offset
<
p_spudec
->
i_rle_size
;
i_offset
+=
SPU_CHUNK_SIZE
)
{
GetChunk
(
&
p_spudec
->
bit_stream
,
p_src
+
i_offset
,
(
i_offset
+
SPU_CHUNK_SIZE
<
p_spudec
->
i_rle_size
)
?
SPU_CHUNK_SIZE
:
p_spudec
->
i_rle_size
-
i_offset
);
/* Abort subtitle parsing if we were requested to stop */
if
(
p_spudec
->
p_fifo
->
b_die
)
{
free
(
p_src
);
vout_DestroySubPicture
(
p_spudec
->
p_vout
,
p_spu
);
return
;
}
}
#if 0
/* Dump the subtitle info */
intf_WarnHexDump( 5, p_spu->p_sys->p_data, p_spudec->i_rle_size );
#endif
/* Getting the control part */
/* Getting the control part */
if
(
ParseControlSeq
(
p_
spu
dec
,
p_spu
)
)
if
(
ParseControlSeq
(
p_dec
,
p_spu
)
)
{
{
/* There was a parse error, delete the subpicture */
/* There was a parse error, delete the subpicture */
free
(
p_src
);
vout_DestroySubPicture
(
p_sys
->
p_vout
,
p_spu
);
vout_DestroySubPicture
(
p_spudec
->
p_vout
,
p_spu
);
return
;
return
;
}
}
/* At this point, no more GetBit() command is needed, so we have all
/* We try to display it */
* the data we need to tell whether the subtitle is valid. Thus we
if
(
ParseRLE
(
p_dec
,
p_spu
)
)
* try to display it and we ignore b_die. */
if
(
ParseRLE
(
p_spudec
,
p_spu
,
p_src
)
)
{
{
/* There was a parse error, delete the subpicture */
/* There was a parse error, delete the subpicture */
free
(
p_src
);
vout_DestroySubPicture
(
p_sys
->
p_vout
,
p_spu
);
vout_DestroySubPicture
(
p_spudec
->
p_vout
,
p_spu
);
return
;
return
;
}
}
msg_Dbg
(
p_
spudec
->
p_fifo
,
"total size: 0x%x, RLE offsets: 0x%x 0x%x"
,
msg_Dbg
(
p_
dec
,
"total size: 0x%x, RLE offsets: 0x%x 0x%x"
,
p_s
pudec
->
i_spu_size
,
p_s
ys
->
i_spu_size
,
p_spu
->
p_sys
->
pi_offset
[
0
],
p_spu
->
p_sys
->
pi_offset
[
1
]
);
p_spu
->
p_sys
->
pi_offset
[
0
],
p_spu
->
p_sys
->
pi_offset
[
1
]
);
/* SPU is finished - we can ask the video output to display it */
/* SPU is finished - we can ask the video output to display it */
vout_DisplaySubPicture
(
p_s
pudec
->
p_vout
,
p_spu
);
vout_DisplaySubPicture
(
p_s
ys
->
p_vout
,
p_spu
);
/* TODO: do stuff! */
/* TODO: do stuff! */
/* Clean up */
free
(
p_src
);
}
}
/*****************************************************************************
/*****************************************************************************
...
@@ -246,11 +158,12 @@ void E_(ParsePacket)( spudec_thread_t *p_spudec )
...
@@ -246,11 +158,12 @@ void E_(ParsePacket)( spudec_thread_t *p_spudec )
* information, coordinates, and so on. For more information on the
* information, coordinates, and so on. For more information on the
* subtitles format, see http://sam.zoy.org/doc/dvd/subtitles/index.html
* subtitles format, see http://sam.zoy.org/doc/dvd/subtitles/index.html
*****************************************************************************/
*****************************************************************************/
static
int
ParseControlSeq
(
spudec_thread_t
*
p_spudec
,
static
int
ParseControlSeq
(
decoder_t
*
p_dec
,
subpicture_t
*
p_spu
)
subpicture_t
*
p_spu
)
{
{
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
/* Our current index in the SPU packet */
/* Our current index in the SPU packet */
unsigned
int
i_index
=
p_s
pudec
->
i_rle_size
+
4
;
unsigned
int
i_index
=
p_s
ys
->
i_rle_size
+
4
;
/* The next start-of-control-sequence index and the previous one */
/* The next start-of-control-sequence index and the previous one */
unsigned
int
i_next_seq
=
0
,
i_cur_seq
=
0
;
unsigned
int
i_next_seq
=
0
,
i_cur_seq
=
0
;
...
@@ -267,25 +180,35 @@ static int ParseControlSeq( spudec_thread_t *p_spudec,
...
@@ -267,25 +180,35 @@ static int ParseControlSeq( spudec_thread_t *p_spudec,
do
do
{
{
if
(
(
int
)
i_index
>=
p_sys
->
i_spu_size
+
1
)
{
/* sanity
* XXX only on test by loop as p_sys->buffer is bigger than needed
* to avoid checking at each access
*/
break
;
}
/* If we just read a command sequence, read the next one;
/* If we just read a command sequence, read the next one;
* otherwise, go on with the commands of the current sequence. */
* otherwise, go on with the commands of the current sequence. */
if
(
i_command
==
SPU_CMD_END
)
if
(
i_command
==
SPU_CMD_END
)
{
{
/* Get the control sequence date */
/* Get the control sequence date */
date
=
(
mtime_t
)
GetBits
(
&
p_spudec
->
bit_stream
,
16
)
*
11000
date
=
(
mtime_t
)
GetWBE
(
&
p_sys
->
buffer
[
i_index
]
)
*
11000
;
/* FIXME How to access i_rate
* p_spudec->bit_stream.p_pes->i_rate / DEFAULT_RATE;
* p_spudec->bit_stream.p_pes->i_rate / DEFAULT_RATE;
*/
/* Next offset */
/* Next offset */
i_cur_seq
=
i_index
;
i_cur_seq
=
i_index
;
i_next_seq
=
Get
Bits
(
&
p_spudec
->
bit_stream
,
16
);
i_next_seq
=
Get
WBE
(
&
p_sys
->
buffer
[
i_index
+
2
]
);
/* Skip what we just read */
/* Skip what we just read */
i_index
+=
4
;
i_index
+=
4
;
}
}
i_command
=
GetBits
(
&
p_spudec
->
bit_stream
,
8
);
i_command
=
p_sys
->
buffer
[
i_index
++
];
i_index
++
;
switch
(
i_command
)
switch
(
i_command
)
{
{
case
SPU_CMD_FORCE_DISPLAY
:
/* 00 (force displaying) */
case
SPU_CMD_FORCE_DISPLAY
:
/* 00 (force displaying) */
...
@@ -305,17 +228,23 @@ static int ParseControlSeq( spudec_thread_t *p_spudec,
...
@@ -305,17 +228,23 @@ static int ParseControlSeq( spudec_thread_t *p_spudec,
case
SPU_CMD_SET_PALETTE
:
case
SPU_CMD_SET_PALETTE
:
/* 03xxxx (palette) */
/* 03xxxx (palette) */
if
(
p_
spu
dec
->
p_fifo
->
p_demux_data
if
(
p_dec
->
p_fifo
->
p_demux_data
&&
*
(
int
*
)
p_
spu
dec
->
p_fifo
->
p_demux_data
==
0xBeeF
)
&&
*
(
int
*
)
p_dec
->
p_fifo
->
p_demux_data
==
0xBeeF
)
{
{
u
int32_t
i_color
;
u
nsigned
int
idx
[
4
]
;
p_spu
->
p_sys
->
b_palette
=
VLC_TRUE
;
p_spu
->
p_sys
->
b_palette
=
VLC_TRUE
;
idx
[
0
]
=
(
p_sys
->
buffer
[
i_index
+
0
]
>>
4
)
&
0x0f
;
idx
[
1
]
=
(
p_sys
->
buffer
[
i_index
+
0
])
&
0x0f
;
idx
[
2
]
=
(
p_sys
->
buffer
[
i_index
+
1
]
>>
4
)
&
0x0f
;
idx
[
3
]
=
(
p_sys
->
buffer
[
i_index
+
1
])
&
0x0f
;
for
(
i
=
0
;
i
<
4
;
i
++
)
for
(
i
=
0
;
i
<
4
;
i
++
)
{
{
i_color
=
((
uint32_t
*
)((
char
*
)
p_spudec
->
p_fifo
->
uint32_t
i_color
;
p_demux_data
+
sizeof
(
int
)))[
i_color
=
((
uint32_t
*
)((
char
*
)
p_dec
->
p_fifo
->
p_demux_data
+
GetBits
(
&
p_spudec
->
bit_stream
,
4
)
];
sizeof
(
int
)))[
idx
[
i
]
];
/* FIXME: this job should be done sooner */
/* FIXME: this job should be done sooner */
p_spu
->
p_sys
->
pi_yuv
[
3
-
i
][
0
]
=
(
i_color
>>
16
)
&
0xff
;
p_spu
->
p_sys
->
pi_yuv
[
3
-
i
][
0
]
=
(
i_color
>>
16
)
&
0xff
;
...
@@ -323,19 +252,15 @@ static int ParseControlSeq( spudec_thread_t *p_spudec,
...
@@ -323,19 +252,15 @@ static int ParseControlSeq( spudec_thread_t *p_spudec,
p_spu
->
p_sys
->
pi_yuv
[
3
-
i
][
2
]
=
(
i_color
>>
8
)
&
0xff
;
p_spu
->
p_sys
->
pi_yuv
[
3
-
i
][
2
]
=
(
i_color
>>
8
)
&
0xff
;
}
}
}
}
else
{
RemoveBits
(
&
p_spudec
->
bit_stream
,
16
);
}
i_index
+=
2
;
i_index
+=
2
;
break
;
break
;
case
SPU_CMD_SET_ALPHACHANNEL
:
/* 04xxxx (alpha channel) */
case
SPU_CMD_SET_ALPHACHANNEL
:
/* 04xxxx (alpha channel) */
pi_alpha
[
3
]
=
GetBits
(
&
p_spudec
->
bit_stream
,
4
)
;
pi_alpha
[
3
]
=
(
p_sys
->
buffer
[
i_index
+
0
]
>>
4
)
&
0x0f
;
pi_alpha
[
2
]
=
GetBits
(
&
p_spudec
->
bit_stream
,
4
)
;
pi_alpha
[
2
]
=
(
p_sys
->
buffer
[
i_index
+
0
])
&
0x0f
;
pi_alpha
[
1
]
=
GetBits
(
&
p_spudec
->
bit_stream
,
4
)
;
pi_alpha
[
1
]
=
(
p_sys
->
buffer
[
i_index
+
1
]
>>
4
)
&
0x0f
;
pi_alpha
[
0
]
=
GetBits
(
&
p_spudec
->
bit_stream
,
4
)
;
pi_alpha
[
0
]
=
(
p_sys
->
buffer
[
i_index
+
1
])
&
0x0f
;
/* Ignore blank alpha palette. Sometimes spurious blank
/* Ignore blank alpha palette. Sometimes spurious blank
* alpha palettes are present - dunno why. */
* alpha palettes are present - dunno why. */
...
@@ -348,31 +273,29 @@ static int ParseControlSeq( spudec_thread_t *p_spudec,
...
@@ -348,31 +273,29 @@ static int ParseControlSeq( spudec_thread_t *p_spudec,
}
}
else
else
{
{
msg_Warn
(
p_
spudec
->
p_fifo
,
"ignoring blank alpha palette"
);
msg_Warn
(
p_
dec
,
"ignoring blank alpha palette"
);
}
}
i_index
+=
2
;
i_index
+=
2
;
break
;
break
;
case
SPU_CMD_SET_COORDINATES
:
/* 05xxxyyyxxxyyy (coordinates) */
case
SPU_CMD_SET_COORDINATES
:
/* 05xxxyyyxxxyyy (coordinates) */
p_spu
->
i_x
=
GetBits
(
&
p_spudec
->
bit_stream
,
12
);
p_spu
->
i_x
=
(
p_sys
->
buffer
[
i_index
+
0
]
<<
4
)
|
p_spu
->
i_width
=
GetBits
(
&
p_spudec
->
bit_stream
,
12
)
((
p_sys
->
buffer
[
i_index
+
1
]
>>
4
)
&
0x0f
);
-
p_spu
->
i_x
+
1
;
p_spu
->
i_width
=
(((
p_sys
->
buffer
[
i_index
+
1
]
&
0x0f
)
<<
8
)
|
p_sys
->
buffer
[
i_index
+
2
])
-
p_spu
->
i_x
+
1
;
p_spu
->
i_y
=
GetBits
(
&
p_spudec
->
bit_stream
,
12
);
p_spu
->
i_y
=
(
p_sys
->
buffer
[
i_index
+
3
]
<<
4
)
|
p_spu
->
i_height
=
GetBits
(
&
p_spudec
->
bit_stream
,
12
)
((
p_sys
->
buffer
[
i_index
+
4
]
>>
4
)
&
0x0f
);
-
p_spu
->
i_y
+
1
;
p_spu
->
i_height
=
(((
p_sys
->
buffer
[
i_index
+
4
]
&
0x0f
)
<<
8
)
|
p_sys
->
buffer
[
i_index
+
5
])
-
p_spu
->
i_y
+
1
;
i_index
+=
6
;
i_index
+=
6
;
break
;
break
;
case
SPU_CMD_SET_OFFSETS
:
/* 06xxxxyyyy (byte offsets) */
case
SPU_CMD_SET_OFFSETS
:
/* 06xxxxyyyy (byte offsets) */
p_spu
->
p_sys
->
pi_offset
[
0
]
=
p_spu
->
p_sys
->
pi_offset
[
0
]
=
GetWBE
(
&
p_sys
->
buffer
[
i_index
+
0
])
-
4
;
GetBits
(
&
p_spudec
->
bit_stream
,
16
)
-
4
;
p_spu
->
p_sys
->
pi_offset
[
1
]
=
GetWBE
(
&
p_sys
->
buffer
[
i_index
+
2
])
-
4
;
p_spu
->
p_sys
->
pi_offset
[
1
]
=
GetBits
(
&
p_spudec
->
bit_stream
,
16
)
-
4
;
i_index
+=
4
;
i_index
+=
4
;
break
;
break
;
...
@@ -380,13 +303,12 @@ static int ParseControlSeq( spudec_thread_t *p_spudec,
...
@@ -380,13 +303,12 @@ static int ParseControlSeq( spudec_thread_t *p_spudec,
break
;
break
;
default:
/* xx (unknown command) */
default:
/* xx (unknown command) */
msg_Err
(
p_spudec
->
p_fifo
,
"unknown command 0x%.2x"
,
msg_Err
(
p_dec
,
"unknown command 0x%.2x"
,
i_command
);
i_command
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
/* We need to check for quit commands here */
/* We need to check for quit commands here */
if
(
p_
spudec
->
p_fifo
->
b_die
)
if
(
p_
dec
->
b_die
)
{
{
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
...
@@ -396,55 +318,41 @@ static int ParseControlSeq( spudec_thread_t *p_spudec,
...
@@ -396,55 +318,41 @@ static int ParseControlSeq( spudec_thread_t *p_spudec,
/* Check that the next sequence index matches the current one */
/* Check that the next sequence index matches the current one */
if
(
i_next_seq
!=
i_cur_seq
)
if
(
i_next_seq
!=
i_cur_seq
)
{
{
msg_Err
(
p_
spudec
->
p_fifo
,
"index mismatch (0x%.4x != 0x%.4x)"
,
msg_Err
(
p_
dec
,
"index mismatch (0x%.4x != 0x%.4x)"
,
i_next_seq
,
i_cur_seq
);
i_next_seq
,
i_cur_seq
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
if
(
i_index
>
p_spudec
->
i_spu_size
)
if
(
(
int
)
i_index
>
p_sys
->
i_spu_size
)
{
{
msg_Err
(
p_
spudec
->
p_fifo
,
"uh-oh, we went too far (0x%.4x > 0x%.4x)"
,
msg_Err
(
p_
dec
,
"uh-oh, we went too far (0x%.4x > 0x%.4x)"
,
i_index
,
p_spudec
->
i_spu_size
);
i_index
,
p_sys
->
i_spu_size
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
if
(
!
p_spu
->
i_start
)
if
(
!
p_spu
->
i_start
)
{
{
msg_Err
(
p_
spudec
->
p_fifo
,
"no `start display' command"
);
msg_Err
(
p_
dec
,
"no `start display' command"
);
}
}
if
(
p_spu
->
i_stop
<=
p_spu
->
i_start
&&
!
p_spu
->
b_ephemer
)
if
(
p_spu
->
i_stop
<=
p_spu
->
i_start
&&
!
p_spu
->
b_ephemer
)
{
{
/* This subtitle will live for 5 seconds or until the next subtitle */
/* This subtitle will live for 5 seconds or until the next subtitle */
p_spu
->
i_stop
=
p_spu
->
i_start
+
(
mtime_t
)
500
*
11000
p_spu
->
i_stop
=
p_spu
->
i_start
+
(
mtime_t
)
500
*
11000
;
/* FIXME how to access i_rate ?
* p_spudec->bit_stream.p_pes->i_rate / DEFAULT_RATE;
* p_spudec->bit_stream.p_pes->i_rate / DEFAULT_RATE;
*/
p_spu
->
b_ephemer
=
VLC_TRUE
;
p_spu
->
b_ephemer
=
VLC_TRUE
;
}
}
/* Get rid of padding bytes */
/* Get rid of padding bytes */
switch
(
p_spudec
->
i_spu_size
-
i_index
)
if
(
p_sys
->
i_spu_size
>
(
int
)
i_index
+
1
)
{
{
/* Zero or one padding byte, quite usual */
/* Zero or one padding byte, are quite usual
case
1
:
* More than one padding byte - this is very strange, but
RemoveBits
(
&
p_spudec
->
bit_stream
,
8
);
i_index
++
;
case
0
:
break
;
/* More than one padding byte - this is very strange, but
* we can deal with it */
* we can deal with it */
default:
msg_Warn
(
p_dec
,
"%i padding bytes, we usually get 0 or 1 of them"
,
msg_Warn
(
p_spudec
->
p_fifo
,
p_sys
->
i_spu_size
-
i_index
);
"%i padding bytes, we usually get 0 or 1 of them"
,
p_spudec
->
i_spu_size
-
i_index
);
while
(
i_index
<
p_spudec
->
i_spu_size
)
{
RemoveBits
(
&
p_spudec
->
bit_stream
,
8
);
i_index
++
;
}
break
;
}
}
/* Successfully parsed ! */
/* Successfully parsed ! */
...
@@ -458,9 +366,11 @@ static int ParseControlSeq( spudec_thread_t *p_spudec,
...
@@ -458,9 +366,11 @@ static int ParseControlSeq( spudec_thread_t *p_spudec,
* convenient structure for later decoding. For more information on the
* convenient structure for later decoding. For more information on the
* subtitles format, see http://sam.zoy.org/doc/dvd/subtitles/index.html
* subtitles format, see http://sam.zoy.org/doc/dvd/subtitles/index.html
*****************************************************************************/
*****************************************************************************/
static
int
ParseRLE
(
spudec_thread_t
*
p_spudec
,
static
int
ParseRLE
(
decoder_t
*
p_dec
,
subpicture_t
*
p_spu
)
subpicture_t
*
p_spu
,
uint8_t
*
p_src
)
{
{
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
uint8_t
*
p_src
=
&
p_sys
->
buffer
[
4
];
unsigned
int
i_code
;
unsigned
int
i_code
;
unsigned
int
i_width
=
p_spu
->
i_width
;
unsigned
int
i_width
=
p_spu
->
i_width
;
...
@@ -519,7 +429,7 @@ static int ParseRLE( spudec_thread_t *p_spudec,
...
@@ -519,7 +429,7 @@ static int ParseRLE( spudec_thread_t *p_spudec,
else
else
{
{
/* We have a boo boo ! */
/* We have a boo boo ! */
msg_Err
(
p_
spudec
->
p_fifo
,
"unknown RLE code "
msg_Err
(
p_
dec
,
"unknown RLE code "
"0x%.4x"
,
i_code
);
"0x%.4x"
,
i_code
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
...
@@ -530,7 +440,7 @@ static int ParseRLE( spudec_thread_t *p_spudec,
...
@@ -530,7 +440,7 @@ static int ParseRLE( spudec_thread_t *p_spudec,
if
(
(
(
i_code
>>
2
)
+
i_x
+
i_y
*
i_width
)
>
i_height
*
i_width
)
if
(
(
(
i_code
>>
2
)
+
i_x
+
i_y
*
i_width
)
>
i_height
*
i_width
)
{
{
msg_Err
(
p_
spudec
->
p_fifo
,
msg_Err
(
p_
dec
,
"out of bounds, %i at (%i,%i) is out of %ix%i"
,
"out of bounds, %i at (%i,%i) is out of %ix%i"
,
i_code
>>
2
,
i_x
,
i_y
,
i_width
,
i_height
);
i_code
>>
2
,
i_x
,
i_y
,
i_width
,
i_height
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
...
@@ -580,8 +490,8 @@ static int ParseRLE( spudec_thread_t *p_spudec,
...
@@ -580,8 +490,8 @@ static int ParseRLE( spudec_thread_t *p_spudec,
/* Check that we didn't go too far */
/* Check that we didn't go too far */
if
(
i_x
>
i_width
)
if
(
i_x
>
i_width
)
{
{
msg_Err
(
p_
spudec
->
p_fifo
,
"i_x overflowed, %i > %i"
,
msg_Err
(
p_
dec
,
"i_x overflowed, %i > %i"
,
i_x
,
i_width
);
i_x
,
i_width
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
...
@@ -598,9 +508,9 @@ static int ParseRLE( spudec_thread_t *p_spudec,
...
@@ -598,9 +508,9 @@ static int ParseRLE( spudec_thread_t *p_spudec,
/* We shouldn't get any padding bytes */
/* We shouldn't get any padding bytes */
if
(
i_y
<
i_height
)
if
(
i_y
<
i_height
)
{
{
msg_Err
(
p_
spudec
->
p_fifo
,
"padding bytes found in RLE sequence"
);
msg_Err
(
p_
dec
,
"padding bytes found in RLE sequence"
);
msg_Err
(
p_
spudec
->
p_fifo
,
"send mail to <sam@zoy.org> if you "
msg_Err
(
p_
dec
,
"send mail to <sam@zoy.org> if you "
"want to help debugging this"
);
"want to help debugging this"
);
/* Skip them just in case */
/* Skip them just in case */
while
(
i_y
<
i_height
)
while
(
i_y
<
i_height
)
...
@@ -612,7 +522,7 @@ static int ParseRLE( spudec_thread_t *p_spudec,
...
@@ -612,7 +522,7 @@ static int ParseRLE( spudec_thread_t *p_spudec,
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
msg_Dbg
(
p_
spudec
->
p_fifo
,
"valid subtitle, size: %ix%i, position: %i,%i"
,
msg_Dbg
(
p_
dec
,
"valid subtitle, size: %ix%i, position: %i,%i"
,
p_spu
->
i_width
,
p_spu
->
i_height
,
p_spu
->
i_x
,
p_spu
->
i_y
);
p_spu
->
i_width
,
p_spu
->
i_height
,
p_spu
->
i_x
,
p_spu
->
i_y
);
#if 0 /* cropping */
#if 0 /* cropping */
...
@@ -679,7 +589,7 @@ static int ParseRLE( spudec_thread_t *p_spudec,
...
@@ -679,7 +589,7 @@ static int ParseRLE( spudec_thread_t *p_spudec,
p_spu
->
p_sys
->
pi_yuv
[
i_shade
][
2
]
=
0x80
;
p_spu
->
p_sys
->
pi_yuv
[
i_shade
][
2
]
=
0x80
;
}
}
msg_Dbg
(
p_
spudec
->
p_fifo
,
msg_Dbg
(
p_
dec
,
"using custom palette (border %i, inner %i, shade %i)"
,
"using custom palette (border %i, inner %i, shade %i)"
,
i_border
,
i_inner
,
i_shade
);
i_border
,
i_inner
,
i_shade
);
}
}
...
...
modules/codec/spudec/render.c
View file @
82ca25cb
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* render.c : SPU renderer
* render.c : SPU renderer
*****************************************************************************
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
* Copyright (C) 2000-2001 VideoLAN
* $Id: render.c,v 1.
6 2003/10/25 00:49:14 sam
Exp $
* $Id: render.c,v 1.
7 2003/11/22 19:55:47 fenrir
Exp $
*
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Authors: Samuel Hocevar <sam@zoy.org>
* Rudolf Cornelissen <rag.cornelissen@inter.nl.net>
* Rudolf Cornelissen <rag.cornelissen@inter.nl.net>
...
@@ -27,7 +27,6 @@
...
@@ -27,7 +27,6 @@
* Preamble
* Preamble
*****************************************************************************/
*****************************************************************************/
#include <stdlib.h>
/* malloc(), free() */
#include <stdlib.h>
/* malloc(), free() */
#include <string.h>
/* memcpy(), memset() */
#include <vlc/vlc.h>
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include <vlc/vout.h>
...
...
modules/codec/spudec/spudec.c
View file @
82ca25cb
...
@@ -2,15 +2,16 @@
...
@@ -2,15 +2,16 @@
* spudec.c : SPU decoder thread
* spudec.c : SPU decoder thread
*****************************************************************************
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
* Copyright (C) 2000-2001 VideoLAN
* $Id: spudec.c,v 1.2
7 2003/11/16 21:07:31 gbazin
Exp $
* $Id: spudec.c,v 1.2
8 2003/11/22 19:55:47 fenrir
Exp $
*
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Authors: Samuel Hocevar <sam@zoy.org>
* 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
* the Free Software Foundation; either version 2 of the License, or
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
...
@@ -25,169 +26,258 @@
...
@@ -25,169 +26,258 @@
* Preamble
* Preamble
*****************************************************************************/
*****************************************************************************/
#include <stdlib.h>
/* malloc(), free() */
#include <stdlib.h>
/* malloc(), free() */
#include <string.h>
/* memcpy(), memset() */
#include <vlc/vlc.h>
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include <vlc/vout.h>
#include <vlc/decoder.h>
#include <vlc/decoder.h>
#include <vlc/input.h>
#include "spudec.h"
#include "spudec.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static
int
OpenDecoder
(
vlc_object_t
*
);
static
int
RunDecoder
(
decoder_fifo_t
*
);
static
int
InitThread
(
spudec_thread_t
*
);
static
void
EndThread
(
spudec_thread_t
*
);
static
vout_thread_t
*
FindVout
(
spudec_thread_t
*
);
/*****************************************************************************
/*****************************************************************************
* Module descriptor.
* Module descriptor.
*****************************************************************************/
*****************************************************************************/
static
int
DecoderOpen
(
vlc_object_t
*
);
static
int
PacketizerOpen
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
vlc_module_begin
();
vlc_module_begin
();
set_description
(
_
(
"DVD subtitles decoder"
)
);
set_description
(
_
(
"DVD subtitles decoder"
)
);
set_capability
(
"decoder"
,
50
);
set_capability
(
"decoder"
,
50
);
set_callbacks
(
OpenDecoder
,
NULL
);
set_callbacks
(
DecoderOpen
,
Close
);
add_submodule
();
set_description
(
_
(
"DVD subtitles packetizer"
)
);
set_capability
(
"decoder"
,
50
);
set_callbacks
(
PacketizerOpen
,
Close
);
vlc_module_end
();
vlc_module_end
();
/*****************************************************************************
/*****************************************************************************
* OpenDecoder: probe the decoder and return score
* Local prototypes
*****************************************************************************/
static
vout_thread_t
*
FindVout
(
decoder_t
*
);
static
block_t
*
Reassemble
(
decoder_t
*
,
block_t
**
);
static
void
Decode
(
decoder_t
*
,
block_t
**
);
static
block_t
*
Packetize
(
decoder_t
*
,
block_t
**
);
/*****************************************************************************
* DecoderOpen
*****************************************************************************
*****************************************************************************
* Tries to launch a decoder and return score so that the interface is able
* Tries to launch a decoder and return score so that the interface is able
* to chose.
* to chose.
*****************************************************************************/
*****************************************************************************/
static
int
OpenDecoder
(
vlc_object_t
*
p_this
)
static
int
DecoderOpen
(
vlc_object_t
*
p_this
)
{
{
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
decoder_sys_t
*
p_sys
;
if
(
p_dec
->
fmt_in
.
i_codec
!=
VLC_FOURCC
(
's'
,
'p'
,
'u'
,
' '
)
if
(
p_dec
->
fmt_in
.
i_codec
!=
VLC_FOURCC
(
's'
,
'p'
,
'u'
,
' '
)
&&
&&
p_dec
->
fmt_in
.
i_codec
!=
VLC_FOURCC
(
's'
,
'p'
,
'u'
,
'b'
)
)
p_dec
->
fmt_in
.
i_codec
!=
VLC_FOURCC
(
's'
,
'p'
,
'u'
,
'b'
)
)
{
{
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
p_dec
->
pf_run
=
RunDecoder
;
p_dec
->
p_sys
=
p_sys
=
malloc
(
sizeof
(
decoder_sys_t
)
);
p_sys
->
b_packetizer
=
VLC_FALSE
;
p_sys
->
i_spu_size
=
0
;
p_sys
->
i_spu
=
0
;
p_sys
->
p_block
=
NULL
;
p_sys
->
p_vout
=
NULL
;
es_format_Init
(
&
p_dec
->
fmt_out
,
SPU_ES
,
VLC_FOURCC
(
's'
,
'p'
,
'u'
,
' '
)
);
p_dec
->
pf_decode_sub
=
Decode
;
p_dec
->
pf_packetize
=
Packetize
;
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
/*****************************************************************************
/*****************************************************************************
* RunDecoder: this function is called just after the thread is created
* PacketizerOpen
*****************************************************************************
* Tries to launch a decoder and return score so that the interface is able
* to chose.
*****************************************************************************/
*****************************************************************************/
static
int
RunDecoder
(
decoder_fifo_t
*
p_fifo
)
static
int
PacketizerOpen
(
vlc_object_t
*
p_this
)
{
{
spudec_thread_t
*
p_spudec
;
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
/* Allocate the memory needed to store the thread's structure */
p_spudec
=
(
spudec_thread_t
*
)
malloc
(
sizeof
(
spudec_thread_t
)
);
if
(
p_spudec
==
NULL
)
if
(
DecoderOpen
(
p_this
)
)
{
{
msg_Err
(
p_fifo
,
"out of memory"
);
return
VLC_EGENERIC
;
DecoderError
(
p_fifo
);
return
(
-
1
);
}
}
p_dec
->
p_sys
->
b_packetizer
=
VLC_TRUE
;
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Close:
*****************************************************************************/
static
void
Close
(
vlc_object_t
*
p_this
)
{
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
/*
if
(
!
p_sys
->
b_packetizer
)
* Initialize the thread properties
*/
p_spudec
->
p_vout
=
NULL
;
p_spudec
->
p_fifo
=
p_fifo
;
/*
* Initialize thread and free configuration
*/
p_spudec
->
p_fifo
->
b_error
=
InitThread
(
p_spudec
);
/*
* Main loop - it is not executed if an error occured during
* initialization
*/
while
(
(
!
p_spudec
->
p_fifo
->
b_die
)
&&
(
!
p_spudec
->
p_fifo
->
b_error
)
)
{
{
if
(
E_
(
SyncPacket
)(
p_spudec
)
)
/* FIXME check if it's ok to not lock vout */
if
(
p_sys
->
p_vout
!=
NULL
&&
p_sys
->
p_vout
->
p_subpicture
!=
NULL
)
{
{
continue
;
subpicture_t
*
p_subpic
;
int
i_subpic
;
for
(
i_subpic
=
0
;
i_subpic
<
VOUT_MAX_SUBPICTURES
;
i_subpic
++
)
{
p_subpic
=
&
p_sys
->
p_vout
->
p_subpicture
[
i_subpic
];
if
(
p_subpic
!=
NULL
&&
(
(
p_subpic
->
i_status
==
RESERVED_SUBPICTURE
)
||
(
p_subpic
->
i_status
==
READY_SUBPICTURE
)
)
)
{
vout_DestroySubPicture
(
p_sys
->
p_vout
,
p_subpic
);
}
}
}
}
}
if
(
p_sys
->
p_block
)
{
block_ChainRelease
(
p_sys
->
p_block
);
}
free
(
p_sys
);
}
/* Find/Wait for a video output */
/*****************************************************************************
p_spudec
->
p_vout
=
FindVout
(
p_spudec
);
* Decode:
if
(
p_spudec
->
p_vout
)
*****************************************************************************/
static
void
Decode
(
decoder_t
*
p_dec
,
block_t
**
pp_block
)
{
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
block_t
*
p_spu
=
Reassemble
(
p_dec
,
pp_block
);
if
(
p_spu
)
{
p_sys
->
i_spu
=
block_ChainExtract
(
p_spu
,
p_sys
->
buffer
,
65536
);
p_sys
->
i_pts
=
p_spu
->
i_pts
;
block_ChainRelease
(
p_spu
);
if
(
(
p_sys
->
p_vout
=
FindVout
(
p_dec
)
)
)
{
{
E_
(
ParsePacket
)(
p_spudec
);
/* Parse and decode */
vlc_object_release
(
p_spudec
->
p_vout
);
E_
(
ParsePacket
)(
p_dec
);
vlc_object_release
(
p_sys
->
p_vout
);
}
}
/* reinit context */
p_sys
->
i_spu_size
=
0
;
p_sys
->
i_rle_size
=
0
;
p_sys
->
i_spu
=
0
;
p_sys
->
p_block
=
NULL
;
}
}
}
/*****************************************************************************
* Packetize:
*****************************************************************************/
static
block_t
*
Packetize
(
decoder_t
*
p_dec
,
block_t
**
pp_block
)
{
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
block_t
*
p_spu
=
Reassemble
(
p_dec
,
pp_block
);
/*
if
(
p_spu
)
* Error loop
*/
if
(
p_spudec
->
p_fifo
->
b_error
)
{
{
DecoderError
(
p_spudec
->
p_fifo
);
/* reinit context */
p_sys
->
i_spu_size
=
0
;
p_sys
->
i_rle_size
=
0
;
p_sys
->
i_spu
=
0
;
p_sys
->
p_block
=
NULL
;
/* End of thread */
return
block_ChainGather
(
p_spu
);
EndThread
(
p_spudec
);
return
-
1
;
}
}
return
NULL
;
/* End of thread */
EndThread
(
p_spudec
);
return
0
;
}
}
/* following functions are local */
/*****************************************************************************
/*****************************************************************************
* InitThread: initialize spu decoder thread
* Reassemble:
*****************************************************************************
* 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
)
static
block_t
*
Reassemble
(
decoder_t
*
p_dec
,
block_t
**
pp_block
)
{
{
int
i_ret
;
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
block_t
*
p_block
;
/* Call InitBitstream anyway so p_spudec->bit_stream is in a known
* state before calling CloseBitstream */
if
(
pp_block
==
NULL
||
*
pp_block
==
NULL
)
i_ret
=
InitBitstream
(
&
p_spudec
->
bit_stream
,
p_spudec
->
p_fifo
,
{
NULL
,
NULL
)
;
return
NULL
;
}
/* Check for a video output */
p_block
=
*
pp_block
;
p_spudec
->
p_vout
=
FindVout
(
p_spudec
)
;
*
pp_block
=
NULL
;
if
(
!
p_spudec
->
p_vout
)
if
(
p_sys
->
i_spu_size
<=
0
&&
(
p_block
->
i_pts
<=
0
||
p_block
->
i_buffer
<
4
)
)
{
{
return
-
1
;
msg_Dbg
(
p_dec
,
"invalid starting packet (size < 4 or pts <=0)"
);
block_Release
(
p_block
);
return
NULL
;
}
}
/* It was just a check */
block_ChainAppend
(
&
p_sys
->
p_block
,
p_block
);
vlc_object_release
(
p_spudec
->
p_vout
);
p_sys
->
i_spu
+=
p_block
->
i_buffer
;
p_spudec
->
p_vout
=
NULL
;
if
(
p_sys
->
i_spu_size
<=
0
)
return
i_ret
;
{
p_sys
->
i_spu_size
=
(
p_block
->
p_buffer
[
0
]
<<
8
)
|
p_block
->
p_buffer
[
1
];
p_sys
->
i_rle_size
=
(
(
p_block
->
p_buffer
[
2
]
<<
8
)
|
p_block
->
p_buffer
[
3
]
)
-
4
;
msg_Dbg
(
p_dec
,
"i_spu_size=%d i_rle=%d"
,
p_sys
->
i_spu_size
,
p_sys
->
i_rle_size
);
if
(
p_sys
->
i_spu_size
<=
0
||
p_sys
->
i_rle_size
>=
p_sys
->
i_spu_size
)
{
p_sys
->
i_spu_size
=
0
;
p_sys
->
i_rle_size
=
0
;
p_sys
->
i_spu
=
0
;
p_sys
->
p_block
=
NULL
;
block_Release
(
p_block
);
return
NULL
;
}
}
if
(
p_sys
->
i_spu
>=
p_sys
->
i_spu_size
)
{
/* We have a complete sub */
block_t
*
p_ret
=
p_sys
->
p_block
;
msg_Dbg
(
p_dec
,
"SPU packets size=%d should be %d"
,
p_sys
->
i_spu
,
p_sys
->
i_spu_size
);
return
p_ret
;
}
return
NULL
;
}
}
/* following functions are local */
/*****************************************************************************
/*****************************************************************************
* FindVout: Find a vout or wait for one to be created.
* FindVout: Find a vout or wait for one to be created.
*****************************************************************************/
*****************************************************************************/
static
vout_thread_t
*
FindVout
(
spudec_thread_t
*
p_spu
dec
)
static
vout_thread_t
*
FindVout
(
decoder_t
*
p_
dec
)
{
{
vout_thread_t
*
p_vout
=
NULL
;
vout_thread_t
*
p_vout
=
NULL
;
/* Find an available video output */
/* Find an available video output */
do
do
{
{
if
(
p_
spudec
->
p_fifo
->
b_die
||
p_spudec
->
p_fifo
->
b_error
)
if
(
p_
dec
->
b_die
||
p_dec
->
b_error
)
{
{
break
;
break
;
}
}
p_vout
=
vlc_object_find
(
p_spudec
->
p_fifo
,
VLC_OBJECT_VOUT
,
p_vout
=
vlc_object_find
(
p_dec
,
VLC_OBJECT_VOUT
,
FIND_ANYWHERE
);
FIND_ANYWHERE
);
if
(
p_vout
)
if
(
p_vout
)
{
{
break
;
break
;
...
@@ -200,33 +290,3 @@ static vout_thread_t *FindVout( spudec_thread_t *p_spudec )
...
@@ -200,33 +290,3 @@ static vout_thread_t *FindVout( spudec_thread_t *p_spudec )
return
p_vout
;
return
p_vout
;
}
}
/*****************************************************************************
* EndThread: thread destruction
*****************************************************************************
* This function is called when the thread ends after a sucessful
* initialization.
*****************************************************************************/
static
void
EndThread
(
spudec_thread_t
*
p_spudec
)
{
if
(
p_spudec
->
p_vout
!=
NULL
&&
p_spudec
->
p_vout
->
p_subpicture
!=
NULL
)
{
subpicture_t
*
p_subpic
;
int
i_subpic
;
for
(
i_subpic
=
0
;
i_subpic
<
VOUT_MAX_SUBPICTURES
;
i_subpic
++
)
{
p_subpic
=
&
p_spudec
->
p_vout
->
p_subpicture
[
i_subpic
];
if
(
p_subpic
!=
NULL
&&
(
(
p_subpic
->
i_status
==
RESERVED_SUBPICTURE
)
||
(
p_subpic
->
i_status
==
READY_SUBPICTURE
)
)
)
{
vout_DestroySubPicture
(
p_spudec
->
p_vout
,
p_subpic
);
}
}
}
CloseBitstream
(
&
p_spudec
->
bit_stream
);
free
(
p_spudec
);
}
modules/codec/spudec/spudec.h
View file @
82ca25cb
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* spudec.h : sub picture unit decoder thread interface
* spudec.h : sub picture unit decoder thread interface
*****************************************************************************
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* Copyright (C) 1999, 2000 VideoLAN
* $Id: spudec.h,v 1.
7 2003/07/22 20:49:10 hartman
Exp $
* $Id: spudec.h,v 1.
8 2003/11/22 19:55:47 fenrir
Exp $
*
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Authors: Samuel Hocevar <sam@zoy.org>
*
*
...
@@ -21,7 +21,21 @@
...
@@ -21,7 +21,21 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
*****************************************************************************/
typedef
struct
spudec_thread_t
spudec_thread_t
;
struct
decoder_sys_t
{
int
b_packetizer
;
mtime_t
i_pts
;
int
i_spu_size
;
int
i_rle_size
;
int
i_spu
;
block_t
*
p_block
;
uint8_t
buffer
[
65536
+
20
];
/* we will never overflow more than 11 bytes if I'm right */
vout_thread_t
*
p_vout
;
};
struct
subpicture_sys_t
struct
subpicture_sys_t
{
{
...
@@ -44,35 +58,6 @@ struct subpicture_sys_t
...
@@ -44,35 +58,6 @@ struct subpicture_sys_t
unsigned
int
i_x_start
,
i_y_start
,
i_x_end
,
i_y_end
;
unsigned
int
i_x_start
,
i_y_start
,
i_x_end
,
i_y_end
;
};
};
/*****************************************************************************
* spudec_thread_t : sub picture unit decoder thread descriptor
*****************************************************************************/
struct
spudec_thread_t
{
/*
* Thread properties and locks
*/
vlc_thread_t
thread_id
;
/* id for thread functions */
/*
* Input properties
*/
decoder_fifo_t
*
p_fifo
;
/* stores the PES stream data */
/* The bit stream structure handles the PES stream at the bit level */
bit_stream_t
bit_stream
;
/*
* Output properties
*/
vout_thread_t
*
p_vout
;
/* needed to create the spu objects */
/*
* Private properties
*/
unsigned
int
i_spu_size
;
/* size of current SPU packet */
unsigned
int
i_rle_size
;
/* size of the RLE part */
};
/*****************************************************************************
/*****************************************************************************
* Amount of bytes we GetChunk() in one go
* Amount of bytes we GetChunk() in one go
*****************************************************************************/
*****************************************************************************/
...
@@ -93,9 +78,7 @@ struct spudec_thread_t
...
@@ -93,9 +78,7 @@ struct spudec_thread_t
/*****************************************************************************
/*****************************************************************************
* Prototypes
* Prototypes
*****************************************************************************/
*****************************************************************************/
int
E_
(
SyncPacket
)
(
spudec_thread_t
*
);
void
E_
(
ParsePacket
)(
decoder_t
*
);
void
E_
(
ParsePacket
)
(
spudec_thread_t
*
);
void
E_
(
RenderSPU
)
(
vout_thread_t
*
,
picture_t
*
,
void
E_
(
RenderSPU
)
(
vout_thread_t
*
,
picture_t
*
,
const
subpicture_t
*
);
const
subpicture_t
*
);
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