Beispiel #1
0
void
backend_unregister_dynamic(backend_t *be)
{
  hts_lwmutex_lock(&dyanamic_backends_mutex);
  LIST_REMOVE(be, be_global_link);
  hts_lwmutex_unlock(&dyanamic_backends_mutex);
}
Beispiel #2
0
void free(void *ptr)
{
  if(ptr == NULL)
    return;
  const int bs = tlsf_block_size(ptr);

  if(bs >= 65536) {
    const int p = (intptr_t)ptr;

    const int np = ROUND_UP(p, 65536);
    int s = bs - (np - p);
    if(s > 0) {
      s &= ~0xffff;
      if(s > 0) {
#if 0
	tracelog(TRACE_NO_PROP, TRACE_DEBUG, "MEMORY",
	      "free(%p+%d) == page_free(0x%x+%d)",
	      ptr, bs, np, s);
#endif
#ifdef USE_VIRTUAL_MEM
	if(Lv2Syscall2(308, np, s))  // Invalidate
	  tracelog(TRACE_NO_PROP, TRACE_ERROR, "MEMORY",
		"Invalidate failed");
	if(Lv2Syscall2(310, np, s))  // Sync
	  tracelog(TRACE_NO_PROP, TRACE_ERROR, "MEMORY",
		"Sync failed");
#endif
      }
    }
  }
  hts_lwmutex_lock(&mutex);
  tlsf_free(gpool, ptr);
  hts_lwmutex_unlock(&mutex);
}
Beispiel #3
0
void
backend_register_dynamic(backend_t *be)
{
  hts_lwmutex_lock(&dyanamic_backends_mutex);
  LIST_INSERT_HEAD(&dynamic_backends, be, be_global_link);
  hts_lwmutex_unlock(&dyanamic_backends_mutex);
}
Beispiel #4
0
void myfree(void *ptr)
{
  if(ptr == NULL)
    return;
  hts_lwmutex_lock(&mutex);
  tlsf_free(gpool, ptr);
  hts_lwmutex_unlock(&mutex);
}
Beispiel #5
0
struct mallinfo mallinfo(void)
{
  struct mallinfo mi;
  mi.arena =  total_avail;
  hts_lwmutex_lock(&mutex);
  mi.uordblks = tlsf_used(gpool);
  hts_lwmutex_unlock(&mutex);
  mi.fordblks = mi.arena - mi.uordblks;
  return mi;
}
Beispiel #6
0
void 
verify_heap(void)
{
  hts_lwmutex_lock(&mutex);
  int r = tlsf_check_heap(gpool);
  hts_lwmutex_unlock(&mutex);

  if(r)
    tracelog(TRACE_NO_PROP, TRACE_ERROR, "HEAPCHECK", "Heap check verify failed");
  else
    tracelog(TRACE_NO_PROP, TRACE_DEBUG, "HEAPCHECK", "Heap OK");
}
Beispiel #7
0
void *
myrealloc(void *ptr, size_t bytes)
{
  hts_lwmutex_lock(&mutex);
  void *r = tlsf_realloc(gpool, ptr, bytes);

  hts_lwmutex_unlock(&mutex);
  if(r == NULL) {
    memtrace();
    tracelog(TRACE_NO_PROP, TRACE_ERROR, "MEMORY",
          "realloc(%d) failed", (int)bytes);
    errno = ENOMEM;
  }
  return r;
}
Beispiel #8
0
void *memalign(size_t align, size_t bytes)
{
  void *r;
  if(bytes == 0)
    return NULL;

  hts_lwmutex_lock(&mutex);
  r = tlsf_memalign(gpool, align, bytes);
  hts_lwmutex_unlock(&mutex);
  if(r == NULL) {
    memtrace();
    panic("OOM: memalign(%d, %d)", (int)align, (int)bytes);
  }
  return r;
}
Beispiel #9
0
void *malloc(size_t bytes)
{
  void *r;
  if(bytes == 0)
    return NULL;

  hts_lwmutex_lock(&mutex);
  r = tlsf_malloc(gpool, bytes);
  hts_lwmutex_unlock(&mutex);
  if(r == NULL) {
    memtrace();
    panic("OOM: malloc(%d)", (int)bytes);
  }
  return r;
}
Beispiel #10
0
void *mymemalign(size_t align, size_t bytes)
{
  if(bytes == 0)
    return NULL;

  hts_lwmutex_lock(&mutex);
  void *r = tlsf_memalign(gpool, align, bytes);
  hts_lwmutex_unlock(&mutex);
  if(r == NULL) {
    memtrace();
    tracelog(TRACE_NO_PROP, TRACE_ERROR, "MEMORY",
          "memalign(%d,%d) failed", (int)align, (int)bytes);
    errno = ENOMEM;
  }
  return r;
}
Beispiel #11
0
void *realloc(void *ptr, size_t bytes)
{
  void *r;

  if(bytes == 0) {
    free(ptr);
    return NULL;
  }

  hts_lwmutex_lock(&mutex);
  r = tlsf_realloc(gpool, ptr, bytes);
  hts_lwmutex_unlock(&mutex);
  if(r == NULL) {
    memtrace();
    panic("OOM: realloc(%p, %d)", ptr, (int)bytes);
  }
  return r;
}
Beispiel #12
0
static void
memtrace(void)
{
  memstats_t ms = {0};
  hts_lwmutex_lock(&mutex);
  tlsf_walk_heap(gpool, mywalker, &ms);
  hts_lwmutex_unlock(&mutex);

  tracelog(TRACE_NO_PROP, TRACE_ERROR, "MEMORY",
        "Memory allocator status -- Used: %d (%d segs) Free: %d (%d segs)",
        ms.used, ms.used_segs, ms.free, ms.free_segs);

  for(int i = 0; i < 33; i++) {
    tracelog(TRACE_NO_PROP, TRACE_ERROR, "MEMORY",
          "%2d: %8d %8d",
          i, ms.hist_used[i], ms.hist_free[i]);
  }
}
Beispiel #13
0
static int
memstats(http_connection_t *hc, const char *remain, void *opaque,
	 http_cmd_t method)
{
  htsbuf_queue_t out;
  allsegs_t as = {};

  hts_lwmutex_lock(&mutex);
  tlsf_walk_heap(gpool, list_all_segs_walk, &as);
  int size = as.count * sizeof(seginfo_t);
  as.ptr = halloc(size);
  as.count = 0;
  tlsf_walk_heap(gpool, list_all_segs_walk, &as);
  hts_lwmutex_unlock(&mutex);

  qsort(as.ptr, as.count, sizeof(seginfo_t), seginfo_cmp);

  htsbuf_queue_init(&out, 0);

  htsbuf_qprintf(&out, "%d segments ptr=%p\n\n", as.count, as.ptr);
  int lastsize = -1;
  int dup = 0;
  for(int i = 0; i < as.count; i++) {
    if(as.ptr[i].size == lastsize && i != as.count - 1) {
      dup++;
    } else {
      htsbuf_qprintf(&out, "%s %10d * %d\n",
		     as.ptr[i].used ? "Used" : "Free", as.ptr[i].size,
		     dup + 1);
      dup = 0;
    }
    lastsize = as.ptr[i].size;
  }

  hfree(as.ptr, size);
  

  return http_send_reply(hc, 0, "text/plain", NULL, NULL, 0, &out);
}
Beispiel #14
0
static int
video_ps3_vdec_codec_create(media_codec_t *mc, const media_codec_params_t *mcp,
			    media_pipe_t *mp)
{
  vdec_decoder_t *vdd;
  struct vdec_type dec_type = {0};
  struct vdec_attr dec_attr = {0};
  int spu_threads;
  int r;
  int crop_right = 0;
  int crop_bottom = 0;

  switch(mc->codec_id) {
  case AV_CODEC_ID_MPEG2VIDEO:

    hts_lwmutex_lock(&ps3_codec_sysmodule_mutex);
    if(vdec_mpeg2_loaded == -1)
      vdec_mpeg2_loaded = !SysLoadModule(SYSMODULE_VDEC_MPEG2);

    if(!vdec_mpeg2_loaded) {
      hts_lwmutex_unlock(&ps3_codec_sysmodule_mutex);
      return no_lib(mp, "MPEG-2");
    }
    hts_lwmutex_unlock(&ps3_codec_sysmodule_mutex);

    dec_type.codec_type = VDEC_CODEC_TYPE_MPEG2;
    dec_type.profile_level = VDEC_MPEG2_MP_HL;
    spu_threads = 1;
    break;

  case AV_CODEC_ID_H264:
    if(mcp != NULL) {
      TRACE(TRACE_DEBUG, "VDEC", "H264: Profile:%d Level:%d",
            mcp->profile, mcp->level);

      if(mcp->profile != FF_PROFILE_H264_CONSTRAINED_BASELINE &&
         mcp->profile >= FF_PROFILE_H264_HIGH_10) {
        TRACE(TRACE_DEBUG, "VDEC",
              "Refusing to play h264 profile %d", mcp->profile);
	return 1; // No 10bit support
      }
      if(mcp->extradata != NULL) {
	h264_parser_t hp;

	hexdump("extradata", mcp->extradata, mcp->extradata_size);

	if(h264_parser_init(&hp, mcp->extradata, mcp->extradata_size)) {
	  notify_add(mp->mp_prop_notifications, NOTIFY_WARNING, NULL, 10,
		     _("Cell-h264: Broken headers, Disabling acceleration"));
	  return -1;
	}

	TRACE(TRACE_DEBUG, "VDEC", "Dumping SPS");
	int too_big_refframes = 0;
        int mb_height = 0;
	for(int i = 0; i < H264_PARSER_NUM_SPS; i++) {
	  const h264_sps_t *s = &hp.sps_array[i];
	  if(!s->present)
	    continue;
	  TRACE(TRACE_DEBUG, "VDEC",
		"SPS[%d]: %d x %d profile:%d level:%d.%d ref-frames:%d",
		i, s->mb_width * 16, s->mb_height * 16,
		s->profile,
		s->level / 10,
		s->level % 10,
		s->num_ref_frames);

	  TRACE(TRACE_DEBUG, "VDEC",
                "        crop: left:%d right:%d top:%d bottom:%d",
                s->crop_left,
                s->crop_right,
                s->crop_top,
                s->crop_bottom);

          crop_right  = s->crop_right;
          crop_bottom = s->crop_bottom;

	  if(s->mb_height >= 45 && s->num_ref_frames > 9)
	    too_big_refframes = s->num_ref_frames;

	  if(s->mb_height >= 68 && s->num_ref_frames > 4)
	    too_big_refframes = s->num_ref_frames;
          mb_height = s->mb_height;
	}
	h264_parser_fini(&hp);

	if(too_big_refframes) {
	  notify_add(mp->mp_prop_notifications, NOTIFY_WARNING, NULL, 10,
		     _("Cell-h264: %d Ref-frames for %d content is incompatible with PS3 HW decoder. Disabling acceleration"), too_big_refframes,
                     mb_height * 16);
	  return -1;
	}
      }
    }

    hts_lwmutex_lock(&ps3_codec_sysmodule_mutex);
    if(vdec_h264_loaded == -1)
      vdec_h264_loaded = !SysLoadModule(SYSMODULE_VDEC_H264);

    if(!vdec_h264_loaded) {
      hts_lwmutex_unlock(&ps3_codec_sysmodule_mutex);
      return no_lib(mp, "h264");
    }
    hts_lwmutex_unlock(&ps3_codec_sysmodule_mutex);

    dec_type.codec_type = VDEC_CODEC_TYPE_H264;
    if(mcp != NULL && mcp->level > 42) {
      notify_add(mp->mp_prop_notifications, NOTIFY_WARNING, NULL, 5,
		 _("Cell-h264: Forcing level 4.2 for content in level %d.%d. This may break video playback."), mcp->level / 10, mcp->level % 10);
    }
    dec_type.profile_level = 42;
    spu_threads = 4;
    break;

  default:
    return 1;
  }

  r = vdec_query_attr(&dec_type, &dec_attr);
  if(r) {
    notify_add(mp->mp_prop_notifications, NOTIFY_WARNING, NULL, 10,
	       _("Unable to query Cell codec. Error 0x%x"), r);
    return 1;
  }

  vdd = calloc(1, sizeof(vdec_decoder_t));


#define ROUND_UP(p, round) ((p + round - 1) & ~(round - 1))

  size_t allocsize = ROUND_UP(dec_attr.mem_size, 1024*1024);
  u32 taddr;

  if(Lv2Syscall3(348, allocsize, 0x400, (u64)&taddr)) {
    notify_add(mp->mp_prop_notifications, NOTIFY_WARNING, NULL, 10,
	       _("Unable to open Cell codec. Unable to allocate %d bytes of RAM"), dec_attr.mem_size);
    return 1;
  }
  vdd->mem = (void *)(uint64_t)taddr;

  TRACE(TRACE_DEBUG, "VDEC", "Opening codec %s level %d using %d bytes of RAM",
	mc->codec_id == AV_CODEC_ID_H264 ? "h264" : "MPEG2",
	dec_type.profile_level,
	dec_attr.mem_size);

  vdd->config.mem_addr = (intptr_t)vdd->mem;
  vdd->config.mem_size = dec_attr.mem_size;
  vdd->config.num_spus = spu_threads;
  vdd->config.ppu_thread_prio = THREAD_PRIO_VDEC;
  vdd->config.spu_thread_prio = VDEC_SPU_PRIO;
  vdd->config.ppu_thread_stack_size = 1 << 14;

  vdec_closure c;
  c.fn = (intptr_t)OPD32(decoder_callback);
  c.arg = (intptr_t)vdd;

  r = vdec_open(&dec_type, &vdd->config, &c, &vdd->handle);
  if(r) {
    notify_add(mp->mp_prop_notifications, NOTIFY_WARNING, NULL, 10,
	       _("Unable to open Cell codec. Error 0x%x"), r);
    Lv2Syscall1(349, (uint64_t)vdd->mem);
    free(vdd);
    return 1;
  }

  if(mcp != NULL) {
    vdd->level_major = mcp->level / 10;
    vdd->level_minor = mcp->level % 10;
    vdd->filter_aud = mcp->broken_aud_placement;
  }

  if(mc->codec_id == AV_CODEC_ID_H264 && mcp != NULL && mcp->extradata_size)
    h264_to_annexb_init(&vdd->annexb, mcp->extradata, mcp->extradata_size);

  vdd->max_order = -1;

  hts_mutex_init(&vdd->mtx);
  hts_cond_init(&vdd->audone, &vdd->mtx);
  hts_cond_init(&vdd->seqdone, &vdd->mtx);

  TRACE(TRACE_DEBUG, "VDEC", 
	"Cell accelerated codec created using %d bytes of RAM",
	dec_attr.mem_size);

  mc->opaque = vdd;
  mc->decode = decoder_decode;
  mc->flush  = decoder_flush;
  mc->close  = decoder_close;

  vdd->crop_right = crop_right;
  vdd->crop_bottom = crop_bottom;


  vdec_start_sequence(vdd->handle);

  return 0;
}