Ejemplo n.º 1
0
static int
sidfile_scandir(fa_dir_t *fd, const char *url, char *errbuf, size_t errlen)
{
  void *fh = NULL;
  char *p, *fpath = mystrdupa(url);
  char buf[128];
  char name[32];
  char turl[URL_MAX];
  int tracks, i;
  fa_dir_entry_t *fde;
  rstr_t *album, *artist;
 

  if((p = strrchr(fpath, '/')) == NULL) {
    snprintf(errbuf, errlen, "Invalid filename");
    return -1;
  }

  *p = 0;
  if((fh = fa_open(fpath, errbuf, errlen)) == NULL)
    return -1;

  if(fa_read(fh, buf, 128) != 128) {
    snprintf(errbuf, errlen, "Unable to read file");
    fa_close(fh);
    return -1;
  }

  album = rstr_alloc(utf8_from_bytes((char *)buf + 0x16, 32, NULL));
  artist = rstr_alloc(utf8_from_bytes((char *)buf + 0x36, 32, NULL));

  tracks = buf[0xf];
  for(i = 0; i < tracks; i++) {

    snprintf(name, sizeof(name), "Track %02d", i + 1);
    snprintf(turl, sizeof(turl), "sidplayer:%s/%d", fpath, i + 1);
    fde = fa_dir_add(fd, turl, name, CONTENT_AUDIO);

    fde->fde_probestatus = FDE_PROBE_DEEP;

    fde->fde_metadata = prop_create_root("metadata");
    prop_set_string(prop_create(fde->fde_metadata, "title"), name);
    prop_set_rstring(prop_create(fde->fde_metadata, "album"), album);
    prop_set_rstring(prop_create(fde->fde_metadata, "artist"), artist);
  }

  rstr_release(album);
  rstr_release(artist);

  fa_close(fh);
  return 0;
}
Ejemplo n.º 2
0
static void
bwlimit_close(fa_handle_t *h)
{
  bwlimit_t *s = (bwlimit_t *)h;
  fa_close(s->s_src);
  free(s);
}
Ejemplo n.º 3
0
void
fa_libav_close(AVIOContext *avio)
{
  fa_close(avio->opaque);
  av_free(avio->buffer);
  av_free(avio);
}
Ejemplo n.º 4
0
static event_t *
be_gmeplayer_play(const char *url0, media_pipe_t *mp, 
		  char *errbuf, size_t errlen, int hold)
{
  event_t *e;
  char *url, *p;
  int track;
  void *fh;

  url0 += strlen("gmeplayer:");

  url = mystrdupa(url0);
  p = strrchr(url, '/');
  if(p == NULL) {
    snprintf(errbuf, errlen, "Invalid filename");
    return NULL;
  }

  *p++= 0;
  track = atoi(p) - 1;

  if((fh = fa_open(url, errbuf, errlen)) == NULL)
    return NULL;

  e = fa_gme_playfile_internal(mp, fh, errbuf, errlen, hold, track);
  fa_close(fh);
  return e;

}
Ejemplo n.º 5
0
void
load_syms(void)
{
  char sympath[256];
  char errbuf[256];

  snprintf(sympath, sizeof(sympath), "%s/showtime.syms", showtime_dataroot());

  my_trace("sympath: %s\n", sympath);

  fa_handle_t *fh = fa_open(sympath, errbuf, sizeof(errbuf));

  if(fh == NULL) {
    my_trace("Unable to open symbol file %s -- %s",
	  sympath, errbuf);
    return;
  }

  int size = fa_fsize(fh);
  char *buf = halloc(size + 1);

  int r = fa_read(fh, buf, size);
  if(r != size) {
    my_trace("Unable to read %d bytes", size);
    hfree(buf, size+1);
  } else {
    buf[size] = 0;
    my_trace("Loaded symbol table %d bytes to %p",
	  size, buf);
    symbuf = buf;
  }
  fa_close(fh);
}
Ejemplo n.º 6
0
static void
cmp_close(fa_handle_t *h)
{
  cmp_t *s = (cmp_t *)h;
  fa_close(s->s_src);
  close(s->s_fd);
  free(s);
}
Ejemplo n.º 7
0
static void
es_fd_destroy(es_resource_t *eres)
{
  es_fd_t *efd = (es_fd_t *)eres;
  if(efd->efd_fh != NULL) {
    fa_close(efd->efd_fh);
    efd->efd_fh = NULL;
  }
  free(efd->efd_path);
  es_resource_unlink(&efd->super);
}
Ejemplo n.º 8
0
metadata_t *
fa_probe_metadata(const char *url, char *errbuf, size_t errsize,
		  const char *filename)
{
  AVFormatContext *fctx;

  fa_handle_t *fh = fa_open_ex(url, errbuf, errsize, FA_BUFFERED_SMALL, NULL);

  if(fh == NULL) 
    return NULL;

  metadata_t *md = metadata_create();

#if ENABLE_LIBGME
  if(gme_probe(md, url, fh))
    return md;
#endif

#if ENABLE_XMP
  if(xmp_probe(md, url, fh))
    return md;
#endif

  fa_seek(fh, 0, SEEK_SET);

  if(fa_probe_header(md, url, fh, filename)) {
    fa_close(fh);
    return md;
  }

  AVIOContext *avio = fa_libav_reopen(fh);
 
  if((fctx = fa_libav_open_format(avio, url, errbuf, errsize, NULL)) == NULL) {
    fa_libav_close(avio);
    metadata_destroy(md);
    return NULL;
  }

  fa_lavf_load_meta(md, fctx, filename);
  fa_libav_close_format(fctx);
  return md;
}
Ejemplo n.º 9
0
static event_t *
openspc_play(media_pipe_t *mp, AVIOContext *avio, char *errbuf, size_t errlen)
{
  media_queue_t *mq = &mp->mp_audio;
#error fa_fsize can return -1 .. deal with it
  size_t r, siz = fa_fsize(fh);
  uint8_t *buf = malloc(siz);
  media_buf_t *mb = NULL;
  event_t *e;
  int hold = 0, lost_focus = 0;
  int sample = 0;
  unsigned int duration = INT32_MAX;

  mp_set_playstatus_by_hold(mp, hold, NULL);

  mp->mp_audio.mq_stream = 0;

  fa_seek(fh, 0, SEEK_SET);
  r = fa_read(fh, buf, siz);
  fa_close(fh);
  
  if(r != siz) {
    free(buf);
    snprintf(errbuf, errlen, "openspc: Unable to read file");
    return NULL;
  }

  if(OSPC_Init(buf, siz)) {
    free(buf);
    snprintf(errbuf, errlen, "openspc: Unable to initialize file");
    return NULL;
  }

  if(!memcmp("v0.30", buf + 0x1c, 4) && buf[0x23] == 0x1a) {
    char str[4];
    memcpy(str, buf + 0xa9, 3);
    str[3] = 0;
    duration = atoi(str) * 32000;
  }

  mp_set_play_caps(mp, MP_PLAY_CAPS_PAUSE);

  mp_become_primary(mp);

  while(1) {

    if(mb == NULL) {

      if(sample > duration) {
	while((e = mp_wait_for_empty_queues(mp, 0)) != NULL) {
	  if(event_is_type(e, EVENT_PLAYQUEUE_JUMP) ||
	     event_is_action(e, ACTION_PREV_TRACK) ||
	     event_is_action(e, ACTION_NEXT_TRACK) ||
	     event_is_action(e, ACTION_STOP)) {
	    mp_flush(mp, 0);
	    break;
	  }
	  event_release(e);
	}
	if(e == NULL)
	  e = event_create_type(EVENT_EOF);
	break;
       }

      mb = media_buf_alloc();
      mb->mb_data_type = MB_AUDIO;
      mb->mb_size = sizeof(int16_t) * 2048 * 2;
      mb->mb_data = malloc(mb->mb_size);
      mb->mb_size = OSPC_Run(-1, mb->mb_data, mb->mb_size);

      mb->mb_channels = 2;
      mb->mb_rate = 32000;

      mb->mb_time = sample * 1000000LL / mb->mb_rate;
      sample += 2048;
    }

    if((e = mb_enqueue_with_events(mp, mq, mb)) == NULL) {
      mb = NULL; /* Enqueue succeeded */
      continue;
    }

    if(event_is_type(e, EVENT_PLAYQUEUE_JUMP)) {
      mp_flush(mp, 0);
      break;
    } else if(event_is_action(e, ACTION_PLAYPAUSE) ||
	      event_is_action(e, ACTION_PLAY) ||
	      event_is_action(e, ACTION_PAUSE)) {

      hold = action_update_hold_by_event(hold, e);
      mp_send_cmd_head(mp, mq, hold ? MB_CTRL_PAUSE : MB_CTRL_PLAY);
      lost_focus = 0;
      mp_set_playstatus_by_hold(mp, hold, NULL);

    } else if(event_is_type(e, EVENT_MP_NO_LONGER_PRIMARY)) {

      hold = 1;
      lost_focus = 1;
      mp_send_cmd_head(mp, mq, MB_CTRL_PAUSE);
      mp_set_playstatus_by_hold(mp, hold, e->e_payload);

    } else if(event_is_type(e, EVENT_MP_IS_PRIMARY)) {

      if(lost_focus) {
	hold = 0;
	lost_focus = 0;
	mp_send_cmd_head(mp, mq, MB_CTRL_PLAY);
	mp_set_playstatus_by_hold(mp, hold, NULL);
      }

    } else if(event_is_type(e, EVENT_INTERNAL_PAUSE)) {

      hold = 1;
      lost_focus = 0;
      mp_send_cmd_head(mp, mq, MB_CTRL_PAUSE);
      mp_set_playstatus_by_hold(mp, hold, e->e_payload);

    } else if(event_is_action(e, ACTION_PREV_TRACK) ||
	      event_is_action(e, ACTION_NEXT_TRACK) ||
	      event_is_action(e, ACTION_STOP)) {
      mp_flush(mp, 0);
      break;
    }
    event_release(e);
  }

  free(buf);
  return e;
}
Ejemplo n.º 10
0
event_t *
be_file_playaudio(const char *url, media_pipe_t *mp,
		  char *errbuf, size_t errlen, int hold, const char *mimetype)
{
  AVFormatContext *fctx;
  AVCodecContext *ctx;
  AVPacket pkt;
  media_format_t *fw;
  int i, r, si;
  media_buf_t *mb = NULL;
  media_queue_t *mq;
  event_ts_t *ets;
  int64_t ts, seekbase = 0;
  media_codec_t *cw;
  event_t *e;
  int lost_focus = 0;
  int registered_play = 0;

  mp_set_playstatus_by_hold(mp, hold, NULL);

  fa_handle_t *fh = fa_open_ex(url, errbuf, errlen, FA_BUFFERED_SMALL, NULL);
  if(fh == NULL)
    return NULL;

  // First we need to check for a few other formats
#if ENABLE_LIBOPENSPC || ENABLE_LIBGME

  uint8_t pb[128];
  size_t psiz;
  
  psiz = fa_read(fh, pb, sizeof(pb));
  if(psiz < sizeof(pb)) {
    fa_close(fh);
    snprintf(errbuf, errlen, "Fill too small");
    return NULL;
  }

#if ENABLE_LIBGME
  if(*gme_identify_header(pb))
    return fa_gme_playfile(mp, fh, errbuf, errlen, hold, url);
#endif

#if ENABLE_LIBOPENSPC
  if(!memcmp(pb, "SNES-SPC700 Sound File Data", 27))
    return openspc_play(mp, fh, errbuf, errlen);
#endif

#endif

  
  AVIOContext *avio = fa_libav_reopen(fh);

  if(avio == NULL) {
    fa_close(fh);
    return NULL;
  }

  if((fctx = fa_libav_open_format(avio, url, 
				  errbuf, errlen, mimetype)) == NULL) {
    fa_libav_close(avio);
    return NULL;
  }

  TRACE(TRACE_DEBUG, "Audio", "Starting playback of %s", url);

  mp_configure(mp, MP_PLAY_CAPS_SEEK | MP_PLAY_CAPS_PAUSE,
	       MP_BUFFER_SHALLOW);

  mp->mp_audio.mq_stream = -1;
  mp->mp_video.mq_stream = -1;

  fw = media_format_create(fctx);

  cw = NULL;
  for(i = 0; i < fctx->nb_streams; i++) {
    ctx = fctx->streams[i]->codec;

    if(ctx->codec_type != AVMEDIA_TYPE_AUDIO)
      continue;

    cw = media_codec_create(ctx->codec_id, 0, fw, ctx, NULL, mp);
    mp->mp_audio.mq_stream = i;
    break;
  }
  
  if(cw == NULL) {
    media_format_deref(fw);
    snprintf(errbuf, errlen, "Unable to open codec");
    return NULL;
  }

  mp_become_primary(mp);
  mq = &mp->mp_audio;

  while(1) {

    /**
     * Need to fetch a new packet ?
     */
    if(mb == NULL) {
      
      mp->mp_eof = 0;
      r = av_read_frame(fctx, &pkt);
      if(r == AVERROR(EAGAIN))
	continue;
      
      if(r == AVERROR_EOF || r == AVERROR(EIO)) {
	mb = MB_SPECIAL_EOF;
	mp->mp_eof = 1;
	continue;
      }
      
      if(r != 0) {
	char msg[100];
	fa_ffmpeg_error_to_txt(r, msg, sizeof(msg));
	TRACE(TRACE_ERROR, "Audio", "Playback error: %s", msg);

	while((e = mp_wait_for_empty_queues(mp)) != NULL) {
	  if(event_is_type(e, EVENT_PLAYQUEUE_JUMP) ||
	     event_is_action(e, ACTION_PREV_TRACK) ||
	     event_is_action(e, ACTION_NEXT_TRACK) ||
	     event_is_action(e, ACTION_STOP)) {
	    mp_flush(mp, 0);
	    break;
	  }
	  event_release(e);
	}
	if(e == NULL)
	  e = event_create_type(EVENT_EOF);
	break;
      }

      si = pkt.stream_index;

      if(si != mp->mp_audio.mq_stream) {
	av_free_packet(&pkt);
	continue;
      }



      mb = media_buf_alloc_unlocked(mp, pkt.size);
      mb->mb_data_type = MB_AUDIO;

      mb->mb_pts      = rescale(fctx, pkt.pts,      si);
      mb->mb_dts      = rescale(fctx, pkt.dts,      si);
      mb->mb_duration = rescale(fctx, pkt.duration, si);

      mb->mb_cw = media_codec_ref(cw);

      /* Move the data pointers from ffmpeg's packet */

      mb->mb_stream = pkt.stream_index;

      memcpy(mb->mb_data, pkt.data, pkt.size);

      if(mb->mb_pts != AV_NOPTS_VALUE) {
	if(fctx->start_time == AV_NOPTS_VALUE)
	  mb->mb_time = mb->mb_pts;
	else
	  mb->mb_time = mb->mb_pts - fctx->start_time;
      } else
	mb->mb_time = AV_NOPTS_VALUE;

      mb->mb_send_pts = 1;

      av_free_packet(&pkt);
    }

    /*
     * Try to send the buffer.  If mb_enqueue() returns something we
     * catched an event instead of enqueueing the buffer. In this case
     * 'mb' will be left untouched.
     */

    if(mb == MB_SPECIAL_EOF) {
      // We have reached EOF, drain queues
      e = mp_wait_for_empty_queues(mp);
      
      if(e == NULL) {
	e = event_create_type(EVENT_EOF);
	break;
      }

    } else if((e = mb_enqueue_with_events(mp, mq, mb)) == NULL) {
      mb = NULL; /* Enqueue succeeded */
      continue;
    }      

    if(event_is_type(e, EVENT_PLAYQUEUE_JUMP)) {

      mp_flush(mp, 0);
      break;

    } else if(event_is_type(e, EVENT_CURRENT_PTS)) {

      ets = (event_ts_t *)e;
      seekbase = ets->ts;

      if(registered_play == 0) {
	if(ets->ts - fctx->start_time > METADB_AUDIO_PLAY_THRESHOLD) {
	  registered_play = 1;
	  metadb_register_play(url, 1, CONTENT_AUDIO);
	}
      }

    } else if(event_is_type(e, EVENT_SEEK)) {

      ets = (event_ts_t *)e;
      ts = ets->ts + fctx->start_time;
      if(ts < fctx->start_time)
	ts = fctx->start_time;
      av_seek_frame(fctx, -1, ts, AVSEEK_FLAG_BACKWARD);
      seekflush(mp, &mb);
      
    } else if(event_is_action(e, ACTION_SEEK_FAST_BACKWARD)) {

      av_seek_frame(fctx, -1, seekbase - 60000000, AVSEEK_FLAG_BACKWARD);
      seekflush(mp, &mb);

    } else if(event_is_action(e, ACTION_SEEK_BACKWARD)) {

      av_seek_frame(fctx, -1, seekbase - 15000000, AVSEEK_FLAG_BACKWARD);
      seekflush(mp, &mb);

    } else if(event_is_action(e, ACTION_SEEK_FAST_FORWARD)) {

      av_seek_frame(fctx, -1, seekbase + 60000000, 0);
      seekflush(mp, &mb);

    } else if(event_is_action(e, ACTION_SEEK_FORWARD)) {

      av_seek_frame(fctx, -1, seekbase + 15000000, 0);
      seekflush(mp, &mb);
#if 0
    } else if(event_is_action(e, ACTION_RESTART_TRACK)) {

      av_seek_frame(fctx, -1, 0, AVSEEK_FLAG_BACKWARD);
      seekflush(mp, &mb);
#endif
    } else if(event_is_action(e, ACTION_PLAYPAUSE) ||
	      event_is_action(e, ACTION_PLAY) ||
	      event_is_action(e, ACTION_PAUSE)) {

      hold = action_update_hold_by_event(hold, e);
      mp_send_cmd_head(mp, mq, hold ? MB_CTRL_PAUSE : MB_CTRL_PLAY);
      lost_focus = 0;
      mp_set_playstatus_by_hold(mp, hold, NULL);

    } else if(event_is_type(e, EVENT_MP_NO_LONGER_PRIMARY)) {

      hold = 1;
      lost_focus = 1;
      mp_send_cmd_head(mp, mq, MB_CTRL_PAUSE);
      mp_set_playstatus_by_hold(mp, hold, e->e_payload);

    } else if(event_is_type(e, EVENT_MP_IS_PRIMARY)) {

      if(lost_focus) {
	hold = 0;
	lost_focus = 0;
	mp_send_cmd_head(mp, mq, MB_CTRL_PLAY);
	mp_set_playstatus_by_hold(mp, hold, NULL);
      }

    } else if(event_is_type(e, EVENT_INTERNAL_PAUSE)) {

      hold = 1;
      lost_focus = 0;
      mp_send_cmd_head(mp, mq, MB_CTRL_PAUSE);
      mp_set_playstatus_by_hold(mp, hold, e->e_payload);

    } else if(event_is_action(e, ACTION_PREV_TRACK) ||
	      event_is_action(e, ACTION_NEXT_TRACK) ||
	      event_is_action(e, ACTION_STOP)) {
      mp_flush(mp, 0);
      break;
    }
    event_release(e);
  }

  if(mb != NULL && mb != MB_SPECIAL_EOF)
    media_buf_free_unlocked(mp, mb);

  media_codec_deref(cw);
  media_format_deref(fw);

  if(hold) { 
    // If we were paused, release playback again.
    mp_send_cmd(mp, mq, MB_CTRL_PLAY);
    mp_set_playstatus_by_hold(mp, 0, NULL);
  }

  return e;
}
Ejemplo n.º 11
0
pixmap_t *
fa_imageloader(const char *url, const struct image_meta *im,
	       const char **vpaths, char *errbuf, size_t errlen,
	       int *cache_control, cancellable_t *c)
{
  uint8_t p[16];
  int r;
  int width = -1, height = -1, orientation = 0;
  fa_handle_t *fh;
  pixmap_t *pm;
  pixmap_type_t fmt;

#if ENABLE_LIBAV
  if(strchr(url, '#'))
    return fa_image_from_video(url, im, errbuf, errlen, cache_control, c);
#endif

  if(!im->im_want_thumb)
    return fa_imageloader2(url, vpaths, errbuf, errlen, cache_control, c);

  fa_open_extra_t foe = {
    .foe_c = c
  };

  if((fh = fa_open_vpaths(url, vpaths, errbuf, errlen,
			  FA_BUFFERED_SMALL, &foe)) == NULL)
    return NULL;

  if(ONLY_CACHED(cache_control)) {
    snprintf(errbuf, errlen, "Not cached");
    return NULL;
  }

  if(fa_read(fh, p, sizeof(p)) != sizeof(p)) {
    snprintf(errbuf, errlen, "File too short");
    fa_close(fh);
    return NULL;
  }

  /* Probe format */

  if((p[6] == 'J' && p[7] == 'F' && p[8] == 'I' && p[9] == 'F') ||
     (p[6] == 'E' && p[7] == 'x' && p[8] == 'i' && p[9] == 'f')) {
      
    jpeginfo_t ji;
    
    if(jpeg_info(&ji, jpeginfo_reader, fh,
		 JPEG_INFO_DIMENSIONS |
		 JPEG_INFO_ORIENTATION |
		 (im->im_want_thumb ? JPEG_INFO_THUMBNAIL : 0),
		 p, sizeof(p), errbuf, errlen)) {
      fa_close(fh);
      return NULL;
    }

    if(im->im_want_thumb && ji.ji_thumbnail) {
      pixmap_t *pm = pixmap_dup(ji.ji_thumbnail);
      fa_close(fh);
      jpeg_info_clear(&ji);
      return pm;
    }

    fmt = PIXMAP_JPEG;

    width = ji.ji_width;
    height = ji.ji_height;
    orientation = ji.ji_orientation;

    jpeg_info_clear(&ji);

  } else if(!memcmp(pngsig, p, 8)) {
    fmt = PIXMAP_PNG;
  } else if(!memcmp(gif87sig, p, sizeof(gif87sig)) ||
	    !memcmp(gif89sig, p, sizeof(gif89sig))) {
    fmt = PIXMAP_GIF;
  } else if(!memcmp(svgsig1, p, sizeof(svgsig1)) ||
	    !memcmp(svgsig2, p, sizeof(svgsig2))) {
    fmt = PIXMAP_SVG;
  } else {
    snprintf(errbuf, errlen, "Unknown format");
    fa_close(fh);
    return NULL;
  }

  int64_t s = fa_fsize(fh);
  if(s < 0) {
    snprintf(errbuf, errlen, "Can't read from non-seekable file");
    fa_close(fh);
    return NULL;
  }

  pm = pixmap_alloc_coded(NULL, s, fmt);

  if(pm == NULL) {
    snprintf(errbuf, errlen, "Out of memory");
    fa_close(fh);
    return NULL;
  }

  pm->pm_width = width;
  pm->pm_height = height;
  pm->pm_orientation = orientation;
  fa_seek(fh, SEEK_SET, 0);
  r = fa_read(fh, pm->pm_data, pm->pm_size);
  fa_close(fh);

  if(r != pm->pm_size) {
    pixmap_release(pm);
    snprintf(errbuf, errlen, "Read error");
    return NULL;
  }
  return pm;
}
Ejemplo n.º 12
0
static void
screenshot_process(void *task)
{
  pixmap_t *pm = task;

  if(pm == NULL) {
    screenshot_response(NULL, "Screenshot not supported on this platform");
    return;
  }

  TRACE(TRACE_DEBUG, "Screenshot", "Processing image %d x %d",
        pm->pm_width, pm->pm_height);

  int codecid = AV_CODEC_ID_PNG;
  if(screenshot_connection)
    codecid = AV_CODEC_ID_MJPEG;

  buf_t *b = screenshot_compress(pm, codecid);
  pixmap_release(pm);
  if(b == NULL) {
    screenshot_response(NULL, "Unable to compress image");
    return;
  }

  if(!screenshot_connection) {
    char path[512];
    char errbuf[512];
    snprintf(path, sizeof(path), "%s/screenshot.png",
             gconf.cache_path);
    fa_handle_t *fa = fa_open_ex(path, errbuf, sizeof(errbuf),
                                 FA_WRITE, NULL);
    if(fa == NULL) {
      TRACE(TRACE_ERROR, "SCREENSHOT", "Unable to open %s -- %s",
            path, errbuf);
      buf_release(b);
      return;
    }
    fa_write(fa, buf_data(b), buf_len(b));
    fa_close(fa);
    TRACE(TRACE_INFO, "SCREENSHOT", "Written to %s", path);
    buf_release(b);
    return;
  }

  buf_t *result = NULL;
  htsbuf_queue_t hq;
  htsbuf_queue_init(&hq, 0);

  htsbuf_append(&hq, "image=", 6);
  htsbuf_append_and_escape_url_len(&hq, buf_cstr(b), buf_len(b));

  char errbuf[256];

  int ret = http_req("https://api.imgur.com/3/upload",
                     HTTP_FLAGS(FA_CONTENT_ON_ERROR),
                     HTTP_REQUEST_HEADER("Authorization",
                                         "Client-ID 7c79b311d4797ed"),
                     HTTP_RESULT_PTR(&result),
                     HTTP_POSTDATA(&hq, "application/x-www-form-urlencoded"),
                     HTTP_ERRBUF(errbuf, sizeof(errbuf)),
                     NULL);


  if(ret) {
    screenshot_response(NULL, errbuf);
  } else {

    htsmsg_t *response = htsmsg_json_deserialize(buf_cstr(result));
    if(response == NULL) {
      screenshot_response(NULL, "Unable to parse imgur response");
    } else {

      if(htsmsg_get_u32_or_default(response, "success", 0)) {
        const char *url = htsmsg_get_str_multi(response, "data", "link", NULL);
        screenshot_response(url, "No link in imgur response");
      } else {
        const char *msg = htsmsg_get_str_multi(response, "data", "error", NULL);
        if(msg == NULL) {
          screenshot_response(NULL, "Unkown imgur error");
        } else {
          snprintf(errbuf, sizeof(errbuf), "Imgur error: %s", msg);
          screenshot_response(NULL, errbuf);
        }
      }
      htsmsg_release(response);
    }
    buf_release(result);
  }
  buf_release(b);
}
Ejemplo n.º 13
0
static int
gmefile_scandir(fa_dir_t *fd, const char *url, char *errbuf, size_t errlen)
{
  void *fh = NULL;
  char *p, *fpath = mystrdupa(url);
  char name[32];
  char turl[URL_MAX];
  int tracks, i, size;
  fa_dir_entry_t *fde;
  const char *title;
  char *buf;
  Music_Emu *emu;
  gme_info_t *info;
  gme_err_t err;
  size_t r;
  if((p = strrchr(fpath, '/')) == NULL) {
    snprintf(errbuf, errlen, "Invalid filename");
    return -1;
  }

  *p = 0;
  if((fh = fa_open(fpath, errbuf, errlen)) == NULL)
    return -1;

  size = fa_fsize(fh);

  buf = malloc(size);
  r = fa_read(fh, buf, size);
  fa_close(fh);
  if(r != size) {
    snprintf(errbuf, errlen, "Unable to read file");
    free(buf);
    return -1;
  }

  err = gme_open_data(buf, size, &emu, gme_info_only);
  free(buf);
  if(err != NULL)
    return 0;

  tracks = gme_track_count(emu);
  
  for(i = 0; i < tracks; i++) {

    snprintf(turl, sizeof(turl), "gmeplayer:%s/%d", fpath, i + 1);

    err = gme_track_info(emu, &info, i);

    if(err == NULL && info->song[0]) {
      title = info->song;
    } else {
      snprintf(name, sizeof(name), "Track %02d", i + 1);
      title = name;
    }

      
    fde = fa_dir_add(fd, turl, title, CONTENT_AUDIO);

    fde->fde_probestatus = FDE_PROBE_DEEP;

    fde->fde_metadata = prop_create_root("metadata");
    prop_set_string(prop_create(fde->fde_metadata, "title"), title);

    if(err == NULL) {
      if(info->game[0])
	prop_set_string(prop_create(fde->fde_metadata, "album"), info->game);
      if(info->author[0])
	prop_set_string(prop_create(fde->fde_metadata, "artist"), info->author);

      prop_set_float(prop_create(fde->fde_metadata, "duration"), 
		     info->play_length / 1000.0);

      gme_free_info(info);
    }
  }

  gme_delete(emu);
  return 0;
}
Ejemplo n.º 14
0
image_t *
fa_imageloader(const char *url, const struct image_meta *im,
	       const char **vpaths, char *errbuf, size_t errlen,
	       int *cache_control, cancellable_t *c)
{
  uint8_t p[16];
  int r;
  int width = -1, height = -1, orientation = 0;
  fa_handle_t *fh;
  image_t *img;
  image_coded_type_t fmt;

#if ENABLE_LIBAV
  if(strchr(url, '#'))
    return fa_image_from_video(url, im, errbuf, errlen, cache_control, c);
#endif

  if(!im->im_want_thumb)
    return fa_imageloader2(url, vpaths, errbuf, errlen, cache_control, c);

  fa_open_extra_t foe = {
    .foe_cancellable = c
  };

  if((fh = fa_open_vpaths(url, vpaths, errbuf, errlen,
			  FA_BUFFERED_SMALL, &foe)) == NULL)
    return NULL;

  if(ONLY_CACHED(cache_control)) {
    snprintf(errbuf, errlen, "Not cached");
    return NULL;
  }

  if(fa_read(fh, p, sizeof(p)) != sizeof(p)) {
    snprintf(errbuf, errlen, "File too short");
    fa_close(fh);
    return NULL;
  }

  /* Probe format */

  if(p[0] == 0xff && p[1] == 0xd8 && p[2] == 0xff) {
      
    jpeginfo_t ji;
    
    if(jpeg_info(&ji, jpeginfo_reader, fh,
		 JPEG_INFO_DIMENSIONS |
		 JPEG_INFO_ORIENTATION |
		 (im->im_want_thumb ? JPEG_INFO_THUMBNAIL : 0),
		 p, sizeof(p), errbuf, errlen)) {
      fa_close(fh);
      return NULL;
    }

    if(im->im_want_thumb && ji.ji_thumbnail) {
      image_t *im = image_retain(ji.ji_thumbnail);
      fa_close(fh);
      jpeg_info_clear(&ji);
      im->im_flags |= IMAGE_ADAPTED;
      return im;
    }

    fmt = IMAGE_JPEG;

    width = ji.ji_width;
    height = ji.ji_height;
    orientation = ji.ji_orientation;

    jpeg_info_clear(&ji);

  } else if(!memcmp(pngsig, p, 8)) {
    fmt = IMAGE_PNG;
  } else if(!memcmp(gif87sig, p, sizeof(gif87sig)) ||
	    !memcmp(gif89sig, p, sizeof(gif89sig))) {
    fmt = IMAGE_GIF;
  } else if(p[0] == 'B' && p[1] == 'M') {
    fmt = IMAGE_BMP;
  } else if(!memcmp(svgsig1, p, sizeof(svgsig1)) ||
	    !memcmp(svgsig2, p, sizeof(svgsig2))) {
    fmt = IMAGE_SVG;
  } else {
    snprintf(errbuf, errlen, "Unknown format");
    fa_close(fh);
    return NULL;
  }

  int64_t s = fa_fsize(fh);
  if(s < 0) {
    snprintf(errbuf, errlen, "Can't read from non-seekable file");
    fa_close(fh);
    return NULL;
  }

  void *ptr;
  img = image_coded_alloc(&ptr, s, fmt);

  if(img == NULL) {
    snprintf(errbuf, errlen, "Out of memory");
    fa_close(fh);
    return NULL;
  }

  img->im_width = width;
  img->im_height = height;
  img->im_orientation = orientation;
  fa_seek(fh, SEEK_SET, 0);
  r = fa_read(fh, ptr, s);
  fa_close(fh);

  if(r != s) {
    image_release(img);
    snprintf(errbuf, errlen, "Read error");
    return NULL;
  }
  return img;
}
Ejemplo n.º 15
0
static int
cookie_close(void *fh)
{
  fa_close(fh);
  return 0;
}