コード例 #1
0
ファイル: amstream.c プロジェクト: miurahr/wine
/*** IAMMultiMediaStream methods ***/
static HRESULT WINAPI IAMMultiMediaStreamImpl_Initialize(IAMMultiMediaStream* iface, STREAM_TYPE StreamType, DWORD dwFlags, IGraphBuilder* pFilterGraph)
{
    IAMMultiMediaStreamImpl *This = impl_from_IAMMultiMediaStream(iface);
    HRESULT hr = S_OK;
    const WCHAR filternameW[] = {'M','e','d','i','a','S','t','r','e','a','m','F','i','l','t','e','r',0};

    TRACE("(%p/%p)->(%x,%x,%p)\n", This, iface, (DWORD)StreamType, dwFlags, pFilterGraph);

    if (pFilterGraph)
    {
        This->pFilterGraph = pFilterGraph;
        IGraphBuilder_AddRef(This->pFilterGraph);
    }
    else
    {
        hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IGraphBuilder, (LPVOID*)&This->pFilterGraph);
    }

    if (SUCCEEDED(hr))
    {
        This->StreamType = StreamType;
        hr = IGraphBuilder_QueryInterface(This->pFilterGraph, &IID_IMediaSeeking, (void**)&This->media_seeking);
        if (SUCCEEDED(hr))
            IGraphBuilder_QueryInterface(This->pFilterGraph, &IID_IMediaControl, (void**)&This->media_control);
        if (SUCCEEDED(hr))
            hr = CoCreateInstance(&CLSID_MediaStreamFilter, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&This->media_stream_filter);
        if (SUCCEEDED(hr))
            IGraphBuilder_AddFilter(This->pFilterGraph, This->media_stream_filter, filternameW);
        if (SUCCEEDED(hr))
        {
            IMediaEventEx* media_event = NULL;
            hr = IGraphBuilder_QueryInterface(This->pFilterGraph, &IID_IMediaEventEx, (void**)&media_event);
            if (SUCCEEDED(hr))
                hr = IMediaEventEx_GetEventHandle(media_event, &This->event);
            if (SUCCEEDED(hr))
                hr = IMediaEventEx_SetNotifyFlags(media_event, AM_MEDIAEVENT_NONOTIFY);
            if (media_event)
                IMediaEventEx_Release(media_event);
        }
    }

    if (FAILED(hr))
    {
        if (This->media_stream_filter)
            IBaseFilter_Release(This->media_stream_filter);
        This->media_stream_filter = NULL;
        if (This->media_seeking)
            IMediaSeeking_Release(This->media_seeking);
        This->media_seeking = NULL;
        if (This->media_control)
            IMediaControl_Release(This->media_control);
        This->media_control = NULL;
        if (This->pFilterGraph)
            IGraphBuilder_Release(This->pFilterGraph);
        This->pFilterGraph = NULL;
    }

    return hr;
}
コード例 #2
0
ファイル: dshow.c プロジェクト: 3688/FFmpeg
static int
dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum,
                  enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype)
{
    struct dshow_ctx *ctx = avctx->priv_data;
    IBaseFilter *device_filter = NULL;
    IGraphBuilder *graph = ctx->graph;
    IPin *device_pin = NULL;
    libAVPin *capture_pin = NULL;
    libAVFilter *capture_filter = NULL;
    ICaptureGraphBuilder2 *graph_builder2 = NULL;
    int ret = AVERROR(EIO);
    int r;
    IStream *ifile_stream = NULL;
    IStream *ofile_stream = NULL;
    IPersistStream *pers_stream = NULL;

    const wchar_t *filter_name[2] = { L"Audio capture filter", L"Video capture filter" };


    if ( ((ctx->audio_filter_load_file) && (strlen(ctx->audio_filter_load_file)>0) && (sourcetype == AudioSourceDevice)) ||
            ((ctx->video_filter_load_file) && (strlen(ctx->video_filter_load_file)>0) && (sourcetype == VideoSourceDevice)) ) {
        HRESULT hr;
        char *filename = NULL;

        if (sourcetype == AudioSourceDevice)
            filename = ctx->audio_filter_load_file;
        else
            filename = ctx->video_filter_load_file;

        hr = SHCreateStreamOnFile ((LPCSTR) filename, STGM_READ, &ifile_stream);
        if (S_OK != hr) {
            av_log(avctx, AV_LOG_ERROR, "Could not open capture filter description file.\n");
            goto error;
        }

        hr = OleLoadFromStream(ifile_stream, &IID_IBaseFilter, (void **) &device_filter);
        if (hr != S_OK) {
            av_log(avctx, AV_LOG_ERROR, "Could not load capture filter from file.\n");
            goto error;
        }

        if (sourcetype == AudioSourceDevice)
            av_log(avctx, AV_LOG_INFO, "Audio-");
        else
            av_log(avctx, AV_LOG_INFO, "Video-");
        av_log(avctx, AV_LOG_INFO, "Capture filter loaded successfully from file \"%s\".\n", filename);
    } else {

        if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, &device_filter)) < 0) {
            ret = r;
            goto error;
        }
    }

    ctx->device_filter [devtype] = device_filter;

    r = IGraphBuilder_AddFilter(graph, device_filter, NULL);
    if (r != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not add device filter to graph.\n");
        goto error;
    }

    if ((r = dshow_cycle_pins(avctx, devtype, sourcetype, device_filter, &device_pin)) < 0) {
        ret = r;
        goto error;
    }

    ctx->device_pin[devtype] = device_pin;

    capture_filter = libAVFilter_Create(avctx, callback, devtype);
    if (!capture_filter) {
        av_log(avctx, AV_LOG_ERROR, "Could not create grabber filter.\n");
        goto error;
    }
    ctx->capture_filter[devtype] = capture_filter;

    if ( ((ctx->audio_filter_save_file) && (strlen(ctx->audio_filter_save_file)>0) && (sourcetype == AudioSourceDevice)) ||
            ((ctx->video_filter_save_file) && (strlen(ctx->video_filter_save_file)>0) && (sourcetype == VideoSourceDevice)) ) {

        HRESULT hr;
        char *filename = NULL;

        if (sourcetype == AudioSourceDevice)
            filename = ctx->audio_filter_save_file;
        else
            filename = ctx->video_filter_save_file;

        hr = SHCreateStreamOnFile ((LPCSTR) filename, STGM_CREATE | STGM_READWRITE, &ofile_stream);
        if (S_OK != hr) {
            av_log(avctx, AV_LOG_ERROR, "Could not create capture filter description file.\n");
            goto error;
        }

        hr  = IBaseFilter_QueryInterface(device_filter, &IID_IPersistStream, (void **) &pers_stream);
        if (hr != S_OK) {
            av_log(avctx, AV_LOG_ERROR, "Query for IPersistStream failed.\n");
            goto error;
        }

        hr = OleSaveToStream(pers_stream, ofile_stream);
        if (hr != S_OK) {
            av_log(avctx, AV_LOG_ERROR, "Could not save capture filter \n");
            goto error;
        }

        hr = IStream_Commit(ofile_stream, STGC_DEFAULT);
        if (S_OK != hr) {
            av_log(avctx, AV_LOG_ERROR, "Could not commit capture filter data to file.\n");
            goto error;
        }

        if (sourcetype == AudioSourceDevice)
            av_log(avctx, AV_LOG_INFO, "Audio-");
        else
            av_log(avctx, AV_LOG_INFO, "Video-");
        av_log(avctx, AV_LOG_INFO, "Capture filter saved successfully to file \"%s\".\n", filename);
    }

    r = IGraphBuilder_AddFilter(graph, (IBaseFilter *) capture_filter,
                                filter_name[devtype]);
    if (r != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not add capture filter to graph\n");
        goto error;
    }

    libAVPin_AddRef(capture_filter->pin);
    capture_pin = capture_filter->pin;
    ctx->capture_pin[devtype] = capture_pin;

    r = CoCreateInstance(&CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER,
                         &IID_ICaptureGraphBuilder2, (void **) &graph_builder2);
    if (r != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not create CaptureGraphBuilder2\n");
        goto error;
    }
    ICaptureGraphBuilder2_SetFiltergraph(graph_builder2, graph);
    if (r != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not set graph for CaptureGraphBuilder2\n");
        goto error;
    }

    r = ICaptureGraphBuilder2_RenderStream(graph_builder2, NULL, NULL, (IUnknown *) device_pin, NULL /* no intermediate filter */,
        (IBaseFilter *) capture_filter); /* connect pins, optionally insert intermediate filters like crossbar if necessary */

    if (r != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not RenderStream to connect pins\n");
        goto error;
    }

    r = dshow_try_setup_crossbar_options(graph_builder2, device_filter, devtype, avctx);

    if (r != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not setup CrossBar\n");
        goto error;
    }

    ret = 0;

