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 "GStreamerUtilities.h" 33#include "Logging.h" 34#include <glib-object.h> 35#include <gst/gst.h> 36 37GST_DEBUG_CATEGORY_EXTERN(webkit_media_player_debug); 38#define GST_CAT_DEFAULT webkit_media_player_debug 39 40namespace WebCore { 41 42static GstPadProbeReturn textTrackPrivateEventCallback(GstPad*, GstPadProbeInfo* info, InbandTextTrackPrivateGStreamer* track) 43{ 44 GstEvent* event = gst_pad_probe_info_get_event(info); 45 switch (GST_EVENT_TYPE(event)) { 46 case GST_EVENT_STREAM_START: 47 track->streamChanged(); 48 break; 49 default: 50 break; 51 } 52 return GST_PAD_PROBE_OK; 53} 54 55InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstPad> pad) 56 : InbandTextTrackPrivate(WebVTT), TrackPrivateBaseGStreamer(this, index, pad) 57{ 58 m_eventProbe = gst_pad_add_probe(m_pad.get(), GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, 59 reinterpret_cast<GstPadProbeCallback>(textTrackPrivateEventCallback), this, 0); 60 61 notifyTrackOfStreamChanged(); 62} 63 64void InbandTextTrackPrivateGStreamer::disconnect() 65{ 66 if (!m_pad) 67 return; 68 69 gst_pad_remove_probe(m_pad.get(), m_eventProbe); 70 71 m_streamTimerHandler.cancel(); 72 73 TrackPrivateBaseGStreamer::disconnect(); 74} 75 76void InbandTextTrackPrivateGStreamer::handleSample(GRefPtr<GstSample> sample) 77{ 78 m_sampleTimerHandler.cancel(); 79 { 80 MutexLocker lock(m_sampleMutex); 81 m_pendingSamples.append(sample); 82 } 83 m_sampleTimerHandler.schedule("[WebKit] InbandTextTrackPrivateGStreamer::notifyTrackOfSample", std::function<void()>(std::bind(&InbandTextTrackPrivateGStreamer::notifyTrackOfSample, this))); 84} 85 86void InbandTextTrackPrivateGStreamer::streamChanged() 87{ 88 m_streamTimerHandler.schedule("[WebKit] InbandTextTrackPrivateGStreamer::notifyTrackOfStreamChanged", std::function<void()>(std::bind(&InbandTextTrackPrivateGStreamer::notifyTrackOfStreamChanged, this))); 89} 90 91void InbandTextTrackPrivateGStreamer::notifyTrackOfSample() 92{ 93 Vector<GRefPtr<GstSample> > samples; 94 { 95 MutexLocker lock(m_sampleMutex); 96 m_pendingSamples.swap(samples); 97 } 98 99 for (size_t i = 0; i < samples.size(); ++i) { 100 GRefPtr<GstSample> sample = samples[i]; 101 GstBuffer* buffer = gst_sample_get_buffer(sample.get()); 102 if (!buffer) { 103 WARN_MEDIA_MESSAGE("Track %d got sample with no buffer.", m_index); 104 continue; 105 } 106 GstMapInfo info; 107 gboolean ret = gst_buffer_map(buffer, &info, GST_MAP_READ); 108 ASSERT(ret); 109 if (!ret) { 110 WARN_MEDIA_MESSAGE("Track %d unable to map buffer.", m_index); 111 continue; 112 } 113 114 INFO_MEDIA_MESSAGE("Track %d parsing sample: %.*s", m_index, static_cast<int>(info.size), 115 reinterpret_cast<char*>(info.data)); 116 client()->parseWebVTTCueData(this, reinterpret_cast<char*>(info.data), info.size); 117 gst_buffer_unmap(buffer, &info); 118 } 119} 120 121void InbandTextTrackPrivateGStreamer::notifyTrackOfStreamChanged() 122{ 123 GRefPtr<GstEvent> event = adoptGRef(gst_pad_get_sticky_event(m_pad.get(), 124 GST_EVENT_STREAM_START, 0)); 125 if (!event) 126 return; 127 128 const gchar* streamId; 129 gst_event_parse_stream_start(event.get(), &streamId); 130 INFO_MEDIA_MESSAGE("Track %d got stream start for stream %s.", m_index, streamId); 131 m_streamId = streamId; 132} 133 134} // namespace WebCore 135 136#endif // ENABLE(VIDEO) && USE(GSTREAMER) && ENABLE(VIDEO_TRACK) 137