winegstreamer: Implement IWMReaderAdvanced::SetAllocateForStream().
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
894e071245
commit
cad38401bf
|
@ -125,6 +125,7 @@ struct wm_stream
|
|||
WORD index;
|
||||
bool eos;
|
||||
bool allocate_output;
|
||||
bool allocate_stream;
|
||||
/* 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
|
||||
|
@ -183,6 +184,7 @@ HRESULT wm_reader_open_file(struct wm_reader *reader, const WCHAR *filename);
|
|||
HRESULT wm_reader_open_stream(struct wm_reader *reader, IStream *stream);
|
||||
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_allocate_for_stream(struct wm_reader *reader, WORD stream_number, 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,
|
||||
|
|
|
@ -528,11 +528,14 @@ static HRESULT WINAPI WMReaderAdvanced_GetAllocateForOutput(IWMReaderAdvanced6 *
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI WMReaderAdvanced_SetAllocateForStream(IWMReaderAdvanced6 *iface, WORD output_num, BOOL allocate)
|
||||
static HRESULT WINAPI WMReaderAdvanced_SetAllocateForStream(IWMReaderAdvanced6 *iface,
|
||||
WORD stream_number, BOOL allocate)
|
||||
{
|
||||
struct async_reader *This = impl_from_IWMReaderAdvanced6(iface);
|
||||
FIXME("(%p)->(%d %x)\n", This, output_num, allocate);
|
||||
return E_NOTIMPL;
|
||||
struct async_reader *reader = impl_from_IWMReaderAdvanced6(iface);
|
||||
|
||||
TRACE("reader %p, stream_number %u, allocate %d.\n", reader, stream_number, allocate);
|
||||
|
||||
return wm_reader_set_allocate_for_stream(&reader->reader, stream_number, allocate);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI WMReaderAdvanced_GetAllocateForStream(IWMReaderAdvanced6 *iface, WORD output_num, BOOL *allocate)
|
||||
|
|
|
@ -1770,12 +1770,22 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream,
|
|||
HRESULT hr;
|
||||
BYTE *data;
|
||||
|
||||
if (callback_advanced && !stream->read_compressed && stream->allocate_output)
|
||||
if (callback_advanced && stream->read_compressed && stream->allocate_stream)
|
||||
{
|
||||
if (FAILED(hr = IWMReaderCallbackAdvanced_AllocateForStream(callback_advanced,
|
||||
stream->index + 1, event.u.buffer.size, &sample, NULL)))
|
||||
{
|
||||
ERR("Failed to allocate stream sample of %u bytes, hr %#x.\n", event.u.buffer.size, hr);
|
||||
wg_parser_stream_release_buffer(wg_stream);
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
else if (callback_advanced && !stream->read_compressed && stream->allocate_output)
|
||||
{
|
||||
if (FAILED(hr = IWMReaderCallbackAdvanced_AllocateForOutput(callback_advanced,
|
||||
stream->index, event.u.buffer.size, &sample, NULL)))
|
||||
{
|
||||
ERR("Failed to allocate sample of %u bytes, hr %#x.\n", event.u.buffer.size, hr);
|
||||
ERR("Failed to allocate output sample of %u bytes, hr %#x.\n", event.u.buffer.size, hr);
|
||||
wg_parser_stream_release_buffer(wg_stream);
|
||||
return hr;
|
||||
}
|
||||
|
@ -1948,6 +1958,24 @@ HRESULT wm_reader_set_allocate_for_output(struct wm_reader *reader, DWORD output
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT wm_reader_set_allocate_for_stream(struct wm_reader *reader, WORD stream_number, BOOL allocate)
|
||||
{
|
||||
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->allocate_stream = !!allocate;
|
||||
|
||||
LeaveCriticalSection(&reader->cs);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT wm_reader_set_read_compressed(struct wm_reader *reader, WORD stream_number, BOOL compressed)
|
||||
{
|
||||
struct wm_stream *stream;
|
||||
|
|
|
@ -356,8 +356,13 @@ static HRESULT WINAPI buffer_GetMaxLength(INSSBuffer *iface, DWORD *size)
|
|||
|
||||
static HRESULT WINAPI buffer_GetBuffer(INSSBuffer *iface, BYTE **data)
|
||||
{
|
||||
ok(0, "Unexpected call.\n");
|
||||
return E_NOTIMPL;
|
||||
struct buffer *buffer = impl_from_INSSBuffer(iface);
|
||||
|
||||
if (winetest_debug > 1)
|
||||
trace("%04x: INSSBuffer::GetBuffer()\n", GetCurrentThreadId());
|
||||
|
||||
*data = buffer->data;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI buffer_GetBufferAndLength(INSSBuffer *iface, BYTE **data, DWORD *size)
|
||||
|
@ -1618,8 +1623,32 @@ static HRESULT WINAPI callback_advanced_OnOutputPropsChanged(IWMReaderCallbackAd
|
|||
static HRESULT WINAPI callback_advanced_AllocateForStream(IWMReaderCallbackAdvanced *iface,
|
||||
WORD stream_number, DWORD size, INSSBuffer **sample, void *context)
|
||||
{
|
||||
ok(0, "Unexpected call.\n");
|
||||
return E_NOTIMPL;
|
||||
struct callback *callback = impl_from_IWMReaderCallbackAdvanced(iface);
|
||||
struct buffer *object;
|
||||
|
||||
if (winetest_debug > 1)
|
||||
trace("%u: %04x: IWMReaderCallbackAdvanced::AllocateForStream(output %u, size %u)\n",
|
||||
GetTickCount(), GetCurrentThreadId(), stream_number, size);
|
||||
|
||||
ok(callback->read_compressed, "AllocateForStream() should only be called when reading compressed samples.\n");
|
||||
ok(callback->allocated_samples, "AllocateForStream() should only be called when using a custom allocator.\n");
|
||||
|
||||
if (!(object = malloc(offsetof(struct buffer, data[size]))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
size = max(size, 65536);
|
||||
|
||||
object->INSSBuffer_iface.lpVtbl = &buffer_vtbl;
|
||||
object->refcount = 1;
|
||||
object->capacity = size;
|
||||
/* Native seems to break if we set the size to zero. */
|
||||
object->size = size;
|
||||
*sample = &object->INSSBuffer_iface;
|
||||
|
||||
InterlockedIncrement(&outstanding_buffers);
|
||||
|
||||
ok(!context, "Got unexpected context %p.\n", context);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI callback_advanced_AllocateForOutput(IWMReaderCallbackAdvanced *iface,
|
||||
|
@ -1632,7 +1661,15 @@ static HRESULT WINAPI callback_advanced_AllocateForOutput(IWMReaderCallbackAdvan
|
|||
trace("%u: %04x: IWMReaderCallbackAdvanced::AllocateForOutput(output %u, size %u)\n",
|
||||
GetTickCount(), GetCurrentThreadId(), output, size);
|
||||
|
||||
ok(callback->allocated_samples, "AllocateForOutput() should only be called when using a custom allocator.\n");
|
||||
if (!callback->read_compressed)
|
||||
{
|
||||
/* Actually AllocateForOutput() isn't called when reading compressed
|
||||
* samples either, but native seems to have some sort of race that
|
||||
* causes one call to this function to happen in
|
||||
* test_async_reader_allocate_compressed(). */
|
||||
ok(callback->allocated_samples,
|
||||
"AllocateForOutput() should only be called when using a custom allocator.\n");
|
||||
}
|
||||
|
||||
if (!(object = malloc(offsetof(struct buffer, data[size]))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
@ -1829,13 +1866,13 @@ static void test_async_reader_allocate(IWMReader *reader,
|
|||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IWMReaderAdvanced2_SetAllocateForStream(advanced, 0, TRUE);
|
||||
todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
|
||||
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
|
||||
hr = IWMReaderAdvanced2_SetAllocateForStream(advanced, 1, TRUE);
|
||||
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
hr = IWMReaderAdvanced2_SetAllocateForStream(advanced, 2, TRUE);
|
||||
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
hr = IWMReaderAdvanced2_SetAllocateForStream(advanced, 3, TRUE);
|
||||
todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
|
||||
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IWMReaderAdvanced2_GetAllocateForOutput(advanced, 0, &allocate);
|
||||
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
@ -1858,9 +1895,9 @@ static void test_async_reader_allocate(IWMReader *reader,
|
|||
run_async_reader(reader, advanced, callback);
|
||||
|
||||
hr = IWMReaderAdvanced2_SetAllocateForStream(advanced, 1, FALSE);
|
||||
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
hr = IWMReaderAdvanced2_SetAllocateForStream(advanced, 2, FALSE);
|
||||
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
}
|
||||
|
||||
static void test_async_reader_selection(IWMReader *reader,
|
||||
|
@ -1963,6 +2000,54 @@ static void test_async_reader_compressed(IWMReader *reader,
|
|||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
}
|
||||
|
||||
static void test_async_reader_allocate_compressed(IWMReader *reader,
|
||||
IWMReaderAdvanced2 *advanced, struct callback *callback)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
callback->read_compressed = true;
|
||||
|
||||
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->allocated_samples = true;
|
||||
|
||||
hr = IWMReaderAdvanced2_SetAllocateForStream(advanced, 1, TRUE);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
hr = IWMReaderAdvanced2_SetAllocateForStream(advanced, 2, TRUE);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
run_async_reader(reader, advanced, callback);
|
||||
|
||||
hr = IWMReaderAdvanced2_SetAllocateForStream(advanced, 1, FALSE);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
hr = IWMReaderAdvanced2_SetAllocateForStream(advanced, 2, FALSE);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IWMReaderAdvanced2_SetAllocateForOutput(advanced, 0, TRUE);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
hr = IWMReaderAdvanced2_SetAllocateForOutput(advanced, 1, TRUE);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
callback->allocated_samples = false;
|
||||
|
||||
run_async_reader(reader, advanced, callback);
|
||||
|
||||
hr = IWMReaderAdvanced2_SetAllocateForOutput(advanced, 0, FALSE);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
hr = IWMReaderAdvanced2_SetAllocateForOutput(advanced, 1, FALSE);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
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);
|
||||
|
||||
callback->read_compressed = false;
|
||||
}
|
||||
|
||||
static void test_async_reader_streaming(void)
|
||||
{
|
||||
const WCHAR *filename = load_resource(L"test.wmv");
|
||||
|
@ -2056,6 +2141,7 @@ static void test_async_reader_streaming(void)
|
|||
test_async_reader_selection(reader, advanced, &callback);
|
||||
test_async_reader_allocate(reader, advanced, &callback);
|
||||
test_async_reader_compressed(reader, advanced, &callback);
|
||||
test_async_reader_allocate_compressed(reader, advanced, &callback);
|
||||
|
||||
hr = IWMReader_Close(reader);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
|
Loading…
Reference in New Issue