Beispiel #1
0
static void test_AviCo(void)
{
    IPersistPropertyBag *persist_bag;
    IPin *pin, *in_pin, *out_pin;
    IEnumPins *enum_pins;
    IBaseFilter *avico;
    PIN_INFO pin_info;
    HRESULT hres;

    static const WCHAR inputW[] = {'I','n','p','u','t',0};
    static const WCHAR outputW[] = {'O','u','t','p','u','t',0};

    hres = CoCreateInstance(&CLSID_AVICo, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (void**)&avico);
    if(hres == REGDB_E_CLASSNOTREG) {
        win_skip("CLSID_AVICo not restered\n");
        return;
    }
    ok(hres == S_OK, "Could not create CLSID_AVICo class: %08x\n", hres);

    hres = IBaseFilter_QueryInterface(avico, &IID_IPin, (void**)&pin);
    ok(hres == E_NOINTERFACE, "QueryInterface(IID_IPin) returned: %08x\n", hres);

    hres = IBaseFilter_QueryInterface(avico, &IID_IPersistPropertyBag, (void**)&persist_bag);
    ok(hres == S_OK, "QueryInterface(IID_IPersistPropertyBag) returned: %08x\n", hres);

    SET_EXPECT(Read_FccHandler);
    hres = IPersistPropertyBag_Load(persist_bag, &PropertyBag, NULL);
    ok(hres == S_OK, "Load failed: %08x\n", hres);
    CHECK_CALLED(Read_FccHandler);

    IPersistPropertyBag_Release(persist_bag);

    hres = IBaseFilter_EnumPins(avico, &enum_pins);
    ok(hres == S_OK, "EnumPins failed: %08x\n", hres);

    hres = IEnumPins_Next(enum_pins, 1, &in_pin, NULL);
    ok(hres == S_OK, "Next failed: %08x\n", hres);

    hres = IPin_QueryPinInfo(in_pin, &pin_info);
    ok(hres == S_OK, "QueryPinInfo failed: %08x\n", hres);
    ok(pin_info.pFilter == avico, "pin_info.pFilter != avico\n");
    ok(pin_info.dir == PINDIR_INPUT, "pin_info.dir = %d\n", pin_info.dir);
    ok(!lstrcmpW(pin_info.achName, inputW), "pin_info.achName = %s\n", wine_dbgstr_w(pin_info.achName));

    hres = IEnumPins_Next(enum_pins, 1, &out_pin, NULL);
    ok(hres == S_OK, "Next failed: %08x\n", hres);

    hres = IPin_QueryPinInfo(out_pin, &pin_info);
    ok(hres == S_OK, "QueryPinInfo failed: %08x\n", hres);
    ok(pin_info.pFilter == avico, "pin_info.pFilter != avico\n");
    ok(pin_info.dir == PINDIR_OUTPUT, "pin_info.dir = %d\n", pin_info.dir);
    ok(!lstrcmpW(pin_info.achName, outputW), "pin_info.achName = %s\n", wine_dbgstr_w(pin_info.achName));

    IEnumPins_Release(enum_pins);

    IPin_Release(in_pin);
    IPin_Release(out_pin);
    IBaseFilter_Release(avico);
}
Beispiel #2
0
static HRESULT WINAPI MediaDet_get_OutputStreams(IMediaDet* iface, LONG *pVal)
{
    MediaDetImpl *This = impl_from_IMediaDet(iface);
    IEnumPins *pins;
    IPin *pin;
    HRESULT hr;

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

    if (!This->splitter)
        return E_INVALIDARG;

    if (This->num_streams != -1)
    {
        *pVal = This->num_streams;
        return S_OK;
    }

    *pVal = 0;

    hr = IBaseFilter_EnumPins(This->splitter, &pins);
    if (FAILED(hr))
        return hr;

    while (IEnumPins_Next(pins, 1, &pin, NULL) == S_OK)
    {
        PIN_DIRECTION dir;
        hr = IPin_QueryDirection(pin, &dir);
        IPin_Release(pin);
        if (FAILED(hr))
        {
            IEnumPins_Release(pins);
            return hr;
        }

        if (dir == PINDIR_OUTPUT)
            ++*pVal;
    }
    IEnumPins_Release(pins);

    This->num_streams = *pVal;
    return S_OK;
}
Beispiel #3
0
static HRESULT SetCurPin(MediaDetImpl *This, LONG strm)
{
    IEnumPins *pins;
    IPin *pin;
    HRESULT hr;

    assert(This->splitter);
    assert(0 <= strm && strm < This->num_streams);

    if (This->cur_pin)
    {
        IPin_Release(This->cur_pin);
        This->cur_pin = NULL;
    }

    hr = IBaseFilter_EnumPins(This->splitter, &pins);
    if (FAILED(hr))
        return hr;

    while (IEnumPins_Next(pins, 1, &pin, NULL) == S_OK && !This->cur_pin)
    {
        PIN_DIRECTION dir;
        hr = IPin_QueryDirection(pin, &dir);
        if (FAILED(hr))
        {
            IPin_Release(pin);
            IEnumPins_Release(pins);
            return hr;
        }

        if (dir == PINDIR_OUTPUT && strm-- == 0)
            This->cur_pin = pin;
        else
            IPin_Release(pin);
    }
    IEnumPins_Release(pins);

    assert(This->cur_pin);
    return S_OK;
}
Beispiel #4
0
static void test_basefilter(void)
{
    IEnumPins *pin_enum = NULL;
    IBaseFilter *base = NULL;
    IPin *pins[2];
    ULONG ref;
    HRESULT hr;

    IUnknown_QueryInterface(pAviSplitter, &IID_IBaseFilter, (void **)&base);
    if (base == NULL)
    {
        /* test_query_interface handles this case */
        skip("No IBaseFilter\n");
        return;
    }

    hr = IBaseFilter_EnumPins(base, NULL);
    ok(hr == E_POINTER, "hr = %08x and not E_POINTER\n", hr);

    hr= IBaseFilter_EnumPins(base, &pin_enum);
    ok(hr == S_OK, "hr = %08x and not S_OK\n", hr);

    hr = IEnumPins_Next(pin_enum, 1, NULL, NULL);
    ok(hr == E_POINTER, "hr = %08x and not E_POINTER\n", hr);

    hr = IEnumPins_Next(pin_enum, 2, pins, NULL);
    ok(hr == E_INVALIDARG, "hr = %08x and not E_INVALIDARG\n", hr);

    pins[0] = (void *)0xdead;
    pins[1] = (void *)0xdeed;

    hr = IEnumPins_Next(pin_enum, 2, pins, &ref);
    ok(hr == S_FALSE, "hr = %08x instead of S_FALSE\n", hr);
    ok(pins[0] != (void *)0xdead && pins[0] != NULL,
        "pins[0] = %p\n", pins[0]);
    if (pins[0] != (void *)0xdead && pins[0] != NULL)
    {
        test_pin(pins[0]);
        IPin_Release(pins[0]);
    }

    ok(pins[1] == (void *)0xdeed, "pins[1] = %p\n", pins[1]);

    ref = IEnumPins_Release(pin_enum);
    ok(ref == 0, "ref is %u and not 0!\n", ref);

    IBaseFilter_Release(base);
}
Beispiel #5
0
static HRESULT WINAPI IAMMultiMediaStreamImpl_OpenFile(IAMMultiMediaStream* iface, LPCWSTR filename, DWORD flags)
{
    IAMMultiMediaStreamImpl *This = impl_from_IAMMultiMediaStream(iface);
    HRESULT ret = S_OK;
    IBaseFilter *BaseFilter = NULL;
    IEnumPins *EnumPins = NULL;
    IPin *ipin;
    PIN_DIRECTION pin_direction;
    const WCHAR sourceW[] = {'S','o','u','r','c','e',0};

    TRACE("(%p/%p)->(%s,%x)\n", This, iface, debugstr_w(filename), flags);

    if (!filename)
        return E_POINTER;

    /* If Initialize was not called before, we do it here */
    if (!This->pFilterGraph)
        ret = IAMMultiMediaStream_Initialize(iface, STREAMTYPE_READ, 0, NULL);

    if (SUCCEEDED(ret))
        ret = IGraphBuilder_AddSourceFilter(This->pFilterGraph, filename, sourceW, &BaseFilter);

    if (SUCCEEDED(ret))
        ret = IBaseFilter_EnumPins(BaseFilter, &EnumPins);

    if (SUCCEEDED(ret))
        ret = IEnumPins_Next(EnumPins, 1, &ipin, NULL);

    if (SUCCEEDED(ret))
    {
        ret = IPin_QueryDirection(ipin, &pin_direction);
        if (ret == S_OK && pin_direction == PINDIR_OUTPUT)
            This->ipin = ipin;
    }

    if (SUCCEEDED(ret) && !(flags & AMMSF_NORENDER))
        ret = IGraphBuilder_Render(This->pFilterGraph, This->ipin);

    if (EnumPins)
        IEnumPins_Release(EnumPins);
    if (BaseFilter)
        IBaseFilter_Release(BaseFilter);
    return ret;
}
Beispiel #6
0
static HRESULT WINAPI
fnCaptureGraphBuilder2_FindPin(ICaptureGraphBuilder2 * iface,
                               IUnknown *pSource,
                               PIN_DIRECTION pindir,
                               const GUID *pCategory,
                               const GUID *pType,
                               BOOL fUnconnected,
                               INT num,
                               IPin **ppPin)
{
    HRESULT hr;
    IEnumPins *enumpins = NULL;
    IPin *pin;
    CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);

    TRACE("(%p/%p)->(%p, %x, %s, %s, %d, %i, %p)\n", This, iface,
          pSource, pindir, debugstr_guid(pCategory), debugstr_guid(pType),
          fUnconnected, num, ppPin);

    pin = NULL;

    hr = IUnknown_QueryInterface(pSource, &IID_IPin, (void**)&pin);
    if (hr == E_NOINTERFACE)
    {
        IBaseFilter *filter = NULL;
        int numcurrent = 0;

        hr = IUnknown_QueryInterface(pSource, &IID_IBaseFilter, (void**)&filter);
        if (hr == E_NOINTERFACE)
        {
            WARN("Input not filter or pin?!\n");
            return E_FAIL;
        }

        hr = IBaseFilter_EnumPins(filter, &enumpins);
        if (FAILED(hr))
        {
            WARN("Could not enumerate\n");
            return hr;
        }

        IEnumPins_Reset(enumpins);

        while (1)
        {
            hr = IEnumPins_Next(enumpins, 1, &pin, NULL);
            if (hr == VFW_E_ENUM_OUT_OF_SYNC)
            {
                numcurrent = 0;
                IEnumPins_Reset(enumpins);
                pin = NULL;
                continue;
            }

            if (hr != S_OK)
                break;
            TRACE("Testing match\n");
            if (pin_matches(pin, pindir, pCategory, pType, fUnconnected) && numcurrent++ == num)
                break;
            IPin_Release(pin);
            pin = NULL;
        }
        IEnumPins_Release(enumpins);

        if (hr != S_OK)
        {
            WARN("Could not find %s pin # %d\n", (pindir == PINDIR_OUTPUT ? "output" : "input"), numcurrent);
            return E_FAIL;
        }
    }
    else if (!pin_matches(pin, pindir, pCategory, pType, fUnconnected))
    {
        IPin_Release(pin);
        return E_FAIL;
    }

    *ppPin = pin;
    return S_OK;
}
Beispiel #7
0
/**
 * Cycle through available pins using the device_filter device, of type
 * devtype, retrieve the first output pin and return the pointer to the
 * object found in *ppin.
 * If ppin is NULL, cycle through all pins listing audio/video capabilities.
 */
