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

📄 dvdread.c

📁 vlc源码
💻 C
📖 第 1 页 / 共 3 页
字号:
        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;            uint16_t i_id;            //IfoPrintAudio( p_demux, i );            /* Audio channel is active if first byte is 0x80 */            if( audio_control & 0x8000 )            {                i_position = ( audio_control & 0x7F00 ) >> 8;                msg_Dbg( p_demux, "audio position  %d", i_position );                switch( p_vts->vtsi_mat->vts_audio_attr[i - 1].audio_format )                {                case 0x00: /* A52 */                    i_id = (0x80 + i_position) | 0xbd00;                    break;                case 0x02:                case 0x03: /* MPEG audio */                    i_id = 0xc000 + i_position;                    break;                case 0x04: /* LPCM */                    i_id = (0xa0 + i_position) | 0xbd00;                    break;                case 0x06: /* DTS */                    i_id = (0x88 + i_position) | 0xbd00;                    break;                default:                    i_id = 0;                    msg_Err( p_demux, "unknown audio type %.2x",                        p_vts->vtsi_mat->vts_audio_attr[i - 1].audio_format );                }                ESNew( p_demux, i_id, p_sys->p_vts_file->vtsi_mat->                       vts_audio_attr[i - 1].lang_code );            }        }#undef audio_control#define spu_palette \    p_sys->p_vts_file->vts_pgcit->pgci_srp[pgc_id-1].pgc->palette        memcpy( p_sys->clut, spu_palette, 16 * sizeof( uint32_t ) );#define spu_control \    p_sys->p_vts_file->vts_pgcit->pgci_srp[pgc_id-1].pgc->subp_control[i-1]        /* Sub Picture ES */        for( i = 1; i <= p_vts->vtsi_mat->nr_of_vts_subp_streams; i++ )        {            int i_position = 0;            uint16_t i_id;            //IfoPrintSpu( p_sys, i );            msg_Dbg( p_demux, "spu %d 0x%02x", i, spu_control );            if( spu_control & 0x80000000 )            {                /*  there are several streams for one spu */                if( p_vts->vtsi_mat->vts_video_attr.display_aspect_ratio )                {                    /* 16:9 */                    switch( p_vts->vtsi_mat->vts_video_attr.permitted_df )                    {                    case 1: /* letterbox */                        i_position = spu_control & 0xff;                        break;                    case 2: /* pan&scan */                        i_position = ( spu_control >> 8 ) & 0xff;                        break;                    default: /* widescreen */                        i_position = ( spu_control >> 16 ) & 0xff;                        break;                    }                }                else                {                    /* 4:3 */                    i_position = ( spu_control >> 24 ) & 0x7F;                }                i_id = (0x20 + i_position) | 0xbd00;                ESNew( p_demux, i_id, p_sys->p_vts_file->vtsi_mat->                       vts_subp_attr[i - 1].lang_code );            }        }#undef spu_control    }    else if( i_title != -1 && i_title != p_sys->i_title )    {        return VLC_EGENERIC; /* Couldn't set title */    }    /*     * Chapter selection     */    if( i_chapter >= 0 && i_chapter < p_sys->i_chapters )    {        pgc_id = p_vts->vts_ptt_srpt->title[                     p_sys->i_ttn - 1].ptt[i_chapter].pgcn;        pgn = p_vts->vts_ptt_srpt->title[                  p_sys->i_ttn - 1].ptt[i_chapter].pgn;        p_pgc = p_vts->vts_pgcit->pgci_srp[pgc_id - 1].pgc;        p_sys->i_cur_cell = p_pgc->program_map[pgn - 1] - 1;        p_sys->i_chapter = i_chapter;        DvdReadFindCell( p_demux );        p_sys->i_title_offset = 0;        for( i = p_sys->i_title_start_cell; i < p_sys->i_cur_cell; i++ )        {            p_sys->i_title_offset += p_pgc->cell_playback[i].last_sector -                p_pgc->cell_playback[i].first_sector + 1;        }        p_sys->i_pack_len = 0;        p_sys->i_next_vobu = p_sys->i_cur_block =            p_pgc->cell_playback[p_sys->i_cur_cell].first_sector;        if( p_demux->info.i_seekpoint != i_chapter )        {            p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;            p_demux->info.i_seekpoint = i_chapter;        }    }    else if( i_chapter != -1 )    {        return VLC_EGENERIC; /* Couldn't set chapter */    }#undef p_pgc#undef p_vts#undef p_vmg    return VLC_SUCCESS;}/***************************************************************************** * DvdReadSeek : Goes to a given position on the stream. ***************************************************************************** * This one is used by the input and translate chronological position from * input to logical position on the device. *****************************************************************************/static void DvdReadSeek( demux_t *p_demux, int i_block_offset ){    demux_sys_t *p_sys = p_demux->p_sys;    int i_chapter = 0;    int i_cell = 0;    int i_vobu = 0;    int i_sub_cell = 0;    int i_block;#define p_pgc p_sys->p_cur_pgc#define p_vts p_sys->p_vts_file    /* Find cell */    i_block = i_block_offset;    for( i_cell = p_sys->i_title_start_cell;         i_cell <= p_sys->i_title_end_cell; i_cell++ )    {        if( i_block < (int)p_pgc->cell_playback[i_cell].last_sector -            (int)p_pgc->cell_playback[i_cell].first_sector + 1 ) break;        i_block -= (p_pgc->cell_playback[i_cell].last_sector -            p_pgc->cell_playback[i_cell].first_sector + 1);    }    if( i_cell > p_sys->i_title_end_cell )    {        msg_Err( p_demux, "couldn't find cell for block %i", i_block_offset );        return;    }    i_block += p_pgc->cell_playback[i_cell].first_sector;    p_sys->i_title_offset = i_block_offset;    /* Find chapter */    for( i_chapter = 0; i_chapter < p_sys->i_chapters; i_chapter++ )    {        int pgc_id, pgn, i_tmp;        pgc_id = p_vts->vts_ptt_srpt->title[                    p_sys->i_ttn - 1].ptt[i_chapter].pgcn;        pgn = p_vts->vts_ptt_srpt->title[                    p_sys->i_ttn - 1].ptt[i_chapter].pgn;        i_tmp = p_vts->vts_pgcit->pgci_srp[pgc_id - 1].pgc->program_map[pgn-1];        if( i_tmp > i_cell ) break;    }    if( i_chapter < p_sys->i_chapters &&        p_demux->info.i_seekpoint != i_chapter )    {        p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;        p_demux->info.i_seekpoint = i_chapter;    }    /* Find vobu */    while( (int)p_vts->vts_vobu_admap->vobu_start_sectors[i_vobu] <= i_block )    {        i_vobu++;    }    /* Find sub_cell */    while( p_vts->vts_c_adt->cell_adr_table[i_sub_cell].start_sector <           p_vts->vts_vobu_admap->vobu_start_sectors[i_vobu-1] )    {        i_sub_cell++;    }#if 1    msg_Dbg( p_demux, "cell %d i_sub_cell %d chapter %d vobu %d "             "cell_sector %d vobu_sector %d sub_cell_sector %d",             i_cell, i_sub_cell, i_chapter, i_vobu,             p_sys->p_cur_pgc->cell_playback[i_cell].first_sector,             p_vts->vts_vobu_admap->vobu_start_sectors[i_vobu],             p_vts->vts_c_adt->cell_adr_table[i_sub_cell - 1].start_sector);#endif    p_sys->i_cur_block = i_block;    p_sys->i_next_vobu = p_vts->vts_vobu_admap->vobu_start_sectors[i_vobu];    p_sys->i_pack_len = p_sys->i_next_vobu - i_block;    p_sys->i_cur_cell = i_cell;    p_sys->i_chapter = i_chapter;    DvdReadFindCell( p_demux );#undef p_vts#undef p_pgc    return;}/***************************************************************************** * DvdReadHandleDSI *****************************************************************************/static void DvdReadHandleDSI( demux_t *p_demux, uint8_t *p_data ){    demux_sys_t *p_sys = p_demux->p_sys;    navRead_DSI( &p_sys->dsi_pack, &p_data[DSI_START_BYTE] );    /*     * Determine where we go next.  These values are the ones we mostly     * care about.     */    p_sys->i_cur_block = p_sys->dsi_pack.dsi_gi.nv_pck_lbn;    p_sys->i_pack_len = p_sys->dsi_pack.dsi_gi.vobu_ea;    /*     * Store the timecodes so we can get the current time     */    p_sys->i_title_cur_time = (mtime_t) (p_sys->dsi_pack.dsi_gi.nv_pck_scr / 90 * 1000);    p_sys->i_cell_cur_time = (mtime_t) dvdtime_to_time( &p_sys->dsi_pack.dsi_gi.c_eltm, 0 );    /*     * 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.     */    p_sys->i_next_vobu = p_sys->i_cur_block +        ( p_sys->dsi_pack.vobu_sri.next_vobu & 0x7fffffff );    if( p_sys->dsi_pack.vobu_sri.next_vobu != SRI_END_OF_CELL        && p_sys->i_angle > 1 )    {        switch( ( p_sys->dsi_pack.sml_pbi.category & 0xf000 ) >> 12 )        {        case 0x4:            /* Interleaved unit with no angle */            if( p_sys->dsi_pack.sml_pbi.ilvu_sa != 0 )            {                p_sys->i_next_vobu = p_sys->i_cur_block +                    p_sys->dsi_pack.sml_pbi.ilvu_sa;                p_sys->i_pack_len = p_sys->dsi_pack.sml_pbi.ilvu_ea;            }            else            {                p_sys->i_next_vobu = p_sys->i_cur_block +                    p_sys->dsi_pack.dsi_gi.vobu_ea + 1;            }            break;        case 0x5:            /* vobu is end of ilvu */            if( p_sys->dsi_pack.sml_agli.data[p_sys->i_angle-1].address )            {                p_sys->i_next_vobu = p_sys->i_cur_block +                    p_sys->dsi_pack.sml_agli.data[p_sys->i_angle-1].address;                p_sys->i_pack_len = p_sys->dsi_pack.sml_pbi.ilvu_ea;                break;            }        case 0x6:            /* vobu is beginning of ilvu */        case 0x9:            /* next scr is 0 */        case 0xa:            /* entering interleaved section */        case 0x8:            /* non interleaved cells in interleaved section */        default:            p_sys->i_next_vobu = p_sys->i_cur_block +                ( p_sys->dsi_pack.vobu_sri.next_vobu & 0x7fffffff );            break;        }    }    else if( p_sys->dsi_pack.vobu_sri.next_vobu == SRI_END_OF_CELL )    {        p_sys->i_cur_cell = p_sys->i_next_cell;        /* End of title */        if( p_sys->i_cur_cell >= p_sys->p_cur_pgc->nr_of_cells ) return;        DvdReadFindCell( p_demux );        p_sys->i_next_vobu =            p_sys->p_cur_pgc->cell_playback[p_sys->i_cur_cell].first_sector;        p_sys->i_cell_duration = (mtime_t)dvdtime_to_time( &p_sys->p_cur_pgc->cell_playback[p_sys->i_cur_cell].playback_time, 0 );    }#if 0    msg_Dbg( p_demux, "scr %d lbn 0x%02x vobu_ea %d vob_id %d c_id %d c_time %lld",             p_sys->dsi_pack.dsi_gi.nv_pck_scr,             p_sys->dsi_pack.dsi_gi.nv_pck_lbn,             p_sys->dsi_pack.dsi_gi.vobu_ea,             p_sys->dsi_pack.dsi_gi.vobu_vob_idn,             p_sys->dsi_pack.dsi_gi.vobu_c_idn,             dvdtime_to_time( &p_sys->dsi_pack.dsi_gi.c_eltm, 0 ) );    msg_Dbg( p_demux, "cell duration: %lld",             (mtime_t)dvdtime_to_time( &p_sys->p_cur_pgc->cell_playback[p_sys->i_cur_cell].playback_time, 0 ) );    msg_Dbg( p_demux, "cat 0x%02x ilvu_ea %d ilvu_sa %d size %d",             p_sys->dsi_pack.sml_pbi.category,             p_sys->dsi_pack.sml_pbi.ilvu_ea,             p_sys->dsi_pack.sml_pbi.ilvu_sa,             p_sys->dsi_pack.sml_pbi.size );    msg_Dbg( p_demux, "next_vobu %d next_ilvu1 %d next_ilvu2 %d",             p_sys->dsi_pack.vobu_sri.next_vobu & 0x7fffffff,             p_sys->dsi_pack.sml_agli.data[ p_sys->i_angle - 1 ].address,             p_sys->dsi_pack.sml_agli.data[ p_sys->i_angle ].address);#endif}/***************************************************************************** * DvdReadFindCell *****************************************************************************/static void DvdReadFindCell( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    pgc_t *p_pgc;    int   pgc_id, pgn;    int   i = 0;#define cell p_sys->p_cur_pgc->cell_playback    if( cell[p_sys->i_cur_cell].block_type == BLOCK_TYPE_ANGLE_BLOCK )    {        p_sys->i_cur_cell += p_sys->i_angle - 1;        while( cell[p_sys->i_cur_cell+i].block_mode != BLOCK_MODE_LAST_CELL )        {            i++;        }        p_sys->i_next_cell = p_sys->i_cur_cell + i + 1;    }    else    {        p_sys->i_next_cell = p_sys->i_cur_cell + 1;    }#undef cell    if( p_sys->i_chapter + 1 >= p_sys->i_chapters ) return;    pgc_id = p_sys->p_vts_file->vts_ptt_srpt->title[                p_sys->i_ttn - 1].ptt[p_sys->i_chapter + 1].pgcn;    pgn = p_sys->p_vts_file->vts_ptt_srpt->title[              p_sys->i_ttn - 1].ptt[p_sys->i_chapter + 1].pgn;    p_pgc = p_sys->p_vts_file->vts_pgcit->pgci_srp[pgc_id - 1].pgc;    if( p_sys->i_cur_cell >= p_pgc->program_map[pgn - 1] - 1 )    {        p_sys->i_chapter++;        if( p_sys->i_chapter < p_sys->i_chapters &&            p_demux->info.i_seekpoint != p_sys->i_chapter )        {            p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;            p_demux->info.i_seekpoint = p_sys->i_chapter;        }    }}/***************************************************************************** * DemuxTitles: get the titles/chapters structure *****************************************************************************/static void DemuxTitles( demux_t *p_demux, int *pi_angle ){    demux_sys_t *p_sys = p_demux->p_sys;    input_title_t *t;    seekpoint_t *s;    int32_t i_titles;    int i;    /* Find out number of titles/chapters */#define tt_srpt p_sys->p_vmg_file->tt_srpt    i_titles = tt_srpt->nr_of_srpts;    msg_Dbg( p_demux, "number of titles: %d", i_titles );    for( i = 0; i < i_titles; i++ )    {        int32_t i_chapters = 0;        int j;        i_chapters = tt_srpt->title[i].nr_of_ptts;        msg_Dbg( p_demux, "title %d has %d chapters", i, i_chapters );        t = vlc_input_title_New();        for( j = 0; j < __MAX( i_chapters, 1 ); j++ )        {            s = vlc_seekpoint_New();            TAB_APPEND( t->i_seekpoint, t->seekpoint, s );        }        TAB_APPEND( p_sys->i_titles, p_sys->titles, t );    }#undef tt_srpt}

⌨️ 快捷键说明

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