winegstreamer: Implement IWMReaderAdvanced::SetAllocateForOutput().
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
97d6cfd705
commit
2f7e7d284b
|
@ -120,10 +120,11 @@ struct wm_stream
|
||||||
{
|
{
|
||||||
struct wm_reader *reader;
|
struct wm_reader *reader;
|
||||||
struct wg_parser_stream *wg_stream;
|
struct wg_parser_stream *wg_stream;
|
||||||
WORD index;
|
|
||||||
bool eos;
|
|
||||||
struct wg_format format;
|
struct wg_format format;
|
||||||
WMT_STREAM_SELECTION selection;
|
WMT_STREAM_SELECTION selection;
|
||||||
|
WORD index;
|
||||||
|
bool eos;
|
||||||
|
bool allocate_output;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wm_reader
|
struct wm_reader
|
||||||
|
@ -148,6 +149,8 @@ struct wm_reader
|
||||||
struct wm_stream *streams;
|
struct wm_stream *streams;
|
||||||
WORD stream_count;
|
WORD stream_count;
|
||||||
|
|
||||||
|
IWMReaderCallbackAdvanced *callback_advanced;
|
||||||
|
|
||||||
const struct wm_reader_ops *ops;
|
const struct wm_reader_ops *ops;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -174,6 +177,7 @@ void wm_reader_init(struct wm_reader *reader, const struct wm_reader_ops *ops);
|
||||||
HRESULT wm_reader_open_file(struct wm_reader *reader, const WCHAR *filename);
|
HRESULT wm_reader_open_file(struct wm_reader *reader, const WCHAR *filename);
|
||||||
HRESULT wm_reader_open_stream(struct wm_reader *reader, IStream *stream);
|
HRESULT wm_reader_open_stream(struct wm_reader *reader, IStream *stream);
|
||||||
void wm_reader_seek(struct wm_reader *reader, QWORD start, LONGLONG duration);
|
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,
|
HRESULT wm_reader_set_output_props(struct wm_reader *reader, DWORD output,
|
||||||
IWMOutputMediaProps *props);
|
IWMOutputMediaProps *props);
|
||||||
HRESULT wm_reader_set_streams_selected(struct wm_reader *reader, WORD count,
|
HRESULT wm_reader_set_streams_selected(struct wm_reader *reader, WORD count,
|
||||||
|
|
|
@ -57,10 +57,16 @@ static REFERENCE_TIME get_current_time(const struct async_reader *reader)
|
||||||
static void open_stream(struct async_reader *reader, IWMReaderCallback *callback, void *context)
|
static void open_stream(struct async_reader *reader, IWMReaderCallback *callback, void *context)
|
||||||
{
|
{
|
||||||
static const DWORD zero;
|
static const DWORD zero;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
IWMReaderCallback_AddRef(reader->callback = callback);
|
IWMReaderCallback_AddRef(reader->callback = callback);
|
||||||
reader->context = context;
|
reader->context = context;
|
||||||
IWMReaderCallback_OnStatus(callback, WMT_OPENED, S_OK, WMT_TYPE_DWORD, (BYTE *)&zero, context);
|
IWMReaderCallback_OnStatus(callback, WMT_OPENED, S_OK, WMT_TYPE_DWORD, (BYTE *)&zero, context);
|
||||||
|
|
||||||
|
if (FAILED(hr = IWMReaderCallback_QueryInterface(callback,
|
||||||
|
&IID_IWMReaderCallbackAdvanced, (void **)&reader->reader.callback_advanced)))
|
||||||
|
reader->reader.callback_advanced = NULL;
|
||||||
|
TRACE("Querying for IWMReaderCallbackAdvanced returned %#x.\n", hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD WINAPI stream_thread(void *arg)
|
static DWORD WINAPI stream_thread(void *arg)
|
||||||
|
@ -497,11 +503,14 @@ static HRESULT WINAPI WMReaderAdvanced_GetReceiveStreamSamples(IWMReaderAdvanced
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI WMReaderAdvanced_SetAllocateForOutput(IWMReaderAdvanced6 *iface, DWORD output_num, BOOL allocate)
|
static HRESULT WINAPI WMReaderAdvanced_SetAllocateForOutput(IWMReaderAdvanced6 *iface,
|
||||||
|
DWORD output, BOOL allocate)
|
||||||
{
|
{
|
||||||
struct async_reader *This = impl_from_IWMReaderAdvanced6(iface);
|
struct async_reader *reader = impl_from_IWMReaderAdvanced6(iface);
|
||||||
FIXME("(%p)->(%d %x)\n", This, output_num, allocate);
|
|
||||||
return E_NOTIMPL;
|
TRACE("reader %p, output %u, allocate %d.\n", reader, output, allocate);
|
||||||
|
|
||||||
|
return wm_reader_set_allocate_for_output(&reader->reader, output, allocate);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI WMReaderAdvanced_GetAllocateForOutput(IWMReaderAdvanced6 *iface, DWORD output_num, BOOL *allocate)
|
static HRESULT WINAPI WMReaderAdvanced_GetAllocateForOutput(IWMReaderAdvanced6 *iface, DWORD output_num, BOOL *allocate)
|
||||||
|
|
|
@ -1532,6 +1532,10 @@ HRESULT wm_reader_close(struct wm_reader *reader)
|
||||||
CloseHandle(reader->read_thread);
|
CloseHandle(reader->read_thread);
|
||||||
reader->read_thread = NULL;
|
reader->read_thread = NULL;
|
||||||
|
|
||||||
|
if (reader->callback_advanced)
|
||||||
|
IWMReaderCallbackAdvanced_Release(reader->callback_advanced);
|
||||||
|
reader->callback_advanced = NULL;
|
||||||
|
|
||||||
wg_parser_destroy(reader->wg_parser);
|
wg_parser_destroy(reader->wg_parser);
|
||||||
reader->wg_parser = NULL;
|
reader->wg_parser = NULL;
|
||||||
|
|
||||||
|
@ -1736,9 +1740,9 @@ static const char *get_major_type_string(enum wg_major_type type)
|
||||||
HRESULT wm_reader_get_stream_sample(struct wm_stream *stream,
|
HRESULT wm_reader_get_stream_sample(struct wm_stream *stream,
|
||||||
INSSBuffer **ret_sample, QWORD *pts, QWORD *duration, DWORD *flags)
|
INSSBuffer **ret_sample, QWORD *pts, QWORD *duration, DWORD *flags)
|
||||||
{
|
{
|
||||||
|
IWMReaderCallbackAdvanced *callback_advanced = stream->reader->callback_advanced;
|
||||||
struct wg_parser_stream *wg_stream = stream->wg_stream;
|
struct wg_parser_stream *wg_stream = stream->wg_stream;
|
||||||
struct wg_parser_event event;
|
struct wg_parser_event event;
|
||||||
struct buffer *object;
|
|
||||||
|
|
||||||
if (stream->selection == WMT_OFF)
|
if (stream->selection == WMT_OFF)
|
||||||
return NS_E_INVALID_REQUEST;
|
return NS_E_INVALID_REQUEST;
|
||||||
|
@ -1746,6 +1750,9 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream,
|
||||||
if (stream->eos)
|
if (stream->eos)
|
||||||
return NS_E_NO_MORE_SAMPLES;
|
return NS_E_NO_MORE_SAMPLES;
|
||||||
|
|
||||||
|
if (!stream->allocate_output)
|
||||||
|
callback_advanced = NULL;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (!wg_parser_stream_get_event(wg_stream, &event))
|
if (!wg_parser_stream_get_event(wg_stream, &event))
|
||||||
|
@ -1760,24 +1767,59 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream,
|
||||||
switch (event.type)
|
switch (event.type)
|
||||||
{
|
{
|
||||||
case WG_PARSER_EVENT_BUFFER:
|
case WG_PARSER_EVENT_BUFFER:
|
||||||
/* FIXME: Should these be pooled? */
|
{
|
||||||
if (!(object = calloc(1, offsetof(struct buffer, data[event.u.buffer.size]))))
|
DWORD size, capacity;
|
||||||
|
INSSBuffer *sample;
|
||||||
|
HRESULT hr;
|
||||||
|
BYTE *data;
|
||||||
|
|
||||||
|
if (callback_advanced)
|
||||||
{
|
{
|
||||||
wg_parser_stream_release_buffer(wg_stream);
|
if (FAILED(hr = IWMReaderCallbackAdvanced_AllocateForOutput(callback_advanced,
|
||||||
return E_OUTOFMEMORY;
|
stream->index, event.u.buffer.size, &sample, NULL)))
|
||||||
|
{
|
||||||
|
ERR("Failed to allocate sample of %u bytes, hr %#x.\n", event.u.buffer.size, hr);
|
||||||
|
wg_parser_stream_release_buffer(wg_stream);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct buffer *object;
|
||||||
|
|
||||||
|
/* FIXME: Should these be pooled? */
|
||||||
|
if (!(object = calloc(1, offsetof(struct buffer, data[event.u.buffer.size]))))
|
||||||
|
{
|
||||||
|
wg_parser_stream_release_buffer(wg_stream);
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
object->INSSBuffer_iface.lpVtbl = &buffer_vtbl;
|
||||||
|
object->refcount = 1;
|
||||||
|
object->capacity = event.u.buffer.size;
|
||||||
|
|
||||||
|
TRACE("Created buffer %p.\n", object);
|
||||||
|
sample = &object->INSSBuffer_iface;
|
||||||
}
|
}
|
||||||
|
|
||||||
object->INSSBuffer_iface.lpVtbl = &buffer_vtbl;
|
if (FAILED(hr = INSSBuffer_GetBufferAndLength(sample, &data, &size)))
|
||||||
object->refcount = 1;
|
ERR("Failed to get data pointer, hr %#x.\n", hr);
|
||||||
object->capacity = object->size = event.u.buffer.size;
|
if (FAILED(hr = INSSBuffer_GetMaxLength(sample, &capacity)))
|
||||||
|
ERR("Failed to get capacity, hr %#x.\n", hr);
|
||||||
|
if (event.u.buffer.size > capacity)
|
||||||
|
ERR("Returned capacity %u is less than requested capacity %u.\n",
|
||||||
|
capacity, event.u.buffer.size);
|
||||||
|
|
||||||
if (!wg_parser_stream_copy_buffer(wg_stream, object->data, 0, object->size))
|
if (!wg_parser_stream_copy_buffer(wg_stream, data, 0, event.u.buffer.size))
|
||||||
{
|
{
|
||||||
/* The GStreamer pin has been flushed. */
|
/* The GStreamer pin has been flushed. */
|
||||||
free(object);
|
INSSBuffer_Release(sample);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr = INSSBuffer_SetLength(sample, event.u.buffer.size)))
|
||||||
|
ERR("Failed to set size %u, hr %#x.\n", event.u.buffer.size, hr);
|
||||||
|
|
||||||
wg_parser_stream_release_buffer(wg_stream);
|
wg_parser_stream_release_buffer(wg_stream);
|
||||||
|
|
||||||
if (!event.u.buffer.has_pts)
|
if (!event.u.buffer.has_pts)
|
||||||
|
@ -1793,9 +1835,9 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream,
|
||||||
if (!event.u.buffer.delta)
|
if (!event.u.buffer.delta)
|
||||||
*flags |= WM_SF_CLEANPOINT;
|
*flags |= WM_SF_CLEANPOINT;
|
||||||
|
|
||||||
TRACE("Created buffer %p.\n", object);
|
*ret_sample = sample;
|
||||||
*ret_sample = &object->INSSBuffer_iface;
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
case WG_PARSER_EVENT_EOS:
|
case WG_PARSER_EVENT_EOS:
|
||||||
stream->eos = true;
|
stream->eos = true;
|
||||||
|
@ -1891,6 +1933,24 @@ HRESULT wm_reader_get_stream_selection(struct wm_reader *reader,
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT wm_reader_set_allocate_for_output(struct wm_reader *reader, DWORD output, BOOL allocate)
|
||||||
|
{
|
||||||
|
struct wm_stream *stream;
|
||||||
|
|
||||||
|
EnterCriticalSection(&reader->cs);
|
||||||
|
|
||||||
|
if (!(stream = get_stream_by_output_number(reader, output)))
|
||||||
|
{
|
||||||
|
LeaveCriticalSection(&reader->cs);
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream->allocate_output = !!allocate;
|
||||||
|
|
||||||
|
LeaveCriticalSection(&reader->cs);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
void wm_reader_init(struct wm_reader *reader, const struct wm_reader_ops *ops)
|
void wm_reader_init(struct wm_reader *reader, const struct wm_reader_ops *ops)
|
||||||
{
|
{
|
||||||
reader->IWMHeaderInfo3_iface.lpVtbl = &header_info_vtbl;
|
reader->IWMHeaderInfo3_iface.lpVtbl = &header_info_vtbl;
|
||||||
|
|
Loading…
Reference in New Issue