static int
dshow_cycle_pins(AVFormatContext *avctx, enum dshowDeviceType devtype,
                 enum dshowSourceFilterType sourcetype, IBaseFilter *device_filter, IPin **ppin)
{
    struct dshow_ctx *ctx = avctx->priv_data;
    IEnumPins *pins = 0;
    IPin *device_pin = NULL;
    IPin *pin;
    int r;

    const GUID *mediatype[2] = { &MEDIATYPE_Video, &MEDIATYPE_Audio };
    const char *devtypename = (devtype == VideoDevice) ? "video" : "audio only";
    const char *sourcetypename = (sourcetype == VideoSourceDevice) ? "video" : "audio";

    int set_format = (devtype == VideoDevice && (ctx->framerate ||
                                                (ctx->requested_width && ctx->requested_height) ||
                                                 ctx->pixel_format != AV_PIX_FMT_NONE ||
                                                 ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO))
                  || (devtype == AudioDevice && (ctx->channels || ctx->sample_rate));
    int format_set = 0;
    int should_show_properties = (devtype == VideoDevice) ? ctx->show_video_device_dialog : ctx->show_audio_device_dialog;

    if (should_show_properties)
        dshow_show_filter_properties(device_filter, avctx);

    r = IBaseFilter_EnumPins(device_filter, &pins);
    if (r != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not enumerate pins.\n");
        return AVERROR(EIO);
    }

    if (!ppin) {
        av_log(avctx, AV_LOG_INFO, "DirectShow %s device options (from %s devices)\n",
               devtypename, sourcetypename);
    }

