Пример #1
0
STDMETHODIMP CGfxTitanII::CreateSurfaces()
{
	HRESULT hr;
	int i;
	DWORD height,width,buffers,hpad,wpad;

	if(m_dwWidth==0 || m_dwHeight==0 /*|| m_hwnd==0*/)
		return E_FAIL;
	if(m_pVr && m_dwWidth==m_dwOldWidth && m_dwHeight==m_dwOldHeight && m_hwnd==m_Oldhwnd)
		return S_OK;

	if(m_bBSMMode == TRUE)
	{
		m_BSM_Init(m_pVr);
	}

	m_dwOldWidth = m_dwWidth;
	m_dwOldHeight = m_dwHeight;

	m_Oldhwnd = m_hwnd;

	//VR_LAYER_OVERLAY:VR_LAYER_PRIMARY
#if defined(SIRF_NOTEBOOK	) || defined(RTK_TITAN_II)
	hr = m_CVR_SetRenderLayer(m_pVr, VR_LAYER_PRIMARY,0.0f);
#else
	hr = m_CVR_SetRenderLayer(m_pVr, VR_LAYER_OVERLAY,0.0f);
#endif
	//[optional] it will change settings in renderer. 
	//TITAN_BITMAP_ORDER: this is the set the bitmap data order 
	//inputted. 
	//pInBuf: the pointer of input data block  
	//data_size: the size of input data block 
	//pOutBuf: the pointer of output data block. 
	//CVR_EscapeCtrl(m_pVr, TITAN_BITMAP_ORDER, pInBuf, data_size, 	pOutBuf); 
	  
	//[optional] it will set the display mode 
	//mode: the display mode to be set 
	hr = m_CVR_SetDisplayMode(m_pVr, m_dispmode); 
  
	//if(m_dwHeight<480)
	//	m_sy = 2;		// double the height!
	//else
		m_sy = 1;
	//if(m_bUseDSP)
	//{	// DSP renderer
	//	alignx = 16;	// 16 is required (spec doesn't specify)
	//	aligny = 4;
	//	hr = CVR_EscapeCtrl(m_pVr,TITAN_DSP_RENDERER,0,0,0);
	//	if(hr!=VR_OK)
	//	{
	//		// do something here.
	//	}
	//}
	//else
	{
//		alignx = 2; /* actually 2, but we prefer this for our averaging ops */
//		aligny = 2;

	}
	buffers = m_dwMaxBuffers+1;
	wpad = ~(m_dwWidth-1) & (ALIGNX-1);
	width = m_dwWidth+wpad;
	height = m_dwHeight*m_sy;
	hpad = ~(height-1) & (ALIGNY-1);
	height = height+hpad;
	//width = width + (width&0xf);
	//height = height + (height&0xf);
	//SetDisplayMode(1);


	m_iYPitch = width;
	m_iUVPitch = m_iYPitch>>1;
	//hr = CVR_SetVideoFormat(m_pVr, 0, width, height, 0, &m_iYPitch, &m_iUVPitch);
		//Set the Video parameters. 
	//VR_FORMAT_I420: set the input data format as I420  
	//width: width of source frame 
	//height: height of source frame 
	//rect: the source rect 
	//LumPitch: pitch of lum 
	//ChromPitch: pitch of chrom 

	width = ROOF(m_dwWidth, ALIGNX);

	if(m_bBSMMode == TRUE)
		height = ROOF(m_dwHeight, ALIGNY);
	else
		height = m_dwHeight;

	VR_SRCRECT rect;
	rect.left= 0;
	rect.right = m_dwWidth;
	rect.top = 0;
	rect.bottom= m_dwHeight;

	hr = m_CVR_SetVideoFormat(m_pVr, VR_FORMAT_I420, width, height, &rect,  &m_iYPitch, &m_iUVPitch);

	SetDeinterlaceMode(m_deinterlace_mode);

    if(!m_bBSMMode)
    {
	    m_pBackBuffer = new LPVR_FRAME_SURFACE[buffers];
	    ZeroMemory(m_pBackBuffer,sizeof(m_pBackBuffer[0])*buffers);

	    for(i=0;i<(signed)buffers;i++)
	    {
		    hr = m_CVR_CreateSurface(m_pVr,&m_pBackBuffer[i],1);
		    if(hr!=VR_OK)
			    break;
	    }
	    if(i==0)
	    {
		    delete[] m_pBackBuffer;
		    m_pBackBuffer = 0;
		    //CVR_DeleteVideoRender(m_pVr);
		    //m_pVr = 0;
		    return E_FAIL;
	    }

	    if(i>1)
	    {		// make sure we have at least one surface available for background scratch, otherwise hang.
		    m_CVR_DestroySurface(m_pVr,m_pBackBuffer[--i]);
		    ZeroMemory(&m_pBackBuffer[i],sizeof(m_pBackBuffer[i]));
	    }

	    m_dwBackBuffers = i;

	    // clear out buffers
	    unsigned char *pb;
	    LONG lstride;
	    int xl,xr,yt,yb,ht;

	    yt = hpad>>1&~1;
	    yb = hpad - yt;
	    xl = 0; // (wpad>>1)&~3;
	    xr = wpad -xl;
	    ht = m_dwHeight*m_sy;

	    for(i=0;i<(signed)m_dwBackBuffers;i++)
	    {
		    if(SUCCEEDED(Lock(i, (LPVOID *)&pb, &lstride, 0)))
		    {
			    clearoutsiderect(pb,m_dwWidth,ht,lstride,0,xl,xr,yt,yb);
			    clearoutsiderect(pb+height*width,m_dwWidth>>1,ht>>1,lstride>>1,128,xl>>1,xr>>1,yt>>1,yb>>1);
			    clearoutsiderect(pb+height*width+(height*width>>2),m_dwWidth>>1,ht>>1,lstride>>1,128,xl>>1,xr>>1,yt>>1,yb>>1);
			    Unlock(i);
		    }
	    }
Пример #2
0
static int Open(vlc_object_t *obj)
{
    char ppsz_components[MAX_COMPONENTS_LIST_SIZE][OMX_MAX_STRINGNAME_SIZE];
    OMX_U8 psz_role[OMX_MAX_STRINGNAME_SIZE];
    filter_t *filter = (filter_t*) obj;
    OMX_PARAM_PORTDEFINITIONTYPE def;
    OMX_PORT_PARAM_TYPE param;
    filter_t *p_dec = filter;
    OMX_ERRORTYPE omx_error;
    filter_sys_t *sys;
    unsigned int i, j;
    int components;

    static OMX_CALLBACKTYPE callbacks =
        { OmxEventHandler, OmxEmptyBufferDone, OmxFillBufferDone };

    if (InitOmxCore(obj) != VLC_SUCCESS)
        return VLC_EGENERIC;

    components = CreateComponentsList(obj, "image_fx", ppsz_components);
    if (components <= 0) {
        DeinitOmxCore();
        msg_Err(filter, "Could not find image_fx component.\n");
        return VLC_EGENERIC;
    }

    sys = calloc(1, sizeof(*sys));
    if (unlikely(sys == NULL))
            return VLC_ENOMEM;
    strcpy(sys->psz_component, ppsz_components[0]);
    filter->p_sys = sys;

    /* Initialize the OMX component */
    omx_error = pf_get_handle(&sys->omx_handle, sys->psz_component, filter,
            &callbacks);
    CHECK_ERROR(omx_error, "OMX_GetHandle(%s) failed (%x: %s)",
            sys->psz_component, omx_error, ErrorToString(omx_error));

    omx_error = OMX_ComponentRoleEnum(sys->omx_handle, psz_role, 0);
    if(omx_error == OMX_ErrorNone)
        msg_Dbg(filter, "loaded component %s of role %s", sys->psz_component, psz_role);
    else
        msg_Dbg(filter, "loaded component %s", sys->psz_component);
    PrintOmx(obj, sys->omx_handle, OMX_ALL);

    InitOmxEventQueue(&sys->event_queue);

    OMX_INIT_STRUCTURE(param);
    OMX_INIT_STRUCTURE(def);
    omx_error = OMX_GetParameter(sys->omx_handle, OMX_IndexParamImageInit, &param);
    CHECK_ERROR(omx_error, "OMX_GetParameter(OMX_IndexParamImageInit) failed (%x: %s)",
                omx_error, ErrorToString(omx_error));

    sys->num_ports = param.nPorts;
    sys->ports = &sys->out;
    for (i = 0; i < param.nPorts; i++) {
        OmxPort *p_port;

        def.nPortIndex = param.nStartPortNumber + i;
        omx_error = OMX_GetParameter(sys->omx_handle,
                OMX_IndexParamPortDefinition, &def);
        if (omx_error != OMX_ErrorNone) {
            msg_Warn(obj, "Port Defintion could not be retrieved for port %d",
                    (int)def.nPortIndex);
            continue;
        }

        if (def.eDir == OMX_DirInput) {
            msg_Dbg(obj, "Port %d is input.", (int)def.nPortIndex);
            p_port = &sys->in;
        } else {
            msg_Dbg(obj, "Port %d is output.", (int)def.nPortIndex);
            p_port = &sys->out;
        }

        def.nBufferCountActual = def.nBufferCountMin;
        omx_error = OMX_SetParameter(sys->omx_handle,
                OMX_IndexParamPortDefinition, &def);
        if (omx_error != OMX_ErrorNone) {
            msg_Warn(obj, "Port Defintion could not be updated for port %d",
                    (int)def.nPortIndex);
            continue;
        }

        p_port->b_valid = true;
        p_port->i_port_index = def.nPortIndex;
        p_port->definition = def;
        p_port->omx_handle = sys->omx_handle;
    }

    if (!sys->in.b_valid || !sys->out.b_valid) {
        omx_error = OMX_ErrorInvalidComponent;
        CHECK_ERROR(omx_error, "couldn't find an input and/or output port.");
    }

    SetFormat(filter, &sys->in);
    SetFormat(filter, &sys->out);

    /* allocate array for port buffers */
    for (i = 0; i < sys->num_ports; i++) {
        OmxPort *port = &sys->ports[i];

        vlc_mutex_init(&port->fifo.lock);
        vlc_cond_init(&port->fifo.wait);
        port->fifo.pp_last = &port->fifo.p_first;
        port->b_flushed = true;
        if (port == &sys->in) {
            port->b_direct = true;
            port->p_fmt = &filter->fmt_in;
            port->fifo.offset = offsetof(OMX_BUFFERHEADERTYPE, pOutputPortPrivate) /
                                sizeof(void*);
        } else {
            port->b_direct = true;
            port->p_fmt = &filter->fmt_out;
            port->fifo.offset = offsetof(OMX_BUFFERHEADERTYPE, pInputPortPrivate) /
                                sizeof(void*);
        }

        msg_Dbg(obj, "Allocate headroom for %u buffers.",
                (unsigned)port->definition.nBufferCountActual);
        port->pp_buffers = malloc(port->definition.nBufferCountActual *
                sizeof(OMX_BUFFERHEADERTYPE*));
        if (unlikely(port->pp_buffers == NULL)) {
            omx_error = OMX_ErrorInsufficientResources;
            CHECK_ERROR(omx_error, "memory allocation failed");
        }
        port->i_buffers = port->definition.nBufferCountActual;

        /* enable port */
        if (!port->definition.bEnabled) {
            omx_error = OMX_SendCommand(sys->omx_handle, OMX_CommandPortEnable,
                    port->i_port_index, NULL);
            CHECK_ERROR(omx_error, "OMX_CommandPortEnable on %i failed (%x)",
                    (int)port->i_port_index, omx_error);

            omx_error = WaitForSpecificOmxEvent(&sys->event_queue,
                    OMX_EventCmdComplete, 0, 0, 0);
            CHECK_ERROR(omx_error, "Wait for PortEnable on %i failed (%x)",
                    (int)port->i_port_index, omx_error);
        }
    }

    /* Put component into idle state */
    omx_error = OMX_SendCommand(sys->omx_handle, OMX_CommandStateSet, OMX_StateIdle, 0);
    CHECK_ERROR(omx_error, "OMX_CommandStateSet Idle failed (%x: %s)", omx_error,
            ErrorToString(omx_error));

    /* allocate buffers/bufferheaders for direct rendering */
    for (i = 0; i < sys->num_ports; i++) {
        OmxPort *port = &sys->ports[i];

        for (j = 0; j < port->i_buffers; j++) {
            if (port->b_direct) {
                omx_error = OMX_UseBuffer(sys->omx_handle, &port->pp_buffers[j],
                        port->i_port_index, 0, port->definition.nBufferSize,
                        (void*)1);
                CHECK_ERROR(omx_error, "OMX_UseBuffer failed (%x: %s)", omx_error,
                        ErrorToString(omx_error));
                msg_Dbg(obj, "Use direct rendering on port %u",
                        (unsigned)port->i_port_index);
                msg_Dbg(obj, "Allocated direct rendering buffer header: %p",
                        port->pp_buffers[j]);
            } else {
                omx_error = OMX_AllocateBuffer(sys->omx_handle,
                        &port->pp_buffers[j], port->i_port_index, 0,
                        port->definition.nBufferSize);
                msg_Dbg(obj, "Use indirect rendering on port %u",
                        (unsigned)port->i_port_index);
            }

            if (omx_error != OMX_ErrorNone) {
                msg_Warn(obj, "Buffer allocate failed on buffer %d for port %d (%x: %s)",
                        j, i, omx_error, ErrorToString(omx_error));
                CHECK_ERROR(omx_error, "OMX_FillBuffer failed (%x: %s)", omx_error,
                        ErrorToString(omx_error));
                break;
            }
            OMX_FIFO_PUT(&port->fifo, port->pp_buffers[j]);
        }
        msg_Dbg(obj, "Allocated %u buffers for port %u",
                (unsigned)port->i_buffers, (unsigned)port->i_port_index);
    }

    omx_error = WaitForSpecificOmxEvent(&sys->event_queue, OMX_EventCmdComplete,
            0, 0, 0);
    CHECK_ERROR(omx_error, "Wait for Idle failed (%x: %s)", omx_error,
            ErrorToString(omx_error));

    msg_Dbg(obj, "Reached Idle state, transition to Executing.");
    SetDeinterlaceMode(filter);

    omx_error = OMX_SendCommand(sys->omx_handle, OMX_CommandStateSet,
            OMX_StateExecuting, 0);
    CHECK_ERROR(omx_error, "OMX_CommandStateSet Executing failed (%x)", omx_error);

    omx_error = WaitForSpecificOmxEvent(&sys->event_queue,
            OMX_EventCmdComplete, 0, 0, 0);
    CHECK_ERROR(omx_error, "Wait for Executing failed (%x)", omx_error );

    filter->pf_video_filter = Deinterlace;
    filter->fmt_out.video.i_frame_rate *= 2;
    printf("OMXIL deinterlace filter initialized with %d->%d fps\n",
        filter->fmt_in.video.i_frame_rate,
        filter->fmt_out.video.i_frame_rate);

    return VLC_SUCCESS;

error:
    Close(obj);
    return VLC_EGENERIC;
}