error:
    if (graph_builder2 != NULL)
        ICaptureGraphBuilder2_Release(graph_builder2);

    if (pers_stream)
        IPersistStream_Release(pers_stream);

    if (ifile_stream)
        IStream_Release(ifile_stream);

    if (ofile_stream)
        IStream_Release(ofile_stream);

    return ret;
}
コード例 #3
0
static int
dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum,
                  enum dshowDeviceType devtype)
{
    struct dshow_ctx *ctx = avctx->priv_data;
    IBaseFilter *device_filter = NULL;
    IGraphBuilder *graph = ctx->graph;
    IPin *device_pin = NULL;
    libAVPin *capture_pin = NULL;
    libAVFilter *capture_filter = NULL;
    int ret = AVERROR(EIO);
    int r;

    const wchar_t *filter_name[2] = { L"Audio capture filter", L"Video capture filter" };

    if ((r = dshow_cycle_devices(avctx, devenum, devtype, &device_filter)) < 0) {
        ret = r;
        goto error;
    }

    ctx->device_filter [devtype] = device_filter;

    r = IGraphBuilder_AddFilter(graph, device_filter, NULL);
    if (r != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not add device filter to graph.\n");
        goto error;
    }

    if ((r = dshow_cycle_pins(avctx, devtype, device_filter, &device_pin)) < 0) {
        ret = r;
        goto error;
    }
    ctx->device_pin[devtype] = device_pin;

