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

📄 input.c

📁 VLC媒体播放程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************** * input.c: DvdRead plugin. ***************************************************************************** * This plugins should handle all the known specificities of the DVD format, * especially the 2048 bytes logical block size. * It depends on: libdvdread for ifo files and block reading. ***************************************************************************** * Copyright (C) 2001, 2003 VideoLAN * $Id: input.c,v 1.23 2003/09/07 22:49:05 fenrir Exp $ * * Author: St閜hane Borel <stef@via.ecp.fr> * * Some code taken form the play_title.c by Billy Biggs <vektor@dumbterm.net> * in libdvdread. * * 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>#include <vlc/vlc.h>#include <vlc/input.h>#include "../../demux/mpeg/system.h"#ifdef HAVE_UNISTD_H#   include <unistd.h>#endif#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include <string.h>#include <errno.h>#include <assert.h>#ifdef STRNCASECMP_IN_STRINGS_H#   include <strings.h>#endif#if defined( WIN32 )#   include <io.h>                                                 /* read() */#endif#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>#include "input.h"#include "iso_lang.h"/* how many blocks DVDRead will read in each loop */#define DVD_BLOCK_READ_ONCE 64/***************************************************************************** * Private structure *****************************************************************************/struct demux_sys_t{    module_t *   p_module;    mpeg_demux_t mpeg;};/***************************************************************************** * Local prototypes *****************************************************************************//* called from outside */static int     DvdReadDemux    ( input_thread_t * );static int     DvdReadRewind   ( input_thread_t * );static int     DvdReadSetArea    ( input_thread_t *, input_area_t * );static int     DvdReadSetProgram ( input_thread_t *, pgrm_descriptor_t * );static ssize_t DvdReadRead       ( input_thread_t *, byte_t *, size_t );static void    DvdReadSeek       ( input_thread_t *, off_t );/* called only from here */static void    DvdReadLauchDecoders( input_thread_t * p_input );static void    DvdReadHandleDSI( thread_dvd_data_t * p_dvd, uint8_t * p_data );static void    DvdReadFindCell ( thread_dvd_data_t * p_dvd );/* * Data demux functions *//***************************************************************************** * InitDVD: initialize DVD structures *****************************************************************************/int E_(InitDVD) ( vlc_object_t *p_this ){    input_thread_t *p_input = (input_thread_t *)p_this;    demux_sys_t *   p_demux;    if( p_input->stream.i_method != INPUT_METHOD_DVD )    {        return VLC_EGENERIC;    }    p_demux = p_input->p_demux_data = malloc( sizeof(demux_sys_t ) );    if( p_demux == NULL )    {        return VLC_ENOMEM;    }    p_input->p_private = (void*)&p_demux->mpeg;    p_demux->p_module = module_Need( p_input, "mpeg-system", NULL );    if( p_demux->p_module == NULL )    {        free( p_input->p_demux_data );        return VLC_ENOMOD;    }    p_input->pf_demux = DvdReadDemux;    p_input->pf_demux_control = demux_vaControlDefault;    p_input->pf_rewind = NULL;    vlc_mutex_lock( &p_input->stream.stream_lock );    DvdReadLauchDecoders( p_input );    vlc_mutex_unlock( &p_input->stream.stream_lock );    return VLC_SUCCESS;}/***************************************************************************** * EndDVD: end DVD structures *****************************************************************************/void E_(EndDVD) ( vlc_object_t *p_this ){    input_thread_t *p_input = (input_thread_t *)p_this;    module_Unneed( p_input, p_input->p_demux_data->p_module );    free( p_input->p_demux_data );}/***************************************************************************** * DvdReadDemux *****************************************************************************/#define PEEK( SIZE )                                                        \    i_result = input_Peek( p_input, &p_peek, SIZE );                        \    if( i_result == -1 )                                                    \    {                                                                       \        return -1;                                                          \    }                                                                       \    else if( i_result < SIZE )                                              \    {                                                                       \        /* EOF */                                                           \        return 0;                                                           \    }static int DvdReadDemux( input_thread_t * p_input ){    int                 i;    byte_t *            p_peek;    data_packet_t *     p_data;    ssize_t             i_result;    int                 i_packet_size;    /* Read headers to compute payload length */    for( i = 0 ; i < DVD_BLOCK_READ_ONCE ; i++ )    {        /* Read what we believe to be a packet header. */        PEEK( 4 );        /* Default header */        if( U32_AT( p_peek ) != 0x1BA )        {            /* That's the case for all packets, except pack header. */            i_packet_size = U16_AT( p_peek + 4 );        }        else        {            /* MPEG-2 Pack header. */            i_packet_size = 8;        }        /* Fetch a packet of the appropriate size. */        i_result = input_SplitBuffer( p_input, &p_data, i_packet_size + 6 );        if( i_result <= 0 )        {            return( i_result );        }        /* In MPEG-2 pack headers we still have to read stuffing bytes. */        if( (p_data->p_demux_start[3] == 0xBA) && (i_packet_size == 8) )        {            ssize_t i_stuffing = (p_data->p_demux_start[13] & 0x7);            /* Force refill of the input buffer - though we don't care             * about p_peek. Please note that this is unoptimized. */            PEEK( i_stuffing );            p_input->p_current_data += i_stuffing;        }        p_input->p_demux_data->mpeg.pf_demux_ps( p_input, p_data );    }    return i;}/***************************************************************************** * DVDRewind : reads a stream backward *****************************************************************************/static int DvdReadRewind( input_thread_t * p_input ){    return -1;}/* * Data access functions *//***************************************************************************** * OpenDVD: open libdvdread *****************************************************************************/int E_(OpenDVD) ( vlc_object_t *p_this ){    input_thread_t *        p_input = (input_thread_t *)p_this;    char *                  psz_parser;    char *                  psz_source;    char *                  psz_next;    struct stat             stat_info;    thread_dvd_data_t *     p_dvd;    dvd_reader_t *          p_dvdread;    input_area_t *          p_area;    unsigned int            i_title = 1;    unsigned int            i_chapter = 1;    unsigned int            i_angle = 1;    unsigned int            i;    psz_source = strdup( p_input->psz_name );    if( psz_source == NULL )    {        return VLC_ENOMEM;    }    p_input->pf_read = DvdReadRead;    p_input->pf_seek = DvdReadSeek;    p_input->pf_set_area = DvdReadSetArea;    p_input->pf_set_program = DvdReadSetProgram;    /* Start with the end, because you could have :     * dvdread:/Volumes/my@toto/VIDEO_TS@1,1     * (yes, this is kludgy). */    for ( psz_parser = psz_source + strlen(psz_source) - 1;          psz_parser >= psz_source && *psz_parser != '@';          psz_parser-- );    if( psz_parser >= psz_source && *psz_parser == '@' )    {        /* Found options */        *psz_parser = '\0';        ++psz_parser;        i_title = (int)strtol( psz_parser, &psz_next, 10 );        if( *psz_next )        {            psz_parser = psz_next + 1;            i_chapter = (int)strtol( psz_parser, &psz_next, 10 );            if( *psz_next )            {                i_angle = (int)strtol( psz_next + 1, NULL, 10 );            }        }        i_title = i_title ? i_title : 1;        i_chapter = i_chapter ? i_chapter : 1;        i_angle = i_angle ? i_angle : 1;    }    if( !*psz_source )    {        free( psz_source );        if( !p_input->psz_access )        {            return VLC_EGENERIC;        }        psz_source = config_GetPsz( p_input, "dvd" );        if( !psz_source ) return VLC_EGENERIC;    }    if( stat( psz_source, &stat_info ) == -1 )    {        msg_Warn( p_input, "cannot stat() source `%s' (%s)",                           psz_source, strerror(errno) );        free( psz_source );        return VLC_EGENERIC;    }    if( !S_ISBLK(stat_info.st_mode) &&        !S_ISCHR(stat_info.st_mode) &&        !S_ISDIR(stat_info.st_mode) )    {        msg_Warn( p_input, "dvdread module discarded (not a valid source)" );        free( psz_source );        return VLC_EGENERIC;    }    msg_Dbg( p_input, "dvdroot=%s title=%d chapter=%d angle=%d",                      psz_source, i_title, i_chapter, i_angle );    p_dvdread = DVDOpen( psz_source );    /* free allocated strings */    free( psz_source );    if( ! p_dvdread )    {        msg_Err( p_input, "libdvdcss cannot open source" );        return VLC_EGENERIC;    }    /* set up input  */    p_input->i_mtu = 0;    p_dvd = malloc( sizeof(thread_dvd_data_t) );    if( p_dvd == NULL )    {        msg_Err( p_input, "out of memory" );        return VLC_ENOMEM;    }    p_dvd->p_dvdread = p_dvdread;    p_dvd->p_title = NULL;    p_dvd->p_vts_file = NULL;    p_input->p_access_data = (void *)p_dvd;    /* Ifo allocation & initialisation */    if( ! ( p_dvd->p_vmg_file = ifoOpen( p_dvd->p_dvdread, 0 ) ) )    {        msg_Warn( p_input, "cannot open VMG info" );        free( p_dvd );        return VLC_EGENERIC;    }    msg_Dbg( p_input, "VMG opened" );    /* Set stream and area data */    vlc_mutex_lock( &p_input->stream.stream_lock );    p_input->stream.i_method = INPUT_METHOD_DVD;    /* If we are here we can control the pace... */    p_input->stream.b_pace_control = VLC_TRUE;    p_input->stream.b_seekable = VLC_TRUE;    p_input->stream.p_selected_area->i_size = 0;    p_input->stream.p_selected_area->i_tell = 0;    /* Initialize ES structures */    input_InitStream( p_input, sizeof( stream_ps_data_t ) );    /* disc input method */    p_input->stream.i_method = INPUT_METHOD_DVD;#define tt_srpt p_dvd->p_vmg_file->tt_srpt    msg_Dbg( p_input, "number of titles: %d", tt_srpt->nr_of_srpts );#define area p_input->stream.pp_areas    /* We start from 1 here since the default area 0     * is reserved for video_ts.vob */    for( i = 1 ; i <= tt_srpt->nr_of_srpts ; i++ )    {        /* Titles are Program Chains */        input_AddArea( p_input, i, tt_srpt->title[i-1].nr_of_ptts );        /* Absolute start offset and size         * We can only set that with vts ifo, so we do it during the         * first call to DVDSetArea */        area[i]->i_start = 0;        area[i]->i_size = 0;        /* Default Chapter */        area[i]->i_part = 1;        area[i]->i_plugin_data = tt_srpt->title[i-1].title_set_nr;    }#undef area    p_dvd->i_title = i_title <= tt_srpt->nr_of_srpts ? i_title : 1;#undef tt_srpt    p_area = p_input->stream.pp_areas[p_dvd->i_title];    p_dvd->i_chapter = i_chapter;    p_dvd->i_chapter = i_chapter < p_area->i_part_nb ? i_chapter : 1;    p_area->i_part = p_dvd->i_chapter;    p_dvd->i_angle = i_angle;    /* set title, chapter, audio and subpic */    if( DvdReadSetArea( p_input, p_area ) )    {        vlc_mutex_unlock( &p_input->stream.stream_lock );        return VLC_EGENERIC;    }    vlc_mutex_unlock( &p_input->stream.stream_lock );    if( !p_input->psz_demux || !*p_input->psz_demux )    {

⌨️ 快捷键说明

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