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

📄 dvdread.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
                INPUT_UPDATE_TITLE | INPUT_UPDATE_SEEKPOINT;            p_demux->info.i_title = i;            p_demux->info.i_seekpoint = 0;            return VLC_SUCCESS;        case DEMUX_SET_SEEKPOINT:            i = (int)va_arg( args, int );            if( DvdReadSetArea( p_demux, -1, i, -1 ) != VLC_SUCCESS )            {                msg_Warn( p_demux, "cannot set title/chapter" );                return VLC_EGENERIC;            }            p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;            p_demux->info.i_seekpoint = i;            return VLC_SUCCESS;        case DEMUX_GET_PTS_DELAY:            pi64 = (int64_t*)va_arg( args, int64_t * );            *pi64 = (int64_t)var_GetInteger( p_demux, "dvdread-caching" )*1000;            return VLC_SUCCESS;        /* TODO implement others */        default:            return VLC_EGENERIC;    }}/***************************************************************************** * Demux: *****************************************************************************/static int Demux( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    uint8_t p_buffer[DVD_VIDEO_LB_LEN * DVD_BLOCK_READ_ONCE];    int i_blocks_once, i_read;    int i;    /*     * Playback by cell in this pgc, starting at the cell for our chapter.     */    /*     * Check end of pack, and select the following one     */    if( !p_sys->i_pack_len )    {        /* Read NAV packet */        if( DVDReadBlocks( p_sys->p_title, p_sys->i_next_vobu,                           1, p_buffer ) != 1 )        {            msg_Err( p_demux, "read failed for block %d", p_sys->i_next_vobu );            return -1;        }        /* Basic check to be sure we don't have a empty title         * go to next title if so */        //assert( p_buffer[41] == 0xbf && p_buffer[1027] == 0xbf );        /* Parse the contained dsi packet */        DvdReadHandleDSI( p_demux, p_buffer );        /* End of title */        if( p_sys->i_cur_cell >= p_sys->p_cur_pgc->nr_of_cells )        {            if( p_sys->i_title + 1 >= p_sys->i_titles )            {                return 0; /* EOF */            }            DvdReadSetArea( p_demux, p_sys->i_title + 1, 0, -1 );        }        if( p_sys->i_pack_len >= 1024 )        {            msg_Err( p_demux, "i_pack_len >= 1024 (%i). "                     "This shouldn't happen!", p_sys->i_pack_len );            return 0; /* EOF */        }        /* FIXME: Ugly kludge: we send the pack block to the input for it         * sometimes has a zero scr and restart the sync */        p_sys->i_cur_block++;        p_sys->i_title_offset++;        DemuxBlock( p_demux, p_buffer, DVD_VIDEO_LB_LEN );    }    if( p_sys->i_cur_cell >= p_sys->p_cur_pgc->nr_of_cells )    {        if( p_sys->i_title + 1 >= p_sys->i_titles )        {            return 0; /* EOF */        }        DvdReadSetArea( p_demux, p_sys->i_title + 1, 0, -1 );    }    /*     * Read actual data     */    i_blocks_once = __MIN( p_sys->i_pack_len, DVD_BLOCK_READ_ONCE );    p_sys->i_pack_len -= i_blocks_once;    /* Reads from DVD */    i_read = DVDReadBlocks( p_sys->p_title, p_sys->i_cur_block,                            i_blocks_once, p_buffer );    if( i_read != i_blocks_once )    {        msg_Err( p_demux, "read failed for %d/%d blocks at 0x%02x",                 i_read, i_blocks_once, p_sys->i_cur_block );        return -1;    }    p_sys->i_cur_block += i_read;    p_sys->i_title_offset += i_read;#if 0    msg_Dbg( p_demux, "i_blocks: %d len: %d current: 0x%02x",             i_read, p_sys->i_pack_len, p_sys->i_cur_block );#endif    for( i = 0; i < i_read; i++ )    {        DemuxBlock( p_demux, p_buffer + i * DVD_VIDEO_LB_LEN,                    DVD_VIDEO_LB_LEN );    }#undef p_pgc    return 1;}/***************************************************************************** * DemuxBlock: demux a given block *****************************************************************************/static int DemuxBlock( demux_t *p_demux, uint8_t *pkt, int i_pkt ){    demux_sys_t *p_sys = p_demux->p_sys;    uint8_t     *p = pkt;    while( p < &pkt[i_pkt] )    {        int i_size = ps_pkt_size( p, &pkt[i_pkt] - p );        block_t *p_pkt;        if( i_size <= 0 )        {            break;        }        /* Create a block */        p_pkt = block_New( p_demux, i_size );        memcpy( p_pkt->p_buffer, p, i_size);        /* Parse it and send it */        switch( 0x100 | p[3] )        {        case 0x1b9:        case 0x1bb:        case 0x1bc:#ifdef DVDREAD_DEBUG            if( p[3] == 0xbc )            {                msg_Warn( p_demux, "received a PSM packet" );            }            else if( p[3] == 0xbb )            {                msg_Warn( p_demux, "received a SYSTEM packet" );            }#endif            block_Release( p_pkt );            break;        case 0x1ba:        {            int64_t i_scr;            int i_mux_rate;            if( !ps_pkt_parse_pack( p_pkt, &i_scr, &i_mux_rate ) )            {                es_out_Control( p_demux->out, ES_OUT_SET_PCR, i_scr );                if( i_mux_rate > 0 ) p_sys->i_mux_rate = i_mux_rate;            }            block_Release( p_pkt );            break;        }        default:        {            int i_id = ps_pkt_id( p_pkt );            if( i_id >= 0xc0 )            {                ps_track_t *tk = &p_sys->tk[PS_ID_TO_TK(i_id)];                if( !tk->b_seen )                {                    ESNew( p_demux, i_id, 0 );                }                if( tk->b_seen && tk->es &&                    !ps_pkt_parse_pes( p_pkt, tk->i_skip ) )                {                    es_out_Send( p_demux->out, tk->es, p_pkt );                }                else                {                    block_Release( p_pkt );                }            }            else            {                block_Release( p_pkt );            }            break;        }        }        p += i_size;    }    return VLC_SUCCESS;}/***************************************************************************** * ESNew: register a new elementary stream *****************************************************************************/static void ESNew( demux_t *p_demux, int i_id, int i_lang ){    demux_sys_t *p_sys = p_demux->p_sys;    ps_track_t  *tk = &p_sys->tk[PS_ID_TO_TK(i_id)];    char psz_language[3];    if( tk->b_seen ) return;    if( ps_track_fill( tk, 0, i_id ) )    {        msg_Warn( p_demux, "unknown codec for id=0x%x", i_id );        return;    }    psz_language[0] = psz_language[1] = psz_language[2] = 0;    if( i_lang && i_lang != 0xffff )    {        psz_language[0] = (i_lang >> 8)&0xff;        psz_language[1] = (i_lang     )&0xff;    }    /* Add a new ES */    if( tk->fmt.i_cat == VIDEO_ES )    {        if( p_sys->i_aspect >= 0 )        {            tk->fmt.video.i_aspect = p_sys->i_aspect;        }    }    else if( tk->fmt.i_cat == AUDIO_ES )    {        int i_audio = -1;        /* find the audio number PLEASE find another way */        if( (i_id&0xbdf8) == 0xbd88 )       /* dts */        {            i_audio = i_id&0x07;        }        else if( (i_id&0xbdf0) == 0xbd80 )  /* a52 */        {            i_audio = i_id&0xf;        }        else if( (i_id&0xbdf0) == 0xbda0 )  /* lpcm */        {            i_audio = i_id&0x1f;        }        else if( ( i_id&0xe0 ) == 0xc0 )    /* mpga */        {            i_audio = i_id&0x1f;        }        if( psz_language[0] ) tk->fmt.psz_language = strdup( psz_language );    }    else if( tk->fmt.i_cat == SPU_ES )    {        /* Palette */        tk->fmt.subs.spu.palette[0] = 0xBeef;        memcpy( &tk->fmt.subs.spu.palette[1], p_sys->clut,                16 * sizeof( uint32_t ) );        if( psz_language[0] ) tk->fmt.psz_language = strdup( psz_language );    }    tk->es = es_out_Add( p_demux->out, &tk->fmt );    tk->b_seen = VLC_TRUE;}/***************************************************************************** * DvdReadSetArea: initialize input data for title x, chapter y. * It should be called for each user navigation request. ***************************************************************************** * Take care that i_title and i_chapter start from 0. *****************************************************************************/static int DvdReadSetArea( demux_t *p_demux, int i_title, int i_chapter,                           int i_angle ){    demux_sys_t *p_sys = p_demux->p_sys;    int pgc_id = 0, pgn = 0;    int i;#define p_pgc p_sys->p_cur_pgc#define p_vmg p_sys->p_vmg_file#define p_vts p_sys->p_vts_file    if( i_title >= 0 && i_title < p_sys->i_titles &&        i_title != p_sys->i_title )    {        int i_start_cell, i_end_cell;        if( p_sys->p_title != NULL ) DVDCloseFile( p_sys->p_title );        if( p_vts != NULL ) ifoClose( p_vts );        p_sys->i_title = i_title;        /*         *  We have to load all title information         */        msg_Dbg( p_demux, "open VTS %d, for title %d",                 p_vmg->tt_srpt->title[i_title].title_set_nr, i_title + 1 );        /* Ifo vts */        if( !( p_vts = ifoOpen( p_sys->p_dvdread,               p_vmg->tt_srpt->title[i_title].title_set_nr ) ) )        {            msg_Err( p_demux, "fatal error in vts ifo" );            return VLC_EGENERIC;        }        /* Title position inside the selected vts */        p_sys->i_ttn = p_vmg->tt_srpt->title[i_title].vts_ttn;        /* Find title start/end */        pgc_id = p_vts->vts_ptt_srpt->title[p_sys->i_ttn - 1].ptt[0].pgcn;        pgn = p_vts->vts_ptt_srpt->title[p_sys->i_ttn - 1].ptt[0].pgn;        p_pgc = p_vts->vts_pgcit->pgci_srp[pgc_id - 1].pgc;        p_sys->i_title_start_cell =            i_start_cell = p_pgc->program_map[pgn - 1] - 1;        p_sys->i_title_start_block =            p_pgc->cell_playback[i_start_cell].first_sector;        p_sys->i_title_end_cell =            i_end_cell = p_pgc->nr_of_cells - 1;        p_sys->i_title_end_block =            p_pgc->cell_playback[i_end_cell].last_sector;        p_sys->i_title_offset = 0;        p_sys->i_title_blocks = 0;        for( i = i_start_cell; i <= i_end_cell; i++ )        {            p_sys->i_title_blocks += p_pgc->cell_playback[i].last_sector -                p_pgc->cell_playback[i].first_sector + 1;        }        msg_Dbg( p_demux, "title %d vts_title %d pgc %d pgn %d "                 "start %d end %d blocks: %d",                 i_title + 1, p_sys->i_ttn, pgc_id, pgn,                 p_sys->i_title_start_block, p_sys->i_title_end_block,                 p_sys->i_title_blocks );        /*         * Set properties for current chapter         */        p_sys->i_chapter = 0;        p_sys->i_chapters =            p_vts->vts_ptt_srpt->title[p_sys->i_ttn - 1].nr_of_ptts;        pgc_id = p_vts->vts_ptt_srpt->title[                    p_sys->i_ttn - 1].ptt[p_sys->i_chapter].pgcn;        pgn = p_vts->vts_ptt_srpt->title[                    p_sys->i_ttn - 1].ptt[p_sys->i_chapter].pgn;        p_pgc = p_vts->vts_pgcit->pgci_srp[pgc_id - 1].pgc;        p_sys->i_pack_len = 0;        p_sys->i_next_cell =            p_sys->i_cur_cell = p_pgc->program_map[pgn - 1] - 1;        DvdReadFindCell( p_demux );        p_sys->i_next_vobu = p_sys->i_cur_block =            p_pgc->cell_playback[p_sys->i_cur_cell].first_sector;        /*         * Angle management         */        p_sys->i_angles = p_vmg->tt_srpt->title[i_title].nr_of_angles;        if( p_sys->i_angle > p_sys->i_angles ) p_sys->i_angle = 1;        /*         * We've got enough info, time to open the title set data.         */        if( !( p_sys->p_title = DVDOpenFile( p_sys->p_dvdread,            p_vmg->tt_srpt->title[i_title].title_set_nr,            DVD_READ_TITLE_VOBS ) ) )        {            msg_Err( p_demux, "cannot open title (VTS_%02d_1.VOB)",                     p_vmg->tt_srpt->title[i_title].title_set_nr );            return VLC_EGENERIC;        }        //IfoPrintTitle( p_demux );        /*         * Destroy obsolete ES by reinitializing program 0         * and find all ES in title with ifo data         */        es_out_Control( p_demux->out, ES_OUT_RESET_PCR );        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 );            }            tk->b_seen = VLC_FALSE;        }        if( p_demux->info.i_title != i_title )        {            p_demux->info.i_update |=                INPUT_UPDATE_TITLE | INPUT_UPDATE_SEEKPOINT;            p_demux->info.i_title = i_title;            p_demux->info.i_seekpoint = 0;        }        /* TODO: re-add angles */        ESNew( p_demux, 0xe0, 0 ); /* Video, FIXME ? */        p_sys->i_aspect = p_vts->vtsi_mat->vts_video_attr.display_aspect_ratio;#define audio_control \    p_sys->p_vts_file->vts_pgcit->pgci_srp[pgc_id-1].pgc->audio_control[i-1]        /* Audio ES, in the order they appear in the .ifo */        for( i = 1; i <= p_vts->vtsi_mat->nr_of_vts_audio_streams; i++ )        {            int i_position = 0;

⌨️ 快捷键说明

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