static char *xmcd_parse_ttitle(cd_info_t *cd_info, char *line) { unsigned int track_nb; unsigned long sec, off; char *ptr; ptr = strstr(line, "TTITLE"); if (ptr != NULL) { ptr += 6; // Here we point to the track number track_nb = atoi(ptr); ptr = strstr(ptr, "="); if (ptr == NULL) return NULL; ptr++; sec = cdtoc[track_nb].frame; off = cdtoc[track_nb + 1].frame - sec + 1; cd_info_add_track(cd_info, ptr, track_nb + 1, (unsigned int) (off / (60 * 75)), (unsigned int) ((off / 75) % 60), (unsigned int) (off % 75), sec, off); } return ptr; }
static int open_cdda(stream_t *st,int m, void* opts, int* file_format) { struct cdda_params* p = (struct cdda_params*)opts; int mode = p->paranoia_mode; int offset = p->toc_offset; #ifndef HAVE_LIBCDIO cdrom_drive* cdd = NULL; #else cdrom_drive_t* cdd = NULL; #endif cdda_priv* priv; cd_info_t *cd_info,*cddb_info = NULL; unsigned int audiolen=0; int last_track; int i; char *xmcd_file = NULL; if(m != STREAM_READ) { m_struct_free(&stream_opts,opts); return STREAM_UNSUPORTED; } if(!p->device) { if (cdrom_device) p->device = strdup(cdrom_device); else p->device = strdup(DEFAULT_CDROM_DEVICE); } #ifdef HAVE_CDDB // cdd_identify returns -1 if it cannot read the TOC, // in which case there is no point in calling cddb_resolve if(cdd_identify(p->device) >= 0 && strncmp(st->url,"cddb",4) == 0) { i = cddb_resolve(p->device, &xmcd_file); if(i == 0) { cddb_info = cddb_parse_xmcd(xmcd_file); free(xmcd_file); } } #endif #ifndef HAVE_LIBCDIO if(p->generic_dev) cdd = cdda_identify_scsi(p->generic_dev,p->device,0,NULL); else #endif #if defined(__NetBSD__) cdd = cdda_identify_scsi(p->device,p->device,0,NULL); #else cdd = cdda_identify(p->device,0,NULL); #endif if(!cdd) { mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_MPDEMUX_CDDA_CantOpenCDDADevice); m_struct_free(&stream_opts,opts); free(cddb_info); return STREAM_ERROR; } cdda_verbose_set(cdd, CDDA_MESSAGE_FORGETIT, CDDA_MESSAGE_FORGETIT); if(p->sector_size) { cdd->nsectors = p->sector_size; #ifndef HAVE_LIBCDIO cdd->bigbuff = p->sector_size * CD_FRAMESIZE_RAW; #endif } if(cdda_open(cdd) != 0) { mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_MPDEMUX_CDDA_CantOpenDisc); cdda_close(cdd); m_struct_free(&stream_opts,opts); free(cddb_info); return STREAM_ERROR; } cd_info = cd_info_new(); mp_msg(MSGT_OPEN,MSGL_INFO,MSGTR_MPDEMUX_CDDA_AudioCDFoundWithNTracks,cdda_tracks(cdd)); for(i=0;i<cdd->tracks;i++) { char track_name[80]; long sec=cdda_track_firstsector(cdd,i+1); long off=cdda_track_lastsector(cdd,i+1)-sec+1; sprintf(track_name, "Track %d", i+1); cd_info_add_track(cd_info, track_name, i+1, (unsigned int)(off/(60*75)), (unsigned int)((off/75)%60), (unsigned int)(off%75), sec, off ); audiolen += off; } cd_info->min = (unsigned int)(audiolen/(60*75)); cd_info->sec = (unsigned int)((audiolen/75)%60); cd_info->msec = (unsigned int)(audiolen%75); priv = malloc(sizeof(cdda_priv)); memset(priv, 0, sizeof(cdda_priv)); priv->cd = cdd; priv->cd_info = cd_info; if(p->toc_bias) offset -= cdda_track_firstsector(cdd,1); if(offset) { int i; for(i = 0 ; i < cdd->tracks + 1 ; i++) cdd->disc_toc[i].dwStartSector += offset; } if(p->speed) cdda_speed_set(cdd,p->speed); last_track = cdda_tracks(cdd); if (p->span.start > last_track) p->span.start = last_track; if (p->span.end < p->span.start) p->span.end = p->span.start; if (p->span.end > last_track) p->span.end = last_track; if(p->span.start) priv->start_sector = cdda_track_firstsector(cdd,p->span.start); else priv->start_sector = cdda_disc_firstsector(cdd); if(p->span.end) { priv->end_sector = cdda_track_lastsector(cdd,p->span.end); } else priv->end_sector = cdda_disc_lastsector(cdd); priv->cdp = paranoia_init(cdd); if(priv->cdp == NULL) { cdda_close(cdd); free(priv); cd_info_free(cd_info); m_struct_free(&stream_opts,opts); free(cddb_info); return STREAM_ERROR; } if(mode == 0) mode = PARANOIA_MODE_DISABLE; else if(mode == 1) mode = PARANOIA_MODE_OVERLAP; else mode = PARANOIA_MODE_FULL; if(p->no_skip) mode |= PARANOIA_MODE_NEVERSKIP; #ifndef HAVE_LIBCDIO paranoia_modeset(cdd, mode); if(p->search_overlap >= 0) paranoia_overlapset(cdd,p->search_overlap); #else paranoia_modeset(priv->cdp, mode); if(p->search_overlap >= 0) paranoia_overlapset(priv->cdp,p->search_overlap); #endif paranoia_seek(priv->cdp,priv->start_sector,SEEK_SET); priv->sector = priv->start_sector; #ifdef HAVE_CDDB if(cddb_info) { cd_info_free(cd_info); priv->cd_info = cddb_info; cd_info_debug( cddb_info ); } #endif st->priv = priv; st->start_pos = priv->start_sector*CD_FRAMESIZE_RAW; st->end_pos = priv->end_sector*CD_FRAMESIZE_RAW; st->type = STREAMTYPE_CDDA; st->sector_size = CD_FRAMESIZE_RAW; st->fill_buffer = fill_buffer; st->seek = seek; st->close = close_cdda; *file_format = DEMUXER_TYPE_RAWAUDIO; m_struct_free(&stream_opts,opts); return STREAM_OK; }