static struct input_stream * bz2_open_stream(struct archive_file *file, const char *path, GMutex *mutex, GCond *cond, GError **error_r) { struct bz2_archive_file *context = (struct bz2_archive_file *) file; struct bz2_input_stream *bis = g_new(struct bz2_input_stream, 1); input_stream_init(&bis->base, &bz2_inputplugin, path, mutex, cond); bis->archive = context; bis->base.ready = true; bis->base.seekable = false; if (!bz2_alloc(bis, error_r)) { input_stream_deinit(&bis->base); g_free(bis); return NULL; } bis->eof = false; refcount_inc(&context->ref); return &bis->base; }
static struct input_stream * input_despotify_open(const char *url, G_GNUC_UNUSED GError **error_r) { struct input_despotify *ctx; struct despotify_session *session; struct ds_link *ds_link; struct ds_track *track; if (!g_str_has_prefix(url, "spt://")) return NULL; session = mpd_despotify_get_session(); if (!session) return NULL; ds_link = despotify_link_from_uri(url + 6); if (!ds_link) { g_debug("Can't find %s\n", url); return NULL; } if (ds_link->type != LINK_TYPE_TRACK) { despotify_free_link(ds_link); return NULL; } ctx = g_new(struct input_despotify, 1); memset(ctx, 0, sizeof(*ctx)); track = despotify_link_get_track(session, ds_link); despotify_free_link(ds_link); if (!track) { g_free(ctx); return NULL; } input_stream_init(&ctx->base, &input_plugin_despotify, url); ctx->session = session; ctx->track = track; ctx->tag = mpd_despotify_tag_from_track(track); ctx->eof = false; /* Despotify outputs pcm data */ ctx->base.mime = g_strdup("audio/x-mpd-cdda-pcm"); ctx->base.ready = true; if (!mpd_despotify_register_callback(callback, ctx)) { despotify_free_link(ds_link); return NULL; } if (despotify_play(ctx->session, ctx->track, false) == false) { despotify_free_track(ctx->track); g_free(ctx); return NULL; } return &ctx->base; }
static struct input_stream * input_ffmpeg_open(const char *uri, GMutex *mutex, GCond *cond, GError **error_r) { struct input_ffmpeg *i; if (!g_str_has_prefix(uri, "gopher://") && !g_str_has_prefix(uri, "rtp://") && !g_str_has_prefix(uri, "rtsp://") && !g_str_has_prefix(uri, "rtmp://") && !g_str_has_prefix(uri, "rtmpt://") && !g_str_has_prefix(uri, "rtmps://")) return NULL; i = g_new(struct input_ffmpeg, 1); input_stream_init(&i->base, &input_plugin_ffmpeg, uri, mutex, cond); #if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,1,0) int ret = avio_open(&i->h, uri, AVIO_FLAG_READ); #elif LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,0,0) int ret = avio_open(&i->h, uri, AVIO_RDONLY); #else int ret = url_open(&i->h, uri, URL_RDONLY); #endif if (ret != 0) { g_free(i); g_set_error(error_r, ffmpeg_quark(), ret, "libavformat failed to open the URI"); return NULL; } i->eof = false; i->base.ready = true; #if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,0,0) i->base.seekable = (i->h->seekable & AVIO_SEEKABLE_NORMAL) != 0; i->base.size = avio_size(i->h); #else i->base.seekable = !i->h->is_streamed; i->base.size = url_filesize(i->h); #endif /* hack to make MPD select the "ffmpeg" decoder plugin - since avio.h doesn't tell us the MIME type of the resource, we can't select a decoder plugin, but the "ffmpeg" plugin is quite good at auto-detection */ i->base.mime = g_strdup("audio/x-mpd-ffmpeg"); return &i->base; }
static struct input_stream * input_file_open(const char *filename, GError **error_r) { int fd, ret; struct stat st; struct file_input_stream *fis; if (!g_path_is_absolute(filename)) return false; fd = open_cloexec(filename, O_RDONLY, 0); if (fd < 0) { if (errno != ENOENT && errno != ENOTDIR) g_set_error(error_r, file_quark(), errno, "Failed to open \"%s\": %s", filename, g_strerror(errno)); return false; } ret = fstat(fd, &st); if (ret < 0) { g_set_error(error_r, file_quark(), errno, "Failed to stat \"%s\": %s", filename, g_strerror(errno)); close(fd); return false; } if (!S_ISREG(st.st_mode)) { g_set_error(error_r, file_quark(), 0, "Not a regular file: %s", filename); close(fd); return false; } #ifdef POSIX_FADV_SEQUENTIAL posix_fadvise(fd, (off_t)0, st.st_size, POSIX_FADV_SEQUENTIAL); #endif fis = g_new(struct file_input_stream, 1); input_stream_init(&fis->base, &input_plugin_file, filename); fis->base.size = st.st_size; fis->base.seekable = true; fis->base.ready = true; fis->fd = fd; return &fis->base; }
static struct input_stream * input_curl_open(const char *url, GError **error_r) { struct input_curl *c; bool ret; if (strncmp(url, "http://", 7) != 0) return NULL; c = g_new0(struct input_curl, 1); input_stream_init(&c->base, &input_plugin_curl, url); c->url = g_strdup(url); c->buffers = g_queue_new(); c->multi = curl_multi_init(); if (c->multi == NULL) { g_set_error(error_r, curl_quark(), 0, "curl_multi_init() failed"); input_curl_free(c); return NULL; } icy_clear(&c->icy_metadata); c->tag = NULL; ret = input_curl_easy_init(c, error_r); if (!ret) { input_curl_free(c); return NULL; } ret = input_curl_send_request(c, error_r); if (!ret) { input_curl_free(c); return NULL; } ret = input_curl_multi_info_read(c, error_r); if (!ret) { input_curl_free(c); return NULL; } return &c->base; }
static struct input_stream * input_file_open(const char *filename, GMutex *mutex, GCond *cond, GError **error_r) { int fd, ret; struct stat st; struct file_input_stream *fis; if (!g_path_is_absolute(filename)) return NULL; fd = open_cloexec(filename, O_RDONLY|O_BINARY, 0); if (fd < 0) { // the filename doesn't exist // try and open uri as if it were a track inside a container char* pathname = NULL; unsigned tnum; pathname = g_strdup(filename); remove_suffix(pathname,'/'); tnum = cue_vtrack_tnum(filename); if ( tnum == 0 ) tnum=1; // use filename from first track of cue file if no track found if( g_str_has_suffix(pathname,".cue")) pathname=cue_locate_audio_container_file(pathname,tnum) ; fd = open_cloexec(pathname, O_RDONLY|O_BINARY, 0); g_free(pathname); if (fd < 0) { if (errno != ENOENT && errno != ENOTDIR) g_set_error(error_r, file_quark(), errno, "Failed to open \"%s\": %s", filename, g_strerror(errno)); return NULL; } } ret = fstat(fd, &st); if (ret < 0) { g_set_error(error_r, file_quark(), errno, "Failed to stat \"%s\": %s", filename, g_strerror(errno)); close(fd); return NULL; } if (!S_ISREG(st.st_mode)) { g_set_error(error_r, file_quark(), 0, "Not a regular file: %s", filename); close(fd); return NULL; } #ifdef POSIX_FADV_SEQUENTIAL posix_fadvise(fd, (off_t)0, st.st_size, POSIX_FADV_SEQUENTIAL); #endif fis = g_new(struct file_input_stream, 1); input_stream_init(&fis->base, &input_plugin_file, filename, mutex, cond); fis->base.size = st.st_size; fis->base.seekable = true; fis->base.ready = true; fis->fd = fd; return &fis->base; }
static struct input_stream * input_cdio_open(const char *uri, GMutex *mutex, GCond *cond, GError **error_r) { struct input_cdio_paranoia *i; struct cdio_uri parsed_uri; if (!parse_cdio_uri(&parsed_uri, uri, error_r)) return NULL; i = g_new(struct input_cdio_paranoia, 1); input_stream_init(&i->base, &input_plugin_cdio_paranoia, uri, mutex, cond); /* initialize everything (should be already) */ i->drv = NULL; i->cdio = NULL; i->para = NULL; i->trackno = parsed_uri.track; pcm_buffer_init(&i->conv_buffer); /* get list of CD's supporting CD-DA */ char *device = parsed_uri.device[0] != 0 ? g_strdup(parsed_uri.device) : cdio_detect_device(); if (device == NULL) { g_set_error(error_r, cdio_quark(), 0, "Unable find or access a CD-ROM drive with an audio CD in it."); input_cdio_close(&i->base); return NULL; } /* Found such a CD-ROM with a CD-DA loaded. Use the first drive in the list. */ i->cdio = cdio_open(device, DRIVER_UNKNOWN); g_free(device); i->drv = cdio_cddap_identify_cdio(i->cdio, 1, NULL); if ( !i->drv ) { g_set_error(error_r, cdio_quark(), 0, "Unable to identify audio CD disc."); input_cdio_close(&i->base); return NULL; } cdda_verbose_set(i->drv, CDDA_MESSAGE_FORGETIT, CDDA_MESSAGE_FORGETIT); if ( 0 != cdio_cddap_open(i->drv) ) { g_set_error(error_r, cdio_quark(), 0, "Unable to open disc."); input_cdio_close(&i->base); return NULL; } i->endian = data_bigendianp(i->drv); switch (i->endian) { case -1: g_debug("cdda: drive returns unknown audio data, assuming Little Endian"); i->endian = 0; break; case 0: g_debug("cdda: drive returns audio data Little Endian."); break; case 1: g_debug("cdda: drive returns audio data Big Endian."); break; default: g_set_error(error_r, cdio_quark(), 0, "Drive returns unknown data type %d", i->endian); input_cdio_close(&i->base); return NULL; } i->lsn_relofs = 0; if (i->trackno >= 0) { i->lsn_from = cdio_get_track_lsn(i->cdio, i->trackno); i->lsn_to = cdio_get_track_last_lsn(i->cdio, i->trackno); } else { i->lsn_from = 0; i->lsn_to = cdio_get_disc_last_lsn(i->cdio); } i->para = cdio_paranoia_init(i->drv); /* Set reading mode for full paranoia, but allow skipping sectors. */ paranoia_modeset(i->para, PARANOIA_MODE_FULL^PARANOIA_MODE_NEVERSKIP); /* seek to beginning of the track */ cdio_paranoia_seek(i->para, i->lsn_from, SEEK_SET); i->base.ready = true; i->base.seekable = true; i->base.size = (i->lsn_to - i->lsn_from + 1) * CDIO_CD_FRAMESIZE_RAW; /* hack to make MPD select the "pcm" decoder plugin */ i->base.mime = g_strdup("audio/x-mpd-cdda-pcm"); return &i->base; }