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

📄 input.c

📁 VLC媒体播放程序
💻 C
📖 第 1 页 / 共 3 页
字号:
    val.i_int = p_area->i_part;    var_Change( p_input, "chapter", VLC_VAR_SETVALUE, &val, NULL );    return VLC_SUCCESS;}/***************************************************************************** * DvdReadRead: reads data packets. ***************************************************************************** * Returns -1 in case of error, 0 in case of EOF, otherwise the number of * bytes. *****************************************************************************/static ssize_t DvdReadRead( input_thread_t * p_input,                            byte_t * p_buffer, size_t i_count ){    thread_dvd_data_t *     p_dvd;    byte_t *                p_buf;    unsigned int            i_blocks_once;    unsigned int            i_blocks;    int                     i_read;    int                     i_read_total;    vlc_bool_t              b_eot = VLC_FALSE;    p_dvd = (thread_dvd_data_t *)p_input->p_access_data;    p_buf = p_buffer;    /*     * Playback by cell in this pgc, starting at the cell for our chapter.     */    i_blocks = OFF2LB( i_count );    i_read_total = 0;    i_read = 0;    while( i_blocks )    {        /*         * End of pack, we select the following one         */        if( ! p_dvd->i_pack_len )        {            /*             * Read NAV packet.             */            if( ( i_read = DVDReadBlocks( p_dvd->p_title, p_dvd->i_next_vobu,                           1, p_buf ) ) != 1 )            {                msg_Err( p_input, "read failed for block %d",                                  p_dvd->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_dvd, p_buf );            /* End of title */            if( p_dvd->i_next_vobu >= p_dvd->i_end_block + 1 )            {                b_eot = 1;                break;            }            assert( p_dvd->i_pack_len < 1024 );            /* FIXME: Ugly kludge: we send the pack block to the input for it             * sometimes has a zero scr and restart the sync */            p_dvd->i_cur_block ++;            //p_dvd->i_pack_len++;            i_read_total++;            p_buf += DVD_VIDEO_LB_LEN;            i_blocks--;        }        /*         * Compute the number of blocks to read         */        i_blocks_once = __MIN( p_dvd->i_pack_len, i_blocks );        p_dvd->i_pack_len -= i_blocks_once;        /* Reads from DVD */        i_read = DVDReadBlocks( p_dvd->p_title, p_dvd->i_cur_block,                                i_blocks_once, p_buf );        if( (unsigned int)i_read != i_blocks_once )        {            msg_Err( p_input, "read failed for %d/%d blocks at 0x%02x",                              i_read, i_blocks_once, p_dvd->i_cur_block );            return -1;        }        i_blocks -= i_read;        i_read_total += i_read;        p_dvd->i_cur_block += i_read;        p_buf += LB2OFF( i_read );    }/*    msg_Dbg( p_input, "i_blocks: %d len: %d current: 0x%02x", i_read, p_dvd->i_pack_len, p_dvd->i_cur_block );*/    vlc_mutex_lock( &p_input->stream.stream_lock );    if( p_dvd->b_eoc )    {        /* We modify i_part only at end of chapter not to erase         * some modification from the interface */        p_input->stream.p_selected_area->i_part = p_dvd->i_chapter;        p_dvd->b_eoc = VLC_FALSE;    }    if( ( LB2OFF( p_dvd->i_cur_block )          - p_input->stream.p_selected_area->i_start )            >= p_input->stream.p_selected_area->i_size || b_eot )    {        if( ( p_input->stream.p_selected_area->i_id + 1 ) >=                        p_input->stream.i_area_nb )        {            /* EOF */            vlc_mutex_unlock( &p_input->stream.stream_lock );            return 0;        }        /* EOT */        msg_Dbg( p_input, "new title" );        DvdReadSetArea( p_input, p_input->stream.pp_areas[                        p_input->stream.p_selected_area->i_id+1] );    }    vlc_mutex_unlock( &p_input->stream.stream_lock );    return LB2OFF( i_read_total );}#undef p_pgc/***************************************************************************** * 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. * The lock should be taken before calling this function. *****************************************************************************/static void DvdReadSeek( input_thread_t * p_input, off_t i_off ){    thread_dvd_data_t *     p_dvd;    unsigned int            i_lb;    unsigned int            i_tmp;    unsigned int            i_chapter = 0;    unsigned int            i_cell = 0;    unsigned int            i_vobu = 0;    unsigned int            i_sub_cell = 0;    vlc_mutex_lock( &p_input->stream.stream_lock );    i_off += p_input->stream.p_selected_area->i_start;    vlc_mutex_unlock( &p_input->stream.stream_lock );    i_lb = OFF2LB( i_off );    p_dvd = ( thread_dvd_data_t * )p_input->p_access_data;    /* find cell */    while( p_dvd->p_cur_pgc->cell_playback[i_cell].last_sector < i_lb )    {        i_cell++;    }    /* find chapter */    do    {        pgc_t *     p_pgc;        int         pgc_id, pgn;        i_chapter++;        pgc_id = p_dvd->p_vts_file->vts_ptt_srpt->title[                    p_dvd->i_ttn-1].ptt[i_chapter-1].pgcn;        pgn = p_dvd->p_vts_file->vts_ptt_srpt->title[                    p_dvd->i_ttn-1].ptt[i_chapter-1].pgn;        p_pgc = p_dvd->p_vts_file->vts_pgcit->pgci_srp[pgc_id-1].pgc;        i_tmp = p_pgc->program_map[pgn-1];    } while( i_tmp <= i_cell );    /* find vobu */    while( p_dvd->p_vts_file->vts_vobu_admap->vobu_start_sectors[i_vobu]            <= i_lb )    {        i_vobu++;    }    /* find sub_cell */    while( p_dvd->p_vts_file->vts_c_adt->cell_adr_table[i_sub_cell].start_sector <            p_dvd->p_vts_file->vts_vobu_admap->vobu_start_sectors[i_vobu-1] )    {        i_sub_cell++;    }/*    msg_Dbg( p_input, "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_dvd->p_cur_pgc->cell_playback[i_cell].first_sector,            p_dvd->p_vts_file->vts_vobu_admap->vobu_start_sectors[i_vobu],            p_dvd->p_vts_file->vts_c_adt->cell_adr_table[i_sub_cell-1].start_sector);*/    p_dvd->i_cur_block = i_lb;    p_dvd->i_next_vobu =        p_dvd->p_vts_file->vts_vobu_admap->vobu_start_sectors[i_vobu];    p_dvd->i_pack_len = p_dvd->i_next_vobu - i_lb;    p_dvd->i_cur_cell = i_cell;    p_dvd->i_chapter = i_chapter;    DvdReadFindCell( p_dvd );    vlc_mutex_lock( &p_input->stream.stream_lock );    p_input->stream.p_selected_area->i_tell =        LB2OFF ( p_dvd->i_cur_block )         - p_input->stream.p_selected_area->i_start;    p_input->stream.p_selected_area->i_part = p_dvd->i_chapter;    vlc_mutex_unlock( &p_input->stream.stream_lock );    return;}/***************************************************************************** * DvdReadHandleDSI *****************************************************************************/static void DvdReadHandleDSI( thread_dvd_data_t * p_dvd, uint8_t * p_data ){    navRead_DSI( &(p_dvd->dsi_pack), &(p_data[ DSI_START_BYTE ]) );    /*     * Determine where we go next.  These values are the ones we mostly     * care about.     */    p_dvd->i_cur_block = p_dvd->dsi_pack.dsi_gi.nv_pck_lbn;    /*     * 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.     */    if( p_dvd->dsi_pack.vobu_sri.next_vobu != SRI_END_OF_CELL )    {#if 1        switch( ( p_dvd->dsi_pack.sml_pbi.category & 0xf000 ) >> 12 )        {            case 0x4:                /* interleaved unit with no angle */                if( p_dvd->dsi_pack.sml_pbi.ilvu_sa != 0 )                {                    p_dvd->i_next_vobu = p_dvd->i_cur_block +                        p_dvd->dsi_pack.sml_pbi.ilvu_sa;                    p_dvd->i_pack_len = p_dvd->dsi_pack.sml_pbi.ilvu_ea;                }                else                {                    p_dvd->i_next_vobu = p_dvd->i_cur_block +                        p_dvd->dsi_pack.dsi_gi.vobu_ea + 1;                    p_dvd->i_pack_len = p_dvd->dsi_pack.dsi_gi.vobu_ea;                }                break;            case 0x5:                /* vobu is end of ilvu */                if( p_dvd->dsi_pack.sml_agli.data[p_dvd->i_angle-1].address )                {                    p_dvd->i_next_vobu = p_dvd->i_cur_block +                        p_dvd->dsi_pack.sml_agli.data[p_dvd->i_angle-1].address;                    p_dvd->i_pack_len = p_dvd->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_dvd->i_next_vobu = p_dvd->i_cur_block +                    ( p_dvd->dsi_pack.vobu_sri.next_vobu & 0x7fffffff );                p_dvd->i_pack_len = p_dvd->dsi_pack.dsi_gi.vobu_ea;                break;        }#else        p_dvd->i_next_vobu = p_dvd->i_cur_block +            ( p_dvd->dsi_pack.vobu_sri.next_vobu & 0x7fffffff );        p_dvd->i_pack_len = p_dvd->dsi_pack.dsi_gi.vobu_ea;#endif    }    else    {        p_dvd->i_cur_cell = p_dvd->i_next_cell;        DvdReadFindCell( p_dvd );        p_dvd->i_pack_len = p_dvd->dsi_pack.dsi_gi.vobu_ea;        p_dvd->i_next_vobu =            p_dvd->p_cur_pgc->cell_playback[p_dvd->i_cur_cell].first_sector;    }#if 0    msg_Dbg( p_input, 12, "scr %d lbn 0x%02x vobu_ea %d vob_id %d c_id %d",             p_dvd->dsi_pack.dsi_gi.nv_pck_scr,             p_dvd->dsi_pack.dsi_gi.nv_pck_lbn,             p_dvd->dsi_pack.dsi_gi.vobu_ea,             p_dvd->dsi_pack.dsi_gi.vobu_vob_idn,             p_dvd->dsi_pack.dsi_gi.vobu_c_idn );    msg_Dbg( p_input, 12, "cat 0x%02x ilvu_ea %d ilvu_sa %d size %d",             p_dvd->dsi_pack.sml_pbi.category,             p_dvd->dsi_pack.sml_pbi.ilvu_ea,             p_dvd->dsi_pack.sml_pbi.ilvu_sa,             p_dvd->dsi_pack.sml_pbi.size );    msg_Dbg( p_input, 12, "next_vobu %d next_ilvu1 %d next_ilvu2 %d",             p_dvd->dsi_pack.vobu_sri.next_vobu & 0x7fffffff,             p_dvd->dsi_pack.sml_agli.data[ p_dvd->i_angle - 1 ].address,             p_dvd->dsi_pack.sml_agli.data[ p_dvd->i_angle ].address);#endif}/***************************************************************************** * DvdReadFindCell *****************************************************************************/static void DvdReadFindCell( thread_dvd_data_t * p_dvd ){    int         pgc_id, pgn;    int         i = 0;    pgc_t *     p_pgc;#define cell p_dvd->p_cur_pgc->cell_playback    if( cell[p_dvd->i_cur_cell].block_type == BLOCK_TYPE_ANGLE_BLOCK )    {#if 0        p_dvd->i_next_cell = p_dvd->i_cur_cell + p_dvd->i_angle_nb;        p_dvd->i_cur_cell += p_dvd->i_angle - 1;#else        p_dvd->i_cur_cell += p_dvd->i_angle - 1;        while( cell[p_dvd->i_cur_cell+i].block_mode != BLOCK_MODE_LAST_CELL )        {            i++;        }        p_dvd->i_next_cell = p_dvd->i_cur_cell + i + 1;#endif    }    else    {        p_dvd->i_next_cell = p_dvd->i_cur_cell + 1;    }#undef cell    pgc_id = p_dvd->p_vts_file->vts_ptt_srpt->title[                p_dvd->i_ttn-1].ptt[p_dvd->i_chapter-1].pgcn;    pgn = p_dvd->p_vts_file->vts_ptt_srpt->title[                p_dvd->i_ttn-1].ptt[p_dvd->i_chapter-1].pgn;    p_pgc = p_dvd->p_vts_file->vts_pgcit->pgci_srp[pgc_id-1].pgc;    if( p_pgc->program_map[pgn-1] <= p_dvd->i_cur_cell )    {        p_dvd->i_chapter++;        p_dvd->b_eoc = VLC_TRUE;    }}/***************************************************************************** * DvdReadLaunchDecoders *****************************************************************************/static void DvdReadLauchDecoders( input_thread_t * p_input ){    thread_dvd_data_t * p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);    int i_audio, i_spu;    input_SelectES( p_input, p_input->stream.pp_es[0] );    /* For audio: first one if none or a not existing one specified */    i_audio = config_GetInt( p_input, "audio-channel" );    if( i_audio < 0 /*|| i_audio > i_audio_nb*/ )    {        config_PutInt( p_input, "audio-channel", 1 );        i_audio = 1;    }    if( i_audio > 0/* && i_audio_nb > 0*/ )    {        if( config_GetInt( p_input, "audio-type" ) == REQUESTED_A52 )        {            int     i_a52 = i_audio;            while( ( p_input->stream.pp_es[i_a52]->i_fourcc !=                   VLC_FOURCC('a','5','2','b') ) && ( i_a52 <=                   p_dvd->p_vts_file->vtsi_mat->nr_of_vts_audio_streams ) )            {                i_a52++;            }            if( p_input->stream.pp_es[i_a52]->i_fourcc                 == VLC_FOURCC('a','5','2','b') )            {                input_SelectES( p_input, p_input->stream.pp_es[i_a52] );            }        }        else        {            input_SelectES( p_input, p_input->stream.pp_es[i_audio] );        }    }    /* for spu, default is none */    i_spu = config_GetInt( p_input, "spu-channel" );    if( i_spu < 0 /*|| i_spu > i_spu_nb*/ )    {        config_PutInt( p_input, "spu-channel", 0 );        i_spu = 0;    }    if( i_spu > 0 /*&& i_spu_nb > 0*/ )    {        i_spu += p_dvd->p_vts_file->vtsi_mat->nr_of_vts_audio_streams;        input_SelectES( p_input, p_input->stream.pp_es[i_spu] );    }}

⌨️ 快捷键说明

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