Commit 917d2574 authored by Stéphane Borel's avatar Stéphane Borel

-New function for DVD reading, that is able to read multiple blocks

(I've chosen 32 now), that doesn't use any memcpy anymore and is also much
faster. It is ready now for cell positioning in multi-angle DVD (to come
soon).

-DVD specific netlist adapted to 2048 bytes long blocks that contain
several data_packets.

-Modification in mpeg_system.c to use p_payload_start instead of
p_buffer (necessary for DVD plugin). It does not break other plugins
since they set p_payload_start to p_buffer

-New field i_read_once in input_thread_s to be able to read more than
the TS related 7 packets ; i_read_once is set to INPUT_READ_ONCE by
defaults but plugins can change it during initialisation.

Please check that nothing is broken :)
parent 2fe30f26
......@@ -300,6 +300,7 @@ PLUGIN_DUMMY = plugins/dummy/dummy.o \
PLUGIN_DVD = plugins/dvd/dvd.o \
plugins/dvd/input_dvd.o \
plugins/dvd/dvd_netlist.o \
plugins/dvd/dvd_ioctl.o \
plugins/dvd/dvd_ifo.o \
plugins/dvd/dvd_udf.o \
......
......@@ -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.22 2001/02/08 17:44:12 massiot Exp $
* $Id: input_ext-dec.h,v 1.23 2001/03/02 03:32:46 stef Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Michel Kaempf <maxx@via.ecp.fr>
......@@ -40,6 +40,8 @@ typedef struct data_packet_s
byte_t * p_payload_end; /* guess ? :-) */
boolean_t b_discard_payload; /* is the packet messed up ? */
int * pi_refcount;
/* Used to chain the TS packets that carry data for a same PES or PSI */
struct data_packet_s * p_next;
} data_packet_t;
......
......@@ -4,7 +4,7 @@
* control the pace of reading.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ext-intf.h,v 1.26 2001/02/22 17:00:20 massiot Exp $
* $Id: input_ext-intf.h,v 1.27 2001/03/02 03:32:46 stef Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -278,6 +278,8 @@ typedef struct input_thread_s
char * p_source;
int i_handle; /* socket or file descriptor */
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 */
......
This diff is collapsed.
/*****************************************************************************
* dvd_netlist.h: Specific netlist structures for DVD packets
*****************************************************************************
* Copyright (C) 1998, 1999, 2000, 2001 VideoLAN
* $Id: dvd_netlist.h,v 1.1 2001/03/02 03:32:46 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.
*****************************************************************************/
/*****************************************************************************
* netlist_t: structure to manage a netlist
*****************************************************************************/
typedef struct netlist_s
{
vlc_mutex_t lock;
size_t i_buffer_size;
/* 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 */
/* FIFOs of free packets */
data_packet_t ** pp_free_data;
pes_packet_t ** pp_free_pes;
struct iovec * p_free_iovec;
/* FIFO size */
unsigned int i_nb_iovec;
unsigned int i_nb_pes;
unsigned int i_nb_data;
/* 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;
/* Reference counters for iovec */
unsigned int * pi_refcount;
/* Nb of packets read once */
unsigned int i_read_once;
} netlist_t;
/*****************************************************************************
* Prototypes
*****************************************************************************/
int DVDNetlistInit( struct input_thread_s *,
int , int, int, size_t, int );
struct iovec * DVDGetiovec( void * p_method_data );
void DVDMviovec( void * , int, struct data_packet_s **);
struct data_packet_s * DVDNewPtr( void * );
struct data_packet_s * DVDNewPacket( void *, size_t );
struct pes_packet_s * DVDNewPES( void * );
void DVDDeletePacket( void *, struct data_packet_s * );
void DVDDeletePES( void *, struct pes_packet_s * );
void DVDNetlistEnd( struct input_thread_s * );
......@@ -10,7 +10,7 @@
* -dvd_udf to find files
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: input_dvd.c,v 1.21 2001/02/26 12:16:28 sam Exp $
* $Id: input_dvd.c,v 1.22 2001/03/02 03:32:46 stef Exp $
*
* Author: Stphane Borel <stef@via.ecp.fr>
*
......@@ -65,8 +65,8 @@
#include "input_ext-dec.h"
#include "input.h"
#include "input_netlist.h"
#include "dvd_netlist.h"
#include "dvd_ifo.h"
#include "dvd_css.h"
#include "input_dvd.h"
......@@ -262,10 +262,10 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
input.pf_read = DVDRead;
input.pf_set_area = DVDSetArea;
input.pf_demux = input_DemuxPS;
input.pf_new_packet = input_NetlistNewPacket;
input.pf_new_pes = input_NetlistNewPES;
input.pf_delete_packet = input_NetlistDeletePacket;
input.pf_delete_pes = input_NetlistDeletePES;
input.pf_new_packet = DVDNewPacket;
input.pf_new_pes = DVDNewPES;
input.pf_delete_packet = DVDDeletePacket;
input.pf_delete_pes = DVDDeletePES;
input.pf_rewind = DVDRewind;
input.pf_seek = DVDSeek;
#undef input
......@@ -487,7 +487,8 @@ static int DVDSetArea( input_thread_t * p_input,
{
#if 0
fprintf( stderr, "Audio %d: %x %x %x %x %x %x\n", i,
fprintf( stderr, "Audio %d: %x %x %x %x %x %x %x\n", i,
p_method->ifo.vts.mat.p_audio_atrt[i].i_num_channels,
p_method->ifo.vts.mat.p_audio_atrt[i].i_coding_mode,
p_method->ifo.vts.mat.p_audio_atrt[i].i_multichannel_extension,
p_method->ifo.vts.mat.p_audio_atrt[i].i_type,
......@@ -674,15 +675,17 @@ static void DVDInit( input_thread_t * p_input )
p_input->p_method_data = NULL;
p_method->i_fd = p_input->i_handle;
/* FIXME: read several packets once */
p_method->i_read_once = 1;
p_method->i_block_once = 32;
p_input->i_read_once = 128;
p_method->b_encrypted = DVDCheckCSS( p_input );
lseek( p_input->i_handle, 0, SEEK_SET );
/* Reading structures initialisation */
input_NetlistInit( p_input, 4096, 4096, DVD_LB_SIZE,
p_method->i_read_once );
DVDNetlistInit( p_input, 4096, 16384, 4096, DVD_LB_SIZE,
p_method->i_block_once );
intf_WarnMsg( 2, "DVD: Netlist initialized" );
/* Ifo initialisation */
......@@ -781,7 +784,7 @@ static void DVDEnd( input_thread_t * p_input )
// IfoEnd( (ifo_t*)(&p_input->p_plugin_data->ifo ) );
free( p_input->stream.p_demux_data );
free( p_input->p_plugin_data );
input_NetlistEnd( p_input );
DVDNetlistEnd( p_input );
}
/*****************************************************************************
......@@ -791,59 +794,57 @@ static void DVDEnd( input_thread_t * p_input )
* EOF.
*****************************************************************************/
static int DVDRead( input_thread_t * p_input,
data_packet_t ** pp_packets )
data_packet_t ** pp_packets )
{
thread_dvd_data_t * p_method;
netlist_t * p_netlist;
struct iovec * p_vec;
struct data_packet_s * p_data;
struct data_packet_s * pp_data[p_input->i_read_once];
u8 * pi_cur;
int i_packet_size;
int i_iovec;
int i_packet;
int i_pos;
int i;
boolean_t b_first_packet;
p_method = ( thread_dvd_data_t * ) p_input->p_plugin_data;
p_netlist = ( netlist_t * ) p_input->p_method_data;
/* Get an iovec pointer */
if( ( p_vec = input_NetlistGetiovec( p_netlist ) ) == NULL )
if( ( p_vec = DVDGetiovec( p_netlist ) ) == NULL )
{
intf_ErrMsg( "DVD: read error" );
return -1;
}
/* Reads from DVD */
readv( p_input->i_handle, p_vec, p_method->i_read_once );
readv( p_input->i_handle, p_vec, p_method->i_block_once );
if( p_method->b_encrypted )
/* Update netlist indexes */
DVDMviovec( p_netlist, p_method->i_block_once, pp_data );
i_packet = 0;
/* Read headers to compute payload length */
for( i_iovec = 0 ; i_iovec < p_method->i_block_once ; i_iovec++ )
{
for( i=0 ; i<p_method->i_read_once ; i++ )
if( p_method->b_encrypted )
{
CSSDescrambleSector( p_method->css.pi_title_key,
p_vec[i].iov_base );
((u8*)(p_vec[i].iov_base))[0x14] &= 0x8F;
p_vec[i_iovec].iov_base );
((u8*)(p_vec[i_iovec].iov_base))[0x14] &= 0x8F;
}
}
/* Update netlist indexes */
input_NetlistMviovec( p_netlist, p_method->i_read_once, &p_data );
i_packet = 0;
/* Read headers to compute payload length */
for( i = 0 ; i < p_method->i_read_once ; i++ )
{
i_pos = 0;
b_first_packet = 1;
while( i_pos < p_netlist->i_buffer_size )
{
pi_cur = (u8*)(p_vec[i].iov_base + i_pos);
pi_cur = (u8*)(p_vec[i_iovec].iov_base + i_pos);
/*default 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] = DVDNewPtr( p_netlist );
}
else
{
......@@ -863,31 +864,33 @@ static int DVDRead( input_thread_t * p_input,
intf_ErrMsg( "Unable to determine stream type" );
return( -1 );
}
pp_packets[i_packet] = pp_data[i_iovec];
}
if( b_first_packet )
{
p_data->b_discard_payload = 0;
b_first_packet = 0;
}
else
{
p_data = input_NetlistNewPacket( p_netlist ,
i_packet_size + 6 );
memcpy( p_data->p_buffer,
p_vec[i].iov_base + i_pos , i_packet_size + 6 );
}
p_data->p_payload_end = p_data->p_payload_start + i_packet_size + 6;
pp_packets[i_packet] = p_data;
(*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;
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;
i_packet++;
i_pos += i_packet_size + 6;
}
}
pp_packets[i_packet] = NULL;
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.p_selected_area->i_tell +=
p_method->i_read_once *DVD_LB_SIZE;
p_method->i_block_once *DVD_LB_SIZE;
vlc_mutex_unlock( &p_input->stream.stream_lock );
return( 0 );
......
......@@ -33,7 +33,9 @@ typedef struct thread_dvd_data_s
{
int i_fd; // File descriptor of device
boolean_t b_encrypted; // CSS encryption
int i_read_once; // NB of bytes read by DVDRead
int i_block_once; // Nb of block read once by
// readv
int i_chapter_nb;
off_t i_start;
......
......@@ -4,7 +4,7 @@
* decoders.
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: input.c,v 1.87 2001/02/20 09:10:36 sam Exp $
* $Id: input.c,v 1.88 2001/03/02 03:32:46 stef Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -89,6 +89,9 @@ 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;
......@@ -193,7 +196,6 @@ void input_DestroyThread( input_thread_t *p_input, int *pi_status )
*****************************************************************************/
static void RunThread( input_thread_t *p_input )
{
data_packet_t * pp_packets[INPUT_READ_ONCE];
int i_error, i;
if( InitThread( p_input ) )
......@@ -209,6 +211,7 @@ static void RunThread( input_thread_t *p_input )
while( !p_input->b_die && !p_input->b_error && !p_input->b_eof )
{
data_packet_t * pp_packets[p_input->i_read_once];
#ifdef STATS
p_input->c_loops++;
......@@ -241,7 +244,7 @@ static void RunThread( input_thread_t *p_input )
i_error = p_input->pf_read( p_input, pp_packets );
/* Demultiplex read packets. */
for( i = 0; i < INPUT_READ_ONCE && pp_packets[i] != NULL; i++ )
for( i = 0; i < p_input->i_read_once && pp_packets[i] != NULL; i++ )
{
p_input->pf_demux( p_input, pp_packets[i] );
}
......
......@@ -2,7 +2,7 @@
* mpeg_system.c: TS, PS and PES management
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: mpeg_system.c,v 1.38 2001/02/21 04:38:59 henri Exp $
* $Id: mpeg_system.c,v 1.39 2001/03/02 03:32:46 stef Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr>
......@@ -500,11 +500,11 @@ static u16 GetID( data_packet_t * p_data )
{
u16 i_id;
i_id = p_data->p_buffer[3]; /* stream_id */
i_id = p_data->p_payload_start[3]; /* stream_id */
if( i_id == 0xBD )
{
/* stream_private_id */
i_id |= p_data->p_buffer[ 9 + p_data->p_buffer[8] ] << 8;
i_id |= p_data->p_payload_start[ 9 + p_data->p_payload_start[8] ] << 8;
}
return( i_id );
}
......@@ -528,7 +528,7 @@ static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data )
}
if( p_demux->b_has_PSM
&& p_demux->i_PSM_version == (p_data->p_buffer[6] & 0x1F) )
&& p_demux->i_PSM_version == (p_data->p_payload_start[6] & 0x1F) )
{
/* Already got that one. */
return;
......@@ -536,7 +536,7 @@ 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_buffer[6] & 0x1F;
p_demux->i_PSM_version = p_data->p_payload_start[6] & 0x1F;
/* Go to elementary_stream_map_length, jumping over
* program_stream_info. */
......@@ -647,7 +647,7 @@ es_descriptor_t * input_ParsePS( input_thread_t * p_input,
u32 i_code;
es_descriptor_t * p_es = NULL;
i_code = U32_AT( p_data->p_buffer );
i_code = U32_AT( p_data->p_payload_start );
if( i_code > 0x1BC ) /* ES start code */
{
u16 i_id;
......@@ -685,7 +685,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_buffer[3];
p_es->i_stream_id = p_data->p_payload_start[3];
/* Set stream type and auto-spawn. */
if( (i_id & 0xF0) == 0xE0 )
......@@ -777,7 +777,7 @@ 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_buffer );
i_code = U32_AT( p_data->p_payload_start );
if( i_code <= 0x1BC )
{
switch( i_code )
......@@ -788,30 +788,30 @@ 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_buffer[4] & 0xC0) == 0x40 )
if( (p_data->p_payload_start[4] & 0xC0) == 0x40 )
{
/* MPEG-2 */
scr_time =
((mtime_t)(p_data->p_buffer[4] & 0x38) << 27) |
((mtime_t)(U32_AT(p_data->p_buffer + 4) & 0x03FFF800)
((mtime_t)(p_data->p_payload_start[4] & 0x38) << 27) |
((mtime_t)(U32_AT(p_data->p_payload_start + 4) & 0x03FFF800)
<< 4) |
((mtime_t)(U32_AT(p_data->p_buffer + 6) & 0x03FFF800)
((mtime_t)(U32_AT(p_data->p_payload_start + 6) & 0x03FFF800)
>> 11);
/* mux_rate */
i_mux_rate = (U32_AT(p_data->p_buffer + 10) & 0xFFFFFC00);
i_mux_rate = (U32_AT(p_data->p_payload_start + 10) & 0xFFFFFC00);
}
else
{
/* MPEG-1 SCR is like PTS. */
scr_time =
((mtime_t)(p_data->p_buffer[4] & 0x0E) << 29) |
(((mtime_t)U16_AT(p_data->p_buffer + 5) << 14)
((mtime_t)(p_data->p_payload_start[4] & 0x0E) << 29) |
(((mtime_t)U16_AT(p_data->p_payload_start + 5) << 14)
- (1 << 14)) |
((mtime_t)U16_AT(p_data->p_buffer + 7) >> 1);
((mtime_t)U16_AT(p_data->p_payload_start + 7) >> 1);
/* mux_rate */
i_mux_rate = (U32_AT(p_data->p_buffer + 8) & 0x8FFFFE);
i_mux_rate = (U32_AT(p_data->p_payload_start + 8) & 0x8FFFFE);
}
/* Call the pace control. */
input_ClockManageRef( p_input, p_input->stream.pp_programs[0],
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment