Beispiel #1
0
Datei: access.c Projekt: BtbN/vlc
/*****************************************************************************
  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 bool
VCDEntryPoints( access_t * p_access )
{
    if (!p_access || !p_access->p_sys) return false;
 
    vcdplayer_t       *p_vcdplayer = (vcdplayer_t *) p_access->p_sys;
    const unsigned int i_entries   = vcdinfo_get_num_entries(p_vcdplayer->vcd);
    const track_t      i_last_track
           = cdio_get_num_tracks(vcdinfo_get_cd_image(p_vcdplayer->vcd))
           + cdio_get_first_track_num(vcdinfo_get_cd_image(p_vcdplayer->vcd));
    unsigned int i;
 
    if (0 == i_entries) {
        LOG_ERR ("no entires found -- something is wrong" );
        return false;
    }
 
    p_vcdplayer->p_entries  = malloc( sizeof( lsn_t ) * i_entries );
 
    if( p_vcdplayer->p_entries == NULL )
    {
        LOG_ERR ("not enough memory for entry points treatment" );
        return false;
    }
 
    p_vcdplayer->i_entries = i_entries;
 
    for( i = 0 ; i < i_entries ; i++ )
    {
        const track_t i_track = vcdinfo_get_track(p_vcdplayer->vcd, i);
        if( i_track <= i_last_track )
        {
            seekpoint_t *s = vlc_seekpoint_New();
            char psz_entry[100];
    
            snprintf(psz_entry, sizeof(psz_entry), "%s %02d", _("Entry"), i );

            p_vcdplayer->p_entries[i] =
                                   vcdinfo_get_entry_lsn(p_vcdplayer->vcd, i);
    
            s->psz_name      = strdup(psz_entry);
            s->i_byte_offset = (p_vcdplayer->p_entries[i]
                             - vcdinfo_get_track_lsn(p_vcdplayer->vcd,i_track))
                             * M2F2_SECTOR_SIZE;
    
            dbg_print( INPUT_DBG_MRL, "%s, lsn %d,  byte_offset %"PRId64"",
                       s->psz_name, p_vcdplayer->p_entries[i],
                       s->i_byte_offset);
            TAB_APPEND( p_vcdplayer->p_title[i_track-1]->i_seekpoint,
                        p_vcdplayer->p_title[i_track-1]->seekpoint, s );

        } else
            msg_Warn( p_access, "wrong track number found in entry points" );
    }
    p_vcdplayer->b_valid_ep = true;
    return true;
}
Beispiel #2
0
/*!
  Set reading to play an entry
*/
static void
_vcdplayer_set_entry(access_t * p_access, unsigned int num)
{
  vcdplayer_t   *p_vcdplayer = (vcdplayer_t *)p_access->p_sys;
  vcdinfo_obj_t *p_vcdinfo   = p_vcdplayer->vcd;
  const unsigned int   i_entries = vcdinfo_get_num_entries(p_vcdinfo);

  if (num >= i_entries) {
    LOG_ERR("%s %d", "bad entry number", num);
    return;
  } else {
    vcdinfo_itemid_t itemid;

    itemid.num            = num;
    itemid.type           = VCDINFO_ITEM_TYPE_ENTRY;
    p_vcdplayer->i_still  = 0;

    VCDSetOrigin(p_access, vcdinfo_get_entry_lsn(p_vcdinfo, num),
        vcdinfo_get_track(p_vcdinfo, num), &itemid);

    dbg_print(INPUT_DBG_LSN, "LSN: %u, track_end LSN: %u",
              p_vcdplayer->i_lsn, p_vcdplayer->track_end_lsn);
  }
}
Beispiel #3
0
Datei: access.c Projekt: BtbN/vlc
/*****************************************************************************
 * vcd_Open: Opens a VCD device or file initializes, a list of
   tracks, segements and entry lsns and sizes and returns an opaque handle.
 *****************************************************************************/