    capture_filter = libAVFilter_Create(avctx, callback, devtype);
    if (!capture_filter) {
        av_log(avctx, AV_LOG_ERROR, "Could not create grabber filter.\n");
        goto error;
    }
    ctx->capture_filter[devtype] = capture_filter;

    r = IGraphBuilder_AddFilter(graph, (IBaseFilter *) capture_filter,
                                filter_name[devtype]);
    if (r != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not add capture filter to graph\n");
        goto error;
    }

    libAVPin_AddRef(capture_filter->pin);
    capture_pin = capture_filter->pin;
    ctx->capture_pin[devtype] = capture_pin;

    r = IGraphBuilder_ConnectDirect(graph, device_pin, (IPin *) capture_pin, NULL);
    if (r != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not connect pins\n");
        goto error;
    }

    ret = 0;

error:
    return ret;
}
コード例 #4
0
ファイル: amstream.c プロジェクト: miurahr/wine
static HRESULT WINAPI IAMMultiMediaStreamImpl_AddMediaStream(IAMMultiMediaStream* iface, IUnknown* pStreamObject, const MSPID* PurposeId,
                                          DWORD dwFlags, IMediaStream** ppNewStream)
{
    IAMMultiMediaStreamImpl *This = impl_from_IAMMultiMediaStream(iface);
    HRESULT hr;
    IMediaStream* pStream;
    IMediaStream** pNewStreams;

    TRACE("(%p/%p)->(%p,%s,%x,%p)\n", This, iface, pStreamObject, debugstr_guid(PurposeId), dwFlags, ppNewStream);

    if (!IsEqualGUID(PurposeId, &MSPID_PrimaryVideo) && !IsEqualGUID(PurposeId, &MSPID_PrimaryAudio))
        return MS_E_PURPOSEID;

    if (dwFlags & AMMSF_ADDDEFAULTRENDERER)
    {
        if (IsEqualGUID(PurposeId, &MSPID_PrimaryVideo))
        {
            /* Default renderer not supported by video stream */
            return MS_E_PURPOSEID;
        }
        else
        {
            IBaseFilter* dsoundrender_filter;

            /* Create the default renderer for audio */
            hr = CoCreateInstance(&CLSID_DSoundRender, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&dsoundrender_filter);
            if (SUCCEEDED(hr))
            {
                 hr = IGraphBuilder_AddFilter(This->pFilterGraph, dsoundrender_filter, NULL);
                 IBaseFilter_Release(dsoundrender_filter);
            }

            /* No media stream created when the default renderer is used */
            return hr;
        }
    }

    if (IsEqualGUID(PurposeId, &MSPID_PrimaryVideo))
        hr = ddrawmediastream_create((IMultiMediaStream*)iface, PurposeId, This->StreamType, &pStream);
    else
        hr = audiomediastream_create((IMultiMediaStream*)iface, PurposeId, This->StreamType, &pStream);
    if (SUCCEEDED(hr))
    {
        pNewStreams = CoTaskMemRealloc(This->pStreams, (This->nbStreams+1) * sizeof(IMediaStream*));
        if (!pNewStreams)
        {
            IMediaStream_Release(pStream);
            return E_OUTOFMEMORY;
        }
        This->pStreams = pNewStreams;
        This->pStreams[This->nbStreams] = pStream;
        This->nbStreams++;

        if (ppNewStream)
            *ppNewStream = pStream;
    }

    if (SUCCEEDED(hr))
    {
        /* Add stream to the media stream filter */
        IMediaStreamFilter_AddMediaStream((IMediaStreamFilter*)This->media_stream_filter, (IAMMediaStream*)pStream);
    }

    return hr;
}
コード例 #5
0
static HRESULT GetSplitter(MediaDetImpl *This)
{
    IFileSourceFilter *file;
    LPOLESTR name;
    AM_MEDIA_TYPE mt;
    GUID type[2];
    IFilterMapper2 *map;
    IEnumMoniker *filters;
    IMoniker *mon;
    VARIANT var;
    GUID clsid;
    IBaseFilter *splitter;
    IEnumPins *pins;
    IPin *source_pin, *splitter_pin;
    HRESULT hr;

    hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
                          &IID_IFilterMapper2, (void **) &map);
    if (FAILED(hr))
        return hr;

    hr = IBaseFilter_QueryInterface(This->source, &IID_IFileSourceFilter,
                                    (void **) &file);
    if (FAILED(hr))
    {
        IFilterMapper2_Release(map);
        return hr;
    }

    hr = IFileSourceFilter_GetCurFile(file, &name, &mt);
    IFileSourceFilter_Release(file);
    CoTaskMemFree(name);
    if (FAILED(hr))
    {
        IFilterMapper2_Release(map);
        return hr;
    }
    type[0] = mt.majortype;
    type[1] = mt.subtype;
    CoTaskMemFree(mt.pbFormat);

    hr = IFilterMapper2_EnumMatchingFilters(map, &filters, 0, TRUE,
                                            MERIT_UNLIKELY, FALSE, 1, type,
                                            NULL, NULL, FALSE, TRUE,
                                            0, NULL, NULL, NULL);
    IFilterMapper2_Release(map);
    if (FAILED(hr))
        return hr;

    hr = E_NOINTERFACE;
    while (IEnumMoniker_Next(filters, 1, &mon, NULL) == S_OK)
    {
        hr = GetFilterInfo(mon, &clsid, &var);
        IMoniker_Release(mon);
        if (FAILED(hr))
            continue;

        hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER,
                              &IID_IBaseFilter, (void **) &splitter);
        if (FAILED(hr))
        {
            VariantClear(&var);
            continue;
        }

        hr = IGraphBuilder_AddFilter(This->graph, splitter,
                                     V_UNION(&var, bstrVal));
        VariantClear(&var);
        This->splitter = splitter;
        if (FAILED(hr))
            goto retry;

        hr = IBaseFilter_EnumPins(This->source, &pins);
        if (FAILED(hr))
            goto retry;
        IEnumPins_Next(pins, 1, &source_pin, NULL);
        IEnumPins_Release(pins);

        hr = IBaseFilter_EnumPins(splitter, &pins);
        if (FAILED(hr))
        {
            IPin_Release(source_pin);
            goto retry;
        }
        IEnumPins_Next(pins, 1, &splitter_pin, NULL);
        IEnumPins_Release(pins);

        hr = IPin_Connect(source_pin, splitter_pin, NULL);
        IPin_Release(source_pin);
        IPin_Release(splitter_pin);
        if (SUCCEEDED(hr))
            break;

