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

📄 ifo.c

📁 VLC媒体播放程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************** * ifo.c: Functions for ifo parsing ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN * $Id: ifo.c,v 1.6 2003/10/25 00:49:13 sam Exp $ * * Authors: St閜hane Borel <stef@via.ecp.fr> *          German Tischler <tanis@gaspode.franken.de> * * based on: *  - libifo by Thomas Mirlacher <dent@cosy.sbg.ac.at> *  - IFO structure documentation by Thomas Mirlacher, Bj鰎n Englund, *  H錵an Hjort * * 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>#ifdef HAVE_UNISTD_H#   include <unistd.h>#endif#include <string.h>#include <fcntl.h>#ifdef GOD_DAMN_DMCA#   include "dvdcss.h"#else#   include <dvdcss/dvdcss.h>#endif#include "dvd.h"#include "ifo.h"#include "udf.h"/***************************************************************************** * Local prototypes *****************************************************************************/void            CommandRead     ( command_desc_t );static int      ReadTitle       ( ifo_t * , title_t *, int, int );static int      FreeTitle       ( title_t * );static int      ReadUnitInf     ( ifo_t * , unit_inf_t *, int, int );static int      FreeUnitInf     ( unit_inf_t * );static int      ReadTitleUnit   ( ifo_t * , title_unit_t *, int );static int      FreeTitleUnit   ( title_unit_t * );static int      ReadVobuMap     ( ifo_t * , vobu_map_t *, int );static int      FreeVobuMap     ( vobu_map_t * );static int      ReadCellInf     ( ifo_t * , cell_inf_t *, int );static int      FreeCellInf     ( cell_inf_t * );static int      FreeTitleSet    ( vts_t * );static uint8_t* FillBuffer      ( ifo_t *, uint8_t *, int );static uint8_t  ReadByte        ( ifo_t *, uint8_t *, uint8_t ** );static void     ReadBytes       ( ifo_t *, uint8_t *, uint8_t **, uint8_t *, int );static void     DumpBytes       ( ifo_t *, uint8_t *, uint8_t **, int );static uint16_t ReadWord        ( ifo_t *, uint8_t *, uint8_t ** );static uint32_t ReadDouble      ( ifo_t *, uint8_t *, uint8_t ** );static uint64_t ReadQuad        ( ifo_t *, uint8_t *, uint8_t ** );/* * IFO Management. *//***************************************************************************** * IfoCreate : Creates an ifo structure and prepares for parsing directly *             on DVD device *****************************************************************************/int IfoCreate( thread_dvd_data_t * p_dvd ){    p_dvd->p_ifo = malloc( sizeof(ifo_t) );    if( p_dvd->p_ifo == NULL )    {        return -1;    }    /* memset to 0 to avoid crashing on deallocation later */    memset( p_dvd->p_ifo, 0, sizeof(ifo_t) );    /* if we are here the dvd device has already been opened */    p_dvd->p_ifo->dvdhandle = p_dvd->dvdhandle;    return 0;}/***************************************************************************** * IfoInit : Reads information from the management table. *****************************************************************************/int IfoInit( ifo_t * p_ifo ){    uint8_t             p_buf[DVD_LB_SIZE];    uint8_t *           p_tmp;    uint64_t            i_temp;    int                 i, j, k;    int                 i_start;    /* find the start sector of video information on the dvd */    p_ifo->i_start = DVDUDFFindFile( p_ifo->dvdhandle, "/VIDEO_TS/VIDEO_TS.IFO" );    if( !p_ifo->i_start ) return -1;    p_tmp = FillBuffer( p_ifo, p_buf, p_ifo->i_start );    /*i_start = p_ifo->i_pos; */    /*     * read the video manager information table     */#define MGINF     p_ifo->vmg.manager_inf    /*fprintf( stderr, "VMGI\n" ); */    ReadBytes( p_ifo, p_buf, &p_tmp, MGINF.psz_id, 12 );    MGINF.psz_id[12] = '\0';    MGINF.i_vmg_end_sector = ReadDouble( p_ifo, p_buf, &p_tmp );    DumpBytes( p_ifo, p_buf, &p_tmp, 12 );    MGINF.i_vmg_inf_end_sector = ReadDouble( p_ifo, p_buf, &p_tmp );    DumpBytes( p_ifo, p_buf, &p_tmp, 1 );    MGINF.i_spec_ver = ReadByte( p_ifo, p_buf, &p_tmp );    MGINF.i_cat = ReadDouble( p_ifo, p_buf, &p_tmp );    MGINF.i_volume_nb = ReadWord( p_ifo, p_buf, &p_tmp );    MGINF.i_volume = ReadWord( p_ifo, p_buf, &p_tmp );    MGINF.i_disc_side = ReadByte( p_ifo, p_buf, &p_tmp );    DumpBytes( p_ifo, p_buf, &p_tmp, 19 );    MGINF.i_title_set_nb = ReadWord( p_ifo, p_buf, &p_tmp );    ReadBytes( p_ifo, p_buf, &p_tmp, MGINF.ps_provider_id, 32 );    MGINF.i_pos_code = ReadQuad( p_ifo, p_buf, &p_tmp );    DumpBytes( p_ifo, p_buf, &p_tmp, 24 );    MGINF.i_vmg_inf_end_byte = ReadDouble( p_ifo, p_buf, &p_tmp );    MGINF.i_first_play_title_start_byte = ReadDouble( p_ifo, p_buf, &p_tmp );    DumpBytes( p_ifo, p_buf, &p_tmp, 56 );    MGINF.i_vob_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );    MGINF.i_title_inf_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );    MGINF.i_title_unit_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );    MGINF.i_parental_inf_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );    MGINF.i_vts_inf_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );    MGINF.i_text_data_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );    MGINF.i_cell_inf_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );    MGINF.i_vobu_map_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );    DumpBytes( p_ifo, p_buf, &p_tmp, 32 );    DumpBytes( p_ifo, p_buf, &p_tmp, 2 );    DumpBytes( p_ifo, p_buf, &p_tmp, 1 );    MGINF.i_audio_nb = ReadByte( p_ifo, p_buf, &p_tmp );    /*fprintf( stderr, "vmgi audio nb : %d\n", MGINF.i_audio_nb ); */    for( i = 0 ; i < 8 ; i++ )    {        i_temp = ReadQuad( p_ifo, p_buf, &p_tmp );    }    DumpBytes( p_ifo, p_buf, &p_tmp, 17 );    MGINF.i_spu_nb = ReadByte( p_ifo, p_buf, &p_tmp );    /*fprintf( stderr, "vmgi subpic nb : %d\n", MGINF.i_spu_nb ); */    for( i = 0 ; i < MGINF.i_spu_nb ; i++ )    {        ReadBytes( p_ifo, p_buf, &p_tmp, (uint8_t*)(&i_temp), 6 );        /* FIXME : take care of endianness */    }    /*     * read first play title.     */    /*fprintf(stderr,"readtitle %i\n", MGINF.i_first_play_title_start_byte & 0x7ff ); */    if( ReadTitle( p_ifo, &p_ifo->vmg.title, p_ifo->i_start                           + OFF2LB( MGINF.i_first_play_title_start_byte ),                   MGINF.i_first_play_title_start_byte & 0x7ff ) < 0 )    {        return -1;    }    /*     * fills the title information structure.     */#define TITINF       p_ifo->vmg.title_inf    if( MGINF.i_title_inf_start_sector )    {        p_tmp = FillBuffer( p_ifo, p_buf,                        p_ifo->i_start + MGINF.i_title_inf_start_sector );        /*fprintf( stderr, "title inf %d\n", p_ifo->i_pos ); */        TITINF.i_title_nb = ReadWord( p_ifo, p_buf, &p_tmp );        /*fprintf( stderr, "title_inf: TTU nb %d\n", TITINF.i_title_nb ); */        DumpBytes( p_ifo, p_buf, &p_tmp, 2 );        TITINF.i_last_byte = ReadDouble( p_ifo, p_buf, &p_tmp );        /* parsing of title attributes */        TITINF.p_attr = malloc( TITINF.i_title_nb *sizeof(title_attr_t) );        if( TITINF.p_attr == NULL )        {            return -1;        }        for( i = 0 ; i < TITINF.i_title_nb ; i++ )        {            TITINF.p_attr[i].i_play_type = ReadByte( p_ifo, p_buf, &p_tmp );            TITINF.p_attr[i].i_angle_nb = ReadByte( p_ifo, p_buf, &p_tmp );            TITINF.p_attr[i].i_chapter_nb = ReadWord( p_ifo, p_buf, &p_tmp );            TITINF.p_attr[i].i_parental_id = ReadWord( p_ifo, p_buf, &p_tmp );            TITINF.p_attr[i].i_title_set_num = ReadByte( p_ifo, p_buf, &p_tmp );            TITINF.p_attr[i].i_title_num = ReadByte( p_ifo, p_buf, &p_tmp );            TITINF.p_attr[i].i_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );            /*fprintf( stderr, "title_inf: %d %d %d\n", TITINF.p_attr[i].i_chapter_nb, TITINF.p_attr[i].i_title_set_num, TITINF.p_attr[i].i_title_num ); */        }    }    else    {        TITINF.p_attr = NULL;    }#undef TITINF    /*     * fills the title unit structure.     */    if( MGINF.i_title_unit_start_sector )    {        if( ReadTitleUnit( p_ifo, &p_ifo->vmg.title_unit, p_ifo->i_start                            + MGINF.i_title_unit_start_sector ) < 0 )        {            return -1;        }    }    /*     * fills the structure about parental information.     */#define PARINF        p_ifo->vmg.parental_inf    if( MGINF.i_parental_inf_start_sector )    {        p_tmp = FillBuffer( p_ifo, p_buf, p_ifo->i_start +                                MGINF.i_parental_inf_start_sector );        i_start = p_ifo->i_pos;        /*fprintf( stderr, "PTL\n" ); */        PARINF.i_country_nb = ReadWord( p_ifo, p_buf, &p_tmp );        PARINF.i_vts_nb = ReadWord( p_ifo, p_buf, &p_tmp );        PARINF.i_last_byte = ReadDouble( p_ifo, p_buf, &p_tmp );        PARINF.p_parental_desc = malloc( PARINF.i_country_nb                                          * sizeof(parental_desc_t) );        if( PARINF.p_parental_desc == NULL )        {            return -1;        }        for( i = 0 ; i < PARINF.i_country_nb ; i++ )        {            ReadBytes( p_ifo, p_buf, &p_tmp,                       PARINF.p_parental_desc[i].ps_country_code, 2 );            DumpBytes( p_ifo, p_buf, &p_tmp, 2 );            PARINF.p_parental_desc[i].i_parental_mask_start_byte =                                            ReadWord( p_ifo, p_buf, &p_tmp );            DumpBytes( p_ifo, p_buf, &p_tmp, 2 );        }        PARINF.p_parental_mask = malloc( PARINF.i_country_nb                                          * sizeof(parental_mask_t) );        if( PARINF.p_parental_mask == NULL )        {            return -1;        }        for( i = 0 ; i < PARINF.i_country_nb ; i++ )        {            p_tmp = FillBuffer( p_ifo, p_buf, i_start + OFF2LB(                      PARINF.p_parental_desc[i].i_parental_mask_start_byte ) )              + (PARINF.p_parental_desc[i].i_parental_mask_start_byte & 0x7ff);            for( j = 0 ; j < 8 ; j++ )            {                PARINF.p_parental_mask[i].ppi_mask[j] =                            malloc( ( PARINF.i_vts_nb + 1 ) * sizeof(uint16_t) );                if( PARINF.p_parental_mask[i].ppi_mask[j] == NULL )                {                    return -1;                }                for( k = 0 ; k < PARINF.i_vts_nb + 1 ; k++ )                {                    PARINF.p_parental_mask[i].ppi_mask[j][k] =                                            ReadWord( p_ifo, p_buf, &p_tmp );                }            }        }    }#undef PARINF    /*     * information and attributes about for each vts.     */#define VTSINF     p_ifo->vmg.vts_inf    if( MGINF.i_vts_inf_start_sector )    {        uint64_t i_temp;        p_tmp = FillBuffer( p_ifo, p_buf, p_ifo->i_start +                                MGINF.i_vts_inf_start_sector );        i_start = p_ifo->i_pos;        /*fprintf( stderr, "VTS ATTR\n" ); */        VTSINF.i_vts_nb = ReadWord( p_ifo, p_buf, &p_tmp );;        /*fprintf( stderr, "VTS ATTR Nb: %d\n", VTSINF.i_vts_nb ); */        DumpBytes( p_ifo, p_buf, &p_tmp, 2 );        VTSINF.i_last_byte = ReadDouble( p_ifo, p_buf, &p_tmp );        VTSINF.pi_vts_attr_start_byte =                            malloc( VTSINF.i_vts_nb * sizeof(uint32_t) );        if( VTSINF.pi_vts_attr_start_byte == NULL )        {            return -1;        }        for( i = 0 ; i < VTSINF.i_vts_nb ; i++ )        {            VTSINF.pi_vts_attr_start_byte[i] =                                      ReadDouble( p_ifo, p_buf, &p_tmp );        }        VTSINF.p_vts_attr = malloc( VTSINF.i_vts_nb * sizeof(vts_attr_t) );        if( VTSINF.p_vts_attr == NULL )        {            return -1;        }        for( i = 0 ; i < VTSINF.i_vts_nb ; i++ )        {            p_tmp = FillBuffer( p_ifo, p_buf, i_start +                                OFF2LB( VTSINF.pi_vts_attr_start_byte[i] ) )                     + ( VTSINF.pi_vts_attr_start_byte[i] & 0x7ff );            VTSINF.p_vts_attr[i].i_last_byte =                                ReadDouble( p_ifo, p_buf, &p_tmp );            VTSINF.p_vts_attr[i].i_cat_app_type =                                ReadDouble( p_ifo, p_buf, &p_tmp );            DumpBytes( p_ifo, p_buf, &p_tmp, 2 );            DumpBytes( p_ifo, p_buf, &p_tmp, 1 );            VTSINF.p_vts_attr[i].i_vts_menu_audio_nb =                                ReadByte( p_ifo, p_buf, &p_tmp );            /*fprintf( stderr, "m audio nb : %d\n", VTSINF.p_vts_attr[i].i_vts_menu_audio_nb ); */            for( j = 0 ; j < 8 ; j++ )            {                i_temp = ReadQuad( p_ifo, p_buf, &p_tmp );            }            DumpBytes( p_ifo, p_buf, &p_tmp, 17 );            VTSINF.p_vts_attr[i].i_vts_menu_spu_nb =                                ReadByte( p_ifo, p_buf, &p_tmp );            /*fprintf( stderr, "m subp nb : %d\n", VTSINF.p_vts_attr[i].i_vts_menu_spu_nb ); */            for( j = 0 ; j < 28 ; j++ )            {                /* FIXME : Fix endianness issue here */                ReadBytes( p_ifo, p_buf, &p_tmp, (uint8_t*)(&i_temp), 6 );            }            DumpBytes( p_ifo, p_buf, &p_tmp, 2 );            DumpBytes( p_ifo, p_buf, &p_tmp, 2 );            DumpBytes( p_ifo, p_buf, &p_tmp, 1 );            VTSINF.p_vts_attr[i].i_vts_title_audio_nb =                                ReadDouble( p_ifo, p_buf, &p_tmp );            /*fprintf( stderr, "tt audio nb : %d\n", VTSINF.p_vts_attr[i].i_vts_title_audio_nb ); */            for( j = 0 ; j < 8 ; j++ )            {                i_temp = ReadQuad( p_ifo, p_buf, &p_tmp );;            }            DumpBytes( p_ifo, p_buf, &p_tmp, 17 );            VTSINF.p_vts_attr[i].i_vts_title_spu_nb =                                ReadByte( p_ifo, p_buf, &p_tmp );            /*fprintf( stderr, "tt subp nb : %d\n", VTSINF.p_vts_attr[i].i_vts_title_spu_nb ); */            for( j = 0 ; j < 28 /*VTSINF.p_vts_vts_inf[i].i_vtstt_subpic_nb*/ ; j++ )            {                /* FIXME : Fix endianness issue here */                ReadBytes( p_ifo, p_buf, &p_tmp, (uint8_t*)(&i_temp), 6 );            }        }    }#undef VTSINF    /*     * global cell map.     */    if( MGINF.i_cell_inf_start_sector )    {        if( ReadCellInf( p_ifo, &p_ifo->vmg.cell_inf, p_ifo->i_start +                         MGINF.i_cell_inf_start_sector ) < 0 )        {            return -1;        }    }    /*     * global vob unit map.     */    if( MGINF.i_vobu_map_start_sector )    {        if( ReadVobuMap( p_ifo, &p_ifo->vmg.vobu_map, p_ifo->i_start +                         MGINF.i_vobu_map_start_sector ) < 0 )        {            return -1;        }    }#undef MGINF    p_ifo->vts.b_initialized = 0;

⌨️ 快捷键说明

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