    while (!device_pin && IEnumPins_Next(pins, 1, &pin, NULL) == S_OK) {
        IKsPropertySet *p = NULL;
        IEnumMediaTypes *types = NULL;
        PIN_INFO info = {0};
        AM_MEDIA_TYPE *type;
        GUID category;
        DWORD r2;
        char *name_buf = NULL;
        wchar_t *pin_id = NULL;
        char *pin_buf = NULL;
        char *desired_pin_name = devtype == VideoDevice ? ctx->video_pin_name : ctx->audio_pin_name;

        IPin_QueryPinInfo(pin, &info);
        IBaseFilter_Release(info.pFilter);

        if (info.dir != PINDIR_OUTPUT)
            goto next;
        if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **) &p) != S_OK)
            goto next;
        if (IKsPropertySet_Get(p, &AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY,
                               NULL, 0, &category, sizeof(GUID), &r2) != S_OK)
            goto next;
        if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE))
            goto next;
        name_buf = dup_wchar_to_utf8(info.achName);

        r = IPin_QueryId(pin, &pin_id);
        if (r != S_OK) {
            av_log(avctx, AV_LOG_ERROR, "Could not query pin id\n");
            return AVERROR(EIO);
        }
        pin_buf = dup_wchar_to_utf8(pin_id);

        if (!ppin) {
            av_log(avctx, AV_LOG_INFO, " Pin \"%s\" (alternative pin name \"%s\")\n", name_buf, pin_buf);
            dshow_cycle_formats(avctx, devtype, pin, NULL);
            goto next;
        }

        if (desired_pin_name) {
            if(strcmp(name_buf, desired_pin_name) && strcmp(pin_buf, desired_pin_name)) {
                av_log(avctx, AV_LOG_DEBUG, "skipping pin \"%s\" (\"%s\") != requested \"%s\"\n",
                    name_buf, pin_buf, desired_pin_name);
                goto next;
            }
        }

        if (set_format) {
            dshow_cycle_formats(avctx, devtype, pin, &format_set);
            if (!format_set) {
                goto next;
            }
        }
        if (devtype == AudioDevice && ctx->audio_buffer_size) {
            if (dshow_set_audio_buffer_size(avctx, pin) < 0) {
                av_log(avctx, AV_LOG_ERROR, "unable to set audio buffer size %d to pin, using pin anyway...", ctx->audio_buffer_size);
            }
        }

        if (IPin_EnumMediaTypes(pin, &types) != S_OK)
            goto next;

        IEnumMediaTypes_Reset(types);
        /* in case format_set was not called, just verify the majortype */
        while (!device_pin && IEnumMediaTypes_Next(types, 1, &type, NULL) == S_OK) {
            if (IsEqualGUID(&type->majortype, mediatype[devtype])) {
                device_pin = pin;
                av_log(avctx, AV_LOG_DEBUG, "Selecting pin %s on %s\n", name_buf, devtypename);
                goto next;
            }
            CoTaskMemFree(type);
        }

next:
        if (types)
            IEnumMediaTypes_Release(types);
        if (p)
            IKsPropertySet_Release(p);
        if (device_pin != pin)
            IPin_Release(pin);
        av_free(name_buf);
        av_free(pin_buf);
        if (pin_id)
            CoTaskMemFree(pin_id);
    }

    IEnumPins_Release(pins);

    if (ppin) {
        if (set_format && !format_set) {
            av_log(avctx, AV_LOG_ERROR, "Could not set %s options\n", devtypename);
            return AVERROR(EIO);
        }
        if (!device_pin) {
            av_log(avctx, AV_LOG_ERROR,
                "Could not find output pin from %s capture device.\n", devtypename);
            return AVERROR(EIO);
        }
        *ppin = device_pin;
    }

    return 0;
}
Beispiel #8
0
/**
 * Cycle through available pins using the device_filter device, of type
 * devtype, retrieve the first output pin and return the pointer to the
 * object found in *ppin.
 * If ppin is NULL, cycle through all pins listing audio/video capabilities.
 */
static int
dshow_cycle_pins(AVFormatContext *avctx, enum dshowDeviceType devtype,
                 IBaseFilter *device_filter, IPin **ppin)
{
    struct dshow_ctx *ctx = avctx->priv_data;
    IEnumPins *pins = 0;
    IPin *device_pin = NULL;
    IPin *pin;
    int r;

    const GUID *mediatype[2] = { &MEDIATYPE_Video, &MEDIATYPE_Audio };
    const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";

    int set_format = (devtype == VideoDevice && (ctx->framerate ||
                                                (ctx->requested_width && ctx->requested_height) ||
                                                 ctx->pixel_format != AV_PIX_FMT_NONE ||
                                                 ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO))
                  || (devtype == AudioDevice && (ctx->channels || ctx->sample_rate));
    int format_set = 0;

    r = IBaseFilter_EnumPins(device_filter, &pins);
    if (r != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not enumerate pins.\n");
        return AVERROR(EIO);
    }

    if (!ppin) {
        av_log(avctx, AV_LOG_INFO, "DirectShow %s device options\n",
               devtypename);
    }
    while (!device_pin && IEnumPins_Next(pins, 1, &pin, NULL) == S_OK) {
        IKsPropertySet *p = NULL;
        IEnumMediaTypes *types = NULL;
        PIN_INFO info = {0};
        AM_MEDIA_TYPE *type;
        GUID category;
        DWORD r2;

        IPin_QueryPinInfo(pin, &info);
        IBaseFilter_Release(info.pFilter);

        if (info.dir != PINDIR_OUTPUT)
            goto next;
        if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **) &p) != S_OK)
            goto next;
        if (IKsPropertySet_Get(p, &AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY,
                               NULL, 0, &category, sizeof(GUID), &r2) != S_OK)
            goto next;
        if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE))
            goto next;

        if (!ppin) {
            char *buf = dup_wchar_to_utf8(info.achName);
            av_log(avctx, AV_LOG_INFO, " Pin \"%s\"\n", buf);
            av_free(buf);
            dshow_cycle_formats(avctx, devtype, pin, NULL);
            goto next;
        }
        if (set_format) {
            dshow_cycle_formats(avctx, devtype, pin, &format_set);
            if (!format_set) {
                goto next;
            }
        }
        if (devtype == AudioDevice && ctx->audio_buffer_size) {
            if (dshow_set_audio_buffer_size(avctx, pin) < 0)
                goto next;
        }

        if (IPin_EnumMediaTypes(pin, &types) != S_OK)
            goto next;

        IEnumMediaTypes_Reset(types);
        while (!device_pin && IEnumMediaTypes_Next(types, 1, &type, NULL) == S_OK) {
            if (IsEqualGUID(&type->majortype, mediatype[devtype])) {
                device_pin = pin;
                goto next;
            }
            CoTaskMemFree(type);
        }

