mirror of
https://code.videolan.org/videolan/vlc
synced 2024-09-12 13:44:56 +02:00
. Beginning of dvd_input.
. Parsing of ifo file almost completed. . Still does not work well.
This commit is contained in:
parent
e360e2a431
commit
a9729877b7
@ -186,6 +186,8 @@ INTERFACE = src/interface/main.o \
|
||||
|
||||
INPUT = src/input/input_ps.o \
|
||||
src/input/input_ts.o \
|
||||
src/input/dvd_ifo.o \
|
||||
src/input/input_dvd.o \
|
||||
src/input/mpeg_system.o \
|
||||
src/input/input_ext-dec.o \
|
||||
src/input/input_dec.o \
|
||||
|
@ -211,6 +211,8 @@
|
||||
* mark it to be presented */
|
||||
#define DEFAULT_PTS_DELAY (.2*CLOCK_FREQ)
|
||||
|
||||
#define INPUT_DVD_DEVICE_VAR "vlc_dvd_device"
|
||||
#define INPUT_DVD_DEVICE_DEFAULT "/dev/dvd"
|
||||
#define INPUT_DVD_AUDIO_VAR "vlc_dvd_audio"
|
||||
#define INPUT_DVD_CHANNEL_VAR "vlc_dvd_channel"
|
||||
#define INPUT_DVD_SUBTITLE_VAR "vlc_dvd_subtitle"
|
||||
@ -243,9 +245,9 @@
|
||||
#define AOUT_STEREO_DEFAULT 1
|
||||
|
||||
/* Volume */
|
||||
#define VOLUME_DEFAULT 256
|
||||
#define VOLUME_STEP 5
|
||||
#define VOLUME_MAX 765
|
||||
#define VOLUME_DEFAULT 512
|
||||
#define VOLUME_STEP 128
|
||||
#define VOLUME_MAX 1024
|
||||
|
||||
/* Environment variable for output rate, and default value */
|
||||
#define AOUT_RATE_VAR "vlc_audio_rate"
|
||||
|
@ -4,7 +4,7 @@
|
||||
* control the pace of reading.
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: input_ext-intf.h,v 1.8 2000/12/21 19:24:26 massiot Exp $
|
||||
* $Id: input_ext-intf.h,v 1.9 2001/01/14 07:08:00 stef Exp $
|
||||
*
|
||||
* Authors:
|
||||
*
|
||||
@ -255,6 +255,7 @@ typedef struct input_config_s
|
||||
/* Input methods */
|
||||
#define INPUT_METHOD_NONE 0 /* input thread is inactive */
|
||||
#define INPUT_METHOD_FILE 10 /* stream is read from file p_source */
|
||||
#define INPUT_METHOD_DVD 11 /* stream is read from dvd device */
|
||||
#define INPUT_METHOD_UCAST 20 /* UDP unicast */
|
||||
#define INPUT_METHOD_MCAST 21 /* UDP multicast */
|
||||
#define INPUT_METHOD_BCAST 22 /* UDP broadcast */
|
||||
|
@ -44,6 +44,7 @@ typedef struct
|
||||
boolean_t b_audio; /* is audio output allowed ? */
|
||||
boolean_t b_video; /* is video output allowed ? */
|
||||
boolean_t b_vlans; /* are vlans supported ? */
|
||||
boolean_t b_dvd; /* DVD mode ? */
|
||||
|
||||
/* Unique threads */
|
||||
p_aout_thread_t p_aout; /* audio output thread */
|
||||
|
1038
src/input/dvd_ifo.c
Normal file
1038
src/input/dvd_ifo.c
Normal file
File diff suppressed because it is too large
Load Diff
484
src/input/dvd_ifo.h
Normal file
484
src/input/dvd_ifo.h
Normal file
@ -0,0 +1,484 @@
|
||||
/*****************************************************************************
|
||||
* ifo.h: Structures for ifo parsing
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999-2001 VideoLAN
|
||||
*
|
||||
* Author: Stéphane Borel <stef@via.ecp.fr>
|
||||
*
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
#define DVD_LB_SIZE 2048
|
||||
|
||||
/*****************************************************************************
|
||||
* Common structures for Video Management and Video Title sets
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Program Chain structures
|
||||
*/
|
||||
|
||||
/* Program Chain Command Table
|
||||
- start at i_pgc_com_tab_sbyte */
|
||||
typedef struct pgc_com_tab_s
|
||||
{
|
||||
u16 i_pre_com_nb; // 2 bytes
|
||||
u16 i_post_com_nb; // 2 bytes
|
||||
u16 i_cell_com_nb; // 2 bytes
|
||||
// char[2] ???
|
||||
char* psz_pre_com; // i_pre_com_nb * 8 bytes
|
||||
char* psz_post_com; // i_post_com_nb * 8 bytes
|
||||
char* psz_cell_com; // i_cell_com_nb * 8 bytes
|
||||
} pgc_com_tab_t;
|
||||
|
||||
/* Program Chain Map Table
|
||||
* - start at "i_pgc_prg_map_sbyte" */
|
||||
typedef struct pgc_prg_map_s
|
||||
{
|
||||
u8* pi_entry_cell; // i_prg_nb * 1 byte
|
||||
} pgc_prg_map_t;
|
||||
|
||||
/* Cell Playback Information Table
|
||||
* we have a pointer to such a structure for each cell
|
||||
* - first start at "i_cell_play_inf_sbyte" */
|
||||
typedef struct cell_play_inf_s
|
||||
{
|
||||
/* This information concerns the currently selected cell */
|
||||
u16 i_cat; // 2 bytes
|
||||
u8 i_still_time; // 1 byte; in seconds; ff=inf
|
||||
u8 i_com_nb; // 1 byte; 0 = no com
|
||||
u32 i_play_time; // 4 bytes
|
||||
u32 i_entry_sector; // 4 bytes
|
||||
u32 i_first_ilvu_vobu_esector; // 4 bytes; ???
|
||||
u32 i_lvobu_ssector; // 4 bytes
|
||||
u32 i_lsector; // 4 bytes
|
||||
} cell_play_inf_t;
|
||||
|
||||
/* Cell Position Information Table
|
||||
* we have a pointer to such a structure for each cell
|
||||
* - first start at "i_cell_pos_inf_sbyte" */
|
||||
typedef struct cell_pos_inf_s
|
||||
{
|
||||
/* This information concerns the currently selected cell */
|
||||
u16 i_vob_id; // 2 bytes
|
||||
// char ???
|
||||
u8 i_cell_id; // 1 byte
|
||||
} cell_pos_inf_t;
|
||||
|
||||
/* Main structure for Program Chain
|
||||
* - start at i_fp_pgc_sbyte
|
||||
* - or at i_vmgm_pgci_sbyte in vmgm_pgci_srp_t */
|
||||
typedef struct pgc_s
|
||||
{
|
||||
/* Global features of program chain */
|
||||
// char[2] ???
|
||||
u8 i_prg_nb; // 1 byte
|
||||
u8 i_cell_nb; // 1 byte
|
||||
u32 i_play_time; // 4 bytes
|
||||
u32 i_prohibited_user_op; // 4 bytes
|
||||
u16 pi_audio_status[8]; // 8*2 bytes
|
||||
u32 pi_subpic_status[32]; // 32*4 bytes
|
||||
u16 i_next_pgc_nb; // 2 bytes
|
||||
u16 i_prev_pgc_nb; // 2 bytes
|
||||
u16 i_goup_pgc_nb; // 2 bytes
|
||||
u8 i_still_time; // 1 byte ; in seconds
|
||||
u8 i_play_mode; // 1 byte
|
||||
/* In video_ts.ifo, the 3 significant bytes of each color are
|
||||
* preceded by 1 unsignificant byte */
|
||||
u32 pi_yuv_color[16]; // 16*3 bytes
|
||||
/* Here come the start bytes of the following structures */
|
||||
u16 i_com_tab_sbyte; // 2 bytes
|
||||
u16 i_prg_map_sbyte; // 2 bytes
|
||||
u16 i_cell_play_inf_sbyte; // 2 bytes
|
||||
u16 i_cell_pos_inf_sbyte; // 2 bytes
|
||||
/* Predefined structures */
|
||||
pgc_com_tab_t com_tab;
|
||||
pgc_prg_map_t prg_map;
|
||||
cell_play_inf_t* p_cell_play_inf; // i_cell_nb * 24 bytes
|
||||
cell_pos_inf_t* p_cell_pos_inf; // i_cell_nb * 4 bytes
|
||||
} pgc_t;
|
||||
|
||||
/*
|
||||
* Menu PGCI Unit Table
|
||||
*/
|
||||
|
||||
/* Menu PGCI Language unit Descriptor */
|
||||
typedef struct pgci_lu_desc_s
|
||||
{
|
||||
u16 i_lang_code; // 2 bytes (ISO-xx)
|
||||
// char ???
|
||||
u8 i_existence_mask; // 1 byte
|
||||
u32 i_lu_sbyte; // 4 bytes
|
||||
} pgci_lu_desc_t;
|
||||
|
||||
typedef struct pgci_srp_s
|
||||
{
|
||||
u8 i_pgc_cat_mask; // 1 byte
|
||||
u8 i_pgc_cat; // 1 byte
|
||||
u16 i_par_mask; // 2 bytes
|
||||
u32 i_pgci_sbyte; // 4 bytes
|
||||
pgc_t pgc;
|
||||
} pgci_srp_t;
|
||||
|
||||
/* Menu PGCI Language Unit Table
|
||||
* - start at i_lu_sbyte */
|
||||
typedef struct pgci_lu_s
|
||||
{
|
||||
u16 i_srp_nb; // 2 bytes
|
||||
// char[2] ???
|
||||
u32 i_lu_ebyte; // 4 bytes
|
||||
pgci_srp_t* p_srp; // i_srp_nb * 8 bytes
|
||||
} pgci_lu_t;
|
||||
|
||||
/* Main Struct for Menu PGCI
|
||||
* - start at i_*_pgci_ut_ssector */
|
||||
typedef struct pgci_ut_s
|
||||
{
|
||||
u16 i_lu_nb; // 2 bytes; ???
|
||||
// char[2] ???
|
||||
u32 i_ebyte; // 4 bytes
|
||||
pgci_lu_desc_t* p_lu_desc; // i_lu_nb * 8 bytes
|
||||
pgci_lu_t* p_lu; // i_lu_nb * 8 bytes
|
||||
} pgci_ut_t;
|
||||
|
||||
/*
|
||||
* Cell Adress Table Information
|
||||
*/
|
||||
typedef struct cell_inf_s
|
||||
{
|
||||
u16 i_vob_id; // 2 bytes
|
||||
u8 i_cell_id; // 1 byte
|
||||
// char ???
|
||||
u32 i_ssector; // 4 bytes
|
||||
u32 i_esector; // 4 bytes
|
||||
} cell_inf_t;
|
||||
|
||||
typedef struct c_adt_s
|
||||
{
|
||||
u16 i_vob_nb; // 2 bytes
|
||||
// char[2] ???
|
||||
u32 i_ebyte; // 4 bytes
|
||||
cell_inf_t* p_cell_inf;
|
||||
} c_adt_t;
|
||||
|
||||
|
||||
/*
|
||||
* VOBU Adress Map Table
|
||||
*/
|
||||
typedef struct vobu_admap_s
|
||||
{
|
||||
u32 i_ebyte; // 4 bytes
|
||||
u32* pi_vobu_ssector; // (nb of vobu) * 4 bytes
|
||||
} vobu_admap_t;
|
||||
|
||||
/*****************************************************************************
|
||||
* Structures for Video Management (cf video_ts.ifo)
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Video Manager Information Management Table
|
||||
*/
|
||||
typedef struct vmgi_mat_s
|
||||
{
|
||||
char psz_id[13]; // 12 bytes (DVDVIDEO-VMG)
|
||||
u32 i_lsector; // 4 bytes
|
||||
// char[12] ???
|
||||
u32 i_i_lsector; // 4 bytes
|
||||
// char ???
|
||||
u8 i_spec_ver; // 1 byte
|
||||
u32 i_cat; // 4 bytes
|
||||
u16 i_vol_nb; // 2 bytes
|
||||
u16 i_vol; // 2 bytes
|
||||
u8 i_disc_side; // 1 bytes
|
||||
// char[20] ???
|
||||
u16 i_tts_nb; // 2 bytes
|
||||
char psz_provider_id[32]; // 32 bytes
|
||||
u64 i_pos_code; // 8 bytes
|
||||
// char[24] ???
|
||||
u32 i_i_mat_ebyte; // 4 bytes
|
||||
u32 i_fp_pgc_sbyte; // 4 bytes
|
||||
// char[56] ???
|
||||
u32 i_vobs_ssector; // 4 bytes
|
||||
u32 i_ptt_srpt_ssector; // 4 bytes
|
||||
u32 i_pgci_ut_ssector; // 4 bytes
|
||||
u32 i_ptl_mait_ssector; // 4 bytes
|
||||
u32 i_vts_atrt_ssector; // 4 bytes
|
||||
u32 i_txtdt_mg_ssector; // 4 bytes
|
||||
u32 i_c_adt_ssector; // 4 bytes
|
||||
u32 i_vobu_admap_ssector; // 4 bytes
|
||||
// char[2] ???
|
||||
u16 i_video_atrt; // 2 bytes
|
||||
// char ???
|
||||
u8 i_audio_nb; // 1 byte
|
||||
u64 pi_audio_atrt[8]; // i_vmgm_audio_nb * 8 bytes
|
||||
// char[16] ???
|
||||
u8 i_subpic_nb; // 1 byte
|
||||
u64 pi_subpic_atrt[32]; // i_subpic_nb * 6 bytes
|
||||
} vmgi_mat_t;
|
||||
|
||||
|
||||
/*
|
||||
* Part Of Title Search Pointer Table Information
|
||||
*/
|
||||
|
||||
/* Title sets structure
|
||||
* we have a pointer to this structure for each tts */
|
||||
typedef struct tts_s
|
||||
{
|
||||
u8 i_play_type; // 1 byte
|
||||
u8 i_angle_nb; // 1 byte
|
||||
u16 i_ptt_nb; // 2 bytes; Chapters/PGs
|
||||
u16 i_parental_id; // 2 bytes
|
||||
u8 i_tts_nb; // 1 byte (VTS#)
|
||||
u8 i_vts_ttn; // 1 byte ???
|
||||
u32 i_ssector; // 4 bytes
|
||||
} tts_t;
|
||||
|
||||
/* Main struct for tts
|
||||
* - start at "i_vmg_ptt_srpt_ssector" */
|
||||
typedef struct vmg_ptt_srpt_s
|
||||
{
|
||||
u16 i_ttu_nb; // 2 bytes
|
||||
// char[2] ???
|
||||
u32 i_ebyte; // 4 bytes
|
||||
tts_t* p_tts; // i_ttu_nb * 12 bytes
|
||||
} vmg_ptt_srpt_t;
|
||||
|
||||
/*
|
||||
* Parental Management Information Table
|
||||
*/
|
||||
typedef struct vmg_ptl_mai_desc_s
|
||||
{
|
||||
u16 i_country_code; // 2 bytes
|
||||
// char[2] ???
|
||||
u16 i_ptl_mai_sbyte; // 2 bytes
|
||||
// char[2] ???
|
||||
} vmg_ptl_mai_desc_t;
|
||||
|
||||
typedef struct vmg_ptl_mask_s
|
||||
{
|
||||
u16* ppi_ptl_mask[8]; // (i_vts_nb +1) * 8 * 2 bytes
|
||||
} vmg_ptl_mask_t;
|
||||
|
||||
/* Main struct for parental management
|
||||
* - start at i_vmg_ptl_mait_ssector */
|
||||
typedef struct vmg_ptl_mait_s
|
||||
{
|
||||
u16 i_country_nb; // 2 bytes
|
||||
u16 i_vts_nb; // 2 bytes
|
||||
u32 i_ebyte; // 4 bytes
|
||||
vmg_ptl_mai_desc_t* p_ptl_desc; // i_country_nb * 8 bytes
|
||||
vmg_ptl_mask_t* p_ptl_mask; // i_country_nb * sizeof(vmg_ptl_mask_t)
|
||||
} vmg_ptl_mait_t;
|
||||
|
||||
/*
|
||||
* Video Title Set Attribute Table
|
||||
*/
|
||||
|
||||
/* Attribute structure : one for each vts
|
||||
* - start at pi_atrt_sbyte */
|
||||
typedef struct vts_atrt_s
|
||||
{
|
||||
u32 i_ebyte; // 4 bytes
|
||||
u32 i_cat_app_type; // 4 bytes
|
||||
u16 i_vtsm_video_atrt; // 2 bytes
|
||||
// char ???
|
||||
u8 i_vtsm_audio_nb; // 1 byte
|
||||
u64 pi_vtsm_audio_atrt[8]; // i_vtsm_audio_nb * 8 bytes
|
||||
// char ???
|
||||
u8 i_vtsm_subpic_nb; // 1 byte
|
||||
u64 pi_vtsm_subpic_atrt[32]; // i_vtsm_subpic_nb * 6 bytes
|
||||
u16 i_vtstt_video_atrt; // 2 bytes
|
||||
// char ???
|
||||
u8 i_vtstt_audio_nb; // 1 byte
|
||||
u64 pi_vtstt_audio_atrt[8]; // i_vtstt_audio_nb * 8 bytes
|
||||
// char ???
|
||||
u8 i_vtstt_subpic_nb; // 1 byte
|
||||
u64 pi_vtstt_subpic_atrt[32]; // i_vtstt_subpic_nb * 6 bytes
|
||||
} vts_atrt_t;
|
||||
|
||||
/* Main struct for vts attributes
|
||||
* - start at i_vmg_vts_atrt_ssector */
|
||||
typedef struct vmg_vts_atrt_s
|
||||
{
|
||||
u16 i_vts_nb; // 2 bytes
|
||||
// char[2] ???
|
||||
u32 i_ebyte; // 4 bytes
|
||||
u32* pi_vts_atrt_sbyte; // i_vts_nb * 4 bytes
|
||||
vts_atrt_t* p_vts_atrt;
|
||||
} vmg_vts_atrt_t;
|
||||
|
||||
/*
|
||||
* Global Structure for Video Manager
|
||||
*/
|
||||
typedef struct vmg_s
|
||||
{
|
||||
vmgi_mat_t mat;
|
||||
pgc_t pgc;
|
||||
vmg_ptt_srpt_t ptt_srpt;
|
||||
pgci_ut_t pgci_ut;
|
||||
vmg_ptl_mait_t ptl_mait;
|
||||
vmg_vts_atrt_t vts_atrt;
|
||||
c_adt_t c_adt;
|
||||
vobu_admap_t vobu_admap;
|
||||
} vmg_t;
|
||||
|
||||
/*****************************************************************************
|
||||
* Structures for Video Title Sets (cf vts_*.ifo)
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* Video Title Sets Information Management Table
|
||||
*/
|
||||
typedef struct vtsi_mat_s
|
||||
{
|
||||
char psz_id[13]; // 12 bytes (DVDVIDEO-VTS)
|
||||
u32 i_lsector; // 4 bytes
|
||||
// char[12] ???
|
||||
u32 i_i_lsector; // 4 bytes
|
||||
// char ???
|
||||
u8 i_spec_ver; // 1 byte
|
||||
u32 i_cat; // 4 bytes
|
||||
// char[90] ???
|
||||
u32 i_mat_ebyte; // 4 bytes
|
||||
// char[60] ???
|
||||
u32 i_m_vobs_ssector; // 4 bytes
|
||||
u32 i_tt_vobs_ssector; // 4 bytes
|
||||
u32 i_ptt_srpt_ssector; // 4 bytes
|
||||
u32 i_pgcit_ssector; // 4 bytes
|
||||
u32 i_m_pgci_ut_ssector; // 4 bytes
|
||||
u32 i_tmap_ti_ssector; // 4 bytes
|
||||
u32 i_m_c_adt_ssector; // 4 bytes
|
||||
u32 i_m_vobu_admap_ssector; // 4 bytes
|
||||
u32 i_c_adt_ssector; // 4 bytes
|
||||
u32 i_vobu_admap_ssector; // 4 bytes
|
||||
// char[24] ???
|
||||
u16 i_m_video_atrt; // 2 bytes
|
||||
// char ???
|
||||
u8 i_m_audio_nb; // 1 byte
|
||||
u64 pi_m_audio_atrt[8]; // i_vmgm_audio_nb * 8 bytes
|
||||
// char[16] ???
|
||||
u8 i_m_subpic_nb; // 1 byte
|
||||
u64 pi_m_subpic_atrt[32]; // i_subpic_nb * 6 bytes
|
||||
// !!! only 28 subpics ???
|
||||
// char[2] ???
|
||||
u16 i_video_atrt; // 2 bytes
|
||||
// char ???
|
||||
u8 i_audio_nb; // 1 byte
|
||||
u64 pi_audio_atrt[8]; // i_vmgm_audio_nb * 8 bytes
|
||||
// char[16] ???
|
||||
u8 i_subpic_nb; // 1 byte
|
||||
u64 pi_subpic_atrt[32]; // i_subpic_nb * 6 bytes
|
||||
} vtsi_mat_t;
|
||||
|
||||
/*
|
||||
* Part Of Title Search Pointer Table Information
|
||||
*/
|
||||
|
||||
/* Title sets structure
|
||||
* we have a pointer to this structure for each tts */
|
||||
typedef struct ttu_s
|
||||
{
|
||||
u16 i_pgc_nb; // 2 bytes; Chapters/PGs
|
||||
u16 i_prg_nb; // 2 bytes
|
||||
} ttu_t;
|
||||
|
||||
/* Main struct for tts
|
||||
* - start at "i_vts_ptt_srpt_ssector" */
|
||||
typedef struct vts_ptt_srpt_s
|
||||
{
|
||||
u16 i_ttu_nb; // 2 bytes
|
||||
// char[2] ???
|
||||
u32 i_ebyte; // 4 bytes
|
||||
u32* pi_ttu_sbyte;
|
||||
ttu_t* p_ttu; // i_ttu_nb * 4 bytes
|
||||
} vts_ptt_srpt_t;
|
||||
|
||||
/*
|
||||
* Time Map table information
|
||||
*/
|
||||
|
||||
/* Time Map structure */
|
||||
typedef struct tmap_s
|
||||
{
|
||||
u8 i_time_unit; // 1 byte
|
||||
// char ???
|
||||
u16 i_entry_nb; // 2 bytes
|
||||
u32* pi_sector; // i_entry_nb * 4 bytes
|
||||
} tmap_t;
|
||||
|
||||
/* Main structure for tmap_ti
|
||||
* - start at "i_tmap_ti_ssector" */
|
||||
typedef struct vts_tmap_ti_s
|
||||
{
|
||||
u16 i_nb; // 2 bytes
|
||||
// char[2] ???
|
||||
u32 i_ebyte; // 4 bytes
|
||||
u32* pi_sbyte; // i_tmap_nb * 4 bytes
|
||||
tmap_t* p_tmap;
|
||||
} vts_tmap_ti_t;
|
||||
|
||||
/*
|
||||
* Video Title Set
|
||||
*/
|
||||
typedef struct vts_s
|
||||
{
|
||||
u32 i_pos;
|
||||
vtsi_mat_t mat;
|
||||
/* Part Of Title Search Pointer Table Info */
|
||||
vts_ptt_srpt_t ptt_srpt;
|
||||
/* Video Title Set Menu PGCI Unit Table */
|
||||
pgci_ut_t pgci_ut;
|
||||
/* Video Title Set Program Chain Info Table */
|
||||
pgci_ut_t pgci_ti;
|
||||
/* Video Title Set Time Map Table */
|
||||
vts_tmap_ti_t tmap_ti;
|
||||
/* VTSM Cell Adress Table Information */
|
||||
c_adt_t m_c_adt;
|
||||
/* VTSM VOBU Adress Map Table */
|
||||
vobu_admap_t m_vobu_admap;
|
||||
/* VTS Cell Adress Table Information */
|
||||
c_adt_t c_adt;
|
||||
/* VTS VOBU Adress Map Table */
|
||||
vobu_admap_t vobu_admap;
|
||||
} vts_t;
|
||||
|
||||
/*
|
||||
* Global Ifo Structure
|
||||
*/
|
||||
typedef struct ifo_s
|
||||
{
|
||||
/* File descriptor for the device */
|
||||
int i_fd;
|
||||
/* Offset to video_ts.ifo on the device */
|
||||
u32 i_off;
|
||||
/* Position of stream pointer */
|
||||
u32 i_pos;
|
||||
/* Error Management */
|
||||
boolean_t b_error;
|
||||
/* Structure described in video_ts */
|
||||
vmg_t vmg;
|
||||
/* Table of vts ifos */
|
||||
vts_t * p_vts;
|
||||
} ifo_t;
|
||||
|
||||
/*****************************************************************************
|
||||
* Prototypes in ifo.c
|
||||
*****************************************************************************/
|
||||
ifo_t IfoInit( int );
|
||||
void IfoRead( ifo_t* );
|
@ -4,7 +4,7 @@
|
||||
* decoders.
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1998, 1999, 2000 VideoLAN
|
||||
* $Id: input.c,v 1.67 2001/01/07 04:31:18 henri Exp $
|
||||
* $Id: input.c,v 1.68 2001/01/14 07:08:00 stef Exp $
|
||||
*
|
||||
* Authors:
|
||||
*
|
||||
@ -62,6 +62,7 @@ static void ErrorThread ( input_thread_t *p_input );
|
||||
static void EndThread ( input_thread_t *p_input );
|
||||
static void NetworkOpen ( input_thread_t *p_input );
|
||||
static void FileOpen ( input_thread_t *p_input );
|
||||
static void DvdOpen ( input_thread_t *p_input );
|
||||
|
||||
/*****************************************************************************
|
||||
* input_CreateThread: creates a new input thread
|
||||
@ -223,6 +224,7 @@ static void RunThread( input_thread_t *p_input )
|
||||
* InitThread: init the input thread
|
||||
*****************************************************************************/
|
||||
input_capabilities_t * PSKludge( void );
|
||||
input_capabilities_t * DVDKludge( void );
|
||||
static void InitThread( input_thread_t * p_input )
|
||||
{
|
||||
/* Initialize default settings for spawned decoders */
|
||||
@ -243,6 +245,13 @@ static void InitThread( input_thread_t * p_input )
|
||||
{
|
||||
case INPUT_METHOD_FILE: /* file methods */
|
||||
FileOpen( p_input );
|
||||
/* Probe plugin (FIXME: load plugins before & write this) */
|
||||
p_input->p_plugin = PSKludge();
|
||||
break;
|
||||
case INPUT_METHOD_DVD: /* DVD method */
|
||||
DvdOpen( p_input );
|
||||
/* DVD plugin */
|
||||
p_input->p_plugin = DVDKludge();
|
||||
break;
|
||||
case INPUT_METHOD_VLAN_BCAST: /* vlan network method */
|
||||
/* if( !p_main->b_vlans )
|
||||
@ -269,8 +278,6 @@ static void InitThread( input_thread_t * p_input )
|
||||
|
||||
free( p_input->p_config );
|
||||
|
||||
/* Probe plugin (FIXME: load plugins before & write this) */
|
||||
p_input->p_plugin = PSKludge();
|
||||
p_input->p_plugin->pf_init( p_input );
|
||||
|
||||
*p_input->pi_status = THREAD_READY;
|
||||
@ -398,3 +405,27 @@ static void FileOpen( input_thread_t * p_input )
|
||||
|
||||
#undef p_config
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* DvdOpen : open the dvd device
|
||||
*****************************************************************************/
|
||||
static void DvdOpen( input_thread_t * p_input )
|
||||
{
|
||||
intf_Msg( "Opening DVD %s", p_input->p_config->p_source );
|
||||
if( (p_input->i_handle = open( p_input->p_config->p_source,
|
||||
O_RDONLY|O_LARGEFILE )) == (-1) )
|
||||
{
|
||||
intf_ErrMsg( "input error: cannot open device %s", strerror(errno) );
|
||||
p_input->b_error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
vlc_mutex_lock( &p_input->stream.stream_lock );
|
||||
|
||||
p_input->stream.b_pace_control = 1;
|
||||
p_input->stream.b_seekable = 1;
|
||||
p_input->stream.i_size = 0;
|
||||
p_input->stream.i_tell = 0;
|
||||
|
||||
vlc_mutex_unlock( &p_input->stream.stream_lock );
|
||||
}
|
||||
|
541
src/input/input_dvd.c
Normal file
541
src/input/input_dvd.c
Normal file
@ -0,0 +1,541 @@
|
||||
/*****************************************************************************
|
||||
* input_dvd.c: DVD reading
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1998-2001 VideoLAN
|
||||
*
|
||||
* Author: Stéphane Borel <stef@via.ecp.fr>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "common.h"
|
||||
#include "threads.h"
|
||||
#include "mtime.h"
|
||||
|
||||
#include "intf_msg.h"
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#include "stream_control.h"
|
||||
#include "input_ext-intf.h"
|
||||
#include "input_ext-dec.h"
|
||||
|
||||
#include "input.h"
|
||||
|
||||
#include "dvd_ifo.h"
|
||||
#include "input_dvd.h"
|
||||
#include "mpeg_system.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Local prototypes
|
||||
*****************************************************************************/
|
||||
static int DVDProbe ( struct input_thread_s * );
|
||||
static int DVDRead ( struct input_thread_s *,
|
||||
data_packet_t * p_packets[INPUT_READ_ONCE] );
|
||||
static void DVDInit ( struct input_thread_s * );
|
||||
static void DVDEnd ( struct input_thread_s * );
|
||||
static int DVDSeek ( struct input_thread_s *, off_t );
|
||||
static int DVDRewind ( struct input_thread_s * );
|
||||
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 * );
|
||||
|
||||
/*
|
||||
* Data reading functions
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* DVDProbe: check the stream
|
||||
*****************************************************************************/
|
||||
static int DVDProbe( input_thread_t * p_input )
|
||||
{
|
||||
/* verify that the first three bytes are 0x000001, or unscramble and
|
||||
* re-do. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* DVDInit: initializes DVD structures
|
||||
*****************************************************************************/
|
||||
static void DVDInit( input_thread_t * p_input )
|
||||
{
|
||||
thread_dvd_data_t * p_method;
|
||||
u32 i_start;// = 2048*90000;
|
||||
|
||||
if( (p_method = malloc( sizeof(thread_dvd_data_t) )) == NULL )
|
||||
{
|
||||
intf_ErrMsg( "Out of memory" );
|
||||
p_input->b_error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
p_input->p_plugin_data = (void *)p_method;
|
||||
|
||||
lseek( p_input->i_handle, 0, SEEK_SET );
|
||||
|
||||
vlc_mutex_lock( &p_input->stream.stream_lock );
|
||||
|
||||
p_method->ifo = IfoInit( p_input->i_handle );
|
||||
IfoRead( &(p_method->ifo) );
|
||||
|
||||
vlc_mutex_unlock( &p_input->stream.stream_lock );
|
||||
|
||||
i_start = p_method->ifo.p_vts[0].i_pos +
|
||||
p_method->ifo.p_vts[0].mat.i_tt_vobs_ssector *DVD_LB_SIZE;
|
||||
fprintf(stderr, "Begin at : %d\n", i_start );
|
||||
|
||||
lseek( p_input->i_handle, i_start, SEEK_SET );
|
||||
|
||||
input_InitStream( p_input, sizeof( stream_ps_data_t ) );
|
||||
input_AddProgram( p_input, 0, sizeof( stream_ps_data_t ) );
|
||||
|
||||
if( p_input->stream.b_seekable )
|
||||
{
|
||||
stream_ps_data_t * p_demux_data =
|
||||
(stream_ps_data_t *)p_input->stream.pp_programs[0]->p_demux_data;
|
||||
|
||||
/* Pre-parse the stream to gather stream_descriptor_t. */
|
||||
p_input->stream.pp_programs[0]->b_is_ok = 0;
|
||||
p_demux_data->i_PSM_version = EMPTY_PSM_VERSION;
|
||||
|
||||
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];
|
||||
|
||||
i_result = DVDRead( p_input, pp_packets );
|
||||
if( i_result == 1 )
|
||||
{
|
||||
/* EOF */
|
||||
vlc_mutex_lock( &p_input->stream.stream_lock );
|
||||
p_input->stream.pp_programs[0]->b_is_ok = 1;
|
||||
vlc_mutex_unlock( &p_input->stream.stream_lock );
|
||||
break;
|
||||
}
|
||||
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.i_tell > INPUT_PREPARSE_LENGTH )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
lseek( p_input->i_handle, i_start, SEEK_SET );
|
||||
vlc_mutex_lock( &p_input->stream.stream_lock );
|
||||
p_input->stream.i_tell = 0;
|
||||
if( p_demux_data->b_has_PSM )
|
||||
{
|
||||
/* (The PSM decoder will care about spawning the decoders) */
|
||||
p_input->stream.pp_programs[0]->b_is_ok = 1;
|
||||
}
|
||||
#ifdef AUTO_SPAWN
|
||||
else
|
||||
{
|
||||
/* (We have to do it ourselves) */
|
||||
int i_es;
|
||||
|
||||
/* FIXME: we should do multiple passes in case an audio type
|
||||
* is not present */
|
||||
for( i_es = 0;
|
||||
i_es < p_input->stream.pp_programs[0]->i_es_number;
|
||||
i_es++ )
|
||||
{
|
||||
#define p_es p_input->stream.pp_programs[0]->pp_es[i_es]
|
||||
switch( p_es->i_type )
|
||||
{
|
||||
case MPEG1_VIDEO_ES:
|
||||
case MPEG2_VIDEO_ES:
|
||||
input_SelectES( p_input, p_es );
|
||||
break;
|
||||
|
||||
case MPEG1_AUDIO_ES:
|
||||
case MPEG2_AUDIO_ES:
|
||||
if( main_GetIntVariable( INPUT_DVD_AUDIO_VAR, 0 )
|
||||
== REQUESTED_MPEG
|
||||
&& main_GetIntVariable( INPUT_DVD_CHANNEL_VAR, 0 )
|
||||
== (p_es->i_id & 0x1F) )
|
||||
{
|
||||
input_SelectES( p_input, p_es );
|
||||
}
|
||||
break;
|
||||
|
||||
case AC3_AUDIO_ES:
|
||||
if( main_GetIntVariable( INPUT_DVD_AUDIO_VAR, 0 )
|
||||
== REQUESTED_AC3
|
||||
&& main_GetIntVariable( INPUT_DVD_CHANNEL_VAR, 0 )
|
||||
== ((p_es->i_id & 0xF00) >> 8) )
|
||||
{
|
||||
input_SelectES( p_input, p_es );
|
||||
}
|
||||
break;
|
||||
|
||||
case DVD_SPU_ES:
|
||||
if( main_GetIntVariable( INPUT_DVD_SUBTITLE_VAR, -1 )
|
||||
== ((p_es->i_id & 0x1F00) >> 8) )
|
||||
{
|
||||
input_SelectES( p_input, p_es );
|
||||
}
|
||||
break;
|
||||
|
||||
case LPCM_AUDIO_ES:
|
||||
/* FIXME ! */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
#ifdef STATS
|
||||
input_DumpStream( p_input );
|
||||
#endif
|
||||
vlc_mutex_unlock( &p_input->stream.stream_lock );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The programs will be added when we read them. */
|
||||
vlc_mutex_lock( &p_input->stream.stream_lock );
|
||||
p_input->stream.pp_programs[0]->b_is_ok = 0;
|
||||
vlc_mutex_unlock( &p_input->stream.stream_lock );
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* DVDEnd: frees unused data
|
||||
*****************************************************************************/
|
||||
static void DVDEnd( input_thread_t * p_input )
|
||||
{
|
||||
free( p_input->stream.p_demux_data );
|
||||
free( p_input->p_plugin_data );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* SafeRead: reads a chunk of stream and correctly detects errors
|
||||
*****************************************************************************/
|
||||
static __inline__ int SafeRead( input_thread_t * p_input, byte_t * p_buffer,
|
||||
size_t i_len )
|
||||
{
|
||||
thread_dvd_data_t * p_method;
|
||||
int i_nb;
|
||||
|
||||
p_method = (thread_dvd_data_t *)p_input->p_plugin_data;
|
||||
i_nb = read( p_input->i_handle, p_buffer, i_len );
|
||||
switch( i_nb )
|
||||
{
|
||||
case 0:
|
||||
/* End of File */
|
||||
return( 1 );
|
||||
case -1:
|
||||
intf_ErrMsg( "Read failed (%s)", strerror(errno) );
|
||||
return( -1 );
|
||||
default:
|
||||
break;
|
||||
}
|
||||
vlc_mutex_lock( &p_input->stream.stream_lock );
|
||||
p_input->stream.i_tell += i_nb;
|
||||
vlc_mutex_unlock( &p_input->stream.stream_lock );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* DVDRead: reads data packets
|
||||
*****************************************************************************
|
||||
* Returns -1 in case of error, 0 if everything went well, and 1 in case of
|
||||
* EOF.
|
||||
*****************************************************************************/
|
||||
static int DVDRead( input_thread_t * p_input,
|
||||
data_packet_t * pp_packets[INPUT_READ_ONCE] )
|
||||
{
|
||||
byte_t p_header[6];
|
||||
data_packet_t * p_data;
|
||||
size_t i_packet_size;
|
||||
int i_packet, i_error;
|
||||
thread_dvd_data_t * p_method;
|
||||
|
||||
p_method = (thread_dvd_data_t *)p_input->p_plugin_data;
|
||||
|
||||
memset( pp_packets, 0, INPUT_READ_ONCE * sizeof(data_packet_t *) );
|
||||
for( i_packet = 0; i_packet < INPUT_READ_ONCE; i_packet++ )
|
||||
{
|
||||
/* Read what we believe to be a packet header. */
|
||||
if( (i_error = SafeRead( p_input, p_header, 6 )) )
|
||||
{
|
||||
return( i_error );
|
||||
}
|
||||
|
||||
if( (U32_AT(p_header) & 0xFFFFFF00) != 0x100L )
|
||||
{
|
||||
/* This is not the startcode of a packet. Read the stream
|
||||
* until we find one. */
|
||||
u32 i_startcode = U32_AT(p_header);
|
||||
int i_dummy,i_nb;
|
||||
|
||||
if( i_startcode )
|
||||
{
|
||||
/* 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( 1, "Garbage at input (%x)", i_startcode );
|
||||
}
|
||||
|
||||
while( (i_startcode & 0xFFFFFF00) != 0x100L )
|
||||
{
|
||||
i_startcode <<= 8;
|
||||
if( (i_nb = read( p_input->i_handle, &i_dummy, 1 )) != 0 )
|
||||
{
|
||||
i_startcode |= i_dummy;
|
||||
fprintf(stderr, "tut :%d %d\n", i_dummy, i_nb );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "poc\n" );
|
||||
return( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Packet found. */
|
||||
*(u32 *)p_header = U32_AT(&i_startcode);
|
||||
if( (i_error = SafeRead( p_input, p_header + 4, 2 )) )
|
||||
{
|
||||
return( i_error );
|
||||
}
|
||||
}
|
||||
|
||||
if( U32_AT(p_header) != 0x1BA )
|
||||
{
|
||||
/* That's the case for all packets, except pack header. */
|
||||
i_packet_size = U16_AT(&p_header[4]);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Pack header. */
|
||||
if( (p_header[4] & 0xC0) == 0x40 )
|
||||
{
|
||||
/* MPEG-2 */
|
||||
i_packet_size = 8;
|
||||
}
|
||||
else if( (p_header[4] & 0xF0) == 0x20 )
|
||||
{
|
||||
/* MPEG-1 */
|
||||
i_packet_size = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
intf_ErrMsg( "Unable to determine stream type" );
|
||||
return( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Fetch a packet of the appropriate size. */
|
||||
if( (p_data = NewPacket( p_input, i_packet_size + 6 )) == NULL )
|
||||
{
|
||||
intf_ErrMsg( "Out of memory" );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* Copy the header we already read. */
|
||||
memcpy( p_data->p_buffer, 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 )) )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
/* MPEG-2 stuffing bytes */
|
||||
byte_t p_garbage[8];
|
||||
if( (i_error = SafeRead( p_input, p_garbage,
|
||||
p_data->p_buffer[13] & 0x7)) )
|
||||
{
|
||||
return( i_error );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Give the packet to the other input stages. */
|
||||
pp_packets[i_packet] = p_data;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* DVDRewind : reads a stream backward
|
||||
*****************************************************************************/
|
||||
static int DVDRewind( input_thread_t * p_input )
|
||||
{
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* DVDSeek : Goes to a given position on the stream
|
||||
*****************************************************************************/
|
||||
static int DVDSeek( input_thread_t * p_input, off_t i_off )
|
||||
{
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Packet management utilities
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* NewPacket: allocates a data packet
|
||||
*****************************************************************************/
|
||||
static struct data_packet_s * NewPacket( void * p_garbage,
|
||||
size_t i_size )
|
||||
{
|
||||
data_packet_t * p_data;
|
||||
|
||||
/* Safety check */
|
||||
if( i_size > INPUT_MAX_PACKET_SIZE )
|
||||
{
|
||||
intf_ErrMsg( "Packet too big (%d)", i_size );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( (p_data = (data_packet_t *)malloc( sizeof(data_packet_t) )) == NULL )
|
||||
{
|
||||
intf_DbgMsg( "Out of memory" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( (p_data->p_buffer = (byte_t *)malloc( i_size )) == NULL )
|
||||
{
|
||||
intf_DbgMsg( "Out of memory" );
|
||||
free( p_data );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 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 + i_size;
|
||||
|
||||
return( p_data );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* NewPES: allocates a pes packet
|
||||
*****************************************************************************/
|
||||
static pes_packet_t * NewPES( void * p_garbage )
|
||||
{
|
||||
pes_packet_t * p_pes;
|
||||
|
||||
if( (p_pes = (pes_packet_t *)malloc( sizeof(pes_packet_t) )) == NULL )
|
||||
{
|
||||
intf_DbgMsg( "Out of memory" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p_pes->b_messed_up = 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_garbage,
|
||||
data_packet_t * p_data )
|
||||
{
|
||||
ASSERT(p_data);
|
||||
ASSERT(p_data->p_buffer);
|
||||
free( p_data->p_buffer );
|
||||
free( p_data );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* DeletePES: deletes a PES packet and associated data packets
|
||||
*****************************************************************************/
|
||||
static void DeletePES( void * p_garbage, pes_packet_t * p_pes )
|
||||
{
|
||||
data_packet_t * p_data;
|
||||
data_packet_t * p_next;
|
||||
|
||||
p_data = p_pes->p_first;
|
||||
|
||||
while( p_data != NULL )
|
||||
{
|
||||
p_next = p_data->p_next;
|
||||
free( p_data->p_buffer );
|
||||
free( p_data );
|
||||
p_data = p_next;
|
||||
}
|
||||
|
||||
free( p_pes );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* DVDKludge: fakes a DVD plugin (FIXME)
|
||||
*****************************************************************************/
|
||||
input_capabilities_t * DVDKludge( void )
|
||||
{
|
||||
input_capabilities_t * p_plugin;
|
||||
|
||||
p_plugin = (input_capabilities_t *)malloc( sizeof(input_capabilities_t) );
|
||||
p_plugin->pf_probe = DVDProbe;
|
||||
p_plugin->pf_init = DVDInit;
|
||||
p_plugin->pf_end = DVDEnd;
|
||||
p_plugin->pf_read = DVDRead;
|
||||
p_plugin->pf_demux = input_DemuxPS; /* FIXME: use i_p_config_t ! */
|
||||
p_plugin->pf_new_packet = NewPacket;
|
||||
p_plugin->pf_new_pes = NewPES;
|
||||
p_plugin->pf_delete_packet = DeletePacket;
|
||||
p_plugin->pf_delete_pes = DeletePES;
|
||||
p_plugin->pf_rewind = DVDRewind;
|
||||
p_plugin->pf_seek = DVDSeek;
|
||||
|
||||
return( p_plugin );
|
||||
}
|
30
src/input/input_dvd.h
Normal file
30
src/input/input_dvd.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*****************************************************************************
|
||||
* input_dvd.h: thread structure of the DVD plugin
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999-2001 VideoLAN
|
||||
*
|
||||
* Author: Stéphane Borel <stef@via.ecp.fr>
|
||||
*
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* thread_dvd_data_t: extension of input_thread_t for DVD specificity
|
||||
*****************************************************************************/
|
||||
typedef struct thread_dvd_data_s
|
||||
{
|
||||
/* Structure that contains all information of the DVD */
|
||||
struct ifo_s ifo;
|
||||
} thread_dvd_data_t;
|
@ -202,6 +202,23 @@ void intf_Run( intf_thread_t *p_intf )
|
||||
p_intf->p_input = input_CreateThread( p_input_config, NULL );
|
||||
}
|
||||
}
|
||||
/* DVD mode */
|
||||
else if( p_main->b_dvd )
|
||||
{
|
||||
if( (p_input_config =
|
||||
(input_config_t *)malloc( sizeof(input_config_t) )) == NULL )
|
||||
{
|
||||
intf_ErrMsg( "intf error: cannot create input_config_t" );
|
||||
}
|
||||
else
|
||||
{
|
||||
p_input_config->i_method = INPUT_METHOD_DVD;
|
||||
p_input_config->p_source = main_GetPszVariable( INPUT_DVD_DEVICE_VAR, INPUT_DVD_DEVICE_DEFAULT );
|
||||
p_input_config->p_default_aout = p_main->p_aout;
|
||||
p_input_config->p_default_vout = p_intf->p_vout;
|
||||
p_intf->p_input = input_CreateThread( p_input_config, NULL );
|
||||
}
|
||||
}
|
||||
/* Or if a file was specified */
|
||||
else if( p_main->p_playlist->p_list != NULL )
|
||||
{
|
||||
@ -452,15 +469,15 @@ int intf_ProcessKey( intf_thread_t *p_intf, int g_key )
|
||||
* its own error messages */
|
||||
intf_SelectChannel( p_intf, k_reply.param );
|
||||
break;
|
||||
case INTF_KEY_INC_VOLUME: /* volume + */
|
||||
case INTF_KEY_INC_VOLUME: /* volume + */
|
||||
if( (p_main->p_aout != NULL) && (p_main->p_aout->vol < VOLUME_MAX) )
|
||||
p_main->p_aout->vol += VOLUME_STEP;
|
||||
break;
|
||||
case INTF_KEY_DEC_VOLUME: /* volume - */
|
||||
case INTF_KEY_DEC_VOLUME: /* volume - */
|
||||
if( (p_main->p_aout != NULL) && (p_main->p_aout->vol > VOLUME_STEP) )
|
||||
p_main->p_aout->vol -= VOLUME_STEP;
|
||||
break;
|
||||
case INTF_KEY_TOGGLE_VOLUME: /* toggle mute */
|
||||
case INTF_KEY_TOGGLE_VOLUME: /* toggle mute */
|
||||
if( (p_main->p_aout != NULL) && (p_main->p_aout->vol))
|
||||
{
|
||||
i_volbackup = p_main->p_aout->vol;
|
||||
@ -469,7 +486,7 @@ int intf_ProcessKey( intf_thread_t *p_intf, int g_key )
|
||||
else if( (p_main->p_aout != NULL) && (!p_main->p_aout->vol))
|
||||
p_main->p_aout->vol = i_volbackup;
|
||||
break;
|
||||
case INTF_KEY_DEC_GAMMA: /* gamma - */
|
||||
case INTF_KEY_DEC_GAMMA: /* gamma - */
|
||||
if( (p_intf->p_vout != NULL) && (p_intf->p_vout->f_gamma > -INTF_GAMMA_LIMIT) )
|
||||
{
|
||||
vlc_mutex_lock( &p_intf->p_vout->change_lock );
|
||||
@ -478,7 +495,7 @@ int intf_ProcessKey( intf_thread_t *p_intf, int g_key )
|
||||
vlc_mutex_unlock( &p_intf->p_vout->change_lock );
|
||||
}
|
||||
break;
|
||||
case INTF_KEY_INC_GAMMA: /* gamma + */
|
||||
case INTF_KEY_INC_GAMMA: /* gamma + */
|
||||
if( (p_intf->p_vout != NULL) && (p_intf->p_vout->f_gamma < INTF_GAMMA_LIMIT) )
|
||||
{
|
||||
vlc_mutex_lock( &p_intf->p_vout->change_lock );
|
||||
@ -487,7 +504,7 @@ int intf_ProcessKey( intf_thread_t *p_intf, int g_key )
|
||||
vlc_mutex_unlock( &p_intf->p_vout->change_lock );
|
||||
}
|
||||
break;
|
||||
case INTF_KEY_TOGGLE_GRAYSCALE: /* toggle grayscale */
|
||||
case INTF_KEY_TOGGLE_GRAYSCALE: /* toggle grayscale */
|
||||
if( p_intf->p_vout != NULL )
|
||||
{
|
||||
vlc_mutex_lock( &p_intf->p_vout->change_lock );
|
||||
@ -496,7 +513,7 @@ int intf_ProcessKey( intf_thread_t *p_intf, int g_key )
|
||||
vlc_mutex_unlock( &p_intf->p_vout->change_lock );
|
||||
}
|
||||
break;
|
||||
case INTF_KEY_TOGGLE_INTERFACE: /* toggle interface */
|
||||
case INTF_KEY_TOGGLE_INTERFACE: /* toggle interface */
|
||||
if( p_intf->p_vout != NULL )
|
||||
{
|
||||
vlc_mutex_lock( &p_intf->p_vout->change_lock );
|
||||
@ -505,7 +522,7 @@ int intf_ProcessKey( intf_thread_t *p_intf, int g_key )
|
||||
vlc_mutex_unlock( &p_intf->p_vout->change_lock );
|
||||
}
|
||||
break;
|
||||
case INTF_KEY_TOGGLE_INFO: /* toggle info */
|
||||
case INTF_KEY_TOGGLE_INFO: /* toggle info */
|
||||
if( p_intf->p_vout != NULL )
|
||||
{
|
||||
vlc_mutex_lock( &p_intf->p_vout->change_lock );
|
||||
@ -514,7 +531,7 @@ int intf_ProcessKey( intf_thread_t *p_intf, int g_key )
|
||||
vlc_mutex_unlock( &p_intf->p_vout->change_lock );
|
||||
}
|
||||
break;
|
||||
case INTF_KEY_TOGGLE_SCALING: /* toggle scaling */
|
||||
case INTF_KEY_TOGGLE_SCALING: /* toggle scaling */
|
||||
if( p_intf->p_vout != NULL )
|
||||
{
|
||||
vlc_mutex_lock( &p_intf->p_vout->change_lock );
|
||||
|
@ -85,6 +85,7 @@
|
||||
#define OPT_SERVER 171
|
||||
#define OPT_PORT 172
|
||||
#define OPT_BROADCAST 173
|
||||
#define OPT_DVD 174
|
||||
|
||||
#define OPT_SYNCHRO 180
|
||||
|
||||
@ -132,6 +133,7 @@ static const struct option longopts[] =
|
||||
{ "server", 1, 0, OPT_SERVER },
|
||||
{ "port", 1, 0, OPT_PORT },
|
||||
{ "broadcast", 0, 0, OPT_BROADCAST },
|
||||
{ "dvd", 0, 0, OPT_DVD },
|
||||
|
||||
/* Synchro options */
|
||||
{ "synchro", 1, 0, OPT_SYNCHRO },
|
||||
@ -458,6 +460,7 @@ static void SetDefaultConfiguration( void )
|
||||
p_main->b_audio = 1;
|
||||
p_main->b_video = 1;
|
||||
p_main->b_vlans = 0;
|
||||
p_main->b_dvd = 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
@ -589,6 +592,9 @@ static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
|
||||
case OPT_BROADCAST: /* --broadcast */
|
||||
main_PutIntVariable( INPUT_BROADCAST_VAR, 1 );
|
||||
break;
|
||||
case OPT_DVD: /* --dvd */
|
||||
p_main->b_dvd = 1;
|
||||
break;
|
||||
|
||||
/* Synchro options */
|
||||
case OPT_SYNCHRO:
|
||||
@ -658,6 +664,7 @@ static void Usage( int i_fashion )
|
||||
"\n --server <host> \tvideo server address"
|
||||
"\n --port <port> \tvideo server port"
|
||||
"\n --broadcast \tlisten to a broadcast"
|
||||
"\n --dvd \tread dvd"
|
||||
"\n"
|
||||
"\n --synchro <type> \tforce synchro algorithm"
|
||||
"\n"
|
||||
@ -705,7 +712,9 @@ static void Usage( int i_fashion )
|
||||
"\n " INPUT_IFACE_VAR "=<interface> \tnetwork interface"
|
||||
"\n " INPUT_BROADCAST_VAR "={1|0} \tbroadcast mode"
|
||||
"\n " INPUT_VLAN_SERVER_VAR "=<hostname> \tvlan server"
|
||||
"\n " INPUT_VLAN_PORT_VAR "=<port> \tvlan server port" );
|
||||
"\n " INPUT_VLAN_PORT_VAR "=<port> \tvlan server port"
|
||||
"\n " INPUT_DVD_DEVICE_VAR "=<device> \tDVD device"
|
||||
);
|
||||
|
||||
/* Synchro parameters */
|
||||
intf_Msg( "\nSynchro parameters:"
|
||||
|
Loading…
Reference in New Issue
Block a user