Exemple #1
0
static int Open(vlc_object_t *object)
{
    vout_display_t *vd = (vout_display_t *)object;
    vout_display_sys_t *sys;
    uint32_t buffer_pitch, buffer_height;
    vout_display_place_t place;
    MMAL_DISPLAYREGION_T display_region;
    uint32_t offsets[3];
    MMAL_STATUS_T status;
    int ret = VLC_SUCCESS;
    unsigned i;

    if (vout_display_IsWindowed(vd))
        return VLC_EGENERIC;

    sys = calloc(1, sizeof(struct vout_display_sys_t));
    if (!sys)
        return VLC_ENOMEM;
    vd->sys = sys;

    sys->layer = var_InheritInteger(vd, MMAL_LAYER_NAME);
    bcm_host_init();

    vd->info.has_hide_mouse = true;
    sys->opaque = vd->fmt.i_chroma == VLC_CODEC_MMAL_OPAQUE;

    status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, &sys->component);
    if (status != MMAL_SUCCESS) {
        msg_Err(vd, "Failed to create MMAL component %s (status=%"PRIx32" %s)",
                        MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, status, mmal_status_to_string(status));
        ret = VLC_EGENERIC;
        goto out;
    }

    sys->component->control->userdata = (struct MMAL_PORT_USERDATA_T *)vd;
    status = mmal_port_enable(sys->component->control, control_port_cb);
    if (status != MMAL_SUCCESS) {
        msg_Err(vd, "Failed to enable control port %s (status=%"PRIx32" %s)",
                        sys->component->control->name, status, mmal_status_to_string(status));
        ret = VLC_EGENERIC;
        goto out;
    }

    sys->input = sys->component->input[0];
    sys->input->userdata = (struct MMAL_PORT_USERDATA_T *)vd;

    if (sys->opaque) {
        sys->input->format->encoding = MMAL_ENCODING_OPAQUE;
        sys->i_planes = 1;
        sys->buffer_size = sys->input->buffer_size_recommended;
    } else {
        sys->input->format->encoding = MMAL_ENCODING_I420;
        vd->fmt.i_chroma = VLC_CODEC_I420;
        buffer_pitch = align(vd->fmt.i_width, 32);
        buffer_height = align(vd->fmt.i_height, 16);
        sys->i_planes = 3;
        sys->buffer_size = 3 * buffer_pitch * buffer_height / 2;
    }

    sys->input->format->es->video.width = vd->fmt.i_width;
    sys->input->format->es->video.height = vd->fmt.i_height;
    sys->input->format->es->video.crop.x = 0;
    sys->input->format->es->video.crop.y = 0;
    sys->input->format->es->video.crop.width = vd->fmt.i_width;
    sys->input->format->es->video.crop.height = vd->fmt.i_height;
    sys->input->format->es->video.par.num = vd->source.i_sar_num;
    sys->input->format->es->video.par.den = vd->source.i_sar_den;

    status = mmal_port_format_commit(sys->input);
    if (status != MMAL_SUCCESS) {
        msg_Err(vd, "Failed to commit format for input port %s (status=%"PRIx32" %s)",
                        sys->input->name, status, mmal_status_to_string(status));
        ret = VLC_EGENERIC;
        goto out;
    }
    sys->input->buffer_size = sys->input->buffer_size_recommended;

    vout_display_PlacePicture(&place, &vd->source, vd->cfg, false);
    display_region.hdr.id = MMAL_PARAMETER_DISPLAYREGION;
    display_region.hdr.size = sizeof(MMAL_DISPLAYREGION_T);
    display_region.fullscreen = MMAL_FALSE;
    display_region.src_rect.x = vd->fmt.i_x_offset;
    display_region.src_rect.y = vd->fmt.i_y_offset;
    display_region.src_rect.width = vd->fmt.i_visible_width;
    display_region.src_rect.height = vd->fmt.i_visible_height;
    display_region.dest_rect.x = place.x;
    display_region.dest_rect.y = place.y;
    display_region.dest_rect.width = place.width;
    display_region.dest_rect.height = place.height;
    display_region.layer = sys->layer;
    display_region.set = MMAL_DISPLAY_SET_FULLSCREEN | MMAL_DISPLAY_SET_SRC_RECT |
            MMAL_DISPLAY_SET_DEST_RECT | MMAL_DISPLAY_SET_LAYER;
    status = mmal_port_parameter_set(sys->input, &display_region.hdr);
    if (status != MMAL_SUCCESS) {
        msg_Err(vd, "Failed to set display region (status=%"PRIx32" %s)",
                        status, mmal_status_to_string(status));
        ret = VLC_EGENERIC;
        goto out;
    }

    offsets[0] = 0;
    for (i = 0; i < sys->i_planes; ++i) {
        sys->planes[i].i_lines = buffer_height;
        sys->planes[i].i_pitch = buffer_pitch;
        sys->planes[i].i_visible_lines = vd->fmt.i_visible_height;
        sys->planes[i].i_visible_pitch = vd->fmt.i_visible_width;

        if (i > 0) {
            offsets[i] = offsets[i - 1] + sys->planes[i - 1].i_pitch * sys->planes[i - 1].i_lines;
            sys->planes[i].i_lines /= 2;
            sys->planes[i].i_pitch /= 2;
            sys->planes[i].i_visible_lines /= 2;
            sys->planes[i].i_visible_pitch /= 2;
        }

        sys->planes[i].p_pixels = (uint8_t *)offsets[i];
    }

    vlc_mutex_init(&sys->buffer_mutex);
    vlc_cond_init(&sys->buffer_cond);
    vlc_mutex_init(&sys->manage_mutex);

    vd->pool = vd_pool;
    vd->prepare = vd_prepare;
    vd->display = vd_display;
    vd->control = vd_control;
    vd->manage = vd_manage;

    vc_tv_register_callback(tvservice_cb, vd);

    if (query_resolution(vd, &sys->display_width, &sys->display_height) >= 0) {
        vout_display_SendEventDisplaySize(vd, sys->display_width, sys->display_height);
    } else {
        sys->display_width = vd->cfg->display.width;
        sys->display_height = vd->cfg->display.height;
    }

    sys->dmx_handle = vc_dispmanx_display_open(0);
    vd->info.subpicture_chromas = subpicture_chromas;