next:
        if (types)
            IEnumMediaTypes_Release(types);
        if (p)
            IKsPropertySet_Release(p);
        if (device_pin != pin)
            IPin_Release(pin);
    }

    IEnumPins_Release(pins);

    if (ppin) {
        if (set_format && !format_set) {
            av_log(avctx, AV_LOG_ERROR, "Could not set %s options\n", devtypename);
            return AVERROR(EIO);
        }
        if (!device_pin) {
            av_log(avctx, AV_LOG_ERROR,
                "Could not find output pin from %s capture device.\n", devtypename);
            return AVERROR(EIO);
        }
        *ppin = device_pin;
    }

    return 0;
}
Beispiel #9
0
static void test_media_streams(void)
{
    HRESULT hr;
    IMediaStream *video_stream = NULL;
    IMediaStream *audio_stream = NULL;
    IMediaStream *dummy_stream;
    IMediaStreamFilter* media_stream_filter = NULL;

    if (!create_ammultimediastream())
        return;
    if (!create_directdraw())
    {
        release_ammultimediastream();
        return;
    }

    hr = IAMMultiMediaStream_Initialize(pams, STREAMTYPE_READ, 0, NULL);
    ok(hr == S_OK, "IAMMultiMediaStream_Initialize returned: %x\n", hr);

    /* Retrieve media stream filter */
    hr = IAMMultiMediaStream_GetFilter(pams, NULL);
    ok(hr == E_POINTER, "IAMMultiMediaStream_GetFilter returned: %x\n", hr);
    hr = IAMMultiMediaStream_GetFilter(pams, &media_stream_filter);
    ok(hr == S_OK, "IAMMultiMediaStream_GetFilter returned: %x\n", hr);

    /* Verify behaviour with invalid purpose id */
    hr = IAMMultiMediaStream_GetMediaStream(pams, &IID_IUnknown, &dummy_stream);
    ok(hr == MS_E_NOSTREAM, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
    hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &IID_IUnknown, 0, NULL);
    ok(hr == MS_E_PURPOSEID, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);

    /* Verify there is no video media stream */
    hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryVideo, &video_stream);
    ok(hr == MS_E_NOSTREAM, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);

    /* Verify there is no default renderer for video stream */
    hr = IAMMultiMediaStream_AddMediaStream(pams, (IUnknown*)pdd7, &MSPID_PrimaryVideo, AMMSF_ADDDEFAULTRENDERER, NULL);
    ok(hr == MS_E_PURPOSEID, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
    hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryVideo, &video_stream);
    ok(hr == MS_E_NOSTREAM, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
    hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryVideo, AMMSF_ADDDEFAULTRENDERER, NULL);
    ok(hr == MS_E_PURPOSEID, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
    hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryVideo, &video_stream);
    ok(hr == MS_E_NOSTREAM, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);

    /* Verify normal case for video stream */
    hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryVideo, 0, NULL);
    ok(hr == S_OK, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
    hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryVideo, &video_stream);
    ok(hr == S_OK, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);

    /* Verify the video stream has been added to the media stream filter */
    if (media_stream_filter)
    {
        hr = IMediaStreamFilter_GetMediaStream(media_stream_filter, &MSPID_PrimaryVideo, &dummy_stream);
        ok(hr == S_OK, "IMediaStreamFilter_GetMediaStream returned: %x\n", hr);
        ok(dummy_stream == video_stream, "Got wrong returned pointer %p, expected %p\n", dummy_stream, video_stream);
        if (SUCCEEDED(hr))
            IMediaStream_Release(dummy_stream);
    }

    /* Check interfaces and samples for video */
    if (video_stream)
    {
        IAMMediaStream* am_media_stream;
        IAudioMediaStream* audio_media_stream;
        IDirectDrawMediaStream *ddraw_stream = NULL;
        IDirectDrawStreamSample *ddraw_sample = NULL;

        hr = IMediaStream_QueryInterface(video_stream, &IID_IAMMediaStream, (LPVOID*)&am_media_stream);
        todo_wine ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
        todo_wine ok((void*)am_media_stream == (void*)video_stream, "Not same interface, got %p expected %p\n", am_media_stream, video_stream);
        if (hr == S_OK)
            IAMMediaStream_Release(am_media_stream);

        hr = IMediaStream_QueryInterface(video_stream, &IID_IAudioMediaStream, (LPVOID*)&audio_media_stream);
        ok(hr == E_NOINTERFACE, "IMediaStream_QueryInterface returned: %x\n", hr);

        hr = IMediaStream_QueryInterface(video_stream, &IID_IDirectDrawMediaStream, (LPVOID*)&ddraw_stream);
        ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);

        if (SUCCEEDED(hr))
        {
            DDSURFACEDESC current_format, desired_format;
            IDirectDrawPalette *palette;
            DWORD flags;

            hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, &current_format, &palette, &desired_format, &flags);
            ok(hr == MS_E_NOSTREAM, "IDirectDrawoMediaStream_GetFormat returned: %x\n", hr);

            hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &ddraw_sample);
            ok(hr == S_OK, "IDirectDrawMediaStream_CreateSample returned: %x\n", hr);
        }

        if (ddraw_sample)
            IDirectDrawStreamSample_Release(ddraw_sample);
        if (ddraw_stream)
            IDirectDrawMediaStream_Release(ddraw_stream);
    }

    /* Verify there is no audio media stream */
    hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryAudio, &audio_stream);
    ok(hr == MS_E_NOSTREAM, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);

    /* Verify no stream is created when using the default renderer for audio stream */
    hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryAudio, AMMSF_ADDDEFAULTRENDERER, NULL);
    ok((hr == S_OK) || (hr == VFW_E_NO_AUDIO_HARDWARE), "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
    if (hr == S_OK)
    {
        IGraphBuilder* filtergraph = NULL;
        IBaseFilter* filter = NULL;
        const WCHAR name[] = {'0','0','0','1',0};
        CLSID clsid;

        hr = IAMMultiMediaStream_GetFilterGraph(pams, &filtergraph);
        ok(hr == S_OK, "IAMMultiMediaStream_GetFilterGraph returned: %x\n", hr);
        if (hr == S_OK)
        {
            hr = IGraphBuilder_FindFilterByName(filtergraph, name, &filter);
            ok(hr == S_OK, "IGraphBuilder_FindFilterByName returned: %x\n", hr);
        }
        if (hr == S_OK)
        {
            hr = IBaseFilter_GetClassID(filter, &clsid);
            ok(hr == S_OK, "IGraphBuilder_FindFilterByName returned: %x\n", hr);
        }
        if (hr == S_OK)
            ok(IsEqualGUID(&clsid, &CLSID_DSoundRender), "Got wrong CLSID\n");
        if (filter)
            IBaseFilter_Release(filter);
        if (filtergraph)
            IGraphBuilder_Release(filtergraph);
    }
    hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryAudio, &audio_stream);
    ok(hr == MS_E_NOSTREAM, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);

    /* Verify a stream is created when no default renderer is used */
    hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryAudio, 0, NULL);
    ok(hr == S_OK, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
    hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryAudio, &audio_stream);
    ok(hr == S_OK, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);

    /* verify the audio stream has been added to the media stream filter */
    if (media_stream_filter)
    {
        hr = IMediaStreamFilter_GetMediaStream(media_stream_filter, &MSPID_PrimaryAudio, &dummy_stream);
        ok(hr == S_OK, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
        ok(dummy_stream == audio_stream, "Got wrong returned pointer %p, expected %p\n", dummy_stream, audio_stream);
        if (SUCCEEDED(hr))
            IMediaStream_Release(dummy_stream);
    }

   /* Check interfaces and samples for audio */
    if (audio_stream)
    {
        IAMMediaStream* am_media_stream;
        IDirectDrawMediaStream* ddraw_stream = NULL;
        IAudioMediaStream* audio_media_stream = NULL;
        IAudioStreamSample *audio_sample = NULL;

        hr = IMediaStream_QueryInterface(audio_stream, &IID_IAMMediaStream, (LPVOID*)&am_media_stream);
        todo_wine ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
        todo_wine ok((void*)am_media_stream == (void*)audio_stream, "Not same interface, got %p expected %p\n", am_media_stream, video_stream);
        if (hr == S_OK)
            IAMMediaStream_Release(am_media_stream);

        hr = IMediaStream_QueryInterface(audio_stream, &IID_IDirectDrawMediaStream, (LPVOID*)&ddraw_stream);
        ok(hr == E_NOINTERFACE, "IMediaStream_QueryInterface returned: %x\n", hr);

        hr = IMediaStream_QueryInterface(audio_stream, &IID_IAudioMediaStream, (LPVOID*)&audio_media_stream);
        ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);

        if (SUCCEEDED(hr))
        {
            IAudioData* audio_data = NULL;
            WAVEFORMATEX format;

            hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data);
            ok(hr == S_OK, "CoCreateInstance returned: %x\n", hr);

            hr = IAudioMediaStream_GetFormat(audio_media_stream, NULL);
            ok(hr == E_POINTER, "IAudioMediaStream_GetFormat returned: %x\n", hr);
            hr = IAudioMediaStream_GetFormat(audio_media_stream, &format);
            ok(hr == MS_E_NOSTREAM, "IAudioMediaStream_GetFormat returned: %x\n", hr);

            hr = IAudioMediaStream_CreateSample(audio_media_stream, NULL, 0, &audio_sample);
            ok(hr == E_POINTER, "IAudioMediaStream_CreateSample returned: %x\n", hr);
            hr = IAudioMediaStream_CreateSample(audio_media_stream, audio_data, 0, &audio_sample);
            ok(hr == S_OK, "IAudioMediaStream_CreateSample returned: %x\n", hr);

            if (audio_data)
                IAudioData_Release(audio_data);
            if (audio_sample)
                IAudioStreamSample_Release(audio_sample);
            if (audio_media_stream)
                IAudioMediaStream_Release(audio_media_stream);
        }
    }

    if (media_stream_filter)
    {
        IEnumPins *enum_pins;

        hr = IMediaStreamFilter_EnumPins(media_stream_filter, &enum_pins);
        ok(hr == S_OK, "IBaseFilter_EnumPins returned: %x\n", hr);
        if (hr == S_OK)
        {
            IPin* pins[3] = { NULL, NULL, NULL };
            ULONG nb_pins;
            ULONG expected_nb_pins = audio_stream ? 2 : 1;
            int i;

            hr = IEnumPins_Next(enum_pins, 3, pins, &nb_pins);
            ok(SUCCEEDED(hr), "IEnumPins_Next returned: %x\n", hr);
            ok(nb_pins == expected_nb_pins, "Number of pins is %u instead of %u\n", nb_pins, expected_nb_pins);
            for (i = 0; i < min(nb_pins, expected_nb_pins); i++)
            {
                IEnumMediaTypes* enum_media_types;
                AM_MEDIA_TYPE* media_types[10];
                ULONG nb_media_types;
                IPin* pin;
                PIN_INFO info;
                WCHAR id[40];

                /* Pin name is "I{guid MSPID_PrimaryVideo or MSPID_PrimaryAudio}" */
                id[0] = 'I';
                StringFromGUID2(i ? &MSPID_PrimaryAudio : &MSPID_PrimaryVideo, id + 1, 40);

                hr = IPin_ConnectedTo(pins[i], &pin);
                ok(hr == VFW_E_NOT_CONNECTED, "IPin_ConnectedTo returned: %x\n", hr);
                hr = IPin_QueryPinInfo(pins[i], &info);
                ok(hr == S_OK, "IPin_QueryPinInfo returned: %x\n", hr);
                IBaseFilter_Release(info.pFilter);
                ok(info.dir == PINDIR_INPUT, "Pin direction is %u instead of %u\n", info.dir, PINDIR_INPUT);
                ok(!lstrcmpW(info.achName, id), "Pin name is %s instead of %s\n", wine_dbgstr_w(info.achName), wine_dbgstr_w(id));
                hr = IPin_EnumMediaTypes(pins[i], &enum_media_types);
                ok(hr == S_OK, "IPin_EnumMediaTypes returned: %x\n", hr);
                hr = IEnumMediaTypes_Next(enum_media_types, sizeof(media_types) / sizeof(AM_MEDIA_TYPE), media_types, &nb_media_types);
                ok(SUCCEEDED(hr), "IEnumMediaTypes_Next returned: %x\n", hr);
                ok(nb_media_types == 0, "nb_media_types should be 0 instead of %u\n", nb_media_types);
                IEnumMediaTypes_Release(enum_media_types);
                IPin_Release(pins[i]);
            }
            IEnumPins_Release(enum_pins);
        }
    }

    if (video_stream)
        IMediaStream_Release(video_stream);
    if (audio_stream)
        IMediaStream_Release(audio_stream);
    if (media_stream_filter)
        IMediaStreamFilter_Release(media_stream_filter);

    release_directdraw();
    release_ammultimediastream();
}
Beispiel #10
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;
}
Beispiel #11
0
static void test_smart_tee_filter(void)
{
    HRESULT hr;
    IBaseFilter *smartTeeFilter = NULL;
    IEnumPins *enumPins = NULL;
    IPin *pin;
    FILTER_INFO filterInfo;
    int pinNumber = 0;

    hr = CoCreateInstance(&CLSID_SmartTee, NULL, CLSCTX_INPROC_SERVER,
            &IID_IBaseFilter, (void**)&smartTeeFilter);
    todo_wine ok(SUCCEEDED(hr), "couldn't create smart tee filter, hr=%08x\n", hr);
    if (FAILED(hr))
        goto end;

    hr = IBaseFilter_QueryFilterInfo(smartTeeFilter, &filterInfo);
    ok(SUCCEEDED(hr), "QueryFilterInfo failed, hr=%08x\n", hr);
    if (FAILED(hr))
        goto end;

    ok(lstrlenW(filterInfo.achName) == 0,
            "filter's name is meant to be empty but it's %s\n", wine_dbgstr_w(filterInfo.achName));

    hr = IBaseFilter_EnumPins(smartTeeFilter, &enumPins);
    ok(SUCCEEDED(hr), "cannot enum filter pins, hr=%08x\n", hr);
    if (FAILED(hr))
        goto end;

    while (IEnumPins_Next(enumPins, 1, &pin, NULL) == S_OK)
    {
        PIN_INFO pinInfo;
        hr = IPin_QueryPinInfo(pin, &pinInfo);
        ok(SUCCEEDED(hr), "QueryPinInfo failed, hr=%08x\n", hr);
        if (FAILED(hr))
            goto endwhile;

        if (pinNumber == 0)
        {
            static const WCHAR wszInput[] = {'I','n','p','u','t',0};
            ok(pinInfo.dir == PINDIR_INPUT, "pin 0 isn't an input pin\n");
            ok(!lstrcmpW(pinInfo.achName, wszInput), "pin 0 is called %s, not 'Input'\n", wine_dbgstr_w(pinInfo.achName));
        }
        else if (pinNumber == 1)
        {
            static const WCHAR wszCapture[] = {'C','a','p','t','u','r','e',0};
            ok(pinInfo.dir == PINDIR_OUTPUT, "pin 1 isn't an output pin\n");
            ok(!lstrcmpW(pinInfo.achName, wszCapture), "pin 1 is called %s, not 'Capture'\n", wine_dbgstr_w(pinInfo.achName));
        }
        else if (pinNumber == 2)
        {
            static const WCHAR wszPreview[] = {'P','r','e','v','i','e','w',0};
            ok(pinInfo.dir == PINDIR_OUTPUT, "pin 2 isn't an output pin\n");
            ok(!lstrcmpW(pinInfo.achName, wszPreview), "pin 2 is called %s, not 'Preview'\n", wine_dbgstr_w(pinInfo.achName));
        }
        else
            ok(0, "pin %d isn't supposed to exist\n", pinNumber);

    endwhile:
        IPin_Release(pin);
        pinNumber++;
    }

end:
    if (smartTeeFilter)
        IBaseFilter_Release(smartTeeFilter);
    if (enumPins)
        IEnumPins_Release(enumPins);
}
Beispiel #12
0
static GstCaps *
gst_dshowaudiosrc_get_caps (GstBaseSrc * basesrc)
{
  HRESULT hres = S_OK;
  IBindCtx *lpbc = NULL;
  IMoniker *audiom = NULL;
  DWORD dwEaten;
  GstDshowAudioSrc *src = GST_DSHOWAUDIOSRC (basesrc);
  gunichar2 *unidevice = NULL;

  if (src->device) {
    g_free (src->device);
    src->device = NULL;
  }

  src->device =
      gst_dshow_getdevice_from_devicename (&CLSID_AudioInputDeviceCategory,
      &src->device_name);
  if (!src->device) {
    GST_CAT_ERROR (dshowaudiosrc_debug, "No audio device found.");
    return NULL;
  }
  unidevice =
      g_utf8_to_utf16 (src->device, strlen (src->device), NULL, NULL, NULL);

  if (!src->audio_cap_filter) {
    hres = CreateBindCtx (0, &lpbc);
    if (SUCCEEDED (hres)) {
      hres = MkParseDisplayName (lpbc, unidevice, &dwEaten, &audiom);
      if (SUCCEEDED (hres)) {
        hres =
            IMoniker_BindToObject (audiom, lpbc, NULL, &IID_IBaseFilter,
            &src->audio_cap_filter);
        IMoniker_Release (audiom);
      }
      IBindCtx_Release (lpbc);
    }
  }

  if (src->audio_cap_filter && !src->caps) {
    /* get the capture pins supported types */
    IPin *capture_pin = NULL;
    IEnumPins *enumpins = NULL;
    HRESULT hres;

    hres = IBaseFilter_EnumPins (src->audio_cap_filter, &enumpins);
    if (SUCCEEDED (hres)) {
      while (IEnumPins_Next (enumpins, 1, &capture_pin, NULL) == S_OK) {
        IKsPropertySet *pKs = NULL;

        hres =
            IPin_QueryInterface (capture_pin, &IID_IKsPropertySet,
            (void **) &pKs);
        if (SUCCEEDED (hres) && pKs) {
          DWORD cbReturned;
          GUID pin_category;
          RPC_STATUS rpcstatus;

          hres =
              IKsPropertySet_Get (pKs, &AMPROPSETID_Pin,
              AMPROPERTY_PIN_CATEGORY, NULL, 0, &pin_category, sizeof (GUID),
              &cbReturned);

          /* we only want capture pins */
          if (UuidCompare (&pin_category, &PIN_CATEGORY_CAPTURE,
                  &rpcstatus) == 0) {
            IAMStreamConfig *streamcaps = NULL;

            if (SUCCEEDED (IPin_QueryInterface (capture_pin,
                        &IID_IAMStreamConfig, (void **) &streamcaps))) {
              src->caps =
                  gst_dshowaudiosrc_getcaps_from_streamcaps (src, capture_pin,
                  streamcaps);
              IAMStreamConfig_Release (streamcaps);
            }
          }
          IKsPropertySet_Release (pKs);
        }
        IPin_Release (capture_pin);
      }
      IEnumPins_Release (enumpins);
    }
  }

  if (unidevice) {
    g_free (unidevice);
  }

  if (src->caps) {
    return gst_caps_ref (src->caps);
  }

  return NULL;
}
Beispiel #13
0
static HRESULT WINAPI IAMMultiMediaStreamImpl_OpenFile(IAMMultiMediaStream* iface, LPCWSTR pszFileName, DWORD dwFlags)
{
    HRESULT ret;
    IAMMultiMediaStreamImpl *This = impl_from_IAMMultiMediaStream(iface);
    IFileSourceFilter *SourceFilter;
    IBaseFilter *BaseFilter;
    IEnumPins *EnumPins;
    IPin *ipin;
    PIN_DIRECTION pin_direction;

    TRACE("(%p/%p)->(%s,%x)\n", This, iface, debugstr_w(pszFileName), dwFlags);

    ret = CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER, &IID_IFileSourceFilter, (void**)&SourceFilter);
    if(ret != S_OK)
        return ret;

    ret = IFileSourceFilter_Load(SourceFilter, pszFileName, NULL);
    if(ret != S_OK)
    {
        IFileSourceFilter_Release(SourceFilter);
        return ret;
    }

    ret = IFileSourceFilter_QueryInterface(SourceFilter, &IID_IBaseFilter, (void**)&BaseFilter);
    if(ret != S_OK)
    {
        IFileSourceFilter_Release(SourceFilter);
        return ret;
    }

    ret = IBaseFilter_EnumPins(BaseFilter, &EnumPins);
    if(ret != S_OK)
    {
        goto end;
    }

    ret = IEnumPins_Next(EnumPins, 1, &ipin, NULL);
    if(ret == S_OK)
    {
        ret = IPin_QueryDirection(ipin, &pin_direction);
        IEnumPins_Release(EnumPins);
        if(ret == S_OK && pin_direction == PINDIR_OUTPUT)
            This->ipin = ipin;
        else
            goto end;
    }
    else
    {
        IEnumPins_Release(EnumPins);
        goto end;
    }

    /* If Initialize was not called before, we do it here */
    if (!This->pFilterGraph)
    {
        ret = IAMMultiMediaStream_Initialize(iface, STREAMTYPE_READ, 0, NULL);
        if (FAILED(ret))
            goto end;
    }

    ret = IFilterGraph_QueryInterface(This->pFilterGraph, &IID_IGraphBuilder, (void**)&This->GraphBuilder);
    if(ret != S_OK)
    {
        goto end;
    }

    ret = IGraphBuilder_AddSourceFilter(This->GraphBuilder, pszFileName, pszFileName, &BaseFilter);

