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

📄 play_title.c

📁 有关mpeg2的deocde代码
💻 C
字号:
/* * Copyright (C) 2001 Billy Biggs <vektor@dumbterm.net>. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <stdio.h>#include <stdlib.h>#include <assert.h>#include <dvdread/dvd_reader.h>#include <dvdread/ifo_types.h>#include <dvdread/ifo_read.h>#include <dvdread/dvd_udf.h>#include <dvdread/nav_read.h>#include <dvdread/nav_print.h>/** * Returns true if the pack is a NAV pack.  This check is clearly insufficient, * and sometimes we incorrectly think that valid other packs are NAV packs.  I * need to make this stronger. */int is_nav_pack( unsigned char *buffer ){    return ( buffer[ 41 ] == 0xbf && buffer[ 1027 ] == 0xbf );}int main( int argc, char **argv ){    int titleid, chapid, pgc_id, len, start_cell, cur_cell;    unsigned int cur_pack;    int angle, ttn, pgn, next_cell;    unsigned char data[ 1024 * DVD_VIDEO_LB_LEN ];    dvd_reader_t *dvd;    dvd_file_t *title;    ifo_handle_t *vmg_file;    tt_srpt_t *tt_srpt;    ifo_handle_t *vts_file;    vts_ptt_srpt_t *vts_ptt_srpt;    pgc_t *cur_pgc;    /**     * Usage.     */    if( argc != 5 ) {        fprintf( stderr, "Usage: %s <dvd path> <title number> "                         "<start chapter> <angle>\n\n"                         "Title Number  [1-X]: Movie Title on Disc.\n"                         "Start Chapter [1-X]: Chapter to start at.\n"                         "Angle Number  [1-X]: Which angle to show.\n\n"                         "This app outputs an MPEG2 system stream.\n"                         "Make sure you redirect the output somewhere.\n\n"                         "Example: %s /dev/dvd 1 1 1 | xine stdin://mpeg2\n",                 argv[ 0 ], argv[ 0 ] );        return -1;    }    titleid = atoi( argv[ 2 ] ) - 1;    chapid = atoi( argv[ 3 ] ) - 1;    angle = atoi( argv[ 4 ] ) - 1;    /**     * Open the disc.     */    dvd = DVDOpen( argv[ 1 ] );    if( !dvd ) {        fprintf( stderr, "Couldn't open DVD: %s\n", argv[ 1 ] );        return -1;    }    /**     * Load the video manager to find out the information about the titles on     * this disc.     */    vmg_file = ifoOpen( dvd, 0 );    if( !vmg_file ) {        fprintf( stderr, "Can't open VMG info.\n" );        DVDClose( dvd );        return -1;    }    tt_srpt = vmg_file->tt_srpt;    /**     * Make sure our title number is valid.     */    fprintf( stderr, "There are %d titles on this DVD.\n",             tt_srpt->nr_of_srpts );    if( titleid < 0 || titleid >= tt_srpt->nr_of_srpts ) {        fprintf( stderr, "Invalid title %d.\n", titleid + 1 );        ifoClose( vmg_file );        DVDClose( dvd );        return -1;    }    /**     * Make sure the chapter number is valid for this title.     */    fprintf( stderr, "There are %d chapters in this title.\n",             tt_srpt->title[ titleid ].nr_of_ptts );    if( chapid < 0 || chapid >= tt_srpt->title[ titleid ].nr_of_ptts ) {        fprintf( stderr, "Invalid chapter %d\n", chapid + 1 );        ifoClose( vmg_file );        DVDClose( dvd );        return -1;    }    /**     * Make sure the angle number is valid for this title.     */    fprintf( stderr, "There are %d angles in this title.\n",             tt_srpt->title[ titleid ].nr_of_angles );    if( angle < 0 || angle >= tt_srpt->title[ titleid ].nr_of_angles ) {        fprintf( stderr, "Invalid angle %d\n", angle + 1 );        ifoClose( vmg_file );        DVDClose( dvd );        return -1;    }    /**     * Load the VTS information for the title set our title is in.     */    vts_file = ifoOpen( dvd, tt_srpt->title[ titleid ].title_set_nr );    if( !vts_file ) {        fprintf( stderr, "Can't open the title %d info file.\n",                 tt_srpt->title[ titleid ].title_set_nr );        ifoClose( vmg_file );        DVDClose( dvd );        return -1;    }    /**     * Determine which program chain we want to watch.  This is based on the     * chapter number.     */    ttn = tt_srpt->title[ titleid ].vts_ttn;    vts_ptt_srpt = vts_file->vts_ptt_srpt;    pgc_id = vts_ptt_srpt->title[ ttn - 1 ].ptt[ chapid ].pgcn;    pgn = vts_ptt_srpt->title[ ttn - 1 ].ptt[ chapid ].pgn;    cur_pgc = vts_file->vts_pgcit->pgci_srp[ pgc_id - 1 ].pgc;    start_cell = cur_pgc->program_map[ pgn - 1 ] - 1;    /**     * We've got enough info, time to open the title set data.     */    title = DVDOpenFile( dvd, tt_srpt->title[ titleid ].title_set_nr,                         DVD_READ_TITLE_VOBS );    if( !title ) {        fprintf( stderr, "Can't open title VOBS (VTS_%02d_1.VOB).\n",                 tt_srpt->title[ titleid ].title_set_nr );        ifoClose( vts_file );        ifoClose( vmg_file );        DVDClose( dvd );        return -1;    }    /**     * Playback by cell in this pgc, starting at the cell for our chapter.     */    next_cell = start_cell;    for( cur_cell = start_cell; next_cell < cur_pgc->nr_of_cells; ) {        cur_cell = next_cell;        /* Check if we're entering an angle block. */        if( cur_pgc->cell_playback[ cur_cell ].block_type                                        == BLOCK_TYPE_ANGLE_BLOCK ) {            int i;            cur_cell += angle;            for( i = 0;; ++i ) {                if( cur_pgc->cell_playback[ cur_cell + i ].block_mode                                          == BLOCK_MODE_LAST_CELL ) {                    next_cell = cur_cell + i + 1;                    break;                }            }        } else {            next_cell = cur_cell + 1;        }        /**         * We loop until we're out of this cell.         */        for( cur_pack = cur_pgc->cell_playback[ cur_cell ].first_sector;             cur_pack < cur_pgc->cell_playback[ cur_cell ].last_sector; ) {            dsi_t dsi_pack;            unsigned int next_vobu, next_ilvu_start, cur_output_size;            /**             * Read NAV packet.             */            len = DVDReadBlocks( title, (int) cur_pack, 1, data );            if( len != 1 ) {                fprintf( stderr, "Read failed for block %d\n", cur_pack );                ifoClose( vts_file );                ifoClose( vmg_file );                DVDCloseFile( title );                DVDClose( dvd );                return -1;            }            assert( is_nav_pack( data ) );            /**             * Parse the contained dsi packet.             */            navRead_DSI( &dsi_pack, &(data[ DSI_START_BYTE ]) );            assert( cur_pack == dsi_pack.dsi_gi.nv_pck_lbn );            /**             * Determine where we go next.  These values are the ones we mostly             * care about.             */            next_ilvu_start = cur_pack                              + dsi_pack.sml_agli.data[ angle ].address;            cur_output_size = dsi_pack.dsi_gi.vobu_ea;            /**             * If we're not at the end of this cell, we can determine the next             * VOBU to display using the VOBU_SRI information section of the             * DSI.  Using this value correctly follows the current angle,             * avoiding the doubled scenes in The Matrix, and makes our life             * really happy.             *             * Otherwise, we set our next address past the end of this cell to             * force the code above to go to the next cell in the program.             */            if( dsi_pack.vobu_sri.next_vobu != SRI_END_OF_CELL ) {                next_vobu = cur_pack                            + ( dsi_pack.vobu_sri.next_vobu & 0x7fffffff );            } else {                next_vobu = cur_pack + cur_output_size + 1;            }            assert( cur_output_size < 1024 );            cur_pack++;            /**             * Read in and output cursize packs.             */            len = DVDReadBlocks( title, (int)cur_pack, cur_output_size, data );            if( len != (int) cur_output_size ) {                fprintf( stderr, "Read failed for %d blocks at %d\n",                         cur_output_size, cur_pack );                ifoClose( vts_file );                ifoClose( vmg_file );                DVDCloseFile( title );                DVDClose( dvd );                return -1;            }            fwrite( data, cur_output_size, DVD_VIDEO_LB_LEN, stdout );            cur_pack = next_vobu;        }    }    ifoClose( vts_file );    ifoClose( vmg_file );    DVDCloseFile( title );    DVDClose( dvd );    return 0;}

⌨️ 快捷键说明

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