out:
    if (ret != VLC_SUCCESS)
        Close(object);

    return ret;
}
Exemple #2
0
/**
 * This function initializes libcaca vout method.
 */
static int Open(vlc_object_t *object)
{
    vout_display_t *vd = (vout_display_t *)object;
    vout_display_sys_t *sys;

    if (vout_display_IsWindowed(vd))
        return VLC_EGENERIC;
#if !defined(__APPLE__) && !defined(_WIN32)
# ifndef X_DISPLAY_MISSING
    if (!vlc_xlib_init(object))
        return VLC_EGENERIC;
# endif
#endif

#if defined(_WIN32)
    CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
    SMALL_RECT rect;
    COORD coord;
    HANDLE hstdout;

    if (!AllocConsole()) {
        msg_Err(vd, "cannot create console");
        return VLC_EGENERIC;
    }

    hstdout =
        CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
                                  FILE_SHARE_READ | FILE_SHARE_WRITE,
                                  NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
    if (!hstdout || hstdout == INVALID_HANDLE_VALUE) {
        msg_Err(vd, "cannot create screen buffer");
        FreeConsole();
        return VLC_EGENERIC;
    }

    if (!SetConsoleActiveScreenBuffer(hstdout)) {
        msg_Err(vd, "cannot set active screen buffer");
        FreeConsole();
        return VLC_EGENERIC;
    }

    coord = GetLargestConsoleWindowSize(hstdout);
    msg_Dbg(vd, "SetConsoleWindowInfo: %ix%i", coord.X, coord.Y);

    /* Force size for now */
    coord.X = 100;
    coord.Y = 40;

    if (!SetConsoleScreenBufferSize(hstdout, coord))
        msg_Warn(vd, "SetConsoleScreenBufferSize %i %i",
                  coord.X, coord.Y);

    /* Get the current screen buffer size and window position. */
    if (GetConsoleScreenBufferInfo(hstdout, &csbiInfo)) {
        rect.Top = 0; rect.Left = 0;
        rect.Right = csbiInfo.dwMaximumWindowSize.X - 1;
        rect.Bottom = csbiInfo.dwMaximumWindowSize.Y - 1;
        if (!SetConsoleWindowInfo(hstdout, TRUE, &rect))
            msg_Dbg(vd, "SetConsoleWindowInfo failed: %ix%i",
                     rect.Right, rect.Bottom);
    }
#endif

    /* Allocate structure */
    vd->sys = sys = calloc(1, sizeof(*sys));
    if (!sys)
        goto error;

    sys->cv = cucul_create_canvas(0, 0);
    if (!sys->cv) {
        msg_Err(vd, "cannot initialize libcucul");
        goto error;
    }

    const char *driver = NULL;
#ifdef __APPLE__
    // Make sure we don't try to open a window.
    driver = "ncurses";
#endif

    sys->dp = caca_create_display_with_driver(sys->cv, driver);
    if (!sys->dp) {
        msg_Err(vd, "cannot initialize libcaca");
        goto error;
    }

    if (vd->cfg->display.title)
        caca_set_display_title(sys->dp,
                               vd->cfg->display.title);
    else
        caca_set_display_title(sys->dp,
                               VOUT_TITLE "(Colour AsCii Art)");

    /* Fix format */
    video_format_t fmt = vd->fmt;
    if (fmt.i_chroma != VLC_CODEC_RGB32) {
        fmt.i_chroma = VLC_CODEC_RGB32;
        fmt.i_rmask = 0x00ff0000;
        fmt.i_gmask = 0x0000ff00;
        fmt.i_bmask = 0x000000ff;
    }

    /* TODO */
    vout_display_info_t info = vd->info;

    /* Setup vout_display now that everything is fine */
    vd->fmt = fmt;
    vd->info = info;

    vd->pool    = Pool;
    vd->prepare = Prepare;
    vd->display = PictureDisplay;
    vd->control = Control;
    vd->manage  = Manage;

    /* Fix initial state */
    vout_display_SendEventFullscreen(vd, false);
    Refresh(vd);

    return VLC_SUCCESS;

error:
    if (sys) {
        if (sys->pool)
            picture_pool_Release(sys->pool);
        if (sys->dither)
            cucul_free_dither(sys->dither);
        if (sys->dp)
            caca_free_display(sys->dp);
        if (sys->cv)
            cucul_free_canvas(sys->cv);

        free(sys);
    }
#if defined(_WIN32)
    FreeConsole();
#endif
    return VLC_EGENERIC;
}
Exemple #3
0
static int Open(vlc_object_t *p_this)
{
    vout_display_t *vd = (vout_display_t*)p_this;
    vout_display_sys_t *sys;
    video_format_t sub_fmt;

    if (vout_display_IsWindowed(vd))
        return VLC_EGENERIC;

    /* XXX: android_window use a surface created by VideoPlayerActivity to
     * alloc pictures. Don't try to open the vout if this activity is not
     * created. This need to be replaced by something like var_CreateGetAddress
     * (vd, "drawable-android") in the future. */
    if (!jni_IsVideoPlayerActivityCreated())
        return VLC_EGENERIC;

    /* Allocate structure */
    vd->sys = sys = (struct vout_display_sys_t*)calloc(1, sizeof(*sys));
    if (!sys)
        return VLC_ENOMEM;

    sys->p_library = LoadNativeWindowAPI(&sys->anw);
    if (!sys->p_library) {
        msg_Err(vd, "Could not initialize NativeWindow API.");
        goto error;
    }

#ifdef USE_ANWP
    if (LoadNativeWindowPrivAPI(&sys->anwp) == 0)
        sys->b_has_anwp = true;
    else
        msg_Warn(vd, "Could not initialize NativeWindow Priv API.");
#endif

    sys->i_display_width = vd->cfg->display.width;
    sys->i_display_height = vd->cfg->display.height;

    if (vd->fmt.i_chroma != VLC_CODEC_ANDROID_OPAQUE) {
        /* Setup chroma */
        char *psz_fcc = var_InheritString(vd, CFG_PREFIX "chroma");
        if (psz_fcc) {
            vd->fmt.i_chroma = vlc_fourcc_GetCodecFromString(VIDEO_ES, psz_fcc);
            free(psz_fcc);
        } else
            vd->fmt.i_chroma = VLC_CODEC_RGB32;

        switch(vd->fmt.i_chroma) {
            case VLC_CODEC_YV12:
                /* avoid swscale usage by asking for I420 instead since the
                 * vout already has code to swap the buffers */
                vd->fmt.i_chroma = VLC_CODEC_I420;
            case VLC_CODEC_I420:
                break;
            case VLC_CODEC_RGB16:
            case VLC_CODEC_RGB32:
            case VLC_CODEC_RGBA:
                SetRGBMask(&vd->fmt);
                video_format_FixRgb(&vd->fmt);
                break;
            default:
                goto error;
        }
    }

    sys->p_window = AndroidWindow_New(sys, &vd->fmt, true);
    if (!sys->p_window)
        goto error;

    if (SetupWindowSurface(sys, 0) != 0)
        goto error;

    /* use software rotation if we don't use private anw */
    if (!sys->p_window->b_opaque && !sys->p_window->b_use_priv)
        video_format_ApplyRotation(&vd->fmt, &vd->fmt);

    msg_Dbg(vd, "using %s", sys->p_window->b_opaque ? "opaque" :
            (sys->p_window->b_use_priv ? "ANWP" : "ANW"));

    video_format_ApplyRotation(&sub_fmt, &vd->fmt);
    sub_fmt.i_chroma = subpicture_chromas[0];
    SetRGBMask(&sub_fmt);
    video_format_FixRgb(&sub_fmt);
    sys->p_sub_window = AndroidWindow_New(sys, &sub_fmt, false);
    if (!sys->p_sub_window)
        goto error;
    FixSubtitleFormat(sys);
    sys->i_sub_last_order = -1;

    /* Export the subpicture capability of this vout. */
    vd->info.subpicture_chromas = subpicture_chromas;

    /* Setup vout_display */
    vd->pool    = Pool;
    vd->prepare = Prepare;
    vd->display = Display;
    vd->control = Control;
    vd->manage  = Manage;

    /* Fix initial state */
    vout_display_SendEventFullscreen(vd, true);
    SendEventDisplaySize(vd);

    return VLC_SUCCESS;

error:
    Close(p_this);
    return VLC_ENOMEM;
}
Exemple #4
0
/**
 * This function initializes SDL vout method.
 */
static int Open(vlc_object_t *object)
{
    vout_display_t *vd = (vout_display_t *)object;
    vout_display_sys_t *sys;

    if (vout_display_IsWindowed(vd))
        return VLC_EGENERIC;
#if !defined(_WIN32) && !defined(__OS2__)
    if (!vlc_xlib_init (object))
        return VLC_EGENERIC;
#endif

    /* XXX: check for conflicts with the SDL audio output */
    vlc_mutex_lock(&sdl_lock);

    /* Check if SDL video module has been initialized */
    if (SDL_WasInit(SDL_INIT_VIDEO) != 0) {
        vlc_mutex_unlock(&sdl_lock);
        return VLC_EGENERIC;
    }

    vd->sys = sys = calloc(1, sizeof(*sys));
    if (!sys) {
        vlc_mutex_unlock(&sdl_lock);
        return VLC_ENOMEM;
    }

    /* */
    int sdl_flags = SDL_INIT_VIDEO;
#ifndef _WIN32
    /* Win32 SDL implementation doesn't support SDL_INIT_EVENTTHREAD yet*/
    sdl_flags |= SDL_INIT_EVENTTHREAD;
#endif
    /* In debug mode you may want vlc to dump a core instead of staying stuck */
    sdl_flags |= SDL_INIT_NOPARACHUTE;

    /* Initialize library */
    if (SDL_Init(sdl_flags) < 0) {
        vlc_mutex_unlock(&sdl_lock);

        msg_Err(vd, "cannot initialize SDL (%s)", SDL_GetError());
        free(sys);
        return VLC_EGENERIC;
    }
    vlc_mutex_unlock(&sdl_lock);

    /* Translate keys into unicode */
    SDL_EnableUNICODE(1);

    /* Get the desktop resolution */
    /* FIXME: SDL has a problem with virtual desktop */
    sys->desktop_width  = SDL_GetVideoInfo()->current_w;
    sys->desktop_height = SDL_GetVideoInfo()->current_h;

    /* */
    video_format_t fmt;
    video_format_ApplyRotation(&fmt, &vd->fmt);

    /* */
    vout_display_info_t info = vd->info;

    info.needs_event_thread = true;

    /* Set main window's size */
    int display_width;
    int display_height;
    if (vd->cfg->is_fullscreen) {
        display_width  = sys->desktop_width;
        display_height = sys->desktop_height;
    } else {
        display_width  = vd->cfg->display.width;
        display_height = vd->cfg->display.height;
    }

    /* Initialize flags and cursor */
    sys->display_flags = SDL_ANYFORMAT | SDL_HWPALETTE | SDL_HWSURFACE | SDL_DOUBLEBUF;
    sys->display_flags |= vd->cfg->is_fullscreen ? SDL_FULLSCREEN : SDL_RESIZABLE;

    sys->display_bpp = SDL_VideoModeOK(display_width, display_height,
                                       16, sys->display_flags);
    if (sys->display_bpp == 0) {
        msg_Err(vd, "no video mode available");
        goto error;
    }

    sys->display = SDL_SetVideoMode(display_width, display_height,
                                    sys->display_bpp, sys->display_flags);
    if (!sys->display) {
        msg_Err(vd, "cannot set video mode");
        goto error;
    }

    /* We keep the surface locked forever */
    SDL_LockSurface(sys->display);

    /* */
    vlc_fourcc_t forced_chroma = 0;
    char *psz_chroma = var_InheritString(vd, "sdl-chroma");
    if (psz_chroma) {
        forced_chroma = vlc_fourcc_GetCodecFromString(VIDEO_ES, psz_chroma);
        if (forced_chroma)
            msg_Dbg(vd, "Forcing chroma to 0x%.8x (%4.4s)",
                    forced_chroma, (const char*)&forced_chroma);
        free(psz_chroma);
    }

    /* Try to open an overlay if requested */
    sys->overlay = NULL;
    const bool is_overlay = var_InheritBool(vd, "sdl-overlay");
    if (is_overlay) {
        static const struct
        {
            vlc_fourcc_t vlc;
            uint32_t     sdl;
        } vlc_to_sdl[] = {
            { VLC_CODEC_YV12, SDL_YV12_OVERLAY },
            { VLC_CODEC_I420, SDL_IYUV_OVERLAY },
            { VLC_CODEC_YUYV, SDL_YUY2_OVERLAY },
            { VLC_CODEC_UYVY, SDL_UYVY_OVERLAY },
            { VLC_CODEC_YVYU, SDL_YVYU_OVERLAY },

            { 0, 0 }
        };
        const vlc_fourcc_t forced_chromas[] = {
            forced_chroma, 0
        };
        const vlc_fourcc_t *fallback_chromas =
            vlc_fourcc_GetYUVFallback(fmt.i_chroma);
        const vlc_fourcc_t *chromas = forced_chroma ? forced_chromas : fallback_chromas;

        for (int pass = forced_chroma ? 1 : 0; pass < 2 && !sys->overlay; pass++) {
            for (int i = 0; chromas[i] != 0; i++) {
                const vlc_fourcc_t vlc = chromas[i];

                uint32_t sdl = 0;
                for (int j = 0; vlc_to_sdl[j].vlc != 0 && !sdl; j++) {
                    if (vlc_to_sdl[j].vlc == vlc)
                        sdl = vlc_to_sdl[j].sdl;
                }
                if (!sdl)
                    continue;

                sys->overlay = SDL_CreateYUVOverlay(fmt.i_width, fmt.i_height,
                                                    sdl, sys->display);
                if (sys->overlay && !sys->overlay->hw_overlay && pass == 0) {
                    /* Ignore non hardware overlay surface in first pass */
                    SDL_FreeYUVOverlay(sys->overlay);
                    sys->overlay = NULL;
                }
                if (sys->overlay) {
                    /* We keep the surface locked forever */
                    SDL_LockYUVOverlay(sys->overlay);

                    fmt.i_chroma = vlc;
                    sys->is_uv_swapped = vlc_fourcc_AreUVPlanesSwapped(fmt.i_chroma,
                                                                       vd->fmt.i_chroma);
                    if (sys->is_uv_swapped)
                        fmt.i_chroma = vd->fmt.i_chroma;
                    break;
                }
            }
        }
    } else {
        msg_Warn(vd, "SDL overlay disabled by the user");
    }

    /* */
    vout_display_cfg_t place_cfg = *vd->cfg;
    place_cfg.display.width  = display_width;
    place_cfg.display.height = display_height;
    vout_display_PlacePicture(&sys->place, &vd->source, &place_cfg, !sys->overlay);

    /* If no overlay, fallback to software output */
    if (!sys->overlay) {
        /* */
        switch (sys->display->format->BitsPerPixel) {
        case 8:
            fmt.i_chroma = VLC_CODEC_RGB8;
            break;
        case 15:
            fmt.i_chroma = VLC_CODEC_RGB15;
            break;
        case 16:
            fmt.i_chroma = VLC_CODEC_RGB16;
            break;
        case 24:
            fmt.i_chroma = VLC_CODEC_RGB24;
            break;
        case 32:
            fmt.i_chroma = VLC_CODEC_RGB32;
            break;
        default:
            msg_Err(vd, "unknown screen depth %i",
                    sys->display->format->BitsPerPixel);
            goto error;
        }

        /* All we have is an RGB image with square pixels */
        fmt.i_width  = display_width;
        fmt.i_height = display_height;
        fmt.i_rmask = sys->display->format->Rmask;
        fmt.i_gmask = sys->display->format->Gmask;
        fmt.i_bmask = sys->display->format->Bmask;

        info.has_pictures_invalid = true;
    }

    if (vd->cfg->display.title)
        SDL_WM_SetCaption(vd->cfg->display.title,
                          vd->cfg->display.title);
    else if (!sys->overlay)
        SDL_WM_SetCaption(VOUT_TITLE " (software RGB SDL output)",
                          VOUT_TITLE " (software RGB SDL output)");
    else if (sys->overlay->hw_overlay)
        SDL_WM_SetCaption(VOUT_TITLE " (hardware YUV SDL output)",
                          VOUT_TITLE " (hardware YUV SDL output)");
    else
        SDL_WM_SetCaption(VOUT_TITLE " (software YUV SDL output)",
                          VOUT_TITLE " (software YUV SDL output)");

    /* Setup events */
    SDL_EventState(SDL_KEYUP, SDL_IGNORE);               /* ignore keys up */

    /* Setup vout_display now that everything is fine */
    vd->fmt = fmt;
    vd->info = info;

    vd->pool    = Pool;
    vd->prepare = NULL;
    vd->display = PictureDisplay;
    vd->control = Control;
    vd->manage  = Manage;

    /* */
    vout_display_SendEventDisplaySize(vd, display_width, display_height);
    return VLC_SUCCESS;

error:
    msg_Err(vd, "cannot set up SDL (%s)", SDL_GetError());

    if (sys->display) {
        SDL_UnlockSurface(sys->display);
        SDL_FreeSurface(sys->display);
    }

    vlc_mutex_lock(&sdl_lock);
    SDL_QuitSubSystem(SDL_INIT_VIDEO);
    vlc_mutex_unlock(&sdl_lock);

    free(sys);
    return VLC_EGENERIC;
}
Exemple #5
0
static int Open(vlc_object_t *p_this)
{
    vout_display_t *vd = (vout_display_t*)p_this;
    vout_display_sys_t *sys;
    video_format_t sub_fmt;

    if (vout_display_IsWindowed(vd))
        return VLC_EGENERIC;

    /* Allocate structure */
    vd->sys = sys = (struct vout_display_sys_t*)calloc(1, sizeof(*sys));
    if (!sys)
        return VLC_ENOMEM;

    sys->p_awh = AWindowHandler_new(p_this);
    if (!sys->p_awh)
    {
        free(sys);
        msg_Err(vd, "AWindowHandler_new failed");
        return VLC_EGENERIC;
    }
    sys->anw = AWindowHandler_getANativeWindowAPI(sys->p_awh);

#ifdef USE_ANWP
    sys->anwp = AWindowHandler_getANativeWindowPrivAPI(sys->p_awh);
    if (!sys->anwp)
        msg_Warn(vd, "Could not initialize NativeWindow Priv API.");
#endif

    sys->i_display_width = vd->cfg->display.width;
    sys->i_display_height = vd->cfg->display.height;

    if (vd->fmt.i_chroma != VLC_CODEC_ANDROID_OPAQUE) {
        /* Setup chroma */
        char *psz_fcc = var_InheritString(vd, CFG_PREFIX "chroma");
        if (psz_fcc) {
            vd->fmt.i_chroma = vlc_fourcc_GetCodecFromString(VIDEO_ES, psz_fcc);
            free(psz_fcc);
        } else
            vd->fmt.i_chroma = VLC_CODEC_RGB32;

        switch(vd->fmt.i_chroma) {
            case VLC_CODEC_YV12:
                /* avoid swscale usage by asking for I420 instead since the
                 * vout already has code to swap the buffers */
                vd->fmt.i_chroma = VLC_CODEC_I420;
            case VLC_CODEC_I420:
                break;
            case VLC_CODEC_RGB16:
            case VLC_CODEC_RGB32:
            case VLC_CODEC_RGBA:
                SetRGBMask(&vd->fmt);
                video_format_FixRgb(&vd->fmt);
                break;
            default:
                goto error;
        }
    }

    sys->p_window = AndroidWindow_New(vd, &vd->fmt, AWindow_Video, true);
    if (!sys->p_window)
        goto error;

    if (AndroidWindow_Setup(sys, sys->p_window, 0) != 0)
        goto error;

    /* use software rotation if we don't use private anw */
    if (!sys->p_window->b_opaque && !sys->p_window->b_use_priv)
        video_format_ApplyRotation(&vd->fmt, &vd->fmt);

    msg_Dbg(vd, "using %s", sys->p_window->b_opaque ? "opaque" :
            (sys->p_window->b_use_priv ? "ANWP" : "ANW"));

    video_format_ApplyRotation(&sub_fmt, &vd->fmt);
    sub_fmt.i_chroma = subpicture_chromas[0];
    SetRGBMask(&sub_fmt);
    video_format_FixRgb(&sub_fmt);
    sys->p_sub_window = AndroidWindow_New(vd, &sub_fmt, AWindow_Subtitles, false);
    if (sys->p_sub_window) {

        FixSubtitleFormat(sys);
        sys->i_sub_last_order = -1;

        /* Export the subpicture capability of this vout. */
        vd->info.subpicture_chromas = subpicture_chromas;
    }

    /* Setup vout_display */
    vd->pool    = Pool;
    vd->prepare = Prepare;
    vd->display = Display;
    vd->control = Control;
    vd->manage  = Manage;

    /* Fix initial state */
    vout_display_SendEventFullscreen(vd, true);
    SendEventDisplaySize(vd);

    return VLC_SUCCESS;

error:
    Close(p_this);
    return VLC_ENOMEM;
}
Exemple #6
0
static int Open(vlc_object_t *p_this)
{
    vout_display_t *vd = (vout_display_t *)p_this;
    video_format_t fmt;
    video_format_ApplyRotation(&fmt, &vd->fmt);

    if (fmt.i_chroma == VLC_CODEC_ANDROID_OPAQUE)
        return VLC_EGENERIC;
    if (vout_display_IsWindowed(vd))
        return VLC_EGENERIC;

    /* Allocate structure */
    vout_display_sys_t *sys = (struct vout_display_sys_t*) calloc(1, sizeof(*sys));
    if (!sys)
        goto error;

    /* */
    sys->p_library = InitLibrary(sys);
    if (!sys->p_library) {
        msg_Err(vd, "Could not initialize libandroid.so/libui.so/libgui.so/libsurfaceflinger_client.so!");
        goto error;
    }

    /* Setup chroma */
    char *psz_fcc = var_InheritString(vd, CFG_PREFIX "chroma");
    if( psz_fcc ) {
        fmt.i_chroma = vlc_fourcc_GetCodecFromString(VIDEO_ES, psz_fcc);
        free(psz_fcc);
    } else
        fmt.i_chroma = VLC_CODEC_RGB32;

    switch(fmt.i_chroma) {
        case VLC_CODEC_RGB16:
            fmt.i_bmask = 0x0000001f;
            fmt.i_gmask = 0x000007e0;
            fmt.i_rmask = 0x0000f800;
            break;

        case VLC_CODEC_YV12:
        case VLC_CODEC_I420:
            fmt.i_chroma = VLC_CODEC_RGB32;
        case VLC_CODEC_RGB32:
            fmt.i_rmask  = 0x000000ff;
            fmt.i_gmask  = 0x0000ff00;
            fmt.i_bmask  = 0x00ff0000;
            break;

        default:
            return VLC_EGENERIC;
    }
    video_format_FixRgb(&fmt);

    msg_Dbg(vd, "Pixel format %4.4s", (char*)&fmt.i_chroma);
    sys->i_android_hal = ChromaToAndroidHal(fmt.i_chroma);
    if (sys->i_android_hal == -1)
        goto error;

    sys->fmt = fmt;
    UpdateLayout(sys);

    /* Create the associated picture */
    picture_sys_t *picsys = calloc(1, sizeof(picture_sys_t));
    if (unlikely(picsys == NULL))
        goto error;
    picsys->sys = sys;

    picture_resource_t resource = { .p_sys = picsys };
    picture_t *picture = picture_NewFromResource(&fmt, &resource);
    if (!picture) {
        free(picsys);
        goto error;
    }

    /* Wrap it into a picture pool */
    picture_pool_configuration_t pool_cfg;
    memset(&pool_cfg, 0, sizeof(pool_cfg));
    pool_cfg.picture_count = 1;
    pool_cfg.picture       = &picture;
    pool_cfg.lock          = AndroidLockSurface;
    pool_cfg.unlock        = AndroidUnlockSurface;

    sys->pool = picture_pool_NewExtended(&pool_cfg);
    if (!sys->pool) {
        picture_Release(picture);
        goto error;
    }

    /* Setup vout_display */
    vd->sys     = sys;
    vd->fmt     = fmt;
    vd->pool    = Pool;
    vd->display = Display;
    vd->control = Control;
    vd->prepare = NULL;
    vd->manage  = Manage;

    /* Fix initial state */
    vout_display_SendEventFullscreen(vd, false);

    return VLC_SUCCESS;

error:
    Close(p_this);
    return VLC_ENOMEM;
}
Exemple #7
0
static int
Open( vlc_object_t *p_this )
{
    vout_display_t *vd = (vout_display_t*)p_this;
    vout_display_sys_t *sys;
    Evas_Object *p_evas;

    if( vout_display_IsWindowed( vd ) )
        return VLC_EGENERIC;

    p_evas = var_InheritAddress( p_this, "drawable-evasobject" );
    if( !p_evas )
        return VLC_EGENERIC;

    vd->sys = sys = (struct vout_display_sys_t *) calloc( 1, sizeof(*sys) );
    if( !sys )
        return VLC_ENOMEM;

    vlc_mutex_init( &sys->cb_lock );
    vlc_cond_init( &sys->cb_wait );
    fifo_init( &sys->buffer_fifo );
    fifo_init( &sys->event_fifo );

    sys->p_evas = p_evas;

    msg_Dbg( vd, "request video format: %4.4s",
             (const char *)&vd->fmt.i_chroma );

    /* Evas Initialisation must be done from the Mainloop */
    if( EcoreMainLoopCallSync( vd, EvasInitMainloopCb ) )
    {
        msg_Err( vd, "EvasInitMainloopCb failed" );
        Close( p_this );
        return VLC_EGENERIC;
    }

    for( unsigned int i = 0; i < PICTURE_PLANE_MAX; ++i )
        sys->i_planes_order[i] = i;

    switch( vd->fmt.i_chroma )
    {
        case VLC_CODEC_RGB32:
        case VLC_CODEC_RGB16:
            video_format_FixRgb(&vd->fmt);
            break;
        case VLC_CODEC_YV12:
            sys->i_planes_order[1] = 2;
            sys->i_planes_order[2] = 1;
        default:
            break;
    }

    msg_Dbg( vd, "got video format: %4.4s, size: %dx%d",
             (const char *)&vd->fmt.i_chroma,
             sys->i_width, sys->i_height );

    /* Setup vout_display */
    vd->pool    = Pool;
    vd->prepare = NULL;
    vd->display = Display;
    vd->control = Control;
    vd->manage  = Manage;

    return VLC_SUCCESS;
}