static int AndroidWindow_LockPicture(vout_display_sys_t *sys, android_window *p_window, picture_t *p_pic) { picture_sys_t *p_picsys = p_pic->p_sys; if (p_picsys->b_locked) return -1; if (sys->anw->winLock(p_window->p_surface, &p_picsys->sw.buf, NULL) != 0) return -1; if (p_picsys->sw.buf.width < 0 || p_picsys->sw.buf.height < 0 || (unsigned)p_picsys->sw.buf.width < p_window->fmt.i_width || (unsigned)p_picsys->sw.buf.height < p_window->fmt.i_height) { p_picsys->b_locked = true; AndroidWindow_UnlockPicture(sys, p_window, p_pic); return -1; } p_pic->p[0].p_pixels = p_picsys->sw.buf.bits; p_pic->p[0].i_lines = p_picsys->sw.buf.height; p_pic->p[0].i_pitch = p_pic->p[0].i_pixel_pitch * p_picsys->sw.buf.stride; if (p_picsys->sw.buf.format == PRIV_WINDOW_FORMAT_YV12) SetupPictureYV12(p_pic, p_picsys->sw.buf.stride); p_picsys->b_locked = true; return 0; }
static int AndroidLockSurface(picture_t *picture) { picture_sys_t *picsys = picture->p_sys; vout_display_sys_t *sys = picsys->sys; SurfaceInfo *info; uint32_t sw, sh; void *surf; sw = picture->p[0].i_visible_pitch / picture->p[0].i_pixel_pitch; sh = picture->p[0].i_visible_lines; picsys->surf = surf = jni_LockAndGetAndroidSurface(); info = &(picsys->info); if (unlikely(!surf)) { jni_UnlockAndroidSurface(); return VLC_EGENERIC; } if (sys->s_lock) sys->s_lock(surf, info, 1); else sys->s_lock2(surf, info, NULL); // For RGB (32 or 16) we need to align on 8 or 4 pixels, 16 pixels for YUV int align_pixels = (16 / picture->p[0].i_pixel_pitch) - 1; uint32_t aligned_width = (sw + align_pixels) & ~align_pixels; if (info->w != aligned_width || info->h != sh) { // input size doesn't match the surface size -> request a resize jni_SetAndroidSurfaceSize(sw, sh, sys->i_sar_num, sys->i_sar_den); sys->s_unlockAndPost(surf); jni_UnlockAndroidSurface(); return VLC_EGENERIC; } picture->p[0].p_pixels = (uint8_t*)info->bits; picture->p[0].i_lines = info->h; picture->p[0].i_pitch = picture->p[0].i_pixel_pitch * info->s; if (info->format == 0x32315659 /*ANDROID_IMAGE_FORMAT_YV12*/) SetupPictureYV12(info, picture); return VLC_SUCCESS; }
static int AndroidWindow_LockPicture(vout_display_sys_t *sys, android_window *p_window, picture_t *p_pic) { picture_sys_t *p_picsys = p_pic->p_sys; if (p_window->b_use_priv) { void *p_handle; int err; err = sys->anwp.lockData(p_window->p_handle_priv, &p_handle, &p_picsys->priv.sw.buf); if (err != 0) return -1; p_picsys->priv.sw.p_handle = p_handle; } else { if (sys->anw.winLock(p_window->p_handle, &p_picsys->priv.sw.buf, NULL) != 0) return -1; } if (p_picsys->priv.sw.buf.width < 0 || p_picsys->priv.sw.buf.height < 0 || (unsigned)p_picsys->priv.sw.buf.width < p_window->fmt.i_width || (unsigned)p_picsys->priv.sw.buf.height < p_window->fmt.i_height) { AndroidWindow_UnlockPicture(sys, p_window, p_pic, false); return -1; } p_pic->p[0].p_pixels = p_picsys->priv.sw.buf.bits; p_pic->p[0].i_lines = p_picsys->priv.sw.buf.height; p_pic->p[0].i_pitch = p_pic->p[0].i_pixel_pitch * p_picsys->priv.sw.buf.stride; if (p_picsys->priv.sw.buf.format == PRIV_WINDOW_FORMAT_YV12) SetupPictureYV12(p_pic, p_picsys->priv.sw.buf.stride); return 0; }
static int AndroidLockSurface(picture_t *picture) { picture_sys_t *picsys = picture->p_sys; vout_display_sys_t *sys = picsys->sys; SurfaceInfo *info; uint32_t sw, sh; void *surf; sw = sys->fmt.i_width; sh = sys->fmt.i_height; if (sys->native_window.winFromSurface) { jobject jsurf = jni_LockAndGetAndroidJavaSurface(); if (unlikely(!jsurf)) { jni_UnlockAndroidSurface(); return VLC_EGENERIC; } if (sys->window && jsurf != sys->jsurf) { sys->native_window.winRelease(sys->window); sys->window = NULL; } sys->jsurf = jsurf; if (!sys->window) { JNIEnv *p_env; (*myVm)->AttachCurrentThread(myVm, &p_env, NULL); sys->window = sys->native_window.winFromSurface(p_env, jsurf); (*myVm)->DetachCurrentThread(myVm); } // Using sys->window instead of the native surface object // as parameter to the unlock function picsys->surf = surf = sys->window; } else { picsys->surf = surf = jni_LockAndGetAndroidSurface(); if (unlikely(!surf)) { jni_UnlockAndroidSurface(); return VLC_EGENERIC; } } info = &picsys->info; if (sys->native_window.winLock) { ANativeWindow_Buffer buf = { 0 }; sys->native_window.winLock(sys->window, &buf, NULL); info->w = buf.width; info->h = buf.height; info->bits = buf.bits; info->s = buf.stride; info->format = buf.format; } else if (sys->s_lock) sys->s_lock(surf, info, 1); else sys->s_lock2(surf, info, NULL); // For RGB (32 or 16) we need to align on 8 or 4 pixels, 16 pixels for YUV int align_pixels = (16 / picture->p[0].i_pixel_pitch) - 1; uint32_t aligned_width = (sw + align_pixels) & ~align_pixels; if (info->w != aligned_width || info->h != sh || sys->b_changed_crop) { // input size doesn't match the surface size -> request a resize jni_SetAndroidSurfaceSize(aligned_width, sh, sys->fmt.i_visible_width, sys->fmt.i_visible_height, sys->i_sar_num, sys->i_sar_den); // When using ANativeWindow, one should use ANativeWindow_setBuffersGeometry // to set the size and format. In our case, these are set via the SurfaceHolder // in Java, so we seem to manage without calling this ANativeWindow function. sys->s_unlockAndPost(surf); jni_UnlockAndroidSurface(); sys->b_changed_crop = false; return VLC_EGENERIC; } picture->p[0].p_pixels = (uint8_t*)info->bits; picture->p[0].i_lines = info->h; picture->p[0].i_pitch = picture->p[0].i_pixel_pitch * info->s; if (info->format == 0x32315659 /*ANDROID_IMAGE_FORMAT_YV12*/) SetupPictureYV12(info, picture); return VLC_SUCCESS; }