2010-10-20 20:55:16 +02:00
|
|
|
/*
|
|
|
|
* GStreamer splitter + decoder, adapted from parser.c
|
|
|
|
*
|
|
|
|
* Copyright 2010 Maarten Lankhorst for CodeWeavers
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __GST_PRIVATE_INCLUDED__
|
|
|
|
#define __GST_PRIVATE_INCLUDED__
|
|
|
|
|
2021-02-22 23:53:47 +01:00
|
|
|
#include <assert.h>
|
2021-09-16 01:00:08 +02:00
|
|
|
#include <limits.h>
|
2010-10-20 20:55:16 +02:00
|
|
|
#include <stdarg.h>
|
winegstreamer: Manage our own streaming thread.
This is a rather large and complex change. It comprises several parts:
(1) Instead of directly sending EOS, segment, and sample events to the
downstream DirectShow sink, first queue them in a local buffer (i.e.
"pin->event").
(2) Spawn a separate thread per source pin (i.e. "stream_thread") which consumes
said events and sends them downstream.
(3) When flushing or stopping, explicitly wait for this thread to pause or stop
(respectively).
There are a few reasons for this:
(1) It reduces the number of Unix -> PE callbacks we need to make, easing PE
conversion. This is not a great advantage *a priori*, and may not be worth a
similar dedicated "handler" thread for most modules, but winegstreamer is
different—we were already marshalling these calls onto another thread, and
now that marshalling can go away (almost).
(2) Because GStreamer can only do pad negotiation (and hence autoplugging) while
running (in contrast to DirectShow, which can do it while stopped), we
currently have to renegotiate every time the pipeline is started. Most
applications don't start the graph more than once, but even that requires
two negotiations, and startup time is demonstrably too high. It would be
nice to keep the graph in PAUSED state all of the time, but this is
difficult to do without more fine-grained control over the streaming thread.
[In particular, we cannot reliably wait for all samples to be delivered
except by stopping the GStreamer pipeline.]
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
2021-01-20 04:35:38 +01:00
|
|
|
#include <stdbool.h>
|
2021-01-22 00:22:52 +01:00
|
|
|
#include <stdint.h>
|
2020-03-08 20:05:09 +01:00
|
|
|
#include <stdio.h>
|
2010-10-20 20:55:16 +02:00
|
|
|
|
|
|
|
#define COBJMACROS
|
2020-03-08 20:05:09 +01:00
|
|
|
#define NONAMELESSSTRUCT
|
|
|
|
#define NONAMELESSUNION
|
2010-10-20 20:55:16 +02:00
|
|
|
#include "dshow.h"
|
2021-02-22 23:53:47 +01:00
|
|
|
#include "mfidl.h"
|
2020-10-22 18:10:17 +02:00
|
|
|
#include "wine/debug.h"
|
2010-10-20 20:55:16 +02:00
|
|
|
#include "wine/strmbase.h"
|
|
|
|
|
2021-10-05 02:20:49 +02:00
|
|
|
#include "unixlib.h"
|
|
|
|
|
2020-10-22 18:10:17 +02:00
|
|
|
static inline const char *debugstr_time(REFERENCE_TIME time)
|
|
|
|
{
|
|
|
|
ULONGLONG abstime = time >= 0 ? time : -time;
|
|
|
|
unsigned int i = 0, j = 0;
|
|
|
|
char buffer[23], rev[23];
|
|
|
|
|
|
|
|
while (abstime || i <= 8)
|
|
|
|
{
|
|
|
|
buffer[i++] = '0' + (abstime % 10);
|
|
|
|
abstime /= 10;
|
|
|
|
if (i == 7) buffer[i++] = '.';
|
|
|
|
}
|
|
|
|
if (time < 0) buffer[i++] = '-';
|
|
|
|
|
|
|
|
while (i--) rev[j++] = buffer[i];
|
|
|
|
while (rev[j-1] == '0' && rev[j-2] != '.') --j;
|
|
|
|
rev[j] = 0;
|
|
|
|
|
|
|
|
return wine_dbg_sprintf("%s", rev);
|
|
|
|
}
|
|
|
|
|
2010-10-26 18:39:15 +02:00
|
|
|
#define MEDIATIME_FROM_BYTES(x) ((LONGLONG)(x) * 10000000)
|
|
|
|
|
2021-02-11 23:18:56 +01:00
|
|
|
extern const struct unix_funcs *unix_funcs;
|
|
|
|
|
2020-03-08 20:05:09 +01:00
|
|
|
HRESULT avi_splitter_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
|
2021-01-16 00:59:17 +01:00
|
|
|
HRESULT decodebin_parser_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
|
2020-03-08 20:05:09 +01:00
|
|
|
HRESULT mpeg_splitter_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
|
|
|
|
HRESULT wave_parser_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
|
2010-10-26 18:39:15 +02:00
|
|
|
|
2019-03-26 06:57:33 +01:00
|
|
|
BOOL init_gstreamer(void) DECLSPEC_HIDDEN;
|
2016-01-12 20:35:04 +01:00
|
|
|
|
2019-07-05 15:23:21 +02:00
|
|
|
extern HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) DECLSPEC_HIDDEN;
|
2020-12-03 17:42:19 +01:00
|
|
|
extern HRESULT mfplat_DllRegisterServer(void) DECLSPEC_HIDDEN;
|
2019-07-05 15:23:21 +02:00
|
|
|
|
2021-02-19 00:01:27 +01:00
|
|
|
IMFMediaType *mf_media_type_from_wg_format(const struct wg_format *format) DECLSPEC_HIDDEN;
|
|
|
|
void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format) DECLSPEC_HIDDEN;
|
2020-09-28 22:59:54 +02:00
|
|
|
|
2020-09-02 22:05:02 +02:00
|
|
|
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
|
|
|
|
|
2020-12-03 17:42:18 +01:00
|
|
|
HRESULT audio_converter_create(REFIID riid, void **ret) DECLSPEC_HIDDEN;
|
|
|
|
|
2010-10-20 20:55:16 +02:00
|
|
|
#endif /* __GST_PRIVATE_INCLUDED__ */
|