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

📄 stream_dvd.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 3 页
字号:
#include <ctype.h>#include <mplaylib.h>#include <mplaylib.h>#include <mplaylib.h>#include <mplaylib.h>#include <fcntl.h>#include <mplaylib.h>#include "config.h"#include "mp_msg.h"#include "help_mp.h"#ifdef __FreeBSD__#include <sys/cdrio.h>#endif#ifdef __linux__#include <linux/cdrom.h>#include <scsi/sg.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#endif#define FIRST_AC3_AID 128#define FIRST_DTS_AID 136#define FIRST_MPG_AID 0#define FIRST_PCM_AID 160#include "stream.h"#include "m_option.h"#include "m_struct.h"#include "stream_dvd.h"#include "stream_dvd_common.h"#include "libmpdemux/demuxer.h"#undef memcpy#define memcpy uc_memcpyextern int stream_cache_size;extern char* dvd_device;int dvd_angle=1;int dvd_speed=0; /* 0 => don't touch speed */static void dvd_set_speed(char *device, unsigned speed){#if defined(__linux__) && defined(SG_IO) && defined(GPCMD_SET_STREAMING)  int fd;  unsigned char buffer[28];  unsigned char cmd[16];  unsigned char sense[16];  struct sg_io_hdr sghdr;  struct stat st;  memset(&sghdr, 0, sizeof(sghdr));  memset(buffer, 0, sizeof(buffer));  memset(sense, 0, sizeof(sense));  memset(cmd, 0, sizeof(cmd));  memset(&st, 0, sizeof(st));  if (stat(device, &st) == -1) return;  if (!S_ISBLK(st.st_mode)) return; /* not a block device */  if ((fd = open(device, O_RDWR | O_NONBLOCK,-1)) == -1) {    mp_msg(MSGT_OPEN, MSGL_INFO, MSGTR_DVDspeedCantOpen);    return;  }  if (speed < 100) { /* speed times 1350KB/s (DVD single speed) */    speed *= 1350;  }  switch (speed) {  case 0: /* don't touch speed setting */    return;  case -1: /* restore default value */    if (dvd_speed == 0) return; /* we haven't touched the speed setting */    speed = 0;    buffer[0] = 4; /* restore default */    mp_msg(MSGT_OPEN, MSGL_INFO, MSGTR_DVDrestoreSpeed);    break;  default: /* limit to <speed> KB/s */    mp_msg(MSGT_OPEN, MSGL_INFO, MSGTR_DVDlimitSpeed, speed);    break;  }  sghdr.interface_id = 'S';  sghdr.timeout = 5000;  sghdr.dxfer_direction = SG_DXFER_TO_DEV;  sghdr.mx_sb_len = sizeof(sense);  sghdr.dxfer_len = sizeof(buffer);  sghdr.cmd_len = sizeof(cmd);  sghdr.sbp = sense;  sghdr.dxferp = buffer;  sghdr.cmdp = cmd;  cmd[0] = GPCMD_SET_STREAMING;  cmd[10] = sizeof(buffer);  buffer[8] = 0xff;  /* first sector 0, last sector 0xffffffff */  buffer[9] = 0xff;  buffer[10] = 0xff;  buffer[11] = 0xff;  buffer[12] = buffer[20] = (speed >> 24) & 0xff; /* <speed> kilobyte */  buffer[13] = buffer[21] = (speed >> 16) & 0xff;  buffer[14] = buffer[22] = (speed >> 8)  & 0xff;  buffer[15] = buffer[23] = speed & 0xff;  buffer[18] = buffer[26] = 0x03; /* 1 second */  buffer[19] = buffer[27] = 0xe8;  if (ioctl(fd, SG_IO, &sghdr) < 0) {    mp_msg(MSGT_OPEN, MSGL_INFO, MSGTR_DVDlimitFail);  }  mp_msg(MSGT_OPEN, MSGL_INFO, MSGTR_DVDlimitOk);#endif}#define	LIBDVDREAD_VERSION(maj,min,micro)	((maj)*10000 + (min)*100 + (micro))/* * Try to autodetect the libdvd-0.9.0 library * (0.9.0 removed the <dvdread/dvd_udf.h> header, and moved the two defines * DVD_VIDEO_LB_LEN and MAX_UDF_FILE_NAME_LEN from it to * <dvdread/dvd_reader.h>) */#ifndef DVDREAD_VERSION#if defined(DVD_VIDEO_LB_LEN) && defined(MAX_UDF_FILE_NAME_LEN)#define	DVDREAD_VERSION	LIBDVDREAD_VERSION(0,9,0)#else#define	DVDREAD_VERSION	LIBDVDREAD_VERSION(0,8,0)#endif#endifchar * dvd_audio_stream_types[8] = { "ac3","unknown","mpeg1","mpeg2ext","lpcm","unknown","dts" };char * dvd_audio_stream_channels[6] = { "mono", "stereo", "unknown", "unknown", "5.1/6.1", "5.1" };static struct stream_priv_s {  int title;} stream_priv_dflts = {  1};#define ST_OFF(f) M_ST_OFF(struct stream_priv_s,f)/// URL definitionstatic m_option_t stream_opts_fields[] = {  { "hostname", ST_OFF(title), CONF_TYPE_INT, M_OPT_MIN, 1, 0, NULL },  { NULL, NULL, 0, 0, 0, 0,  NULL }};static struct m_struct_st stream_opts = {  "dvd",  sizeof(struct stream_priv_s),  &stream_priv_dflts,  stream_opts_fields};int dvd_parse_chapter_range(m_option_t *conf, const char *range) {  const char *s;  char *t;  if (!range)    return M_OPT_MISSING_PARAM;  s = range;  dvd_chapter = 1;  dvd_last_chapter = 0;  if(*range && isdigit(*range)) {    dvd_chapter = strtol(range, &s, 10);    if(range == s) {      mp_msg(MSGT_OPEN, MSGL_ERR, MSGTR_DVDinvalidChapterRange, range);      return M_OPT_INVALID;    }  }  if(*s == 0)    return 0;  else if(*s != '-') {    mp_msg(MSGT_OPEN, MSGL_ERR, MSGTR_DVDinvalidChapterRange, range);    return M_OPT_INVALID;  }  ++s;  if(*s == 0)      return 0;  if(! isdigit(*s)) {    mp_msg(MSGT_OPEN, MSGL_ERR, MSGTR_DVDinvalidChapterRange, range);    return M_OPT_INVALID;  }  dvd_last_chapter = strtol(s, &t, 10);  if (s == t || *t) {    mp_msg(MSGT_OPEN, MSGL_ERR, MSGTR_DVDinvalidChapterRange, range);    return M_OPT_INVALID;  }  return 0;}int dvd_chapter_from_cell(dvd_priv_t* dvd,int title,int cell){  pgc_t * cur_pgc;  ptt_info_t* ptt;  int chapter = cell;  int pgc_id,pgn;  if(title < 0 || cell < 0){    return 0;  }  /* for most DVD's chapter == cell */  /* but there are more complecated cases... */  if(chapter >= dvd->vmg_file->tt_srpt->title[title].nr_of_ptts) {    chapter = dvd->vmg_file->tt_srpt->title[title].nr_of_ptts-1;  }  title = dvd->tt_srpt->title[title].vts_ttn-1;  ptt = dvd->vts_file->vts_ptt_srpt->title[title].ptt;  while(chapter >= 0) {    pgc_id = ptt[chapter].pgcn;    pgn = ptt[chapter].pgn;    cur_pgc = dvd->vts_file->vts_pgcit->pgci_srp[pgc_id-1].pgc;    if(cell >= cur_pgc->program_map[pgn-1]-1) {      return chapter;    }    --chapter;  }  /* didn't find a chapter ??? */  return chapter;}int dvd_lang_from_aid(stream_t *stream, int id) {  dvd_priv_t *d;  int i;  if (!stream) return 0;  d = stream->priv;  if (!d) return 0;  for(i=0;i<d->nr_of_channels;i++) {    if(d->audio_streams[i].id==id)      return d->audio_streams[i].language;  }  return 0;}int dvd_aid_from_lang(stream_t *stream, unsigned char* lang) {  dvd_priv_t *d=stream->priv;  int code,i;  if(lang) {    while(strlen(lang)>=2) {      code=lang[1]|(lang[0]<<8);      for(i=0;i<d->nr_of_channels;i++) {        if(d->audio_streams[i].language==code) {          mp_msg(MSGT_OPEN,MSGL_INFO,MSGTR_DVDaudioChannel,          d->audio_streams[i].id, lang[0],lang[1]);          return d->audio_streams[i].id;        }        //printf("%X != %X  (%c%c)\n",code,d->audio_streams[i].language,lang[0],lang[1]);      }      lang+=2; while (lang[0]==',' || lang[0]==' ') ++lang;    }    mp_msg(MSGT_OPEN,MSGL_WARN,MSGTR_DVDnoMatchingAudio);  }  return -1;}int dvd_number_of_subs(stream_t *stream) {  int i;  int maxid = -1;  dvd_priv_t *d;  if (!stream) return -1;  d = stream->priv;  if (!d) return -1;  for (i = 0; i < d->nr_of_subtitles; i++)    if (d->subtitles[i].id > maxid) maxid = d->subtitles[i].id;  return maxid + 1;}int dvd_lang_from_sid(stream_t *stream, int id) {  int i;  dvd_priv_t *d;  if (!stream) return 0;  d = stream->priv;  if (!d) return 0;  for (i = 0; i < d->nr_of_subtitles; i++)    if (d->subtitles[i].id == id && d->subtitles[i].language) return d->subtitles[i].language;  return 0;}int dvd_sid_from_lang(stream_t *stream, unsigned char* lang) {  dvd_priv_t *d=stream->priv;  int code,i;  while(lang && strlen(lang)>=2) {    code=lang[1]|(lang[0]<<8);    for(i=0;i<d->nr_of_subtitles;i++) {      if(d->subtitles[i].language==code) {        mp_msg(MSGT_OPEN,MSGL_INFO,MSGTR_DVDsubtitleChannel, i, lang[0],lang[1]);        return d->subtitles[i].id;      }    }    lang+=2;     while (lang[0]==',' || lang[0]==' ') ++lang;  }  mp_msg(MSGT_OPEN,MSGL_WARN,MSGTR_DVDnoMatchingSubtitle);  return -1;}static int dvd_next_cell(dvd_priv_t *d) {  int next_cell=d->cur_cell;  mp_msg(MSGT_DVD,MSGL_DBG2, "dvd_next_cell: next1=0x%X  \n",next_cell);  if( d->cur_pgc->cell_playback[ next_cell ].block_type == BLOCK_TYPE_ANGLE_BLOCK ) {    while(next_cell<d->last_cell) {      if( d->cur_pgc->cell_playback[next_cell].block_mode == BLOCK_MODE_LAST_CELL )        break;      ++next_cell;    }  }  mp_msg(MSGT_DVD,MSGL_DBG2, "dvd_next_cell: next2=0x%X  \n",next_cell);  ++next_cell;  if(next_cell>=d->last_cell)     return -1; // EOF  if(d->cur_pgc->cell_playback[next_cell].block_type == BLOCK_TYPE_ANGLE_BLOCK ) {    next_cell+=dvd_angle;    if(next_cell>=d->last_cell)       return -1; // EOF  }  mp_msg(MSGT_DVD,MSGL_DBG2, "dvd_next_cell: next3=0x%X  \n",next_cell);  return next_cell;}int dvd_read_sector(dvd_priv_t *d,unsigned char* data) {  int len;  if(d->packs_left==0) {    /**     * 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.     *     * Otherwise, we set our next address past the end of this cell to     * force the code above to go to the next cell in the program.     */    if(d->dsi_pack.vobu_sri.next_vobu != SRI_END_OF_CELL) {       d->cur_pack= d->dsi_pack.dsi_gi.nv_pck_lbn + ( d->dsi_pack.vobu_sri.next_vobu & 0x7fffffff );       mp_msg(MSGT_DVD,MSGL_DBG2, "Navi  new pos=0x%X  \n",d->cur_pack);    } else {      // end of cell! find next cell!      mp_msg(MSGT_DVD,MSGL_V, "--- END OF CELL !!! ---\n");      d->cur_pack=d->cell_last_pack+1;    }  }read_next:  if(d->cur_pack>d->cell_last_pack) {    // end of cell!    int next=dvd_next_cell(d);    if(next>=0) {      d->cur_cell=next;      // if( d->cur_pgc->cell_playback[d->cur_cell].block_type       // == BLOCK_TYPE_ANGLE_BLOCK ) d->cur_cell+=dvd_angle;      d->cur_pack = d->cur_pgc->cell_playback[ d->cur_cell ].first_sector;      d->cell_last_pack=d->cur_pgc->cell_playback[ d->cur_cell ].last_sector;      mp_msg(MSGT_DVD,MSGL_V, "DVD next cell: %d  pack: 0x%X-0x%X  \n",d->cur_cell,d->cur_pack,d->cell_last_pack);    } else         return -1; // EOF  }  len = DVDReadBlocks(d->title, d->cur_pack, 1, data);  if(!len) return -1; //error  if(data[38]==0 && data[39]==0 && data[40]==1 && data[41]==0xBF &&    data[1024]==0 && data[1025]==0 && data[1026]==1 && data[1027]==0xBF) {       // found a Navi packet!!!#if DVDREAD_VERSION >= LIBDVDREAD_VERSION(0,9,0)    navRead_DSI(&d->dsi_pack, &(data[ DSI_START_BYTE ]));

⌨️ 快捷键说明

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