access.c

来自「VLC媒体播放程序」· C语言 代码 · 共 1,611 行 · 第 1/4 页

C
1,611
字号
            if( p_vcd->cur_lsn < p_vcd->p_entries[i_entry] )            {              VCDUpdateVar( p_input, i_entry, VLC_VAR_SETVALUE,                            "chapter", _("Entry"), "Setting entry" );              break;            }        }        p_vcd->play_item.num  = p_area->i_part = i_entry;        p_vcd->play_item.type = VCDINFO_ITEM_TYPE_ENTRY;    }#undef p_area    p_input->stream.p_selected_area->i_tell = i_off;    dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_SEEK),    "orig %d, cur: %d, offset: %lld, start: %lld, entry %d",               p_vcd->origin_lsn, p_vcd->cur_lsn, i_off,               p_input->stream.p_selected_area->i_start, i_entry );    vlc_mutex_unlock( &p_input->stream.stream_lock );}/*****************************************************************************  VCDPlay: set up internal structures so seeking/reading places an item.  itemid: the thing to play.  user_entry: true if itemid is a user selection (rather than internally-  generated selection such as via PBC) in which case we may have to adjust  for differences in numbering. *****************************************************************************/intVCDPlay( input_thread_t *p_input, vcdinfo_itemid_t itemid ){    thread_vcd_data_t *     p_vcd= (thread_vcd_data_t *)p_input->p_access_data;    input_area_t *          p_area;    bool                    b_was_still;    dbg_print(INPUT_DBG_CALL, "itemid.num: %d, itemid.type: %d\n",              itemid.num, itemid.type);    if (!p_input->p_access_data) return VLC_EGENERIC;        b_was_still = p_vcd->in_still;#define area p_input->stream.pp_areas    switch (itemid.type) {    case VCDINFO_ITEM_TYPE_TRACK:      /* Valid tracks go from 1...num_tracks-1, because track 0 is unplayable.       */      if (itemid.num == 0 || itemid.num >= p_vcd->num_tracks) {        LOG_ERR ("Invalid track number %d", itemid.num );        return VLC_EGENERIC;      }      p_vcd->in_still  = false;      p_area           = area[itemid.num];      p_area->i_part   = p_area->i_plugin_data;      p_input->stream.b_seekable = 1;      break;    case VCDINFO_ITEM_TYPE_SEGMENT:      /* Valid segments go from 0...num_segments-1. */      if (itemid.num >= p_vcd->num_segments) {        LOG_ERR ( "Invalid segment number: %d", itemid.num );        return VLC_EGENERIC;      } else {        vcdinfo_video_segment_type_t segtype =          vcdinfo_get_video_type(p_vcd->vcd, itemid.num);        dbg_print(INPUT_DBG_PBC, "%s (%d), seg_num: %d",                  vcdinfo_video_type2str(p_vcd->vcd, itemid.num),                  (int) segtype, itemid.num);        p_area           = area[0];        p_area->i_part   = itemid.num;        switch (segtype)          {          case VCDINFO_FILES_VIDEO_NTSC_STILL:          case VCDINFO_FILES_VIDEO_NTSC_STILL2:          case VCDINFO_FILES_VIDEO_PAL_STILL:          case VCDINFO_FILES_VIDEO_PAL_STILL2:            p_input->stream.b_seekable = 0;            p_vcd->in_still = true;            break;          default:            p_input->stream.b_seekable = 1;            p_vcd->in_still = false;          }      }      break;    case VCDINFO_ITEM_TYPE_LID:      /* LIDs go from 1..num_lids. */      if (itemid.num == 0 || itemid.num > p_vcd->num_lids) {        LOG_ERR ( "Invalid LID number: %d", itemid.num );        return VLC_EGENERIC;      } else {        p_vcd->cur_lid = itemid.num;        vcdinfo_lid_get_pxd(p_vcd->vcd, &(p_vcd->pxd), itemid.num);        switch (p_vcd->pxd.descriptor_type) {        case PSD_TYPE_SELECTION_LIST:        case PSD_TYPE_EXT_SELECTION_LIST: {          vcdinfo_itemid_t trans_itemid;          uint16_t trans_itemid_num;          if (p_vcd->pxd.psd == NULL) return VLC_EGENERIC;          trans_itemid_num  = vcdinf_psd_get_itemid(p_vcd->pxd.psd);          vcdinfo_classify_itemid(trans_itemid_num, &trans_itemid);          p_vcd->loop_count = 1;          p_vcd->loop_item  = trans_itemid;          return VCDPlay( p_input, trans_itemid );          break;        }        case PSD_TYPE_PLAY_LIST: {          if (p_vcd->pxd.pld == NULL) return VLC_EGENERIC;          p_vcd->pdi = -1;          return vcdplayer_inc_play_item(p_input)            ? VLC_SUCCESS : VLC_EGENERIC;          break;        }        case PSD_TYPE_END_LIST:        case PSD_TYPE_COMMAND_LIST:        default:          ;        }      }      return VLC_EGENERIC;    case VCDINFO_ITEM_TYPE_ENTRY:      /* Entries go from 0..num_entries-1. */      if (itemid.num >= p_vcd->num_entries) {        LOG_ERR ("Invalid entry number: %d", itemid.num );        return VLC_EGENERIC;      } else {        track_t cur_track  = vcdinfo_get_track(p_vcd->vcd,  itemid.num);        p_vcd->in_still    = false;        p_area             = area[cur_track];        p_area->i_part     = itemid.num;        p_input->stream.b_seekable = 1;      }      break;    default:      LOG_ERR ("unknown entry type" );      return VLC_EGENERIC;    }    VCDSetArea( p_input, p_area );#undef area#if 1    if ( p_vcd->in_still != b_was_still ) {      if (p_input->stream.pp_selected_es) {	input_SetStatus( p_input, INPUT_STATUS_END );	input_SetStatus( p_input, INPUT_STATUS_PLAY );      }    }#endif    p_vcd->play_item = itemid;    dbg_print( (INPUT_DBG_CALL),               "i_start %lld, i_size: %lld, i_tell: %lld, lsn %d",               p_area->i_start, p_area->i_size,               p_area->i_tell, p_vcd->cur_lsn );    return VLC_SUCCESS;}/*****************************************************************************  VCDEntryPoints: Reads the information about the entry points on the disc  and initializes area information with that.  Before calling this track information should have been read in. *****************************************************************************/static intVCDEntryPoints( input_thread_t * p_input ){    thread_vcd_data_t *               p_vcd;    unsigned int                      i_nb;    unsigned int                      i, i_entry_index = 0;    unsigned int                      i_previous_track = CDIO_INVALID_TRACK;    p_vcd = (thread_vcd_data_t *) p_input->p_access_data;    i_nb = vcdinfo_get_num_entries(p_vcd->vcd);    if (0 == i_nb)      return -1;    p_vcd->p_entries  = malloc( sizeof( lba_t ) * i_nb );    if( p_vcd->p_entries == NULL )    {        LOG_ERR ("not enough memory for entry points treatment" );        return -1;    }    p_vcd->num_entries = 0;    for( i = 0 ; i < i_nb ; i++ )    {        track_t i_track = vcdinfo_get_track(p_vcd->vcd, i);        if( i_track <= p_input->stream.i_area_nb )        {            p_vcd->p_entries[i] =              vcdinfo_get_entry_lsn(p_vcd->vcd, i);            p_input->stream.pp_areas[i_track]->i_part_nb ++;            /* if this entry belongs to a new track */            if( i_track != i_previous_track )            {                /* i_plugin_data is used to store the first entry of the area*/                p_input->stream.pp_areas[i_track]->i_plugin_data =                                                            i_entry_index;                i_previous_track = i_track;                p_input->stream.pp_areas[i_track]->i_part_nb = 1;            }            i_entry_index ++;            p_vcd->num_entries ++;        }        else            msg_Warn( p_input, "wrong track number found in entry points" );    }    p_vcd->b_valid_ep = true;    return 0;}/***************************************************************************** * VCDSegments: Reads the information about the segments the disc. *****************************************************************************/static intVCDSegments( input_thread_t * p_input ){    thread_vcd_data_t * p_vcd;    unsigned int        i;    unsigned int        num_segments;    p_vcd = (thread_vcd_data_t *) p_input->p_access_data;    num_segments = p_vcd->num_segments = vcdinfo_get_num_segments(p_vcd->vcd);#define area p_input->stream.pp_areas    /* area 0 is reserved for segments. Set Absolute start offset         and size */    area[0]->i_plugin_data = 0;    input_DelArea( p_input, area[0] );    input_AddArea( p_input, 0, 0 );    area[0]->i_start = (off_t)p_vcd->p_sectors[0]      * (off_t)M2F2_SECTOR_SIZE;    area[0]->i_size = (off_t)(p_vcd->p_sectors[1] - p_vcd->p_sectors[0])      * (off_t)M2F2_SECTOR_SIZE;    /* Default Segment  */    area[0]->i_part = 0;    /* i_plugin_data is used to store which entry point is the first       of the track (area) */    area[0]->i_plugin_data = 0;    area[0]->i_part_nb = 0;    dbg_print( INPUT_DBG_MRL,               "area[0] id: %d, i_start: %lld, i_size: %lld",               area[0]->i_id, area[0]->i_start, area[0]->i_size );    if (num_segments == 0) return 0;    /* We have one additional segment allocated so we can get the size       by subtracting seg[i+1] - seg[i].     */    p_vcd->p_segments = malloc( sizeof( lba_t ) * (num_segments+1) );    if( p_vcd->p_segments == NULL )    {        LOG_ERR ("not enough memory for segment treatment" );        return -1;    }    /* Update the navigation variables without triggering a callback */    VCDUpdateVar( p_input, 0, VLC_VAR_SETVALUE, "title", _("Track"),		  "Setting track" );    var_Change( p_input, "chapter", VLC_VAR_CLEARCHOICES, NULL, NULL );    for( i = 0 ; i < num_segments ; i++ )    {      p_vcd->p_segments[i] = vcdinfo_get_seg_lsn(p_vcd->vcd, i);      area[0]->i_part_nb ++;      VCDUpdateVar( p_input, i , VLC_VAR_ADDCHOICE,                    "chapter", _("Segment"), "Adding segment choice");    }#undef area    p_vcd->p_segments[num_segments] = p_vcd->p_segments[num_segments-1]+      vcdinfo_get_seg_sector_count(p_vcd->vcd, num_segments-1);    return 0;}/***************************************************************************** VCDTracks: initializes area information. Before calling this track information should have been read in. *****************************************************************************/static voidVCDTracks( input_thread_t * p_input ){    thread_vcd_data_t * p_vcd;    unsigned int        i;    p_vcd = (thread_vcd_data_t *) p_input->p_access_data;#define area p_input->stream.pp_areas    /* We start area addressing for tracks at 1 since the default area 0       is reserved for segments */    for( i = 1 ; i < p_vcd->num_tracks ; i++ )    {        /* Tracks are Program Chains */        input_AddArea( p_input, i, i );        /* Absolute start byte offset and byte size */        area[i]->i_start = (off_t) p_vcd->p_sectors[i]                           * (off_t)M2F2_SECTOR_SIZE;        area[i]->i_size = (off_t)(p_vcd->p_sectors[i+1] - p_vcd->p_sectors[i])                           * (off_t)M2F2_SECTOR_SIZE;        /* Current entry being played in track */        area[i]->i_part = 0;        /* i_plugin_data is used to store which entry point is the first         * of the track (area) */        area[i]->i_plugin_data = 0;        dbg_print( INPUT_DBG_MRL,                   "area[%d] id: %d, i_start: %lld, i_size: %lld",                   i, area[i]->i_id, area[i]->i_start, area[i]->i_size );    }#undef area    return ;}/*****************************************************************************  VCDLIDs: Reads the LIST IDs from the LOT. *****************************************************************************/static intVCDLIDs( input_thread_t * p_input ){    thread_vcd_data_t *p_vcd = (thread_vcd_data_t *) p_input->p_access_data;    p_vcd->num_lids = vcdinfo_get_num_LIDs(p_vcd->vcd);    p_vcd->cur_lid  = VCDINFO_INVALID_ENTRY;    if (vcdinfo_read_psd (p_vcd->vcd)) {      vcdinfo_visit_lot (p_vcd->vcd, false);#if FIXED    /*       We need to change libvcdinfo to be more robust when there are       problems reading the extended PSD. Given that area-highlighting and       selection features in the extended PSD haven't been implemented,       it's best then to not try to read this at all.     */      if (vcdinfo_get_psd_x_size(p_vcd->vcd))        vcdinfo_visit_lot (p_vcd->vcd, true);#endif    }    dbg_print( (INPUT_DBG_CALL|INPUT_DBG_MRL),               "num LIDs=%d", p_vcd->num_lids);    return 0;}/***************************************************************************** * VCDParse: parse command line *****************************************************************************/static char *VCDParse( input_thread_t * p_input, /*out*/ vcdinfo_itemid_t * p_itemid,          /*out*/ bool *play_single_item ){    thread_vcd_data_t *p_vcd = (thread_vcd_data_t *)p_input->p_access_data;    char *             psz_parser;    char *             psz_source;    char *             psz_next;    if ( config_GetInt( p_input, MODULE_STRING "-PBC" ) ) {      p_itemid->type=VCDINFO_ITEM_TYPE_LID;      p_itemid->num=1;      *play_single_item=false;    } else {      p_itemid->type=VCDINFO_ITEM_TYPE_ENTRY;      p_itemid->num=0;    }

⌨️ 快捷键说明

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