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 wg_parser_stream *wg_stream;
|
||||
WORD index;
|
||||
bool eos;
|
||||
struct wg_format format;
|
||||
WMT_STREAM_SELECTION selection;
|
||||
WORD index;
|
||||
bool eos;
|
||||
bool allocate_output;
|
||||
};
|
||||
|
||||
struct wm_reader
|
||||
|
@ -148,6 +149,8 @@ struct wm_reader
|
|||
struct wm_stream *streams;
|
||||
WORD stream_count;
|
||||
|
||||
IWMReaderCallbackAdvanced *callback_advanced;
|
||||
|
||||
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_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_output_props(struct wm_reader *reader, DWORD output,
|
||||
IWMOutputMediaProps *props);
|
||||
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 const DWORD zero;
|
||||
HRESULT hr;
|
||||
|
||||
IWMReaderCallback_AddRef(reader->callback = callback);
|
||||
reader->context = 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)
|
||||
|
@ -497,11 +503,14 @@ static HRESULT WINAPI WMReaderAdvanced_GetReceiveStreamSamples(IWMReaderAdvanced
|
|||
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);
|
||||
FIXME("(%p)->(%d %x)\n", This, output_num, allocate);
|
||||
return E_NOTIMPL;
|
||||
struct async_reader *reader = impl_from_IWMReaderAdvanced6(iface);
|
||||
|
||||
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)
|
||||
|
|
|
@ -1532,6 +1532,10 @@ HRESULT wm_reader_close(struct wm_reader *reader)
|
|||
CloseHandle(reader->read_thread);
|
||||
reader->read_thread = NULL;
|
||||
|
||||
if (reader->callback_advanced)
|
||||
IWMReaderCallbackAdvanced_Release(reader->callback_advanced);
|
||||
reader->callback_advanced = NULL;
|
||||
|
||||
wg_parser_destroy(reader->wg_parser);
|
||||
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,
|
||||
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_event event;
|
||||
struct buffer *object;
|
||||
|
||||
if (stream->selection == WMT_OFF)
|
||||
return NS_E_INVALID_REQUEST;
|
||||
|
@ -1746,6 +1750,9 @@ 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))
|
||||
|
@ -1760,24 +1767,59 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream,
|
|||
switch (event.type)
|
||||
{
|
||||
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);
|
||||
return E_OUTOFMEMORY;
|
||||
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);
|
||||
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;
|
||||
object->refcount = 1;
|
||||
object->capacity = object->size = event.u.buffer.size;
|
||||
if (FAILED(hr = INSSBuffer_GetBufferAndLength(sample, &data, &size)))
|
||||
ERR("Failed to get data pointer, hr %#x.\n", hr);
|
||||
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. */
|
||||
free(object);
|
||||
INSSBuffer_Release(sample);
|
||||
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);
|
||||
|
||||
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)
|
||||
*flags |= WM_SF_CLEANPOINT;
|
||||
|
||||
TRACE("Created buffer %p.\n", object);
|
||||
*ret_sample = &object->INSSBuffer_iface;
|
||||
*ret_sample = sample;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
case WG_PARSER_EVENT_EOS:
|
||||
stream->eos = true;
|
||||
|
@ -1891,6 +1933,24 @@ HRESULT wm_reader_get_stream_selection(struct wm_reader *reader,
|
|||
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)
|
||||
{
|
||||
reader->IWMHeaderInfo3_iface.lpVtbl = &header_info_vtbl;
|
||||
|
|
Loading…
Reference in New Issue