fbffee601cf936e71fd2857759dd34bb393cb825
[WebKit-https.git] / Source / WebCore / platform / graphics / gstreamer / InbandTextTrackPrivateGStreamer.cpp
1 /*
2  * Copyright (C) 2013 Cable Television Laboratories, Inc.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27
28 #if ENABLE(VIDEO) && USE(GSTREAMER) && ENABLE(VIDEO_TRACK)
29
30 #include "InbandTextTrackPrivateGStreamer.h"
31
32 #include "GStreamerCommon.h"
33 #include "Logging.h"
34 #include <glib-object.h>
35 #include <gst/gst.h>
36
37 GST_DEBUG_CATEGORY_EXTERN(webkit_media_player_debug);
38 #define GST_CAT_DEFAULT webkit_media_player_debug
39
40 namespace WebCore {
41
42 InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstPad> pad)
43     : InbandTextTrackPrivate(WebVTT)
44     , TrackPrivateBaseGStreamer(this, index, pad)
45 {
46     m_eventProbe = gst_pad_add_probe(m_pad.get(), GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, [] (GstPad*, GstPadProbeInfo* info, gpointer userData) -> GstPadProbeReturn {
47         auto* track = static_cast<InbandTextTrackPrivateGStreamer*>(userData);
48         switch (GST_EVENT_TYPE(gst_pad_probe_info_get_event(info))) {
49         case GST_EVENT_STREAM_START:
50             track->streamChanged();
51             break;
52         default:
53             break;
54         }
55         return GST_PAD_PROBE_OK;
56     }, this, nullptr);
57
58     notifyTrackOfStreamChanged();
59 }
60
61 #if GST_CHECK_VERSION(1, 10, 0)
62 InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstStream> stream)
63     : InbandTextTrackPrivate(WebVTT)
64     , TrackPrivateBaseGStreamer(this, index, stream)
65 {
66     m_streamId = gst_stream_get_stream_id(stream.get());
67     GST_INFO("Track %d got stream start for stream %s.", m_index, m_streamId.utf8().data());
68 }
69 #endif
70
71 void InbandTextTrackPrivateGStreamer::disconnect()
72 {
73     if (m_pad)
74         gst_pad_remove_probe(m_pad.get(), m_eventProbe);
75
76     TrackPrivateBaseGStreamer::disconnect();
77 }
78
79 void InbandTextTrackPrivateGStreamer::handleSample(GRefPtr<GstSample> sample)
80 {
81     {
82         LockHolder lock(m_sampleMutex);
83         m_pendingSamples.append(sample);
84     }
85
86     RefPtr<InbandTextTrackPrivateGStreamer> protectedThis(this);
87     m_notifier->notify(MainThreadNotification::NewSample, [protectedThis] {
88         protectedThis->notifyTrackOfSample();
89     });
90 }
91
92 void InbandTextTrackPrivateGStreamer::streamChanged()
93 {
94     RefPtr<InbandTextTrackPrivateGStreamer> protectedThis(this);
95     m_notifier->notify(MainThreadNotification::StreamChanged, [protectedThis] {
96         protectedThis->notifyTrackOfStreamChanged();
97     });
98 }
99
100 void InbandTextTrackPrivateGStreamer::notifyTrackOfSample()
101 {
102     Vector<GRefPtr<GstSample> > samples;
103     {
104         LockHolder lock(m_sampleMutex);
105         m_pendingSamples.swap(samples);
106     }
107
108     for (size_t i = 0; i < samples.size(); ++i) {
109         GRefPtr<GstSample> sample = samples[i];
110         GstBuffer* buffer = gst_sample_get_buffer(sample.get());
111         if (!buffer) {
112             GST_WARNING("Track %d got sample with no buffer.", m_index);
113             continue;
114         }
115         auto mappedBuffer = GstMappedBuffer::create(buffer, GST_MAP_READ);
116         ASSERT(mappedBuffer);
117         if (!mappedBuffer) {
118             GST_WARNING("Track %d unable to map buffer.", m_index);
119             continue;
120         }
121
122         GST_INFO("Track %d parsing sample: %.*s", m_index, static_cast<int>(mappedBuffer->size()),
123             reinterpret_cast<char*>(mappedBuffer->data()));
124         client()->parseWebVTTCueData(reinterpret_cast<char*>(mappedBuffer->data()), mappedBuffer->size());
125     }
126 }
127
128 void InbandTextTrackPrivateGStreamer::notifyTrackOfStreamChanged()
129 {
130     GRefPtr<GstEvent> event = adoptGRef(gst_pad_get_sticky_event(m_pad.get(),
131         GST_EVENT_STREAM_START, 0));
132     if (!event)
133         return;
134
135     const gchar* streamId;
136     gst_event_parse_stream_start(event.get(), &streamId);
137     GST_INFO("Track %d got stream start for stream %s.", m_index, streamId);
138     m_streamId = streamId;
139 }
140
141 } // namespace WebCore
142
143 #endif // ENABLE(VIDEO) && USE(GSTREAMER) && ENABLE(VIDEO_TRACK)