retry:
        IBaseFilter_Release(splitter);
        This->splitter = NULL;
    }

    IEnumMoniker_Release(filters);
    if (FAILED(hr))
        return hr;

    return S_OK;
}
コード例 #6
0
ファイル: dshow.c プロジェクト: tuyooc/ppsspp-ffmpeg
static int
dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum,
                  enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype)
{
    struct dshow_ctx *ctx = avctx->priv_data;
    IBaseFilter *device_filter = NULL;
    IGraphBuilder *graph = ctx->graph;
    IPin *device_pin = NULL;
    libAVPin *capture_pin = NULL;
    libAVFilter *capture_filter = NULL;
    ICaptureGraphBuilder2 *graph_builder2 = NULL;
    int ret = AVERROR(EIO);
    int r;

    const wchar_t *filter_name[2] = { L"Audio capture filter", L"Video capture filter" };

    if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, &device_filter)) < 0) {
        ret = r;
        goto error;
    }

    ctx->device_filter [devtype] = device_filter;

    r = IGraphBuilder_AddFilter(graph, device_filter, NULL);
    if (r != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not add device filter to graph.\n");
        goto error;
    }

    if ((r = dshow_cycle_pins(avctx, devtype, sourcetype, device_filter, &device_pin)) < 0) {
        ret = r;
        goto error;
    }

    ctx->device_pin[devtype] = device_pin;

    capture_filter = libAVFilter_Create(avctx, callback, devtype);
    if (!capture_filter) {
        av_log(avctx, AV_LOG_ERROR, "Could not create grabber filter.\n");
        goto error;
    }
    ctx->capture_filter[devtype] = capture_filter;

    r = IGraphBuilder_AddFilter(graph, (IBaseFilter *) capture_filter,
                                filter_name[devtype]);
    if (r != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not add capture filter to graph\n");
        goto error;
    }

    libAVPin_AddRef(capture_filter->pin);
    capture_pin = capture_filter->pin;
    ctx->capture_pin[devtype] = capture_pin;

    r = CoCreateInstance(&CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER,
                         &IID_ICaptureGraphBuilder2, (void **) &graph_builder2);
    if (r != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not create CaptureGraphBuilder2\n");
        goto error;
    }
    ICaptureGraphBuilder2_SetFiltergraph(graph_builder2, graph);
    if (r != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not set graph for CaptureGraphBuilder2\n");
        goto error;
    }

    r = ICaptureGraphBuilder2_RenderStream(graph_builder2, NULL, NULL, (IUnknown *) device_pin, NULL /* no intermediate filter */,
        (IBaseFilter *) capture_filter); /* connect pins, optionally insert intermediate filters like crossbar if necessary */

    if (r != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not RenderStream to connect pins\n");
        goto error;
    }

    r = dshow_try_setup_crossbar_options(graph_builder2, device_filter, devtype, avctx);

    if (r != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not setup CrossBar\n");
        goto error;
    }

    ret = 0;

error:
    if (graph_builder2 != NULL)
        ICaptureGraphBuilder2_Release(graph_builder2);

    return ret;
}