Commit 894e0712 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

winegstreamer: Implement IWMReaderAdvanced::SetReceiveStreamSamples().

parent 42da77bb
......@@ -125,6 +125,11 @@ struct wm_stream
WORD index;
bool eos;
bool allocate_output;
/* Note that we only pretend to read compressed samples, and instead output
* uncompressed samples regardless of whether we are configured to read
* compressed samples. Rather, the behaviour of the reader objects differs
* in nontrivial ways depending on this field. */
bool read_compressed;
};
struct wm_reader
......@@ -180,6 +185,8 @@ void wm_reader_seek(struct wm_reader *reader, QWORD start, LONGLONG duration);
HRESULT wm_reader_set_allocate_for_output(struct wm_reader *reader, DWORD output, BOOL allocate);
HRESULT wm_reader_set_output_props(struct wm_reader *reader, DWORD output,
IWMOutputMediaProps *props);
HRESULT wm_reader_set_read_compressed(struct wm_reader *reader,
WORD stream_number, BOOL compressed);
HRESULT wm_reader_set_streams_selected(struct wm_reader *reader, WORD count,
const WORD *stream_numbers, const WMT_STREAM_SELECTION *selections);
......
......@@ -129,7 +129,13 @@ static DWORD WINAPI stream_thread(void *arg)
}
}
IWMReaderCallback_OnSample(callback, i, pts, duration, flags, sample, reader->context);
if (stream->read_compressed)
hr = IWMReaderCallbackAdvanced_OnStreamSample(reader->reader.callback_advanced,
i + 1, pts, duration, flags, sample, reader->context);
else
hr = IWMReaderCallback_OnSample(callback, i, pts, duration,
flags, sample, reader->context);
TRACE("Callback returned %#x.\n", hr);
INSSBuffer_Release(sample);
all_eos = false;
}
......@@ -487,12 +493,14 @@ static HRESULT WINAPI WMReaderAdvanced_GetReceiveSelectionCallbacks(IWMReaderAdv
return E_NOTIMPL;
}
static HRESULT WINAPI WMReaderAdvanced_SetReceiveStreamSamples(IWMReaderAdvanced6 *iface, WORD stream_num,
BOOL receive_stream_samples)
static HRESULT WINAPI WMReaderAdvanced_SetReceiveStreamSamples(IWMReaderAdvanced6 *iface,
WORD stream_number, BOOL compressed)
{
struct async_reader *This = impl_from_IWMReaderAdvanced6(iface);
FIXME("(%p)->(%d %x)\n", This, stream_num, receive_stream_samples);
return E_NOTIMPL;
struct async_reader *reader = impl_from_IWMReaderAdvanced6(iface);
TRACE("reader %p, stream_number %u, compressed %d.\n", reader, stream_number, compressed);
return wm_reader_set_read_compressed(&reader->reader, stream_number, compressed);
}
static HRESULT WINAPI WMReaderAdvanced_GetReceiveStreamSamples(IWMReaderAdvanced6 *iface, WORD stream_num,
......
......@@ -1750,9 +1750,6 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream,
if (stream->eos)
return NS_E_NO_MORE_SAMPLES;
if (!stream->allocate_output)
callback_advanced = NULL;
for (;;)
{
if (!wg_parser_stream_get_event(wg_stream, &event))
......@@ -1773,7 +1770,7 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream,
HRESULT hr;
BYTE *data;
if (callback_advanced)
if (callback_advanced && !stream->read_compressed && stream->allocate_output)
{
if (FAILED(hr = IWMReaderCallbackAdvanced_AllocateForOutput(callback_advanced,
stream->index, event.u.buffer.size, &sample, NULL)))
......@@ -1951,6 +1948,24 @@ HRESULT wm_reader_set_allocate_for_output(struct wm_reader *reader, DWORD output
return S_OK;
}
HRESULT wm_reader_set_read_compressed(struct wm_reader *reader, WORD stream_number, BOOL compressed)
{
struct wm_stream *stream;
EnterCriticalSection(&reader->cs);
if (!(stream = wm_reader_get_stream_by_stream_number(reader, stream_number)))
{
LeaveCriticalSection(&reader->cs);
return E_INVALIDARG;
}
stream->read_compressed = compressed;
LeaveCriticalSection(&reader->cs);
return S_OK;
}
void wm_reader_init(struct wm_reader *reader, const struct wm_reader_ops *ops)
{
reader->IWMHeaderInfo3_iface.lpVtbl = &header_info_vtbl;
......
......@@ -1348,6 +1348,7 @@ struct callback
unsigned int got_closed, got_started, got_sample, got_end_of_streaming, got_eof;
bool all_streams_off;
bool allocated_samples;
bool read_compressed;
};
static struct callback *impl_from_IWMReaderCallback(IWMReaderCallback *iface)
......@@ -1474,20 +1475,12 @@ static HRESULT WINAPI callback_OnStatus(IWMReaderCallback *iface, WMT_STATUS sta
return S_OK;
}
static HRESULT WINAPI callback_OnSample(IWMReaderCallback *iface, DWORD output,
QWORD time, QWORD duration, DWORD flags, INSSBuffer *sample, void *context)
static void check_async_sample(struct callback *callback, INSSBuffer *sample)
{
struct callback *callback = impl_from_IWMReaderCallback(iface);
DWORD size, capacity;
BYTE *data, *data2;
HRESULT hr;
if (winetest_debug > 1)
trace("%u: %04x: IWMReaderCallback::OnSample(output %u, time %I64u, duration %I64u, flags %#x)\n",
GetTickCount(), GetCurrentThreadId(), output, time, duration, flags);
ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context);
if (callback->allocated_samples)
{
struct buffer *buffer = impl_from_INSSBuffer(sample);
......@@ -1521,7 +1514,22 @@ static HRESULT WINAPI callback_OnSample(IWMReaderCallback *iface, DWORD output,
ok(data2 == data, "Data pointers didn't match.\n");
ok(size == capacity - 1, "Expected size %u, got %u.\n", capacity - 1, size);
}
}
static HRESULT WINAPI callback_OnSample(IWMReaderCallback *iface, DWORD output,
QWORD time, QWORD duration, DWORD flags, INSSBuffer *sample, void *context)
{
struct callback *callback = impl_from_IWMReaderCallback(iface);
if (winetest_debug > 1)
trace("%u: %04x: IWMReaderCallback::OnSample(output %u, time %I64u, duration %I64u, flags %#x)\n",
GetTickCount(), GetCurrentThreadId(), output, time, duration, flags);
ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context);
check_async_sample(callback, sample);
ok(!callback->read_compressed, "OnSample() should not be called when reading compressed samples.\n");
ok(callback->got_started > 0, "Got %u WMT_STARTED callbacks.\n", callback->got_started);
ok(!callback->got_eof, "Got %u WMT_EOF callbacks.\n", callback->got_eof);
++callback->got_sample;
......@@ -1564,8 +1572,22 @@ static ULONG WINAPI callback_advanced_Release(IWMReaderCallbackAdvanced *iface)
static HRESULT WINAPI callback_advanced_OnStreamSample(IWMReaderCallbackAdvanced *iface,
WORD stream_number, QWORD pts, QWORD duration, DWORD flags, INSSBuffer *sample, void *context)
{
ok(0, "Unexpected call.\n");
return E_NOTIMPL;
struct callback *callback = impl_from_IWMReaderCallbackAdvanced(iface);
if (winetest_debug > 1)
trace("%u: %04x: IWMReaderCallbackAdvanced::OnStreamSample(stream %u, pts %I64u, duration %I64u, flags %#x)\n",
GetTickCount(), GetCurrentThreadId(), stream_number, pts, duration, flags);
ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context);
check_async_sample(callback, sample);
ok(callback->read_compressed, "OnStreamSample() should not be called unless reading compressed samples.\n");
ok(callback->got_started > 0, "Got %u WMT_STARTED callbacks.\n", callback->got_started);
ok(!callback->got_eof, "Got %u WMT_EOF callbacks.\n", callback->got_eof);
++callback->got_sample;
return S_OK;
}
static HRESULT WINAPI callback_advanced_OnTime(IWMReaderCallbackAdvanced *iface, QWORD time, void *context)
......@@ -1915,6 +1937,32 @@ static void test_async_reader_selection(IWMReader *reader,
ok(hr == S_OK, "Got hr %#x.\n", hr);
}
static void test_async_reader_compressed(IWMReader *reader,
IWMReaderAdvanced2 *advanced, struct callback *callback)
{
HRESULT hr;
hr = IWMReaderAdvanced2_SetReceiveStreamSamples(advanced, 0, TRUE);
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
hr = IWMReaderAdvanced2_SetReceiveStreamSamples(advanced, 3, TRUE);
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
hr = IWMReaderAdvanced2_SetReceiveStreamSamples(advanced, 1, TRUE);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IWMReaderAdvanced2_SetReceiveStreamSamples(advanced, 2, TRUE);
ok(hr == S_OK, "Got hr %#x.\n", hr);
callback->read_compressed = true;
run_async_reader(reader, advanced, callback);
callback->read_compressed = false;
hr = IWMReaderAdvanced2_SetReceiveStreamSamples(advanced, 1, FALSE);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IWMReaderAdvanced2_SetReceiveStreamSamples(advanced, 2, FALSE);
ok(hr == S_OK, "Got hr %#x.\n", hr);
}
static void test_async_reader_streaming(void)
{
const WCHAR *filename = load_resource(L"test.wmv");
......@@ -2007,6 +2055,7 @@ static void test_async_reader_streaming(void)
test_reader_attributes(profile);
test_async_reader_selection(reader, advanced, &callback);
test_async_reader_allocate(reader, advanced, &callback);
test_async_reader_compressed(reader, advanced, &callback);
hr = IWMReader_Close(reader);
ok(hr == S_OK, "Got hr %#x.\n", hr);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment