Пример #1
0
static void list_chapters(ifo_handle_t *vts_file, tt_srpt_t *tt_srpt, int title_no)
{
    unsigned int i, cell, last_cell;
    unsigned int t=0, t2=0;
    ptt_info_t *ptt;
    pgc_t *pgc;

    title_no = tt_srpt->title[title_no].vts_ttn - 1;
    if(vts_file->vts_ptt_srpt->title[title_no].nr_of_ptts < 2)
       return;
    ptt = vts_file->vts_ptt_srpt->title[title_no].ptt;

    mp_msg(MSGT_IDENTIFY, MSGL_INFO, "CHAPTERS: ");
    for(i=0; i<vts_file->vts_ptt_srpt->title[title_no].nr_of_ptts; i++)
    {
        pgc = vts_file->vts_pgcit->pgci_srp[ptt[i].pgcn-1].pgc;
        cell = pgc->program_map[ptt[i].pgn-1]; //here the cell is 1-based
        if(ptt[i].pgn<pgc->nr_of_programs)
            last_cell = pgc->program_map[ptt[i].pgn];
        else
            last_cell = 0;
        t2 = t/1000;
        mp_msg(MSGT_IDENTIFY, MSGL_INFO, "%02d:%02d:%02d,", t2/3600, (t2/60)%60, t2%60);
        do {
            if(!(pgc->cell_playback[cell-1].block_type == BLOCK_TYPE_ANGLE_BLOCK &&
                 pgc->cell_playback[cell-1].block_mode != BLOCK_MODE_FIRST_CELL)
            )
                t += mp_dvdtimetomsec(&pgc->cell_playback[cell-1].playback_time);
            cell++;
        } while(cell < last_cell);
    }
    mp_msg(MSGT_IDENTIFY, MSGL_INFO, "\n");
}
Пример #2
0
static double dvd_get_current_time(stream_t *stream, int cell)
{
    int i, tm;
    dvd_priv_t *d = stream->priv;

    tm=0;
    if(cell < 0) cell=d->cur_cell;
    for(i=0; i<cell; i++) {
        if(d->cur_pgc->cell_playback[i].block_type == BLOCK_TYPE_ANGLE_BLOCK &&
           d->cur_pgc->cell_playback[i].block_mode != BLOCK_MODE_FIRST_CELL
        )
          continue;
        tm += d->cell_times_table[i];
    }
    tm += mp_dvdtimetomsec(&d->dsi_pack.dsi_gi.c_eltm);

    return (double)tm/1000.0;
}
Пример #3
0
static int mp_get_titleset_length(ifo_handle_t *vts_file, tt_srpt_t *tt_srpt, int title_no)
{
    int vts_ttn;  ///< title number within video title set
    int pgc_no;   ///< program chain number
    int msec;     ///< time length in milliseconds

    msec=0;
    if(!vts_file || !tt_srpt)
        return 0;

    if(vts_file->vtsi_mat && vts_file->vts_pgcit)
    {
            vts_ttn = tt_srpt->title[title_no].vts_ttn - 1;
            pgc_no = vts_file->vts_ptt_srpt->title[vts_ttn].ptt[0].pgcn - 1;
            msec = mp_dvdtimetomsec(&vts_file->vts_pgcit->pgci_srp[pgc_no].pgc->playback_time);
    }
    return msec;
}
Пример #4
0
// p: in=chapter number, out=PTS
static int get_chapter_time(ifo_handle_t *vts_file, tt_srpt_t *tt_srpt, int title_no, double *p)
{
    unsigned int i, cell, last_cell;
    unsigned int t=0;
    ptt_info_t *ptt;
    pgc_t *pgc;

    title_no = tt_srpt->title[title_no].vts_ttn - 1;
    if(vts_file->vts_ptt_srpt->title[title_no].nr_of_ptts < 2)
       return 0;
    ptt = vts_file->vts_ptt_srpt->title[title_no].ptt;

    int cur = 0;
    for(i=0; i<vts_file->vts_ptt_srpt->title[title_no].nr_of_ptts; i++)
    {
        pgc = vts_file->vts_pgcit->pgci_srp[ptt[i].pgcn-1].pgc;
        cell = pgc->program_map[ptt[i].pgn-1]; //here the cell is 1-based
        if(ptt[i].pgn<pgc->nr_of_programs)
            last_cell = pgc->program_map[ptt[i].pgn];
        else
            last_cell = 0;
        while (cell < last_cell) {
            if(!(pgc->cell_playback[cell-1].block_type == BLOCK_TYPE_ANGLE_BLOCK &&
                 pgc->cell_playback[cell-1].block_mode != BLOCK_MODE_FIRST_CELL)
            ) {
                if (cur == *p) {
                    *p = t / 1000.0;
                    return 1;
                }
                t += mp_dvdtimetomsec(&pgc->cell_playback[cell-1].playback_time);
                cur++;
            }
            cell++;
        }
    }
    return 0;
}
Пример #5
0
static int dvd_seek_to_time(stream_t *stream, ifo_handle_t *vts_file, double sec)
{
    unsigned int i, j, k, timeunit, ac_time, tmap_sector=0, cell_sector=0, vobu_sector=0;
    int t=0;
    double tm, duration;
    int64_t pos = -1;
    dvd_priv_t *d = stream->priv;
    vts_tmapt_t *vts_tmapt = vts_file->vts_tmapt;

    if(!vts_file->vts_tmapt || sec < 0)
        return 0;

    duration = (double) mp_get_titleset_length(d->vts_file, d->tt_srpt, d->cur_title) / 1000.0f;
    if(sec > duration)
      return 0;

    i=d->cur_pgc_idx;
    timeunit = vts_tmapt->tmap[i].tmu;
    for(j = 0; j < vts_tmapt->tmap[i].nr_of_entries; j++) {
      ac_time = timeunit * (j + 1);
      if(ac_time >= sec)
        break;
      tmap_sector = vts_tmapt->tmap[i].map_ent[j] & 0x7fffffff;
    }
    //search enclosing cell
    for(i=0; i<d->cur_pgc->nr_of_cells; i++) {
      if(tmap_sector >= d->cur_pgc->cell_playback[i].first_sector && tmap_sector <= d->cur_pgc->cell_playback[i].last_sector) {
        cell_sector = d->cur_pgc->cell_playback[i].first_sector;
        break;
      }
    }

    pos = ((int64_t)cell_sector)<<11;
    do_seek(stream, pos);
    do {
      char buf[2048];
      if (dvd_read_sector(stream, stream->priv, buf) < 0) // skip
          break;
      t = mp_dvdtimetomsec(&d->dsi_pack.dsi_gi.c_eltm);
    } while(!t);
    tm = dvd_get_current_time(stream, -1);

    pos = ((int64_t)tmap_sector)<<11;
    do_seek(stream, pos);
    //now get current time in terms of the cell+cell time offset
    memset(&d->dsi_pack.dsi_gi.c_eltm, 0, sizeof(dvd_time_t));
    while(tm <= sec) {
        char buf[2048];
        if (dvd_read_sector(stream, stream->priv, buf) < 0) // skip
            break;
        pos += 2048;
        tm = dvd_get_current_time(stream, -1);
    };
    tmap_sector = pos >> 11;

    //search closest VOBU sector
    k=(vts_file->vts_vobu_admap->last_byte + 1 - VOBU_ADMAP_SIZE)/4; //entries in the vobu admap
    for(i=1; i<k; i++) {
      if(vts_file->vts_vobu_admap->vobu_start_sectors[i] > tmap_sector)
        break;
    }
    vobu_sector = vts_file->vts_vobu_admap->vobu_start_sectors[i-1];
    pos = ((int64_t)vobu_sector) << 11;
    do_seek(stream, pos);

    return 1;
}
Пример #6
0
static int dvdnav_stream_read(dvdnav_priv_t * priv, unsigned char *buf, int *len) {
  int event = DVDNAV_NOP;

  *len=-1;
  if (dvdnav_get_next_block(priv->dvdnav,buf,&event,len)!=DVDNAV_STATUS_OK) {
    mp_msg(MSGT_OPEN,MSGL_V, "Error getting next block from DVD %d (%s)\n",event, dvdnav_err_to_string(priv->dvdnav) );
    *len=-1;
  }
  else if (event!=DVDNAV_BLOCK_OK) {
    // need to handle certain events internally (like skipping stills)
    switch (event) {
      case DVDNAV_NAV_PACKET:
        return event;
      case DVDNAV_STILL_FRAME: {
        dvdnav_still_event_t *still_event = (dvdnav_still_event_t *) buf;
        priv->still_length = still_event->length;
        /* set still frame duration */
        priv->duration = dvdnav_get_duration (priv->still_length);
        if (priv->still_length <= 1) {
          pci_t *pnavpci = dvdnav_get_current_nav_pci (priv->dvdnav);
          priv->duration = mp_dvdtimetomsec (&pnavpci->pci_gi.e_eltm);
        }
        break;
      }
      case DVDNAV_HIGHLIGHT: {
        dvdnav_get_highlight (priv, 1);
        break;
      }
      case DVDNAV_CELL_CHANGE: {
        dvdnav_cell_change_event_t *ev =  (dvdnav_cell_change_event_t*)buf;
        uint32_t nextstill;

        priv->state &= ~NAV_FLAG_WAIT_SKIP;
        priv->state |= NAV_FLAG_STREAM_CHANGE;
        if(ev->pgc_length)
          priv->duration = ev->pgc_length/90;

        if (dvdnav_is_domain_vts(priv->dvdnav)) {
          mp_msg(MSGT_IDENTIFY, MSGL_INFO, "DVDNAV_TITLE_IS_MOVIE\n");
          priv->state &= ~NAV_FLAG_VTS_DOMAIN;
        } else {
          mp_msg(MSGT_IDENTIFY, MSGL_INFO, "DVDNAV_TITLE_IS_MENU\n");
          priv->state |= NAV_FLAG_VTS_DOMAIN;
        }

        nextstill = dvdnav_get_next_still_flag (priv->dvdnav);
        if (nextstill) {
          priv->duration = dvdnav_get_duration (nextstill);
          priv->still_length = nextstill;
          if (priv->still_length <= 1) {
            pci_t *pnavpci = dvdnav_get_current_nav_pci (priv->dvdnav);
            priv->duration = mp_dvdtimetomsec (&pnavpci->pci_gi.e_eltm);
          }
        }

        break;
      }
      case DVDNAV_SPU_CLUT_CHANGE: {
        memcpy(priv->spu_clut, buf, 16*sizeof(unsigned int));
        priv->state |= NAV_FLAG_SPU_SET;
        break;
      }
      case DVDNAV_WAIT: {
        if ((priv->state & NAV_FLAG_WAIT_SKIP) &&
            !(priv->state & NAV_FLAG_WAIT))
          dvdnav_wait_skip (priv->dvdnav);
        else
          priv->state |= NAV_FLAG_WAIT;
        break;
      }
      case DVDNAV_VTS_CHANGE: {
        priv->state &= ~NAV_FLAG_WAIT_SKIP;
        priv->state |= NAV_FLAG_STREAM_CHANGE;
        break;
      }
      case DVDNAV_SPU_STREAM_CHANGE: {
        priv->state |= NAV_FLAG_STREAM_CHANGE;
        break;
      }
    }

    *len=0;
  }
  return event;
}