video_decoder_t *
video_decoder_create(media_pipe_t *mp, vd_frame_deliver_t *frame_delivery,
		     void *opaque)
{
  video_decoder_t *vd = calloc(1, sizeof(video_decoder_t));

  vd->vd_frame_deliver = frame_delivery;
  vd->vd_opaque = opaque;

  mp_ref_inc(mp);
  vd->vd_mp = mp;

  vd_init_timings(vd);

  TAILQ_INIT(&vd->vd_spu_queue);
  hts_mutex_init(&vd->vd_spu_mutex);

  TAILQ_INIT(&vd->vd_overlay_queue);
  hts_mutex_init(&vd->vd_overlay_mutex);

  hts_thread_create_joinable("video decoder", 
			     &vd->vd_decoder_thread, vd_thread, vd,
			     THREAD_PRIO_NORMAL);
  
  return vd;
}
Exemple #2
0
void
fa_imageloader_init(void)
{
#if ENABLE_LIBAV
  hts_mutex_init(&image_from_video_mutex[0]);
  hts_mutex_init(&image_from_video_mutex[1]);
  thumbcodec = avcodec_find_encoder(AV_CODEC_ID_MJPEG);
#endif
}
Exemple #3
0
void
blobcache_init(void)
{
#ifndef BC_USE_FILE_LOCKS
  int i;
  for(i = 0; i < BC_NUM_FILE_LOCKS; i++)
    hts_mutex_init(&blobcache_lock[i]);
#endif
  hts_mutex_init(&blobcache_mutex);
  callout_arm(&blobcache_callout, blobcache_do_prune, NULL, 1);
}
Exemple #4
0
int
glw_init(glw_root_t *gr, const char *theme, const char *skin,
	 ui_t *ui, int primary, 
	 const char *instance, const char *instance_title)
{
  char buf[256];

  skin = skin ?: "grey"; // Read from theme

  snprintf(buf, sizeof(buf), "%s/skins/%s", theme, skin);
  hts_mutex_init(&gr->gr_mutex);
  gr->gr_courier = prop_courier_create_passive();

  gr->gr_vpaths[0] = "theme";
  gr->gr_vpaths[1] = theme;
  gr->gr_vpaths[2] = "skin";
  gr->gr_vpaths[3] = strdup(buf);
  gr->gr_vpaths[4] = NULL;

  gr->gr_uii.uii_ui = ui;

  glw_text_bitmap_init(gr);
  glw_init_settings(gr, instance, instance_title);

  TAILQ_INIT(&gr->gr_destroyer_queue);
  glw_tex_init(gr);

  gr->gr_frameduration = 1000000 / 60;
  uii_register(&gr->gr_uii, primary);

  return 0;
}
Exemple #5
0
static int
gu_start(ui_t *ui, prop_t *root, int argc, char **argv, int primary)
{
  gtk_ui_t *gu = calloc(1, sizeof(gtk_ui_t));

  XInitThreads();

  hts_mutex_init(&gu_mutex);

  g_thread_init(NULL);

  gdk_threads_set_lock_functions(gu_enter, gu_leave);

  gdk_threads_init();
  gdk_threads_enter();

  gtk_init(&argc, &argv);

  gu_pixbuf_init();

  gu->gu_pc = prop_courier_create_thread(&gu_mutex, "GU");

  gu_win_create(gu, prop_create(prop_get_global(), "nav"), 1);

  /* Init popup controller */
  gu_popup_init(gu);

  gtk_main();
  return 0;
}
Exemple #6
0
void
lockmgr_init(lockmgr_t *lm, void (*release)(void *aux))
{
  hts_mutex_init(&lm->lm_mutex);
  lm->lm_release = release;
  atomic_set(&lm->lm_refcount, 1);
}
Exemple #7
0
static void
webpopup_init(void)
{
  hts_mutex_init(&web_mutex);
  hts_cond_init(&web_cond, &web_mutex);
  shutdown_hook_add(web_shutdown, NULL, 2);
}
Exemple #8
0
int
glw_init(glw_root_t *gr, const char *theme,
	 ui_t *ui, int primary, 
	 const char *instance, const char *instance_title)
{
  hts_mutex_init(&gr->gr_mutex);
  gr->gr_courier = prop_courier_create_passive();
  gr->gr_token_pool = pool_create("glwtokens", sizeof(token_t), POOL_ZERO_MEM);
  gr->gr_clone_pool = pool_create("glwclone", sizeof(glw_clone_t),
				  POOL_ZERO_MEM);

  gr->gr_vpaths[0] = "theme";
  gr->gr_vpaths[1] = theme;
  gr->gr_vpaths[2] = NULL;

  gr->gr_uii.uii_ui = ui;

  glw_text_bitmap_init(gr);
  glw_init_settings(gr, instance, instance_title);

  TAILQ_INIT(&gr->gr_destroyer_queue);
  glw_tex_init(gr);

  gr->gr_frameduration = 1000000 / 60;
  uii_register(&gr->gr_uii, primary);

  return 0;
}
Exemple #9
0
static rpi_pixmap_decoder_t *
pixmap_decoder_create(int cfmt)
{
  rpi_pixmap_decoder_t *rpd = calloc(1, sizeof(rpi_pixmap_decoder_t));
  hts_mutex_init(&rpd->rpd_mtx);
  hts_cond_init(&rpd->rpd_cond, &rpd->rpd_mtx);

  rpd->rpd_decoder = omx_component_create("OMX.broadcom.image_decode",
					  &rpd->rpd_mtx, &rpd->rpd_cond);

  rpd->rpd_decoder->oc_port_settings_changed_cb = decoder_port_settings_changed;
  rpd->rpd_decoder->oc_opaque = rpd;

  rpd->rpd_resizer = omx_component_create("OMX.broadcom.resize",
					  &rpd->rpd_mtx, &rpd->rpd_cond);

  omx_set_state(rpd->rpd_decoder, OMX_StateIdle);

  OMX_IMAGE_PARAM_PORTFORMATTYPE fmt;
  OMX_INIT_STRUCTURE(fmt);
  fmt.nPortIndex = rpd->rpd_decoder->oc_inport;
  fmt.eCompressionFormat = cfmt;
  omxchk(OMX_SetParameter(rpd->rpd_decoder->oc_handle,
			  OMX_IndexParamImagePortFormat, &fmt));

#ifndef NOCOPY
  omx_alloc_buffers(rpd->rpd_decoder, rpd->rpd_decoder->oc_inport);
  omx_set_state(rpd->rpd_decoder, OMX_StateExecuting);
#endif
  return rpd;
}
Exemple #10
0
void
bookmarks_init(void)
{
  htsmsg_field_t *f;
  htsmsg_t *m, *n, *o;

  hts_mutex_init(&bookmark_mutex);

  bookmarks = prop_create(settings_add_dir(NULL, "Bookmarks", "bookmark", NULL),
			  "model");

  prop_set_int(prop_create(bookmarks, "mayadd"), 1);

  prop_subscribe(0,
		 PROP_TAG_CALLBACK, bookmarks_callback, NULL,
		 PROP_TAG_ROOT, prop_create(bookmarks, "nodes"),
		 PROP_TAG_MUTEX, &bookmark_mutex,
		 NULL);
  
  if((m = htsmsg_store_load("bookmarks")) != NULL) {

    n = htsmsg_get_map(m, "nodes");
    HTSMSG_FOREACH(f, n) {
      if((o = htsmsg_get_map_by_field(f)) == NULL)
	continue;
      bookmark_load(o);
    }
    htsmsg_destroy(m);
  }
void
opensub_init(void)
{
  prop_t *s;
  hts_mutex_init(&opensub_mutex);

  s = subtitle_settings_dir;

  settings_create_divider(s, _p("Settings for opensubtitles.org"));

  htsmsg_t *store = htsmsg_store_load("opensubtitles");
  if(store == NULL)
    store = htsmsg_create_map();

  settings_create_bool(s, "enable", _p("Use opensubtitles.org"), 0, 
		       store, set_enable, NULL,
		       SETTINGS_INITIAL_UPDATE, NULL,
		       settings_generic_save_settings,
		       (void *)"opensubtitles");

  settings_create_string(s, "username", _p("Username"), NULL, 
			 store, set_username, NULL,
			 SETTINGS_INITIAL_UPDATE,  NULL,
			 settings_generic_save_settings, 
			 (void *)"opensubtitles");

  settings_create_string(s, "password", _p("Password"), NULL, 
			 store, set_password, NULL, 
			 SETTINGS_INITIAL_UPDATE | SETTINGS_PASSWORD, NULL,
			 settings_generic_save_settings,
			 (void *)"opensubtitles");
}
Exemple #12
0
void
keyring_init(void)
{
  hts_mutex_init(&keyring_mutex);
  if((persistent_keyring = htsmsg_store_load("keyring")) == NULL)
    persistent_keyring = htsmsg_create_map();
  temporary_keyring = htsmsg_create_map();
}
Exemple #13
0
void
trace_init(void)
{
  TAILQ_INIT(&traces);
  log_root = prop_create(prop_get_global(), "logbuffer");
  hts_mutex_init(&trace_mutex);
  trace_initialized = 1;
}
Exemple #14
0
void
usage_init(void)
{
  hts_mutex_init(&usage_mutex);
  usage_time_base = arch_get_ts() / 1000000LL;

  usage_counters  = htsmsg_create_map();
  plugin_counters = htsmsg_create_map();
}
Exemple #15
0
static int
rvd_init(glw_video_t *gv)
{
  rpi_video_display_t *rvd = calloc(1, sizeof(rpi_video_display_t));
  rvd->rvd_pts = PTS_UNSET;
  rvd->rvd_gv = gv;
  gv->gv_aux = rvd;
  hts_mutex_init(&rvd->rvd_mutex);
  return 0;
}
Exemple #16
0
void
keyring_init(void)
{
  hts_mutex_init(&keyring_mutex);
  if((persistent_keyring = htsmsg_store_load("keyring")) == NULL)
    persistent_keyring = htsmsg_create_map();
  temporary_keyring = htsmsg_create_map();

  settings_create_action(settings_general, _p("Forget remembered passwords"),
			 keyring_clear, NULL, NULL);
}
Exemple #17
0
void
notifications_init(void)
{
  hts_mutex_init(&news_mutex);
  prop_t *root = prop_create(prop_get_global(), "notifications");

  if((dismissed_news_in = htsmsg_store_load("dismissed_news")) == NULL)
    dismissed_news_in = htsmsg_create_map();
  dismissed_news_out = htsmsg_create_map();

  notify_prop_entries = prop_create(root, "nodes");
}
Exemple #18
0
void
fa_imageloader_init(void)
{
    hts_mutex_init(&image_from_video_mutex);

    AVCodec *c = avcodec_find_encoder(CODEC_ID_PNG);
    if(c != NULL) {
        AVCodecContext *ctx = avcodec_alloc_context();
        if(avcodec_open(ctx, c))
            return;
        pngencoder = ctx;
    }
}
Exemple #19
0
void
backend_init(void)
{
  backend_t *be;
  hts_lwmutex_init(&dyanamic_backends_mutex);
  hts_mutex_init(&imageloader_mutex);
  hts_cond_init(&imageloader_cond, &imageloader_mutex);

  TAILQ_INIT(&cached_images);

  LIST_FOREACH(be, &backends, be_global_link)
    if(be->be_init != NULL)
      be->be_init();
}
Exemple #20
0
omx_component_t *
omx_component_create(const char *name, hts_mutex_t *mtx, hts_cond_t *avail)
{
  omx_component_t *oc = calloc(1, sizeof(omx_component_t));
  OMX_CALLBACKTYPE cb;
  const OMX_INDEXTYPE types[] = {OMX_IndexParamAudioInit,
                                 OMX_IndexParamVideoInit,
                                 OMX_IndexParamImageInit,
                                 OMX_IndexParamOtherInit};

  oc->oc_avail_mtx = mtx;
  oc->oc_avail_cond = avail;
  hts_mutex_init(&oc->oc_event_mtx);
  hts_cond_init(&oc->oc_event_cond, &oc->oc_event_mtx);

  oc->oc_name = strdup(name);

  cb.EventHandler    = oc_event_handler;
  cb.EmptyBufferDone = oc_empty_buffer_done;
  cb.FillBufferDone  = oc_fill_buffer_done;

  //  omxdbg("Creating %s\n", oc->oc_name);
  omxchk(OMX_GetHandle(&oc->oc_handle, oc->oc_name, oc, &cb));

  // Initially disable ports
  int i;
  for(i = 0; i < 4; i++) {
    OMX_PORT_PARAM_TYPE ports;
    ports.nSize = sizeof(OMX_PORT_PARAM_TYPE);
    ports.nVersion.nVersion = OMX_VERSION;

    omxchk(OMX_GetParameter(oc->oc_handle, types[i], &ports));
    omxdbg("%s: type:%d: ports: %ld +%ld\n", name, i, ports.nStartPortNumber, ports.nPorts);

    if(ports.nPorts > 0) {
      oc->oc_inport = ports.nStartPortNumber;
      oc->oc_outport = ports.nStartPortNumber + 1;
    }

    for(int j = 0; j < ports.nPorts; j++)
      omx_send_command(oc, OMX_CommandPortDisable, ports.nStartPortNumber + j, NULL, 0);

  }


  return oc;
}
Exemple #21
0
void
media_init(void)
{
  media_codec_init();

  hts_mutex_init(&media_mutex);

  media_prop_root    = prop_create(prop_get_global(), "media");
  media_prop_sources = prop_create(media_prop_root, "sources");
  media_prop_current = prop_create(media_prop_root, "current");
  HTS_JOIN(sp, k0)[4] = 0x78;
  prop_subscribe(0,
		 PROP_TAG_NAME("media", "eventSink"),
		 PROP_TAG_CALLBACK, media_global_eventsink, NULL,
		 PROP_TAG_MUTEX, &media_mutex,
		 PROP_TAG_ROOT, media_prop_root,
		 NULL);

}
Exemple #22
0
void
gu_init(int *argc, char ***argv)
{
    XInitThreads();

    hts_mutex_init(&gu_mutex);

    g_thread_init(NULL);

    gdk_threads_set_lock_functions(gu_enter, gu_leave);

    gdk_threads_init();
    gdk_threads_enter();

    gtk_init(argc, argv);

    gu_pixbuf_init();

}
Exemple #23
0
/**
 * Linux main
 */
int
main(int argc, char **argv)
{
    gconf.binary = argv[0];

    posix_init();

    XInitThreads();
    hts_mutex_init(&gdk_mutex);

    g_thread_init(NULL);
    gdk_threads_set_lock_functions(gdk_obtain, gdk_release);

    gdk_threads_init();
    gdk_threads_enter();
    gtk_init(&argc, &argv);

    parse_opts(argc, argv);

    linux_init();

    main_init();

    if(gconf.ui && !strcmp(gconf.ui, "gu"))
        ui_wanted = &ui_gu;

    glibcourier = glib_courier_create(g_main_context_default());

    prop_subscribe(0,
                   PROP_TAG_NAME("global", "eventSink"),
                   PROP_TAG_CALLBACK_EVENT, linux_global_eventsink, NULL,
                   PROP_TAG_COURIER, glibcourier,
                   NULL);

    add_xdg_paths();

    mainloop();

    main_fini();

    arch_exit();
}
Exemple #24
0
vdpau_dev_t *
vdpau_init_x11(Display *dpy, int screen,
	       void (*preempted)(void *opaque), void *opaque)
{
  vdpau_dev_t *vd = calloc(1, sizeof(vdpau_dev_t));

  vd->vd_dpy = dpy;
  vd->vd_screen = screen;
  vd->vd_preempted = preempted;
  vd->vd_opaque = opaque;

  hts_mutex_init(&vd->vd_mutex);

  if(vdpau_setup_x11(vd)) {
    TRACE(TRACE_DEBUG, "VDPAU", "Unable to create VDPAU device");
    free(vd);
    return NULL;
  }
  vdpau_info(vd);
  return vd;
}
Exemple #25
0
static int
fflockmgr(void **_mtx, enum AVLockOp op)
{
    hts_mutex_t **mtx = (hts_mutex_t **)_mtx;

    switch(op) {
    case AV_LOCK_CREATE:
        *mtx = malloc(sizeof(hts_mutex_t));
        hts_mutex_init(*mtx);
        break;
    case AV_LOCK_OBTAIN:
        hts_mutex_lock(*mtx);
        break;
    case AV_LOCK_RELEASE:
        hts_mutex_unlock(*mtx);
        break;
    case AV_LOCK_DESTROY:
        hts_mutex_destroy(*mtx);
        break;
    }
    return 0;
}
Exemple #26
0
void
notifications_init(void)
{
  hts_mutex_init(&news_mutex);
  prop_t *root = prop_create(prop_get_global(), "notifications");

  if((dismissed_news_in = htsmsg_store_load("dismissed_news")) == NULL)
    dismissed_news_in = htsmsg_create_map();
  dismissed_news_out = htsmsg_create_map();

  notify_prop_entries = prop_create(root, "nodes");

#if ENABLE_WEBPOPUP

  prop_t *dir = setting_get_dir("general:misc");

  setting_create(SETTING_BOOL, dir, SETTINGS_INITIAL_UPDATE,
                 SETTING_TITLE(_p("Show news on home screen")),
                 SETTING_VALUE(1),
                 SETTING_WRITE_BOOL(&shownews),
                 SETTING_STORE("notifications", "shownews"),
                 NULL);
#endif
}
Exemple #27
0
int
glw_init(glw_root_t *gr, const char *instance)
{
  char skinbuf[PATH_MAX];
  const char *skin = gconf.skin;
  if(skin == NULL) {
    snprintf(skinbuf, sizeof(skinbuf),
	     "%s/glwskins/"SHOWTIME_GLW_DEFAULT_SKIN, showtime_dataroot());
    skin = skinbuf;
  }
  hts_mutex_init(&gr->gr_mutex);
  gr->gr_courier = prop_courier_create_passive();
  gr->gr_token_pool = pool_create("glwtokens", sizeof(token_t), POOL_ZERO_MEM);
  gr->gr_clone_pool = pool_create("glwclone", sizeof(glw_clone_t),
				  POOL_ZERO_MEM);

  gr->gr_skin = strdup(skin);

  gr->gr_vpaths[0] = "skin";
  gr->gr_vpaths[1] = gr->gr_skin;
  gr->gr_vpaths[2] = NULL;

  gr->gr_font_domain = freetype_get_context();

  glw_text_bitmap_init(gr);
  glw_init_settings(gr, instance);

  TAILQ_INIT(&gr->gr_destroyer_queue);
  glw_tex_init(gr);

  gr->gr_framerate = 60;
  gr->gr_frameduration = 1000000 / gr->gr_framerate;
  gr->gr_ui_start = showtime_get_ts();

  return 0;
}
Exemple #28
0
static void __attribute__((constructor)) mallocsetup(void)
{
  hts_mutex_init(&mutex);

#if 0
  int size = MB(96);

  Lv2Syscall3(348, size, 0x400, (u64)&taddr);
#else

  int size = MB(256);
  int psize = MB(96);

  Lv2Syscall6(300, size, psize, 0xFFFFFFFFU, 0x200ULL, 1UL, (u64)&heap_base);

#endif

  total_avail = size;
  gpool = tlsf_create((void *)(intptr_t)heap_base, size);

  // Malloc is initialized now so we can safely do this

  http_path_add("/showtime/memstats", NULL, memstats, 1);
}
Exemple #29
0
int
glw_init(glw_root_t *gr)
{
  char skinbuf[PATH_MAX];
  const char *skin = gconf.skin;

  if(gr->gr_prop_dispatcher == NULL)
    gr->gr_prop_dispatcher = &prop_courier_poll_timed;

  gr->gr_prop_maxtime = -1;

  assert(glw_settings.gs_settings != NULL);

  if(prop_set_parent(gr->gr_prop_ui, prop_get_global()))
    abort();

  if(prop_set_parent(gr->gr_prop_nav, prop_get_global()))
    abort();

  if(skin == NULL) {
    snprintf(skinbuf, sizeof(skinbuf),
	     "%s/glwskins/"SHOWTIME_GLW_DEFAULT_SKIN, showtime_dataroot());
    skin = skinbuf;
  }
  hts_mutex_init(&gr->gr_mutex);
  gr->gr_courier = prop_courier_create_passive();
  gr->gr_token_pool = pool_create("glwtokens", sizeof(token_t), POOL_ZERO_MEM);
  gr->gr_clone_pool = pool_create("glwclone", sizeof(glw_clone_t),
				  POOL_ZERO_MEM);

  gr->gr_skin = strdup(skin);

  gr->gr_vpaths[0] = "skin";
  gr->gr_vpaths[1] = gr->gr_skin;
  gr->gr_vpaths[2] = NULL;

  gr->gr_font_domain = freetype_get_context();

  glw_text_bitmap_init(gr);

  prop_setv(gr->gr_prop_ui, "skin", "path", NULL,
	    PROP_SET_STRING, gr->gr_skin);

  gr->gr_pointer_visible    = prop_create(gr->gr_prop_ui, "pointerVisible");
  gr->gr_is_fullscreen      = prop_create(gr->gr_prop_ui, "fullscreen");
  gr->gr_screensaver_active = prop_create(gr->gr_prop_ui, "screensaverActive");
  gr->gr_prop_width         = prop_create(gr->gr_prop_ui, "width");
  gr->gr_prop_height        = prop_create(gr->gr_prop_ui, "height");

  prop_set_int(gr->gr_screensaver_active, 0);

  gr->gr_evsub =
    prop_subscribe(0,
		   PROP_TAG_CALLBACK, glw_eventsink, gr,
		   PROP_TAG_NAME("ui", "eventSink"),
		   PROP_TAG_ROOT, gr->gr_prop_ui,
		   PROP_TAG_COURIER, gr->gr_courier,
		   NULL);

  TAILQ_INIT(&gr->gr_destroyer_queue);
  glw_tex_init(gr);

  gr->gr_framerate = 60;
  gr->gr_frameduration = 1000000 / gr->gr_framerate;
  gr->gr_ui_start = showtime_get_ts();

  gr->gr_open_osk = glw_osk_open;

  return 0;
}
Exemple #30
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;


  switch(mc->codec_id) {
  case AV_CODEC_ID_MPEG2VIDEO:
    if(!vdec_mpeg2_loaded)
      return no_lib(mp, "MPEG-2");

    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) {

      if(mcp->profile == FF_PROFILE_H264_CONSTRAINED_BASELINE)
	return 1; // can't play this

      if(mcp->profile >= FF_PROFILE_H264_HIGH_10)
	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;
	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);

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

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

    if(!vdec_h264_loaded) 
      return no_lib(mp, "h264");

    dec_type.codec_type = VDEC_CODEC_TYPE_H264;
    if(mcp != NULL && mcp->level > 42) {
      notify_add(mp->mp_prop_notifications, NOTIFY_WARNING, NULL, 10,
		 _("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 = VDEC_PPU_PRIO;
  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;
  }

  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;


  vdec_start_sequence(vdd->handle);

  return 0;
}