dbghelp: Remove superfluous casts to self.
[wine.git] / dlls / winegstreamer / wg_parser.c
blobcd12a23d0c8cec0ab4855b59ea0fea21576f177e
1 /*
2 * GStreamer parser backend
4 * Copyright 2010 Maarten Lankhorst for CodeWeavers
5 * Copyright 2010 Aric Stewart for CodeWeavers
6 * Copyright 2019-2020 Zebediah Figura
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #if 0
24 #pragma makedep unix
25 #endif
27 #include "config.h"
28 #include "ntstatus.h"
29 #define WIN32_NO_STATUS
30 #include "gst_private.h"
31 #include "winternl.h"
33 #include <gst/gst.h>
34 #include <gst/video/video.h>
35 #include <gst/audio/audio.h>
37 /* GStreamer callbacks may be called on threads not created by Wine, and
38 * therefore cannot access the Wine TEB. This means that we must use GStreamer
39 * debug logging instead of Wine debug logging. In order to be safe we forbid
40 * any use of Wine debug logging in this entire file. */
42 GST_DEBUG_CATEGORY_STATIC(wine);
43 #define GST_CAT_DEFAULT wine
45 struct wg_parser
47 BOOL (*init_gst)(struct wg_parser *parser);
49 struct wg_parser_stream **streams;
50 unsigned int stream_count;
52 GstElement *container, *decodebin;
53 GstBus *bus;
54 GstPad *my_src, *their_sink;
56 guint64 file_size, start_offset, next_offset, stop_offset;
57 guint64 next_pull_offset;
59 pthread_t push_thread;
61 pthread_mutex_t mutex;
63 pthread_cond_t init_cond;
64 bool no_more_pads, has_duration, error;
66 pthread_cond_t read_cond, read_done_cond;
67 struct
69 void *data;
70 uint64_t offset;
71 uint32_t size;
72 bool done;
73 bool ret;
74 } read_request;
76 bool flushing, sink_connected;
79 struct wg_parser_stream
81 struct wg_parser *parser;
83 GstPad *their_src, *post_sink, *post_src, *my_sink;
84 GstElement *flip;
85 GstSegment segment;
86 struct wg_format preferred_format, current_format;
88 pthread_cond_t event_cond, event_empty_cond;
89 struct wg_parser_event event;
90 GstBuffer *buffer;
91 GstMapInfo map_info;
93 bool flushing, eos, enabled, has_caps;
95 uint64_t duration;
98 static enum wg_audio_format wg_audio_format_from_gst(GstAudioFormat format)
100 switch (format)
102 case GST_AUDIO_FORMAT_U8:
103 return WG_AUDIO_FORMAT_U8;
104 case GST_AUDIO_FORMAT_S16LE:
105 return WG_AUDIO_FORMAT_S16LE;
106 case GST_AUDIO_FORMAT_S24LE:
107 return WG_AUDIO_FORMAT_S24LE;
108 case GST_AUDIO_FORMAT_S32LE:
109 return WG_AUDIO_FORMAT_S32LE;
110 case GST_AUDIO_FORMAT_F32LE:
111 return WG_AUDIO_FORMAT_F32LE;
112 case GST_AUDIO_FORMAT_F64LE:
113 return WG_AUDIO_FORMAT_F64LE;
114 default:
115 return WG_AUDIO_FORMAT_UNKNOWN;
119 static uint32_t wg_channel_position_from_gst(GstAudioChannelPosition position)
121 static const uint32_t position_map[] =
123 SPEAKER_FRONT_LEFT,
124 SPEAKER_FRONT_RIGHT,
125 SPEAKER_FRONT_CENTER,
126 SPEAKER_LOW_FREQUENCY,
127 SPEAKER_BACK_LEFT,
128 SPEAKER_BACK_RIGHT,
129 SPEAKER_FRONT_LEFT_OF_CENTER,
130 SPEAKER_FRONT_RIGHT_OF_CENTER,
131 SPEAKER_BACK_CENTER,
133 SPEAKER_SIDE_LEFT,
134 SPEAKER_SIDE_RIGHT,
135 SPEAKER_TOP_FRONT_LEFT,
136 SPEAKER_TOP_FRONT_RIGHT,
137 SPEAKER_TOP_FRONT_CENTER,
138 SPEAKER_TOP_CENTER,
139 SPEAKER_TOP_BACK_LEFT,
140 SPEAKER_TOP_BACK_RIGHT,
143 SPEAKER_TOP_BACK_CENTER,
146 if (position < ARRAY_SIZE(position_map))
147 return position_map[position];
148 return 0;
151 static uint32_t wg_channel_mask_from_gst(const GstAudioInfo *info)
153 uint32_t mask = 0, position;
154 unsigned int i;
156 for (i = 0; i < GST_AUDIO_INFO_CHANNELS(info); ++i)
158 if (!(position = wg_channel_position_from_gst(GST_AUDIO_INFO_POSITION(info, i))))
160 GST_WARNING("Unsupported channel %#x.", GST_AUDIO_INFO_POSITION(info, i));
161 return 0;
163 /* Make sure it's also in WinMM order. WinMM mandates that channels be
164 * ordered, as it were, from least to most significant SPEAKER_* bit.
165 * Hence we fail if the current channel was already specified, or if any
166 * higher bit was already specified. */
167 if (mask & ~(position - 1))
169 GST_WARNING("Unsupported channel order.");
170 return 0;
172 mask |= position;
174 return mask;
177 static void wg_format_from_audio_info(struct wg_format *format, const GstAudioInfo *info)
179 format->major_type = WG_MAJOR_TYPE_AUDIO;
180 format->u.audio.format = wg_audio_format_from_gst(GST_AUDIO_INFO_FORMAT(info));
181 format->u.audio.channels = GST_AUDIO_INFO_CHANNELS(info);
182 format->u.audio.channel_mask = wg_channel_mask_from_gst(info);
183 format->u.audio.rate = GST_AUDIO_INFO_RATE(info);
186 static enum wg_video_format wg_video_format_from_gst(GstVideoFormat format)
188 switch (format)
190 case GST_VIDEO_FORMAT_BGRA:
191 return WG_VIDEO_FORMAT_BGRA;
192 case GST_VIDEO_FORMAT_BGRx:
193 return WG_VIDEO_FORMAT_BGRx;
194 case GST_VIDEO_FORMAT_BGR:
195 return WG_VIDEO_FORMAT_BGR;
196 case GST_VIDEO_FORMAT_RGB15:
197 return WG_VIDEO_FORMAT_RGB15;
198 case GST_VIDEO_FORMAT_RGB16:
199 return WG_VIDEO_FORMAT_RGB16;
200 case GST_VIDEO_FORMAT_AYUV:
201 return WG_VIDEO_FORMAT_AYUV;
202 case GST_VIDEO_FORMAT_I420:
203 return WG_VIDEO_FORMAT_I420;
204 case GST_VIDEO_FORMAT_NV12:
205 return WG_VIDEO_FORMAT_NV12;
206 case GST_VIDEO_FORMAT_UYVY:
207 return WG_VIDEO_FORMAT_UYVY;
208 case GST_VIDEO_FORMAT_YUY2:
209 return WG_VIDEO_FORMAT_YUY2;
210 case GST_VIDEO_FORMAT_YV12:
211 return WG_VIDEO_FORMAT_YV12;
212 case GST_VIDEO_FORMAT_YVYU:
213 return WG_VIDEO_FORMAT_YVYU;
214 default:
215 return WG_VIDEO_FORMAT_UNKNOWN;
219 static void wg_format_from_video_info(struct wg_format *format, const GstVideoInfo *info)
221 format->major_type = WG_MAJOR_TYPE_VIDEO;
222 format->u.video.format = wg_video_format_from_gst(GST_VIDEO_INFO_FORMAT(info));
223 format->u.video.width = GST_VIDEO_INFO_WIDTH(info);
224 format->u.video.height = GST_VIDEO_INFO_HEIGHT(info);
225 format->u.video.fps_n = GST_VIDEO_INFO_FPS_N(info);
226 format->u.video.fps_d = GST_VIDEO_INFO_FPS_D(info);
229 static void wg_format_from_caps_audio_mpeg(struct wg_format *format, const GstCaps *caps)
231 const GstStructure *structure = gst_caps_get_structure(caps, 0);
232 gint layer, channels, rate;
234 if (!gst_structure_get_int(structure, "layer", &layer))
236 GST_WARNING("Missing \"layer\" value.");
237 return;
239 if (!gst_structure_get_int(structure, "channels", &channels))
241 GST_WARNING("Missing \"channels\" value.");
242 return;
244 if (!gst_structure_get_int(structure, "rate", &rate))
246 GST_WARNING("Missing \"rate\" value.");
247 return;
250 format->major_type = WG_MAJOR_TYPE_AUDIO;
252 if (layer == 1)
253 format->u.audio.format = WG_AUDIO_FORMAT_MPEG1_LAYER1;
254 else if (layer == 2)
255 format->u.audio.format = WG_AUDIO_FORMAT_MPEG1_LAYER2;
256 else if (layer == 3)
257 format->u.audio.format = WG_AUDIO_FORMAT_MPEG1_LAYER3;
259 format->u.audio.channels = channels;
260 format->u.audio.rate = rate;
263 static void wg_format_from_caps_video_cinepak(struct wg_format *format, const GstCaps *caps)
265 const GstStructure *structure = gst_caps_get_structure(caps, 0);
266 gint width, height, fps_n, fps_d;
268 if (!gst_structure_get_int(structure, "width", &width))
270 GST_WARNING("Missing \"width\" value.");
271 return;
273 if (!gst_structure_get_int(structure, "height", &height))
275 GST_WARNING("Missing \"height\" value.");
276 return;
278 if (!gst_structure_get_fraction(structure, "framerate", &fps_n, &fps_d))
280 fps_n = 0;
281 fps_d = 1;
284 format->major_type = WG_MAJOR_TYPE_VIDEO;
285 format->u.video.format = WG_VIDEO_FORMAT_CINEPAK;
286 format->u.video.width = width;
287 format->u.video.height = height;
288 format->u.video.fps_n = fps_n;
289 format->u.video.fps_d = fps_d;
292 static void wg_format_from_caps(struct wg_format *format, const GstCaps *caps)
294 const GstStructure *structure = gst_caps_get_structure(caps, 0);
295 const char *name = gst_structure_get_name(structure);
297 memset(format, 0, sizeof(*format));
299 if (!strcmp(name, "audio/x-raw"))
301 GstAudioInfo info;
303 if (gst_audio_info_from_caps(&info, caps))
304 wg_format_from_audio_info(format, &info);
306 else if (!strcmp(name, "video/x-raw"))
308 GstVideoInfo info;
310 if (gst_video_info_from_caps(&info, caps))
311 wg_format_from_video_info(format, &info);
313 else if (!strcmp(name, "audio/mpeg"))
315 wg_format_from_caps_audio_mpeg(format, caps);
317 else if (!strcmp(name, "video/x-cinepak"))
319 wg_format_from_caps_video_cinepak(format, caps);
321 else
323 gchar *str = gst_caps_to_string(caps);
325 GST_FIXME("Unhandled caps %s.", str);
326 g_free(str);
330 static GstAudioFormat wg_audio_format_to_gst(enum wg_audio_format format)
332 switch (format)
334 case WG_AUDIO_FORMAT_U8: return GST_AUDIO_FORMAT_U8;
335 case WG_AUDIO_FORMAT_S16LE: return GST_AUDIO_FORMAT_S16LE;
336 case WG_AUDIO_FORMAT_S24LE: return GST_AUDIO_FORMAT_S24LE;
337 case WG_AUDIO_FORMAT_S32LE: return GST_AUDIO_FORMAT_S32LE;
338 case WG_AUDIO_FORMAT_F32LE: return GST_AUDIO_FORMAT_F32LE;
339 case WG_AUDIO_FORMAT_F64LE: return GST_AUDIO_FORMAT_F64LE;
340 default: return GST_AUDIO_FORMAT_UNKNOWN;
344 static void wg_channel_mask_to_gst(GstAudioChannelPosition *positions, uint32_t mask, uint32_t channel_count)
346 const uint32_t orig_mask = mask;
347 unsigned int i;
348 DWORD bit;
350 static const GstAudioChannelPosition position_map[] =
352 GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
353 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
354 GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
355 GST_AUDIO_CHANNEL_POSITION_LFE1,
356 GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
357 GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
358 GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
359 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,
360 GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
361 GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
362 GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
363 GST_AUDIO_CHANNEL_POSITION_TOP_CENTER,
364 GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT,
365 GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER,
366 GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT,
367 GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT,
368 GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER,
369 GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT,
372 for (i = 0; i < channel_count; ++i)
374 positions[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
375 if (BitScanForward(&bit, mask))
377 if (bit < ARRAY_SIZE(position_map))
378 positions[i] = position_map[bit];
379 else
380 GST_WARNING("Invalid channel mask %#x.\n", orig_mask);
381 mask &= ~(1 << bit);
383 else
385 GST_WARNING("Incomplete channel mask %#x.\n", orig_mask);
390 static GstCaps *wg_format_to_caps_audio(const struct wg_format *format)
392 GstAudioChannelPosition positions[32];
393 GstAudioFormat audio_format;
394 GstAudioInfo info;
396 if ((audio_format = wg_audio_format_to_gst(format->u.audio.format)) == GST_AUDIO_FORMAT_UNKNOWN)
397 return NULL;
399 wg_channel_mask_to_gst(positions, format->u.audio.channel_mask, format->u.audio.channels);
400 gst_audio_info_set_format(&info, audio_format, format->u.audio.rate, format->u.audio.channels, positions);
401 return gst_audio_info_to_caps(&info);
404 static GstVideoFormat wg_video_format_to_gst(enum wg_video_format format)
406 switch (format)
408 case WG_VIDEO_FORMAT_BGRA: return GST_VIDEO_FORMAT_BGRA;
409 case WG_VIDEO_FORMAT_BGRx: return GST_VIDEO_FORMAT_BGRx;
410 case WG_VIDEO_FORMAT_BGR: return GST_VIDEO_FORMAT_BGR;
411 case WG_VIDEO_FORMAT_RGB15: return GST_VIDEO_FORMAT_RGB15;
412 case WG_VIDEO_FORMAT_RGB16: return GST_VIDEO_FORMAT_RGB16;
413 case WG_VIDEO_FORMAT_AYUV: return GST_VIDEO_FORMAT_AYUV;
414 case WG_VIDEO_FORMAT_I420: return GST_VIDEO_FORMAT_I420;
415 case WG_VIDEO_FORMAT_NV12: return GST_VIDEO_FORMAT_NV12;
416 case WG_VIDEO_FORMAT_UYVY: return GST_VIDEO_FORMAT_UYVY;
417 case WG_VIDEO_FORMAT_YUY2: return GST_VIDEO_FORMAT_YUY2;
418 case WG_VIDEO_FORMAT_YV12: return GST_VIDEO_FORMAT_YV12;
419 case WG_VIDEO_FORMAT_YVYU: return GST_VIDEO_FORMAT_YVYU;
420 default: return GST_VIDEO_FORMAT_UNKNOWN;
424 static GstCaps *wg_format_to_caps_video(const struct wg_format *format)
426 GstVideoFormat video_format;
427 GstVideoInfo info;
428 unsigned int i;
429 GstCaps *caps;
431 if ((video_format = wg_video_format_to_gst(format->u.video.format)) == GST_VIDEO_FORMAT_UNKNOWN)
432 return NULL;
434 gst_video_info_set_format(&info, video_format, format->u.video.width, format->u.video.height);
435 if ((caps = gst_video_info_to_caps(&info)))
437 /* Clear some fields that shouldn't prevent us from connecting. */
438 for (i = 0; i < gst_caps_get_size(caps); ++i)
440 gst_structure_remove_fields(gst_caps_get_structure(caps, i),
441 "framerate", "pixel-aspect-ratio", "colorimetry", "chroma-site", NULL);
444 return caps;
447 static GstCaps *wg_format_to_caps(const struct wg_format *format)
449 switch (format->major_type)
451 case WG_MAJOR_TYPE_UNKNOWN:
452 return NULL;
453 case WG_MAJOR_TYPE_AUDIO:
454 return wg_format_to_caps_audio(format);
455 case WG_MAJOR_TYPE_VIDEO:
456 return wg_format_to_caps_video(format);
458 assert(0);
459 return NULL;
462 static bool wg_format_compare(const struct wg_format *a, const struct wg_format *b)
464 if (a->major_type != b->major_type)
465 return false;
467 switch (a->major_type)
469 case WG_MAJOR_TYPE_UNKNOWN:
470 return false;
472 case WG_MAJOR_TYPE_AUDIO:
473 return a->u.audio.format == b->u.audio.format
474 && a->u.audio.channels == b->u.audio.channels
475 && a->u.audio.rate == b->u.audio.rate;
477 case WG_MAJOR_TYPE_VIDEO:
478 /* Do not compare FPS. */
479 return a->u.video.format == b->u.video.format
480 && a->u.video.width == b->u.video.width
481 && a->u.video.height == b->u.video.height;
484 assert(0);
485 return false;
488 static uint32_t CDECL wg_parser_get_stream_count(struct wg_parser *parser)
490 return parser->stream_count;
493 static struct wg_parser_stream * CDECL wg_parser_get_stream(struct wg_parser *parser, uint32_t index)
495 return parser->streams[index];
498 static void CDECL wg_parser_begin_flush(struct wg_parser *parser)
500 unsigned int i;
502 pthread_mutex_lock(&parser->mutex);
503 parser->flushing = true;
504 pthread_mutex_unlock(&parser->mutex);
506 for (i = 0; i < parser->stream_count; ++i)
508 if (parser->streams[i]->enabled)
509 pthread_cond_signal(&parser->streams[i]->event_cond);
513 static void CDECL wg_parser_end_flush(struct wg_parser *parser)
515 pthread_mutex_lock(&parser->mutex);
516 parser->flushing = false;
517 pthread_mutex_unlock(&parser->mutex);
520 static bool CDECL wg_parser_get_read_request(struct wg_parser *parser,
521 void **data, uint64_t *offset, uint32_t *size)
523 pthread_mutex_lock(&parser->mutex);
525 while (parser->sink_connected && !parser->read_request.data)
526 pthread_cond_wait(&parser->read_cond, &parser->mutex);
528 if (!parser->sink_connected)
530 pthread_mutex_unlock(&parser->mutex);
531 return false;
534 *data = parser->read_request.data;
535 *offset = parser->read_request.offset;
536 *size = parser->read_request.size;
538 pthread_mutex_unlock(&parser->mutex);
539 return true;
542 static void CDECL wg_parser_complete_read_request(struct wg_parser *parser, bool ret)
544 pthread_mutex_lock(&parser->mutex);
545 parser->read_request.done = true;
546 parser->read_request.ret = ret;
547 parser->read_request.data = NULL;
548 pthread_mutex_unlock(&parser->mutex);
549 pthread_cond_signal(&parser->read_done_cond);
552 static void CDECL wg_parser_set_unlimited_buffering(struct wg_parser *parser)
554 g_object_set(parser->decodebin, "max-size-buffers", G_MAXUINT, NULL);
555 g_object_set(parser->decodebin, "max-size-time", G_MAXUINT64, NULL);
556 g_object_set(parser->decodebin, "max-size-bytes", G_MAXUINT, NULL);
559 static void CDECL wg_parser_stream_get_preferred_format(struct wg_parser_stream *stream, struct wg_format *format)
561 *format = stream->preferred_format;
564 static void CDECL wg_parser_stream_enable(struct wg_parser_stream *stream, const struct wg_format *format)
566 stream->current_format = *format;
567 stream->enabled = true;
569 if (format->major_type == WG_MAJOR_TYPE_VIDEO)
571 switch (format->u.video.format)
573 case WG_VIDEO_FORMAT_BGRA:
574 case WG_VIDEO_FORMAT_BGRx:
575 case WG_VIDEO_FORMAT_BGR:
576 case WG_VIDEO_FORMAT_RGB15:
577 case WG_VIDEO_FORMAT_RGB16:
578 gst_util_set_object_arg(G_OBJECT(stream->flip), "method", "vertical-flip");
579 break;
581 case WG_VIDEO_FORMAT_AYUV:
582 case WG_VIDEO_FORMAT_I420:
583 case WG_VIDEO_FORMAT_NV12:
584 case WG_VIDEO_FORMAT_UYVY:
585 case WG_VIDEO_FORMAT_YUY2:
586 case WG_VIDEO_FORMAT_YV12:
587 case WG_VIDEO_FORMAT_YVYU:
588 case WG_VIDEO_FORMAT_UNKNOWN:
589 case WG_VIDEO_FORMAT_CINEPAK:
590 gst_util_set_object_arg(G_OBJECT(stream->flip), "method", "none");
591 break;
595 gst_pad_push_event(stream->my_sink, gst_event_new_reconfigure());
598 static void CDECL wg_parser_stream_disable(struct wg_parser_stream *stream)
600 stream->enabled = false;
603 static bool CDECL wg_parser_stream_get_event(struct wg_parser_stream *stream, struct wg_parser_event *event)
605 struct wg_parser *parser = stream->parser;
607 pthread_mutex_lock(&parser->mutex);
609 while (!parser->flushing && stream->event.type == WG_PARSER_EVENT_NONE)
610 pthread_cond_wait(&stream->event_cond, &parser->mutex);
612 if (parser->flushing)
614 pthread_mutex_unlock(&parser->mutex);
615 GST_DEBUG("Filter is flushing.\n");
616 return false;
619 *event = stream->event;
621 if (stream->event.type != WG_PARSER_EVENT_BUFFER)
623 stream->event.type = WG_PARSER_EVENT_NONE;
624 pthread_cond_signal(&stream->event_empty_cond);
626 pthread_mutex_unlock(&parser->mutex);
628 return true;
631 static bool CDECL wg_parser_stream_copy_buffer(struct wg_parser_stream *stream,
632 void *data, uint32_t offset, uint32_t size)
634 struct wg_parser *parser = stream->parser;
636 pthread_mutex_lock(&parser->mutex);
638 if (!stream->buffer)
640 pthread_mutex_unlock(&parser->mutex);
641 return false;
644 assert(stream->event.type == WG_PARSER_EVENT_BUFFER);
645 assert(offset < stream->map_info.size);
646 assert(offset + size <= stream->map_info.size);
647 memcpy(data, stream->map_info.data + offset, size);
649 pthread_mutex_unlock(&parser->mutex);
650 return true;
653 static void CDECL wg_parser_stream_release_buffer(struct wg_parser_stream *stream)
655 struct wg_parser *parser = stream->parser;
657 pthread_mutex_lock(&parser->mutex);
659 assert(stream->event.type == WG_PARSER_EVENT_BUFFER);
661 gst_buffer_unmap(stream->buffer, &stream->map_info);
662 gst_buffer_unref(stream->buffer);
663 stream->buffer = NULL;
664 stream->event.type = WG_PARSER_EVENT_NONE;
666 pthread_mutex_unlock(&parser->mutex);
667 pthread_cond_signal(&stream->event_empty_cond);
670 static uint64_t CDECL wg_parser_stream_get_duration(struct wg_parser_stream *stream)
672 return stream->duration;
675 static bool CDECL wg_parser_stream_seek(struct wg_parser_stream *stream, double rate,
676 uint64_t start_pos, uint64_t stop_pos, DWORD start_flags, DWORD stop_flags)
678 GstSeekType start_type = GST_SEEK_TYPE_SET, stop_type = GST_SEEK_TYPE_SET;
679 GstSeekFlags flags = 0;
681 if (start_flags & AM_SEEKING_SeekToKeyFrame)
682 flags |= GST_SEEK_FLAG_KEY_UNIT;
683 if (start_flags & AM_SEEKING_Segment)
684 flags |= GST_SEEK_FLAG_SEGMENT;
685 if (!(start_flags & AM_SEEKING_NoFlush))
686 flags |= GST_SEEK_FLAG_FLUSH;
688 if ((start_flags & AM_SEEKING_PositioningBitsMask) == AM_SEEKING_NoPositioning)
689 start_type = GST_SEEK_TYPE_NONE;
690 if ((stop_flags & AM_SEEKING_PositioningBitsMask) == AM_SEEKING_NoPositioning)
691 stop_type = GST_SEEK_TYPE_NONE;
693 return gst_pad_push_event(stream->my_sink, gst_event_new_seek(rate,
694 GST_FORMAT_TIME, flags, start_type, start_pos * 100, stop_type, stop_pos * 100));
697 static void CDECL wg_parser_stream_notify_qos(struct wg_parser_stream *stream,
698 bool underflow, double proportion, int64_t diff, uint64_t timestamp)
700 GstClockTime stream_time;
701 GstEvent *event;
703 /* We return timestamps in stream time, i.e. relative to the start of the
704 * file (or other medium), but gst_event_new_qos() expects the timestamp in
705 * running time. */
706 stream_time = gst_segment_to_running_time(&stream->segment, GST_FORMAT_TIME, timestamp * 100);
707 if (stream_time == -1)
709 /* This can happen legitimately if the sample falls outside of the
710 * segment bounds. GStreamer elements shouldn't present the sample in
711 * that case, but DirectShow doesn't care. */
712 GST_LOG("Ignoring QoS event.\n");
713 return;
716 if (!(event = gst_event_new_qos(underflow ? GST_QOS_TYPE_UNDERFLOW : GST_QOS_TYPE_OVERFLOW,
717 proportion, diff * 100, stream_time)))
718 GST_ERROR("Failed to create QOS event.\n");
719 gst_pad_push_event(stream->my_sink, event);
722 static GstAutoplugSelectResult autoplug_select_cb(GstElement *bin, GstPad *pad,
723 GstCaps *caps, GstElementFactory *fact, gpointer user)
725 const char *name = gst_element_factory_get_longname(fact);
727 GST_INFO("Using \"%s\".", name);
729 if (strstr(name, "Player protection"))
731 GST_WARNING("Blacklisted a/52 decoder because it only works in Totem.");
732 return GST_AUTOPLUG_SELECT_SKIP;
734 if (!strcmp(name, "Fluendo Hardware Accelerated Video Decoder"))
736 GST_WARNING("Disabled video acceleration since it breaks in wine.");
737 return GST_AUTOPLUG_SELECT_SKIP;
739 return GST_AUTOPLUG_SELECT_TRY;
742 static void no_more_pads_cb(GstElement *element, gpointer user)
744 struct wg_parser *parser = user;
746 GST_DEBUG("parser %p.", parser);
748 pthread_mutex_lock(&parser->mutex);
749 parser->no_more_pads = true;
750 pthread_mutex_unlock(&parser->mutex);
751 pthread_cond_signal(&parser->init_cond);
754 static GstFlowReturn queue_stream_event(struct wg_parser_stream *stream,
755 const struct wg_parser_event *event, GstBuffer *buffer)
757 struct wg_parser *parser = stream->parser;
759 /* Unlike request_buffer_src() [q.v.], we need to watch for GStreamer
760 * flushes here. The difference is that we can be blocked by the streaming
761 * thread not running (or itself flushing on the DirectShow side).
762 * request_buffer_src() can only be blocked by the upstream source, and that
763 * is solved by flushing the upstream source. */
765 pthread_mutex_lock(&parser->mutex);
766 while (!stream->flushing && stream->event.type != WG_PARSER_EVENT_NONE)
767 pthread_cond_wait(&stream->event_empty_cond, &parser->mutex);
768 if (stream->flushing)
770 pthread_mutex_unlock(&parser->mutex);
771 GST_DEBUG("Filter is flushing; discarding event.");
772 return GST_FLOW_FLUSHING;
774 if (buffer)
776 assert(GST_IS_BUFFER(buffer));
777 if (!gst_buffer_map(buffer, &stream->map_info, GST_MAP_READ))
779 pthread_mutex_unlock(&parser->mutex);
780 GST_ERROR("Failed to map buffer.\n");
781 return GST_FLOW_ERROR;
784 stream->event = *event;
785 stream->buffer = buffer;
786 pthread_mutex_unlock(&parser->mutex);
787 pthread_cond_signal(&stream->event_cond);
788 GST_LOG("Event queued.");
789 return GST_FLOW_OK;
792 static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event)
794 struct wg_parser_stream *stream = gst_pad_get_element_private(pad);
795 struct wg_parser *parser = stream->parser;
797 GST_LOG("stream %p, type \"%s\".", stream, GST_EVENT_TYPE_NAME(event));
799 switch (event->type)
801 case GST_EVENT_SEGMENT:
802 if (stream->enabled)
804 struct wg_parser_event stream_event;
805 const GstSegment *segment;
807 gst_event_parse_segment(event, &segment);
809 if (segment->format != GST_FORMAT_TIME)
811 GST_FIXME("Unhandled format \"%s\".", gst_format_get_name(segment->format));
812 break;
815 gst_segment_copy_into(segment, &stream->segment);
817 stream_event.type = WG_PARSER_EVENT_SEGMENT;
818 stream_event.u.segment.position = segment->position / 100;
819 stream_event.u.segment.stop = segment->stop / 100;
820 stream_event.u.segment.rate = segment->rate * segment->applied_rate;
821 queue_stream_event(stream, &stream_event, NULL);
823 break;
825 case GST_EVENT_EOS:
826 if (stream->enabled)
828 struct wg_parser_event stream_event;
830 stream_event.type = WG_PARSER_EVENT_EOS;
831 queue_stream_event(stream, &stream_event, NULL);
833 else
835 pthread_mutex_lock(&parser->mutex);
836 stream->eos = true;
837 pthread_mutex_unlock(&parser->mutex);
838 pthread_cond_signal(&parser->init_cond);
840 break;
842 case GST_EVENT_FLUSH_START:
843 if (stream->enabled)
845 pthread_mutex_lock(&parser->mutex);
847 stream->flushing = true;
848 pthread_cond_signal(&stream->event_empty_cond);
850 if (stream->event.type == WG_PARSER_EVENT_BUFFER)
852 gst_buffer_unmap(stream->buffer, &stream->map_info);
853 gst_buffer_unref(stream->buffer);
854 stream->buffer = NULL;
856 stream->event.type = WG_PARSER_EVENT_NONE;
858 pthread_mutex_unlock(&parser->mutex);
860 break;
862 case GST_EVENT_FLUSH_STOP:
864 gboolean reset_time;
866 gst_event_parse_flush_stop(event, &reset_time);
868 if (reset_time)
869 gst_segment_init(&stream->segment, GST_FORMAT_UNDEFINED);
871 if (stream->enabled)
873 pthread_mutex_lock(&parser->mutex);
874 stream->flushing = false;
875 pthread_mutex_unlock(&parser->mutex);
877 break;
880 case GST_EVENT_CAPS:
882 GstCaps *caps;
884 gst_event_parse_caps(event, &caps);
885 pthread_mutex_lock(&parser->mutex);
886 wg_format_from_caps(&stream->preferred_format, caps);
887 stream->has_caps = true;
888 pthread_mutex_unlock(&parser->mutex);
889 pthread_cond_signal(&parser->init_cond);
890 break;
893 default:
894 GST_WARNING("Ignoring \"%s\" event.", GST_EVENT_TYPE_NAME(event));
896 gst_event_unref(event);
897 return TRUE;
900 static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *buffer)
902 struct wg_parser_stream *stream = gst_pad_get_element_private(pad);
903 struct wg_parser_event stream_event;
904 GstFlowReturn ret;
906 GST_LOG("stream %p, buffer %p.", stream, buffer);
908 if (!stream->enabled)
910 gst_buffer_unref(buffer);
911 return GST_FLOW_OK;
914 stream_event.type = WG_PARSER_EVENT_BUFFER;
916 /* FIXME: Should we use gst_segment_to_stream_time_full()? Under what
917 * circumstances is the stream time not equal to the buffer PTS? Note that
918 * this will need modification to wg_parser_stream_notify_qos() as well. */
920 if ((stream_event.u.buffer.has_pts = GST_BUFFER_PTS_IS_VALID(buffer)))
921 stream_event.u.buffer.pts = GST_BUFFER_PTS(buffer) / 100;
922 if ((stream_event.u.buffer.has_duration = GST_BUFFER_DURATION_IS_VALID(buffer)))
923 stream_event.u.buffer.duration = GST_BUFFER_DURATION(buffer) / 100;
924 stream_event.u.buffer.discontinuity = GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DISCONT);
925 stream_event.u.buffer.preroll = GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_LIVE);
926 stream_event.u.buffer.delta = GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT);
927 stream_event.u.buffer.size = gst_buffer_get_size(buffer);
929 /* Transfer our reference to the buffer to the stream object. */
930 if ((ret = queue_stream_event(stream, &stream_event, buffer)) != GST_FLOW_OK)
931 gst_buffer_unref(buffer);
932 return ret;
935 static gboolean sink_query_cb(GstPad *pad, GstObject *parent, GstQuery *query)
937 struct wg_parser_stream *stream = gst_pad_get_element_private(pad);
939 GST_LOG("stream %p, type \"%s\".", stream, gst_query_type_get_name(query->type));
941 switch (query->type)
943 case GST_QUERY_CAPS:
945 GstCaps *caps, *filter, *temp;
947 gst_query_parse_caps(query, &filter);
949 if (stream->enabled)
950 caps = wg_format_to_caps(&stream->current_format);
951 else
952 caps = gst_caps_new_any();
953 if (!caps)
954 return FALSE;
956 if (filter)
958 temp = gst_caps_intersect(caps, filter);
959 gst_caps_unref(caps);
960 caps = temp;
963 gst_query_set_caps_result(query, caps);
964 gst_caps_unref(caps);
965 return TRUE;
968 case GST_QUERY_ACCEPT_CAPS:
970 struct wg_format format;
971 gboolean ret = TRUE;
972 GstCaps *caps;
974 if (!stream->enabled)
976 gst_query_set_accept_caps_result(query, TRUE);
977 return TRUE;
980 gst_query_parse_accept_caps(query, &caps);
981 wg_format_from_caps(&format, caps);
982 ret = wg_format_compare(&format, &stream->current_format);
983 if (!ret && gst_debug_category_get_threshold(GST_CAT_DEFAULT) >= GST_LEVEL_WARNING)
985 gchar *str = gst_caps_to_string(caps);
986 GST_WARNING("Rejecting caps \"%s\".", str);
987 g_free(str);
989 gst_query_set_accept_caps_result(query, ret);
990 return TRUE;
993 default:
994 return gst_pad_query_default (pad, parent, query);
998 static GstElement *create_element(const char *name, const char *plugin_set)
1000 GstElement *element;
1002 if (!(element = gst_element_factory_make(name, NULL)))
1003 fprintf(stderr, "winegstreamer: failed to create %s, are %u-bit GStreamer \"%s\" plugins installed?\n",
1004 name, 8 * (unsigned int)sizeof(void *), plugin_set);
1005 return element;
1008 static struct wg_parser_stream *create_stream(struct wg_parser *parser)
1010 struct wg_parser_stream *stream, **new_array;
1011 char pad_name[19];
1013 if (!(new_array = realloc(parser->streams, (parser->stream_count + 1) * sizeof(*parser->streams))))
1014 return NULL;
1015 parser->streams = new_array;
1017 if (!(stream = calloc(1, sizeof(*stream))))
1018 return NULL;
1020 gst_segment_init(&stream->segment, GST_FORMAT_UNDEFINED);
1022 stream->parser = parser;
1023 pthread_cond_init(&stream->event_cond, NULL);
1024 pthread_cond_init(&stream->event_empty_cond, NULL);
1026 sprintf(pad_name, "qz_sink_%u", parser->stream_count);
1027 stream->my_sink = gst_pad_new(pad_name, GST_PAD_SINK);
1028 gst_pad_set_element_private(stream->my_sink, stream);
1029 gst_pad_set_chain_function(stream->my_sink, sink_chain_cb);
1030 gst_pad_set_event_function(stream->my_sink, sink_event_cb);
1031 gst_pad_set_query_function(stream->my_sink, sink_query_cb);
1033 parser->streams[parser->stream_count++] = stream;
1034 return stream;
1037 static void pad_added_cb(GstElement *element, GstPad *pad, gpointer user)
1039 struct wg_parser *parser = user;
1040 struct wg_parser_stream *stream;
1041 const char *name;
1042 GstCaps *caps;
1043 int ret;
1045 GST_LOG("parser %p, element %p, pad %p.", parser, element, pad);
1047 if (gst_pad_is_linked(pad))
1048 return;
1050 caps = gst_pad_query_caps(pad, NULL);
1051 name = gst_structure_get_name(gst_caps_get_structure(caps, 0));
1053 if (!(stream = create_stream(parser)))
1054 goto out;
1056 if (!strcmp(name, "video/x-raw"))
1058 GstElement *deinterlace, *vconv, *flip, *vconv2;
1060 /* DirectShow can express interlaced video, but downstream filters can't
1061 * necessarily consume it. In particular, the video renderer can't. */
1062 if (!(deinterlace = create_element("deinterlace", "good")))
1063 goto out;
1065 /* decodebin considers many YUV formats to be "raw", but some quartz
1066 * filters can't handle those. Also, videoflip can't handle all "raw"
1067 * formats either. Add a videoconvert to swap color spaces. */
1068 if (!(vconv = create_element("videoconvert", "base")))
1069 goto out;
1071 /* GStreamer outputs RGB video top-down, but DirectShow expects bottom-up. */
1072 if (!(flip = create_element("videoflip", "good")))
1073 goto out;
1075 /* videoflip does not support 15 and 16-bit RGB so add a second videoconvert
1076 * to do the final conversion. */
1077 if (!(vconv2 = create_element("videoconvert", "base")))
1078 goto out;
1080 /* The bin takes ownership of these elements. */
1081 gst_bin_add(GST_BIN(parser->container), deinterlace);
1082 gst_element_sync_state_with_parent(deinterlace);
1083 gst_bin_add(GST_BIN(parser->container), vconv);
1084 gst_element_sync_state_with_parent(vconv);
1085 gst_bin_add(GST_BIN(parser->container), flip);
1086 gst_element_sync_state_with_parent(flip);
1087 gst_bin_add(GST_BIN(parser->container), vconv2);
1088 gst_element_sync_state_with_parent(vconv2);
1090 gst_element_link(deinterlace, vconv);
1091 gst_element_link(vconv, flip);
1092 gst_element_link(flip, vconv2);
1094 stream->post_sink = gst_element_get_static_pad(deinterlace, "sink");
1095 stream->post_src = gst_element_get_static_pad(vconv2, "src");
1096 stream->flip = flip;
1098 else if (!strcmp(name, "audio/x-raw"))
1100 GstElement *convert;
1102 /* Currently our dsound can't handle 64-bit formats or all
1103 * surround-sound configurations. Native dsound can't always handle
1104 * 64-bit formats either. Add an audioconvert to allow changing bit
1105 * depth and channel count. */
1106 if (!(convert = create_element("audioconvert", "base")))
1107 goto out;
1109 gst_bin_add(GST_BIN(parser->container), convert);
1110 gst_element_sync_state_with_parent(convert);
1112 stream->post_sink = gst_element_get_static_pad(convert, "sink");
1113 stream->post_src = gst_element_get_static_pad(convert, "src");
1116 if (stream->post_sink)
1118 if ((ret = gst_pad_link(pad, stream->post_sink)) < 0)
1120 GST_ERROR("Failed to link decodebin source pad to post-processing elements, error %s.",
1121 gst_pad_link_get_name(ret));
1122 gst_object_unref(stream->post_sink);
1123 stream->post_sink = NULL;
1124 goto out;
1127 if ((ret = gst_pad_link(stream->post_src, stream->my_sink)) < 0)
1129 GST_ERROR("Failed to link post-processing elements to our sink pad, error %s.",
1130 gst_pad_link_get_name(ret));
1131 gst_object_unref(stream->post_src);
1132 stream->post_src = NULL;
1133 gst_object_unref(stream->post_sink);
1134 stream->post_sink = NULL;
1135 goto out;
1138 else if ((ret = gst_pad_link(pad, stream->my_sink)) < 0)
1140 GST_ERROR("Failed to link decodebin source pad to our sink pad, error %s.",
1141 gst_pad_link_get_name(ret));
1142 goto out;
1145 gst_pad_set_active(stream->my_sink, 1);
1146 gst_object_ref(stream->their_src = pad);
1147 out:
1148 gst_caps_unref(caps);
1151 static void pad_removed_cb(GstElement *element, GstPad *pad, gpointer user)
1153 struct wg_parser *parser = user;
1154 unsigned int i;
1155 char *name;
1157 GST_LOG("parser %p, element %p, pad %p.", parser, element, pad);
1159 for (i = 0; i < parser->stream_count; ++i)
1161 struct wg_parser_stream *stream = parser->streams[i];
1163 if (stream->their_src == pad)
1165 if (stream->post_sink)
1166 gst_pad_unlink(stream->their_src, stream->post_sink);
1167 else
1168 gst_pad_unlink(stream->their_src, stream->my_sink);
1169 gst_object_unref(stream->their_src);
1170 stream->their_src = NULL;
1171 return;
1175 name = gst_pad_get_name(pad);
1176 GST_WARNING("No pin matching pad \"%s\" found.", name);
1177 g_free(name);
1180 static GstFlowReturn src_getrange_cb(GstPad *pad, GstObject *parent,
1181 guint64 offset, guint size, GstBuffer **buffer)
1183 struct wg_parser *parser = gst_pad_get_element_private(pad);
1184 GstBuffer *new_buffer = NULL;
1185 GstMapInfo map_info;
1186 bool ret;
1188 GST_LOG("pad %p, offset %" G_GINT64_MODIFIER "u, length %u, buffer %p.", pad, offset, size, *buffer);
1190 if (offset == GST_BUFFER_OFFSET_NONE)
1191 offset = parser->next_pull_offset;
1192 parser->next_pull_offset = offset + size;
1193 if (offset >= parser->file_size)
1194 return GST_FLOW_EOS;
1195 if (offset + size >= parser->file_size)
1196 size = parser->file_size - offset;
1198 if (!*buffer)
1199 *buffer = new_buffer = gst_buffer_new_and_alloc(size);
1201 gst_buffer_map(*buffer, &map_info, GST_MAP_WRITE);
1203 pthread_mutex_lock(&parser->mutex);
1205 assert(!parser->read_request.data);
1206 parser->read_request.data = map_info.data;
1207 parser->read_request.offset = offset;
1208 parser->read_request.size = size;
1209 parser->read_request.done = false;
1210 pthread_cond_signal(&parser->read_cond);
1212 /* Note that we don't unblock this wait on GST_EVENT_FLUSH_START. We expect
1213 * the upstream pin to flush if necessary. We should never be blocked on
1214 * read_thread() not running. */
1216 while (!parser->read_request.done)
1217 pthread_cond_wait(&parser->read_done_cond, &parser->mutex);
1219 ret = parser->read_request.ret;
1221 pthread_mutex_unlock(&parser->mutex);
1223 gst_buffer_unmap(*buffer, &map_info);
1225 GST_LOG("Request returned %d.", ret);
1227 if (!ret && new_buffer)
1228 gst_buffer_unref(new_buffer);
1230 return ret ? GST_FLOW_OK : GST_FLOW_ERROR;
1233 static gboolean src_query_cb(GstPad *pad, GstObject *parent, GstQuery *query)
1235 struct wg_parser *parser = gst_pad_get_element_private(pad);
1236 GstFormat format;
1238 GST_LOG("parser %p, type %s.", parser, GST_QUERY_TYPE_NAME(query));
1240 switch (GST_QUERY_TYPE(query))
1242 case GST_QUERY_DURATION:
1243 gst_query_parse_duration(query, &format, NULL);
1244 if (format == GST_FORMAT_PERCENT)
1246 gst_query_set_duration(query, GST_FORMAT_PERCENT, GST_FORMAT_PERCENT_MAX);
1247 return TRUE;
1249 else if (format == GST_FORMAT_BYTES)
1251 gst_query_set_duration(query, GST_FORMAT_BYTES, parser->file_size);
1252 return TRUE;
1254 return FALSE;
1256 case GST_QUERY_SEEKING:
1257 gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
1258 if (format != GST_FORMAT_BYTES)
1260 GST_WARNING("Cannot seek using format \"%s\".", gst_format_get_name(format));
1261 return FALSE;
1263 gst_query_set_seeking(query, GST_FORMAT_BYTES, 1, 0, parser->file_size);
1264 return TRUE;
1266 case GST_QUERY_SCHEDULING:
1267 gst_query_set_scheduling(query, GST_SCHEDULING_FLAG_SEEKABLE, 1, -1, 0);
1268 gst_query_add_scheduling_mode(query, GST_PAD_MODE_PUSH);
1269 gst_query_add_scheduling_mode(query, GST_PAD_MODE_PULL);
1270 return TRUE;
1272 default:
1273 GST_WARNING("Unhandled query type %s.", GST_QUERY_TYPE_NAME(query));
1274 return FALSE;
1278 static void *push_data(void *arg)
1280 struct wg_parser *parser = arg;
1281 GstBuffer *buffer;
1282 guint max_size;
1284 GST_DEBUG("Starting push thread.");
1286 if (!(buffer = gst_buffer_new_allocate(NULL, 16384, NULL)))
1288 GST_ERROR("Failed to allocate memory.");
1289 return NULL;
1292 max_size = parser->stop_offset ? parser->stop_offset : parser->file_size;
1294 for (;;)
1296 ULONG size;
1297 int ret;
1299 if (parser->next_offset >= max_size)
1300 break;
1301 size = min(16384, max_size - parser->next_offset);
1303 if ((ret = src_getrange_cb(parser->my_src, NULL, parser->next_offset, size, &buffer)) < 0)
1305 GST_ERROR("Failed to read data, ret %s.", gst_flow_get_name(ret));
1306 break;
1309 parser->next_offset += size;
1311 buffer->duration = buffer->pts = -1;
1312 if ((ret = gst_pad_push(parser->my_src, buffer)) < 0)
1314 GST_ERROR("Failed to push data, ret %s.", gst_flow_get_name(ret));
1315 break;
1319 gst_buffer_unref(buffer);
1321 gst_pad_push_event(parser->my_src, gst_event_new_eos());
1323 GST_DEBUG("Stopping push thread.");
1325 return NULL;
1328 static gboolean activate_push(GstPad *pad, gboolean activate)
1330 struct wg_parser *parser = gst_pad_get_element_private(pad);
1332 if (!activate)
1334 if (parser->push_thread)
1336 pthread_join(parser->push_thread, NULL);
1337 parser->push_thread = 0;
1340 else if (!parser->push_thread)
1342 int ret;
1344 if ((ret = pthread_create(&parser->push_thread, NULL, push_data, parser)))
1346 GST_ERROR("Failed to create push thread: %s", strerror(errno));
1347 parser->push_thread = 0;
1348 return FALSE;
1351 return TRUE;
1354 static gboolean src_activate_mode_cb(GstPad *pad, GstObject *parent, GstPadMode mode, gboolean activate)
1356 struct wg_parser *parser = gst_pad_get_element_private(pad);
1358 GST_DEBUG("%s source pad for parser %p in %s mode.",
1359 activate ? "Activating" : "Deactivating", parser, gst_pad_mode_get_name(mode));
1361 switch (mode)
1363 case GST_PAD_MODE_PULL:
1364 return TRUE;
1365 case GST_PAD_MODE_PUSH:
1366 return activate_push(pad, activate);
1367 case GST_PAD_MODE_NONE:
1368 break;
1370 return FALSE;
1373 static GstBusSyncReply bus_handler_cb(GstBus *bus, GstMessage *msg, gpointer user)
1375 struct wg_parser *parser = user;
1376 gchar *dbg_info = NULL;
1377 GError *err = NULL;
1379 GST_DEBUG("parser %p, message type %s.", parser, GST_MESSAGE_TYPE_NAME(msg));
1381 switch (msg->type)
1383 case GST_MESSAGE_ERROR:
1384 gst_message_parse_error(msg, &err, &dbg_info);
1385 fprintf(stderr, "winegstreamer error: %s: %s\n", GST_OBJECT_NAME(msg->src), err->message);
1386 fprintf(stderr, "winegstreamer error: %s: %s\n", GST_OBJECT_NAME(msg->src), dbg_info);
1387 g_error_free(err);
1388 g_free(dbg_info);
1389 pthread_mutex_lock(&parser->mutex);
1390 parser->error = true;
1391 pthread_mutex_unlock(&parser->mutex);
1392 pthread_cond_signal(&parser->init_cond);
1393 break;
1395 case GST_MESSAGE_WARNING:
1396 gst_message_parse_warning(msg, &err, &dbg_info);
1397 fprintf(stderr, "winegstreamer warning: %s: %s\n", GST_OBJECT_NAME(msg->src), err->message);
1398 fprintf(stderr, "winegstreamer warning: %s: %s\n", GST_OBJECT_NAME(msg->src), dbg_info);
1399 g_error_free(err);
1400 g_free(dbg_info);
1401 break;
1403 case GST_MESSAGE_DURATION_CHANGED:
1404 pthread_mutex_lock(&parser->mutex);
1405 parser->has_duration = true;
1406 pthread_mutex_unlock(&parser->mutex);
1407 pthread_cond_signal(&parser->init_cond);
1408 break;
1410 default:
1411 break;
1413 gst_message_unref(msg);
1414 return GST_BUS_DROP;
1417 static gboolean src_perform_seek(struct wg_parser *parser, GstEvent *event)
1419 BOOL thread = !!parser->push_thread;
1420 GstSeekType cur_type, stop_type;
1421 GstFormat seek_format;
1422 GstEvent *flush_event;
1423 GstSeekFlags flags;
1424 gint64 cur, stop;
1425 guint32 seqnum;
1426 gdouble rate;
1428 gst_event_parse_seek(event, &rate, &seek_format, &flags,
1429 &cur_type, &cur, &stop_type, &stop);
1431 if (seek_format != GST_FORMAT_BYTES)
1433 GST_FIXME("Unhandled format \"%s\".", gst_format_get_name(seek_format));
1434 return FALSE;
1437 seqnum = gst_event_get_seqnum(event);
1439 /* send flush start */
1440 if (flags & GST_SEEK_FLAG_FLUSH)
1442 flush_event = gst_event_new_flush_start();
1443 gst_event_set_seqnum(flush_event, seqnum);
1444 gst_pad_push_event(parser->my_src, flush_event);
1445 if (thread)
1446 gst_pad_set_active(parser->my_src, 1);
1449 parser->next_offset = parser->start_offset = cur;
1451 /* and prepare to continue streaming */
1452 if (flags & GST_SEEK_FLAG_FLUSH)
1454 flush_event = gst_event_new_flush_stop(TRUE);
1455 gst_event_set_seqnum(flush_event, seqnum);
1456 gst_pad_push_event(parser->my_src, flush_event);
1457 if (thread)
1458 gst_pad_set_active(parser->my_src, 1);
1461 return TRUE;
1464 static gboolean src_event_cb(GstPad *pad, GstObject *parent, GstEvent *event)
1466 struct wg_parser *parser = gst_pad_get_element_private(pad);
1467 gboolean ret = TRUE;
1469 GST_LOG("parser %p, type \"%s\".", parser, GST_EVENT_TYPE_NAME(event));
1471 switch (event->type)
1473 case GST_EVENT_SEEK:
1474 ret = src_perform_seek(parser, event);
1475 break;
1477 case GST_EVENT_FLUSH_START:
1478 case GST_EVENT_FLUSH_STOP:
1479 case GST_EVENT_QOS:
1480 case GST_EVENT_RECONFIGURE:
1481 break;
1483 default:
1484 GST_WARNING("Ignoring \"%s\" event.", GST_EVENT_TYPE_NAME(event));
1485 ret = FALSE;
1486 break;
1488 gst_event_unref(event);
1489 return ret;
1492 static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_size)
1494 GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE("quartz_src",
1495 GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY);
1496 unsigned int i;
1498 parser->file_size = file_size;
1499 parser->sink_connected = true;
1501 if (!parser->bus)
1503 parser->bus = gst_bus_new();
1504 gst_bus_set_sync_handler(parser->bus, bus_handler_cb, parser, NULL);
1507 parser->container = gst_bin_new(NULL);
1508 gst_element_set_bus(parser->container, parser->bus);
1510 parser->my_src = gst_pad_new_from_static_template(&src_template, "quartz-src");
1511 gst_pad_set_getrange_function(parser->my_src, src_getrange_cb);
1512 gst_pad_set_query_function(parser->my_src, src_query_cb);
1513 gst_pad_set_activatemode_function(parser->my_src, src_activate_mode_cb);
1514 gst_pad_set_event_function(parser->my_src, src_event_cb);
1515 gst_pad_set_element_private(parser->my_src, parser);
1517 parser->start_offset = parser->next_offset = parser->stop_offset = 0;
1518 parser->next_pull_offset = 0;
1520 if (!parser->init_gst(parser))
1521 return E_FAIL;
1523 pthread_mutex_lock(&parser->mutex);
1525 for (i = 0; i < parser->stream_count; ++i)
1527 struct wg_parser_stream *stream = parser->streams[i];
1528 gint64 duration;
1530 while (!stream->has_caps && !parser->error)
1531 pthread_cond_wait(&parser->init_cond, &parser->mutex);
1533 /* GStreamer doesn't actually provide any guarantees about when duration
1534 * is available, even for seekable streams. It's basically built for
1535 * applications that don't care, e.g. movie players that can display
1536 * a duration once it's available, and update it visually if a better
1537 * estimate is found. This doesn't really match well with DirectShow or
1538 * Media Foundation, which both expect duration to be available
1539 * immediately on connecting, so we have to use some complex heuristics
1540 * to try to actually get a usable duration.
1542 * Some elements (avidemux, wavparse, qtdemux) record duration almost
1543 * immediately, before fixing caps. Such elements don't send
1544 * duration-changed messages. Therefore always try querying duration
1545 * after caps have been found.
1547 * Some elements (mpegaudioparse) send duration-changed. In the case of
1548 * a mp3 stream without seek tables it will not be sent immediately, but
1549 * only after enough frames have been parsed to form an estimate. They
1550 * may send it multiple times with increasingly accurate estimates, but
1551 * unfortunately we have no way of knowing whether another estimate will
1552 * be sent, so we always take the first one. We assume that if the
1553 * duration is not immediately available then the element will always
1554 * send duration-changed.
1557 for (;;)
1559 if (parser->error)
1561 pthread_mutex_unlock(&parser->mutex);
1562 return E_FAIL;
1564 if (gst_pad_query_duration(stream->their_src, GST_FORMAT_TIME, &duration))
1566 stream->duration = duration / 100;
1567 break;
1570 if (stream->eos)
1572 stream->duration = 0;
1573 GST_WARNING("Failed to query duration.\n");
1574 break;
1577 /* Elements based on GstBaseParse send duration-changed before
1578 * actually updating the duration in GStreamer versions prior
1579 * to 1.17.1. See <gstreamer.git:d28e0b4147fe7073b2>. So after
1580 * receiving duration-changed we have to continue polling until
1581 * the query succeeds. */
1582 if (parser->has_duration)
1584 pthread_mutex_unlock(&parser->mutex);
1585 g_usleep(10000);
1586 pthread_mutex_lock(&parser->mutex);
1588 else
1590 pthread_cond_wait(&parser->init_cond, &parser->mutex);
1595 pthread_mutex_unlock(&parser->mutex);
1597 parser->next_offset = 0;
1598 return S_OK;
1601 static void free_stream(struct wg_parser_stream *stream)
1603 if (stream->their_src)
1605 if (stream->post_sink)
1607 gst_pad_unlink(stream->their_src, stream->post_sink);
1608 gst_pad_unlink(stream->post_src, stream->my_sink);
1609 gst_object_unref(stream->post_src);
1610 gst_object_unref(stream->post_sink);
1611 stream->post_src = stream->post_sink = NULL;
1613 else
1614 gst_pad_unlink(stream->their_src, stream->my_sink);
1615 gst_object_unref(stream->their_src);
1617 gst_object_unref(stream->my_sink);
1619 pthread_cond_destroy(&stream->event_cond);
1620 pthread_cond_destroy(&stream->event_empty_cond);
1622 free(stream);
1625 static void CDECL wg_parser_disconnect(struct wg_parser *parser)
1627 unsigned int i;
1629 /* Unblock all of our streams. */
1630 pthread_mutex_lock(&parser->mutex);
1631 for (i = 0; i < parser->stream_count; ++i)
1633 parser->streams[i]->flushing = true;
1634 pthread_cond_signal(&parser->streams[i]->event_empty_cond);
1636 pthread_mutex_unlock(&parser->mutex);
1638 gst_element_set_state(parser->container, GST_STATE_NULL);
1639 gst_pad_unlink(parser->my_src, parser->their_sink);
1640 gst_object_unref(parser->my_src);
1641 gst_object_unref(parser->their_sink);
1642 parser->my_src = parser->their_sink = NULL;
1644 pthread_mutex_lock(&parser->mutex);
1645 parser->sink_connected = false;
1646 pthread_mutex_unlock(&parser->mutex);
1647 pthread_cond_signal(&parser->read_cond);
1649 for (i = 0; i < parser->stream_count; ++i)
1650 free_stream(parser->streams[i]);
1652 parser->stream_count = 0;
1653 free(parser->streams);
1654 parser->streams = NULL;
1656 gst_element_set_bus(parser->container, NULL);
1657 gst_object_unref(parser->container);
1658 parser->container = NULL;
1661 static BOOL decodebin_parser_init_gst(struct wg_parser *parser)
1663 GstElement *element;
1664 int ret;
1666 if (!(element = create_element("decodebin", "base")))
1667 return FALSE;
1669 gst_bin_add(GST_BIN(parser->container), element);
1670 parser->decodebin = element;
1672 g_signal_connect(element, "pad-added", G_CALLBACK(pad_added_cb), parser);
1673 g_signal_connect(element, "pad-removed", G_CALLBACK(pad_removed_cb), parser);
1674 g_signal_connect(element, "autoplug-select", G_CALLBACK(autoplug_select_cb), parser);
1675 g_signal_connect(element, "no-more-pads", G_CALLBACK(no_more_pads_cb), parser);
1677 parser->their_sink = gst_element_get_static_pad(element, "sink");
1679 pthread_mutex_lock(&parser->mutex);
1680 parser->no_more_pads = parser->error = false;
1681 pthread_mutex_unlock(&parser->mutex);
1683 if ((ret = gst_pad_link(parser->my_src, parser->their_sink)) < 0)
1685 GST_ERROR("Failed to link pads, error %d.\n", ret);
1686 return FALSE;
1689 gst_element_set_state(parser->container, GST_STATE_PAUSED);
1690 ret = gst_element_get_state(parser->container, NULL, NULL, -1);
1691 if (ret == GST_STATE_CHANGE_FAILURE)
1693 GST_ERROR("Failed to play stream.\n");
1694 return FALSE;
1697 pthread_mutex_lock(&parser->mutex);
1698 while (!parser->no_more_pads && !parser->error)
1699 pthread_cond_wait(&parser->init_cond, &parser->mutex);
1700 if (parser->error)
1702 pthread_mutex_unlock(&parser->mutex);
1703 return FALSE;
1705 pthread_mutex_unlock(&parser->mutex);
1707 return TRUE;
1710 static BOOL avi_parser_init_gst(struct wg_parser *parser)
1712 GstElement *element;
1713 int ret;
1715 if (!(element = create_element("avidemux", "good")))
1716 return FALSE;
1718 gst_bin_add(GST_BIN(parser->container), element);
1720 g_signal_connect(element, "pad-added", G_CALLBACK(pad_added_cb), parser);
1721 g_signal_connect(element, "pad-removed", G_CALLBACK(pad_removed_cb), parser);
1722 g_signal_connect(element, "no-more-pads", G_CALLBACK(no_more_pads_cb), parser);
1724 parser->their_sink = gst_element_get_static_pad(element, "sink");
1726 pthread_mutex_lock(&parser->mutex);
1727 parser->no_more_pads = parser->error = false;
1728 pthread_mutex_unlock(&parser->mutex);
1730 if ((ret = gst_pad_link(parser->my_src, parser->their_sink)) < 0)
1732 GST_ERROR("Failed to link pads, error %d.\n", ret);
1733 return FALSE;
1736 gst_element_set_state(parser->container, GST_STATE_PAUSED);
1737 ret = gst_element_get_state(parser->container, NULL, NULL, -1);
1738 if (ret == GST_STATE_CHANGE_FAILURE)
1740 GST_ERROR("Failed to play stream.\n");
1741 return FALSE;
1744 pthread_mutex_lock(&parser->mutex);
1745 while (!parser->no_more_pads && !parser->error)
1746 pthread_cond_wait(&parser->init_cond, &parser->mutex);
1747 if (parser->error)
1749 pthread_mutex_unlock(&parser->mutex);
1750 return FALSE;
1752 pthread_mutex_unlock(&parser->mutex);
1754 return TRUE;
1757 static BOOL mpeg_audio_parser_init_gst(struct wg_parser *parser)
1759 struct wg_parser_stream *stream;
1760 GstElement *element;
1761 int ret;
1763 if (!(element = create_element("mpegaudioparse", "good")))
1764 return FALSE;
1766 gst_bin_add(GST_BIN(parser->container), element);
1768 parser->their_sink = gst_element_get_static_pad(element, "sink");
1769 if ((ret = gst_pad_link(parser->my_src, parser->their_sink)) < 0)
1771 GST_ERROR("Failed to link sink pads, error %d.\n", ret);
1772 return FALSE;
1775 if (!(stream = create_stream(parser)))
1776 return FALSE;
1778 gst_object_ref(stream->their_src = gst_element_get_static_pad(element, "src"));
1779 if ((ret = gst_pad_link(stream->their_src, stream->my_sink)) < 0)
1781 GST_ERROR("Failed to link source pads, error %d.\n", ret);
1782 return FALSE;
1785 gst_pad_set_active(stream->my_sink, 1);
1786 gst_element_set_state(parser->container, GST_STATE_PAUSED);
1787 ret = gst_element_get_state(parser->container, NULL, NULL, -1);
1788 if (ret == GST_STATE_CHANGE_FAILURE)
1790 GST_ERROR("Failed to play stream.\n");
1791 return FALSE;
1794 return TRUE;
1797 static BOOL wave_parser_init_gst(struct wg_parser *parser)
1799 struct wg_parser_stream *stream;
1800 GstElement *element;
1801 int ret;
1803 if (!(element = create_element("wavparse", "good")))
1804 return FALSE;
1806 gst_bin_add(GST_BIN(parser->container), element);
1808 parser->their_sink = gst_element_get_static_pad(element, "sink");
1809 if ((ret = gst_pad_link(parser->my_src, parser->their_sink)) < 0)
1811 GST_ERROR("Failed to link sink pads, error %d.\n", ret);
1812 return FALSE;
1815 if (!(stream = create_stream(parser)))
1816 return FALSE;
1818 stream->their_src = gst_element_get_static_pad(element, "src");
1819 gst_object_ref(stream->their_src);
1820 if ((ret = gst_pad_link(stream->their_src, stream->my_sink)) < 0)
1822 GST_ERROR("Failed to link source pads, error %d.\n", ret);
1823 return FALSE;
1826 gst_pad_set_active(stream->my_sink, 1);
1827 gst_element_set_state(parser->container, GST_STATE_PAUSED);
1828 ret = gst_element_get_state(parser->container, NULL, NULL, -1);
1829 if (ret == GST_STATE_CHANGE_FAILURE)
1831 GST_ERROR("Failed to play stream.\n");
1832 return FALSE;
1835 return TRUE;
1838 static struct wg_parser *wg_parser_create(void)
1840 struct wg_parser *parser;
1842 if (!(parser = calloc(1, sizeof(*parser))))
1843 return NULL;
1845 pthread_mutex_init(&parser->mutex, NULL);
1846 pthread_cond_init(&parser->init_cond, NULL);
1847 pthread_cond_init(&parser->read_cond, NULL);
1848 pthread_cond_init(&parser->read_done_cond, NULL);
1849 parser->flushing = true;
1851 GST_DEBUG("Created winegstreamer parser %p.\n", parser);
1852 return parser;
1855 static struct wg_parser * CDECL wg_decodebin_parser_create(void)
1857 struct wg_parser *parser;
1859 if ((parser = wg_parser_create()))
1860 parser->init_gst = decodebin_parser_init_gst;
1861 return parser;
1864 static struct wg_parser * CDECL wg_avi_parser_create(void)
1866 struct wg_parser *parser;
1868 if ((parser = wg_parser_create()))
1869 parser->init_gst = avi_parser_init_gst;
1870 return parser;
1873 static struct wg_parser * CDECL wg_mpeg_audio_parser_create(void)
1875 struct wg_parser *parser;
1877 if ((parser = wg_parser_create()))
1878 parser->init_gst = mpeg_audio_parser_init_gst;
1879 return parser;
1882 static struct wg_parser * CDECL wg_wave_parser_create(void)
1884 struct wg_parser *parser;
1886 if ((parser = wg_parser_create()))
1887 parser->init_gst = wave_parser_init_gst;
1888 return parser;
1891 static void CDECL wg_parser_destroy(struct wg_parser *parser)
1893 if (parser->bus)
1895 gst_bus_set_sync_handler(parser->bus, NULL, NULL, NULL);
1896 gst_object_unref(parser->bus);
1899 pthread_mutex_destroy(&parser->mutex);
1900 pthread_cond_destroy(&parser->init_cond);
1901 pthread_cond_destroy(&parser->read_cond);
1902 pthread_cond_destroy(&parser->read_done_cond);
1904 free(parser);
1907 static const struct unix_funcs funcs =
1909 wg_decodebin_parser_create,
1910 wg_avi_parser_create,
1911 wg_mpeg_audio_parser_create,
1912 wg_wave_parser_create,
1913 wg_parser_destroy,
1915 wg_parser_connect,
1916 wg_parser_disconnect,
1918 wg_parser_begin_flush,
1919 wg_parser_end_flush,
1921 wg_parser_get_read_request,
1922 wg_parser_complete_read_request,
1924 wg_parser_set_unlimited_buffering,
1926 wg_parser_get_stream_count,
1927 wg_parser_get_stream,
1929 wg_parser_stream_get_preferred_format,
1930 wg_parser_stream_enable,
1931 wg_parser_stream_disable,
1933 wg_parser_stream_get_event,
1934 wg_parser_stream_copy_buffer,
1935 wg_parser_stream_release_buffer,
1936 wg_parser_stream_notify_qos,
1938 wg_parser_stream_get_duration,
1939 wg_parser_stream_seek,
1942 NTSTATUS CDECL __wine_init_unix_lib(HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out)
1944 if (reason == DLL_PROCESS_ATTACH)
1946 char arg0[] = "wine";
1947 char arg1[] = "--gst-disable-registry-fork";
1948 char *args[] = {arg0, arg1, NULL};
1949 int argc = ARRAY_SIZE(args) - 1;
1950 char **argv = args;
1951 GError *err;
1953 if (!gst_init_check(&argc, &argv, &err))
1955 fprintf(stderr, "winegstreamer: failed to initialize GStreamer: %s\n", debugstr_a(err->message));
1956 g_error_free(err);
1957 return STATUS_UNSUCCESSFUL;
1960 GST_DEBUG_CATEGORY_INIT(wine, "WINE", GST_DEBUG_FG_RED, "Wine GStreamer support");
1962 GST_INFO("GStreamer library version %s; wine built with %d.%d.%d.\n",
1963 gst_version_string(), GST_VERSION_MAJOR, GST_VERSION_MINOR, GST_VERSION_MICRO);
1965 *(const struct unix_funcs **)ptr_out = &funcs;
1967 return STATUS_SUCCESS;