ReactOS 0.4.17-dev-923-g4c9a150
filewriter.c
Go to the documentation of this file.
1/*
2 * File writer filter
3 *
4 * Copyright (C) 2020 Zebediah Figura
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include "qcap_private.h"
22
24
26{
30
32
35
37};
38
39static inline struct file_writer *impl_from_strmbase_pin(struct strmbase_pin *iface)
40{
41 return CONTAINING_RECORD(iface, struct file_writer, sink.pin);
42}
43
45{
47
48 if (IsEqualGUID(iid, &IID_IMemInputPin))
49 *out = &filter->sink.IMemInputPin_iface;
50 else
51 return E_NOINTERFACE;
52
53 IUnknown_AddRef((IUnknown *)*out);
54 return S_OK;
55}
56
58{
60
61 if (filter->filename && !IsEqualGUID(&mt->majortype, &MEDIATYPE_Stream))
62 return S_FALSE;
63 return S_OK;
64}
65
67{
72 HRESULT hr;
73 BYTE *data;
74
75 if ((hr = IMediaSample_GetTime(sample, &start, &stop)) != S_OK)
76 ERR("Failed to get sample time, hr %#lx.\n", hr);
77 size = stop - start;
78
79 if ((hr = IMediaSample_GetPointer(sample, &data)) != S_OK)
80 ERR("Failed to get sample pointer, hr %#lx.\n", hr);
81
82 offset.QuadPart = start;
84 || !WriteFile(filter->file, data, size, &ret_size, NULL))
85 {
86 ERR("Failed to write file, error %lu.\n", GetLastError());
87 return HRESULT_FROM_WIN32(hr);
88 }
89
90 if (ret_size != size)
91 ERR("Short write, %lu/%lu.\n", ret_size, size);
92
93 return S_OK;
94}
95
97{
98 IMediaEventSink *event_sink;
99
100 if (SUCCEEDED(IFilterGraph_QueryInterface(filter->filter.graph,
101 &IID_IMediaEventSink, (void **)&event_sink)))
102 {
103 IMediaEventSink_Notify(event_sink, EC_COMPLETE, S_OK,
104 (LONG_PTR)&filter->filter.IBaseFilter_iface);
105 IMediaEventSink_Release(event_sink);
106 }
107}
108
110{
111 struct file_writer *filter = impl_from_strmbase_pin(&iface->pin);
112
114
115 if (filter->filter.state == State_Running)
117 else
118 filter->eos = TRUE;
119
121 return S_OK;
122}
123
124static const struct strmbase_sink_ops sink_ops =
125{
126 .base.pin_query_interface = file_writer_sink_query_interface,
127 .base.pin_query_accept = file_writer_sink_query_accept,
128 .pfnReceive = file_writer_sink_receive,
129 .sink_eos = file_writer_sink_eos,
130};
131
132static inline struct file_writer *impl_from_strmbase_filter(struct strmbase_filter *iface)
133{
134 return CONTAINING_RECORD(iface, struct file_writer, filter);
135}
136
138{
140
141 if (IsEqualGUID(iid, &IID_IAMFilterMiscFlags))
142 *out = &filter->IAMFilterMiscFlags_iface;
143 else if (IsEqualGUID(iid, &IID_IFileSinkFilter))
144 *out = &filter->IFileSinkFilter_iface;
145 else
146 return E_NOINTERFACE;
147
148 IUnknown_AddRef((IUnknown *)*out);
149 return S_OK;
150}
151
152static struct strmbase_pin *file_writer_get_pin(struct strmbase_filter *iface, unsigned int index)
153{
155
156 if (!index)
157 return &filter->sink.pin;
158 return NULL;
159}
160
161static void file_writer_destroy(struct strmbase_filter *iface)
162{
164
165 free(filter->filename);
168 free(filter);
169}
170
172{
174 HANDLE file;
175
178 {
179 ERR("Failed to create %s, error %lu.\n", debugstr_w(filter->filename), GetLastError());
181 }
182 filter->file = file;
183 return S_OK;
184}
185
187{
189
190 if (filter->eos)
192 filter->eos = FALSE;
193 return S_OK;
194}
195
197{
199
200 CloseHandle(filter->file);
201 return S_OK;
202}
203
205{
206 .filter_query_interface = file_writer_query_interface,
207 .filter_get_pin = file_writer_get_pin,
208 .filter_destroy = file_writer_destroy,
209 .filter_init_stream = file_writer_init_stream,
210 .filter_start_stream = file_writer_start_stream,
211 .filter_cleanup_stream = file_writer_cleanup_stream,
212};
213
215{
217}
218
220{
222 return IUnknown_QueryInterface(filter->filter.outer_unk, iid, out);
223}
224
226{
228 return IUnknown_AddRef(filter->filter.outer_unk);
229}
230
232{
234 return IUnknown_Release(filter->filter.outer_unk);
235}
236
238 LPCOLESTR filename, const AM_MEDIA_TYPE *mt)
239{
241 WCHAR *new_filename;
242
243 TRACE("filter %p, filename %s, mt %p.\n", filter, debugstr_w(filename), mt);
245
246 if (mt)
247 FIXME("Ignoring media type %p.\n", mt);
248
249 if (!(new_filename = wcsdup(filename)))
250 return E_OUTOFMEMORY;
251
252 free(filter->filename);
253 filter->filename = new_filename;
254 return S_OK;
255}
256
258 LPOLESTR *filename, AM_MEDIA_TYPE *mt)
259{
261
262 FIXME("filter %p, filename %p, mt %p, stub!\n", filter, filename, mt);
263
264 return E_NOTIMPL;
265}
266
267static const IFileSinkFilterVtbl filesinkfilter_vtbl =
268{
274};
275
277{
279}
280
282{
284 return IUnknown_QueryInterface(filter->filter.outer_unk, iid, out);
285}
286
288{
290 return IUnknown_AddRef(filter->filter.outer_unk);
291}
292
294{
296 return IUnknown_Release(filter->filter.outer_unk);
297}
298
300{
302
303 TRACE("filter %p.\n", filter);
304
306}
307
308static const IAMFilterMiscFlagsVtbl misc_flags_vtbl =
309{
314};
315
317{
318 struct file_writer *object;
319
320 if (!(object = calloc(1, sizeof(*object))))
321 return E_OUTOFMEMORY;
322
323 strmbase_filter_init(&object->filter, outer, &CLSID_FileWriter, &filter_ops);
324 object->IFileSinkFilter_iface.lpVtbl = &filesinkfilter_vtbl;
325 object->IAMFilterMiscFlags_iface.lpVtbl = &misc_flags_vtbl;
326
327 strmbase_sink_init(&object->sink, &object->filter, L"in", &sink_ops, NULL);
328
329 TRACE("Created file writer %p.\n", object);
330 *out = &object->filter.IUnknown_inner;
331 return S_OK;
332}
@ AM_FILTER_MISC_FLAGS_IS_RENDERER
Definition: axextend.idl:1244
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: precomp.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_NOTIMPL
Definition: ddrawi.h:99
#define free
Definition: debug_ros.c:5
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define FILE_BEGIN
Definition: compat.h:761
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CreateFileW
Definition: compat.h:741
#define FILE_SHARE_READ
Definition: compat.h:136
BOOL WINAPI SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod)
Definition: fileinfo.c:177
BOOL WINAPI WriteFile(_In_ HANDLE hFile, _In_reads_bytes_opt_(nNumberOfBytesToWrite) LPCVOID lpBuffer, _In_ DWORD nNumberOfBytesToWrite, _Out_opt_ LPDWORD lpNumberOfBytesWritten, _Inout_opt_ LPOVERLAPPED lpOverlapped)
Definition: rw.c:25
static wchar_t * wcsdup(const wchar_t *str)
Definition: string.h:94
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
#define L(x)
Definition: resources.c:13
#define EC_COMPLETE
Definition: evcode.h:17
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
static HRESULT file_writer_sink_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
Definition: filewriter.c:44
static HRESULT WINAPI filesinkfilter_GetCurFile(IFileSinkFilter *iface, LPOLESTR *filename, AM_MEDIA_TYPE *mt)
Definition: filewriter.c:257
static const IFileSinkFilterVtbl filesinkfilter_vtbl
Definition: filewriter.c:267
static struct strmbase_pin * file_writer_get_pin(struct strmbase_filter *iface, unsigned int index)
Definition: filewriter.c:152
static HRESULT WINAPI file_writer_sink_receive(struct strmbase_sink *iface, IMediaSample *sample)
Definition: filewriter.c:66
static ULONG WINAPI misc_flags_Release(IAMFilterMiscFlags *iface)
Definition: filewriter.c:293
static HRESULT file_writer_init_stream(struct strmbase_filter *iface)
Definition: filewriter.c:171
static ULONG WINAPI misc_flags_AddRef(IAMFilterMiscFlags *iface)
Definition: filewriter.c:287
static const IAMFilterMiscFlagsVtbl misc_flags_vtbl
Definition: filewriter.c:308
static HRESULT file_writer_start_stream(struct strmbase_filter *iface, REFERENCE_TIME start)
Definition: filewriter.c:186
static HRESULT file_writer_query_interface(struct strmbase_filter *iface, REFIID iid, void **out)
Definition: filewriter.c:137
HRESULT file_writer_create(IUnknown *outer, IUnknown **out)
Definition: filewriter.c:316
static HRESULT file_writer_cleanup_stream(struct strmbase_filter *iface)
Definition: filewriter.c:196
static struct file_writer * impl_from_IAMFilterMiscFlags(IAMFilterMiscFlags *iface)
Definition: filewriter.c:276
static HRESULT file_writer_sink_eos(struct strmbase_sink *iface)
Definition: filewriter.c:109
static ULONG WINAPI filesinkfilter_Release(IFileSinkFilter *iface)
Definition: filewriter.c:231
static const struct strmbase_sink_ops sink_ops
Definition: filewriter.c:124
static void file_writer_destroy(struct strmbase_filter *iface)
Definition: filewriter.c:161
static HRESULT WINAPI filesinkfilter_SetFileName(IFileSinkFilter *iface, LPCOLESTR filename, const AM_MEDIA_TYPE *mt)
Definition: filewriter.c:237
static struct strmbase_filter_ops filter_ops
Definition: filewriter.c:204
static ULONG WINAPI filesinkfilter_AddRef(IFileSinkFilter *iface)
Definition: filewriter.c:225
static ULONG WINAPI misc_flags_GetMiscFlags(IAMFilterMiscFlags *iface)
Definition: filewriter.c:299
static struct file_writer * impl_from_strmbase_pin(struct strmbase_pin *iface)
Definition: filewriter.c:39
static struct file_writer * impl_from_IFileSinkFilter(IFileSinkFilter *iface)
Definition: filewriter.c:214
static void deliver_ec_complete(struct file_writer *filter)
Definition: filewriter.c:96
static HRESULT WINAPI misc_flags_QueryInterface(IAMFilterMiscFlags *iface, REFIID iid, void **out)
Definition: filewriter.c:281
static HRESULT file_writer_sink_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt)
Definition: filewriter.c:57
static HRESULT WINAPI filesinkfilter_QueryInterface(IFileSinkFilter *iface, REFIID iid, void **out)
Definition: filewriter.c:219
static struct file_writer * impl_from_strmbase_filter(struct strmbase_filter *iface)
Definition: filewriter.c:132
GLuint start
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
GLuint index
Definition: glext.h:6031
GLsizei GLenum GLboolean sink
Definition: glext.h:5672
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
const char * filename
Definition: ioapi.h:137
#define debugstr_w
Definition: kernel32.h:32
#define CREATE_ALWAYS
Definition: disk.h:72
static void ULONG ULONG * ret_size
Definition: time.c:40
static IUnknown * outer
Definition: compobj.c:82
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define GENERIC_WRITE
Definition: nt_native.h:90
short WCHAR
Definition: pedump.c:58
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define calloc
Definition: rosglue.h:14
#define TRACE(s)
Definition: solgame.cpp:4
void strmbase_dump_media_type(const AM_MEDIA_TYPE *mt)
Definition: mediatype.c:58
void strmbase_sink_cleanup(struct strmbase_sink *pin)
Definition: pin.c:1185
void strmbase_sink_init(struct strmbase_sink *pin, struct strmbase_filter *filter, const WCHAR *name, const struct strmbase_sink_ops *ops, IMemAllocator *allocator)
Definition: pin.c:1168
void strmbase_filter_cleanup(struct strmbase_filter *filter)
Definition: filter.c:540
void strmbase_filter_init(struct strmbase_filter *filter, IUnknown *outer, const CLSID *clsid, const struct strmbase_filter_ops *func_table)
Definition: filter.c:517
IFileSinkFilter IFileSinkFilter_iface
Definition: filewriter.c:29
IAMFilterMiscFlags IAMFilterMiscFlags_iface
Definition: filewriter.c:28
WCHAR * filename
Definition: filewriter.c:33
HANDLE file
Definition: filewriter.c:34
Definition: fci.c:123
Definition: filter.c:165
IBaseFilter * filter
Definition: filtergraph.c:75
Definition: wave.c:25
struct strmbase_pin pin
Definition: strmbase.h:106
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define E_NOINTERFACE
Definition: winerror.h:3479
unsigned char BYTE
Definition: xxhash.c:193