⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dvdread.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************** * dvdread.c : DvdRead input module for vlc ***************************************************************************** * Copyright (C) 2001-2004 VideoLAN * $Id: dvdread.c 11429 2005-06-15 09:26:07Z xtophe $ * * Authors: St閜hane Borel <stef@via.ecp.fr> *          Gildas Bazin <gbazin@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 <stdio.h>#include <stdlib.h>                                      /* malloc(), free() */#include <string.h>                                              /* strdup() */#include <vlc/vlc.h>#include <vlc/input.h>#include "iso_lang.h"#include "../demux/ps.h"#ifdef HAVE_UNISTD_H#   include <unistd.h>#endif#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include <string.h>#include <dvdread/dvd_reader.h>#include <dvdread/ifo_types.h>#include <dvdread/ifo_read.h>#include <dvdread/nav_read.h>#include <dvdread/nav_print.h>/***************************************************************************** * Module descriptor *****************************************************************************/#define ANGLE_TEXT N_("DVD angle")#define ANGLE_LONGTEXT N_( \    "Allows you to select the default DVD angle." )#define CACHING_TEXT N_("Caching value in ms")#define CACHING_LONGTEXT N_( \    "Allows you to modify the default caching value for DVDread streams. " \    "This value should be set in millisecond units." )#define CSSMETHOD_TEXT N_("Method used by libdvdcss for decryption")#define CSSMETHOD_LONGTEXT N_( \    "Set the method used by libdvdcss for key decryption.\n" \    "title: decrypted title key is guessed from the encrypted sectors of " \           "the stream. Thus it should work with a file as well as the " \           "DVD device. But it sometimes takes much time to decrypt a title " \           "key and may even fail. With this method, the key is only checked "\           "at the beginning of each title, so it won't work if the key " \           "changes in the middle of a title.\n" \    "disc: the disc key is first cracked, then all title keys can be " \           "decrypted instantly, which allows us to check them often.\n" \    "key: the same as \"disc\" if you don't have a file with player keys " \           "at compilation time. If you do, the decryption of the disc key " \           "will be faster with this method. It is the one that was used by " \           "libcss.\n" \    "The default method is: key.")static char *psz_css_list[] = { "title", "disc", "key" };static char *psz_css_list_text[] = { N_("title"), N_("Disc"), N_("Key") };static int  Open ( vlc_object_t * );static void Close( vlc_object_t * );vlc_module_begin();    set_shortname( _("DVD without menus") );    set_description( _("DVDRead Input (DVD without menu support)") );    set_category( CAT_INPUT );    set_subcategory( SUBCAT_INPUT_ACCESS );    add_integer( "dvdread-angle", 1, NULL, ANGLE_TEXT,        ANGLE_LONGTEXT, VLC_FALSE );    add_integer( "dvdread-caching", DEFAULT_PTS_DELAY / 1000, NULL,        CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE );    add_string( "dvdread-css-method", NULL, NULL, CSSMETHOD_TEXT,                CSSMETHOD_LONGTEXT, VLC_TRUE );        change_string_list( psz_css_list, psz_css_list_text, 0 );    set_capability( "access_demux", 0 );    add_shortcut( "dvd" );    add_shortcut( "dvdread" );    add_shortcut( "dvdsimple" );    set_callbacks( Open, Close );vlc_module_end();/* how many blocks DVDRead will read in each loop */#define DVD_BLOCK_READ_ONCE 4/***************************************************************************** * Local prototypes *****************************************************************************/struct demux_sys_t{    /* DVDRead state */    dvd_reader_t *p_dvdread;    dvd_file_t   *p_title;    ifo_handle_t *p_vmg_file;    ifo_handle_t *p_vts_file;    int i_title;    int i_chapter, i_chapters;    int i_angle, i_angles;    tt_srpt_t    *p_tt_srpt;    pgc_t        *p_cur_pgc;    dsi_t        dsi_pack;    int          i_ttn;    int i_pack_len;    int i_cur_block;    int i_next_vobu;    /* Current title start/end blocks */    int i_title_start_block;    int i_title_end_block;    int i_title_blocks;    int i_title_offset;    mtime_t i_title_cur_time;    int i_title_start_cell;    int i_title_end_cell;    int i_cur_cell;    int i_next_cell;    mtime_t i_cell_cur_time;    mtime_t i_cell_duration;    /* Track */    ps_track_t    tk[PS_TK_COUNT];    int           i_titles;    input_title_t **titles;    /* Video */    int i_aspect;    /* SPU */    uint32_t clut[16];};static int Control   ( demux_t *, int, va_list );static int Demux     ( demux_t * );static int DemuxBlock( demux_t *, uint8_t *, int );static void DemuxTitles( demux_t *, int * );static void ESNew( demux_t *, int, int );static int  DvdReadSetArea  ( demux_t *, int, int, int );static void DvdReadSeek     ( demux_t *, int );static void DvdReadHandleDSI( demux_t *, uint8_t * );static void DvdReadFindCell ( demux_t * );/***************************************************************************** * Open: *****************************************************************************/static int Open( vlc_object_t *p_this ){    demux_t      *p_demux = (demux_t*)p_this;    demux_sys_t  *p_sys;    char         *psz_name;    char         *psz_dvdcss_env;    dvd_reader_t *p_dvdread;    ifo_handle_t *p_vmg_file;    vlc_value_t  val;    if( !p_demux->psz_path || !*p_demux->psz_path )    {        /* Only when selected */        if( !p_this->b_force ) return VLC_EGENERIC;        psz_name = var_CreateGetString( p_this, "dvd" );        if( !psz_name || !*psz_name )        {            if( psz_name ) free( psz_name );            return VLC_EGENERIC;        }    }    else psz_name = strdup( p_demux->psz_path );#ifdef WIN32    if( psz_name[0] && psz_name[1] == ':' &&        psz_name[2] == '\\' && psz_name[3] == '\0' ) psz_name[2] = '\0';#endif    /* Override environment variable DVDCSS_METHOD with config option     * (FIXME: this creates a small memory leak) */    psz_dvdcss_env = config_GetPsz( p_demux, "dvdread-css-method" );    if( psz_dvdcss_env && *psz_dvdcss_env )    {        char *psz_env;        psz_env = malloc( strlen("DVDCSS_METHOD=") +                          strlen( psz_dvdcss_env ) + 1 );        if( !psz_env )        {            free( psz_dvdcss_env );            return VLC_ENOMEM;        }        sprintf( psz_env, "%s%s", "DVDCSS_METHOD=", psz_dvdcss_env );        putenv( psz_env );    }    if( psz_dvdcss_env ) free( psz_dvdcss_env );    /* Open dvdread */    if( !(p_dvdread = DVDOpen( psz_name )) )    {        msg_Err( p_demux, "DVDRead cannot open source: %s", psz_name );        free( psz_name );        return VLC_EGENERIC;    }    free( psz_name );    /* Ifo allocation & initialisation */    if( !( p_vmg_file = ifoOpen( p_dvdread, 0 ) ) )    {        msg_Warn( p_demux, "cannot open VMG info" );        return VLC_EGENERIC;    }    msg_Dbg( p_demux, "VMG opened" );    /* Fill p_demux field */    p_demux->pf_demux = Demux;    p_demux->pf_control = Control;    p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );    memset( p_sys, 0, sizeof( demux_sys_t ) );    ps_track_init( p_sys->tk );    p_sys->i_aspect = -1;    p_sys->i_title_cur_time = (mtime_t) 0;    p_sys->i_cell_cur_time = (mtime_t) 0;    p_sys->i_cell_duration = (mtime_t) 0;    p_sys->p_dvdread = p_dvdread;    p_sys->p_vmg_file = p_vmg_file;    p_sys->p_title = NULL;    p_sys->p_vts_file = NULL;    p_sys->i_title = p_sys->i_chapter = -1;    var_Create( p_demux, "dvdread-angle", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );    var_Get( p_demux, "dvdread-angle", &val );    p_sys->i_angle = val.i_int > 0 ? val.i_int : 1;    DemuxTitles( p_demux, &p_sys->i_angle );    if( DvdReadSetArea( p_demux, 0, 0, p_sys->i_angle ) != VLC_SUCCESS )    {        Close( p_this );        msg_Err( p_demux, "DvdReadSetArea(0,0,%i) failed (can't decrypt DVD?)",                 p_sys->i_angle );        return VLC_EGENERIC;    }    /* Update default_pts to a suitable value for dvdread access */    var_Create( p_demux, "dvdread-caching",                VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );    return VLC_SUCCESS;}/***************************************************************************** * Close: *****************************************************************************/static void Close( vlc_object_t *p_this ){    demux_t     *p_demux = (demux_t*)p_this;    demux_sys_t *p_sys = p_demux->p_sys;    int i;    for( i = 0; i < PS_TK_COUNT; i++ )    {        ps_track_t *tk = &p_sys->tk[i];        if( tk->b_seen )        {            es_format_Clean( &tk->fmt );            if( tk->es ) es_out_Del( p_demux->out, tk->es );        }    }    /* Close libdvdread */    if( p_sys->p_title ) DVDCloseFile( p_sys->p_title );    if( p_sys->p_vts_file ) ifoClose( p_sys->p_vts_file );    if( p_sys->p_vmg_file ) ifoClose( p_sys->p_vmg_file );    DVDClose( p_sys->p_dvdread );    free( p_sys );}static int64_t dvdtime_to_time( dvd_time_t *dtime, uint8_t still_time ){/* Macro to convert Binary Coded Decimal to Decimal */#define BCD2D(__x__) (((__x__ & 0xf0) >> 4) * 10 + (__x__ & 0x0f))    double f_fps, f_ms;    int64_t i_micro_second = 0;    if (still_time == 0 || still_time == 0xFF)    {        i_micro_second += (int64_t)(BCD2D(dtime->hour)) * 60 * 60 * 1000000;        i_micro_second += (int64_t)(BCD2D(dtime->minute)) * 60 * 1000000;        i_micro_second += (int64_t)(BCD2D(dtime->second)) * 1000000;        switch((dtime->frame_u & 0xc0) >> 6)         {        case 1:            f_fps = 25.0;            break;        case 3:            f_fps = 29.97;            break;        default:            f_fps = 2500.0;            break;        }        f_ms = BCD2D(dtime->frame_u&0x3f) * 1000.0 / f_fps;        i_micro_second += (int64_t)(f_ms * 1000.0);    }    else    {        i_micro_second = still_time;        i_micro_second = (int64_t)((double)i_micro_second * 1000000.0);    }        return i_micro_second;}/***************************************************************************** * Control: *****************************************************************************/static int Control( demux_t *p_demux, int i_query, va_list args ){    demux_sys_t *p_sys = p_demux->p_sys;    double f, *pf;    vlc_bool_t *pb;    int64_t *pi64;    input_title_t ***ppp_title;    int *pi_int;    int i;    switch( i_query )    {        case DEMUX_GET_POSITION:        {            pf = (double*) va_arg( args, double* );            if( p_sys->i_title_blocks > 0 )                *pf = (double)p_sys->i_title_offset / p_sys->i_title_blocks;            else                *pf = 0.0;            return VLC_SUCCESS;        }        case DEMUX_SET_POSITION:        {            f = (double)va_arg( args, double );            DvdReadSeek( p_demux, f * p_sys->i_title_blocks );            return VLC_SUCCESS;        }        case DEMUX_GET_TIME:            pi64 = (int64_t*)va_arg( args, int64_t * );            if( p_sys->i_title_cur_time > 0 )            {                *pi64 = (int64_t)p_sys->i_title_cur_time;                return VLC_SUCCESS;            }            *pi64 = 0;            return VLC_EGENERIC;        case DEMUX_GET_LENGTH:            pi64 = (int64_t*)va_arg( args, int64_t * );            if (p_demux->info.i_title >= 0 && p_demux->info.i_title < p_sys->i_titles)            {                *pi64 = dvdtime_to_time( &p_sys->p_cur_pgc->playback_time, 0 );                return VLC_SUCCESS;            }            *pi64 = 0;            return VLC_EGENERIC;        /* Special for access_demux */        case DEMUX_CAN_PAUSE:        case DEMUX_CAN_CONTROL_PACE:            /* TODO */            pb = (vlc_bool_t*)va_arg( args, vlc_bool_t * );            *pb = VLC_TRUE;            return VLC_SUCCESS;        case DEMUX_SET_PAUSE_STATE:            return VLC_SUCCESS;        case DEMUX_GET_TITLE_INFO:            ppp_title = (input_title_t***)va_arg( args, input_title_t*** );            pi_int    = (int*)va_arg( args, int* );            *((int*)va_arg( args, int* )) = 1; /* Title offset */            *((int*)va_arg( args, int* )) = 1; /* Chapter offset */            /* Duplicate title infos */            *pi_int = p_sys->i_titles;            *ppp_title = malloc( sizeof(input_title_t **) * p_sys->i_titles );            for( i = 0; i < p_sys->i_titles; i++ )            {                (*ppp_title)[i] = vlc_input_title_Duplicate(p_sys->titles[i]);            }            return VLC_SUCCESS;        case DEMUX_SET_TITLE:            i = (int)va_arg( args, int );            if( DvdReadSetArea( p_demux, i, 0, -1 ) != VLC_SUCCESS )            {                msg_Warn( p_demux, "cannot set title/chapter" );                return VLC_EGENERIC;            }            p_demux->info.i_update |=                INPUT_UPDATE_TITLE | INPUT_UPDATE_SEEKPOINT;            p_demux->info.i_title = i;            p_demux->info.i_seekpoint = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -