Exemplo n.º 1
0
SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface* display)
{
    SDL_Overlay* overlay;
    struct private_yuvhwdata* hwdata;
    int vidport;
    int rtncode;
    int planes;
    int i=0;
    PhPoint_t pos;

    /* Create the overlay structure */
    overlay = SDL_calloc(1, sizeof(SDL_Overlay));

    if (overlay == NULL)
    {
        SDL_OutOfMemory();
        return NULL;
    }

    /* Fill in the basic members */
    overlay->format = format;
    overlay->w = width;
    overlay->h = height;
    overlay->hwdata = NULL;
	
    /* Set up the YUV surface function structure */
    overlay->hwfuncs = &ph_yuvfuncs;

    /* Create the pixel data and lookup tables */
    hwdata = SDL_calloc(1, sizeof(struct private_yuvhwdata));

    if (hwdata == NULL)
    {
        SDL_OutOfMemory();
        SDL_FreeYUVOverlay(overlay);
        return NULL;
    }

    overlay->hwdata = hwdata;

    PhDCSetCurrent(0);
    if (overlay->hwdata->channel == NULL)
    {
        if ((overlay->hwdata->channel = PgCreateVideoChannel(Pg_VIDEO_CHANNEL_SCALER, 0)) == NULL)
        {
            SDL_SetError("ph_CreateYUVOverlay(): Create channel failed: %s\n", strerror(errno));
            SDL_FreeYUVOverlay(overlay);
            return NULL;

        }
    }

    overlay->hwdata->forcedredraw=0;

    PtGetAbsPosition(window, &pos.x, &pos.y);
    overlay->hwdata->CurrentWindowPos.x = pos.x;
    overlay->hwdata->CurrentWindowPos.y = pos.y;
    overlay->hwdata->CurrentViewPort.pos.x = 0;
    overlay->hwdata->CurrentViewPort.pos.y = 0;
    overlay->hwdata->CurrentViewPort.size.w = width;
    overlay->hwdata->CurrentViewPort.size.h = height;
    overlay->hwdata->State = OVERLAY_STATE_UNINIT;
    overlay->hwdata->FrameData0 = (FRAMEDATA *) SDL_calloc(1, sizeof(FRAMEDATA));
    overlay->hwdata->FrameData1 = (FRAMEDATA *) SDL_calloc(1, sizeof(FRAMEDATA));

    vidport = -1;
    i=0;
    
    overlay->hwdata->ischromakey=0;

    do {
        SDL_memset(&overlay->hwdata->caps, 0x00, sizeof(PgScalerCaps_t));
        overlay->hwdata->caps.size = sizeof(PgScalerCaps_t);
        rtncode = PgGetScalerCapabilities(overlay->hwdata->channel, i, &overlay->hwdata->caps);
        if (rtncode==0)
        { 
            if (overlay->hwdata->caps.format==format)
            {
               if ((overlay->hwdata->caps.flags & Pg_SCALER_CAP_DST_CHROMA_KEY) == Pg_SCALER_CAP_DST_CHROMA_KEY)
               {
                   overlay->hwdata->ischromakey=1;
               }
               vidport=1;
               break;
            }
        }
        else
        {
           break;
        }
        i++;
    } while(1);


    if (vidport == -1)
    {
        SDL_SetError("No available video ports for requested format\n");
        SDL_FreeYUVOverlay(overlay);
        return NULL;
    }

    overlay->hwdata->format = format;
    overlay->hwdata->props.format = format;
    overlay->hwdata->props.size = sizeof(PgScalerProps_t);
    overlay->hwdata->props.src_dim.w = width;
    overlay->hwdata->props.src_dim.h = height;

    /* overlay->hwdata->chromakey = PgGetOverlayChromaColor(); */
    overlay->hwdata->chromakey = PgRGB(12, 6, 12); /* very dark pink color */
    overlay->hwdata->props.color_key = overlay->hwdata->chromakey;

    PhAreaToRect(&overlay->hwdata->CurrentViewPort, &overlay->hwdata->props.viewport);

    overlay->hwdata->props.flags = Pg_SCALER_PROP_DOUBLE_BUFFER;

    if ((overlay->hwdata->ischromakey)&&(overlay->hwdata->chromakey))
    {
        overlay->hwdata->props.flags |= Pg_SCALER_PROP_CHROMA_ENABLE;
        overlay->hwdata->props.flags |= Pg_SCALER_PROP_CHROMA_SPECIFY_KEY_MASK;
    } 
    else
    {
        overlay->hwdata->props.flags &= ~Pg_SCALER_PROP_CHROMA_ENABLE;
    }

    rtncode = PgConfigScalerChannel(overlay->hwdata->channel, &overlay->hwdata->props);

    switch(rtncode)
    {
        case -1: SDL_SetError("PgConfigScalerChannel failed\n");
                 SDL_FreeYUVOverlay(overlay);
                 return NULL;
        case 1:
        case 0:
        default:
                 break;
    }

    planes = grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1);

    if(overlay->hwdata->channel->yplane1 != NULL)
        overlay->hwdata->YStride = overlay->hwdata->channel->yplane1->pitch;
    if(overlay->hwdata->channel->vplane1 != NULL)
        overlay->hwdata->UStride = overlay->hwdata->channel->vplane1->pitch;
    if(overlay->hwdata->channel->uplane1 != NULL)
        overlay->hwdata->VStride = overlay->hwdata->channel->uplane1->pitch;

    /* check for the validness of all planes */
    if ((overlay->hwdata->channel->yplane1 == NULL) &&
        (overlay->hwdata->channel->uplane1 == NULL) &&
        (overlay->hwdata->channel->vplane1 == NULL))
    {
       SDL_FreeYUVOverlay(overlay);
       SDL_SetError("PgConfigScaler() returns all planes equal NULL\n");
       return NULL;
    }
/*
    overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel);

    if (overlay->hwdata->current==0)
    {
        overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;
    }
    else
    {
        overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1;
    }
*/
    overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;

/*
    overlay->hwdata->locked = 1;
*/

    /* Find the pitch and offset values for the overlay */
    overlay->planes = planes;
    overlay->pitches = SDL_calloc(overlay->planes, sizeof(Uint16));
    overlay->pixels  = SDL_calloc(overlay->planes, sizeof(Uint8*));
    if (!overlay->pitches || !overlay->pixels)
    {
        SDL_OutOfMemory();
        SDL_FreeYUVOverlay(overlay);
        return(NULL);
    }

    if (overlay->planes > 0)
    {
        overlay->pitches[0] = overlay->hwdata->channel->yplane1->pitch;
        overlay->pixels[0]  = overlay->hwdata->CurrentFrameData->Y;
    }
    if (overlay->planes > 1)
    {
        overlay->pitches[1] = overlay->hwdata->channel->vplane1->pitch;
        overlay->pixels[1]  = overlay->hwdata->CurrentFrameData->U;
    }
    if (overlay->planes > 2)
    {
        overlay->pitches[2] = overlay->hwdata->channel->uplane1->pitch;
        overlay->pixels[2]  = overlay->hwdata->CurrentFrameData->V;
    }

    overlay->hwdata->State = OVERLAY_STATE_ACTIVE;
    overlay->hwdata->scaler_on = 0;
    overlay->hw_overlay = 1;

    current_overlay=overlay;

    return overlay;
}
Exemplo n.º 2
0
/*****************************************************************************
 * QNXInitDisplay: check screen resolution, depth, amount of video ram, etc
 *****************************************************************************/
static int QNXInitDisplay( vout_thread_t * p_vout )
{
    PgHWCaps_t hwcaps;
    PgDisplaySettings_t cfg;
    PgVideoModeInfo_t minfo;

    /* get graphics card hw capabilities */
    if( PgGetGraphicsHWCaps( &hwcaps ) != 0 )
    {
        msg_Err( p_vout, "unable to get gfx card capabilities" );
        return( 1 );
    }

    /* get current video mode */
    if( PgGetVideoMode( &cfg ) != 0 )
    {
        msg_Err( p_vout, "unable to get current video mode" );
        return( 1 );
    }

    /* get video mode info */
    if( PgGetVideoModeInfo( cfg.mode, &minfo ) != 0 )
    {
        msg_Err( p_vout, "unable to get info for video mode" );
        return( 1 );
    }

    if( p_vout->p_sys->i_mode == MODE_VIDEO_OVERLAY )
    {
        int i = 0;
        PgScalerCaps_t vcaps;

        if( ( p_vout->p_sys->p_channel =
            PgCreateVideoChannel( Pg_VIDEO_CHANNEL_SCALER, 0 ) ) == NULL )
        {
            msg_Err( p_vout, "unable to create video channel" );
            printf("errno = %d\n", errno);
            p_vout->p_sys->i_mode = MODE_NORMAL_MEM;
        }
        else
        {
            vcaps.size = sizeof( vcaps );
            while( PgGetScalerCapabilities( p_vout->p_sys->p_channel,
                                            i++, &vcaps ) == 0 )
            {
                printf("vcaps.format = 0x%x\n", vcaps.format);
                if( vcaps.format == Pg_VIDEO_FORMAT_YV12 ||
                    vcaps.format == Pg_VIDEO_FORMAT_YUV420 ||
                    vcaps.format == Pg_VIDEO_FORMAT_YUY2 ||
                    vcaps.format == Pg_VIDEO_FORMAT_UYVY ||
                    vcaps.format == Pg_VIDEO_FORMAT_RGB555 ||
                    vcaps.format == Pg_VIDEO_FORMAT_RGB565 ||
                    vcaps.format == Pg_VIDEO_FORMAT_RGB8888 )
                {
                    p_vout->p_sys->i_vc_flags  = vcaps.flags;
                    p_vout->p_sys->i_vc_format = vcaps.format;
                }

                vcaps.size = sizeof( vcaps );
            }

            if( p_vout->p_sys->i_vc_format == 0 )
            {
                msg_Warn( p_vout, "need YV12, YUY2 or RGB8888 overlay" );

                p_vout->p_sys->i_mode = MODE_NORMAL_MEM;
            }
        }
    }

    /* use video ram if we have enough available */
    if( p_vout->p_sys->i_mode == MODE_NORMAL_MEM &&
        (minfo.bits_per_pixel != 8) &&
        hwcaps.currently_available_video_ram >=
        ( ( minfo.width * minfo.height * minfo.bits_per_pixel * MAX_DIRECTBUFFERS) / 8 ) )
    {
        p_vout->p_sys->i_mode = MODE_VIDEO_MEM;
        printf("Using video memory...\n");
    }

    p_vout->p_sys->i_img_type = minfo.type;
    p_vout->p_sys->screen_dim.w = minfo.width;
    p_vout->p_sys->screen_dim.h = minfo.height;
    p_vout->p_sys->i_screen_depth = minfo.bits_per_pixel;

    switch( p_vout->p_sys->i_screen_depth )
    {
        case 8:
            p_vout->output.i_chroma = VLC_CODEC_RGB8;
            p_vout->p_sys->i_bytes_per_pixel = 1;
            p_vout->output.pf_setpalette = SetPalette;
            break;

        case 15:
            p_vout->output.i_chroma = VLC_CODEC_RGB15;
            p_vout->p_sys->i_bytes_per_pixel = 2;
            p_vout->output.i_rmask = 0x7c00;
            p_vout->output.i_gmask = 0x03e0;
            p_vout->output.i_bmask = 0x001f;
            break;

        case 16:
            p_vout->output.i_chroma = VLC_CODEC_RGB16;
            p_vout->p_sys->i_bytes_per_pixel = 2;
            p_vout->output.i_rmask = 0xf800;
            p_vout->output.i_gmask = 0x07e0;
            p_vout->output.i_bmask = 0x001f;
            break;

        case 24:
            p_vout->output.i_chroma = VLC_CODEC_RGB24;
            p_vout->p_sys->i_bytes_per_pixel = 3;
            p_vout->output.i_rmask = 0xff0000;
            p_vout->output.i_gmask = 0x00ff00;
            p_vout->output.i_bmask = 0x0000ff;
            break;

        case 32:
        default:
            p_vout->output.i_chroma = VLC_CODEC_RGB32;
            p_vout->p_sys->i_bytes_per_pixel = 4;
            p_vout->output.i_rmask = 0xff0000;
            p_vout->output.i_gmask = 0x00ff00;
            p_vout->output.i_bmask = 0x0000ff;
            break;
    }

    return( 0 );
}