Beispiel #1
0
static int open_s(stream_t *stream,int mode, void* opts, int* file_format) {
  struct stream_priv_s* p = (struct stream_priv_s*)opts;
  char *filename;
  int event,len,tmplen=0;
  uint32_t pos, l2;
  dvdnav_priv_t *priv;
  dvdnav_status_t status;

  if(p->device) filename = p->device; 
  else if(dvd_device) filename= dvd_device; 
  else filename = DEFAULT_DVD_DEVICE;
  if(!(priv=new_dvdnav_stream(filename))) {
    mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_CantOpenDVD,filename);
    return STREAM_UNSUPORTED;
  }

  if(p->track > 0) {
    if(dvd_chapter > 0 && dvd_last_chapter > 0 && dvd_chapter > dvd_last_chapter) {
      mp_msg(MSGT_OPEN,MSGL_FATAL,"dvdnav_stream, invalid chapter range: %d > %d\n", dvd_chapter, dvd_last_chapter);
      return STREAM_UNSUPORTED;
    }
    priv->title = p->track;
    if(dvdnav_title_play(priv->dvdnav, p->track) != DVDNAV_STATUS_OK) {
      mp_msg(MSGT_OPEN,MSGL_FATAL,"dvdnav_stream, couldn't select title %d, error '%s'\n", p->track, dvdnav_err_to_string(priv->dvdnav));
      return STREAM_UNSUPORTED;
    }
    if(dvd_chapter > 0)
      dvdnav_part_play(priv->dvdnav, p->track, dvd_chapter);
  } else if(p->track == -1)
    dvdnav_menu_call(priv->dvdnav, DVD_MENU_Root);
  else {
    mp_msg(MSGT_OPEN,MSGL_INFO,"dvdnav_stream, you didn't specify a track number (as in dvdnav://1), playing whole disc\n");
    dvdnav_menu_call(priv->dvdnav, DVD_MENU_Title);
  }
  if(dvd_angle > 1)
    dvdnav_angle_change(priv->dvdnav, dvd_angle);

  stream->sector_size = 2048;
  stream->flags = STREAM_READ | STREAM_SEEK;
  stream->fill_buffer = fill_buffer;
  stream->seek = seek;
  stream->control = control;
  stream->close = stream_dvdnav_close;
  stream->type = STREAMTYPE_DVDNAV;
  stream->priv=(void*)priv;
  *file_format = DEMUXER_TYPE_MPEG_PS;

  update_title_len(stream);
  if(!stream->pos)
    mp_msg(MSGT_OPEN,MSGL_ERR, "INIT ERROR: %d, couldn't get init pos %s\r\n", status, dvdnav_err_to_string(priv->dvdnav));

  mp_msg(MSGT_OPEN,MSGL_INFO, "Remember to disable MPlayer's cache when playing dvdnav:// streams (adding -nocache to your command line)\r\n");

  return STREAM_OK;
}
Beispiel #2
0
static int control(stream_t *stream, int cmd, void* arg) {
  dvdnav_priv_t* priv=stream->priv;
  int tit, part;

  switch(cmd)
  {
    case STREAM_CTRL_SEEK_TO_CHAPTER:
    {
      int chap = *(unsigned int *)arg+1;

      if(chap < 1 || dvdnav_current_title_info(priv->dvdnav, &tit, &part) != DVDNAV_STATUS_OK)
        break;
      if(dvdnav_part_play(priv->dvdnav, tit, chap) != DVDNAV_STATUS_OK)
        break;
      return 1;
    }
    case STREAM_CTRL_GET_NUM_CHAPTERS:
    {
      if(dvdnav_current_title_info(priv->dvdnav, &tit, &part) != DVDNAV_STATUS_OK)
        break;
      if(dvdnav_get_number_of_parts(priv->dvdnav, tit, &part) != DVDNAV_STATUS_OK)
        break;
      if(!part)
        break;
      *(unsigned int *)arg = part;
      return 1;
    }
    case STREAM_CTRL_GET_CURRENT_CHAPTER:
    {
      if(dvdnav_current_title_info(priv->dvdnav, &tit, &part) != DVDNAV_STATUS_OK)
        break;
      *(unsigned int *)arg = part - 1;
      return 1;
    }
    case STREAM_CTRL_GET_TIME_LENGTH:
    {
      if(priv->duration || priv->still_length)
      {
        *(double *)arg = (double)priv->duration / 1000.0;
        return 1;
      }
      break;
    }
    case STREAM_CTRL_GET_ASPECT_RATIO:
    {
      uint8_t ar = dvdnav_get_video_aspect(priv->dvdnav);
      *(double *)arg = !ar ? 4.0/3.0 : 16.0/9.0;
      return 1;
    }
    case STREAM_CTRL_GET_CURRENT_TIME:
    {
      double tm;
      tm = dvdnav_get_current_time(priv->dvdnav)/90000.0f;
      if(tm != -1)
      {
        *(double *)arg = tm;
        return 1;
      }
      break;
    }
    case STREAM_CTRL_SEEK_TO_TIME:
    {
      uint64_t tm = *(double *)arg * 90000;
      if(dvdnav_time_search(priv->dvdnav, tm) == DVDNAV_STATUS_OK)
        return 1;
      break;
    }
    case STREAM_CTRL_GET_NUM_ANGLES:
    {
        uint32_t curr, angles;
        if(dvdnav_get_angle_info(priv->dvdnav, &curr, &angles) != DVDNAV_STATUS_OK)
          break;
        *(int *)arg = angles;
        return 1;
    }
    case STREAM_CTRL_GET_ANGLE:
    {
        uint32_t curr, angles;
        if(dvdnav_get_angle_info(priv->dvdnav, &curr, &angles) != DVDNAV_STATUS_OK)
          break;
        *(int *)arg = curr;
        return 1;
    }
    case STREAM_CTRL_SET_ANGLE:
    {
        uint32_t curr, angles;
        int new_angle = *(int *)arg;
        if(dvdnav_get_angle_info(priv->dvdnav, &curr, &angles) != DVDNAV_STATUS_OK)
          break;
        if(new_angle>angles || new_angle<1)
            break;
        if(dvdnav_angle_change(priv->dvdnav, new_angle) != DVDNAV_STATUS_OK)
        return 1;
    }
    case STREAM_CTRL_GET_LANG:
    {
        struct stream_lang_req *req = arg;
        int lang = 0;
        switch(req->type) {
        case stream_ctrl_audio:
            lang = mp_dvdnav_lang_from_aid(stream, req->id);
            break;
        case stream_ctrl_sub:
            lang = mp_dvdnav_lang_from_sid(stream, req->id);
            break;
        }
        if (!lang)
            break;
        req->buf[0] = lang >> 8;
        req->buf[1] = lang;
        req->buf[2] = 0;
        return STREAM_OK;
    }
  }

  return STREAM_UNSUPPORTED;
}