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

📄 stream_cue.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
字号:
//=================== VideoCD BinCue ==========================#include <mplaylib.h>#include <mplaylib.h>#include <mplaylib.h>#include <sys/types.h>#include <sys/stat.h>#include <mplaylib.h>#include <fcntl.h>#include "config.h"#include "mp_msg.h"#include "help_mp.h"#include "stream.h"#include "help_mp.h"#include "m_option.h"#include "m_struct.h"#include "libavutil/avstring.h"#define byte    unsigned char#define SIZERAW 2352#define SIZEISO_MODE1 2048#define SIZEISO_MODE2_RAW 2352#define SIZEISO_MODE2_FORM1 2048#define SIZEISO_MODE2_FORM2 2336#define AUDIO 0#define MODE1 1#define MODE2 2#define MODE1_2352 10#define MODE2_2352 20#define MODE1_2048 30#define MODE2_2336 40#define UNKNOWN -1static struct stream_priv_s {  char* filename;} stream_priv_dflts = {  NULL};#define ST_OFF(f) M_ST_OFF(struct stream_priv_s,f)/// URL definitionstatic m_option_t stream_opts_fields[] = {  { "string", ST_OFF(filename), CONF_TYPE_STRING, 0, 0 ,0, NULL},  { NULL, NULL, 0, 0, 0, 0,  NULL }};static struct m_struct_st stream_opts = {  "cue",  sizeof(struct stream_priv_s),  &stream_priv_dflts,  stream_opts_fields};static FILE* fd_cue;static int fd_bin = 0;static char bin_filename[256];static char cue_filename[256];static char bincue_path[256];typedef struct track{   unsigned short mode;   unsigned short minute;   unsigned short second;   unsigned short frame;   /* (min*60 + sec) * 75 + fps   */   unsigned long start_sector;   /* = the sizes in bytes off all tracks bevor this one */   /* its needed if there are mode1 tracks befor the mpeg tracks */   unsigned long start_offset;   /*   unsigned char num[3]; */} tTrack;/* max 99 tracks on a cd */static tTrack tracks[100];static struct cue_track_pos {  int track;  unsigned short mode;  unsigned short minute;  unsigned short second;  unsigned short frame;} cue_current_pos;/* number of tracks on the cd */static int nTracks = 0;/* presumes Line is preloaded with the "current" line of the file */static int cue_getTrackinfo(char *Line, tTrack *track){  char inum[3];  char min;  char sec;  char fps;  int already_set = 0;  /* Get the 'mode' */  if (strncmp(&Line[2], "TRACK ", 6)==0)  {/*    strncpy(track->num, &Line[8], 2); track->num[2] = '\0'; */    track->mode = UNKNOWN;    if(strncmp(&Line[11], "AUDIO", 5)==0) track->mode = AUDIO;    if(strncmp(&Line[11], "MODE1/2352", 10)==0) track->mode = MODE1_2352;    if(strncmp(&Line[11], "MODE1/2048", 10)==0) track->mode = MODE1_2048;    if(strncmp(&Line[11], "MODE2/2352", 10)==0) track->mode = MODE2_2352;    if(strncmp(&Line[11], "MODE2/2336", 10)==0) track->mode = MODE2_2336;  }  else return(1);  /* Get the track indexes */  while(1) {    if(! fgets( Line, 256, fd_cue ) ) { break;}    if (strncmp(&Line[2], "TRACK ", 6)==0)    {      /* next track starting */      break;    }    /* Track 0 or 1, take the first an get fill the values*/    if (strncmp(&Line[4], "INDEX ", 6)==0)    {      /* check stuff here so if the answer is false the else stuff below won't be executed */      strncpy(inum, &Line[10], 2); inum[2] = '\0';      if ((already_set == 0) &&          ((strcmp(inum, "00")==0) || (strcmp(inum, "01")==0)))      {        already_set = 1;        min = ((Line[13]-'0')<<4) | (Line[14]-'0');        sec = ((Line[16]-'0')<<4) | (Line[17]-'0');        fps = ((Line[19]-'0')<<4) | (Line[20]-'0');        track->minute = (((min>>4)*10) + (min&0xf));        track->second = (((sec>>4)*10) + (sec&0xf));        track->frame  = (((fps>>4)*10) + (fps&0xf));      }    }    else if (strncmp(&Line[4], "PREGAP ", 7)==0) { ; /* ignore */ }    else if (strncmp(&Line[4], "FLAGS ", 6)==0)  { ; /* ignore */ }    else mp_msg (MSGT_OPEN,MSGL_INFO,                 MSGTR_MPDEMUX_CUEREAD_UnexpectedCuefileLine, Line);  }  return(0);}/* FIXME: the string operations ( strcpy,strcat ) below depend * on the arrays to have the same size, thus we need to make * sure the sizes are in sync. */static int cue_find_bin (char *firstline) {  int i,j;  char s[256];  char t[256];  /* get the filename out of that */  /*                      12345 6  */  mp_msg (MSGT_OPEN,MSGL_INFO, "[bincue] cue_find_bin(%s)\n", firstline);  if (strncmp(firstline, "FILE \"",6)==0)  {    i = 0;    j = 0;    while ( firstline[6 + i] != '"')    {      bin_filename[j] = firstline[6 + i];      /* if I found a path info, than delete all bevor it */      switch (bin_filename[j])      {        case '\\':          j = 0;          break;        case '/':          j = 0;          break;        default:          j++;      }      i++;    }    bin_filename[j+1] = '\0';  }  /* now try to open that file, without path */  fd_bin = open (bin_filename, O_RDONLY,-1);  if (fd_bin == -1)  {    mp_msg(MSGT_OPEN,MSGL_STATUS, MSGTR_MPDEMUX_CUEREAD_BinFilenameTested,           bin_filename);    /* now try to find it with the path of the cue file */    snprintf(s,sizeof( s ),"%s/%s",bincue_path,bin_filename);    fd_bin = open (s, O_RDONLY,-1);    if (fd_bin == -1)    {      mp_msg(MSGT_OPEN,MSGL_STATUS,             MSGTR_MPDEMUX_CUEREAD_BinFilenameTested, s);      /* now I would say the whole filename is shit, build our own */      strncpy(s, cue_filename, strlen(cue_filename) - 3 );      s[strlen(cue_filename) - 3] = '\0';      strcat(s, "bin");      fd_bin = open (s, O_RDONLY,-1);      if (fd_bin == -1)      {        mp_msg(MSGT_OPEN,MSGL_STATUS,               MSGTR_MPDEMUX_CUEREAD_BinFilenameTested, s);        /* ok try it with path */        snprintf(t, sizeof( t ), "%s/%s", bincue_path, s);        fd_bin = open (t, O_RDONLY,-1);        if (fd_bin == -1)        {          mp_msg(MSGT_OPEN,MSGL_STATUS,                 MSGTR_MPDEMUX_CUEREAD_BinFilenameTested,t);          /* now I would say the whole filename is shit, build our own */          strncpy(s, cue_filename, strlen(cue_filename) - 3 );          s[strlen(cue_filename) - 3] = '\0';          strcat(s, "img");          fd_bin = open (s, O_RDONLY,-1);          if (fd_bin == -1)          {            mp_msg(MSGT_OPEN,MSGL_STATUS,                   MSGTR_MPDEMUX_CUEREAD_BinFilenameTested, s);            /* ok try it with path */            snprintf(t, sizeof( t ), "%s/%s", bincue_path, s);            fd_bin = open (t, O_RDONLY,-1);            if (fd_bin == -1)            {              mp_msg(MSGT_OPEN,MSGL_STATUS,                     MSGTR_MPDEMUX_CUEREAD_BinFilenameTested, s);              /* I'll give up */              mp_msg(MSGT_OPEN,MSGL_ERR,                     MSGTR_MPDEMUX_CUEREAD_CannotFindBinFile);              return -1;            }          }        } else strcpy(bin_filename, t);      } else strcpy(bin_filename, s);    } else strcpy(bin_filename, s);  }  mp_msg(MSGT_OPEN,MSGL_INFO,         MSGTR_MPDEMUX_CUEREAD_UsingBinFile, bin_filename);  return 0;}static inline int cue_msf_2_sector(int minute, int second, int frame) { return frame + (second + minute * 60 ) * 75;}static inline int cue_get_msf(void) {  return cue_msf_2_sector (cue_current_pos.minute,                           cue_current_pos.second,                           cue_current_pos.frame);}static inline void cue_set_msf(unsigned int sect){  cue_current_pos.frame=sect%75;  sect=sect/75;  cue_current_pos.second=sect%60;  sect=sect/60;  cue_current_pos.minute=sect;}static inline int cue_mode_2_sector_size(int mode){  switch (mode)  {    case AUDIO:      return AUDIO;    case MODE1_2352: return SIZERAW;    case MODE1_2048: return SIZEISO_MODE1;    case MODE2_2352: return SIZEISO_MODE2_RAW;    case MODE2_2336: return SIZEISO_MODE2_FORM2;    default:      mp_msg(MSGT_OPEN,MSGL_FATAL,             MSGTR_MPDEMUX_CUEREAD_UnknownModeForBinfile);      abort();  }}static int cue_read_cue (char *in_cue_filename){  struct stat filestat;  char sLine[256];  unsigned int sect;  char *s,*t;  int i;  /* we have no tracks at the beginning */  nTracks = 0;  fd_bin = 0;  /* split the filename into a path and filename part */  s = strdup(in_cue_filename);  t = strrchr(s, '/');  if (t == (char *)NULL)     t = ".";  else {     *t = '\0';     t = s;     if (*t == '\0')       strcpy(t, "/");  }    av_strlcpy(bincue_path,t,sizeof( bincue_path ));  mp_msg(MSGT_OPEN,MSGL_V,"dirname: %s, cuepath: %s\n", t, bincue_path);  /* no path at all? */  if (strcmp(bincue_path, ".") == 0) {    mp_msg(MSGT_OPEN,MSGL_V,"bincue_path: %s\n", bincue_path);    av_strlcpy(cue_filename,in_cue_filename,sizeof( cue_filename ));  } else {    av_strlcpy(cue_filename,in_cue_filename + strlen(bincue_path) + 1,            sizeof( cue_filename ));  }  /* open the cue file */  fd_cue = fopen (in_cue_filename, "r");  if (fd_cue == NULL)  {    mp_msg(MSGT_OPEN,MSGL_ERR,           MSGTR_MPDEMUX_CUEREAD_CannotOpenCueFile, in_cue_filename);    return -1;  }  /* read the first line and hand it to find_bin, which will     test more than one possible name of the file */  if(! fgets( sLine, 256, fd_cue ) )  {    mp_msg(MSGT_OPEN,MSGL_ERR,           MSGTR_MPDEMUX_CUEREAD_ErrReadingFromCueFile, in_cue_filename);    fclose (fd_cue);    return -1;  }  if (cue_find_bin(sLine)) {    fclose (fd_cue);    return -1;  }  /* now build the track list */  /* red the next line and call our track finder */  if(! fgets( sLine, 256, fd_cue ) )  {    mp_msg(MSGT_OPEN,MSGL_ERR,           MSGTR_MPDEMUX_CUEREAD_ErrReadingFromCueFile, in_cue_filename);    fclose (fd_cue);    return -1;  }  while(!feof(fd_cue))  {    if (cue_getTrackinfo(sLine, &tracks[nTracks++]) != 0)    {      mp_msg(MSGT_OPEN,MSGL_ERR,             MSGTR_MPDEMUX_CUEREAD_ErrReadingFromCueFile, in_cue_filename);      fclose (fd_cue);      return -1;    }  }  /* make a fake track with stands for the Lead out */  if (fstat (fd_bin, &filestat) == -1) {    mp_msg(MSGT_OPEN,MSGL_ERR,           MSGTR_MPDEMUX_CUEREAD_ErrGettingBinFileSize);    fclose (fd_cue);    return -1;  }  sect = filestat.st_size / 2352;  tracks[nTracks].frame = sect%75;  sect=sect/75;  tracks[nTracks].second = sect%60;  sect=sect/60;  tracks[nTracks].minute = sect;  /* let's calculate the start sectors and offsets */  for(i = 0; i <= nTracks; i++)  {    tracks[i].start_sector = cue_msf_2_sector(tracks[i].minute,                                              tracks[nTracks].second,                                              tracks[nTracks].frame);    /* if we're the first track we don't need to offset of the one befor */    if (i == 0)    {      /* was always 0 on my svcds, but who knows */      tracks[0].start_offset = tracks[0].start_sector *        cue_mode_2_sector_size(tracks[0].mode);    } else    {      tracks[i].start_offset = tracks[i-1].start_offset +        (tracks[i].start_sector - tracks[i-1].start_sector) *        cue_mode_2_sector_size(tracks[i-1].mode);    }  }  fclose (fd_cue);  return fd_bin;}static int cue_read_toc_entry(void) {  int track = cue_current_pos.track - 1;  /* check if its a valid track, if not return -1 */  if (track >= nTracks)    return -1;  switch (tracks[track].mode)  {    case AUDIO:      cue_current_pos.mode = AUDIO;      break;    case MODE1_2352:      cue_current_pos.mode = MODE1;      break;    case MODE1_2048:      cue_current_pos.mode = MODE1;      break;    default: /* MODE2_2352 and MODE2_2336 */      cue_current_pos.mode = MODE2;  }  cue_current_pos.minute = tracks[track].minute;  cue_current_pos.second = tracks[track].second;  cue_current_pos.frame = tracks[track].frame;  return 0;}static int cue_vcd_seek_to_track (int track){  cue_current_pos.track  = track;  if (cue_read_toc_entry ())    return -1;  return VCD_SECTOR_DATA * cue_get_msf();}static int cue_vcd_get_track_end (int track){  cue_current_pos.frame = tracks[track].frame;  cue_current_pos.second = tracks[track].second;  cue_current_pos.minute = tracks[track].minute;  return VCD_SECTOR_DATA * cue_get_msf();}static void cue_vcd_read_toc(void){  int i;  for (i = 0; i < nTracks; ++i) {    mp_msg(MSGT_OPEN,MSGL_INFO,           MSGTR_MPDEMUX_CUEREAD_InfoTrackFormat,           i+1,           tracks[i].mode,           tracks[i].minute,           tracks[i].second,           tracks[i].frame           );  }}static int cue_vcd_read(stream_t *stream, char *mem, int size) {  unsigned long position;  int track = cue_current_pos.track - 1;  position = tracks[track].start_offset +             (cue_msf_2_sector(cue_current_pos.minute,                               cue_current_pos.second,                               cue_current_pos.frame) -              tracks[track].start_sector)             * cue_mode_2_sector_size(tracks[track].mode);    if(position >= tracks[track+1].start_offset)    return 0;  if(lseek(fd_bin, position+VCD_SECTOR_OFFS, SEEK_SET) == -1) {    mp_msg(MSGT_OPEN,MSGL_ERR, MSGTR_MPDEMUX_CUEREAD_UnexpectedBinFileEOF);    return 0;  }  if(read(fd_bin, mem, VCD_SECTOR_DATA) != VCD_SECTOR_DATA) {    mp_msg(MSGT_OPEN,MSGL_ERR, MSGTR_MPDEMUX_CUEREAD_CannotReadNBytesOfPayload, VCD_SECTOR_DATA);    return 0;  }  cue_current_pos.frame++;  if (cue_current_pos.frame==75){    cue_current_pos.frame=0;    cue_current_pos.second++;    if (cue_current_pos.second==60){      cue_current_pos.second=0;      cue_current_pos.minute++;    }  }  return VCD_SECTOR_DATA;}static int seek(stream_t *s,off_t newpos) {  s->pos=newpos;  cue_set_msf(s->pos/VCD_SECTOR_DATA);  return 1;}static int open_s(stream_t *stream,int mode, void* opts, int* file_format) {  struct stream_priv_s* p = (struct stream_priv_s*)opts;  int ret,ret2,f,track = 0;  char *filename = NULL, *colon = NULL;  if(mode != STREAM_READ || !p->filename) {    m_struct_free(&stream_opts,opts);    return STREAM_UNSUPPORTED;  }  filename = strdup(p->filename);  if(!filename) {    m_struct_free(&stream_opts,opts);    return STREAM_UNSUPPORTED;  }  colon = strstr(filename, ":");  if(colon) {    if(strlen(colon)>1)      track = atoi(colon+1);    *colon = 0;  }  if(!track)    track = 1;    f = cue_read_cue(filename);  if(f < 0) {    m_struct_free(&stream_opts,opts);    return STREAM_UNSUPPORTED;  }  cue_vcd_read_toc();  ret2=cue_vcd_get_track_end(track);  ret=cue_vcd_seek_to_track(track);  if(ret<0){     mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_ErrTrackSelect " (seek)\n");    return STREAM_UNSUPPORTED;  }  mp_msg(MSGT_OPEN,MSGL_INFO,MSGTR_MPDEMUX_CUEREAD_CueStreamInfo_FilenameTrackTracksavail, filename, track, ret, ret2);  stream->fd = f;  stream->type = STREAMTYPE_VCDBINCUE;  stream->sector_size = VCD_SECTOR_DATA;  stream->flags = STREAM_READ | STREAM_SEEK_FW;  stream->start_pos = ret;  stream->end_pos = ret2;  stream->fill_buffer = cue_vcd_read;  stream->seek = seek;  free(filename);  m_struct_free(&stream_opts,opts);  return STREAM_OK;}stream_info_t stream_info_cue = {  "CUE track",  "cue",  "Albeu",  "based on the code from ???",  open_s,  { "cue", NULL },  &stream_opts,  1 // Urls are an option string};

⌨️ 快捷键说明

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