end:
    IBaseFilter_Release(BaseFilter);
    IFileSourceFilter_Release(SourceFilter);
    return ret;
}
Beispiel #14
0
/* This test doesn't use the quartz filtergraph because it makes it impossible
 * to be certain that a thread is really one owned by the avi splitter.
 * A lot of the decoder filters will also have their own thread, and Windows'
 * filtergraph has a separate thread for start/stop/seeking requests.
 * By avoiding the filtergraph altogether and connecting streams directly to
 * the null renderer I am sure that this is not the case here.
 */
static void test_threads(void)
{
    IFileSourceFilter *pfile = NULL;
    IBaseFilter *preader = NULL, *pavi = NULL;
    IEnumPins *enumpins = NULL;
    IPin *filepin = NULL, *avipin = NULL;
    HRESULT hr;
    int baselevel, curlevel, expected;
    HANDLE file = NULL;
    PIN_DIRECTION dir = PINDIR_OUTPUT;
    char buffer[13];
    DWORD readbytes;
    FILTER_STATE state;

    /* We need another way of counting threads on NT4. Skip these tests (for now) */
    if (!pCreateToolhelp32Snapshot || !pThread32First || !pThread32Next)
    {
        win_skip("Needed thread functions are not available (NT4)\n");
        return;
    }

    /* Before doing anything (the thread count at the start differs per OS) */
    baselevel = count_threads();

    file = CreateFileW(wfile, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
        NULL, OPEN_EXISTING, 0, NULL);
    if (file == INVALID_HANDLE_VALUE)
    {
        skip("Could not read test file \"%s\", skipping test\n", afile);
        return;
    }

    memset(buffer, 0, 13);
    readbytes = 12;
    ReadFile(file, buffer, readbytes, &readbytes, NULL);
    CloseHandle(file);
    if (strncmp(buffer, "RIFF", 4) || strcmp(buffer + 8, "AVI "))
    {
        skip("%s is not an avi riff file, not doing the avi splitter test\n",
            afile);
        return;
    }

    hr = IUnknown_QueryInterface(pAviSplitter, &IID_IFileSourceFilter,
        (void **)&pfile);
    ok(hr == E_NOINTERFACE,
        "Avi splitter returns unexpected error: %08x\n", hr);
    if (pfile)
        IFileSourceFilter_Release(pfile);
    pfile = NULL;

    hr = CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER,
        &IID_IBaseFilter, (LPVOID*)&preader);
    ok(hr == S_OK, "Could not create asynchronous reader: %08x\n", hr);
    if (hr != S_OK)
        goto fail;

    hr = IBaseFilter_QueryInterface(preader, &IID_IFileSourceFilter,
        (void**)&pfile);
    ok(hr == S_OK, "Could not get IFileSourceFilter: %08x\n", hr);
    if (hr != S_OK)
        goto fail;

    hr = IUnknown_QueryInterface(pAviSplitter, &IID_IBaseFilter,
        (void**)&pavi);
    ok(hr == S_OK, "Could not get base filter: %08x\n", hr);
    if (hr != S_OK)
        goto fail;

    hr = IFileSourceFilter_Load(pfile, wfile, NULL);
    if (hr != S_OK)
    {
        trace("Could not load file\n");
        goto fail;
    }

    hr = IBaseFilter_EnumPins(preader, &enumpins);
    ok(hr == S_OK, "No enumpins: %08x\n", hr);
    if (hr != S_OK)
        goto fail;

    hr = IEnumPins_Next(enumpins, 1, &filepin, NULL);
    ok(hr == S_OK, "No pin: %08x\n", hr);
    if (hr != S_OK)
        goto fail;

    IEnumPins_Release(enumpins);
    enumpins = NULL;

    hr = IBaseFilter_EnumPins(pavi, &enumpins);
    ok(hr == S_OK, "No enumpins: %08x\n", hr);
    if (hr != S_OK)
        goto fail;

    hr = IEnumPins_Next(enumpins, 1, &avipin, NULL);
    ok(hr == S_OK, "No pin: %08x\n", hr);
    if (hr != S_OK)
        goto fail;

    curlevel = count_threads();
    ok(curlevel == baselevel,
        "The thread count should be %d not %d\n", baselevel, curlevel);

    hr = IPin_Connect(filepin, avipin, NULL);
    ok(hr == S_OK, "Could not connect: %08x\n", hr);
    if (hr != S_OK)
        goto fail;

    expected = 1 + baselevel;
    curlevel = count_threads();
    ok(curlevel == expected,
        "The thread count should be %d not %d\n", expected, curlevel);

    IPin_Release(avipin);
    avipin = NULL;

    IEnumPins_Reset(enumpins);

    /* Windows puts the pins in the order: Outputpins - Inputpin,
     * wine does the reverse, just don't test it for now
     * Hate to admit it, but windows way makes more sense
     */
    while (IEnumPins_Next(enumpins, 1, &avipin, NULL) == S_OK)
    {
        IPin_QueryDirection(avipin, &dir);
        if (dir == PINDIR_OUTPUT)
        {
            /* Well, connect it to a null renderer! */
            IBaseFilter *pnull = NULL;
            IEnumPins *nullenum = NULL;
            IPin *nullpin = NULL;

            hr = CoCreateInstance(&CLSID_NullRenderer, NULL,
                CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&pnull);
            ok(hr == S_OK, "Could not create null renderer: %08x\n", hr);
            if (hr != S_OK)
                break;

            IBaseFilter_EnumPins(pnull, &nullenum);
            IEnumPins_Next(nullenum, 1, &nullpin, NULL);
            IEnumPins_Release(nullenum);
            IPin_QueryDirection(nullpin, &dir);

            hr = IPin_Connect(avipin, nullpin, NULL);
            ok(hr == S_OK, "Failed to connect output pin: %08x\n", hr);
            IPin_Release(nullpin);
            if (hr != S_OK)
            {
                IBaseFilter_Release(pnull);
                break;
            }
            IBaseFilter_Run(pnull, 0);
            ++expected;
        }

        IPin_Release(avipin);
        avipin = NULL;
    }

    if (avipin)
        IPin_Release(avipin);
    avipin = NULL;

    if (hr != S_OK)
        goto fail2;
    /* At this point there is a minimalistic connected avi splitter that can
     * be used for all sorts of source filter tests. However that still needs
     * to be written at a later time.
     *
     * Interesting tests:
     * - Can you disconnect an output pin while running?
     *   Expecting: Yes
     * - Can you disconnect the pullpin while running?
     *   Expecting: No
     * - Is the reference count incremented during playback or when connected?
     *   Does this happen once for every output pin? Or is there something else
     *   going on.
     *   Expecting: You tell me
     */

    IBaseFilter_Run(preader, 0);
    IBaseFilter_Run(pavi, 0);
    IBaseFilter_GetState(pavi, INFINITE, &state);

    curlevel = count_threads();
    ok(curlevel == expected,
        "The thread count should be %d not %d\n", expected, curlevel);

    IBaseFilter_Pause(pavi);
    IBaseFilter_Pause(preader);
    IBaseFilter_Stop(pavi);
    IBaseFilter_Stop(preader);
    IBaseFilter_GetState(pavi, INFINITE, &state);
    IBaseFilter_GetState(preader, INFINITE, &state);