static vcdinfo_obj_t *
vcd_Open( vlc_object_t *p_this, const char *psz_dev )
{
    access_t    *p_access = (access_t *)p_this;
    vcdplayer_t *p_vcdplayer    = (vcdplayer_t *) p_access->p_sys;
    vcdinfo_obj_t *p_vcdobj;
    char  *actual_dev;
    unsigned int i;

    dbg_print(INPUT_DBG_CALL, "called with %s", psz_dev);

    if( !psz_dev ) return NULL;

    actual_dev= ToLocaleDup(psz_dev);
    if( vcdinfo_open(&p_vcdobj, &actual_dev, DRIVER_UNKNOWN, NULL) !=
                                                    VCDINFO_OPEN_VCD)
    {
        free(actual_dev);
        return NULL;
    }
    free(actual_dev);

    /*
       Save summary info on tracks, segments and entries...
    */

    if ( 0 < (p_vcdplayer->i_tracks = vcdinfo_get_num_tracks(p_vcdobj)) )
    {
        p_vcdplayer->track = (vcdplayer_play_item_info_t *)
          calloc(p_vcdplayer->i_tracks, sizeof(vcdplayer_play_item_info_t));

        for (i=0; i<p_vcdplayer->i_tracks; i++)
        {
            unsigned int track_num=i+1;
            p_vcdplayer->track[i].size  =
            vcdinfo_get_track_sect_count(p_vcdobj, track_num);
            p_vcdplayer->track[i].start_LSN =
            vcdinfo_get_track_lsn(p_vcdobj, track_num);
        }
    } else
        p_vcdplayer->track = NULL;

    if( 0 < (p_vcdplayer->i_entries = vcdinfo_get_num_entries(p_vcdobj)) )
    {
        p_vcdplayer->entry = (vcdplayer_play_item_info_t *)
            calloc(p_vcdplayer->i_entries, sizeof(vcdplayer_play_item_info_t));

        for (i=0; i<p_vcdplayer->i_entries; i++)
        {
            p_vcdplayer->entry[i].size =
                                    vcdinfo_get_entry_sect_count(p_vcdobj, i);
            p_vcdplayer->entry[i].start_LSN =
                                           vcdinfo_get_entry_lsn(p_vcdobj, i);
        }
    } else
      p_vcdplayer->entry = NULL;

    if ( 0 < (p_vcdplayer->i_segments = vcdinfo_get_num_segments(p_vcdobj)) )
    {
        p_vcdplayer->segment = (vcdplayer_play_item_info_t *)
          calloc(p_vcdplayer->i_segments,  sizeof(vcdplayer_play_item_info_t));

        for (i=0; i<p_vcdplayer->i_segments; i++)
        {
            p_vcdplayer->segment[i].size =
                                    vcdinfo_get_seg_sector_count(p_vcdobj, i);
            p_vcdplayer->segment[i].start_LSN =
                                             vcdinfo_get_seg_lsn(p_vcdobj, i);
        }
    } else
      p_vcdplayer->segment = NULL;

    return p_vcdobj;
}
Beispiel #4
0
Datei: access.c Projekt: BtbN/vlc
/*****************************************************************************
  VCDRead: reads VCD_BLOCKS_ONCE from the VCD and returns that.
  NULL is returned if something went wrong.
 *****************************************************************************/
static block_t *
VCDReadBlock( access_t * p_access )
{
    vcdplayer_t *p_vcdplayer= (vcdplayer_t *)p_access->p_sys;
    const int    i_blocks   = p_vcdplayer->i_blocks_per_read;
    block_t     *p_block;
    int          i_read;
    uint8_t     *p_buf;

    dbg_print( (INPUT_DBG_LSN), "lsn: %lu",
               (long unsigned int) p_vcdplayer->i_lsn );

    /* Allocate a block for the reading */
    if( !( p_block = block_Alloc( i_blocks * M2F2_SECTOR_SIZE ) ) )
    {
        msg_Err( p_access, "cannot get a new block of size: %i",
                 i_blocks * M2F2_SECTOR_SIZE );
        block_Release( p_block );
        return NULL;
    }

    p_buf = (uint8_t *) p_block->p_buffer;
    for ( i_read = 0 ; i_read < i_blocks ; i_read++ )
    {
        vcdplayer_read_status_t read_status = vcdplayer_read(p_access, p_buf);

        p_access->info.i_pos += M2F2_SECTOR_SIZE;

        switch ( read_status ) {
        case READ_END:
            /* End reached. Return NULL to indicated this. */
            /* We also set the postion to the end so the higher level
               (demux?) doesn't try to keep reading. If everything works out
               right this shouldn't have to happen.
             */
#if 0
            if( p_access->info.i_pos != p_access->info.i_size ) {
                msg_Warn( p_access,
                    "At end but pos (%llu) is not size (%llu). Adjusting.",
                    p_access->info.i_pos, p_access->info.i_size );
                p_access->info.i_pos = p_access->info.i_size;
            }
#endif

            block_Release( p_block );
            return NULL;

        case READ_ERROR:
            /* Some sort of error. Should we increment lsn? to skip block? */
            block_Release( p_block );
            return NULL;
        case READ_STILL_FRAME:
          /* FIXME The below should be done in an event thread.
             Until then...
           */
#if 1
            msleep( INT64_C(1000) * *p_buf );
            VCDSetOrigin(p_access, p_vcdplayer->origin_lsn,
                         p_vcdplayer->i_track, &(p_vcdplayer->play_item));
            // p_vcd->in_still = false;
            dbg_print(INPUT_DBG_STILL, "still wait time done");
#endif

            block_Release( p_block );
            return NULL;

        default:
        case READ_BLOCK:
            /* Read buffer */
            break;
        }

        p_buf += M2F2_SECTOR_SIZE;
        /* Update seekpoint */
        if ( VCDINFO_ITEM_TYPE_ENTRY == p_vcdplayer->play_item.type )
        {
            size_t i_entry = p_vcdplayer->play_item.num+1;
            lsn_t  i_lsn   = vcdinfo_get_entry_lsn(p_vcdplayer->vcd, i_entry);
            if ( p_vcdplayer->i_lsn >= i_lsn && i_lsn != VCDINFO_NULL_LSN )
            {
                dbg_print( (INPUT_DBG_LSN|INPUT_DBG_PBC),
                           "entry change to %zu, current LSN %u >= end %u",
                           i_entry, p_vcdplayer->i_lsn, i_lsn);

                p_vcdplayer->play_item.num = i_entry;

                VCDSetOrigin( p_access,  i_lsn, p_vcdplayer->i_track,
                              &(p_vcdplayer->play_item) );
            }
        }
    }

    return p_block;
}