static int AndroidWindow_Setup(vout_display_sys_t *sys, android_window *p_window, unsigned int i_pic_count) { bool b_java_configured = false; if (i_pic_count != 0) p_window->i_pic_count = i_pic_count; if (!p_window->b_opaque) { int align_pixels; picture_t *p_pic = PictureAlloc(sys, &p_window->fmt, false); // For RGB (32 or 16) we need to align on 8 or 4 pixels, 16 pixels for YUV align_pixels = (16 / p_pic->p[0].i_pixel_pitch) - 1; p_window->fmt.i_height = p_pic->format.i_height; p_window->fmt.i_width = (p_pic->format.i_width + align_pixels) & ~align_pixels; picture_Release(p_pic); if (AndroidWindow_SetupANW(sys, p_window, b_java_configured) != 0) return -1; } else { sys->p_window->i_pic_count = 31; // TODO sys->p_window->i_min_undequeued = 0; } return 0; }
static void Prepare(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture, vlc_tick_t date) { vout_display_sys_t *sys = vd->sys; VLC_UNUSED(picture); if (subpicture && sys->p_sub_window) { if (sys->b_sub_invalid) { sys->b_sub_invalid = false; if (sys->p_sub_pic) { picture_Release(sys->p_sub_pic); sys->p_sub_pic = NULL; } if (sys->p_spu_blend) { filter_DeleteBlend(sys->p_spu_blend); sys->p_spu_blend = NULL; } free(sys->p_sub_buffer_bounds); sys->p_sub_buffer_bounds = NULL; } if (!sys->p_sub_pic && AndroidWindow_Setup(sys, sys->p_sub_window, 1) == 0) sys->p_sub_pic = PictureAlloc(sys, &sys->p_sub_window->fmt, false); if (!sys->p_spu_blend && sys->p_sub_pic) sys->p_spu_blend = filter_NewBlend(VLC_OBJECT(vd), &sys->p_sub_pic->format); if (sys->p_sub_pic && sys->p_spu_blend) sys->b_has_subpictures = true; } /* As long as no subpicture was received, do not call SubpictureDisplay since JNI calls and clearing the subtitles surface are expensive operations. */ if (sys->b_has_subpictures) { SubpicturePrepare(vd, subpicture); if (!subpicture) { /* The surface has been cleared and there is no new subpicture to upload, do not clear again until a new subpicture is received. */ sys->b_has_subpictures = false; } } if (sys->p_window->b_opaque && AndroidOpaquePicture_CanReleaseAtTime(picture->p_sys)) { vlc_tick_t now = vlc_tick_now(); if (date > now) { if (date - now <= VLC_TICK_FROM_SEC(1)) AndroidOpaquePicture_ReleaseAtTime(picture->p_sys, date); else /* The picture will be displayed from the Display callback */ msg_Warn(vd, "picture way too early to release at time"); } } }
static picture_pool_t * PoolAlloc( vout_display_t *vd, unsigned i_requested_count ) { picture_t **pp_pics = NULL; picture_pool_t *p_pool; picture_pool_configuration_t pool_cfg; msg_Dbg(vd, "PoolAlloc, requested_count: %d", i_requested_count); i_requested_count++; /* picture owned by evas */ if( BuffersSetup( vd, &vd->fmt, &i_requested_count) ) { msg_Err( vd, "BuffersSetup failed" ); return NULL; } if( i_requested_count <= 1 ) { msg_Err( vd, "not enough buffers allocated" ); goto error; } i_requested_count--; msg_Dbg( vd, "PoolAlloc, got: %d", i_requested_count ); if( !( pp_pics = calloc( i_requested_count, sizeof(picture_t) ) ) ) goto error; for( unsigned int i = 0; i < i_requested_count; ++i ) { if( !( pp_pics[i] = PictureAlloc( vd ) ) ) { i_requested_count = i; msg_Err( vd, "PictureAlloc failed" ); goto error; } } memset( &pool_cfg, 0, sizeof(pool_cfg) ); pool_cfg.picture_count = i_requested_count; pool_cfg.picture = pp_pics; pool_cfg.lock = PoolLockPicture; pool_cfg.unlock = PoolUnlockPicture; p_pool = picture_pool_NewExtended( &pool_cfg ); if( p_pool ) return p_pool; error: if( pp_pics ) { for( unsigned int i = 0; i < i_requested_count; ++i ) picture_Release( pp_pics[i] ); free( pp_pics ); } BuffersClean( vd ); return NULL; }
static picture_pool_t *PoolAlloc(vout_display_t *vd, unsigned requested_count) { vout_display_sys_t *sys = vd->sys; picture_pool_t *pool = NULL; picture_t **pp_pics = NULL; unsigned int i = 0; msg_Dbg(vd, "PoolAlloc: request %d frames", requested_count); if (AndroidWindow_Setup(sys, sys->p_window, requested_count) != 0) goto error; requested_count = sys->p_window->i_pic_count; msg_Dbg(vd, "PoolAlloc: got %d frames", requested_count); UpdateVideoSize(sys, &sys->p_window->fmt); pp_pics = calloc(requested_count, sizeof(picture_t)); for (i = 0; i < requested_count; i++) { picture_t *p_pic = PictureAlloc(sys, &sys->p_window->fmt, sys->p_window->b_opaque); if (!p_pic) goto error; pp_pics[i] = p_pic; } picture_pool_configuration_t pool_cfg; memset(&pool_cfg, 0, sizeof(pool_cfg)); pool_cfg.picture_count = requested_count; pool_cfg.picture = pp_pics; if (sys->p_window->b_opaque) { pool_cfg.lock = PoolLockOpaquePicture; pool_cfg.unlock = PoolUnlockOpaquePicture; } else { pool_cfg.lock = PoolLockPicture; pool_cfg.unlock = PoolUnlockPicture; } pool = picture_pool_NewExtended(&pool_cfg); error: if (!pool && pp_pics) { for (unsigned j = 0; j < i; j++) picture_Release(pp_pics[j]); } free(pp_pics); return pool; }
static void Prepare(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture) { vout_display_sys_t *sys = vd->sys; VLC_UNUSED(picture); SendEventDisplaySize(vd); if (subpicture && sys->p_sub_window) { if (sys->b_sub_invalid) { sys->b_sub_invalid = false; if (sys->p_sub_pic) { picture_Release(sys->p_sub_pic); sys->p_sub_pic = NULL; } if (sys->p_spu_blend) { filter_DeleteBlend(sys->p_spu_blend); sys->p_spu_blend = NULL; } free(sys->p_sub_buffer_bounds); sys->p_sub_buffer_bounds = NULL; } if (!sys->p_sub_pic && AndroidWindow_Setup(sys, sys->p_sub_window, 1) == 0) sys->p_sub_pic = PictureAlloc(sys, &sys->p_sub_window->fmt, false); if (!sys->p_spu_blend && sys->p_sub_pic) sys->p_spu_blend = filter_NewBlend(VLC_OBJECT(vd), &sys->p_sub_pic->format); if (sys->p_sub_pic && sys->p_spu_blend) sys->b_has_subpictures = true; } /* As long as no subpicture was received, do not call SubpictureDisplay since JNI calls and clearing the subtitles surface are expensive operations. */ if (sys->b_has_subpictures) { SubpicturePrepare(vd, subpicture); if (!subpicture) { /* The surface has been cleared and there is no new subpicture to upload, do not clear again until a new subpicture is received. */ sys->b_has_subpictures = false; } } }