fail2:
    IEnumPins_Reset(enumpins);
    while (IEnumPins_Next(enumpins, 1, &avipin, NULL) == S_OK)
    {
        IPin *to = NULL;

        IPin_QueryDirection(avipin, &dir);
        IPin_ConnectedTo(avipin, &to);
        if (to)
        {
            IPin_Release(to);

            if (dir == PINDIR_OUTPUT)
            {
                PIN_INFO info;
                IPin_QueryPinInfo(to, &info);

                /* Release twice: Once normal, second from the
                 * previous while loop
                 */
                IBaseFilter_Stop(info.pFilter);
                IPin_Disconnect(to);
                IPin_Disconnect(avipin);
                IBaseFilter_Release(info.pFilter);
                IBaseFilter_Release(info.pFilter);
            }
            else
            {
                IPin_Disconnect(to);
                IPin_Disconnect(avipin);
            }
        }
        IPin_Release(avipin);
        avipin = NULL;
    }

fail:
    if (hr != S_OK)
        skip("Prerequisites not matched, skipping remainder of test\n");
    if (enumpins)
        IEnumPins_Release(enumpins);

    if (avipin)
        IPin_Release(avipin);
    if (filepin)
    {
        IPin *to = NULL;

        IPin_ConnectedTo(filepin, &to);
        if (to)
        {
            IPin_Disconnect(filepin);
            IPin_Disconnect(to);
        }
        IPin_Release(filepin);
    }

    if (preader)
        IBaseFilter_Release(preader);
    if (pavi)
        IBaseFilter_Release(pavi);
    if (pfile)
        IFileSourceFilter_Release(pfile);

    curlevel = count_threads();
    todo_wine
    ok(curlevel == baselevel,
        "The thread count should be %d not %d\n", baselevel, curlevel);
}
Beispiel #15
0
static void test_AviMux(void)
{
    test_filter source_filter, sink_filter;
    VIDEOINFOHEADER videoinfoheader;
    IPin *avimux_in, *avimux_out, *pin;
    AM_MEDIA_TYPE source_media_type;
    AM_MEDIA_TYPE *media_type;
    PIN_DIRECTION dir;
    IBaseFilter *avimux;
    IEnumPins *ep;
    IEnumMediaTypes *emt;
    HRESULT hr;

    init_test_filter(&source_filter, PINDIR_OUTPUT, SOURCE_FILTER);
    init_test_filter(&sink_filter, PINDIR_INPUT, SINK_FILTER);

    hr = CoCreateInstance(&CLSID_AviDest, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (void**)&avimux);
    ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG),
            "couldn't create AVI Mux filter, hr = %08x\n", hr);
    if(hr != S_OK) {
        win_skip("AVI Mux filter is not registered\n");
        return;
    }

    hr = IBaseFilter_EnumPins(avimux, &ep);
    ok(hr == S_OK, "EnumPins returned %x\n", hr);

    hr = IEnumPins_Next(ep, 1, &avimux_out, NULL);
    ok(hr == S_OK, "Next returned %x\n", hr);
    hr = IPin_QueryDirection(avimux_out, &dir);
    ok(hr == S_OK, "QueryDirection returned %x\n", hr);
    ok(dir == PINDIR_OUTPUT, "dir = %d\n", dir);

    hr = IEnumPins_Next(ep, 1, &avimux_in, NULL);
    ok(hr == S_OK, "Next returned %x\n", hr);
    hr = IPin_QueryDirection(avimux_in, &dir);
    ok(hr == S_OK, "QueryDirection returned %x\n", hr);
    ok(dir == PINDIR_INPUT, "dir = %d\n", dir);
    IEnumPins_Release(ep);

    hr = IPin_EnumMediaTypes(avimux_out, &emt);
    ok(hr == S_OK, "EnumMediaTypes returned %x\n", hr);
    hr = IEnumMediaTypes_Next(emt, 1, &media_type, NULL);
    ok(hr == S_OK, "Next returned %x\n", hr);
    ok(IsEqualIID(&media_type->majortype, &MEDIATYPE_Stream), "majortype = %s\n",
            debugstr_guid(&media_type->majortype));
    ok(IsEqualIID(&media_type->subtype, &MEDIASUBTYPE_Avi), "subtype = %s\n",
            debugstr_guid(&media_type->subtype));
    ok(media_type->bFixedSizeSamples, "bFixedSizeSamples = %x\n", media_type->bFixedSizeSamples);
    ok(!media_type->bTemporalCompression, "bTemporalCompression = %x\n", media_type->bTemporalCompression);
    ok(media_type->lSampleSize == 1, "lSampleSize = %d\n", media_type->lSampleSize);
    ok(IsEqualIID(&media_type->formattype, &GUID_NULL), "formattype = %s\n",
            debugstr_guid(&media_type->formattype));
    ok(!media_type->pUnk, "pUnk = %p\n", media_type->pUnk);
    ok(!media_type->cbFormat, "cbFormat = %d\n", media_type->cbFormat);
    ok(!media_type->pbFormat, "pbFormat = %p\n", media_type->pbFormat);
    CoTaskMemFree(media_type);
    hr = IEnumMediaTypes_Next(emt, 1, &media_type, NULL);
    ok(hr == S_FALSE, "Next returned %x\n", hr);
    IEnumMediaTypes_Release(emt);

    hr = IPin_EnumMediaTypes(avimux_in, &emt);
    ok(hr == S_OK, "EnumMediaTypes returned %x\n", hr);
    hr = IEnumMediaTypes_Reset(emt);
    ok(hr == S_OK, "Reset returned %x\n", hr);
    hr = IEnumMediaTypes_Next(emt, 1, &media_type, NULL);
    ok(hr == S_FALSE, "Next returned %x\n", hr);
    IEnumMediaTypes_Release(emt);

    hr = IPin_ReceiveConnection(avimux_in, &source_filter.IPin_iface, NULL);
    ok(hr == E_POINTER, "ReceiveConnection returned %x\n", hr);

    current_calls_list = NULL;
    memset(&source_media_type, 0, sizeof(AM_MEDIA_TYPE));
    memset(&videoinfoheader, 0, sizeof(VIDEOINFOHEADER));
    source_media_type.majortype = MEDIATYPE_Video;
    source_media_type.subtype = MEDIASUBTYPE_RGB32;
    source_media_type.formattype = FORMAT_VideoInfo;
    source_media_type.bFixedSizeSamples = TRUE;
    source_media_type.lSampleSize = 40000;
    source_media_type.cbFormat = sizeof(VIDEOINFOHEADER);
    source_media_type.pbFormat = (BYTE*)&videoinfoheader;
    videoinfoheader.AvgTimePerFrame = 333333;
    videoinfoheader.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    videoinfoheader.bmiHeader.biWidth = 100;
    videoinfoheader.bmiHeader.biHeight = 100;
    videoinfoheader.bmiHeader.biPlanes = 1;
    videoinfoheader.bmiHeader.biBitCount = 32;
    videoinfoheader.bmiHeader.biSizeImage = 40000;
    videoinfoheader.bmiHeader.biClrImportant = 256;
    hr = IPin_ReceiveConnection(avimux_in, &source_filter.IPin_iface, &source_media_type);
    ok(hr == S_OK, "ReceiveConnection returned %x\n", hr);

    hr = IPin_ConnectedTo(avimux_in, &pin);
    ok(hr == S_OK, "ConnectedTo returned %x\n", hr);
    ok(pin == &source_filter.IPin_iface, "incorrect pin: %p, expected %p\n",
            pin, &source_filter.IPin_iface);

    hr = IPin_Connect(avimux_out, &source_filter.IPin_iface, NULL);
    todo_wine ok(hr == VFW_E_INVALID_DIRECTION, "Connect returned %x\n", hr);

    hr = IBaseFilter_JoinFilterGraph(avimux, (IFilterGraph*)&GraphBuilder, NULL);
    ok(hr == S_OK, "JoinFilterGraph returned %x\n", hr);

    SET_EXPECT(ReceiveConnection);
    SET_EXPECT(GetAllocatorRequirements);
    SET_EXPECT(NotifyAllocator);
    SET_EXPECT(Reconnect);
    hr = IPin_Connect(avimux_out, &sink_filter.IPin_iface, NULL);
    ok(hr == S_OK, "Connect returned %x\n", hr);
    CHECK_CALLED(ReceiveConnection);
    CHECK_CALLED(GetAllocatorRequirements);
    CHECK_CALLED(NotifyAllocator);
    CHECK_CALLED(Reconnect);

    hr = IPin_Disconnect(avimux_out);
    ok(hr == S_OK, "Disconnect returned %x\n", hr);

    IPin_Release(avimux_in);
    IPin_Release(avimux_out);
    IBaseFilter_Release(avimux);
}