Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-1.1
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-1.1
Commits
d5b04453
Commit
d5b04453
authored
Dec 31, 2001
by
Christophe Massiot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
STABLE/HEAD merge ; backported the Next Generation Buffer Manager.
parent
f6b7894d
Changes
31
Show whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
1493 additions
and
2457 deletions
+1493
-2457
Makefile
Makefile
+1
-1
include/common.h
include/common.h
+1
-13
include/config.h.in
include/config.h.in
+3
-7
include/input_ext-dec.h
include/input_ext-dec.h
+28
-31
include/input_ext-intf.h
include/input_ext-intf.h
+3
-6
include/input_ext-plugins.h
include/input_ext-plugins.h
+667
-57
include/modules_export.h
include/modules_export.h
+0
-9
plugins/ac3_adec/ac3_adec.c
plugins/ac3_adec/ac3_adec.c
+4
-4
plugins/ac3_spdif/ac3_spdif.c
plugins/ac3_spdif/ac3_spdif.c
+3
-3
plugins/dvd/input_dvd.c
plugins/dvd/input_dvd.c
+80
-71
plugins/dvdread/input_dvdread.c
plugins/dvdread/input_dvdread.c
+132
-74
plugins/lpcm_adec/lpcm_adec.c
plugins/lpcm_adec/lpcm_adec.c
+4
-4
plugins/mad_adec/mad_libmad.c
plugins/mad_adec/mad_libmad.c
+3
-3
plugins/mpeg/input_es.c
plugins/mpeg/input_es.c
+72
-47
plugins/mpeg/input_es.h
plugins/mpeg/input_es.h
+3
-5
plugins/mpeg/input_ps.c
plugins/mpeg/input_ps.c
+64
-465
plugins/mpeg/input_ps.h
plugins/mpeg/input_ps.h
+2
-51
plugins/mpeg/input_ts.c
plugins/mpeg/input_ts.c
+53
-45
plugins/mpeg/input_ts.h
plugins/mpeg/input_ts.h
+6
-4
plugins/mpeg_adec/mpeg_adec.c
plugins/mpeg_adec/mpeg_adec.c
+4
-4
plugins/mpeg_vdec/video_parser.c
plugins/mpeg_vdec/video_parser.c
+5
-37
plugins/spu_dec/spu_decoder.c
plugins/spu_dec/spu_decoder.c
+3
-3
plugins/vcd/input_vcd.c
plugins/vcd/input_vcd.c
+189
-610
plugins/vcd/input_vcd.h
plugins/vcd/input_vcd.h
+8
-16
plugins/vcd/linux_cdrom_tools.c
plugins/vcd/linux_cdrom_tools.c
+70
-102
plugins/vcd/linux_cdrom_tools.h
plugins/vcd/linux_cdrom_tools.h
+3
-4
src/input/input.c
src/input/input.c
+23
-36
src/input/input_dec.c
src/input/input_dec.c
+16
-23
src/input/input_ext-dec.c
src/input/input_ext-dec.c
+16
-16
src/input/input_netlist.c
src/input/input_netlist.c
+0
-685
src/input/mpeg_system.c
src/input/mpeg_system.c
+27
-21
No files found.
Makefile
View file @
d5b04453
...
...
@@ -110,7 +110,7 @@ PLUGINS_TARGETS := ac3_adec/ac3_adec \
# C Objects
#
INTERFACE
:=
main interface intf_msg intf_playlist intf_channels
INPUT
:=
input input_ext-dec input_ext-intf input_dec input_programs input_
netlist input_
clock mpeg_system
INPUT
:=
input input_ext-dec input_ext-intf input_dec input_programs input_clock mpeg_system
VIDEO_OUTPUT
:=
video_output video_text video_spu video_yuv
AUDIO_OUTPUT
:=
audio_output aout_ext-dec aout_u8 aout_s8 aout_u16 aout_s16 aout_spdif
MISC
:=
mtime tests modules netutils iso_lang
...
...
include/common.h
View file @
d5b04453
...
...
@@ -3,7 +3,7 @@
* Collection of useful common types and macros definitions
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: common.h,v 1.53.2.
1 2001/12/30 06:06:00 sam
Exp $
* $Id: common.h,v 1.53.2.
2 2001/12/31 01:21:44 massiot
Exp $
*
* Authors: Samuel Hocevar <sam@via.ecp.fr>
* Vincent Seguin <seguin@via.ecp.fr>
...
...
@@ -347,18 +347,6 @@ typedef struct module_symbols_s
struct
pgrm_descriptor_s
*
,
mtime_t
);
int
(
*
input_NetlistInit
)
(
struct
input_thread_s
*
,
int
,
int
,
int
,
size_t
,
int
);
struct
iovec
*
(
*
input_NetlistGetiovec
)
(
void
*
p_method_data
);
void
(
*
input_NetlistMviovec
)
(
void
*
,
int
,
struct
data_packet_s
**
);
struct
data_packet_s
*
(
*
input_NetlistNewPacket
)
(
void
*
,
size_t
);
struct
data_packet_s
*
(
*
input_NetlistNewPtr
)
(
void
*
);
struct
pes_packet_s
*
(
*
input_NetlistNewPES
)
(
void
*
);
void
(
*
input_NetlistDeletePacket
)
(
void
*
,
struct
data_packet_s
*
);
void
(
*
input_NetlistDeletePES
)
(
void
*
,
struct
pes_packet_s
*
);
void
(
*
input_NetlistEnd
)
(
struct
input_thread_s
*
);
struct
aout_fifo_s
*
(
*
aout_CreateFifo
)
(
int
,
int
,
long
,
long
,
long
,
void
*
);
void
(
*
aout_DestroyFifo
)
(
struct
aout_fifo_s
*
);
...
...
include/config.h.in
View file @
d5b04453
...
...
@@ -97,13 +97,6 @@
/* Environment variable containing the memcpy method */
#define MEMCPY_METHOD_VAR "vlc_memcpy"
/*
* Decoders FIFO configuration
*/
/* Size of the FIFO. FIFO_SIZE+1 must be a power of 2 */
#define FIFO_SIZE 1023
/*
* Paths
*/
...
...
@@ -175,6 +168,9 @@
/* Maximum length of a hostname or source name */
#define INPUT_MAX_SOURCE_LENGTH 100
/* Maximum memory the input is allowed to use (20 MB) */
#define INPUT_MAX_ALLOCATION 20971520
/* Default network protocol */
#define INPUT_NETWORK_PROTOCOL_VAR "vlc_network_protocol"
#define INPUT_NETWORK_PROTOCOL_DEFAULT "ts"
...
...
include/input_ext-dec.h
View file @
d5b04453
...
...
@@ -2,7 +2,7 @@
* input_ext-dec.h: structures exported to the VideoLAN decoders
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ext-dec.h,v 1.41.2.
1 2001/12/30 06:06:00 sam
Exp $
* $Id: input_ext-dec.h,v 1.41.2.
2 2001/12/31 01:21:44 massiot
Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Michel Kaempf <maxx@via.ecp.fr>
...
...
@@ -40,22 +40,25 @@
*****************************************************************************
* Describe a data packet.
*****************************************************************************/
#define DATA_PACKET \
/* start of the PS or TS packet */
\
byte_t * p_demux_start; \
/* start of the PES payload in this packet */
\
byte_t * p_payload_start; \
byte_t * p_payload_end;
/* guess ? :-) */
\
/* is the packet messed up ? */
\
boolean_t b_discard_payload;
typedef
struct
data_packet_s
{
/* Nothing before this line, the code relies on that */
byte_t
*
p_buffer
;
/* raw data packet */
long
l_size
;
/* buffer size */
/* Decoders information */
byte_t
*
p_payload_start
;
/* start of the PES payload in this packet */
byte_t
*
p_payload_end
;
/* guess ? :-) */
boolean_t
b_discard_payload
;
/* is the packet messed up ? */
/* Used to chain the packets that carry data for a same PES or PSI */
struct
data_packet_s
*
p_next
;
int
*
pi_refcount
;
DATA_PACKET
/* Used to chain the TS packets that carry data for a same PES or PSI */
struct
data_packet_s
*
p_next
;
/* Please note that at least one buffer allocator (in particular, the
* Next Generation Buffer Allocator) extends this structure with
* private data after DATA_PACKET. */
}
data_packet_t
;
/*****************************************************************************
...
...
@@ -66,6 +69,9 @@ typedef struct data_packet_s
*****************************************************************************/
typedef
struct
pes_packet_s
{
/* Chained list to the next PES packet (depending on the context) */
struct
pes_packet_s
*
p_next
;
/* PES properties */
boolean_t
b_data_alignment
;
/* used to find the beginning of
* a video or audio unit */
...
...
@@ -77,12 +83,15 @@ typedef struct pes_packet_s
int
i_rate
;
/* current pace of reading
* (see stream_control.h) */
int
i_pes_size
;
/* size of the current PES packet */
unsigned
int
i_pes_size
;
/* size of the current PES packet */
/* Pointers to packets (packets are then linked by the p_prev and
p_next fields of the data_packet_t struct) */
/* Chained list to packets */
data_packet_t
*
p_first
;
/* The first packet contained by this
* PES (used by decoders). */
data_packet_t
*
p_last
;
/* The last packet contained by this
PES (used by the buffer allocator) */
unsigned
int
i_nb_data
;
/* Number of data packets in the chained
list */
}
pes_packet_t
;
/*****************************************************************************
...
...
@@ -97,9 +106,9 @@ typedef struct decoder_fifo_s
vlc_cond_t
data_wait
;
/* fifo data conditional variable */
/* Data */
pes_packet_t
*
buffer
[
FIFO_SIZE
+
1
]
;
int
i_star
t
;
int
i_
end
;
pes_packet_t
*
p_first
;
pes_packet_t
**
pp_las
t
;
int
i_
depth
;
/* number of PES packets in the stack */
/* Communication interface between input and decoders */
boolean_t
b_die
;
/* the decoder should return now */
...
...
@@ -110,18 +119,6 @@ typedef struct decoder_fifo_s
/* function to use when releasing a PES */
}
decoder_fifo_t
;
/* Macros to manage a decoder_fifo_t structure. Please remember to take
* data_lock before using them. */
#define DECODER_FIFO_ISEMPTY( fifo ) ( (fifo).i_start == (fifo).i_end )
#define DECODER_FIFO_ISFULL( fifo ) ( ( ((fifo).i_end + 1 - (fifo).i_start)\
& FIFO_SIZE ) == 0 )
#define DECODER_FIFO_START( fifo ) ( (fifo).buffer[ (fifo).i_start ] )
#define DECODER_FIFO_INCSTART( fifo ) ( (fifo).i_start = ((fifo).i_start + 1)\
& FIFO_SIZE )
#define DECODER_FIFO_END( fifo ) ( (fifo).buffer[ (fifo).i_end ] )
#define DECODER_FIFO_INCEND( fifo ) ( (fifo).i_end = ((fifo).i_end + 1) \
& FIFO_SIZE )
/*****************************************************************************
* bit_fifo_t : bit fifo descriptor
*****************************************************************************
...
...
include/input_ext-intf.h
View file @
d5b04453
...
...
@@ -4,7 +4,7 @@
* control the pace of reading.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ext-intf.h,v 1.51
2001/12/07 16:47:47 jobi
Exp $
* $Id: input_ext-intf.h,v 1.51
.2.1 2001/12/31 01:21:44 massiot
Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
...
...
@@ -26,7 +26,6 @@
/*
* Communication input -> interface
*/
#define INPUT_MAX_PLUGINS 1
/* FIXME ! */
#define REQUESTED_MPEG 1
#define REQUESTED_AC3 2
...
...
@@ -66,7 +65,6 @@ typedef struct es_descriptor_s
/* PES parser information */
struct
pes_packet_s
*
p_pes
;
/* Current PES */
struct
data_packet_s
*
p_last
;
/* The last packet gathered at present */
int
i_pes_real_size
;
/* as indicated by the header */
/* Decoder information */
...
...
@@ -95,6 +93,7 @@ typedef struct es_descriptor_s
#define SPU_ES 0x02
#define NAV_ES 0x03
#define UNKNOWN_ES 0xFF
/*****************************************************************************
* pgrm_descriptor_t
*****************************************************************************
...
...
@@ -263,7 +262,7 @@ typedef struct input_thread_s
/* Read & Demultiplex */
int
(
*
pf_read
)(
struct
input_thread_s
*
,
struct
data_packet_s
*
pp_packets
[]
);
struct
data_packet_s
*
*
);
void
(
*
pf_demux
)(
struct
input_thread_s
*
,
struct
data_packet_s
*
);
...
...
@@ -289,8 +288,6 @@ typedef struct input_thread_s
int
i_handle
;
/* socket or file descriptor */
FILE
*
p_stream
;
/* if applicable */
void
*
p_handle
;
/* if i_handle isn't suitable */
int
i_read_once
;
/* number of packet read by
* pf_read once */
void
*
p_method_data
;
/* data of the packet manager */
void
*
p_plugin_data
;
/* data of the plugin */
...
...
include/input_ext-plugins.h
View file @
d5b04453
...
...
@@ -3,7 +3,7 @@
* but exported to plug-ins
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: input_ext-plugins.h,v 1.7
2001/12/07 16:47:47 jobi
Exp $
* $Id: input_ext-plugins.h,v 1.7
.2.1 2001/12/31 01:21:44 massiot
Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
...
...
@@ -27,10 +27,6 @@
*/
/* FIXME: you've gotta move this move this, you've gotta move this move this */
#define INPUT_READ_ONCE 7
/* We live in a world dominated by Ethernet. *
* Ethernet MTU is 1500 bytes, so in a UDP *
* packet we can put : 1500/188 = 7 TS *
* packets. Have a nice day and merry Xmas. */
#define PADDING_PACKET_SIZE 188
/* Size of the NULL packet inserted in case
* of data loss (this should be < 188). */
#define PADDING_PACKET_NUMBER 10
/* Number of padding packets top insert to
...
...
@@ -115,15 +111,16 @@ static __inline__ void input_NullPacket( input_thread_t * p_input,
return
;
}
memset
(
p_pad_data
->
p_
buffer
,
0
,
PADDING_PACKET_SIZE
);
memset
(
p_pad_data
->
p_
payload_start
,
0
,
PADDING_PACKET_SIZE
);
p_pad_data
->
b_discard_payload
=
1
;
p_pes
=
p_es
->
p_pes
;
if
(
p_pes
!=
NULL
)
{
p_pes
->
b_discontinuity
=
1
;
p_es
->
p_last
->
p_next
=
p_pad_data
;
p_es
->
p_last
=
p_pad_data
;
p_pes
->
p_last
->
p_next
=
p_pad_data
;
p_pes
->
p_last
=
p_pad_data
;
p_pes
->
i_nb_data
++
;
}
else
{
...
...
@@ -135,7 +132,8 @@ static __inline__ void input_NullPacket( input_thread_t * p_input,
}
p_pes
->
i_rate
=
p_input
->
stream
.
control
.
i_rate
;
p_pes
->
p_first
=
p_pad_data
;
p_pes
->
p_first
=
p_pes
->
p_last
=
p_pad_data
;
p_pes
->
i_nb_data
=
1
;
p_pes
->
b_discontinuity
=
1
;
input_DecodePES
(
p_es
->
p_decoder_fifo
,
p_pes
);
}
...
...
@@ -143,68 +141,680 @@ static __inline__ void input_NullPacket( input_thread_t * p_input,
/*
* Optional netlist management
* Optional Next Generation buffer manager
*
* Either buffers can only be used in one data packet (PS case), or buffers
* contain several data packets (DVD case). In the first case, buffers are
* embedded into data packets, otherwise they are allocated separately and
* shared with a refcount. --Meuuh
*/
/* Number of buffers for the calculation of the mean */
#define INPUT_BRESENHAM_NB 50
/* Flags */
#define BUFFERS_NOFLAGS 0
#define BUFFERS_UNIQUE_SIZE 1
/* Only with NB_LIFO == 1 */
/*****************************************************************************
*
netlist_t: structure to manage a netlist
*
_input_buffers_t: defines a LIFO per data type to keep
*****************************************************************************/
typedef
struct
netlist_s
#define PACKETS_LIFO( TYPE, NAME ) \
struct \
{ \
TYPE * p_stack; \
unsigned int i_depth; \
} NAME;
#define BUFFERS_LIFO( TYPE, NAME ) \
struct \
{ \
TYPE * p_stack;
/* First item in the LIFO */
\
unsigned int i_depth;
/* Number of items in the LIFO */
\
unsigned int i_average_size;
/* Average size of the items (Bresenham) */
\
} NAME;
#define DECLARE_BUFFERS_EMBEDDED( FLAGS, NB_LIFO ) \
typedef struct _input_buffers_s \
{ \
vlc_mutex_t lock; \
PACKETS_LIFO( pes_packet_t, pes ) \
BUFFERS_LIFO( _data_packet_t, data[NB_LIFO] ) \
size_t i_allocated; \
} _input_buffers_t;
#define DECLARE_BUFFERS_SHARED( FLAGS, NB_LIFO ) \
typedef struct _input_buffers_s \
{ \
vlc_mutex_t lock; \
PACKETS_LIFO( pes_packet_t, pes ) \
PACKETS_LIFO( _data_packet_t, data ) \
BUFFERS_LIFO( _data_buffer_t, buffers[NB_LIFO] ) \
size_t i_allocated; \
} _input_buffers_t;
/* Data buffer, used in case the buffer can be shared between several data
* packets */
typedef
struct
_data_buffer_s
{
vlc_mutex_t
lock
;
struct
_data_buffer_s
*
p_next
;
size_t
i_buffer_size
;
/* number of data packets this buffer is referenced from - when it falls
* down to 0, the buffer is freed */
int
i_refcount
;
/* Buffers */
byte_t
*
p_buffers
;
/* Big malloc'ed area */
data_packet_t
*
p_data
;
/* malloc'ed area */
pes_packet_t
*
p_pes
;
/* malloc'ed area */
struct
/* for compatibility with _data_packet_t */
{
/* size of the current buffer (starting right thereafter) */
unsigned
int
i_size
;
}
_private
;
}
_data_buffer_t
;
/* FIFOs of free packet
s */
data_packet_t
**
pp_free_data
;
pes_packet_t
**
pp_free_pes
;
struct
iovec
*
p_free_iovec
;
/* We overload the data_packet_t type to add private member
s */
typedef
struct
_data_packet_s
{
struct
_data_packet_s
*
p_next
;
/* FIFO size */
unsigned
int
i_nb_iovec
;
unsigned
int
i_nb_pes
;
unsigned
int
i_nb_data
;
DATA_PACKET
/* Index */
unsigned
int
i_iovec_start
,
i_iovec_end
;
unsigned
int
i_data_start
,
i_data_end
;
unsigned
int
i_pes_start
,
i_pes_end
;
union
{
struct
_data_buffer_s
*
p_buffer
;
/* in case of shared buffers */
/* size of the embedded buffer (starting right thereafter) */
unsigned
int
i_size
;
}
_private
;
}
_data_packet_t
;
/* Reference counters for iovec */
unsigned
int
*
pi_refcount
;
/* Number of blocs read once by readv */
unsigned
int
i_read_once
;
}
netlist_t
;
/*****************************************************************************
* input_BuffersInit: initialize the cache structures, return a pointer to it
*****************************************************************************/
#define DECLARE_BUFFERS_INIT( FLAGS, NB_LIFO ) \
static void * input_BuffersInit( void ) \
{ \
_input_buffers_t * p_buffers = malloc( sizeof( _input_buffers_t ) ); \
\
if( p_buffers == NULL ) \
{ \
return( NULL ); \
} \
\
memset( p_buffers, 0, sizeof( _input_buffers_t ) ); \
vlc_mutex_init( &p_buffers->lock ); \
\
return (void *)p_buffers; \
}
/*****************************************************************************
*
Prototyp
es
*
input_BuffersEnd: free all cached structur
es
*****************************************************************************/
#ifndef PLUGIN
int
input_NetlistInit
(
struct
input_thread_s
*
,
int
i_nb_iovec
,
int
i_nb_data
,
int
i_nb_pes
,
size_t
i_buffer_size
,
int
i_read_once
);
struct
iovec
*
input_NetlistGetiovec
(
void
*
p_method_data
);
void
input_NetlistMviovec
(
void
*
,
int
,
struct
data_packet_s
**
);
struct
data_packet_s
*
input_NetlistNewPtr
(
void
*
);
struct
data_packet_s
*
input_NetlistNewPacket
(
void
*
,
size_t
);
struct
pes_packet_s
*
input_NetlistNewPES
(
void
*
);
void
input_NetlistDeletePacket
(
void
*
,
struct
data_packet_s
*
);
void
input_NetlistDeletePES
(
void
*
,
struct
pes_packet_s
*
);
void
input_NetlistEnd
(
struct
input_thread_s
*
);
#endif
#define BUFFERS_END_STAT_BUFFERS_LOOP( STRUCT ) \
for( i = 0; i < NB_LIFO; i++ ) \
{ \
if( FLAGS & BUFFERS_UNIQUE_SIZE ) \
{ \
intf_StatMsg( \
"input buffers stats: " #STRUCT "[%d]: %d packets", \
i, p_buffers->STRUCT[i].i_depth ); \
} \
else \
{ \
intf_StatMsg( \
"input buffers stats: " #STRUCT "[%d]: %d bytes, %d packets", \
i, p_buffers->STRUCT[i].i_average_size, \
p_buffers->STRUCT[i].i_depth ); \
} \
}
#define BUFFERS_END_STAT( FLAGS, NB_LIFO ) \
BUFFERS_END_STAT_BUFFERS_LOOP( data );
#define BUFFERS_END_STAT_SHARED( FLAGS, NB_LIFO ) \
intf_StatMsg( "input buffers stats: data: %d packets", \
p_buffers->data.i_depth ); \
BUFFERS_END_STAT_BUFFERS_LOOP( buffers );
#define BUFFERS_END_BUFFERS_LOOP \
while( p_buf != NULL ) \
{ \
p_next = p_buf->p_next; \
p_buffers->i_allocated -= p_buf->_private.i_size; \
free( p_buf ); \
p_buf = p_next; \
}
#define BUFFERS_END_PACKETS_LOOP \
while( p_packet != NULL ) \
{ \
p_next = p_packet->p_next; \
free( p_packet ); \
p_packet = p_next; \
}
#define BUFFERS_END_LOOP( FLAGS, NB_LIFO ) \
for( i = 0; i < NB_LIFO; i++ ) \
{ \
_data_packet_t * p_next; \
_data_packet_t * p_buf = p_buffers->data[i].p_stack; \
BUFFERS_END_BUFFERS_LOOP; \
} \
#define BUFFERS_END_LOOP_SHARED( FLAGS, NB_LIFO ) \
{ \
/* Free data packets */
\
_data_packet_t * p_next; \
_data_packet_t * p_packet = p_buffers->data.p_stack; \
BUFFERS_END_PACKETS_LOOP; \
} \
\
for( i = 0; i < NB_LIFO; i++ ) \
{ \
_data_buffer_t * p_next; \
_data_buffer_t * p_buf = p_buffers->buffers[i].p_stack; \
BUFFERS_END_BUFFERS_LOOP; \
} \
#define BUFFERS_END( FLAGS, NB_LIFO, STAT_LOOP, LOOP ) \
static void input_BuffersEnd( void * _p_buffers ) \
{ \
_input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
\
if( _p_buffers != NULL ) \
{ \
int i; \
\
if( p_main->b_stats ) \
{ \
int i; \
intf_StatMsg( "input buffers stats: pes: %d packets", \
p_buffers->pes.i_depth ); \
STAT_LOOP( FLAGS, NB_LIFO ); \
} \
\
{ \
/* Free PES */
\
pes_packet_t * p_next, * p_packet = p_buffers->pes.p_stack; \
BUFFERS_END_PACKETS_LOOP; \
} \
\
LOOP( FLAGS, NB_LIFO ); \
\
if( p_buffers->i_allocated ) \
{ \
intf_ErrMsg( "input buffers error: %d bytes have not been" \
" freed, expect memory leak", \
p_buffers->i_allocated ); \
} \
\
vlc_mutex_destroy( &p_buffers->lock ); \
free( _p_buffers ); \
} \
}
#define DECLARE_BUFFERS_END( FLAGS, NB_LIFO ) \
BUFFERS_END( FLAGS, NB_LIFO, BUFFERS_END_STAT, BUFFERS_END_LOOP );
#define DECLARE_BUFFERS_END_SHARED( FLAGS, NB_LIFO ) \
BUFFERS_END( FLAGS, NB_LIFO, BUFFERS_END_STAT_SHARED, \
BUFFERS_END_LOOP_SHARED );
/*****************************************************************************
* input_NewPacket: return a pointer to a data packet of the appropriate size
*****************************************************************************/
#define BUFFERS_NEWPACKET_EXTRA_DECLARATION( FLAGS, NB_LIFO ) \
_data_packet_t ** pp_data = &p_buf;
#define BUFFERS_NEWPACKET_EXTRA_DECLARATION_SHARED( FLAGS, NB_LIFO ) \
_data_packet_t * p_data; \
_data_packet_t ** pp_data = &p_data;
#define BUFFERS_NEWPACKET_EXTRA( FLAGS, NB_LIFO )
#define BUFFERS_NEWPACKET_EXTRA_SHARED( FLAGS, NB_LIFO ) \
/* Find a data packet */
\
if( p_buffers->data.p_stack != NULL ) \
{ \
p_data = p_buffers->data.p_stack; \
p_buffers->data.p_stack = p_data->p_next; \
p_buffers->data.i_depth--; \
} \
else \
{ \
p_data = malloc( sizeof( _data_packet_t ) ); \
if( p_data == NULL ) \
{ \
intf_ErrMsg( "Out of memory" ); \
vlc_mutex_unlock( &p_buffers->lock ); \
return( NULL ); \
} \
} \
\
if( i_size == 0 ) \
{ \
/* Warning : in that case, the data packet is left partly \
* uninitialized ; theorically only input_ShareBuffer may call \
* this. */
\
p_data->p_next = NULL; \
p_data->b_discard_payload = 0; \
return( (data_packet_t *)p_data ); \
}
#define BUFFERS_NEWPACKET_END( FLAGS, NB_LIFO, TYPE ) \
(*pp_data)->p_demux_start = (byte_t *)*pp_data + sizeof( TYPE );
#define BUFFERS_NEWPACKET_END_SHARED( FLAGS, NB_LIFO, TYPE ) \
(*pp_data)->_private.p_buffer = p_buf; \
(*pp_data)->p_demux_start = (byte_t *)(*pp_data)->_private.p_buffer \
+ sizeof( TYPE ); \
/* Initialize refcount */
\
p_buf->i_refcount = 1;
#define BUFFERS_NEWPACKET( FLAGS, NB_LIFO, TYPE, NAME, EXTRA_DECLARATION, \
EXTRA, END ) \
/* This one doesn't take p_buffers->lock. */
\
static __inline__ data_packet_t * _input_NewPacket( void * _p_buffers, \
size_t i_size ) \
{ \
_input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
int i_select; \
TYPE * p_buf; \
EXTRA_DECLARATION( FLAGS, NB_LIFO ); \
\
/* Safety check */
\
if( p_buffers->i_allocated > INPUT_MAX_ALLOCATION ) \
{ \
intf_ErrMsg( "INPUT_MAX_ALLOCATION reached (%d)", \
p_buffers->i_allocated ); \
return NULL; \
} \
\
EXTRA( FLAGS, NB_LIFO ); \
\
for( i_select = 0; i_select < NB_LIFO - 1; i_select++ ) \
{ \
if( i_size <= (2 * p_buffers->NAME[i_select].i_average_size \
+ p_buffers->NAME[i_select + 1].i_average_size) / 3 ) \
{ \
break; \
} \
} \
\
if( p_buffers->NAME[i_select].p_stack != NULL ) \
{ \
/* Take the packet from the cache */
\
p_buf = p_buffers->NAME[i_select].p_stack; \
p_buffers->NAME[i_select].p_stack = p_buf->p_next; \
p_buffers->NAME[i_select].i_depth--; \
\
/* Reallocate the packet if it is too small or too large */
\
if( !(FLAGS & BUFFERS_UNIQUE_SIZE) && \
(p_buf->_private.i_size < i_size \
|| p_buf->_private.i_size > 3 * i_size) ) \
{ \
p_buffers->i_allocated -= p_buf->_private.i_size; \
p_buf = realloc( p_buf, sizeof( TYPE ) + i_size ); \
if( p_buf == NULL ) \
{ \
intf_ErrMsg( "Out of memory" ); \
return NULL; \
} \
p_buf->_private.i_size = i_size; \
p_buffers->i_allocated += i_size; \
} \
} \
else \
{ \
/* Allocate a new packet */
\
p_buf = malloc( sizeof( TYPE ) + i_size ); \
if( p_buf == NULL ) \
{ \
intf_ErrMsg( "Out of memory" ); \
return NULL; \
} \
p_buf->_private.i_size = i_size; \
p_buffers->i_allocated += i_size; \
} \
\
/* Initialize data */
\
END( FLAGS, NB_LIFO, TYPE ); \
(*pp_data)->p_next = NULL; \
(*pp_data)->b_discard_payload = 0; \
(*pp_data)->p_payload_start = (*pp_data)->p_demux_start; \
(*pp_data)->p_payload_end = (*pp_data)->p_payload_start + i_size; \
\
return( (data_packet_t *)*pp_data ); \
} \
\
static data_packet_t * input_NewPacket( void * _p_buffers, size_t i_size ) \
{ \
_input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
data_packet_t * p_data; \
\
/* Safety check */
\
if( !(FLAGS & BUFFERS_UNIQUE_SIZE) && i_size > INPUT_MAX_PACKET_SIZE ) \
{ \
intf_ErrMsg( "Packet too big (%d)", i_size ); \
return NULL; \
} \
\
vlc_mutex_lock( &p_buffers->lock ); \
p_data = _input_NewPacket( _p_buffers, i_size ); \
vlc_mutex_unlock( &p_buffers->lock ); \
return( p_data ); \
}
#define DECLARE_BUFFERS_NEWPACKET( FLAGS, NB_LIFO ) \
BUFFERS_NEWPACKET( FLAGS, NB_LIFO, _data_packet_t, data, \
BUFFERS_NEWPACKET_EXTRA_DECLARATION, BUFFERS_NEWPACKET_EXTRA, \
BUFFERS_NEWPACKET_END )
#define DECLARE_BUFFERS_NEWPACKET_SHARED( FLAGS, NB_LIFO ) \
BUFFERS_NEWPACKET( FLAGS, NB_LIFO, _data_buffer_t, buffers, \
BUFFERS_NEWPACKET_EXTRA_DECLARATION_SHARED, \
BUFFERS_NEWPACKET_EXTRA_SHARED, BUFFERS_NEWPACKET_END_SHARED )
/*****************************************************************************
* input_DeletePacket: put a packet back into the cache
*****************************************************************************/
#define BUFFERS_DELETEPACKET_EXTRA( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \
_data_packet_t * p_buf = p_data;
#define BUFFERS_DELETEPACKET_EXTRA_SHARED( FLAGS, NB_LIFO, DATA_CACHE_SIZE )\
_data_buffer_t * p_buf = (_data_buffer_t *)p_data->_private.p_buffer; \
\
/* Get rid of the data packet */
\
if( p_buffers->data.i_depth < DATA_CACHE_SIZE ) \
{ \
/* Cache not full : store the packet in it */
\
p_data->p_next = p_buffers->data.p_stack; \
p_buffers->data.p_stack = p_data; \
p_buffers->data.i_depth++; \
} \
else \
{ \
free( p_data ); \
} \
\
/* Decrement refcount */
\
p_buf->i_refcount--; \
if( p_buf->i_refcount > 0 ) \
{ \
return; \
}
#define BUFFERS_DELETEPACKETSTACK_EXTRA( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \
_input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
_data_packet_t * p_first = (_data_packet_t *)_p_first; \
_data_packet_t ** pp_last = (_data_packet_t **)_pp_last; \
\
/* Small hopeless optimization */
\
if( (FLAGS & BUFFERS_UNIQUE_SIZE) \
&& p_buffers->data[0].i_depth < DATA_CACHE_SIZE ) \
{ \
p_buffers->data[0].i_depth += i_nb; \
*pp_last = p_buffers->data[0].p_stack; \
p_buffers->data[0].p_stack = p_first; \
} \
else
/* No semicolon after this or you will die */
#define BUFFERS_DELETEPACKETSTACK_EXTRA_SHARED( FLAGS, NB_LIFO, \
DATA_CACHE_SIZE )
#define BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE, TYPE, \
NAME, EXTRA, EXTRA_STACK ) \
/* This one doesn't take p_buffers->lock. */
\
static __inline__ void _input_DeletePacket( void * _p_buffers, \
data_packet_t * _p_data ) \
{ \
_input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
_data_packet_t * p_data = (_data_packet_t *)_p_data; \
int i_select; \
\
while( p_data != NULL ) \
{ \
_data_packet_t * p_next = p_data->p_next; \
\
EXTRA( FLAGS, NB_LIFO, DATA_CACHE_SIZE ); \
\
for( i_select = 0; i_select < NB_LIFO - 1; i_select++ ) \
{ \
if( p_buf->_private.i_size <= \
(2 * p_buffers->NAME[i_select].i_average_size \
+ p_buffers->NAME[i_select + 1].i_average_size) / 3 ) \
{ \
break; \
} \
} \
\
if( p_buffers->NAME[i_select].i_depth < DATA_CACHE_SIZE ) \
{ \
/* Cache not full : store the packet in it */
\
p_buf->p_next = p_buffers->NAME[i_select].p_stack; \
p_buffers->NAME[i_select].p_stack = p_buf; \
p_buffers->NAME[i_select].i_depth++; \
\
if( !(FLAGS & BUFFERS_UNIQUE_SIZE) ) \
{ \
/* Update Bresenham mean (very approximative) */
\
p_buffers->NAME[i_select].i_average_size = \
( p_buf->_private.i_size \
+ p_buffers->NAME[i_select].i_average_size \
* (INPUT_BRESENHAM_NB - 1) ) \
/ INPUT_BRESENHAM_NB; \
} \
} \
else \
{ \
p_buffers->i_allocated -= p_buf->_private.i_size; \
free( p_buf ); \
} \
\
p_data = p_next; \
} \
} \
\
static void input_DeletePacket( void * _p_buffers, data_packet_t * p_data ) \
{ \
_input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
\
vlc_mutex_lock( &p_buffers->lock ); \
_input_DeletePacket( _p_buffers, p_data ); \
vlc_mutex_unlock( &p_buffers->lock ); \
} \
\
/* Delete a chained list of i_nb data packets. -- needed by DeletePES */
\
static __inline__ void _input_DeletePacketStack( void * _p_buffers, \
data_packet_t * _p_first, \
data_packet_t ** _pp_last, \
unsigned int i_nb ) \
{ \
/* Do not add code before, EXTRA_STACK makes its own declarations. */
\
EXTRA_STACK( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \
/* No semicolon - PLEASE */
\
{ \
_input_DeletePacket( _p_buffers, _p_first ); \
} \
}
#define DECLARE_BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \
BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE, _data_packet_t, \
data, BUFFERS_DELETEPACKET_EXTRA, \
BUFFERS_DELETEPACKETSTACK_EXTRA )
#define DECLARE_BUFFERS_DELETEPACKET_SHARED( FLAGS, NB_LIFO, \
DATA_CACHE_SIZE ) \
BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE, _data_buffer_t, \
buffers, BUFFERS_DELETEPACKET_EXTRA_SHARED, \
BUFFERS_DELETEPACKETSTACK_EXTRA_SHARED )
/*****************************************************************************
* input_DeletePacketStack: optimize deleting of a stack of packets when
* knowing much information
*****************************************************************************/
/* AFAIK, this isn't used by anyone - it is here for completion.
* _input_DeletePacketStack is declared in DeletePacket because it is needed
* by DeletePES. */
#define DECLARE_BUFFERS_DELETEPACKETSTACK( FLAGS, NB_LIFO ) \
static void input_DeletePacketStack( void * _p_buffers, \
data_packet_t * p_first, \
data_packet_t ** pp_last, \
unsigned int i_nb ) \
{ \
_input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
\
vlc_mutex_lock( &p_buffers->lock ); \
_input_DeletePacketStack( _p_buffers, p_first, pp_last, i_nb ); \
vlc_mutex_unlock( &p_buffers->lock ); \
}
/*****************************************************************************
* input_NewPES: return a pointer to a new PES packet
*****************************************************************************/
#define DECLARE_BUFFERS_NEWPES( FLAGS, NB_LIFO ) \
static pes_packet_t * input_NewPES( void * _p_buffers ) \
{ \
_input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
pes_packet_t * p_pes; \
\
vlc_mutex_lock( &p_buffers->lock ); \
\
if( p_buffers->pes.p_stack != NULL ) \
{ \
p_pes = p_buffers->pes.p_stack; \
p_buffers->pes.p_stack = p_pes->p_next; \
p_buffers->pes.i_depth--; \
} \
else \
{ \
p_pes = malloc( sizeof( pes_packet_t ) ); \
if( p_pes == NULL ) \
{ \
intf_ErrMsg( "Out of memory" ); \
vlc_mutex_unlock( &p_buffers->lock ); \
return( NULL ); \
} \
} \
\
vlc_mutex_unlock( &p_buffers->lock ); \
\
/* Initialize data */
\
p_pes->p_next = NULL; \
p_pes->b_data_alignment = p_pes->b_discontinuity = \
p_pes->i_pts = p_pes->i_dts = 0; \
p_pes->i_pes_size = 0; \
p_pes->p_first = p_pes->p_last = NULL; \
p_pes->i_nb_data = 0; \
\
return( p_pes ); \
}
/*****************************************************************************
* input_DeletePES: put a pes and all data packets back into the cache
*****************************************************************************/
#define DECLARE_BUFFERS_DELETEPES( FLAGS, NB_LIFO, PES_CACHE_SIZE ) \
static void input_DeletePES( void * _p_buffers, pes_packet_t * p_pes ) \
{ \
_input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
\
vlc_mutex_lock( &p_buffers->lock ); \
\
while( p_pes != NULL ) \
{ \
pes_packet_t * p_next = p_pes->p_next; \
\
/* Delete all data packets */
\
if( p_pes->p_first != NULL ) \
{ \
_input_DeletePacketStack( _p_buffers, p_pes->p_first, \
&p_pes->p_last->p_next, \
p_pes->i_nb_data ); \
} \
\
if( p_buffers->pes.i_depth < PES_CACHE_SIZE ) \
{ \
/* Cache not full : store the packet in it */
\
p_pes->p_next = p_buffers->pes.p_stack; \
p_buffers->pes.p_stack = p_pes; \
p_buffers->pes.i_depth++; \
} \
else \
{ \
free( p_pes ); \
} \
\
p_pes = p_next; \
} \
\
vlc_mutex_unlock( &p_buffers->lock ); \
}
/*****************************************************************************
* input_BuffersToIO: return an IO vector (only with BUFFERS_UNIQUE_SIZE)
*****************************************************************************/
#define DECLARE_BUFFERS_TOIO( FLAGS, BUFFER_SIZE ) \
static data_packet_t * input_BuffersToIO( void * _p_buffers, \
struct iovec * p_iovec, int i_nb )\
{ \
_input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
data_packet_t * p_data = NULL; \
int i; \
\
vlc_mutex_lock( &p_buffers->lock ); \
\
for( i = i_nb - 1; i >= 0; i-- ) \
{ \
data_packet_t * p_next = _input_NewPacket( _p_buffers, \
BUFFER_SIZE
/* UNIQUE_SIZE */
); \
if( p_next == NULL ) \
{ \
_input_DeletePacket( _p_buffers, p_data ); \
return( NULL ); \
} \
\
p_iovec[i].iov_base = p_next->p_demux_start; \
p_iovec[i].iov_len = BUFFER_SIZE; \
p_next->p_next = p_data; \
p_data = p_next; \
} \
\
vlc_mutex_unlock( &p_buffers->lock ); \
\
return( p_data ); \
}
/*****************************************************************************
* input_ShareBuffer: return a new data_packet to the same buffer
*****************************************************************************/
#define DECLARE_BUFFERS_SHAREBUFFER( FLAGS ) \
static data_packet_t * input_ShareBuffer( void * _p_buffers, \
data_packet_t * _p_shared_data ) \
{ \
_input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
_data_packet_t * p_shared_data = (_data_packet_t *)_p_shared_data; \
_data_packet_t * p_data; \
_data_buffer_t * p_buf = p_shared_data->_private.p_buffer; \
\
vlc_mutex_lock( &p_buffers->lock ); \
\
/* Get new data_packet_t, without a buffer through a special backdoor \
* in _input_NewPacket. */
\
p_data = (_data_packet_t *)_input_NewPacket( _p_buffers, 0 ); \
\
/* Finish initialization of p_data */
\
p_data->_private.p_buffer = p_shared_data->_private.p_buffer; \
p_data->p_demux_start = p_data->p_payload_start \
= (byte_t *)p_shared_data->_private.p_buffer \
+ sizeof( _data_buffer_t ); \
p_data->p_payload_end = p_data->p_demux_start + p_buf->_private.i_size; \
\
/* Update refcount */
\
p_buf->i_refcount++; \
\
vlc_mutex_unlock( &p_buffers->lock ); \
\
return( (data_packet_t *)p_data ); \
}
/*
...
...
include/modules_export.h
View file @
d5b04453
...
...
@@ -77,15 +77,6 @@
(p_symbols)->input_DemuxTS = input_DemuxTS; \
(p_symbols)->input_DemuxPSI = input_DemuxPSI; \
(p_symbols)->input_ClockManageControl = input_ClockManageControl; \
(p_symbols)->input_NetlistInit = input_NetlistInit; \
(p_symbols)->input_NetlistGetiovec = input_NetlistGetiovec; \
(p_symbols)->input_NetlistMviovec = input_NetlistMviovec; \
(p_symbols)->input_NetlistNewPacket = input_NetlistNewPacket; \
(p_symbols)->input_NetlistNewPtr = input_NetlistNewPtr; \
(p_symbols)->input_NetlistNewPES = input_NetlistNewPES; \
(p_symbols)->input_NetlistDeletePacket = input_NetlistDeletePacket; \
(p_symbols)->input_NetlistDeletePES = input_NetlistDeletePES; \
(p_symbols)->input_NetlistEnd = input_NetlistEnd; \
(p_symbols)->aout_CreateFifo = aout_CreateFifo; \
(p_symbols)->aout_DestroyFifo = aout_DestroyFifo; \
(p_symbols)->vout_CreateThread = vout_CreateThread; \
...
...
plugins/ac3_adec/ac3_adec.c
View file @
d5b04453
...
...
@@ -2,7 +2,7 @@
* ac3_adec.c: ac3 decoder module main file
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: ac3_adec.c,v 1.5.2.
1 2001/12/30 06:06:00 sam
Exp $
* $Id: ac3_adec.c,v 1.5.2.
2 2001/12/31 01:21:44 massiot
Exp $
*
* Authors: Michel Lespinasse <walken@zoy.org>
*
...
...
@@ -171,12 +171,12 @@ static int decoder_Run ( decoder_config_t * p_config )
sync
=
1
;
}
if
(
DECODER_FIFO_START
(
*
p_ac3thread
->
p_fifo
)
->
i_pts
)
if
(
p_ac3thread
->
p_fifo
->
p_first
->
i_pts
)
{
p_ac3thread
->
p_aout_fifo
->
date
[
p_ac3thread
->
p_aout_fifo
->
l_end_frame
]
=
DECODER_FIFO_START
(
*
p_ac3thread
->
p_fifo
)
->
i_pts
;
DECODER_FIFO_START
(
*
p_ac3thread
->
p_fifo
)
->
i_pts
=
0
;
p_ac3thread
->
p_fifo
->
p_first
->
i_pts
;
p_ac3thread
->
p_fifo
->
p_first
->
i_pts
=
0
;
}
else
{
p_ac3thread
->
p_aout_fifo
->
date
[
p_ac3thread
->
p_aout_fifo
->
l_end_frame
]
=
...
...
plugins/ac3_spdif/ac3_spdif.c
View file @
d5b04453
...
...
@@ -2,7 +2,7 @@
* ac3_spdif.c: ac3 pass-through to external decoder with enabled soundcard
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: ac3_spdif.c,v 1.5.2.
1 2001/12/30 06:06:00 sam
Exp $
* $Id: ac3_spdif.c,v 1.5.2.
2 2001/12/31 01:21:44 massiot
Exp $
*
* Authors: Stphane Borel <stef@via.ecp.fr>
* Juha Yrjola <jyrjola@cc.hut.fi>
...
...
@@ -347,7 +347,7 @@ static void BitstreamCallback ( bit_stream_t * p_bit_stream,
p_bit_stream
->
p_byte
+=
3
;
p_spdif
->
i_pts
=
DECODER_FIFO_START
(
*
p_bit_stream
->
p_decoder_fifo
)
->
i_pts
;
DECODER_FIFO_START
(
*
p_bit_stream
->
p_decoder_fifo
)
->
i_pts
=
0
;
p_bit_stream
->
p_decoder_fifo
->
p_first
->
i_pts
;
p_bit_stream
->
p_decoder_fifo
->
p_first
->
i_pts
=
0
;
}
}
plugins/dvd/input_dvd.c
View file @
d5b04453
...
...
@@ -10,7 +10,7 @@
* -dvd_udf to find files
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: input_dvd.c,v 1.105.2.
1 2001/12/29 23:35:10 sam
Exp $
* $Id: input_dvd.c,v 1.105.2.
2 2001/12/31 01:21:44 massiot
Exp $
*
* Author: Stphane Borel <stef@via.ecp.fr>
*
...
...
@@ -93,10 +93,6 @@
/* how many blocks DVDRead will read in each loop */
#define DVD_BLOCK_READ_ONCE 64
#define DVD_DATA_READ_ONCE (4 * DVD_BLOCK_READ_ONCE)
/* Size of netlist */
#define DVD_NETLIST_SIZE 256
/*****************************************************************************
* Local prototypes
...
...
@@ -119,6 +115,21 @@ static int DVDFindCell( thread_dvd_data_t * );
static
int
DVDFindSector
(
thread_dvd_data_t
*
);
static
int
DVDChapterSelect
(
thread_dvd_data_t
*
,
int
);
/*****************************************************************************
* Declare a buffer manager
*****************************************************************************/
#define FLAGS BUFFERS_UNIQUE_SIZE
#define NB_LIFO 1
DECLARE_BUFFERS_SHARED
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_INIT
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_END_SHARED
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_NEWPACKET_SHARED
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_DELETEPACKET_SHARED
(
FLAGS
,
NB_LIFO
,
1000
);
DECLARE_BUFFERS_NEWPES
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_DELETEPES
(
FLAGS
,
NB_LIFO
,
1000
);
DECLARE_BUFFERS_TOIO
(
FLAGS
,
DVD_LB_SIZE
);
DECLARE_BUFFERS_SHAREBUFFER
(
FLAGS
);
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
* we don't pollute the namespace too much.
...
...
@@ -136,10 +147,10 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
input
.
pf_set_area
=
DVDSetArea
;
input
.
pf_set_program
=
DVDSetProgram
;
input
.
pf_demux
=
input_DemuxPS
;
input
.
pf_new_packet
=
input_Ne
tlistNe
wPacket
;
input
.
pf_new_pes
=
input_Ne
tlistNe
wPES
;
input
.
pf_delete_packet
=
input_
Netlist
DeletePacket
;
input
.
pf_delete_pes
=
input_
Netlist
DeletePES
;
input
.
pf_new_packet
=
input_NewPacket
;
input
.
pf_new_pes
=
input_NewPES
;
input
.
pf_delete_packet
=
input_DeletePacket
;
input
.
pf_delete_pes
=
input_DeletePES
;
input
.
pf_rewind
=
DVDRewind
;
input
.
pf_seek
=
DVDSeek
;
#undef input
...
...
@@ -194,33 +205,31 @@ static void DVDInit( input_thread_t * p_input )
}
p_input
->
p_plugin_data
=
(
void
*
)
p_dvd
;
p_input
->
p_method_data
=
NULL
;
if
(
(
p_input
->
p_method_data
=
input_BuffersInit
())
==
NULL
)
{
p_input
->
b_error
=
1
;
return
;
}
p_dvd
->
dvdhandle
=
(
dvdcss_handle
)
p_input
->
p_handle
;
if
(
dvdcss_seek
(
p_dvd
->
dvdhandle
,
0
,
DVDCSS_NOFLAGS
)
<
0
)
{
intf_ErrMsg
(
"dvd error: %s"
,
dvdcss_error
(
p_dvd
->
dvdhandle
)
);
input_BuffersEnd
(
p_input
->
p_method_data
);
p_input
->
b_error
=
1
;
return
;
}
/* We read DVD_BLOCK_READ_ONCE in each loop, so the input will receive
* DVD_DATA_READ_ONCE at most */
/* We read DVD_BLOCK_READ_ONCE in each loop */
p_dvd
->
i_block_once
=
DVD_BLOCK_READ_ONCE
;
/* this value mustn't be modifed */
p_input
->
i_read_once
=
DVD_DATA_READ_ONCE
;
/* Reading structures initialisation */
input_NetlistInit
(
p_input
,
DVD_NETLIST_SIZE
,
2
*
DVD_NETLIST_SIZE
,
DVD_NETLIST_SIZE
,
DVD_LB_SIZE
,
p_dvd
->
i_block_once
);
intf_WarnMsg
(
2
,
"dvd info: netlist initialized"
);
/* Ifo allocation & initialisation */
if
(
IfoCreate
(
p_dvd
)
<
0
)
{
intf_ErrMsg
(
"dvd error: allcation error in ifo"
);
free
(
p_dvd
);
input_BuffersEnd
(
p_input
->
p_method_data
);
p_input
->
b_error
=
1
;
return
;
}
...
...
@@ -230,6 +239,7 @@ static void DVDInit( input_thread_t * p_input )
intf_ErrMsg
(
"dvd error: fatal failure in ifo"
);
IfoDestroy
(
p_dvd
->
p_ifo
);
free
(
p_dvd
);
input_BuffersEnd
(
p_input
->
p_method_data
);
p_input
->
b_error
=
1
;
return
;
}
...
...
@@ -289,9 +299,8 @@ static void DVDInit( input_thread_t * p_input )
i_chapter
=
1
;
}
p_input
->
stream
.
pp_areas
[
i_title
]
->
i_part
=
i_chapter
;
p_area
=
p_input
->
stream
.
pp_areas
[
i_title
];
p_area
->
i_part
=
i_chapter
;
/* set title, chapter, audio and subpic */
DVDSetArea
(
p_input
,
p_area
);
...
...
@@ -322,7 +331,7 @@ static void DVDOpen( struct input_thread_s *p_input )
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
/* Parse input string : dvd:device[
:
rawdevice] */
/* Parse input string : dvd:device[
@
rawdevice] */
if
(
strlen
(
p_input
->
p_source
)
>
4
&&
!
strncasecmp
(
p_input
->
p_source
,
"dvd:"
,
4
)
)
{
...
...
@@ -383,7 +392,7 @@ static void DVDEnd( input_thread_t * p_input )
free
(
p_dvd
);
input_
NetlistEnd
(
p_input
);
input_
BuffersEnd
(
p_input
->
p_method_data
);
}
/*****************************************************************************
...
...
@@ -816,20 +825,17 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
return
0
;
}
/*****************************************************************************
* DVDRead: reads data packets
into the netlist
.
* DVDRead: reads data packets.
*****************************************************************************
* Returns -1 in case of error, 0 i
f everything went well, and 1 in case
of
*
EOF
.
* Returns -1 in case of error, 0 i
n case of EOF, otherwise the number
of
*
packets
.
*****************************************************************************/
static
int
DVDRead
(
input_thread_t
*
p_input
,
data_packet_t
**
pp_
packets
)
data_packet_t
**
pp_
data
)
{
thread_dvd_data_t
*
p_dvd
;
netlist_t
*
p_netlist
;
struct
iovec
*
p_vec
;
struct
data_packet_s
*
pp_data
[
DVD_DATA_READ_ONCE
];
struct
iovec
p_vec
[
DVD_BLOCK_READ_ONCE
];
u8
*
pi_cur
;
int
i_block_once
;
int
i_packet_size
;
...
...
@@ -838,12 +844,12 @@ static int DVDRead( input_thread_t * p_input,
int
i_pos
;
int
i_read_blocks
;
int
i_sector
;
boolean_t
b_eof
;
boolean_t
b_eot
;
boolean_t
b_eoc
;
data_packet_t
*
p_data
;
p_dvd
=
(
thread_dvd_data_t
*
)
p_input
->
p_plugin_data
;
p_netlist
=
(
netlist_t
*
)
p_input
->
p_method_data
;
*
pp_data
=
NULL
;
b_eoc
=
0
;
i_sector
=
p_dvd
->
i_title_start
+
p_dvd
->
i_sector
;
...
...
@@ -861,7 +867,6 @@ static int DVDRead( input_thread_t * p_input,
/* Find cell index in adress map */
if
(
DVDFindSector
(
p_dvd
)
<
0
)
{
pp_packets
[
0
]
=
NULL
;
intf_ErrMsg
(
"dvd error: can't find next cell"
);
return
1
;
}
...
...
@@ -907,23 +912,20 @@ static int DVDRead( input_thread_t * p_input,
/*
intf_WarnMsg( 2, "Sector: 0x%x Read: %d Chapter: %d", p_dvd->i_sector, i_block_once, p_dvd->i_chapter );
*/
p_netlist
->
i_read_once
=
i_block_once
;
/* Get an iovec pointer */
if
(
(
p_vec
=
input_NetlistGetiovec
(
p_netlist
)
)
==
NULL
)
/* Get iovecs */
*
pp_data
=
p_data
=
input_BuffersToIO
(
p_input
->
p_method_data
,
p_vec
,
DVD_BLOCK_READ_ONCE
);
if
(
p_data
==
NULL
)
{
intf_ErrMsg
(
"dvd error: can't get iovec"
);
return
-
1
;
return
(
-
1
);
}
/* Reads from DVD */
i_read_blocks
=
dvdcss_readv
(
p_dvd
->
dvdhandle
,
p_vec
,
i_block_once
,
DVDCSS_READ_DECRYPT
);
/* Update netlist indexes: we don't do it in DVDGetiovec since we
* need know the real number of blocks read */
input_NetlistMviovec
(
p_netlist
,
i_read_blocks
,
pp_data
);
/* Update global position */
p_dvd
->
i_sector
+=
i_read_blocks
;
...
...
@@ -932,42 +934,50 @@ intf_WarnMsg( 2, "Sector: 0x%x Read: %d Chapter: %d", p_dvd->i_sector, i_block_o
/* Read headers to compute payload length */
for
(
i_iovec
=
0
;
i_iovec
<
i_read_blocks
;
i_iovec
++
)
{
data_packet_t
*
p_current
=
p_data
;
i_pos
=
0
;
while
(
i_pos
<
p_netlist
->
i_buffer_size
)
while
(
i_pos
<
DVD_LB_SIZE
)
{
pi_cur
=
(
u8
*
)
p_vec
[
i_iovec
].
iov_base
+
i_pos
;
/*
d
efault header */
/*
D
efault header */
if
(
U32_AT
(
pi_cur
)
!=
0x1BA
)
{
/* That's the case for all packets, except pack header. */
i_packet_size
=
U16_AT
(
pi_cur
+
4
);
pp_packets
[
i_packet
]
=
input_NetlistNewPtr
(
p_netlist
);
(
*
pp_data
[
i_iovec
]
->
pi_refcount
)
++
;
pp_packets
[
i_packet
]
->
pi_refcount
=
pp_data
[
i_iovec
]
->
pi_refcount
;
pp_packets
[
i_packet
]
->
p_buffer
=
pp_data
[
i_iovec
]
->
p_buffer
;
}
else
{
/* MPEG-2 Pack header. */
i_packet_size
=
8
;
pp_packets
[
i_packet
]
=
pp_data
[
i_iovec
];
}
pp_packets
[
i_packet
]
->
p_payload_start
=
pp_packets
[
i_packet
]
->
p_buffer
+
i_pos
;
if
(
i_pos
!=
0
)
{
*
pp_data
=
input_ShareBuffer
(
p_input
->
p_method_data
,
p_current
);
}
else
{
*
pp_data
=
p_data
;
p_data
=
p_data
->
p_next
;
}
(
*
pp_data
)
->
p_payload_start
=
(
*
pp_data
)
->
p_demux_start
=
(
*
pp_data
)
->
p_demux_start
+
i_pos
;
pp_packets
[
i_packet
]
->
p_payload_end
=
pp_packets
[
i_packet
]
->
p_payload_start
+
i_packet_size
+
6
;
(
*
pp_data
)
->
p_payload_end
=
(
*
pp_data
)
->
p_payload_start
+
i_packet_size
+
6
;
i_packet
++
;
i_pos
+=
i_packet_size
+
6
;
pp_data
=
&
(
*
pp_data
)
->
p_next
;
}
}
pp_packets
[
i_packet
]
=
NULL
;
p_input
->
pf_delete_packet
(
p_input
->
p_method_data
,
p_data
);
*
pp_data
=
NULL
;
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
...
...
@@ -981,33 +991,32 @@ intf_WarnMsg( 2, "Sector: 0x%x Read: %d Chapter: %d", p_dvd->i_sector, i_block_o
p_input
->
stream
.
p_selected_area
->
i_part
=
p_dvd
->
i_chapter
;
}
b_eot
=
!
(
p_input
->
stream
.
p_selected_area
->
i_tell
<
p_input
->
stream
.
p_selected_area
->
i_size
);
b_eof
=
b_eot
&&
(
(
p_dvd
->
i_title
+
1
)
>=
p_input
->
stream
.
i_area_nb
);
if
(
b_eof
)
if
(
p_input
->
stream
.
p_selected_area
->
i_tell
>=
p_input
->
stream
.
p_selected_area
->
i_size
)
{
if
(
(
p_dvd
->
i_title
+
1
)
>=
p_input
->
stream
.
i_area_nb
)
{
/* EOF */
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
return
1
;
return
0
;
}
if
(
b_eot
)
{
/* EOT */
intf_WarnMsg
(
4
,
"dvd info: new title"
);
p_dvd
->
i_title
++
;
DVDSetArea
(
p_input
,
p_input
->
stream
.
pp_areas
[
p_dvd
->
i_title
]
);
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
return
0
;
return
(
i_packet
)
;
}
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
if
(
i_read_blocks
=
=
i_block_once
)
if
(
i_read_blocks
!
=
i_block_once
)
{
return
0
;
return
-
1
;
}
return
-
1
;
return
(
i_packet
)
;
}
/*****************************************************************************
...
...
plugins/dvdread/input_dvdread.c
View file @
d5b04453
...
...
@@ -6,7 +6,7 @@
* It depends on: libdvdread for ifo files and block reading.
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: input_dvdread.c,v 1.3
2001/12/07 18:33:07 sam
Exp $
* $Id: input_dvdread.c,v 1.3
.2.1 2001/12/31 01:21:44 massiot
Exp $
*
* Author: Stphane Borel <stef@via.ecp.fr>
*
...
...
@@ -85,10 +85,6 @@
/* how many blocks DVDRead will read in each loop */
#define DVD_BLOCK_READ_ONCE 64
#define DVD_DATA_READ_ONCE (4 * DVD_BLOCK_READ_ONCE)
/* Size of netlist */
#define DVD_NETLIST_SIZE 512
/*****************************************************************************
* Local prototypes
...
...
@@ -100,6 +96,7 @@ static void DvdReadEnd ( struct input_thread_s * );
static
void
DvdReadOpen
(
struct
input_thread_s
*
);
static
void
DvdReadClose
(
struct
input_thread_s
*
);
static
int
DvdReadSetArea
(
struct
input_thread_s
*
,
struct
input_area_s
*
);
static
int
DvdReadSetProgram
(
struct
input_thread_s
*
,
pgrm_descriptor_t
*
);
static
int
DvdReadRead
(
struct
input_thread_s
*
,
data_packet_t
**
);
static
void
DvdReadSeek
(
struct
input_thread_s
*
,
off_t
);
static
int
DvdReadRewind
(
struct
input_thread_s
*
);
...
...
@@ -108,6 +105,21 @@ static int DvdReadRewind ( struct input_thread_s * );
static
void
DvdReadHandleDSI
(
thread_dvd_data_t
*
p_dvd
,
u8
*
p_data
);
static
void
DvdReadFindCell
(
thread_dvd_data_t
*
p_dvd
);
/*****************************************************************************
* Declare a buffer manager
*****************************************************************************/
#define FLAGS BUFFERS_UNIQUE_SIZE
#define NB_LIFO 1
DECLARE_BUFFERS_SHARED
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_INIT
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_END_SHARED
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_NEWPACKET_SHARED
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_DELETEPACKET_SHARED
(
FLAGS
,
NB_LIFO
,
1000
);
DECLARE_BUFFERS_NEWPES
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_DELETEPES
(
FLAGS
,
NB_LIFO
,
1000
);
DECLARE_BUFFERS_TOIO
(
FLAGS
,
DVD_VIDEO_LB_LEN
);
DECLARE_BUFFERS_SHAREBUFFER
(
FLAGS
);
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
* we don't pollute the namespace too much.
...
...
@@ -123,11 +135,12 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
input
.
pf_init_bit_stream
=
InitBitstream
;
input
.
pf_read
=
DvdReadRead
;
input
.
pf_set_area
=
DvdReadSetArea
;
input
.
pf_set_program
=
DvdReadSetProgram
;
input
.
pf_demux
=
input_DemuxPS
;
input
.
pf_new_packet
=
input_Ne
tlistNe
wPacket
;
input
.
pf_new_pes
=
input_Ne
tlistNe
wPES
;
input
.
pf_delete_packet
=
input_
Netlist
DeletePacket
;
input
.
pf_delete_pes
=
input_
Netlist
DeletePES
;
input
.
pf_new_packet
=
input_NewPacket
;
input
.
pf_new_pes
=
input_NewPES
;
input
.
pf_delete_packet
=
input_DeletePacket
;
input
.
pf_delete_pes
=
input_DeletePES
;
input
.
pf_rewind
=
DvdReadRewind
;
input
.
pf_seek
=
DvdReadSeek
;
#undef input
...
...
@@ -157,7 +170,7 @@ static int DvdReadProbe( probedata_t *p_data )
/* If the user specified "dvdread:" then he probably wants
* to use libdvdread */
i_score
=
100
;
psz_name
+=
4
;
psz_name
+=
8
;
}
return
(
i_score
);
...
...
@@ -188,24 +201,22 @@ static void DvdReadInit( input_thread_t * p_input )
p_dvd
->
p_vts_file
=
NULL
;
p_input
->
p_plugin_data
=
(
void
*
)
p_dvd
;
p_input
->
p_method_data
=
NULL
;
/* We read DVD_BLOCK_READ_ONCE in each loop, so the input will receive
* DVD_DATA_READ_ONCE at most */
p_dvd
->
i_block_once
=
DVD_BLOCK_READ_ONCE
;
/* this value mustn't be modifed */
p_input
->
i_read_once
=
DVD_DATA_READ_ONCE
;
if
(
(
p_input
->
p_method_data
=
input_BuffersInit
())
==
NULL
)
{
free
(
p_dvd
);
p_input
->
b_error
=
1
;
return
;
}
/* Reading structures initialisation */
input_NetlistInit
(
p_input
,
DVD_NETLIST_SIZE
,
2
*
DVD_NETLIST_SIZE
,
DVD_NETLIST_SIZE
,
DVD_VIDEO_LB_LEN
,
p_dvd
->
i_block_once
);
intf_WarnMsg
(
2
,
"dvdread info: netlist initialized"
);
/* We read DVD_BLOCK_READ_ONCE in each loop */
p_dvd
->
i_block_once
=
DVD_BLOCK_READ_ONCE
;
/* Ifo allocation & initialisation */
if
(
!
(
p_dvd
->
p_vmg_file
=
ifoOpen
(
p_dvd
->
p_dvdread
,
0
)
)
)
{
intf_ErrMsg
(
"dvdread error: can't open VMG info"
);
DVDClose
(
p_dvd
->
p_dvdread
);
input_BuffersEnd
(
p_input
->
p_method_data
);
free
(
p_dvd
);
p_input
->
b_error
=
1
;
return
;
...
...
@@ -349,9 +360,16 @@ static void DvdReadEnd( input_thread_t * p_input )
ifoClose
(
p_dvd
->
p_vts_file
);
ifoClose
(
p_dvd
->
p_vmg_file
);
/* Close netlist */
input_NetlistEnd
(
p_input
);
p_input
->
p_method_data
=
NULL
;
input_BuffersEnd
(
p_input
->
p_method_data
);
}
/*****************************************************************************
* DvdReadSetProgram: Does nothing, a DVD is mono-program
*****************************************************************************/
static
int
DvdReadSetProgram
(
input_thread_t
*
p_input
,
pgrm_descriptor_t
*
p_program
)
{
return
0
;
}
#define p_pgc p_dvd->p_cur_pgc
...
...
@@ -511,23 +529,24 @@ static int DvdReadSetArea( input_thread_t * p_input, input_area_t * p_area )
}
free
(
p_input
->
stream
.
pp_selected_es
);
input_DelProgram
(
p_input
,
p_input
->
stream
.
p
p_programs
[
0
]
);
input_DelProgram
(
p_input
,
p_input
->
stream
.
p
_selected_program
);
p_input
->
stream
.
pp_selected_es
=
NULL
;
p_input
->
stream
.
i_selected_es_number
=
0
;
}
input_AddProgram
(
p_input
,
0
,
sizeof
(
stream_ps_data_t
)
);
p_input
->
stream
.
p_selected_program
=
p_input
->
stream
.
pp_programs
[
0
];
/* No PSM to read in DVD mode, we already have all information */
p_input
->
stream
.
p
p_programs
[
0
]
->
b_is_ok
=
1
;
p_input
->
stream
.
p
_selected_program
->
b_is_ok
=
1
;
p_es
=
NULL
;
/* ES 0 -> video MPEG2 */
// IfoPrintVideo( p_dvd );
p_es
=
input_AddES
(
p_input
,
p_input
->
stream
.
p
p_programs
[
0
]
,
0xe0
,
0
);
p_es
=
input_AddES
(
p_input
,
p_input
->
stream
.
p
_selected_program
,
0xe0
,
0
);
p_es
->
i_stream_id
=
0xe0
;
p_es
->
i_type
=
MPEG2_VIDEO_ES
;
p_es
->
i_cat
=
VIDEO_ES
;
...
...
@@ -558,7 +577,7 @@ static int DvdReadSetArea( input_thread_t * p_input, input_area_t * p_area )
case
0x00
:
/* AC3 */
i_id
=
(
(
0x80
+
i_position
)
<<
8
)
|
0xbd
;
p_es
=
input_AddES
(
p_input
,
p_input
->
stream
.
p
p_programs
[
0
]
,
i_id
,
0
);
p_input
->
stream
.
p
_selected_program
,
i_id
,
0
);
p_es
->
i_stream_id
=
0xbd
;
p_es
->
i_type
=
AC3_AUDIO_ES
;
p_es
->
b_audio
=
1
;
...
...
@@ -572,7 +591,7 @@ static int DvdReadSetArea( input_thread_t * p_input, input_area_t * p_area )
case
0x03
:
/* MPEG audio */
i_id
=
0xc0
+
i_position
;
p_es
=
input_AddES
(
p_input
,
p_input
->
stream
.
p
p_programs
[
0
]
,
i_id
,
0
);
p_input
->
stream
.
p
_selected_program
,
i_id
,
0
);
p_es
->
i_stream_id
=
i_id
;
p_es
->
i_type
=
MPEG2_AUDIO_ES
;
p_es
->
b_audio
=
1
;
...
...
@@ -586,7 +605,7 @@ static int DvdReadSetArea( input_thread_t * p_input, input_area_t * p_area )
i_id
=
(
(
0xa0
+
i_position
)
<<
8
)
|
0xbd
;
p_es
=
input_AddES
(
p_input
,
p_input
->
stream
.
p
p_programs
[
0
]
,
i_id
,
0
);
p_input
->
stream
.
p
_selected_program
,
i_id
,
0
);
p_es
->
i_stream_id
=
i_id
;
p_es
->
i_type
=
LPCM_AUDIO_ES
;
p_es
->
b_audio
=
1
;
...
...
@@ -651,7 +670,7 @@ static int DvdReadSetArea( input_thread_t * p_input, input_area_t * p_area )
i_id
=
(
(
0x20
+
i_position
)
<<
8
)
|
0xbd
;
p_es
=
input_AddES
(
p_input
,
p_input
->
stream
.
p
p_programs
[
0
]
,
i_id
,
0
);
p_input
->
stream
.
p
_selected_program
,
i_id
,
0
);
p_es
->
i_stream_id
=
0xbd
;
p_es
->
i_type
=
DVD_SPU_ES
;
p_es
->
i_cat
=
SPU_ES
;
...
...
@@ -772,13 +791,11 @@ static int DvdReadSetArea( input_thread_t * p_input, input_area_t * p_area )
* EOF.
*****************************************************************************/
static
int
DvdReadRead
(
input_thread_t
*
p_input
,
data_packet_t
**
pp_
packets
)
data_packet_t
**
pp_
data
)
{
thread_dvd_data_t
*
p_dvd
;
netlist_t
*
p_netlist
;
u8
p_data
[
DVD_VIDEO_LB_LEN
];
struct
iovec
*
p_vec
;
struct
data_packet_s
*
pp_data
[
DVD_DATA_READ_ONCE
];
struct
iovec
p_vec
[
DVD_BLOCK_READ_ONCE
];
u8
*
pi_cur
;
int
i_blocks
;
int
i_read
;
...
...
@@ -786,9 +803,12 @@ static int DvdReadRead( input_thread_t * p_input,
int
i_packet_size
;
int
i_packet
;
int
i_pos
;
data_packet_t
*
p_data_p
;
boolean_t
b_eot
=
0
;
p_dvd
=
(
thread_dvd_data_t
*
)
p_input
->
p_plugin_data
;
p_netlist
=
(
netlist_t
*
)
p_input
->
p_method_data
;
*
pp_data
=
NULL
;
/*
* Playback by cell in this pgc, starting at the cell for our chapter.
...
...
@@ -810,8 +830,11 @@ static int DvdReadRead( input_thread_t * p_input,
return
-
1
;
}
/* basic check to be sure we don't have a empty title
* go to next title if so */
assert
(
p_data
[
41
]
==
0xbf
&&
p_data
[
1027
]
==
0xbf
);
if
(
p_data
[
41
]
==
0xbf
&&
p_data
[
1027
]
==
0xbf
)
{
/*
* Parse the contained dsi packet.
*/
...
...
@@ -825,11 +848,17 @@ static int DvdReadRead( input_thread_t * p_input,
}
assert
(
p_dvd
->
i_pack_len
<
1024
);
/*
Ugly kludge: we send the pack block to the input for it
/* FIXME:
Ugly kludge: we send the pack block to the input for it
* sometimes has a zero scr and restart the sync */
//
p_dvd->i_cur_block ++;
//
p_dvd->i_cur_block ++;
p_dvd
->
i_pack_len
++
;
}
else
{
b_eot
=
1
;
p_dvd
->
i_pack_len
=
0
;
return
1
;
}
}
/*
...
...
@@ -838,13 +867,14 @@ static int DvdReadRead( input_thread_t * p_input,
i_blocks
=
p_dvd
->
i_pack_len
>=
DVD_BLOCK_READ_ONCE
?
DVD_BLOCK_READ_ONCE
:
p_dvd
->
i_pack_len
;
p_dvd
->
i_pack_len
-=
i_blocks
;
p_netlist
->
i_read_once
=
i_blocks
;
/* Get an iovec pointer */
if
(
(
p_vec
=
input_NetlistGetiovec
(
p_netlist
)
)
==
NULL
)
/* Get iovecs */
*
pp_data
=
p_data_p
=
input_BuffersToIO
(
p_input
->
p_method_data
,
p_vec
,
DVD_BLOCK_READ_ONCE
);
if
(
p_data_p
==
NULL
)
{
intf_ErrMsg
(
"dvdread error: can't get iovec"
);
return
-
1
;
return
(
-
1
);
}
/* Reads from DVD */
...
...
@@ -861,18 +891,15 @@ static int DvdReadRead( input_thread_t * p_input,
/*
intf_WarnMsg( 12, "dvdread i_blocks: %d len: %d current: 0x%02x", i_read, p_dvd->i_pack_len, p_dvd->i_cur_block );
*/
/* Update netlist indexes: we don't do it in DVDGetiovec since we
* need know the real number of blocks read */
input_NetlistMviovec
(
p_netlist
,
i_read
,
pp_data
);
i_packet
=
0
;
/* Read headers to compute payload length */
for
(
i_iovec
=
0
;
i_iovec
<
i_read
;
i_iovec
++
)
{
data_packet_t
*
p_current
=
p_data_p
;
i_pos
=
0
;
while
(
i_pos
<
p_netlist
->
i_buffer_size
)
while
(
i_pos
<
DVD_VIDEO_LB_LEN
)
{
pi_cur
=
(
u8
*
)
p_vec
[
i_iovec
].
iov_base
+
i_pos
;
...
...
@@ -881,35 +908,48 @@ static int DvdReadRead( input_thread_t * p_input,
{
/* That's the case for all packets, except pack header. */
i_packet_size
=
U16_AT
(
pi_cur
+
4
);
pp_packets
[
i_packet
]
=
input_NetlistNewPtr
(
p_netlist
);
(
*
pp_data
[
i_iovec
]
->
pi_refcount
)
++
;
pp_packets
[
i_packet
]
->
pi_refcount
=
pp_data
[
i_iovec
]
->
pi_refcount
;
pp_packets
[
i_packet
]
->
p_buffer
=
pp_data
[
i_iovec
]
->
p_buffer
;
}
else
{
/* MPEG-2 Pack header. */
i_packet_size
=
8
;
pp_packets
[
i_packet
]
=
pp_data
[
i_iovec
];
}
if
(
i_pos
!=
0
)
{
*
pp_data
=
input_ShareBuffer
(
p_input
->
p_method_data
,
p_current
);
}
else
{
*
pp_data
=
p_data_p
;
p_data_p
=
p_data_p
->
p_next
;
}
(
*
pp_data
)
->
p_payload_start
=
(
*
pp_data
)
->
p_demux_start
=
(
*
pp_data
)
->
p_demux_start
+
i_pos
;
pp_packets
[
i_packet
]
->
p_payload_start
=
pp_packets
[
i_packet
]
->
p_buffer
+
i_pos
;
pp_packets
[
i_packet
]
->
p_payload_end
=
pp_packets
[
i_packet
]
->
p_payload_start
+
i_packet_size
+
6
;
(
*
pp_data
)
->
p_payload_end
=
(
*
pp_data
)
->
p_payload_start
+
i_packet_size
+
6
;
pp_packets
[
i_packet
]
->
p_next
=
NULL
;
pp_packets
[
i_packet
]
->
b_discard_payload
=
0
;
//
pp_packets[i_packet]->p_next = NULL;
//
pp_packets[i_packet]->b_discard_payload = 0;
i_packet
++
;
i_pos
+=
i_packet_size
+
6
;
pp_data
=
&
(
*
pp_data
)
->
p_next
;
}
}
pp_packets
[
i_packet
]
=
NULL
;
p_input
->
pf_delete_packet
(
p_input
->
p_method_data
,
p_data_p
);
*
pp_data
=
NULL
;
while
(
p_data_p
!=
NULL
)
{
data_packet_t
*
p_next
=
p_data_p
->
p_next
;
p_input
->
pf_delete_packet
(
p_input
->
p_method_data
,
p_data_p
);
p_data_p
=
p_next
;
}
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
...
...
@@ -925,6 +965,24 @@ static int DvdReadRead( input_thread_t * p_input,
p_dvd
->
b_eoc
=
0
;
}
if
(
p_input
->
stream
.
p_selected_area
->
i_tell
>=
p_input
->
stream
.
p_selected_area
->
i_size
||
b_eot
)
{
if
(
(
p_input
->
stream
.
p_selected_area
->
i_id
+
1
)
>=
p_input
->
stream
.
i_area_nb
)
{
/* EOF */
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
return
1
;
}
/* EOT */
intf_WarnMsg
(
4
,
"dvd info: new title"
);
DvdReadSetArea
(
p_input
,
p_input
->
stream
.
pp_areas
[
p_input
->
stream
.
p_selected_area
->
i_id
+
1
]
);
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
return
0
;
}
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
...
...
plugins/lpcm_adec/lpcm_adec.c
View file @
d5b04453
...
...
@@ -2,7 +2,7 @@
* lpcm_decoder_thread.c: lpcm decoder thread
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: lpcm_adec.c,v 1.3.2.
1 2001/12/30 06:06:00 sam
Exp $
* $Id: lpcm_adec.c,v 1.3.2.
2 2001/12/31 01:21:44 massiot
Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Henri Fallon <henri@videolan.org>
...
...
@@ -187,11 +187,11 @@ void DecodeFrame( lpcmdec_thread_t * p_lpcmdec )
int
i_loop
;
byte_t
byte1
,
byte2
;
if
(
DECODER_FIFO_START
(
*
p_lpcmdec
->
p_fifo
)
->
i_pts
)
if
(
p_lpcmdec
->
p_fifo
->
p_first
->
i_pts
)
{
p_lpcmdec
->
p_aout_fifo
->
date
[
p_lpcmdec
->
p_aout_fifo
->
l_end_frame
]
=
DECODER_FIFO_START
(
*
p_lpcmdec
->
p_fifo
)
->
i_pts
;
DECODER_FIFO_START
(
*
p_lpcmdec
->
p_fifo
)
->
i_pts
=
0
;
p_lpcmdec
->
p_fifo
->
p_first
->
i_pts
;
p_lpcmdec
->
p_fifo
->
p_first
->
i_pts
=
0
;
}
else
{
...
...
plugins/mad_adec/mad_libmad.c
View file @
d5b04453
...
...
@@ -62,9 +62,9 @@ enum mad_flow libmad_input(void *data, struct mad_stream *p_libmad_stream)
byte_t
buffer
[
ADEC_FRAME_SIZE
];
/* Store time stamp of current frame */
if
(
DECODER_FIFO_START
(
*
p_mad_adec
->
p_fifo
)
->
i_pts
)
{
p_mad_adec
->
i_pts_save
=
DECODER_FIFO_START
(
*
p_mad_adec
->
p_fifo
)
->
i_pts
;
DECODER_FIFO_START
(
*
p_mad_adec
->
p_fifo
)
->
i_pts
=
0
;
if
(
p_mad_adec
->
p_fifo
->
p_first
->
i_pts
)
{
p_mad_adec
->
i_pts_save
=
p_mad_adec
->
p_fifo
->
p_first
->
i_pts
;
p_mad_adec
->
p_fifo
->
p_first
->
i_pts
=
0
;
}
else
{
p_mad_adec
->
i_pts_save
=
LAST_MDATE
;
...
...
plugins/mpeg/input_es.c
View file @
d5b04453
...
...
@@ -2,7 +2,7 @@
* input_es.c: Elementary Stream demux and packet management
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: input_es.c,v 1.16.2.
1 2001/12/10 15:56:57
massiot Exp $
* $Id: input_es.c,v 1.16.2.
2 2001/12/31 01:21:45
massiot Exp $
*
* Author: Christophe Massiot <massiot@via.ecp.fr>
*
...
...
@@ -75,7 +75,7 @@
*****************************************************************************/
static
int
ESProbe
(
probedata_t
*
);
static
int
ESRead
(
struct
input_thread_s
*
,
data_packet_t
*
p_packets
[
INPUT_READ_ONCE
]
);
data_packet_t
*
*
);
static
void
ESInit
(
struct
input_thread_s
*
);
static
void
ESEnd
(
struct
input_thread_s
*
);
static
void
ESSeek
(
struct
input_thread_s
*
,
off_t
);
...
...
@@ -89,6 +89,20 @@ static void ESInitBitstream( struct bit_stream_s *, struct decoder_fifo_s *,
void
*
);
/*****************************************************************************
* Declare a buffer manager
*****************************************************************************/
#define FLAGS BUFFERS_UNIQUE_SIZE
#define NB_LIFO 1
DECLARE_BUFFERS_EMBEDDED
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_INIT
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_END
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_NEWPACKET
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_DELETEPACKET
(
FLAGS
,
NB_LIFO
,
150
);
DECLARE_BUFFERS_NEWPES
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_DELETEPES
(
FLAGS
,
NB_LIFO
,
150
);
DECLARE_BUFFERS_TOIO
(
FLAGS
,
ES_PACKET_SIZE
);
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
* we don't pollute the namespace too much.
...
...
@@ -106,10 +120,10 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
input
.
pf_set_program
=
ESSetProgram
;
input
.
pf_read
=
ESRead
;
input
.
pf_demux
=
ESDemux
;
input
.
pf_new_packet
=
input_Ne
tlistNe
wPacket
;
input
.
pf_new_pes
=
input_Ne
tlistNe
wPES
;
input
.
pf_delete_packet
=
input_
Netlist
DeletePacket
;
input
.
pf_delete_pes
=
input_
Netlist
DeletePES
;
input
.
pf_new_packet
=
input_NewPacket
;
input
.
pf_new_pes
=
input_NewPES
;
input
.
pf_delete_packet
=
input_DeletePacket
;
input
.
pf_delete_pes
=
input_DeletePES
;
input
.
pf_rewind
=
NULL
;
input
.
pf_seek
=
ESSeek
;
#undef input
...
...
@@ -141,27 +155,24 @@ static void ESInit( input_thread_t * p_input )
{
es_descriptor_t
*
p_es
;
p_input
->
p_method_data
=
NULL
;
/* Initialize netlist */
if
(
input_NetlistInit
(
p_input
,
NB_DATA
,
NB_DATA
,
NB_PES
,
ES_PACKET_SIZE
,
INPUT_READ_ONCE
)
)
if
(
(
p_input
->
p_method_data
=
input_BuffersInit
())
==
NULL
)
{
intf_ErrMsg
(
"ES input : Could not initialize netlist"
)
;
p_input
->
b_error
=
1
;
return
;
}
/* FIXME : detect if InitStream failed */
input_InitStream
(
p_input
,
0
);
input_AddProgram
(
p_input
,
0
,
0
);
p_input
->
stream
.
p_selected_program
=
p_input
->
stream
.
pp_programs
[
0
];
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
p_es
=
input_AddES
(
p_input
,
p_input
->
stream
.
p
p_programs
[
0
]
,
0xE0
,
0
);
p_es
=
input_AddES
(
p_input
,
p_input
->
stream
.
p
_selected_program
,
0xE0
,
0
);
p_es
->
i_stream_id
=
0xE0
;
p_es
->
i_type
=
MPEG1_VIDEO_ES
;
p_es
->
i_cat
=
VIDEO_ES
;
input_SelectES
(
p_input
,
p_es
);
p_input
->
stream
.
p_selected_area
->
i_tell
=
0
;
p_input
->
stream
.
p
p_programs
[
0
]
->
b_is_ok
=
1
;
p_input
->
stream
.
p
_selected_program
->
b_is_ok
=
1
;
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
}
...
...
@@ -170,49 +181,57 @@ static void ESInit( input_thread_t * p_input )
*****************************************************************************/
static
void
ESEnd
(
input_thread_t
*
p_input
)
{
input_BuffersEnd
(
p_input
->
p_method_data
);
}
/*****************************************************************************
* ESRead: reads data packets
*****************************************************************************
* Returns -1 in case of error, 0 i
f everything went well, and 1 in case
of
*
EOF
.
* Returns -1 in case of error, 0 i
n case of EOF, otherwise the number
of
*
packets
.
*****************************************************************************/
static
int
ESRead
(
input_thread_t
*
p_input
,
data_packet_t
*
pp_packets
[
INPUT_READ_ONCE
]
)
data_packet_t
*
*
pp_data
)
{
int
i_read
;
struct
iovec
*
p_iovec
;
struct
iovec
p_iovec
[
ES_READ_ONCE
];
data_packet_t
*
p_data
;
/* Get iovecs */
p_iovec
=
input_NetlistGetiovec
(
p_input
->
p_method_data
);
*
pp_data
=
p_data
=
input_BuffersToIO
(
p_input
->
p_method_data
,
p_iovec
,
ES_READ_ONCE
);
if
(
p_
iovec
==
NULL
)
if
(
p_
data
==
NULL
)
{
return
(
-
1
);
/* empty netlist */
return
(
-
1
);
}
memset
(
pp_packets
,
0
,
INPUT_READ_ONCE
*
sizeof
(
data_packet_t
*
)
);
i_read
=
readv
(
p_input
->
i_handle
,
p_iovec
,
INPUT_READ_ONCE
);
i_read
=
readv
(
p_input
->
i_handle
,
p_iovec
,
ES_READ_ONCE
);
if
(
i_read
==
-
1
)
{
intf_ErrMsg
(
"input error: ES readv error"
);
p_input
->
pf_delete_packet
(
p_input
->
p_method_data
,
p_data
);
return
(
-
1
);
}
p_input
->
stream
.
p_selected_area
->
i_tell
+=
i_read
;
i_read
/=
ES_PACKET_SIZE
;
/* EOF */
if
(
i_read
==
0
&&
p_input
->
stream
.
b_seekable
)
if
(
i_read
!=
ES_READ_ONCE
)
{
return
(
1
);
}
/* We got fewer packets than wanted. Give remaining packets
* back to the buffer allocator. */
int
i_loop
;
input_NetlistMviovec
(
p_input
->
p_method_data
,
(
int
)(
i_read
/
ES_PACKET_SIZE
),
pp_packets
);
for
(
i_loop
=
0
;
i_loop
<
i_read
;
i_loop
++
)
{
pp_data
=
&
(
*
pp_data
)
->
p_next
;
}
p_input
->
stream
.
p_selected_area
->
i_tell
+=
i_read
;
p_input
->
pf_delete_packet
(
p_input
->
p_method_data
,
*
pp_data
);
*
pp_data
=
NULL
;
}
return
(
0
);
return
(
i_read
);
}
/*****************************************************************************
...
...
@@ -241,7 +260,7 @@ static void ESDemux( input_thread_t * p_input, data_packet_t * p_data )
{
pes_packet_t
*
p_pes
=
p_input
->
pf_new_pes
(
p_input
->
p_method_data
);
decoder_fifo_t
*
p_fifo
=
p_input
->
stream
.
p
p_programs
[
0
]
->
pp_es
[
0
]
->
p_decoder_fifo
;
p_input
->
stream
.
p
_selected_program
->
pp_es
[
0
]
->
p_decoder_fifo
;
if
(
p_pes
==
NULL
)
{
...
...
@@ -251,22 +270,23 @@ static void ESDemux( input_thread_t * p_input, data_packet_t * p_data )
}
p_pes
->
i_rate
=
p_input
->
stream
.
control
.
i_rate
;
p_pes
->
p_first
=
p_data
;
p_pes
->
p_first
=
p_pes
->
p_last
=
p_data
;
p_pes
->
i_nb_data
=
1
;
if
(
(
p_input
->
stream
.
pp_programs
[
0
]
->
i_synchro_state
==
SYNCHRO_REINIT
)
|
(
input_ClockManageControl
(
p_input
,
p_input
->
stream
.
pp_programs
[
0
],
if
(
(
p_input
->
stream
.
p_selected_program
->
i_synchro_state
==
SYNCHRO_REINIT
)
|
(
input_ClockManageControl
(
p_input
,
p_input
->
stream
.
p_selected_program
,
(
mtime_t
)
0
)
==
PAUSE_S
)
)
{
intf_WarnMsg
(
2
,
"synchro reinit"
);
p_pes
->
i_pts
=
mdate
()
+
DEFAULT_PTS_DELAY
;
p_input
->
stream
.
p
p_programs
[
0
]
->
i_synchro_state
=
SYNCHRO_OK
;
p_input
->
stream
.
p
_selected_program
->
i_synchro_state
=
SYNCHRO_OK
;
}
input_DecodePES
(
p_fifo
,
p_pes
);
vlc_mutex_lock
(
&
p_fifo
->
data_lock
);
if
(
(
(
DECODER_FIFO_END
(
*
p_fifo
)
-
DECODER_FIFO_START
(
*
p_fifo
))
&
FIFO_SIZE
)
>=
MAX_PACKETS_IN_FIFO
)
if
(
p_fifo
->
i_depth
>=
MAX_PACKETS_IN_FIFO
)
{
vlc_cond_wait
(
&
p_fifo
->
data_wait
,
&
p_fifo
->
data_lock
);
}
...
...
@@ -290,18 +310,23 @@ static void ESNextDataPacket( bit_stream_t * p_bit_stream )
* time to jump to the next PES packet */
if
(
p_bit_stream
->
p_data
->
p_next
==
NULL
)
{
/* We are going to read/write the start and end indexes of the
* decoder fifo and to use the fifo's conditional variable,
* that's why we need to take the lock before. */
pes_packet_t
*
p_next
;
vlc_mutex_lock
(
&
p_fifo
->
data_lock
);
/* Free the previous PES packet. */
p_next
=
p_fifo
->
p_first
->
p_next
;
p_fifo
->
p_first
->
p_next
=
NULL
;
p_fifo
->
pf_delete_pes
(
p_fifo
->
p_packets_mgt
,
DECODER_FIFO_START
(
*
p_fifo
)
);
DECODER_FIFO_INCSTART
(
*
p_fifo
);
p_fifo
->
p_first
);
p_fifo
->
p_first
=
p_next
;
p_fifo
->
i_depth
--
;
if
(
DECODER_FIFO_ISEMPTY
(
*
p_fifo
)
)
if
(
p_fifo
->
p_first
==
NULL
)
{
/* No PES in the FIFO. p_last is no longer valid. */
p_fifo
->
pp_last
=
&
p_fifo
->
p_first
;
/* Signal the input thread we're waiting. */
vlc_cond_signal
(
&
p_fifo
->
data_wait
);
...
...
@@ -310,7 +335,7 @@ static void ESNextDataPacket( bit_stream_t * p_bit_stream )
}
/* The next byte could be found in the next PES packet */
p_bit_stream
->
p_data
=
DECODER_FIFO_START
(
*
p_fifo
)
->
p_first
;
p_bit_stream
->
p_data
=
p_fifo
->
p_first
->
p_first
;
vlc_mutex_unlock
(
&
p_fifo
->
data_lock
);
...
...
plugins/mpeg/input_es.h
View file @
d5b04453
...
...
@@ -2,7 +2,7 @@
* input_es.h: thread structure of the ES plugin
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: input_es.h,v 1.2
2001/06/27 09:53:56
massiot Exp $
* $Id: input_es.h,v 1.2
.2.1 2001/12/31 01:21:45
massiot Exp $
*
* Authors:
*
...
...
@@ -20,8 +20,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define NB_DATA 8192
#define NB_PES 4096
#define ES_PACKET_SIZE 2048
#define MAX_PACKETS_IN_FIFO 14
#define ES_READ_ONCE 50
#define MAX_PACKETS_IN_FIFO 50
plugins/mpeg/input_ps.c
View file @
d5b04453
...
...
@@ -2,7 +2,7 @@
* input_ps.c: PS demux and packet management
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: input_ps.c,v 1.44
2001/12/07 18:33:07 sam
Exp $
* $Id: input_ps.c,v 1.44
.2.1 2001/12/31 01:21:45 massiot
Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Cyril Deguet <asmax@via.ecp.fr>
...
...
@@ -86,15 +86,25 @@ static __inline__ off_t fseeko( FILE *p_file, off_t i_offset, int i_pos )
*****************************************************************************/
static
int
PSProbe
(
probedata_t
*
);
static
int
PSRead
(
struct
input_thread_s
*
,
data_packet_t
*
p_packets
[
INPUT_READ_ONCE
]
);
data_packet_t
*
*
);
static
void
PSInit
(
struct
input_thread_s
*
);
static
void
PSEnd
(
struct
input_thread_s
*
);
static
int
PSSetProgram
(
struct
input_thread_s
*
,
pgrm_descriptor_t
*
);
static
void
PSSeek
(
struct
input_thread_s
*
,
off_t
);
static
struct
pes_packet_s
*
NewPES
(
void
*
);
static
struct
data_packet_s
*
NewPacket
(
void
*
,
size_t
);
static
void
DeletePacket
(
void
*
,
struct
data_packet_s
*
);
static
void
DeletePES
(
void
*
,
struct
pes_packet_s
*
);
/*****************************************************************************
* Declare a buffer manager
*****************************************************************************/
#define FLAGS BUFFERS_NOFLAGS
#define NB_LIFO 2
DECLARE_BUFFERS_EMBEDDED
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_INIT
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_END
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_NEWPACKET
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_DELETEPACKET
(
FLAGS
,
NB_LIFO
,
300
);
DECLARE_BUFFERS_NEWPES
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_DELETEPES
(
FLAGS
,
NB_LIFO
,
300
);
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
...
...
@@ -113,10 +123,10 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
input
.
pf_set_program
=
PSSetProgram
;
input
.
pf_read
=
PSRead
;
input
.
pf_demux
=
input_DemuxPS
;
input
.
pf_new_packet
=
NewPacket
;
input
.
pf_new_pes
=
NewPES
;
input
.
pf_delete_packet
=
DeletePacket
;
input
.
pf_delete_pes
=
DeletePES
;
input
.
pf_new_packet
=
input_
NewPacket
;
input
.
pf_new_pes
=
input_
NewPES
;
input
.
pf_delete_packet
=
input_
DeletePacket
;
input
.
pf_delete_pes
=
input_
DeletePES
;
input
.
pf_rewind
=
NULL
;
input
.
pf_seek
=
PSSeek
;
#undef input
...
...
@@ -158,64 +168,11 @@ static int PSProbe( probedata_t *p_data )
*****************************************************************************/
static
void
PSInit
(
input_thread_t
*
p_input
)
{
packet_cache_t
*
p_packet_cache
;
/* creates the packet cache structure */
p_packet_cache
=
malloc
(
sizeof
(
packet_cache_t
)
);
if
(
p_packet_cache
==
NULL
)
{
intf_ErrMsg
(
"Out of memory"
);
p_input
->
b_error
=
1
;
return
;
}
p_input
->
p_method_data
=
(
void
*
)
p_packet_cache
;
/* Initialize packet cache mutex */
vlc_mutex_init
(
&
p_packet_cache
->
lock
);
/* allocates the data cache */
p_packet_cache
->
data
.
p_stack
=
malloc
(
DATA_CACHE_SIZE
*
sizeof
(
data_packet_t
*
)
);
if
(
p_packet_cache
->
data
.
p_stack
==
NULL
)
{
intf_ErrMsg
(
"Out of memory"
);
p_input
->
b_error
=
1
;
return
;
}
p_packet_cache
->
data
.
l_index
=
0
;
/* allocates the PES cache */
p_packet_cache
->
pes
.
p_stack
=
malloc
(
PES_CACHE_SIZE
*
sizeof
(
pes_packet_t
*
)
);
if
(
p_packet_cache
->
pes
.
p_stack
==
NULL
)
{
intf_ErrMsg
(
"Out of memory"
);
p_input
->
b_error
=
1
;
return
;
}
p_packet_cache
->
pes
.
l_index
=
0
;
/* allocates the small buffer cache */
p_packet_cache
->
smallbuffer
.
p_stack
=
malloc
(
SMALL_CACHE_SIZE
*
sizeof
(
packet_buffer_t
)
);
if
(
p_packet_cache
->
smallbuffer
.
p_stack
==
NULL
)
if
(
(
p_input
->
p_method_data
=
input_BuffersInit
())
==
NULL
)
{
intf_ErrMsg
(
"Out of memory"
);
p_input
->
b_error
=
1
;
return
;
}
p_packet_cache
->
smallbuffer
.
l_index
=
0
;
/* allocates the large buffer cache */
p_packet_cache
->
largebuffer
.
p_stack
=
malloc
(
LARGE_CACHE_SIZE
*
sizeof
(
packet_buffer_t
)
);
if
(
p_packet_cache
->
largebuffer
.
p_stack
==
NULL
)
{
intf_ErrMsg
(
"Out of memory"
);
p_input
->
b_error
=
1
;
return
;
}
p_packet_cache
->
largebuffer
.
l_index
=
0
;
if
(
p_input
->
p_stream
==
NULL
)
{
...
...
@@ -225,6 +182,7 @@ static void PSInit( input_thread_t * p_input )
if
(
p_input
->
p_stream
==
NULL
)
{
intf_ErrMsg
(
"Cannot open file (%s)"
,
strerror
(
errno
)
);
input_BuffersEnd
(
p_input
->
p_method_data
);
p_input
->
b_error
=
1
;
return
;
}
...
...
@@ -253,11 +211,22 @@ static void PSInit( input_thread_t * p_input )
while
(
!
p_input
->
b_die
&&
!
p_input
->
b_error
&&
!
p_demux_data
->
b_has_PSM
)
{
int
i_result
,
i
;
data_packet_t
*
pp_packets
[
INPUT_READ_ONCE
];
int
i_result
;
data_packet_t
*
p_data
;
data_packet_t
*
p_saved_data
;
i_result
=
PSRead
(
p_input
,
&
p_data
);
p_saved_data
=
p_data
;
while
(
p_data
!=
NULL
)
{
input_ParsePS
(
p_input
,
p_data
);
p_data
=
p_data
->
p_next
;
}
i_result
=
PSRead
(
p_input
,
pp_packets
);
if
(
i_result
==
1
)
p_input
->
pf_delete_packet
(
p_input
->
p_method_data
,
p_saved_data
);
if
(
i_result
==
0
)
{
/* EOF */
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
...
...
@@ -265,19 +234,12 @@ static void PSInit( input_thread_t * p_input )
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
break
;
}
if
(
i_result
==
-
1
)
else
if
(
i_result
==
-
1
)
{
p_input
->
b_error
=
1
;
break
;
}
for
(
i
=
0
;
i
<
INPUT_READ_ONCE
&&
pp_packets
[
i
]
!=
NULL
;
i
++
)
{
/* FIXME: use i_p_config_t */
input_ParsePS
(
p_input
,
pp_packets
[
i
]
);
DeletePacket
(
p_input
->
p_method_data
,
pp_packets
[
i
]
);
}
/* File too big. */
if
(
p_input
->
stream
.
p_selected_area
->
i_tell
>
INPUT_PREPARSE_LENGTH
)
...
...
@@ -388,22 +350,7 @@ static void PSInit( input_thread_t * p_input )
*****************************************************************************/
static
void
PSEnd
(
input_thread_t
*
p_input
)
{
#define p_packet_cache ((packet_cache_t *)p_input->p_method_data)
vlc_mutex_destroy
(
&
p_packet_cache
->
lock
);
if
(
p_packet_cache
->
data
.
p_stack
)
free
(
p_packet_cache
->
data
.
p_stack
);
if
(
p_packet_cache
->
pes
.
p_stack
)
free
(
p_packet_cache
->
pes
.
p_stack
);
if
(
p_packet_cache
->
smallbuffer
.
p_stack
)
free
(
p_packet_cache
->
smallbuffer
.
p_stack
);
if
(
p_packet_cache
->
largebuffer
.
p_stack
)
free
(
p_packet_cache
->
largebuffer
.
p_stack
);
#undef p_packet_cache
free
(
p_input
->
p_method_data
);
input_BuffersEnd
(
p_input
->
p_method_data
);
}
/*****************************************************************************
...
...
@@ -418,7 +365,7 @@ static __inline__ int SafeRead( input_thread_t * p_input, byte_t * p_buffer,
{
if
(
feof
(
p_input
->
p_stream
)
)
{
return
(
1
);
return
(
0
);
}
if
(
(
i_error
=
ferror
(
p_input
->
p_stream
))
)
...
...
@@ -430,28 +377,29 @@ static __inline__ int SafeRead( input_thread_t * p_input, byte_t * p_buffer,
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
p_input
->
stream
.
p_selected_area
->
i_tell
+=
i_len
;
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
return
(
0
);
return
(
i_len
);
}
/*****************************************************************************
* PSRead: reads data packets
*****************************************************************************
* Returns -1 in case of error, 0 i
f everything went well, and 1 in case
of
*
EOF
.
* Returns -1 in case of error, 0 i
n case of EOF, otherwise the number
of
*
packets
.
*****************************************************************************/
static
int
PSRead
(
input_thread_t
*
p_input
,
data_packet_t
*
pp_packets
[
INPUT_READ_ONCE
]
)
data_packet_t
*
*
pp_data
)
{
byte_t
p_header
[
6
];
data_packet_t
*
p_data
;
size_t
i_packet_size
;
int
i_packet
,
i_error
;
memset
(
pp_packets
,
0
,
INPUT_READ_ONCE
*
sizeof
(
data_packet_t
*
)
);
for
(
i_packet
=
0
;
i_packet
<
INPUT_READ_ONCE
;
i_packet
++
)
*
pp_data
=
NULL
;
for
(
i_packet
=
0
;
i_packet
<
PS_READ_ONCE
;
i_packet
++
)
{
/* Read what we believe to be a packet header. */
if
(
(
i_error
=
SafeRead
(
p_input
,
p_header
,
4
))
)
if
(
(
i_error
=
SafeRead
(
p_input
,
p_header
,
4
))
<=
0
)
{
return
(
i_error
);
}
...
...
@@ -480,7 +428,7 @@ static int PSRead( input_thread_t * p_input,
}
else
{
return
(
1
);
return
(
0
);
}
}
/* Packet found. */
...
...
@@ -491,7 +439,7 @@ static int PSRead( input_thread_t * p_input,
if
(
U32_AT
(
p_header
)
!=
0x1B9
)
{
/* The packet is at least 6 bytes long. */
if
(
(
i_error
=
SafeRead
(
p_input
,
p_header
+
4
,
2
))
)
if
(
(
i_error
=
SafeRead
(
p_input
,
p_header
+
4
,
2
))
<=
0
)
{
return
(
i_error
);
}
...
...
@@ -528,7 +476,8 @@ static int PSRead( input_thread_t * p_input,
}
/* Fetch a packet of the appropriate size. */
p_data
=
NewPacket
(
p_input
->
p_method_data
,
i_packet_size
+
6
);
p_data
=
p_input
->
pf_new_packet
(
p_input
->
p_method_data
,
i_packet_size
+
6
);
if
(
p_data
==
NULL
)
{
intf_ErrMsg
(
"Out of memory"
);
...
...
@@ -538,25 +487,29 @@ static int PSRead( input_thread_t * p_input,
if
(
U32_AT
(
p_header
)
!=
0x1B9
)
{
/* Copy the header we already read. */
memcpy
(
p_data
->
p_
buffer
,
p_header
,
6
);
memcpy
(
p_data
->
p_
demux_start
,
p_header
,
6
);
/* Read the remaining of the packet. */
if
(
i_packet_size
&&
(
i_error
=
SafeRead
(
p_input
,
p_data
->
p_buffer
+
6
,
i_packet_size
))
)
SafeRead
(
p_input
,
p_data
->
p_demux_start
+
6
,
i_packet_size
))
<=
0
)
{
p_input
->
pf_delete_packet
(
p_input
->
p_method_data
,
p_data
);
return
(
i_error
);
}
/* In MPEG-2 pack headers we still have to read stuffing bytes. */
if
(
U32_AT
(
p_header
)
==
0x1BA
)
{
if
(
i_packet_size
==
8
&&
(
p_data
->
p_
buffer
[
13
]
&
0x7
)
!=
0
)
if
(
i_packet_size
==
8
&&
(
p_data
->
p_
demux_start
[
13
]
&
0x7
)
!=
0
)
{
/* MPEG-2 stuffing bytes */
byte_t
p_garbage
[
8
];
if
(
(
i_error
=
SafeRead
(
p_input
,
p_garbage
,
p_data
->
p_buffer
[
13
]
&
0x7
))
)
p_data
->
p_demux_start
[
13
]
&
0x7
))
<=
0
)
{
p_input
->
pf_delete_packet
(
p_input
->
p_method_data
,
p_data
);
return
(
i_error
);
}
}
...
...
@@ -565,14 +518,15 @@ static int PSRead( input_thread_t * p_input,
else
{
/* Copy the small header. */
memcpy
(
p_data
->
p_
buffer
,
p_header
,
4
);
memcpy
(
p_data
->
p_
demux_start
,
p_header
,
4
);
}
/* Give the packet to the other input stages. */
pp_packets
[
i_packet
]
=
p_data
;
*
pp_data
=
p_data
;
pp_data
=
&
p_data
->
p_next
;
}
return
(
0
);
return
(
i_packet
+
1
);
}
/*****************************************************************************
...
...
@@ -598,358 +552,3 @@ static void PSSeek( input_thread_t * p_input, off_t i_position )
p_input
->
stream
.
p_selected_area
->
i_tell
=
i_position
;
}
/*
* Packet management utilities
*/
/*****************************************************************************
* NewPacket: allocates a data packet
*****************************************************************************/
static
struct
data_packet_s
*
NewPacket
(
void
*
p_packet_cache
,
size_t
l_size
)
{
packet_cache_t
*
p_cache
;
data_packet_t
*
p_data
;
long
l_index
;
p_cache
=
(
packet_cache_t
*
)
p_packet_cache
;
#ifdef DEBUG
if
(
p_cache
==
NULL
)
{
intf_ErrMsg
(
"PPacket cache not initialized"
);
return
NULL
;
}
#endif
/* Safety check */
if
(
l_size
>
INPUT_MAX_PACKET_SIZE
)
{
intf_ErrMsg
(
"Packet too big (%d)"
,
l_size
);
return
NULL
;
}
vlc_mutex_lock
(
&
p_cache
->
lock
);
/* Checks whether the data cache is empty */
if
(
p_cache
->
data
.
l_index
==
0
)
{
/* Allocates a new packet */
p_data
=
malloc
(
sizeof
(
data_packet_t
)
);
if
(
p_data
==
NULL
)
{
intf_ErrMsg
(
"Out of memory"
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: data packet allocated"
);
#endif
}
else
{
/* Takes the packet out from the cache */
if
(
(
p_data
=
p_cache
->
data
.
p_stack
[
--
p_cache
->
data
.
l_index
])
==
NULL
)
{
intf_ErrMsg
(
"NULL packet in the data cache"
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
}
if
(
l_size
<
MAX_SMALL_SIZE
)
{
/* Small buffer */
/* Checks whether the buffer cache is empty */
if
(
p_cache
->
smallbuffer
.
l_index
==
0
)
{
/* Allocates a new packet */
p_data
->
p_buffer
=
malloc
(
l_size
);
if
(
p_data
->
p_buffer
==
NULL
)
{
intf_DbgMsg
(
"Out of memory"
);
free
(
p_data
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: small buffer allocated"
);
#endif
p_data
->
l_size
=
l_size
;
}
else
{
/* Takes the packet out from the cache */
l_index
=
--
p_cache
->
smallbuffer
.
l_index
;
if
(
(
p_data
->
p_buffer
=
p_cache
->
smallbuffer
.
p_stack
[
l_index
].
p_data
)
==
NULL
)
{
intf_ErrMsg
(
"NULL packet in the small buffer cache"
);
free
(
p_data
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
/* Reallocates the packet if it is too small or too large */
if
(
p_cache
->
smallbuffer
.
p_stack
[
l_index
].
l_size
<
l_size
||
p_cache
->
smallbuffer
.
p_stack
[
l_index
].
l_size
>
2
*
l_size
)
{
p_data
->
p_buffer
=
realloc
(
p_data
->
p_buffer
,
l_size
);
p_data
->
l_size
=
l_size
;
}
else
{
p_data
->
l_size
=
p_cache
->
smallbuffer
.
p_stack
[
l_index
].
l_size
;
}
}
}
else
{
/* Large buffer */
/* Checks whether the buffer cache is empty */
if
(
p_cache
->
largebuffer
.
l_index
==
0
)
{
/* Allocates a new packet */
p_data
->
p_buffer
=
malloc
(
l_size
);
if
(
p_data
->
p_buffer
==
NULL
)
{
intf_ErrMsg
(
"Out of memory"
);
free
(
p_data
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: large buffer allocated"
);
#endif
p_data
->
l_size
=
l_size
;
}
else
{
/* Takes the packet out from the cache */
l_index
=
--
p_cache
->
largebuffer
.
l_index
;
p_data
->
p_buffer
=
p_cache
->
largebuffer
.
p_stack
[
l_index
].
p_data
;
if
(
p_data
->
p_buffer
==
NULL
)
{
intf_ErrMsg
(
"NULL packet in the small buffer cache"
);
free
(
p_data
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
/* Reallocates the packet if it is too small or too large */
if
(
p_cache
->
largebuffer
.
p_stack
[
l_index
].
l_size
<
l_size
||
p_cache
->
largebuffer
.
p_stack
[
l_index
].
l_size
>
2
*
l_size
)
{
p_data
->
p_buffer
=
realloc
(
p_data
->
p_buffer
,
l_size
);
p_data
->
l_size
=
l_size
;
}
else
{
p_data
->
l_size
=
p_cache
->
largebuffer
.
p_stack
[
l_index
].
l_size
;
}
}
}
vlc_mutex_unlock
(
&
p_cache
->
lock
);
/* Initialize data */
p_data
->
p_next
=
NULL
;
p_data
->
b_discard_payload
=
0
;
p_data
->
p_payload_start
=
p_data
->
p_buffer
;
p_data
->
p_payload_end
=
p_data
->
p_buffer
+
l_size
;
return
(
p_data
);
}
/*****************************************************************************
* NewPES: allocates a pes packet
*****************************************************************************/
static
pes_packet_t
*
NewPES
(
void
*
p_packet_cache
)
{
packet_cache_t
*
p_cache
;
pes_packet_t
*
p_pes
;
p_cache
=
(
packet_cache_t
*
)
p_packet_cache
;
#ifdef DEBUG
if
(
p_cache
==
NULL
)
{
intf_ErrMsg
(
"Packet cache not initialized"
);
return
NULL
;
}
#endif
vlc_mutex_lock
(
&
p_cache
->
lock
);
/* Checks whether the PES cache is empty */
if
(
p_cache
->
pes
.
l_index
==
0
)
{
/* Allocates a new packet */
p_pes
=
malloc
(
sizeof
(
pes_packet_t
)
);
if
(
p_pes
==
NULL
)
{
intf_DbgMsg
(
"Out of memory"
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: PES packet allocated"
);
#endif
}
else
{
/* Takes the packet out from the cache */
p_pes
=
p_cache
->
pes
.
p_stack
[
--
p_cache
->
pes
.
l_index
];
if
(
p_pes
==
NULL
)
{
intf_ErrMsg
(
"NULL packet in the data cache"
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
}
vlc_mutex_unlock
(
&
p_cache
->
lock
);
p_pes
->
b_data_alignment
=
p_pes
->
b_discontinuity
=
p_pes
->
i_pts
=
p_pes
->
i_dts
=
0
;
p_pes
->
i_pes_size
=
0
;
p_pes
->
p_first
=
NULL
;
return
(
p_pes
);
}
/*****************************************************************************
* DeletePacket: deletes a data packet
*****************************************************************************/
static
void
DeletePacket
(
void
*
p_packet_cache
,
data_packet_t
*
p_data
)
{
packet_cache_t
*
p_cache
;
p_cache
=
(
packet_cache_t
*
)
p_packet_cache
;
#ifdef DEBUG
if
(
p_cache
==
NULL
)
{
intf_ErrMsg
(
"Packet cache not initialized"
);
return
;
}
#endif
ASSERT
(
p_data
);
vlc_mutex_lock
(
&
p_cache
->
lock
);
/* Checks whether the data cache is full */
if
(
p_cache
->
data
.
l_index
<
DATA_CACHE_SIZE
)
{
/* Cache not full: store the packet in it */
p_cache
->
data
.
p_stack
[
p_cache
->
data
.
l_index
++
]
=
p_data
;
/* Small buffer or large buffer? */
if
(
p_data
->
l_size
<
MAX_SMALL_SIZE
)
{
/* Checks whether the small buffer cache is full */
if
(
p_cache
->
smallbuffer
.
l_index
<
SMALL_CACHE_SIZE
)
{
p_cache
->
smallbuffer
.
p_stack
[
p_cache
->
smallbuffer
.
l_index
].
l_size
=
p_data
->
l_size
;
p_cache
->
smallbuffer
.
p_stack
[
p_cache
->
smallbuffer
.
l_index
++
].
p_data
=
p_data
->
p_buffer
;
}
else
{
ASSERT
(
p_data
->
p_buffer
);
free
(
p_data
->
p_buffer
);
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: small buffer freed"
);
#endif
}
}
else
{
/* Checks whether the large buffer cache is full */
if
(
p_cache
->
largebuffer
.
l_index
<
LARGE_CACHE_SIZE
)
{
p_cache
->
largebuffer
.
p_stack
[
p_cache
->
largebuffer
.
l_index
].
l_size
=
p_data
->
l_size
;
p_cache
->
largebuffer
.
p_stack
[
p_cache
->
largebuffer
.
l_index
++
].
p_data
=
p_data
->
p_buffer
;
}
else
{
ASSERT
(
p_data
->
p_buffer
);
free
(
p_data
->
p_buffer
);
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: large buffer freed"
);
#endif
}
}
}
else
{
/* Cache full: the packet must be freed */
free
(
p_data
->
p_buffer
);
free
(
p_data
);
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: data packet freed"
);
#endif
}
vlc_mutex_unlock
(
&
p_cache
->
lock
);
}
/*****************************************************************************
* DeletePES: deletes a PES packet and associated data packets
*****************************************************************************/
static
void
DeletePES
(
void
*
p_packet_cache
,
pes_packet_t
*
p_pes
)
{
packet_cache_t
*
p_cache
;
data_packet_t
*
p_data
;
data_packet_t
*
p_next
;
p_cache
=
(
packet_cache_t
*
)
p_packet_cache
;
#ifdef DEBUG
if
(
p_cache
==
NULL
)
{
intf_ErrMsg
(
"Packet cache not initialized"
);
return
;
}
#endif
ASSERT
(
p_pes
);
p_data
=
p_pes
->
p_first
;
while
(
p_data
!=
NULL
)
{
p_next
=
p_data
->
p_next
;
DeletePacket
(
p_cache
,
p_data
);
p_data
=
p_next
;
}
vlc_mutex_lock
(
&
p_cache
->
lock
);
/* Checks whether the PES cache is full */
if
(
p_cache
->
pes
.
l_index
<
PES_CACHE_SIZE
)
{
/* Cache not full: store the packet in it */
p_cache
->
pes
.
p_stack
[
p_cache
->
pes
.
l_index
++
]
=
p_pes
;
}
else
{
/* Cache full: the packet must be freed */
free
(
p_pes
);
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: PES packet freed"
);
#endif
}
vlc_mutex_unlock
(
&
p_cache
->
lock
);
}
plugins/mpeg/input_ps.h
View file @
d5b04453
...
...
@@ -2,7 +2,7 @@
* input_ps.h: thread structure of the PS plugin
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ps.h,v 1.9
2001/10/02 16:46:59
massiot Exp $
* $Id: input_ps.h,v 1.9
.2.1 2001/12/31 01:21:45
massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Cyril Deguet <asmax@via.ecp.fr>
...
...
@@ -22,54 +22,5 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define DATA_CACHE_SIZE 150
#define PES_CACHE_SIZE 150
#define SMALL_CACHE_SIZE 150
#define LARGE_CACHE_SIZE 150
#define MAX_SMALL_SIZE 50 // frontier between small and large packets
typedef
struct
{
data_packet_t
**
p_stack
;
long
l_index
;
}
data_packet_cache_t
;
typedef
struct
{
pes_packet_t
**
p_stack
;
long
l_index
;
}
pes_packet_cache_t
;
typedef
struct
{
byte_t
*
p_data
;
long
l_size
;
}
packet_buffer_t
;
typedef
struct
{
packet_buffer_t
*
p_stack
;
long
l_index
;
}
small_buffer_cache_t
;
typedef
struct
{
packet_buffer_t
*
p_stack
;
long
l_index
;
}
large_buffer_cache_t
;
typedef
struct
{
vlc_mutex_t
lock
;
data_packet_cache_t
data
;
pes_packet_cache_t
pes
;
small_buffer_cache_t
smallbuffer
;
large_buffer_cache_t
largebuffer
;
}
packet_cache_t
;
#define PS_READ_ONCE 50
plugins/mpeg/input_ts.c
View file @
d5b04453
...
...
@@ -2,7 +2,7 @@
* input_ts.c: TS demux and netlist management
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: input_ts.c,v 1.42
2001/12/07 18:33:07 sam
Exp $
* $Id: input_ts.c,v 1.42
.2.1 2001/12/31 01:21:45 massiot
Exp $
*
* Authors: Henri Fallon <henri@videolan.org>
*
...
...
@@ -89,7 +89,21 @@ static int TSProbe ( probedata_t * );
static
void
TSInit
(
struct
input_thread_s
*
);
static
void
TSEnd
(
struct
input_thread_s
*
);
static
int
TSRead
(
struct
input_thread_s
*
,
data_packet_t
*
p_packets
[
INPUT_READ_ONCE
]
);
data_packet_t
**
);
/*****************************************************************************
* Declare a buffer manager
*****************************************************************************/
#define FLAGS BUFFERS_UNIQUE_SIZE
#define NB_LIFO 1
DECLARE_BUFFERS_EMBEDDED
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_INIT
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_END
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_NEWPACKET
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_DELETEPACKET
(
FLAGS
,
NB_LIFO
,
1000
);
DECLARE_BUFFERS_NEWPES
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_DELETEPES
(
FLAGS
,
NB_LIFO
,
150
);
DECLARE_BUFFERS_TOIO
(
FLAGS
,
TS_PACKET_SIZE
);
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
...
...
@@ -108,10 +122,10 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
input
.
pf_set_program
=
input_SetProgram
;
input
.
pf_read
=
TSRead
;
input
.
pf_demux
=
input_DemuxTS
;
input
.
pf_new_packet
=
input_Ne
tlistNe
wPacket
;
input
.
pf_new_pes
=
input_Ne
tlistNe
wPES
;
input
.
pf_delete_packet
=
input_
Netlist
DeletePacket
;
input
.
pf_delete_pes
=
input_
Netlist
DeletePES
;
input
.
pf_new_packet
=
input_NewPacket
;
input
.
pf_new_pes
=
input_NewPES
;
input
.
pf_delete_packet
=
input_DeletePacket
;
input
.
pf_delete_pes
=
input_DeletePES
;
input
.
pf_rewind
=
NULL
;
input
.
pf_seek
=
NULL
;
#undef input
...
...
@@ -160,7 +174,6 @@ static int TSProbe( probedata_t * p_data )
*****************************************************************************/
static
void
TSInit
(
input_thread_t
*
p_input
)
{
/* Initialize netlist and TS structures */
thread_ts_data_t
*
p_method
;
es_descriptor_t
*
p_pat_es
;
es_ts_data_t
*
p_demux_data
;
...
...
@@ -184,11 +197,9 @@ static void TSInit( input_thread_t * p_input )
p_input
->
p_method_data
=
NULL
;
/* Initialize netlist */
if
(
input_NetlistInit
(
p_input
,
NB_DATA
,
NB_DATA
,
NB_PES
,
TS_PACKET_SIZE
,
INPUT_READ_ONCE
)
)
if
(
(
p_input
->
p_method_data
=
input_BuffersInit
())
==
NULL
)
{
intf_ErrMsg
(
"TS input : Could not initialize netlist"
)
;
p_input
->
b_error
=
1
;
return
;
}
...
...
@@ -227,23 +238,23 @@ static void TSEnd( input_thread_t * p_input )
input_DelES
(
p_input
,
p_pat_es
);
free
(
p_input
->
p_plugin_data
);
input_
NetlistEnd
(
p_input
);
input_
BuffersEnd
(
p_input
->
p_method_data
);
}
/*****************************************************************************
* TSRead: reads data packets
*****************************************************************************
* Returns -1 in case of error, 0 i
f everything went well, and 1 in case
of
*
EOF
.
* Returns -1 in case of error, 0 i
n case of EOF, otherwise the number
of
*
packets
.
*****************************************************************************/
static
int
TSRead
(
input_thread_t
*
p_input
,
data_packet_t
*
pp_packets
[
INPUT_READ_ONCE
]
)
data_packet_t
*
*
pp_data
)
{
thread_ts_data_t
*
p_method
;
unsigned
int
i_loop
;
int
i_read
;
int
i_read
=
0
,
i_loop
;
int
i_data
=
1
;
struct
iovec
*
p_iovec
;
struct
iovec
p_iovec
[
TS_READ_ONCE
];
data_packet_t
*
p_data
;
struct
timeval
timeout
;
/* Init */
...
...
@@ -257,9 +268,6 @@ static int TSRead( input_thread_t * p_input,
timeout
.
tv_sec
=
0
;
timeout
.
tv_usec
=
500000
;
/* Reset pointer table */
memset
(
pp_packets
,
0
,
INPUT_READ_ONCE
*
sizeof
(
data_packet_t
*
)
);
/* Fill if some data is available */
#if defined( WIN32 )
if
(
!
p_input
->
stream
.
b_pace_control
)
...
...
@@ -278,25 +286,26 @@ static int TSRead( input_thread_t * p_input,
if
(
i_data
)
{
/* Get iovecs */
p_iovec
=
input_NetlistGetiovec
(
p_input
->
p_method_data
);
*
pp_data
=
p_data
=
input_BuffersToIO
(
p_input
->
p_method_data
,
p_iovec
,
TS_READ_ONCE
);
if
(
p_
iovec
==
NULL
)
if
(
p_
data
==
NULL
)
{
return
(
-
1
);
/* empty netlist */
return
(
-
1
);
}
#if defined( WIN32 )
if
(
p_input
->
stream
.
b_pace_control
)
{
i_read
=
readv
(
p_input
->
i_handle
,
p_iovec
,
INPUT
_READ_ONCE
);
i_read
=
readv
(
p_input
->
i_handle
,
p_iovec
,
TS
_READ_ONCE
);
}
else
{
i_read
=
readv_network
(
p_input
->
i_handle
,
p_iovec
,
INPUT
_READ_ONCE
,
p_method
);
TS
_READ_ONCE
,
p_method
);
}
#else
i_read
=
readv
(
p_input
->
i_handle
,
p_iovec
,
INPUT
_READ_ONCE
);
i_read
=
readv
(
p_input
->
i_handle
,
p_iovec
,
TS
_READ_ONCE
);
/* Shouldn't happen, but it does - at least under Linux */
if
(
(
i_read
==
-
1
)
&&
(
(
errno
==
EAGAIN
)
||
(
errno
=
EWOULDBLOCK
)
)
)
...
...
@@ -306,36 +315,35 @@ static int TSRead( input_thread_t * p_input,
i_read
=
0
;
}
#endif
/* Error */
if
(
i_read
==
-
1
)
{
intf_ErrMsg
(
"input error: TS readv error"
);
p_input
->
pf_delete_packet
(
p_input
->
p_method_data
,
p_data
);
return
(
-
1
);
}
p_input
->
stream
.
p_selected_area
->
i_tell
+=
i_read
;
i_read
/=
TS_PACKET_SIZE
;
/*
EOF
*/
if
(
i_read
==
0
&&
p_input
->
stream
.
b_seekable
)
/*
Check correct TS header
*/
for
(
i_loop
=
0
;
i_loop
<
i_read
;
i_loop
++
)
{
return
(
1
);
}
input_NetlistMviovec
(
p_input
->
p_method_data
,
(
int
)(((
i_read
-
1
)
/
TS_PACKET_SIZE
)
+
1
)
,
pp_packets
);
/* check correct TS header */
for
(
i_loop
=
0
;
i_loop
*
TS_PACKET_SIZE
<
i_read
;
i_loop
++
)
if
(
(
*
pp_data
)
->
p_demux_start
[
0
]
!=
0x47
)
{
if
(
pp_packets
[
i_loop
]
->
p_buffer
[
0
]
!=
0x47
)
intf_ErrMsg
(
"input error: bad TS packet (starts with "
"0x%.2x, should be 0x47)"
,
p
p_packets
[
i_loop
]
->
p_buffer
[
0
]
);
p
_data
->
p_demux_start
[
0
]
);
}
for
(
;
i_loop
<
INPUT_READ_ONCE
;
i_loop
++
)
{
pp_packets
[
i_loop
]
=
NULL
;
pp_data
=
&
(
*
pp_data
)
->
p_next
;
}
p_input
->
stream
.
p_selected_area
->
i_tell
+=
i_read
;
if
(
i_read
!=
TS_READ_ONCE
)
{
/* Delete remaining packets */
p_input
->
pf_delete_packet
(
p_input
->
p_method_data
,
*
pp_data
);
*
pp_data
=
NULL
;
}
}
return
0
;
return
(
i_read
)
;
}
plugins/mpeg/input_ts.h
View file @
d5b04453
...
...
@@ -2,7 +2,7 @@
* input_ts.h: structures of the input not exported to other modules
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ts.h,v 1.12.2.
1 2001/12/09 21:14:19 sam
Exp $
* $Id: input_ts.h,v 1.12.2.
2 2001/12/31 01:21:45 massiot
Exp $
*
* Authors: Henri Fallon <henri@via.ecp.fr>
* Boris Dors <babal@via.ecp.fr>
...
...
@@ -22,10 +22,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define NB_DATA 16384
#define
NB_PES 8192
/* UDP packets contain 1500 bytes, that is 7 TS packets */
#define
TS_READ_ONCE 7
#define BUFFER_SIZE (7 * TS_PACKET_SIZE)
#ifdef WIN32
# define BUFFER_SIZE (7 * TS_PACKET_SIZE)
#endif
/*****************************************************************************
* thread_ts_data_t: private input data
...
...
plugins/mpeg_adec/mpeg_adec.c
View file @
d5b04453
...
...
@@ -2,7 +2,7 @@
* mpeg_adec.c: MPEG audio decoder thread
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: mpeg_adec.c,v 1.5.2.
1 2001/12/30 06:06:00 sam
Exp $
* $Id: mpeg_adec.c,v 1.5.2.
2 2001/12/31 01:21:45 massiot
Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr>
...
...
@@ -203,11 +203,11 @@ static void DecodeThread( adec_thread_t * p_adec )
buffer
=
((
s16
*
)
p_adec
->
p_aout_fifo
->
buffer
)
+
(
p_adec
->
p_aout_fifo
->
l_end_frame
*
ADEC_FRAME_SIZE
);
if
(
DECODER_FIFO_START
(
*
p_adec
->
p_fifo
)
->
i_pts
)
if
(
p_adec
->
p_fifo
->
p_first
->
i_pts
)
{
p_adec
->
p_aout_fifo
->
date
[
p_adec
->
p_aout_fifo
->
l_end_frame
]
=
DECODER_FIFO_START
(
*
p_adec
->
p_fifo
)
->
i_pts
;
DECODER_FIFO_START
(
*
p_adec
->
p_fifo
)
->
i_pts
=
0
;
p_adec
->
p_fifo
->
p_first
->
i_pts
;
p_adec
->
p_fifo
->
p_first
->
i_pts
=
0
;
}
else
{
...
...
plugins/mpeg_vdec/video_parser.c
View file @
d5b04453
...
...
@@ -2,7 +2,7 @@
* video_parser.c : video parser thread
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: video_parser.c,v 1.6.2.
1 2001/12/30 06:06:00 sam
Exp $
* $Id: video_parser.c,v 1.6.2.
2 2001/12/31 01:21:45 massiot
Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Samuel Hocevar <sam@via.ecp.fr>
...
...
@@ -281,38 +281,6 @@ static int InitThread( vpar_thread_t *p_vpar )
return
(
0
);
}
/*****************************************************************************
* mpeg_vdec_ErrorThread: RunThread() error loop
*****************************************************************************
* This function is called when an error occured during thread main's loop. The
* thread can still receive feed, but must be ready to terminate as soon as
* possible.
*****************************************************************************/
static
void
mpeg_vdec_ErrorThread
(
vpar_thread_t
*
p_vpar
)
{
/* We take the lock, because we are going to read/write the start/end
* indexes of the decoder fifo */
vlc_mutex_lock
(
&
p_vpar
->
p_fifo
->
data_lock
);
/* Wait until a `die' order is sent */
while
(
!
p_vpar
->
p_fifo
->
b_die
)
{
/* Trash all received PES packets */
while
(
!
DECODER_FIFO_ISEMPTY
(
*
p_vpar
->
p_fifo
)
)
{
p_vpar
->
p_fifo
->
pf_delete_pes
(
p_vpar
->
p_fifo
->
p_packets_mgt
,
DECODER_FIFO_START
(
*
p_vpar
->
p_fifo
)
);
DECODER_FIFO_INCSTART
(
*
p_vpar
->
p_fifo
);
}
/* Waiting for the input thread to put new PES packets in the fifo */
vlc_cond_wait
(
&
p_vpar
->
p_fifo
->
data_wait
,
&
p_vpar
->
p_fifo
->
data_lock
);
}
/* We can release the lock before leaving */
vlc_mutex_unlock
(
&
p_vpar
->
p_fifo
->
data_lock
);
}
/*****************************************************************************
* EndThread: thread destruction
*****************************************************************************
...
...
@@ -428,13 +396,13 @@ static void BitstreamCallback ( bit_stream_t * p_bit_stream,
if
(
b_new_pes
)
{
p_vpar
->
sequence
.
next_pts
=
DECODER_FIFO_START
(
*
p_bit_stream
->
p_decoder_fifo
)
->
i_pts
;
p_bit_stream
->
p_decoder_fifo
->
p_first
->
i_pts
;
p_vpar
->
sequence
.
next_dts
=
DECODER_FIFO_START
(
*
p_bit_stream
->
p_decoder_fifo
)
->
i_dts
;
p_bit_stream
->
p_decoder_fifo
->
p_first
->
i_dts
;
p_vpar
->
sequence
.
i_current_rate
=
DECODER_FIFO_START
(
*
p_bit_stream
->
p_decoder_fifo
)
->
i_rate
;
p_bit_stream
->
p_decoder_fifo
->
p_first
->
i_rate
;
if
(
DECODER_FIFO_START
(
*
p_bit_stream
->
p_decoder_fifo
)
->
b_discontinuity
)
if
(
p_bit_stream
->
p_decoder_fifo
->
p_first
->
b_discontinuity
)
{
#ifdef TRACE_VPAR
intf_DbgMsg
(
"Discontinuity in BitstreamCallback"
);
...
...
plugins/spu_dec/spu_decoder.c
View file @
d5b04453
...
...
@@ -2,7 +2,7 @@
* spu_decoder.c : spu decoder thread
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
* $Id: spu_decoder.c,v 1.5.2.
2 2001/12/30 06:06:00 sam
Exp $
* $Id: spu_decoder.c,v 1.5.2.
3 2001/12/31 01:21:45 massiot
Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
...
...
@@ -275,7 +275,7 @@ static void ParsePacket( spudec_thread_t *p_spudec )
p_spudec
->
i_spu_size
);
/* We cannot display a subpicture with no date */
if
(
DECODER_FIFO_START
(
*
p_spudec
->
p_fifo
)
->
i_pts
==
0
)
if
(
p_spudec
->
p_fifo
->
p_first
->
i_pts
==
0
)
{
intf_WarnMsg
(
3
,
"spudec error: subtitle without a date"
);
return
;
...
...
@@ -295,7 +295,7 @@ static void ParsePacket( spudec_thread_t *p_spudec )
}
/* Get display time now. If we do it later, we may miss the PTS. */
p_spudec
->
i_pts
=
DECODER_FIFO_START
(
*
p_spudec
->
p_fifo
)
->
i_pts
;
p_spudec
->
i_pts
=
p_spudec
->
p_fifo
->
p_first
->
i_pts
;
/* Allocate the temporary buffer we will parse */
p_src
=
malloc
(
p_spudec
->
i_rle_size
);
...
...
plugins/vcd/input_vcd.c
View file @
d5b04453
...
...
@@ -70,17 +70,14 @@
#include "modules.h"
#include "modules_export.h"
#include "../mpeg/input_ps.h"
#include "input_vcd.h"
#include "linux_cdrom_tools.h"
/* how many blocks VCDRead will read in each loop */
#define VCD_BLOCKS_ONCE
6
4
#define VCD_BLOCKS_ONCE 4
#define VCD_DATA_ONCE (2 * VCD_BLOCKS_ONCE)
#define BUFFER_SIZE VCD_DATA_SIZE
/*****************************************************************************
* Local prototypes
*****************************************************************************/
...
...
@@ -95,11 +92,19 @@ static void VCDClose ( struct input_thread_s *);
static
void
VCDEnd
(
struct
input_thread_s
*
);
static
void
VCDSeek
(
struct
input_thread_s
*
,
off_t
);
static
int
VCDRewind
(
struct
input_thread_s
*
);
static
struct
data_packet_s
*
NewPacket
(
void
*
,
size_t
);
static
pes_packet_t
*
NewPES
(
void
*
);
static
void
DeletePacket
(
void
*
,
data_packet_t
*
);
static
void
DeletePES
(
void
*
,
pes_packet_t
*
);
/*****************************************************************************
* Declare a buffer manager
*****************************************************************************/
#define FLAGS BUFFERS_NOFLAGS
#define NB_LIFO 2
DECLARE_BUFFERS_EMBEDDED
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_INIT
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_END
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_NEWPACKET
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_DELETEPACKET
(
FLAGS
,
NB_LIFO
,
1000
);
DECLARE_BUFFERS_NEWPES
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_DELETEPES
(
FLAGS
,
NB_LIFO
,
1000
);
/*****************************************************************************
...
...
@@ -119,10 +124,10 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
input
.
pf_set_area
=
VCDSetArea
;
input
.
pf_set_program
=
VCDSetProgram
;
input
.
pf_demux
=
input_DemuxPS
;
input
.
pf_new_packet
=
NewPacket
;
input
.
pf_new_pes
=
NewPES
;
input
.
pf_delete_packet
=
DeletePacket
;
input
.
pf_delete_pes
=
DeletePES
;
input
.
pf_new_packet
=
input_
NewPacket
;
input
.
pf_new_pes
=
input_
NewPES
;
input
.
pf_delete_packet
=
input_
DeletePacket
;
input
.
pf_delete_pes
=
input_
DeletePES
;
input
.
pf_rewind
=
VCDRewind
;
input
.
pf_seek
=
VCDSeek
;
#undef input
...
...
@@ -162,8 +167,6 @@ static int VCDProbe( probedata_t *p_data )
*****************************************************************************/
static
void
VCDOpen
(
struct
input_thread_s
*
p_input
)
{
int
vcdhandle
;
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
/* If we are here we can control the pace... */
...
...
@@ -171,7 +174,6 @@ static void VCDOpen( struct input_thread_s *p_input )
p_input
->
stream
.
b_seekable
=
1
;
p_input
->
stream
.
p_selected_area
->
i_size
=
0
;
p_input
->
stream
.
p_selected_area
->
i_tell
=
0
;
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
...
...
@@ -181,20 +183,17 @@ static void VCDOpen( struct input_thread_s *p_input )
if
(
strlen
(
p_input
->
p_source
)
>
4
&&
!
strncasecmp
(
p_input
->
p_source
,
"vcd:"
,
4
)
)
{
vcd
handle
=
open
(
p_input
->
p_source
+
4
,
O_RDONLY
|
O_NONBLOCK
);
p_input
->
i_
handle
=
open
(
p_input
->
p_source
+
4
,
O_RDONLY
|
O_NONBLOCK
);
}
else
{
vcd
handle
=
open
(
p_input
->
p_source
+
4
,
O_RDONLY
|
O_NONBLOCK
);
p_input
->
i_
handle
=
open
(
p_input
->
p_source
+
4
,
O_RDONLY
|
O_NONBLOCK
);
}
if
(
vcd
handle
==
-
1
)
if
(
p_input
->
i_
handle
==
-
1
)
{
p_input
->
b_error
=
1
;
return
;
}
p_input
->
i_handle
=
(
int
)
vcdhandle
;
}
/*****************************************************************************
...
...
@@ -216,7 +215,6 @@ static void VCDInit( input_thread_t * p_input )
int
i
;
input_area_t
*
p_area
;
es_descriptor_t
*
p_es
;
packet_cache_t
*
p_packet_cache
;
p_vcd
=
malloc
(
sizeof
(
thread_vcd_data_t
)
);
...
...
@@ -227,78 +225,35 @@ static void VCDInit( input_thread_t * p_input )
return
;
}
p_input
->
p_plugin_data
=
(
void
*
)
p_vcd
;
p_input
->
p_method_data
=
NULL
;
p_vcd
->
vcdhandle
=
p_input
->
i_handle
;
p_vcd
->
b_end_of_track
=
0
;
/* we read the Table Of Content information */
if
(
read_toc
(
p_vcd
)
==
-
1
)
if
(
(
p_input
->
p_method_data
=
input_BuffersInit
())
==
NULL
)
{
intf_ErrMsg
(
"An error occured when reading vcd's TOC"
);
}
p_input
->
i_read_once
=
VCD_DATA_ONCE
;
p_packet_cache
=
malloc
(
sizeof
(
packet_cache_t
)
);
if
(
p_packet_cache
==
NULL
)
{
intf_ErrMsg
(
"vcd error: out of memory"
);
p_input
->
b_error
=
1
;
return
;
}
p_input
->
p_method_data
=
(
void
*
)
p_packet_cache
;
/* Initialize packet cache mutex */
vlc_mutex_init
(
&
p_packet_cache
->
lock
);
/* allocates the data cache */
p_packet_cache
->
data
.
p_stack
=
malloc
(
DATA_CACHE_SIZE
*
sizeof
(
data_packet_t
*
)
);
if
(
p_packet_cache
->
data
.
p_stack
==
NULL
)
{
intf_ErrMsg
(
"Out of memory"
);
free
(
p_vcd
);
p_input
->
b_error
=
1
;
return
;
}
p_packet_cache
->
data
.
l_index
=
0
;
/* allocates the PES cache */
p_packet_cache
->
pes
.
p_stack
=
malloc
(
PES_CACHE_SIZE
*
sizeof
(
pes_packet_t
*
)
);
if
(
p_packet_cache
->
pes
.
p_stack
==
NULL
)
{
intf_ErrMsg
(
"Out of memory"
);
p_input
->
b_error
=
1
;
return
;
}
p_packet_cache
->
pes
.
l_index
=
0
;
p_vcd
->
i_handle
=
p_input
->
i_handle
;
/* allocates the small buffer cache */
p_packet_cache
->
smallbuffer
.
p_stack
=
malloc
(
SMALL_CACHE_SIZE
*
sizeof
(
packet_buffer_t
)
);
if
(
p_packet_cache
->
smallbuffer
.
p_stack
==
NULL
)
/* We read the Table Of Content information */
p_vcd
->
nb_tracks
=
ioctl_GetTrackCount
(
p_input
->
i_handle
);
if
(
p_vcd
->
nb_tracks
<
0
)
{
intf_ErrMsg
(
"Out of memory"
);
input_BuffersEnd
(
p_input
->
p_method_data
);
free
(
p_vcd
);
p_input
->
b_error
=
1
;
return
;
}
p_packet_cache
->
smallbuffer
.
l_index
=
0
;
/* allocates the large buffer cache */
p_packet_cache
->
largebuffer
.
p_stack
=
malloc
(
LARGE_CACHE_SIZE
*
sizeof
(
packet_buffer_t
)
);
if
(
p_packet_cache
->
largebuffer
.
p_stack
==
NULL
)
p_vcd
->
p_sectors
=
ioctl_GetSectors
(
p_input
->
i_handle
);
if
(
p_vcd
->
p_sectors
==
NULL
)
{
intf_ErrMsg
(
"Out of memory"
);
input_BuffersEnd
(
p_input
->
p_method_data
);
free
(
p_vcd
);
p_input
->
b_error
=
1
;
return
;
}
p_packet_cache
->
largebuffer
.
l_index
=
0
;
/* Set stream and area data */
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
...
...
@@ -309,7 +264,6 @@ static void VCDInit( input_thread_t * p_input )
/* disc input method */
p_input
->
stream
.
i_method
=
INPUT_METHOD_VCD
;
#define area p_input->stream.pp_areas
for
(
i
=
1
;
i
<=
p_vcd
->
nb_tracks
-
1
;
i
++
)
{
...
...
@@ -319,8 +273,9 @@ static void VCDInit( input_thread_t * p_input )
area
[
i
]
->
i_id
=
i
;
/* Absolute start offset and size */
area
[
i
]
->
i_start
=
p_vcd
->
tracks_sector
[
i
];
area
[
i
]
->
i_size
=
p_vcd
->
tracks_sector
[
i
+
1
]
-
p_vcd
->
tracks_sector
[
i
];
area
[
i
]
->
i_start
=
(
off_t
)
p_vcd
->
p_sectors
[
i
]
*
(
off_t
)
VCD_DATA_SIZE
;
area
[
i
]
->
i_size
=
(
off_t
)(
p_vcd
->
p_sectors
[
i
+
1
]
-
p_vcd
->
p_sectors
[
i
])
*
(
off_t
)
VCD_DATA_SIZE
;
/* Number of chapters */
area
[
i
]
->
i_part_nb
=
0
;
// will be the entry points
...
...
@@ -330,18 +285,18 @@ static void VCDInit( input_thread_t * p_input )
area
[
i
]
->
i_angle_nb
=
1
;
// no angle support in VCDs
area
[
i
]
->
i_angle
=
1
;
area
[
i
]
->
i_plugin_data
=
p_vcd
->
tracks_sector
[
i
];
area
[
i
]
->
i_plugin_data
=
p_vcd
->
p_sectors
[
i
];
}
#undef area
/* Get requested title - if none try the first title */
i_title
=
main_GetIntVariable
(
INPUT_TITLE_VAR
,
1
);
if
(
i_title
<=
0
)
if
(
i_title
<=
0
)
{
i_title
=
1
;
}
// p_vcd->
current_track = i_title-1
;
// p_vcd->
i_track = i_title-1
;
/* Get requested chapter - if none defaults to first one */
i_chapter
=
main_GetIntVariable
(
INPUT_CHAPTER_VAR
,
1
);
...
...
@@ -350,7 +305,6 @@ static void VCDInit( input_thread_t * p_input )
i_chapter
=
1
;
}
p_input
->
stream
.
pp_areas
[
i_title
]
->
i_part
=
i_chapter
;
p_area
=
p_input
->
stream
.
pp_areas
[
i_title
];
...
...
@@ -362,7 +316,7 @@ static void VCDInit( input_thread_t * p_input )
input_AddProgram
(
p_input
,
0
,
sizeof
(
stream_ps_data_t
)
);
p_input
->
stream
.
p_selected_program
=
p_input
->
stream
.
pp_programs
[
0
];
/* No PSM to read in disc mode, we already have all information */
/* No PSM to read in disc mode, we already have all
the
information */
p_input
->
stream
.
p_selected_program
->
b_is_ok
=
1
;
p_es
=
input_AddES
(
p_input
,
p_input
->
stream
.
p_selected_program
,
0xe0
,
0
);
...
...
@@ -375,8 +329,7 @@ static void VCDInit( input_thread_t * p_input )
input_SelectES
(
p_input
,
p_es
);
}
p_es
=
input_AddES
(
p_input
,
p_input
->
stream
.
p_selected_program
,
0xc0
,
0
);
p_es
=
input_AddES
(
p_input
,
p_input
->
stream
.
p_selected_program
,
0xc0
,
0
);
p_es
->
i_stream_id
=
0xc0
;
p_es
->
i_type
=
MPEG1_AUDIO_ES
;
p_es
->
b_audio
=
1
;
...
...
@@ -388,12 +341,8 @@ static void VCDInit( input_thread_t * p_input )
}
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
return
;
}
/*****************************************************************************
* VCDEnd: frees unused data
*****************************************************************************/
...
...
@@ -401,10 +350,11 @@ static void VCDEnd( input_thread_t * p_input )
{
thread_vcd_data_t
*
p_vcd
;
input_BuffersEnd
(
p_input
->
p_method_data
);
p_vcd
=
(
thread_vcd_data_t
*
)
p_input
->
p_plugin_data
;
free
(
p_vcd
);
}
/*****************************************************************************
...
...
@@ -430,10 +380,10 @@ static int VCDSetArea( input_thread_t * p_input, input_area_t * p_area )
/* we can't use the interface slider until initilization is complete */
p_input
->
stream
.
b_seekable
=
0
;
if
(
p_area
!=
p_input
->
stream
.
p_selected_area
)
if
(
p_area
!=
p_input
->
stream
.
p_selected_area
)
{
/* Reset the Chapter position of the
old
title */
p_input
->
stream
.
p_selected_area
->
i_part
=
0
;
/* Reset the Chapter position of the
current
title */
p_input
->
stream
.
p_selected_area
->
i_part
=
1
;
p_input
->
stream
.
p_selected_area
->
i_tell
=
0
;
/* Change the default area */
...
...
@@ -441,115 +391,102 @@ static int VCDSetArea( input_thread_t * p_input, input_area_t * p_area )
/* Change the current track */
/* The first track is not a valid one */
p_vcd
->
current_track
=
p_area
->
i_id
;
p_vcd
->
current_sector
=
p_vcd
->
tracks_sector
[
p_vcd
->
current_track
]
;
p_vcd
->
i_track
=
p_area
->
i_id
;
p_vcd
->
i_sector
=
p_vcd
->
p_sectors
[
p_vcd
->
i_track
]
;
}
/* warn interface that something has changed */
p_input
->
stream
.
b_seekable
=
1
;
p_input
->
stream
.
b_changed
=
1
;
return
0
;
return
0
;
}
/*****************************************************************************
* VCDRead: reads from the VCD into PES packets.
*****************************************************************************
* Returns -1 in case of error, 0 i
f everything went well, and 1 in case
of
*
EOF
.
* Returns -1 in case of error, 0 i
n case of EOF, otherwise the number
of
*
packets
.
*****************************************************************************/
static
int
VCDRead
(
input_thread_t
*
p_input
,
data_packet_t
**
pp_packets
)
static
int
VCDRead
(
input_thread_t
*
p_input
,
data_packet_t
**
pp_data
)
{
thread_vcd_data_t
*
p_vcd
;
data_packet_t
*
p_data
;
int
i_packet_size
;
int
i_index
;
int
i_packet
;
boolean_t
b_eof
;
byte_t
*
p_buffer
;
boolean_t
b_no_packet
;
u32
i_header
;
byte_t
p_buffer
[
VCD_DATA_SIZE
]
;
boolean_t
b_eot
=
0
;
/* end of track */
/* boolean_t b_eoc; No chapters yet */
p_vcd
=
(
thread_vcd_data_t
*
)
p_input
->
p_plugin_data
;
p_buffer
=
malloc
(
VCD_DATA_SIZE
);
if
(
p_buffer
==
NULL
)
{
intf_ErrMsg
(
"Could not malloc the read buffer"
);
return
-
1
;
}
i_packet
=
0
;
b_no_packet
=
0
;
*
pp_data
=
NULL
;
while
(
i_packet
<
VCD_DATA_ONCE
)
{
i_index
=
0
;
if
(
VCD_sector_read
(
p_vcd
,
p_buffer
)
==
-
1
)
if
(
ioctl_ReadSector
(
p_vcd
->
i_handle
,
p_vcd
->
i_sector
,
p_buffer
)
)
{
return
-
1
;
/* Read error, but assume we reached the end of the track */
b_eot
=
1
;
break
;
}
while
(
i_index
<
BUFFER_SIZE
-
6
)
{
p_vcd
->
i_sector
++
;
if
(
(
U32_AT
(
p_buffer
+
i_index
)
&
0xFFFFFF00
)
!=
0x100L
)
if
(
p_vcd
->
i_sector
>=
p_vcd
->
p_sectors
[
p_vcd
->
i_track
+
1
]
)
{
/* This is not the startcode of a packet. Read the stream
* until we find one. */
b_eot
=
1
;
break
;
}
if
(
!
U32_AT
(
p_buffer
+
i_index
)
)
i_index
=
0
;
while
(
i_index
<
BUFFER_SIZE
-
6
&&
i_packet
<
VCD_DATA_ONCE
)
{
i_header
=
U32_AT
(
p_buffer
+
i_index
);
/* It is common for MPEG-1 streams to pad with zeros
* (although it is forbidden by the recommendation), so
* don't bother everybody in this case. */
intf_WarnMsg
(
3
,
"Garbage at input"
);
while
(
!
i_header
&&
(
++
i_index
<
BUFFER_SIZE
-
4
)
)
{
i_header
=
U32_AT
(
p_buffer
+
i_index
);
}
while
(
(
(
U32_AT
(
p_buffer
+
i_index
)
&
0xFFFFFF00
)
!=
0x100L
)
&&
(
i_index
<
BUFFER_SIZE
-
4
)
)
if
(
!
i_header
)
{
i_index
++
;
intf_WarnMsg
(
12
,
"vcd warning: zero-padded packet"
);
break
;
}
if
(
i_index
==
BUFFER_SIZE
-
4
)
/* Read the stream until we find a startcode. */
while
(
(
i_header
&
0xFFFFFF00
)
!=
0x100L
&&
(
++
i_index
<
BUFFER_SIZE
-
4
)
)
{
b_no_packet
=
1
;
}
/* Packet found. */
i_header
=
U32_AT
(
p_buffer
+
i_index
);
}
if
(
b_no_packet
)
if
(
(
i_header
&
0xFFFFFF00
)
!=
0x100L
)
{
b_no_packet
=
0
;
intf_WarnMsg
(
3
,
"No packet found on sector %d
\n
"
,
p_vcd
->
current_sector
-
1
);
intf_WarnMsg
(
3
,
"vcd warning: no packet at sector %d"
,
p_vcd
->
i_sector
-
1
);
break
;
/* go to the next sector */
}
#ifdef DEBUG
intf_DbgMsg
(
"packet start code : %X
\n
"
,
U32_AT
(
p_buffer
+
i_index
));
#endif
/* 0x1B9 == SYSTEM_END_CODE, it is only 4 bytes long. */
if
(
U32_AT
(
p_buffer
+
i_index
)
!=
0x1B9
)
{
/* The packet is at least 6 bytes long. */
intf_DbgMsg
(
"packet start code : %X"
,
i_header
);
if
(
U32_AT
(
p_buffer
+
i_index
)
!=
0x1BA
)
{
/* That's the case for all packets, except pack header. */
i_packet_size
=
U16_AT
((
p_buffer
+
(
i_index
+
4
)));
}
else
switch
(
i_header
)
{
/* Pack header. */
/* 0x1b9 == SYSTEM_END_CODE, it is only 4 bytes long. */
case
0x1b9
:
i_packet_size
=
-
2
;
break
;
/* Pack header */
case
0x1ba
:
if
(
(
*
(
p_buffer
+
(
i_index
+
4
)
)
&
0xC0
)
==
0x40
)
{
/* MPEG-2 */
...
...
@@ -562,99 +499,99 @@ static int VCDRead( input_thread_t * p_input,
}
else
{
intf_ErrMsg
(
"Unable to determine stream type"
);
intf_ErrMsg
(
"vcd error: unable to determine "
"stream type"
);
return
(
-
1
);
}
break
;
/* The packet is at least 6 bytes long. */
default:
/* That's the case for all packets, except pack header. */
i_packet_size
=
U16_AT
((
p_buffer
+
(
i_index
+
4
)));
break
;
}
}
else
{
/* System End Code */
i_packet_size
=
-
2
;
}
#ifdef DEBUG
intf_DbgMsg
(
"i_index : %d
\n
"
,
i_index
);
intf_DbgMsg
(
"i_packet_size : %d
\n
"
,
i_packet_size
);
#endif
intf_DbgMsg
(
"i_index : %d"
,
i_index
);
intf_DbgMsg
(
"i_packet_size : %d"
,
i_packet_size
);
if
(
i_index
+
i_packet_size
>
BUFFER_SIZE
)
{
intf_ErrMsg
(
"Too long packet"
);
intf_ErrMsg
(
"vcd error: packet too long (%i)"
,
i_index
+
i_packet_size
);
continue
;
}
/* Fetch a packet of the appropriate size. */
p_data
=
NewPacket
(
p_input
->
p_method_data
,
i_packet_size
+
6
);
p_data
=
p_input
->
pf_new_packet
(
p_input
->
p_method_data
,
i_packet_size
+
6
);
if
(
p_data
==
NULL
)
{
intf_ErrMsg
(
"
O
ut of memory"
);
intf_ErrMsg
(
"
vcd error: o
ut of memory"
);
return
(
-
1
);
}
if
(
U32_AT
(
p_buffer
)
!=
0x1B9
)
{
p_main
->
fast_memcpy
(
p_data
->
p_
buffer
,
p_buffer
+
i_index
,
p_main
->
fast_memcpy
(
p_data
->
p_
demux_start
,
p_buffer
+
i_index
,
6
+
i_packet_size
);
i_index
+=
(
6
+
i_packet_size
);
}
else
{
/* Copy the small header. */
memcpy
(
p_data
->
p_
buffer
,
p_buffer
+
i_index
,
4
);
memcpy
(
p_data
->
p_
demux_start
,
p_buffer
+
i_index
,
4
);
i_index
+=
4
;
}
/* Give the packet to the other input stages. */
pp_packets
[
i_packet
]
=
p_data
;
i_packet
++
;
}
*
pp_data
=
p_data
;
pp_data
=
&
p_data
->
p_next
;
if
(
p_vcd
->
b_end_of_track
)
break
;
i_packet
++
;
}
}
pp_packets
[
i_packet
]
=
NULL
;
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
p_input
->
stream
.
p_selected_area
->
i_tell
=
p_vcd
->
current_sector
-
p_input
->
stream
.
p_selected_area
->
i_start
;
(
off_t
)
p_vcd
->
i_sector
*
(
off_t
)
VCD_DATA_SIZE
-
p_input
->
stream
.
p_selected_area
->
i_start
;
/* no chapter for the moment*/
/*if( b_eoc )
#if 0
if( b_eoc )
{
* We modify i_part only at end of chapter not to erase
* some modification from the interface *
/
* We modify i_part only at end of chapter not to erase
* some modification from the interface *
/
p_input->stream.p_selected_area->i_part = p_vcd->i_chapter;
}
*/
}
#endif
b_eof
=
p_vcd
->
b_end_of_track
&&
(
(
p_vcd
->
current_track
)
>=
p_vcd
->
nb_tracks
-
1
);
if
(
b_eot
)
{
input_area_t
*
p_area
;
if
(
b_eof
)
/* EOF ? */
if
(
p_vcd
->
i_track
>=
p_vcd
->
nb_tracks
-
1
)
{
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
return
1
;
return
0
;
}
if
(
p_vcd
->
b_end_of_track
)
{
intf_WarnMsg
(
4
,
"vcd info: new title"
);
p_vcd
->
b_end_of_track
=
0
;
VCDSetArea
(
p_input
,
p_input
->
stream
.
pp_areas
[
p_input
->
stream
.
p_selected_area
->
i_id
+
1
]
);
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
return
0
;
p_area
=
p_input
->
stream
.
pp_areas
[
p_input
->
stream
.
p_selected_area
->
i_id
+
1
];
p_area
->
i_part
=
1
;
VCDSetArea
(
p_input
,
p_area
);
}
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
return
0
;
return
(
i_packet
+
1
);
}
/*****************************************************************************
...
...
@@ -665,7 +602,6 @@ static int VCDRewind( input_thread_t * p_input )
return
(
-
1
);
}
/****************************************************************************
* VCDSeek
****************************************************************************/
...
...
@@ -675,368 +611,11 @@ static void VCDSeek( input_thread_t * p_input, off_t i_off )
p_vcd
=
(
thread_vcd_data_t
*
)
p_input
->
p_plugin_data
;
p_vcd
->
current_sector
=
p_vcd
->
tracks_sector
[
p_vcd
->
current
_track
]
+
i_off
;
p_vcd
->
i_sector
=
p_vcd
->
p_sectors
[
p_vcd
->
i
_track
]
+
i_off
/
(
off_t
)
VCD_DATA_SIZE
;
p_input
->
stream
.
p_selected_area
->
i_tell
=
p_vcd
->
current_sector
p_input
->
stream
.
p_selected_area
->
i_tell
=
(
off_t
)
p_vcd
->
i_sector
*
(
off_t
)
VCD_DATA_SIZE
-
p_input
->
stream
.
p_selected_area
->
i_start
;
return
;
}
/*
* Packet management utilities
*/
/*****************************************************************************
* NewPacket: allocates a data packet
*****************************************************************************/
static
struct
data_packet_s
*
NewPacket
(
void
*
p_packet_cache
,
size_t
l_size
)
{
packet_cache_t
*
p_cache
;
data_packet_t
*
p_data
;
long
l_index
;
p_cache
=
(
packet_cache_t
*
)
p_packet_cache
;
#ifdef DEBUG
if
(
p_cache
==
NULL
)
{
intf_ErrMsg
(
"PPacket cache not initialized"
);
return
NULL
;
}
#endif
/* Safety check */
if
(
l_size
>
INPUT_MAX_PACKET_SIZE
)
{
intf_ErrMsg
(
"Packet too big (%d)"
,
l_size
);
return
NULL
;
}
vlc_mutex_lock
(
&
p_cache
->
lock
);
/* Checks whether the data cache is empty */
if
(
p_cache
->
data
.
l_index
==
0
)
{
/* Allocates a new packet */
p_data
=
malloc
(
sizeof
(
data_packet_t
)
);
if
(
p_data
==
NULL
)
{
intf_ErrMsg
(
"Out of memory"
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: data packet allocated"
);
#endif
}
else
{
/* Takes the packet out from the cache */
if
(
(
p_data
=
p_cache
->
data
.
p_stack
[
--
p_cache
->
data
.
l_index
])
==
NULL
)
{
intf_ErrMsg
(
"NULL packet in the data cache"
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
}
if
(
l_size
<
MAX_SMALL_SIZE
)
{
/* Small buffer */
/* Checks whether the buffer cache is empty */
if
(
p_cache
->
smallbuffer
.
l_index
==
0
)
{
/* Allocates a new packet */
p_data
->
p_buffer
=
malloc
(
l_size
);
if
(
p_data
->
p_buffer
==
NULL
)
{
intf_DbgMsg
(
"Out of memory"
);
free
(
p_data
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: small buffer allocated"
);
#endif
p_data
->
l_size
=
l_size
;
}
else
{
/* Takes the packet out from the cache */
l_index
=
--
p_cache
->
smallbuffer
.
l_index
;
if
(
(
p_data
->
p_buffer
=
p_cache
->
smallbuffer
.
p_stack
[
l_index
].
p_data
)
==
NULL
)
{
intf_ErrMsg
(
"NULL packet in the small buffer cache"
);
free
(
p_data
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
/* Reallocates the packet if it is too small or too large */
if
(
p_cache
->
smallbuffer
.
p_stack
[
l_index
].
l_size
<
l_size
||
p_cache
->
smallbuffer
.
p_stack
[
l_index
].
l_size
>
2
*
l_size
)
{
p_data
->
p_buffer
=
realloc
(
p_data
->
p_buffer
,
l_size
);
p_data
->
l_size
=
l_size
;
}
else
{
p_data
->
l_size
=
p_cache
->
smallbuffer
.
p_stack
[
l_index
].
l_size
;
}
}
}
else
{
/* Large buffer */
/* Checks whether the buffer cache is empty */
if
(
p_cache
->
largebuffer
.
l_index
==
0
)
{
/* Allocates a new packet */
p_data
->
p_buffer
=
malloc
(
l_size
);
if
(
p_data
->
p_buffer
==
NULL
)
{
intf_ErrMsg
(
"Out of memory"
);
free
(
p_data
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: large buffer allocated"
);
#endif
p_data
->
l_size
=
l_size
;
}
else
{
/* Takes the packet out from the cache */
l_index
=
--
p_cache
->
largebuffer
.
l_index
;
p_data
->
p_buffer
=
p_cache
->
largebuffer
.
p_stack
[
l_index
].
p_data
;
if
(
p_data
->
p_buffer
==
NULL
)
{
intf_ErrMsg
(
"NULL packet in the small buffer cache"
);
free
(
p_data
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
/* Reallocates the packet if it is too small or too large */
if
(
p_cache
->
largebuffer
.
p_stack
[
l_index
].
l_size
<
l_size
||
p_cache
->
largebuffer
.
p_stack
[
l_index
].
l_size
>
2
*
l_size
)
{
p_data
->
p_buffer
=
realloc
(
p_data
->
p_buffer
,
l_size
);
p_data
->
l_size
=
l_size
;
}
else
{
p_data
->
l_size
=
p_cache
->
largebuffer
.
p_stack
[
l_index
].
l_size
;
}
}
}
vlc_mutex_unlock
(
&
p_cache
->
lock
);
/* Initialize data */
p_data
->
p_next
=
NULL
;
p_data
->
b_discard_payload
=
0
;
p_data
->
p_payload_start
=
p_data
->
p_buffer
;
p_data
->
p_payload_end
=
p_data
->
p_buffer
+
l_size
;
return
(
p_data
);
}
/*****************************************************************************
* NewPES: allocates a pes packet
*****************************************************************************/
static
pes_packet_t
*
NewPES
(
void
*
p_packet_cache
)
{
packet_cache_t
*
p_cache
;
pes_packet_t
*
p_pes
;
p_cache
=
(
packet_cache_t
*
)
p_packet_cache
;
#ifdef DEBUG
if
(
p_cache
==
NULL
)
{
intf_ErrMsg
(
"Packet cache not initialized"
);
return
NULL
;
}
#endif
vlc_mutex_lock
(
&
p_cache
->
lock
);
/* Checks whether the PES cache is empty */
if
(
p_cache
->
pes
.
l_index
==
0
)
{
/* Allocates a new packet */
p_pes
=
malloc
(
sizeof
(
pes_packet_t
)
);
if
(
p_pes
==
NULL
)
{
intf_DbgMsg
(
"Out of memory"
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: PES packet allocated"
);
#endif
}
else
{
/* Takes the packet out from the cache */
p_pes
=
p_cache
->
pes
.
p_stack
[
--
p_cache
->
pes
.
l_index
];
if
(
p_pes
==
NULL
)
{
intf_ErrMsg
(
"NULL packet in the data cache"
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
}
vlc_mutex_unlock
(
&
p_cache
->
lock
);
p_pes
->
b_data_alignment
=
p_pes
->
b_discontinuity
=
p_pes
->
i_pts
=
p_pes
->
i_dts
=
0
;
p_pes
->
i_pes_size
=
0
;
p_pes
->
p_first
=
NULL
;
return
(
p_pes
);
}
/*****************************************************************************
* DeletePacket: deletes a data packet
*****************************************************************************/
static
void
DeletePacket
(
void
*
p_packet_cache
,
data_packet_t
*
p_data
)
{
packet_cache_t
*
p_cache
;
p_cache
=
(
packet_cache_t
*
)
p_packet_cache
;
#ifdef DEBUG
if
(
p_cache
==
NULL
)
{
intf_ErrMsg
(
"Packet cache not initialized"
);
return
;
}
#endif
ASSERT
(
p_data
);
vlc_mutex_lock
(
&
p_cache
->
lock
);
/* Checks whether the data cache is full */
if
(
p_cache
->
data
.
l_index
<
DATA_CACHE_SIZE
)
{
/* Cache not full: store the packet in it */
p_cache
->
data
.
p_stack
[
p_cache
->
data
.
l_index
++
]
=
p_data
;
/* Small buffer or large buffer? */
if
(
p_data
->
l_size
<
MAX_SMALL_SIZE
)
{
/* Checks whether the small buffer cache is full */
if
(
p_cache
->
smallbuffer
.
l_index
<
SMALL_CACHE_SIZE
)
{
p_cache
->
smallbuffer
.
p_stack
[
p_cache
->
smallbuffer
.
l_index
].
l_size
=
p_data
->
l_size
;
p_cache
->
smallbuffer
.
p_stack
[
p_cache
->
smallbuffer
.
l_index
++
].
p_data
=
p_data
->
p_buffer
;
}
else
{
ASSERT
(
p_data
->
p_buffer
);
free
(
p_data
->
p_buffer
);
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: small buffer freed"
);
#endif
}
}
else
{
/* Checks whether the large buffer cache is full */
if
(
p_cache
->
largebuffer
.
l_index
<
LARGE_CACHE_SIZE
)
{
p_cache
->
largebuffer
.
p_stack
[
p_cache
->
largebuffer
.
l_index
].
l_size
=
p_data
->
l_size
;
p_cache
->
largebuffer
.
p_stack
[
p_cache
->
largebuffer
.
l_index
++
].
p_data
=
p_data
->
p_buffer
;
}
else
{
ASSERT
(
p_data
->
p_buffer
);
free
(
p_data
->
p_buffer
);
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: large buffer freed"
);
#endif
}
}
}
else
{
/* Cache full: the packet must be freed */
free
(
p_data
->
p_buffer
);
free
(
p_data
);
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: data packet freed"
);
#endif
}
vlc_mutex_unlock
(
&
p_cache
->
lock
);
}
/*****************************************************************************
* DeletePES: deletes a PES packet and associated data packets
*****************************************************************************/
static
void
DeletePES
(
void
*
p_packet_cache
,
pes_packet_t
*
p_pes
)
{
packet_cache_t
*
p_cache
;
data_packet_t
*
p_data
;
data_packet_t
*
p_next
;
p_cache
=
(
packet_cache_t
*
)
p_packet_cache
;
#ifdef DEBUG
if
(
p_cache
==
NULL
)
{
intf_ErrMsg
(
"Packet cache not initialized"
);
return
;
}
#endif
ASSERT
(
p_pes
);
p_data
=
p_pes
->
p_first
;
while
(
p_data
!=
NULL
)
{
p_next
=
p_data
->
p_next
;
DeletePacket
(
p_cache
,
p_data
);
p_data
=
p_next
;
}
vlc_mutex_lock
(
&
p_cache
->
lock
);
/* Checks whether the PES cache is full */
if
(
p_cache
->
pes
.
l_index
<
PES_CACHE_SIZE
)
{
/* Cache not full: store the packet in it */
p_cache
->
pes
.
p_stack
[
p_cache
->
pes
.
l_index
++
]
=
p_pes
;
}
else
{
/* Cache full: the packet must be freed */
free
(
p_pes
);
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: PES packet freed"
);
#endif
}
vlc_mutex_unlock
(
&
p_cache
->
lock
);
}
plugins/vcd/input_vcd.h
View file @
d5b04453
...
...
@@ -2,7 +2,7 @@
* input_vcd.h: thread structure of the VCD plugin
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: input_vcd.h,v 1.1
2001/10/23 03:17:49 jobi
Exp $
* $Id: input_vcd.h,v 1.1
.2.1 2001/12/31 01:21:45 massiot
Exp $
*
* Author: Johan Bilien <jobi@via.ecp.fr>
*
...
...
@@ -21,25 +21,17 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
/*****************************************************************************
* thread_vcd_data_t: VCD information
*****************************************************************************/
typedef
struct
thread_vcd_data_s
{
int
vcdhandle
;
// File descriptor
int
nb_tracks
;
// Nb of tracks (titles)
int
current_track
;
// Current track
int
current_sector
;
// Current Sector
int
*
tracks_sector
;
// index of tracks
boolean_t
b_end_of_track
;
// if the end of track is
// reached
}
thread_vcd_data_t
;
int
i_handle
;
/* File descriptor */
int
nb_tracks
;
/* Nb of tracks (titles) */
int
i_track
;
/* Current track */
int
i_sector
;
/* Current Sector */
int
*
p_sectors
;
/* Track sectors */
boolean_t
b_end_of_track
;
/* If the end of track was reached */
}
thread_vcd_data_t
;
plugins/vcd/linux_cdrom_tools.c
View file @
d5b04453
...
...
@@ -71,129 +71,97 @@
#include "modules.h"
#include "modules_export.h"
#include "input_vcd.h"
#include "linux_cdrom_tools.h"
/*****************************************************************************
* read_toc : Reads the Table of Content of a CD-ROM and fills p_vcd with *
* the read information *
*****************************************************************************/
int
read_toc
(
thread_vcd_data_t
*
p_vcd
)
* ioctl_ReadTocHeader: Read the TOC header and return the track number.
*****************************************************************************/
int
ioctl_GetTrackCount
(
int
i_fd
)
{
int
i
;
struct
cdrom_tochdr
tochdr
;
struct
cdrom_tocentry
tocent
;
int
fd
=
p_vcd
->
vcdhandle
;
struct
cdrom_tochdr
tochdr
;
/*
f
irst we read the TOC header */
if
(
ioctl
(
fd
,
CDROMREADTOCHDR
,
&
tochdr
)
==
-
1
)
/*
F
irst we read the TOC header */
if
(
ioctl
(
i_fd
,
CDROMREADTOCHDR
,
&
tochdr
)
==
-
1
)
{
intf_ErrMsg
(
"problem occured when reading CD's TOCHDR
\n
"
)
;
return
-
1
;
}
p_vcd
->
nb_tracks
=
tochdr
.
cdth_trk1
;
/* nb_tracks + 1 because we put the lead_out tracks for computing last
track's size */
p_vcd
->
tracks_sector
=
malloc
(
(
p_vcd
->
nb_tracks
+
1
)
*
sizeof
(
int
)
);
if
(
p_vcd
->
tracks_sector
==
NULL
)
{
intf_ErrMsg
(
"could not malloc tracks_sector"
);
intf_ErrMsg
(
"vcd error: could not read TOCHDR"
);
return
-
1
;
}
/* then for each track we read its TOC entry */
return
tochdr
.
cdth_trk1
-
tochdr
.
cdth_trk0
+
1
;
}
for
(
i
=
tochdr
.
cdth_trk0
;
i
<=
tochdr
.
cdth_trk1
;
i
++
)
{
tocent
.
cdte_track
=
i
;
tocent
.
cdte_format
=
CDROM_LBA
;
if
(
ioctl
(
fd
,
CDROMREADTOCENTRY
,
&
tocent
)
==
-
1
)
/*****************************************************************************
* ioctl_GetSectors: Read the Table of Contents and fill p_vcd.
*****************************************************************************/
int
*
ioctl_GetSectors
(
int
i_fd
)
{
int
i
,
i_tracks
;
int
*
p_sectors
;
struct
cdrom_tochdr
tochdr
;
struct
cdrom_tocentry
tocent
;
/* First we read the TOC header */
if
(
ioctl
(
i_fd
,
CDROMREADTOCHDR
,
&
tochdr
)
==
-
1
)
{
intf_ErrMsg
(
"problem occured when reading CD's TOCENTRY
\n
"
);
free
(
p_vcd
->
tracks_sector
);
return
-
1
;
intf_ErrMsg
(
"vcd error: could not read TOCHDR"
);
return
NULL
;
}
p_vcd
->
tracks_sector
[
i
-
1
]
=
tocent
.
cdte_addr
.
lba
;
i_tracks
=
tochdr
.
cdth_trk1
-
tochdr
.
cdth_trk0
+
1
;
p_sectors
=
malloc
(
(
i_tracks
+
1
)
*
sizeof
(
int
)
);
if
(
p_sectors
==
NULL
)
{
intf_ErrMsg
(
"vcd error: could not allocate p_sectors"
);
return
NULL
;
}
/* finally we read the lead-out track toc entry */
/* Fill the p_sectors structure with the track/sector matches */
for
(
i
=
0
;
i
<=
i_tracks
;
i
++
)
{
tocent
.
cdte_format
=
CDROM_LBA
;
tocent
.
cdte_track
=
(
i
==
i_tracks
)
?
CDROM_LEADOUT
:
tochdr
.
cdth_trk0
+
i
;
tocent
.
cdte_track
=
CDROM_LEADOUT
;
tocent
.
cdte_format
=
CDROM_LBA
;
if
(
ioctl
(
fd
,
CDROMREADTOCENTRY
,
&
tocent
)
==
-
1
)
if
(
ioctl
(
i_fd
,
CDROMREADTOCENTRY
,
&
tocent
)
==
-
1
)
{
intf_ErrMsg
(
"problem occured when readind CD's
lead-out track TOC entry"
)
;
free
(
p_vcd
->
tracks_sector
)
;
return
-
1
;
intf_ErrMsg
(
"vcd error: could not read TOCENTRY"
);
free
(
p_sectors
);
return
NULL
;
}
p_vcd
->
tracks_sector
[
p_vcd
->
nb_tracks
]
=
tocent
.
cdte_addr
.
lba
;
return
1
;
p_sectors
[
i
]
=
tocent
.
cdte_addr
.
lba
;
}
return
p_sectors
;
}
/****************************************************************************
*
VCD_sector_read : Function that reads a sector (2324 bytes) from VCD
*
ioctl_ReadSector: Read a sector (2324 bytes)
****************************************************************************/
int
VCD_sector_read
(
struct
thread_vcd_data_s
*
p_vcd
,
byte_t
*
p_buffer
)
int
ioctl_ReadSector
(
int
i_fd
,
int
i_sector
,
byte_t
*
p_buffer
)
{
byte_t
p_read_block
[
VCD_SECTOR_SIZE
]
;
struct
cdrom_msf0
msf_cursor
;
msf_cursor
=
lba2msf
(
p_vcd
->
current_sector
)
;
#ifdef DEBUG
intf_DbgMsg
(
"Playing frame %d:%d-%d
\n
"
,
msf_cursor
.
minute
,
msf_cursor
.
second
,
msf_cursor
.
frame
)
;
#endif
memcpy
(
p_read_block
,
&
msf_cursor
,
sizeof
(
struct
cdrom_msf0
))
;
if
(
ioctl
(
p_vcd
->
vcdhandle
,
CDROMREADRAW
,
p_read_block
)
==
-
1
)
{
intf_ErrMsg
(
"problem occured when reading CD"
)
;
free
(
p_read_block
)
;
return
-
1
;
}
/* we don't want to keep the header of the read sector */
memcpy
(
p_buffer
,
&
p_read_block
[
VCD_DATA_START
],
VCD_DATA_SIZE
);
byte_t
p_block
[
VCD_SECTOR_SIZE
];
int
i_dummy
=
i_sector
+
2
*
CD_FRAMES
;
#define p_msf ((struct cdrom_msf0 *)p_block)
p_msf
->
minute
=
i_dummy
/
(
CD_FRAMES
*
CD_SECS
);
p_msf
->
second
=
(
i_dummy
%
(
CD_FRAMES
*
CD_SECS
)
)
/
CD_FRAMES
;
p_msf
->
frame
=
(
i_dummy
%
(
CD_FRAMES
*
CD_SECS
)
)
%
CD_FRAMES
;
p_vcd
->
current_sector
++
;
intf_DbgMsg
(
"vcd debug: playing frame %d:%d-%d"
,
p_msf
->
minute
,
p_msf
->
second
,
p_msf
->
frame
);
#undef p_msf
if
(
p_vcd
->
current_sector
==
p_vcd
->
tracks_sector
[
p_vcd
->
current_track
+
1
]
)
if
(
ioctl
(
i_fd
,
CDROMREADRAW
,
p_block
)
==
-
1
)
{
p_vcd
->
b_end_of_track
=
1
;
intf_ErrMsg
(
"vcd error: could not read block %i from disc"
,
i_sector
);
return
-
1
;
}
return
1
;
}
/*****************************************************************************
* lba2msf : converts a logical block address into a minute/second/frame
* address.
*****************************************************************************/
struct
cdrom_msf0
lba2msf
(
int
lba
)
{
struct
cdrom_msf0
msf_result
;
/* we add 2*CD_FRAMES since the 2 first seconds are not played*/
/* We don't want to keep the header of the read sector */
p_main
->
fast_memcpy
(
p_buffer
,
p_block
+
VCD_DATA_START
,
VCD_DATA_SIZE
);
msf_result
.
minute
=
(
lba
+
2
*
CD_FRAMES
)
/
(
CD_FRAMES
*
CD_SECS
)
;
msf_result
.
second
=
(
(
lba
+
2
*
CD_FRAMES
)
%
(
CD_FRAMES
*
CD_SECS
)
)
/
CD_FRAMES
;
msf_result
.
frame
=
(
(
lba
+
2
*
CD_FRAMES
)
%
(
CD_FRAMES
*
CD_SECS
)
)
%
CD_FRAMES
;
return
msf_result
;
return
0
;
}
plugins/vcd/linux_cdrom_tools.h
View file @
d5b04453
...
...
@@ -36,7 +36,6 @@
/******************************************************************************
* Prototypes *
******************************************************************************/
int
read_toc
(
struct
thread_vcd_data_s
*
);
int
VCD_sector_read
(
struct
thread_vcd_data_s
*
,
byte_t
*
)
;
struct
cdrom_msf0
lba2msf
(
int
)
;
int
ioctl_GetTrackCount
(
int
);
int
*
ioctl_GetSectors
(
int
);
int
ioctl_ReadSector
(
int
,
int
,
byte_t
*
);
src/input/input.c
View file @
d5b04453
...
...
@@ -4,7 +4,7 @@
* decoders.
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: input.c,v 1.163.2.
2 2001/12/12 02:13:20 sam
Exp $
* $Id: input.c,v 1.163.2.
3 2001/12/31 01:21:45 massiot
Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
...
...
@@ -120,9 +120,6 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status )
return
(
NULL
);
}
/* Packets read once */
p_input
->
i_read_once
=
INPUT_READ_ONCE
;
/* Initialize thread properties */
p_input
->
b_die
=
0
;
p_input
->
b_error
=
0
;
...
...
@@ -206,7 +203,7 @@ void input_DestroyThread( input_thread_t *p_input, int *pi_status )
/* Request thread destruction */
p_input
->
b_die
=
1
;
/* Make the thread exit
of
an eventual vlc_cond_wait() */
/* Make the thread exit
from
an eventual vlc_cond_wait() */
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
vlc_cond_signal
(
&
p_input
->
stream
.
stream_wait
);
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
...
...
@@ -229,9 +226,6 @@ void input_DestroyThread( input_thread_t *p_input, int *pi_status )
*****************************************************************************/
static
void
RunThread
(
input_thread_t
*
p_input
)
{
int
i_error
,
i
;
data_packet_t
**
pp_packets
;
if
(
InitThread
(
p_input
)
)
{
/* If we failed, wait before we are killed, and exit */
...
...
@@ -242,22 +236,16 @@ static void RunThread( input_thread_t *p_input )
return
;
}
/* initialization is complete
d
*/
/* initialization is complete */
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
p_input
->
stream
.
b_changed
=
1
;
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
pp_packets
=
(
data_packet_t
**
)
malloc
(
p_input
->
i_read_once
*
sizeof
(
data_packet_t
*
)
);
if
(
pp_packets
==
NULL
)
{
intf_ErrMsg
(
"input error: out of memory"
);
free
(
pp_packets
);
p_input
->
b_error
=
1
;
}
while
(
!
p_input
->
b_die
&&
!
p_input
->
b_error
&&
!
p_input
->
b_eof
)
{
data_packet_t
*
p_data
;
int
i_count
,
i
;
p_input
->
c_loops
++
;
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
...
...
@@ -357,32 +345,32 @@ static void RunThread( input_thread_t *p_input )
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
i_
error
=
p_input
->
pf_read
(
p_input
,
pp_packets
);
i_
count
=
p_input
->
pf_read
(
p_input
,
&
p_data
);
/* Demultiplex read packets. */
for
(
i
=
0
;
i
<
p_input
->
i_read_once
&&
pp_packets
[
i
]
!=
NULL
;
i
++
)
while
(
p_data
!=
NULL
)
{
data_packet_t
*
p_next
=
p_data
->
p_next
;
p_data
->
p_next
=
NULL
;
p_input
->
stream
.
c_packets_read
++
;
p_input
->
pf_demux
(
p_input
,
pp_packets
[
i
]
);
p_input
->
pf_demux
(
p_input
,
p_data
);
p_data
=
p_next
;
}
if
(
i_error
)
{
if
(
i_error
==
1
)
if
(
i_count
==
0
&&
p_input
->
stream
.
b_seekable
)
{
/* End of file - we do not set b_die because only the
* interface is allowed to do so. */
intf_WarnMsg
(
3
,
"input: EOF reached"
);
p_input
->
b_eof
=
1
;
}
else
else
if
(
i_count
<
0
)
{
p_input
->
b_error
=
1
;
}
}
}
free
(
pp_packets
);
if
(
p_input
->
b_error
||
p_input
->
b_eof
)
{
...
...
@@ -401,7 +389,6 @@ static void RunThread( input_thread_t *p_input )
*****************************************************************************/
static
int
InitThread
(
input_thread_t
*
p_input
)
{
/* Initialize statistics */
p_input
->
c_loops
=
0
;
p_input
->
stream
.
c_packets_read
=
0
;
...
...
src/input/input_dec.c
View file @
d5b04453
...
...
@@ -2,7 +2,7 @@
* input_dec.c: Functions for the management of decoders
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: input_dec.c,v 1.19
2001/12/03 16:18:37 sam
Exp $
* $Id: input_dec.c,v 1.19
.2.1 2001/12/31 01:21:45 massiot
Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
...
...
@@ -144,21 +144,13 @@ void input_DecodePES( decoder_fifo_t * p_decoder_fifo, pes_packet_t * p_pes )
{
vlc_mutex_lock
(
&
p_decoder_fifo
->
data_lock
);
if
(
!
DECODER_FIFO_ISFULL
(
*
p_decoder_fifo
)
)
{
p_decoder_fifo
->
buffer
[
p_decoder_fifo
->
i_end
]
=
p_pes
;
DECODER_FIFO_INCEND
(
*
p_decoder_fifo
)
;
p_pes
->
p_next
=
NULL
;
*
p_decoder_fifo
->
pp_last
=
p_pes
;
p_decoder_fifo
->
pp_last
=
&
p_pes
->
p_next
;
p_decoder_fifo
->
i_depth
++
;
/* Warn the decoder that it's got work to do. */
vlc_cond_signal
(
&
p_decoder_fifo
->
data_wait
);
}
else
{
/* The FIFO is full !!! This should not happen. */
p_decoder_fifo
->
pf_delete_pes
(
p_decoder_fifo
->
p_packets_mgt
,
p_pes
);
intf_ErrMsg
(
"PES trashed - decoder fifo full !"
);
}
vlc_mutex_unlock
(
&
p_decoder_fifo
->
data_lock
);
}
...
...
@@ -261,7 +253,9 @@ static decoder_config_t * CreateDecoderConfig( input_thread_t * p_input,
p_config
->
i_type
=
p_es
->
i_type
;
p_config
->
p_stream_ctrl
=
&
p_input
->
stream
.
control
;
p_config
->
p_decoder_fifo
->
i_start
=
p_config
->
p_decoder_fifo
->
i_end
=
0
;
p_config
->
p_decoder_fifo
->
p_first
=
NULL
;
p_config
->
p_decoder_fifo
->
pp_last
=
&
p_config
->
p_decoder_fifo
->
p_first
;
p_config
->
p_decoder_fifo
->
i_depth
=
0
;
p_config
->
p_decoder_fifo
->
b_die
=
p_config
->
p_decoder_fifo
->
b_error
=
0
;
p_config
->
p_decoder_fifo
->
p_packets_mgt
=
p_input
->
p_method_data
;
p_config
->
p_decoder_fifo
->
pf_delete_pes
=
p_input
->
pf_delete_pes
;
...
...
@@ -274,14 +268,13 @@ static decoder_config_t * CreateDecoderConfig( input_thread_t * p_input,
*****************************************************************************/
static
void
DeleteDecoderConfig
(
decoder_config_t
*
p_config
)
{
intf_StatMsg
(
"input stats: killing decoder for 0x%x, type 0x%x, %d PES in FIFO"
,
p_config
->
i_id
,
p_config
->
i_type
,
p_config
->
p_decoder_fifo
->
i_depth
);
/* Free all packets still in the decoder fifo. */
while
(
!
DECODER_FIFO_ISEMPTY
(
*
p_config
->
p_decoder_fifo
)
)
{
p_config
->
p_decoder_fifo
->
pf_delete_pes
(
p_config
->
p_decoder_fifo
->
p_packets_mgt
,
DECODER_FIFO_START
(
*
p_config
->
p_decoder_fifo
)
);
DECODER_FIFO_INCSTART
(
*
p_config
->
p_decoder_fifo
);
}
p_config
->
p_decoder_fifo
->
p_first
);
/* Destroy the lock and cond */
vlc_cond_destroy
(
&
p_config
->
p_decoder_fifo
->
data_wait
);
...
...
src/input/input_ext-dec.c
View file @
d5b04453
...
...
@@ -2,7 +2,7 @@
* input_ext-dec.c: services to the decoders
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: input_ext-dec.c,v 1.21.2.
1 2001/12/30 06:06:00 sam
Exp $
* $Id: input_ext-dec.c,v 1.21.2.
2 2001/12/31 01:21:45 massiot
Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
...
...
@@ -55,7 +55,7 @@ void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo,
/* Get the first data packet. */
vlc_mutex_lock
(
&
p_fifo
->
data_lock
);
while
(
DECODER_FIFO_ISEMPTY
(
*
p_fifo
)
)
while
(
p_fifo
->
p_first
==
NULL
)
{
if
(
p_fifo
->
b_die
)
{
...
...
@@ -64,7 +64,7 @@ void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo,
}
vlc_cond_wait
(
&
p_fifo
->
data_wait
,
&
p_fifo
->
data_lock
);
}
p_bit_stream
->
p_data
=
DECODER_FIFO_START
(
*
p_fifo
)
->
p_first
;
p_bit_stream
->
p_data
=
p_fifo
->
p_first
->
p_first
;
p_bit_stream
->
p_byte
=
p_bit_stream
->
p_data
->
p_payload_start
;
p_bit_stream
->
p_end
=
p_bit_stream
->
p_data
->
p_payload_end
;
p_bit_stream
->
fifo
.
buffer
=
0
;
...
...
@@ -100,12 +100,7 @@ void DecoderError( decoder_fifo_t * p_fifo )
while
(
!
p_fifo
->
b_die
)
{
/* Trash all received PES packets */
while
(
!
DECODER_FIFO_ISEMPTY
(
*
p_fifo
)
)
{
p_fifo
->
pf_delete_pes
(
p_fifo
->
p_packets_mgt
,
DECODER_FIFO_START
(
*
p_fifo
)
);
DECODER_FIFO_INCSTART
(
*
p_fifo
);
}
p_fifo
->
pf_delete_pes
(
p_fifo
->
p_packets_mgt
,
p_fifo
->
p_first
);
/* Waiting for the input thread to put new PES packets in the fifo */
vlc_cond_wait
(
&
p_fifo
->
data_wait
,
&
p_fifo
->
data_lock
);
...
...
@@ -131,24 +126,29 @@ void NextDataPacket( bit_stream_t * p_bit_stream )
* time to jump to the next PES packet */
if
(
p_bit_stream
->
p_data
->
p_next
==
NULL
)
{
/* We are going to read/write the start and end indexes of the
* decoder fifo and to use the fifo's conditional variable,
* that's why we need to take the lock before. */
pes_packet_t
*
p_next
;
vlc_mutex_lock
(
&
p_fifo
->
data_lock
);
/* Free the previous PES packet. */
p_next
=
p_fifo
->
p_first
->
p_next
;
p_fifo
->
p_first
->
p_next
=
NULL
;
p_fifo
->
pf_delete_pes
(
p_fifo
->
p_packets_mgt
,
DECODER_FIFO_START
(
*
p_fifo
)
);
DECODER_FIFO_INCSTART
(
*
p_fifo
);
p_fifo
->
p_first
);
p_fifo
->
p_first
=
p_next
;
p_fifo
->
i_depth
--
;
if
(
DECODER_FIFO_ISEMPTY
(
*
p_fifo
)
)
if
(
p_fifo
->
p_first
==
NULL
)
{
/* No PES in the FIFO. p_last is no longer valid. */
p_fifo
->
pp_last
=
&
p_fifo
->
p_first
;
/* Wait for the input to tell us when we receive a packet. */
vlc_cond_wait
(
&
p_fifo
->
data_wait
,
&
p_fifo
->
data_lock
);
}
/* The next byte could be found in the next PES packet */
p_bit_stream
->
p_data
=
DECODER_FIFO_START
(
*
p_fifo
)
->
p_first
;
p_bit_stream
->
p_data
=
p_fifo
->
p_first
->
p_first
;
vlc_mutex_unlock
(
&
p_fifo
->
data_lock
);
...
...
src/input/input_netlist.c
deleted
100644 → 0
View file @
f6b7894d
/*****************************************************************************
* dvd_netlist.c: netlist management v2
*****************************************************************************
* There is only one major change from input_netlist.c (1) : data is now a
* pointer to an offset in iovec ; and iovec has a reference counter. It
* will only be given back to netlist when refcount is zero.
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: input_netlist.c,v 1.47 2001/12/03 17:34:08 stef Exp $
*
* Authors: Henri Fallon <henri@videolan.org>
* Stphane Borel <stef@videolan.org>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include <stdlib.h>
#include <string.h>
/* memcpy(), memset() */
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#if defined( WIN32 )
# include <io.h>
/* read() */
#else
# include <sys/uio.h>
/* struct iovec */
#endif
#include "config.h"
#include "common.h"
#include "intf_msg.h"
/* intf_*Msg */
#include "threads.h"
/* mutex */
#include "mtime.h"
#if defined( WIN32 )
# include "input_iovec.h"
#endif
#include "stream_control.h"
#include "input_ext-intf.h"
#include "input_ext-dec.h"
#include "input_ext-plugins.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
/*****************************************************************************
* input_NetlistInit: allocates netlist buffers and init indexes
* ---
* Changes from input_NetList: we have to give the length of the buffer which
* is different from i_nb_data now, since we may have several data pointers
* in one iovec. Thus we can only delete an iovec when its refcount is 0.
* We only received a buffer with a GetIovec whereas NewPacket gives a pointer.
*****************************************************************************/
int
input_NetlistInit
(
input_thread_t
*
p_input
,
int
i_nb_iovec
,
int
i_nb_data
,
int
i_nb_pes
,
size_t
i_buffer_size
,
int
i_read_once
)
{
unsigned
int
i_loop
;
netlist_t
*
p_netlist
;
/* First we allocate and initialise our netlist struct */
p_input
->
p_method_data
=
malloc
(
sizeof
(
netlist_t
));
if
(
p_input
->
p_method_data
==
NULL
)
{
intf_ErrMsg
(
"Unable to malloc the netlist struct"
);
return
(
-
1
);
}
p_netlist
=
(
netlist_t
*
)
p_input
->
p_method_data
;
/* Nb of packets read once by input */
p_netlist
->
i_read_once
=
i_read_once
;
/* In order to optimize netlist, we are taking i_nb_data a 2^i
* so that modulo is an "&".
* This is not changing i_nb data outside this function except in
* the netlist_t struct */
/* As i_loop is unsigned int, and i_ns_data int, this shouldn't be a
* problem */
for
(
i_loop
=
1
;
i_loop
<
i_nb_data
;
i_loop
*=
2
)
{
;
}
intf_DbgMsg
(
"Netlist : Required %i byte, got %u"
,
i_nb_data
,
i_loop
);
i_nb_data
=
i_loop
;
/* Same thing for i_nb_pes */
for
(
i_loop
=
1
;
i_loop
<
i_nb_pes
;
i_loop
*=
2
)
{
;
}
intf_DbgMsg
(
"Netlist : Required %i byte, got %u"
,
i_nb_pes
,
i_loop
);
i_nb_pes
=
i_loop
;
/* Same thing for i_nb_iovec */
for
(
i_loop
=
1
;
i_loop
<
i_nb_iovec
;
i_loop
*=
2
)
{
;
}
intf_DbgMsg
(
"Netlist : Required %i byte, got %u"
,
i_nb_iovec
,
i_loop
);
i_nb_iovec
=
i_loop
;
/* allocate the buffers */
p_netlist
->
p_buffers
=
malloc
(
i_nb_iovec
*
i_buffer_size
);
if
(
p_netlist
->
p_buffers
==
NULL
)
{
intf_ErrMsg
(
"Unable to malloc in netlist initialization (1)"
);
free
(
p_netlist
);
return
-
1
;
}
/* table of pointers to data packets */
p_netlist
->
p_data
=
malloc
(
i_nb_data
*
sizeof
(
data_packet_t
)
);
if
(
p_netlist
->
p_data
==
NULL
)
{
intf_ErrMsg
(
"Unable to malloc in netlist initialization (2)"
);
free
(
p_netlist
->
p_buffers
);
free
(
p_netlist
);
return
-
1
;
}
/* table of pointer to PES packets */
p_netlist
->
p_pes
=
malloc
(
i_nb_pes
*
sizeof
(
pes_packet_t
)
);
if
(
p_netlist
->
p_pes
==
NULL
)
{
intf_ErrMsg
(
"Unable to malloc in netlist initialization (3)"
);
free
(
p_netlist
->
p_buffers
);
free
(
p_netlist
->
p_data
);
free
(
p_netlist
);
return
-
1
;
}
/* allocate the FIFOs : tables of free pointers */
p_netlist
->
pp_free_data
=
malloc
(
i_nb_data
*
sizeof
(
data_packet_t
*
)
);
if
(
p_netlist
->
pp_free_data
==
NULL
)
{
intf_ErrMsg
(
"Unable to malloc in netlist initialization (4)"
);
free
(
p_netlist
->
p_buffers
);
free
(
p_netlist
->
p_data
);
free
(
p_netlist
->
p_pes
);
free
(
p_netlist
);
return
-
1
;
}
p_netlist
->
pp_free_pes
=
malloc
(
i_nb_pes
*
sizeof
(
pes_packet_t
*
)
);
if
(
p_netlist
->
pp_free_pes
==
NULL
)
{
intf_ErrMsg
(
"Unable to malloc in netlist initialization (5)"
);
free
(
p_netlist
->
p_buffers
);
free
(
p_netlist
->
p_data
);
free
(
p_netlist
->
p_pes
);
free
(
p_netlist
->
pp_free_data
);
free
(
p_netlist
);
return
-
1
;
}
p_netlist
->
p_free_iovec
=
malloc
(
(
i_nb_iovec
+
p_netlist
->
i_read_once
)
*
sizeof
(
struct
iovec
)
);
if
(
p_netlist
->
p_free_iovec
==
NULL
)
{
intf_ErrMsg
(
"Unable to malloc in DVD netlist initialization (6)"
);
free
(
p_netlist
->
p_buffers
);
free
(
p_netlist
->
p_data
);
free
(
p_netlist
->
p_pes
);
free
(
p_netlist
->
pp_free_data
);
free
(
p_netlist
->
pp_free_pes
);
free
(
p_netlist
);
return
-
1
;
}
/* table for reference counter of iovecs */
p_netlist
->
pi_refcount
=
malloc
(
i_nb_iovec
*
sizeof
(
int
)
);
if
(
p_netlist
->
pi_refcount
==
NULL
)
{
intf_ErrMsg
(
"Unable to malloc in DVD netlist initialization (7)"
);
free
(
p_netlist
->
p_buffers
);
free
(
p_netlist
->
p_data
);
free
(
p_netlist
->
p_pes
);
free
(
p_netlist
->
pp_free_data
);
free
(
p_netlist
->
pp_free_pes
);
free
(
p_netlist
->
p_free_iovec
);
free
(
p_netlist
);
return
-
1
;
}
/* Fill the data FIFO */
for
(
i_loop
=
0
;
i_loop
<
i_nb_data
;
i_loop
++
)
{
p_netlist
->
pp_free_data
[
i_loop
]
=
p_netlist
->
p_data
+
i_loop
;
/* by default, one data packet for one buffer */
if
(
i_nb_data
==
i_nb_iovec
)
{
p_netlist
->
pp_free_data
[
i_loop
]
->
p_buffer
=
p_netlist
->
p_buffers
+
i_loop
*
i_buffer_size
;
p_netlist
->
pp_free_data
[
i_loop
]
->
p_payload_start
=
p_netlist
->
pp_free_data
[
i_loop
]
->
p_buffer
;
p_netlist
->
pp_free_data
[
i_loop
]
->
p_payload_end
=
p_netlist
->
pp_free_data
[
i_loop
]
->
p_buffer
+
i_buffer_size
;
}
}
/* Fill the PES FIFO */
for
(
i_loop
=
0
;
i_loop
<
i_nb_pes
;
i_loop
++
)
{
p_netlist
->
pp_free_pes
[
i_loop
]
=
p_netlist
->
p_pes
+
i_loop
;
}
/* Deal with the iovec */
for
(
i_loop
=
0
;
i_loop
<
i_nb_iovec
;
i_loop
++
)
{
p_netlist
->
p_free_iovec
[
i_loop
].
iov_base
=
p_netlist
->
p_buffers
+
i_loop
*
i_buffer_size
;
p_netlist
->
p_free_iovec
[
i_loop
].
iov_len
=
i_buffer_size
;
}
/* initialize reference counters */
memset
(
p_netlist
->
pi_refcount
,
0
,
i_nb_iovec
*
sizeof
(
int
)
);
/* vlc_mutex_init */
vlc_mutex_init
(
&
p_netlist
->
lock
);
/* initialize indexes */
p_netlist
->
i_iovec_start
=
0
;
p_netlist
->
i_iovec_end
=
i_nb_iovec
-
1
;
p_netlist
->
i_data_start
=
0
;
p_netlist
->
i_data_end
=
i_nb_data
-
1
;
p_netlist
->
i_pes_start
=
0
;
p_netlist
->
i_pes_end
=
i_nb_pes
-
1
;
/* we give (nb - 1) to use & instead of %
* if you really need nb you have to add 1 */
p_netlist
->
i_nb_iovec
=
i_nb_iovec
-
1
;
p_netlist
->
i_nb_data
=
i_nb_data
-
1
;
p_netlist
->
i_nb_pes
=
i_nb_pes
-
1
;
p_netlist
->
i_buffer_size
=
i_buffer_size
;
return
0
;
/* Everything went all right */
}
/*****************************************************************************
* input_NetlistGetiovec: returns an iovec pointer for a readv() operation
*****************************************************************************
* We return an iovec vector, so that readv can read many packets at a time.
* pp_data will be set to direct to the fifo pointer in DVDMviovec, which
* will allow us to get the corresponding data_packet.
*****************************************************************************/
struct
iovec
*
input_NetlistGetiovec
(
void
*
p_method_data
)
{
netlist_t
*
p_netlist
;
/* cast */
p_netlist
=
(
netlist_t
*
)
p_method_data
;
/* check that we have enough free iovec */
if
(
(
(
p_netlist
->
i_iovec_end
-
p_netlist
->
i_iovec_start
)
&
p_netlist
->
i_nb_iovec
)
<
p_netlist
->
i_read_once
)
{
intf_WarnMsg
(
4
,
"input info: waiting for free iovec"
);
msleep
(
INPUT_IDLE_SLEEP
);
while
(
(
(
p_netlist
->
i_iovec_end
-
p_netlist
->
i_iovec_start
)
&
p_netlist
->
i_nb_iovec
)
<
p_netlist
->
i_read_once
)
{
msleep
(
INPUT_IDLE_SLEEP
);
}
intf_WarnMsg
(
4
,
"input info: found free iovec"
);
}
if
(
(
(
p_netlist
->
i_data_end
-
p_netlist
->
i_data_start
)
&
p_netlist
->
i_nb_data
)
<
p_netlist
->
i_read_once
)
{
intf_WarnMsg
(
4
,
"input info: waiting for free data packet"
);
msleep
(
INPUT_IDLE_SLEEP
);
while
(
(
(
p_netlist
->
i_data_end
-
p_netlist
->
i_data_start
)
&
p_netlist
->
i_nb_data
)
<
p_netlist
->
i_read_once
)
{
msleep
(
INPUT_IDLE_SLEEP
);
}
intf_WarnMsg
(
4
,
"input info: found free data packet"
);
}
/* readv only takes contiguous buffers
* so, as a solution, we chose to have a FIFO a bit longer
* than i_nb_data, and copy the begining of the FIFO to its end
* if the readv needs to go after the end */
if
(
p_netlist
->
i_nb_iovec
-
p_netlist
->
i_iovec_start
+
1
<
p_netlist
->
i_read_once
)
{
memcpy
(
&
p_netlist
->
p_free_iovec
[
p_netlist
->
i_nb_iovec
+
1
],
p_netlist
->
p_free_iovec
,
(
p_netlist
->
i_read_once
-
(
p_netlist
->
i_nb_iovec
+
1
-
p_netlist
->
i_iovec_start
))
*
sizeof
(
struct
iovec
)
);
}
return
p_netlist
->
p_free_iovec
+
p_netlist
->
i_iovec_start
;
}
/*****************************************************************************
* input_NetlistMviovec: move the iovec pointer by one after a readv()
* operation and gives a data_packet corresponding to iovec in p_data
*****************************************************************************/
void
input_NetlistMviovec
(
void
*
p_method_data
,
int
i_nb_iovec
,
struct
data_packet_s
**
pp_data
)
{
netlist_t
*
p_netlist
;
unsigned
int
i_loop
=
0
;
/* cast */
p_netlist
=
(
netlist_t
*
)
p_method_data
;
/* lock */
vlc_mutex_lock
(
&
p_netlist
->
lock
);
/* Fills a table of pointers to packets associated with the io_vec's */
while
(
i_loop
<
i_nb_iovec
)
{
pp_data
[
i_loop
]
=
p_netlist
->
pp_free_data
[
p_netlist
->
i_data_start
];
pp_data
[
i_loop
]
->
p_buffer
=
p_netlist
->
p_free_iovec
[
p_netlist
->
i_iovec_start
].
iov_base
;
pp_data
[
i_loop
]
->
p_payload_start
=
pp_data
[
i_loop
]
->
p_buffer
;
pp_data
[
i_loop
]
->
p_payload_end
=
pp_data
[
i_loop
]
->
p_buffer
+
p_netlist
->
i_buffer_size
;
pp_data
[
i_loop
]
->
p_next
=
NULL
;
pp_data
[
i_loop
]
->
b_discard_payload
=
0
;
pp_data
[
i_loop
]
->
pi_refcount
=
p_netlist
->
pi_refcount
+
p_netlist
->
i_iovec_start
;
if
(
(
*
pp_data
[
i_loop
]
->
pi_refcount
)
!=
0
)
{
intf_ErrMsg
(
"netlist error: refcount should be 0 (%d)"
,
(
*
pp_data
[
i_loop
]
->
pi_refcount
)
);
}
(
*
pp_data
[
i_loop
]
->
pi_refcount
)
=
1
;
p_netlist
->
i_iovec_start
++
;
p_netlist
->
i_iovec_start
&=
p_netlist
->
i_nb_iovec
;
p_netlist
->
i_data_start
++
;
p_netlist
->
i_data_start
&=
p_netlist
->
i_nb_data
;
i_loop
++
;
}
/* unlock */
vlc_mutex_unlock
(
&
p_netlist
->
lock
);
}
/*****************************************************************************
* input_NetlistNewPtr: returns a free data_packet_t
* Gives a pointer ; its fields need to be initialized
*****************************************************************************/
struct
data_packet_s
*
input_NetlistNewPtr
(
void
*
p_method_data
)
{
netlist_t
*
p_netlist
;
struct
data_packet_s
*
p_return
;
/* cast */
p_netlist
=
(
netlist_t
*
)
p_method_data
;
/* lock */
vlc_mutex_lock
(
&
p_netlist
->
lock
);
/* check */
if
(
p_netlist
->
i_data_start
==
p_netlist
->
i_data_end
)
{
intf_ErrMsg
(
"Empty Data FIFO in netlist. Unable to allocate memory"
);
return
(
NULL
);
}
p_return
=
(
p_netlist
->
pp_free_data
[
p_netlist
->
i_data_start
]);
p_netlist
->
i_data_start
++
;
p_netlist
->
i_data_start
&=
p_netlist
->
i_nb_data
;
p_return
->
p_payload_start
=
p_return
->
p_buffer
;
p_return
->
p_payload_end
=
p_return
->
p_buffer
+
p_netlist
->
i_buffer_size
;
p_return
->
p_next
=
NULL
;
p_return
->
b_discard_payload
=
0
;
/* unlock */
vlc_mutex_unlock
(
&
p_netlist
->
lock
);
return
(
p_return
);
}
/*****************************************************************************
* input_NetlistNewPacket: returns a free data_packet_t, and takes
* a corresponding storage iovec.
*****************************************************************************/
struct
data_packet_s
*
input_NetlistNewPacket
(
void
*
p_method_data
,
size_t
i_buffer_size
)
{
netlist_t
*
p_netlist
;
struct
data_packet_s
*
p_packet
;
/* cast */
p_netlist
=
(
netlist_t
*
)
p_method_data
;
#ifdef DEBUG
if
(
i_buffer_size
>
p_netlist
->
i_buffer_size
)
{
/* This should not happen */
intf_ErrMsg
(
"Netlist packet too small !"
);
return
NULL
;
}
#endif
/* lock */
vlc_mutex_lock
(
&
p_netlist
->
lock
);
/* check */
if
(
p_netlist
->
i_iovec_start
==
p_netlist
->
i_iovec_end
)
{
intf_ErrMsg
(
"Empty io_vec FIFO in netlist. Unable to allocate memory"
);
return
(
NULL
);
}
if
(
p_netlist
->
i_data_start
==
p_netlist
->
i_data_end
)
{
intf_ErrMsg
(
"Empty Data FIFO in netlist. Unable to allocate memory"
);
return
(
NULL
);
}
/* Gives an io_vec and associated data */
p_packet
=
p_netlist
->
pp_free_data
[
p_netlist
->
i_data_start
];
p_packet
->
p_buffer
=
p_netlist
->
p_free_iovec
[
p_netlist
->
i_iovec_start
].
iov_base
;
p_packet
->
p_payload_start
=
p_packet
->
p_buffer
;
p_packet
->
p_payload_end
=
p_packet
->
p_buffer
+
i_buffer_size
;
p_packet
->
p_next
=
NULL
;
p_packet
->
b_discard_payload
=
0
;
p_packet
->
pi_refcount
=
p_netlist
->
pi_refcount
+
p_netlist
->
i_iovec_start
;
if
(
(
*
p_packet
->
pi_refcount
)
!=
0
)
{
intf_ErrMsg
(
"netlist error: refcount should be 0 (%d)"
,
(
*
p_packet
->
pi_refcount
)
);
}
(
*
p_packet
->
pi_refcount
)
=
1
;
p_netlist
->
i_iovec_start
++
;
p_netlist
->
i_iovec_start
&=
p_netlist
->
i_nb_iovec
;
p_netlist
->
i_data_start
++
;
p_netlist
->
i_data_start
&=
p_netlist
->
i_nb_data
;
/* unlock */
vlc_mutex_unlock
(
&
p_netlist
->
lock
);
return
p_packet
;
}
/*****************************************************************************
* input_NetlistNewPES: returns a free pes_packet_t
*****************************************************************************/
struct
pes_packet_s
*
input_NetlistNewPES
(
void
*
p_method_data
)
{
netlist_t
*
p_netlist
;
pes_packet_t
*
p_return
;
/* cast */
p_netlist
=
(
netlist_t
*
)
p_method_data
;
/* lock */
vlc_mutex_lock
(
&
p_netlist
->
lock
);
/* check */
if
(
p_netlist
->
i_pes_start
==
p_netlist
->
i_pes_end
)
{
intf_ErrMsg
(
"Empty PES FIFO in netlist - Unable to allocate memory"
);
return
(
NULL
);
}
/* allocate */
p_return
=
p_netlist
->
pp_free_pes
[
p_netlist
->
i_pes_start
];
p_netlist
->
i_pes_start
++
;
p_netlist
->
i_pes_start
&=
p_netlist
->
i_nb_pes
;
/* unlock */
vlc_mutex_unlock
(
&
p_netlist
->
lock
);
/* initialize PES */
p_return
->
b_data_alignment
=
0
;
p_return
->
b_discontinuity
=
0
;
p_return
->
i_pts
=
0
;
p_return
->
i_dts
=
0
;
p_return
->
i_pes_size
=
0
;
p_return
->
p_first
=
NULL
;
return
(
p_return
);
}
/*****************************************************************************
* input_NetlistDeletePacket: puts a data_packet_t back into the netlist
*****************************************************************************/
void
input_NetlistDeletePacket
(
void
*
p_method_data
,
data_packet_t
*
p_data
)
{
netlist_t
*
p_netlist
;
/* cast */
p_netlist
=
(
netlist_t
*
)
p_method_data
;
/* lock */
vlc_mutex_lock
(
&
p_netlist
->
lock
);
/* Delete data_packet */
p_netlist
->
i_data_end
++
;
p_netlist
->
i_data_end
&=
p_netlist
->
i_nb_data
;
p_data
->
p_payload_start
=
p_data
->
p_buffer
;
p_data
->
p_payload_end
=
p_data
->
p_buffer
+
p_netlist
->
i_buffer_size
;
p_netlist
->
pp_free_data
[
p_netlist
->
i_data_end
]
=
p_data
;
p_data
->
p_next
=
NULL
;
p_data
->
b_discard_payload
=
0
;
/* Update reference counter */
(
*
p_data
->
pi_refcount
)
--
;
if
(
(
*
p_data
->
pi_refcount
)
==
0
)
{
(
*
p_data
->
pi_refcount
)
=
0
;
p_netlist
->
i_iovec_end
++
;
p_netlist
->
i_iovec_end
&=
p_netlist
->
i_nb_iovec
;
p_netlist
->
p_free_iovec
[
p_netlist
->
i_iovec_end
].
iov_base
=
p_data
->
p_buffer
;
}
else
if
(
(
*
p_data
->
pi_refcount
)
<
0
)
{
intf_ErrMsg
(
"netlist error: refcount can't be negative (%d)"
,
(
*
p_data
->
pi_refcount
)
);
}
/* unlock */
vlc_mutex_unlock
(
&
p_netlist
->
lock
);
}
/*****************************************************************************
* input_NetlistDeletePES: puts a pes_packet_t back into the netlist
*****************************************************************************/
void
input_NetlistDeletePES
(
void
*
p_method_data
,
pes_packet_t
*
p_pes
)
{
netlist_t
*
p_netlist
;
data_packet_t
*
p_current_packet
;
data_packet_t
*
p_next_packet
;
/* cast */
p_netlist
=
(
netlist_t
*
)
p_method_data
;
/* lock */
vlc_mutex_lock
(
&
p_netlist
->
lock
);
/* delete free p_pes->p_first, p_next ... */
p_current_packet
=
p_pes
->
p_first
;
while
(
p_current_packet
!=
NULL
)
{
/* copy of NetListDeletePacket, duplicate code avoid many locks */
p_netlist
->
i_data_end
++
;
p_netlist
->
i_data_end
&=
p_netlist
->
i_nb_data
;
/* re initialize */
p_current_packet
->
p_payload_start
=
p_current_packet
->
p_buffer
;
p_current_packet
->
p_payload_end
=
p_current_packet
->
p_buffer
+
p_netlist
->
i_buffer_size
;
p_netlist
->
pp_free_data
[
p_netlist
->
i_data_end
]
=
p_current_packet
;
/* Update reference counter */
(
*
p_current_packet
->
pi_refcount
)
--
;
if
(
(
*
p_current_packet
->
pi_refcount
)
==
0
)
{
(
*
p_current_packet
->
pi_refcount
)
=
0
;
p_netlist
->
i_iovec_end
++
;
p_netlist
->
i_iovec_end
&=
p_netlist
->
i_nb_iovec
;
p_netlist
->
p_free_iovec
[
p_netlist
->
i_iovec_end
].
iov_base
=
p_current_packet
->
p_buffer
;
}
else
if
(
(
*
p_current_packet
->
pi_refcount
)
<
0
)
{
intf_ErrMsg
(
"netlist error: refcount can't be negative (%d)"
,
(
*
p_current_packet
->
pi_refcount
)
);
}
p_next_packet
=
p_current_packet
->
p_next
;
p_current_packet
->
p_next
=
NULL
;
p_current_packet
->
b_discard_payload
=
0
;
p_current_packet
=
p_next_packet
;
}
/* delete our current PES packet */
p_netlist
->
i_pes_end
++
;
p_netlist
->
i_pes_end
&=
p_netlist
->
i_nb_pes
;
p_netlist
->
pp_free_pes
[
p_netlist
->
i_pes_end
]
=
p_pes
;
/* unlock */
vlc_mutex_unlock
(
&
p_netlist
->
lock
);
}
/*****************************************************************************
* input_NetlistEnd: frees all allocated structures
*****************************************************************************/
void
input_NetlistEnd
(
input_thread_t
*
p_input
)
{
netlist_t
*
p_netlist
;
/* cast */
p_netlist
=
(
netlist_t
*
)
p_input
->
p_method_data
;
/* destroy the mutex lock */
vlc_mutex_destroy
(
&
p_netlist
->
lock
);
/* free the FIFO, the buffer, and the netlist structure */
free
(
p_netlist
->
pi_refcount
);
free
(
p_netlist
->
p_free_iovec
);
free
(
p_netlist
->
pp_free_pes
);
free
(
p_netlist
->
pp_free_data
);
free
(
p_netlist
->
p_pes
);
free
(
p_netlist
->
p_data
);
free
(
p_netlist
->
p_buffers
);
/* free the netlist */
free
(
p_netlist
);
}
src/input/mpeg_system.c
View file @
d5b04453
...
...
@@ -2,7 +2,7 @@
* mpeg_system.c: TS, PS and PES management
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: mpeg_system.c,v 1.69.2.
4 2001/12/17 16:37:25 sam
Exp $
* $Id: mpeg_system.c,v 1.69.2.
5 2001/12/31 01:21:45 massiot
Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr>
...
...
@@ -136,7 +136,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
if
(
MoveChunk
(
p_header
,
&
p_data
,
&
p_byte
,
PES_HEADER_SIZE
)
!=
PES_HEADER_SIZE
)
{
intf_WarnMsg
(
1
,
"PES packet too short to have a header"
);
intf_WarnMsg
(
1
,
"
input:
PES packet too short to have a header"
);
p_input
->
pf_delete_pes
(
p_input
->
p_method_data
,
p_pes
);
p_pes
=
NULL
;
return
;
...
...
@@ -154,7 +154,8 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
if
(
(
p_header
[
0
]
||
p_header
[
1
]
||
(
p_header
[
2
]
!=
1
))
)
{
/* packet_start_code_prefix != 0x000001 */
intf_ErrMsg
(
"PES packet doesn't start with 0x000001 : data loss"
);
intf_ErrMsg
(
"input error: data loss, "
"PES packet doesn't start with 0x000001"
);
p_input
->
pf_delete_pes
(
p_input
->
p_method_data
,
p_pes
);
p_pes
=
NULL
;
}
...
...
@@ -167,7 +168,8 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
{
/* PES_packet_length is set and != total received payload */
/* Warn the decoder that the data may be corrupt. */
intf_WarnMsg
(
1
,
"PES sizes do not match : packet corrupted"
);
intf_WarnMsg
(
1
,
"input: packet corrupted, "
"PES sizes do not match"
);
}
switch
(
p_es
->
i_stream_id
)
...
...
@@ -273,7 +275,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
}
if
(
i_pes_header_size
==
23
)
{
intf_ErrMsg
(
"
T
oo much MPEG-1 stuffing"
);
intf_ErrMsg
(
"
input error: t
oo much MPEG-1 stuffing"
);
p_input
->
pf_delete_pes
(
p_input
->
p_method_data
,
p_pes
);
p_pes
=
NULL
;
return
;
...
...
@@ -474,10 +476,11 @@ void input_GatherPES( input_thread_t * p_input, data_packet_t * p_data,
else
{
/* Update the relations between the data packets */
p_es
->
p_last
->
p_next
=
p_data
;
p_
p
es
->
p_last
->
p_next
=
p_data
;
}
p_es
->
p_last
=
p_data
;
p_pes
->
p_last
=
p_data
;
p_pes
->
i_nb_data
++
;
/* Size of the payload carried in the data packet */
p_pes
->
i_pes_size
+=
(
p_data
->
p_payload_end
...
...
@@ -505,13 +508,13 @@ static u16 GetID( data_packet_t * p_data )
{
u16
i_id
;
i_id
=
p_data
->
p_
payload_start
[
3
];
/* stream_id */
i_id
=
p_data
->
p_
demux_start
[
3
];
/* stream_id */
if
(
i_id
==
0xBD
)
{
/* FIXME : this is not valid if the header is split in multiple
* packets */
/* stream_private_id */
i_id
|=
p_data
->
p_
payload_start
[
9
+
p_data
->
p_payload
_start
[
8
]
]
<<
8
;
i_id
|=
p_data
->
p_
demux_start
[
9
+
p_data
->
p_demux
_start
[
8
]
]
<<
8
;
}
return
(
i_id
);
}
...
...
@@ -530,14 +533,14 @@ static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data )
int
i
;
int
i_new_es_number
=
0
;
if
(
p_data
->
p_
payload
_start
+
10
>
p_data
->
p_payload_end
)
if
(
p_data
->
p_
demux
_start
+
10
>
p_data
->
p_payload_end
)
{
intf_ErrMsg
(
"PSM too short : packet corrupt"
);
return
;
}
if
(
p_demux
->
b_has_PSM
&&
p_demux
->
i_PSM_version
==
(
p_data
->
p_
payload
_start
[
6
]
&
0x1F
)
)
&&
p_demux
->
i_PSM_version
==
(
p_data
->
p_
demux
_start
[
6
]
&
0x1F
)
)
{
/* Already got that one. */
return
;
...
...
@@ -545,12 +548,12 @@ static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data )
intf_DbgMsg
(
"Building PSM"
);
p_demux
->
b_has_PSM
=
1
;
p_demux
->
i_PSM_version
=
p_data
->
p_
payload
_start
[
6
]
&
0x1F
;
p_demux
->
i_PSM_version
=
p_data
->
p_
demux
_start
[
6
]
&
0x1F
;
/* Go to elementary_stream_map_length, jumping over
* program_stream_info. */
p_byte
=
p_data
->
p_
payload
_start
+
10
+
U16_AT
(
&
p_data
->
p_
payload
_start
[
8
]);
p_byte
=
p_data
->
p_
demux
_start
+
10
+
U16_AT
(
&
p_data
->
p_
demux
_start
[
8
]);
if
(
p_byte
>
p_data
->
p_payload_end
)
{
intf_ErrMsg
(
"PSM too short : packet corrupt"
);
...
...
@@ -655,7 +658,7 @@ es_descriptor_t * input_ParsePS( input_thread_t * p_input,
u32
i_code
;
es_descriptor_t
*
p_es
=
NULL
;
i_code
=
p_data
->
p_
payload
_start
[
3
];
i_code
=
p_data
->
p_
demux
_start
[
3
];
if
(
i_code
>
0xBC
)
/* ES start code */
{
...
...
@@ -694,7 +697,7 @@ es_descriptor_t * input_ParsePS( input_thread_t * p_input,
i_id
,
0
);
if
(
p_es
!=
NULL
)
{
p_es
->
i_stream_id
=
p_data
->
p_
payload
_start
[
3
];
p_es
->
i_stream_id
=
p_data
->
p_
demux
_start
[
3
];
/* Set stream type and auto-spawn. */
if
(
(
i_id
&
0xF0
)
==
0xE0
)
...
...
@@ -794,7 +797,10 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
boolean_t
b_trash
=
0
;
es_descriptor_t
*
p_es
=
NULL
;
i_code
=
U32_AT
(
p_data
->
p_payload_start
);
i_code
=
((
u32
)
p_data
->
p_demux_start
[
0
]
<<
24
)
|
((
u32
)
p_data
->
p_demux_start
[
1
]
<<
16
)
|
((
u32
)
p_data
->
p_demux_start
[
2
]
<<
8
)
|
p_data
->
p_demux_start
[
3
];
if
(
i_code
<=
0x1BC
)
{
switch
(
i_code
)
...
...
@@ -805,12 +811,12 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
mtime_t
scr_time
;
u32
i_mux_rate
;
if
(
(
p_data
->
p_
payload
_start
[
4
]
&
0xC0
)
==
0x40
)
if
(
(
p_data
->
p_
demux
_start
[
4
]
&
0xC0
)
==
0x40
)
{
/* MPEG-2 */
byte_t
p_header
[
14
];
byte_t
*
p_byte
;
p_byte
=
p_data
->
p_
payload
_start
;
p_byte
=
p_data
->
p_
demux
_start
;
if
(
MoveChunk
(
p_header
,
&
p_data
,
&
p_byte
,
14
)
!=
14
)
{
...
...
@@ -841,7 +847,7 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
/* MPEG-1 SCR is like PTS. */
byte_t
p_header
[
12
];
byte_t
*
p_byte
;
p_byte
=
p_data
->
p_
payload
_start
;
p_byte
=
p_data
->
p_
demux
_start
;
if
(
MoveChunk
(
p_header
,
&
p_data
,
&
p_byte
,
12
)
!=
12
)
{
...
...
@@ -943,7 +949,7 @@ void input_DemuxTS( input_thread_t * p_input, data_packet_t * p_data )
es_ts_data_t
*
p_es_demux
=
NULL
;
pgrm_ts_data_t
*
p_pgrm_demux
=
NULL
;
#define p (p_data->p_
buffer
)
#define p (p_data->p_
demux_start
)
/* Extract flags values from TS common header. */
i_pid
=
((
p
[
1
]
&
0x1F
)
<<
8
)
|
p
[
2
];
b_unit_start
=
(
p
[
1
]
&
0x40
);
...
...
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