Esempio n. 1
0
static HRESULT WINAPI Gstreamer_transform_ProcessData(TransformFilter *iface, IMediaSample *sample)
{
    GstTfImpl *This = (GstTfImpl*)iface;
    REFERENCE_TIME tStart, tStop;
    BYTE *data;
    GstBuffer *buf;
    HRESULT hr;
    DWORD bufsize;
    int ret;

    TRACE("%p, %p\n", This, sample);

    mark_wine_thread();

    EnterCriticalSection(&This->tf.csReceive);
    IMediaSample_GetPointer(sample, &data);

    IMediaSample_AddRef(sample);
    bufsize = IMediaSample_GetActualDataLength(sample);
    buf = gst_buffer_new_wrapped_full(0, data, bufsize, 0, bufsize, sample, release_sample_wrapper);
    if (!buf) {
        IMediaSample_Release(sample);
        LeaveCriticalSection(&This->tf.csReceive);
        return S_OK;
    }

    IMediaSample_AddRef(sample);
    gst_mini_object_set_qdata(GST_MINI_OBJECT(buf), g_quark_from_static_string(media_quark_string), sample, release_sample_wrapper);

    buf->duration = buf->pts = -1;
    hr = IMediaSample_GetTime(sample, &tStart, &tStop);
    if (SUCCEEDED(hr)) {
        buf->pts = tStart * 100;
        if (hr == S_OK)
            buf->duration = (tStop - tStart)*100;
    }
    if (IMediaSample_GetMediaTime(sample, &tStart, &tStop) == S_OK) {
        buf->offset = tStart * 100;
        buf->offset_end = tStop * 100;
    }
    if (IMediaSample_IsDiscontinuity(sample) == S_OK)
        GST_BUFFER_FLAG_SET(buf, GST_BUFFER_FLAG_DISCONT);
    if (IMediaSample_IsPreroll(sample) == S_OK)
        GST_BUFFER_FLAG_SET(buf, GST_BUFFER_FLAG_LIVE);
    if (IMediaSample_IsSyncPoint(sample) != S_OK)
        GST_BUFFER_FLAG_SET(buf, GST_BUFFER_FLAG_DELTA_UNIT);
    LeaveCriticalSection(&This->tf.csReceive);
    ret = gst_pad_push(This->my_src, buf);
    if (ret)
        WARN("Sending returned: %i\n", ret);
    if (ret == GST_FLOW_FLUSHING)
        return VFW_E_WRONG_STATE;
    return S_OK;
}
Esempio n. 2
0
static HRESULT WINAPI BaseMemAllocator_GetBuffer(IMemAllocator * iface, IMediaSample ** pSample, REFERENCE_TIME *pStartTime, REFERENCE_TIME *pEndTime, DWORD dwFlags)
{
    BaseMemAllocator *This = impl_from_IMemAllocator(iface);
    HRESULT hr = S_OK;

    /* NOTE: The pStartTime and pEndTime parameters are not applied to the sample. 
     * The allocator might use these values to determine which buffer it retrieves */
    
    TRACE("(%p)->(%p, %p, %p, %x)\n", This, pSample, pStartTime, pEndTime, dwFlags);

    *pSample = NULL;

    EnterCriticalSection(This->pCritSect);
    if (!This->bCommitted || This->bDecommitQueued)
    {
        WARN("Not committed\n");
        hr = VFW_E_NOT_COMMITTED;
    }
    else
        ++This->lWaiting;
    LeaveCriticalSection(This->pCritSect);
    if (FAILED(hr))
        return hr;

    if (WaitForSingleObject(This->hSemWaiting, (dwFlags & AM_GBF_NOWAIT) ? 0 : INFINITE) != WAIT_OBJECT_0)
    {
        EnterCriticalSection(This->pCritSect);
        --This->lWaiting;
        LeaveCriticalSection(This->pCritSect);
        WARN("Timed out\n");
        return VFW_E_TIMEOUT;
    }

    EnterCriticalSection(This->pCritSect);
    {
        --This->lWaiting;
        if (!This->bCommitted)
            hr = VFW_E_NOT_COMMITTED;
        else if (This->bDecommitQueued)
            hr = VFW_E_TIMEOUT;
        else
        {
            StdMediaSample2 *ms;
            struct list * free = list_head(&This->free_list);
            list_remove(free);
            list_add_head(&This->used_list, free);

            ms = LIST_ENTRY(free, StdMediaSample2, listentry);
            assert(ms->ref == 0);
            *pSample = (IMediaSample *)&ms->IMediaSample2_iface;
            IMediaSample_AddRef(*pSample);
        }
    }
    LeaveCriticalSection(This->pCritSect);

    if (hr != S_OK)
        WARN("%08x\n", hr);
    return hr;
}
Esempio n. 3
0
/* Helper that buffers data and/or calls installed sample callbacks */
static void SampleGrabber_callback(SG_Impl *This, IMediaSample *sample)
{
    double time = 0.0;
    REFERENCE_TIME tStart, tEnd;
    if (This->bufferLen >= 0) {
        BYTE *data = 0;
        LONG size = IMediaSample_GetActualDataLength(sample);
        if (size >= 0 && SUCCEEDED(IMediaSample_GetPointer(sample, &data))) {
            if (!data)
                size = 0;
            EnterCriticalSection(&This->filter.csFilter);
            if (This->bufferLen != size) {
                if (This->bufferData)
                    CoTaskMemFree(This->bufferData);
                This->bufferData = size ? CoTaskMemAlloc(size) : NULL;
                This->bufferLen = size;
            }
            if (size)
                CopyMemory(This->bufferData, data, size);
            LeaveCriticalSection(&This->filter.csFilter);
        }
    }
    if (!This->grabberIface)
        return;
    if (SUCCEEDED(IMediaSample_GetTime(sample, &tStart, &tEnd)))
        time = 1e-7 * tStart;
    switch (This->grabberMethod) {
        case 0:
	    {
		ULONG ref = IMediaSample_AddRef(sample);
		ISampleGrabberCB_SampleCB(This->grabberIface, time, sample);
		ref = IMediaSample_Release(sample) + 1 - ref;
		if (ref)
		{
		    ERR("(%p) Callback referenced sample %p by %u\n", This, sample, ref);
		    /* ugly as hell but some apps are sooo buggy */
		    while (ref--)
			IMediaSample_Release(sample);
		}
	    }
            break;
        case 1:
            {
                BYTE *data = 0;
                LONG size = IMediaSample_GetActualDataLength(sample);
                if (size && SUCCEEDED(IMediaSample_GetPointer(sample, &data)) && data)
                    ISampleGrabberCB_BufferCB(This->grabberIface, time, data, size);
            }
            break;
        case -1:
            break;
        default:
            FIXME("unsupported method %d\n", This->grabberMethod);
            /* do not bother us again */
            This->grabberMethod = -1;
    }
}
Esempio n. 4
0
static HRESULT WINAPI Gstreamer_transform_ProcessData(TransformFilter *iface, IMediaSample *sample) {
    GstTfImpl *This = (GstTfImpl*)iface;
    REFERENCE_TIME tStart, tStop;
    BYTE *data;
    GstBuffer *buf;
    HRESULT hr;
    int ret;
    TRACE("Reading %p\n", sample);

    EnterCriticalSection(&This->tf.filter.csFilter);
    IMediaSample_GetPointer(sample, &data);
    buf = gst_app_buffer_new(data, IMediaSample_GetActualDataLength(sample), release_sample, sample);
    if (!buf) {
        LeaveCriticalSection(&This->tf.filter.csFilter);
        return S_OK;
    }
    gst_buffer_set_caps(buf, gst_pad_get_caps_reffed(This->my_src));
    IMediaSample_AddRef(sample);
    buf->duration = buf->timestamp = -1;
    hr = IMediaSample_GetTime(sample, &tStart, &tStop);
    if (SUCCEEDED(hr)) {
        buf->timestamp = tStart * 100;
        if (hr == S_OK)
            buf->duration = (tStop - tStart)*100;
    }
    if (IMediaSample_GetMediaTime(sample, &tStart, &tStop) == S_OK) {
        buf->offset = tStart * 100;
        buf->offset_end = tStop * 100;
    }
    if (IMediaSample_IsDiscontinuity(sample) == S_OK)
        GST_BUFFER_FLAG_SET(buf, GST_BUFFER_FLAG_DISCONT);
    if (IMediaSample_IsPreroll(sample) == S_OK)
        GST_BUFFER_FLAG_SET(buf, GST_BUFFER_FLAG_PREROLL);
    if (IMediaSample_IsSyncPoint(sample) != S_OK)
        GST_BUFFER_FLAG_SET(buf, GST_BUFFER_FLAG_DELTA_UNIT);
    LeaveCriticalSection(&This->tf.filter.csFilter);
    ret = gst_pad_push(This->my_src, buf);
    if (ret)
        WARN("Sending returned: %i\n", ret);
    if (ret == GST_FLOW_ERROR)
        return E_FAIL;
    if (ret == GST_FLOW_WRONG_STATE)
        return VFW_E_WRONG_STATE;
    if (ret == GST_FLOW_RESEND)
        return S_FALSE;
    return S_OK;
}
Esempio n. 5
0
static HRESULT WINAPI BaseMemAllocator_GetBuffer(IMemAllocator * iface, IMediaSample ** pSample, REFERENCE_TIME *pStartTime, REFERENCE_TIME *pEndTime, DWORD dwFlags)
{
    BaseMemAllocator *This = (BaseMemAllocator *)iface;
    HRESULT hr = S_OK;

    /* NOTE: The pStartTime and pEndTime parameters are not applied to the sample. 
     * The allocator might use these values to determine which buffer it retrieves */
    
    TRACE("(%p)->(%p, %p, %p, %lx)\n", This, pSample, pStartTime, pEndTime, dwFlags);

    *pSample = NULL;

    if (!This->bCommitted)
        return VFW_E_NOT_COMMITTED;

    This->lWaiting++;
    if (WaitForSingleObject(This->hSemWaiting, (dwFlags & AM_GBF_NOWAIT) ? 0 : INFINITE) != WAIT_OBJECT_0)
    {
        This->lWaiting--;
        return VFW_E_TIMEOUT;
    }
    This->lWaiting--;

    EnterCriticalSection(&This->csState);
    {
        if (!This->bCommitted)
            hr = VFW_E_NOT_COMMITTED;
        else if (This->bDecommitQueued)
            hr = VFW_E_TIMEOUT;
        else
        {
            struct list * free = list_head(&This->free_list);
            list_remove(free);
            list_add_head(&This->used_list, free);

            *pSample = (IMediaSample *)LIST_ENTRY(free, StdMediaSample2, listentry);

            assert(((StdMediaSample2 *)*pSample)->ref == 0);

            IMediaSample_AddRef(*pSample);
        }
    }
    LeaveCriticalSection(&This->csState);

    return hr;
}
Esempio n. 6
0
static HRESULT
IMemAllocator_LockUnusedBuffer(CMemoryAllocator* This,IMediaSample** ppSample)
{
	HRESULT hr = E_FAIL;
	LONG	i;

	TRACE("(%p) try to enter critical section\n",This);
	EnterCriticalSection( &This->csMem );
	TRACE("(%p) enter critical section\n",This);

	if ( This->pData == NULL || This->ppSamples == NULL ||
	     This->prop.cBuffers <= 0 )
	{
		hr = VFW_E_NOT_COMMITTED;
		goto end;
	}


	for ( i = 0; i < This->prop.cBuffers; i++ )
	{
		if ( This->ppSamples[i] == NULL )
		{
			hr = VFW_E_NOT_COMMITTED;
			goto end;
		}
		if ( This->ppSamples[i]->ref == 0 )
		{
			*ppSample = (IMediaSample*)(This->ppSamples[i]);
			IMediaSample_AddRef( *ppSample );
			hr = NOERROR;
			goto end;
		}
	}

	hr = VFW_E_TIMEOUT;
end:
	LeaveCriticalSection( &This->csMem );
	TRACE("(%p) leave critical section\n",This);

	return hr;
}
Esempio n. 7
0
HRESULT WINAPI BaseRendererImpl_Receive(BaseRenderer *This, IMediaSample * pSample)
{
    HRESULT hr = S_OK;
    REFERENCE_TIME start, stop;
    AM_MEDIA_TYPE *pmt;

    TRACE("(%p)->%p\n", This, pSample);

    if (This->pInputPin->end_of_stream || This->pInputPin->flushing)
        return S_FALSE;

    if (This->filter.state == State_Stopped)
        return VFW_E_WRONG_STATE;

    if (IMediaSample_GetMediaType(pSample, &pmt) == S_OK)
    {
        if (FAILED(This->pFuncsTable->pfnCheckMediaType(This, pmt)))
        {
            return VFW_E_TYPE_NOT_ACCEPTED;
        }
    }

    This->pMediaSample = pSample;
    IMediaSample_AddRef(pSample);

    if (This->pFuncsTable->pfnPrepareReceive)
        hr = This->pFuncsTable->pfnPrepareReceive(This, pSample);
    if (FAILED(hr))
    {
        if (hr == VFW_E_SAMPLE_REJECTED)
            return S_OK;
        else
            return hr;
    }

    if (This->pFuncsTable->pfnPrepareRender)
        This->pFuncsTable->pfnPrepareRender(This);

    EnterCriticalSection(&This->csRenderLock);
    if ( This->filter.state == State_Paused )
    {
        if (This->pFuncsTable->pfnOnReceiveFirstSample)
            This->pFuncsTable->pfnOnReceiveFirstSample(This, pSample);

        SetEvent(This->evComplete);
    }

    /* Wait for render Time */
    if (SUCCEEDED(IMediaSample_GetMediaTime(pSample, &start, &stop)))
    {
        hr = S_FALSE;
        RendererPosPassThru_RegisterMediaTime(This->pPosition, start);
        if (This->pFuncsTable->pfnShouldDrawSampleNow)
            hr = This->pFuncsTable->pfnShouldDrawSampleNow(This, pSample, &start, &stop);

        if (hr == S_OK)
            ;/* Do not wait: drop through */
        else if (hr == S_FALSE)
        {
            if (This->pFuncsTable->pfnOnWaitStart)
                This->pFuncsTable->pfnOnWaitStart(This);

            hr = QualityControlRender_WaitFor(This->qcimpl, pSample, This->RenderEvent);

            if (This->pFuncsTable->pfnOnWaitEnd)
                This->pFuncsTable->pfnOnWaitEnd(This);
        }
        else
        {
            LeaveCriticalSection(&This->csRenderLock);
            /* Drop Sample */
            return S_OK;
        }
    }

    if (SUCCEEDED(hr))
    {
        QualityControlRender_BeginRender(This->qcimpl);
        hr = This->pFuncsTable->pfnDoRenderSample(This, pSample);
        QualityControlRender_EndRender(This->qcimpl);
    }

    QualityControlRender_DoQOS(This->qcimpl);

    BaseRendererImpl_ClearPendingSample(This);
    LeaveCriticalSection(&This->csRenderLock);

    return hr;
}