18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2007 Collabora Ltd. All rights reserved. 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2007 Alp Toker <alp@atoker.com> 5231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Copyright (C) 2009 Gustavo Noronha Silva <gns@gnome.org> 6692e5dbf12901edacf14812a6fae25462920af42Steve Block * Copyright (C) 2009, 2010 Igalia S.L 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version. 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful, 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details. 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * aint with this library; see the file COPYING.LIB. If not, write to 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA. 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "MediaPlayerPrivateGStreamer.h" 2668513a70bcd92384395513322f1b801e7bf9c729Steve Block 27bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GSTREAMER) 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "ColorSpace.h" 30d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "Document.h" 31d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "Frame.h" 32d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "FrameView.h" 33dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "GOwnPtrGStreamer.h" 34e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#include "GStreamerGWorld.h" 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "GraphicsContext.h" 36dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "GraphicsTypes.h" 37dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "ImageGStreamer.h" 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "IntRect.h" 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "KURL.h" 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "MIMETypeRegistry.h" 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "MediaPlayer.h" 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "NotImplemented.h" 43d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "SecurityOrigin.h" 44cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#include "TimeRanges.h" 450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "VideoSinkGStreamer.h" 468a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#include "WebKitWebSourceGStreamer.h" 47dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <GOwnPtr.h> 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <gst/gst.h> 4981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include <gst/interfaces/streamvolume.h> 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <gst/video/video.h> 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <limits> 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <math.h> 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 54692e5dbf12901edacf14812a6fae25462920af42Steve Block// GstPlayFlags flags from playbin2. It is the policy of GStreamer to 55692e5dbf12901edacf14812a6fae25462920af42Steve Block// not publicly expose element-specific enums. That's why this 56692e5dbf12901edacf14812a6fae25462920af42Steve Block// GstPlayFlags enum has been copied here. 57692e5dbf12901edacf14812a6fae25462920af42Steve Blocktypedef enum { 58692e5dbf12901edacf14812a6fae25462920af42Steve Block GST_PLAY_FLAG_VIDEO = 0x00000001, 59692e5dbf12901edacf14812a6fae25462920af42Steve Block GST_PLAY_FLAG_AUDIO = 0x00000002, 60692e5dbf12901edacf14812a6fae25462920af42Steve Block GST_PLAY_FLAG_TEXT = 0x00000004, 61692e5dbf12901edacf14812a6fae25462920af42Steve Block GST_PLAY_FLAG_VIS = 0x00000008, 62692e5dbf12901edacf14812a6fae25462920af42Steve Block GST_PLAY_FLAG_SOFT_VOLUME = 0x00000010, 63692e5dbf12901edacf14812a6fae25462920af42Steve Block GST_PLAY_FLAG_NATIVE_AUDIO = 0x00000020, 64692e5dbf12901edacf14812a6fae25462920af42Steve Block GST_PLAY_FLAG_NATIVE_VIDEO = 0x00000040, 65692e5dbf12901edacf14812a6fae25462920af42Steve Block GST_PLAY_FLAG_DOWNLOAD = 0x00000080, 66692e5dbf12901edacf14812a6fae25462920af42Steve Block GST_PLAY_FLAG_BUFFERING = 0x000000100 67692e5dbf12901edacf14812a6fae25462920af42Steve Block} GstPlayFlags; 68692e5dbf12901edacf14812a6fae25462920af42Steve Block 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std; 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 73692e5dbf12901edacf14812a6fae25462920af42Steve Blockstatic int greatestCommonDivisor(int a, int b) 74692e5dbf12901edacf14812a6fae25462920af42Steve Block{ 75692e5dbf12901edacf14812a6fae25462920af42Steve Block while (b) { 76692e5dbf12901edacf14812a6fae25462920af42Steve Block int temp = a; 77692e5dbf12901edacf14812a6fae25462920af42Steve Block a = b; 78692e5dbf12901edacf14812a6fae25462920af42Steve Block b = temp % b; 79692e5dbf12901edacf14812a6fae25462920af42Steve Block } 80692e5dbf12901edacf14812a6fae25462920af42Steve Block 81692e5dbf12901edacf14812a6fae25462920af42Steve Block return ABS(a); 82692e5dbf12901edacf14812a6fae25462920af42Steve Block} 83692e5dbf12901edacf14812a6fae25462920af42Steve Block 842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic gboolean mediaPlayerPrivateMessageCallback(GstBus*, GstMessage* message, MediaPlayerPrivateGStreamer* player) 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return player->handleMessage(message); 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic void mediaPlayerPrivateSourceChangedCallback(GObject*, GParamSpec*, MediaPlayerPrivateGStreamer* player) 90d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch player->sourceChanged(); 92d0825bca7fe65beaee391d30da42e937db621564Steve Block} 93d0825bca7fe65beaee391d30da42e937db621564Steve Block 942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic void mediaPlayerPrivateVolumeChangedCallback(GObject*, GParamSpec*, MediaPlayerPrivateGStreamer* player) 95d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 965e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block // This is called when playbin receives the notify::volume signal. 972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch player->volumeChanged(); 98d0825bca7fe65beaee391d30da42e937db621564Steve Block} 99d0825bca7fe65beaee391d30da42e937db621564Steve Block 1002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic gboolean mediaPlayerPrivateVolumeChangeTimeoutCallback(MediaPlayerPrivateGStreamer* player) 101f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 102f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // This is the callback of the timeout source created in ::volumeChanged. 103f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch player->notifyPlayerOfVolumeChange(); 104f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return FALSE; 105f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 106f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic void mediaPlayerPrivateMuteChangedCallback(GObject*, GParamSpec*, MediaPlayerPrivateGStreamer* player) 1085e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 1095e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block // This is called when playbin receives the notify::mute signal. 1102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch player->muteChanged(); 1115e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 1125e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 1132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic gboolean mediaPlayerPrivateMuteChangeTimeoutCallback(MediaPlayerPrivateGStreamer* player) 114f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 115f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // This is the callback of the timeout source created in ::muteChanged. 116f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch player->notifyPlayerOfMute(); 117f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return FALSE; 118f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 119f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic void mediaPlayerPrivateVideoSinkCapsChangedCallback(GObject*, GParamSpec*, MediaPlayerPrivateGStreamer* player) 121f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 1222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch player->videoChanged(); 123f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 124f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic void mediaPlayerPrivateVideoChangedCallback(GObject*, MediaPlayerPrivateGStreamer* player) 126f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 1272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch player->videoChanged(); 128f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 129f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic void mediaPlayerPrivateAudioChangedCallback(GObject*, MediaPlayerPrivateGStreamer* player) 131f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 1322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch player->audioChanged(); 133f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 134f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic gboolean mediaPlayerPrivateAudioChangeTimeoutCallback(MediaPlayerPrivateGStreamer* player) 136f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 1372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // This is the callback of the timeout source created in ::audioChanged. 1382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch player->notifyPlayerOfAudio(); 139f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return FALSE; 140f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 141f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic gboolean mediaPlayerPrivateVideoChangeTimeoutCallback(MediaPlayerPrivateGStreamer* player) 143643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 1442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // This is the callback of the timeout source created in ::videoChanged. 1452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch player->notifyPlayerOfVideo(); 1462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return FALSE; 147643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 148643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 1492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic void mediaPlayerPrivateRepaintCallback(WebKitVideoSink*, GstBuffer *buffer, MediaPlayerPrivateGStreamer* playerPrivate) 1508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 1512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch playerPrivate->triggerRepaint(buffer); 1528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 1538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 154dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockMediaPlayerPrivateInterface* MediaPlayerPrivateGStreamer::create(MediaPlayer* player) 1550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 156dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return new MediaPlayerPrivateGStreamer(player); 1578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 1588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 159dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::registerMediaEngine(MediaEngineRegistrar registrar) 1608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 1618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (isAvailable()) 16281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch registrar(create, getSupportedTypes, supportsType, 0, 0, 0); 1638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 1648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 165231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic bool gstInitialized = false; 166231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 167d0825bca7fe65beaee391d30da42e937db621564Steve Blockstatic bool doGstInit() 168cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 169231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // FIXME: We should pass the arguments from the command line 170231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!gstInitialized) { 171643ca7872b450ea4efacab6188849e5aac2ba161Steve Block GOwnPtr<GError> error; 172643ca7872b450ea4efacab6188849e5aac2ba161Steve Block gstInitialized = gst_init_check(0, 0, &error.outPtr()); 173f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!gstInitialized) 174643ca7872b450ea4efacab6188849e5aac2ba161Steve Block LOG_VERBOSE(Media, "Could not initialize GStreamer: %s", 175643ca7872b450ea4efacab6188849e5aac2ba161Steve Block error ? error->message : "unknown error occurred"); 176f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch else 1778a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block gst_element_register(0, "webkitwebsrc", GST_RANK_PRIMARY + 100, 1788a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block WEBKIT_TYPE_WEB_SRC); 179231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 180643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return gstInitialized; 181643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 182643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 183dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool MediaPlayerPrivateGStreamer::isAvailable() 184643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 185d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!doGstInit()) 186643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return false; 187643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 188643ca7872b450ea4efacab6188849e5aac2ba161Steve Block GstElementFactory* factory = gst_element_factory_find("playbin2"); 189643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (factory) { 190643ca7872b450ea4efacab6188849e5aac2ba161Steve Block gst_object_unref(GST_OBJECT(factory)); 191643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return true; 192643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 193643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return false; 194231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 195231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 196dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockMediaPlayerPrivateGStreamer::MediaPlayerPrivateGStreamer(MediaPlayer* player) 1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project : m_player(player) 1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_playBin(0) 19906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen , m_webkitVideoSink(0) 200d0825bca7fe65beaee391d30da42e937db621564Steve Block , m_fpsSink(0) 2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_source(0) 202643ca7872b450ea4efacab6188849e5aac2ba161Steve Block , m_seekTime(0) 203643ca7872b450ea4efacab6188849e5aac2ba161Steve Block , m_changingRate(false) 2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_endTime(numeric_limits<float>::infinity()) 2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_networkState(MediaPlayer::Empty) 2068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian , m_readyState(MediaPlayer::HaveNothing) 2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_isStreaming(false) 2088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian , m_size(IntSize()) 209cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block , m_buffer(0) 210d0825bca7fe65beaee391d30da42e937db621564Steve Block , m_mediaLocations(0) 211d0825bca7fe65beaee391d30da42e937db621564Steve Block , m_mediaLocationCurrentIndex(0) 212d0825bca7fe65beaee391d30da42e937db621564Steve Block , m_resetPipeline(false) 213231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block , m_paused(true) 214231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block , m_seeking(false) 215dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block , m_buffering(false) 216d0825bca7fe65beaee391d30da42e937db621564Steve Block , m_playbackRate(1) 217231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block , m_errorOccured(false) 218692e5dbf12901edacf14812a6fae25462920af42Steve Block , m_mediaDuration(0) 219692e5dbf12901edacf14812a6fae25462920af42Steve Block , m_startedBuffering(false) 220dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block , m_fillTimer(this, &MediaPlayerPrivateGStreamer::fillTimerFired) 221692e5dbf12901edacf14812a6fae25462920af42Steve Block , m_maxTimeLoaded(0) 222dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block , m_bufferingPercentage(0) 223dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block , m_preload(MediaPlayer::Auto) 224dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block , m_delayingLoad(false) 225dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block , m_mediaDurationKnown(true) 226f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch , m_volumeTimerHandler(0) 227f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch , m_muteTimerHandler(0) 228f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch , m_hasVideo(false) 229f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch , m_hasAudio(false) 2302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_audioTimerHandler(0) 2312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_videoTimerHandler(0) 2322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch , m_webkitAudioSink(0) 2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 234692e5dbf12901edacf14812a6fae25462920af42Steve Block if (doGstInit()) 235692e5dbf12901edacf14812a6fae25462920af42Steve Block createGSTPlayBin(); 236231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 237231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 238dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockMediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer() 2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 240dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (m_fillTimer.isActive()) 241dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_fillTimer.stop(); 242d0825bca7fe65beaee391d30da42e937db621564Steve Block 243cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (m_buffer) 244cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block gst_buffer_unref(m_buffer); 245cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block m_buffer = 0; 2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 247d0825bca7fe65beaee391d30da42e937db621564Steve Block if (m_mediaLocations) { 248d0825bca7fe65beaee391d30da42e937db621564Steve Block gst_structure_free(m_mediaLocations); 249d0825bca7fe65beaee391d30da42e937db621564Steve Block m_mediaLocations = 0; 250d0825bca7fe65beaee391d30da42e937db621564Steve Block } 251d0825bca7fe65beaee391d30da42e937db621564Steve Block 252d0825bca7fe65beaee391d30da42e937db621564Steve Block if (m_source) { 253d0825bca7fe65beaee391d30da42e937db621564Steve Block gst_object_unref(m_source); 254d0825bca7fe65beaee391d30da42e937db621564Steve Block m_source = 0; 255d0825bca7fe65beaee391d30da42e937db621564Steve Block } 256d0825bca7fe65beaee391d30da42e937db621564Steve Block 25706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (m_videoSinkBin) { 25806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen gst_object_unref(m_videoSinkBin); 25906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen m_videoSinkBin = 0; 26006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen } 26106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_playBin) { 2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gst_element_set_state(m_playBin, GST_STATE_NULL); 2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gst_object_unref(GST_OBJECT(m_playBin)); 265f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_playBin = 0; 2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 267231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 268f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_player = 0; 269f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 270f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (m_muteTimerHandler) 271f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch g_source_remove(m_muteTimerHandler); 272f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 273f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (m_volumeTimerHandler) 274f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch g_source_remove(m_volumeTimerHandler); 275f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 2762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_videoTimerHandler) 2772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch g_source_remove(m_videoTimerHandler); 278f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 2792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_audioTimerHandler) 2802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch g_source_remove(m_audioTimerHandler); 2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 283dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::load(const String& url) 2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 285dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block g_object_set(m_playBin, "uri", url.utf8().data(), NULL); 286dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_VERBOSE(Media, "Load %s", url.utf8().data()); 288dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 289dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (m_preload == MediaPlayer::None) { 290dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block LOG_VERBOSE(Media, "Delaying load."); 291dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_delayingLoad = true; 292dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 293dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 294dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // GStreamer needs to have the pipeline set to a paused state to 295dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // start providing anything useful. 296dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gst_element_set_state(m_playBin, GST_STATE_PAUSED); 297dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 298f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!m_delayingLoad) 299f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch commitLoad(); 300f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 301f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 302f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid MediaPlayerPrivateGStreamer::commitLoad() 303f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 304f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch ASSERT(!m_delayingLoad); 305dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block LOG_VERBOSE(Media, "Committing load."); 306f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch updateStates(); 3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochfloat MediaPlayerPrivateGStreamer::playbackPosition() const 3102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 3112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch float ret = 0.0f; 3122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 3132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch GstQuery* query = gst_query_new_position(GST_FORMAT_TIME); 3142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!gst_element_query(m_playBin, query)) { 3152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_VERBOSE(Media, "Position query failed..."); 3162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch gst_query_unref(query); 3172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 3182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 3192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 3202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch gint64 position; 3212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch gst_query_parse_position(query, 0, &position); 3222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 3232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // Position is available only if the pipeline is not in GST_STATE_NULL or 3242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // GST_STATE_READY state. 3252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (position != static_cast<gint64>(GST_CLOCK_TIME_NONE)) 3262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ret = static_cast<float>(position) / static_cast<float>(GST_SECOND); 3272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 3282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_VERBOSE(Media, "Position %" GST_TIME_FORMAT, GST_TIME_ARGS(position)); 3292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 3302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch gst_query_unref(query); 3312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 3322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return ret; 3332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 3342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 335dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool MediaPlayerPrivateGStreamer::changePipelineState(GstState newState) 3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 337d0825bca7fe65beaee391d30da42e937db621564Steve Block ASSERT(newState == GST_STATE_PLAYING || newState == GST_STATE_PAUSED); 338d0825bca7fe65beaee391d30da42e937db621564Steve Block 339d0825bca7fe65beaee391d30da42e937db621564Steve Block GstState currentState; 340643ca7872b450ea4efacab6188849e5aac2ba161Steve Block GstState pending; 341643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 342d0825bca7fe65beaee391d30da42e937db621564Steve Block gst_element_get_state(m_playBin, ¤tState, &pending, 0); 343d0825bca7fe65beaee391d30da42e937db621564Steve Block if (currentState != newState && pending != newState) { 344d0825bca7fe65beaee391d30da42e937db621564Steve Block GstStateChangeReturn ret = gst_element_set_state(m_playBin, newState); 345d0825bca7fe65beaee391d30da42e937db621564Steve Block GstState pausedOrPlaying = newState == GST_STATE_PLAYING ? GST_STATE_PAUSED : GST_STATE_PLAYING; 346d0825bca7fe65beaee391d30da42e937db621564Steve Block if (currentState != pausedOrPlaying && ret == GST_STATE_CHANGE_FAILURE) { 347d0825bca7fe65beaee391d30da42e937db621564Steve Block loadingFailed(MediaPlayer::Empty); 348d0825bca7fe65beaee391d30da42e937db621564Steve Block return false; 349d0825bca7fe65beaee391d30da42e937db621564Steve Block } 350643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 351d0825bca7fe65beaee391d30da42e937db621564Steve Block return true; 3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 354dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::prepareToPlay() 355dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 356dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (m_delayingLoad) { 357dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_delayingLoad = false; 358dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block commitLoad(); 359dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 360dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 361dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 362dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::play() 3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 364d0825bca7fe65beaee391d30da42e937db621564Steve Block if (changePipelineState(GST_STATE_PLAYING)) 365d0825bca7fe65beaee391d30da42e937db621564Steve Block LOG_VERBOSE(Media, "Play"); 366d0825bca7fe65beaee391d30da42e937db621564Steve Block} 367643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 368dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::pause() 369d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 370d0825bca7fe65beaee391d30da42e937db621564Steve Block if (changePipelineState(GST_STATE_PAUSED)) 371643ca7872b450ea4efacab6188849e5aac2ba161Steve Block LOG_VERBOSE(Media, "Pause"); 3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 374dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockfloat MediaPlayerPrivateGStreamer::duration() const 3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_playBin) 3775af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return 0.0f; 3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 379231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_errorOccured) 3805af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return 0.0f; 381231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 382dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Media duration query failed already, don't attempt new useless queries. 383dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!m_mediaDurationKnown) 384dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return numeric_limits<float>::infinity(); 385dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 386d0825bca7fe65beaee391d30da42e937db621564Steve Block if (m_mediaDuration) 387d0825bca7fe65beaee391d30da42e937db621564Steve Block return m_mediaDuration; 388d0825bca7fe65beaee391d30da42e937db621564Steve Block 3898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian GstFormat timeFormat = GST_FORMAT_TIME; 3908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian gint64 timeLength = 0; 3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 392643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!gst_element_query_duration(m_playBin, &timeFormat, &timeLength) || timeFormat != GST_FORMAT_TIME || static_cast<guint64>(timeLength) == GST_CLOCK_TIME_NONE) { 3938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian LOG_VERBOSE(Media, "Time duration query failed."); 3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return numeric_limits<float>::infinity(); 3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 3978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian LOG_VERBOSE(Media, "Duration: %" GST_TIME_FORMAT, GST_TIME_ARGS(timeLength)); 3988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 399cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return (float) ((guint64) timeLength / 1000000000.0); 4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: handle 3.14.9.5 properly 4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 403dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockfloat MediaPlayerPrivateGStreamer::currentTime() const 4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_playBin) 4065af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return 0.0f; 4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 408231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_errorOccured) 4095af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return 0.0f; 410231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 411643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (m_seeking) 4122bde8e466a4451c7319e3a072d118917957d6554Steve Block return m_seekTime; 4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return playbackPosition(); 415231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 418dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::seek(float time) 4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 420d0825bca7fe65beaee391d30da42e937db621564Steve Block // Avoid useless seeking. 4212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (time == playbackPosition()) 422d0825bca7fe65beaee391d30da42e937db621564Steve Block return; 4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_playBin) 4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 427231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_errorOccured) 428231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 429231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 4302bde8e466a4451c7319e3a072d118917957d6554Steve Block // Extract the integer part of the time (seconds) and the 4312bde8e466a4451c7319e3a072d118917957d6554Steve Block // fractional part (microseconds). Attempt to round the 4322bde8e466a4451c7319e3a072d118917957d6554Steve Block // microseconds so no floating point precision is lost and we can 4332bde8e466a4451c7319e3a072d118917957d6554Steve Block // perform an accurate seek. 4342bde8e466a4451c7319e3a072d118917957d6554Steve Block float seconds; 4352bde8e466a4451c7319e3a072d118917957d6554Steve Block float microSeconds = modf(time, &seconds) * 1000000; 4362bde8e466a4451c7319e3a072d118917957d6554Steve Block GTimeVal timeValue; 4372bde8e466a4451c7319e3a072d118917957d6554Steve Block timeValue.tv_sec = static_cast<glong>(seconds); 4382bde8e466a4451c7319e3a072d118917957d6554Steve Block timeValue.tv_usec = static_cast<glong>(roundf(microSeconds / 10000) * 10000); 4392bde8e466a4451c7319e3a072d118917957d6554Steve Block 4402bde8e466a4451c7319e3a072d118917957d6554Steve Block GstClockTime clockTime = GST_TIMEVAL_TO_TIME(timeValue); 4412bde8e466a4451c7319e3a072d118917957d6554Steve Block LOG_VERBOSE(Media, "Seek: %" GST_TIME_FORMAT, GST_TIME_ARGS(clockTime)); 4422bde8e466a4451c7319e3a072d118917957d6554Steve Block 443cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (!gst_element_seek(m_playBin, m_player->rate(), 4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project GST_FORMAT_TIME, 4452bde8e466a4451c7319e3a072d118917957d6554Steve Block (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE), 4462bde8e466a4451c7319e3a072d118917957d6554Steve Block GST_SEEK_TYPE_SET, clockTime, 4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) 4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_VERBOSE(Media, "Seek to %f failed", time); 449643ca7872b450ea4efacab6188849e5aac2ba161Steve Block else { 450231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_seeking = true; 4512bde8e466a4451c7319e3a072d118917957d6554Steve Block m_seekTime = time; 452643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 455dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool MediaPlayerPrivateGStreamer::paused() const 4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 457231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return m_paused; 4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 460dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool MediaPlayerPrivateGStreamer::seeking() const 4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 462231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return m_seeking; 4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Returns the size of the video 466dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockIntSize MediaPlayerPrivateGStreamer::naturalSize() const 4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!hasVideo()) 4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return IntSize(); 4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen GstPad* pad = gst_element_get_static_pad(m_webkitVideoSink, "sink"); 472692e5dbf12901edacf14812a6fae25462920af42Steve Block if (!pad) 473692e5dbf12901edacf14812a6fae25462920af42Steve Block return IntSize(); 474692e5dbf12901edacf14812a6fae25462920af42Steve Block 4755af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke guint64 width = 0, height = 0; 476692e5dbf12901edacf14812a6fae25462920af42Steve Block GstCaps* caps = GST_PAD_CAPS(pad); 477692e5dbf12901edacf14812a6fae25462920af42Steve Block int pixelAspectRatioNumerator, pixelAspectRatioDenominator; 478692e5dbf12901edacf14812a6fae25462920af42Steve Block int displayWidth, displayHeight, displayAspectRatioGCD; 479692e5dbf12901edacf14812a6fae25462920af42Steve Block int originalWidth = 0, originalHeight = 0; 480692e5dbf12901edacf14812a6fae25462920af42Steve Block 481231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // TODO: handle possible clean aperture data. See 482231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // https://bugzilla.gnome.org/show_bug.cgi?id=596571 483231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // TODO: handle possible transformation matrix. See 484231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // https://bugzilla.gnome.org/show_bug.cgi?id=596326 485231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 486692e5dbf12901edacf14812a6fae25462920af42Steve Block // Get the video PAR and original size. 487692e5dbf12901edacf14812a6fae25462920af42Steve Block if (!GST_IS_CAPS(caps) || !gst_caps_is_fixed(caps) 488692e5dbf12901edacf14812a6fae25462920af42Steve Block || !gst_video_format_parse_caps(caps, 0, &originalWidth, &originalHeight) 489692e5dbf12901edacf14812a6fae25462920af42Steve Block || !gst_video_parse_caps_pixel_aspect_ratio(caps, &pixelAspectRatioNumerator, 490692e5dbf12901edacf14812a6fae25462920af42Steve Block &pixelAspectRatioDenominator)) { 4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gst_object_unref(GST_OBJECT(pad)); 4922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // The video-sink has likely not yet negotiated its caps. 493692e5dbf12901edacf14812a6fae25462920af42Steve Block return IntSize(); 4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 496692e5dbf12901edacf14812a6fae25462920af42Steve Block gst_object_unref(GST_OBJECT(pad)); 497692e5dbf12901edacf14812a6fae25462920af42Steve Block 498692e5dbf12901edacf14812a6fae25462920af42Steve Block LOG_VERBOSE(Media, "Original video size: %dx%d", originalWidth, originalHeight); 499692e5dbf12901edacf14812a6fae25462920af42Steve Block LOG_VERBOSE(Media, "Pixel aspect ratio: %d/%d", pixelAspectRatioNumerator, pixelAspectRatioDenominator); 500692e5dbf12901edacf14812a6fae25462920af42Steve Block 501692e5dbf12901edacf14812a6fae25462920af42Steve Block // Calculate DAR based on PAR and video size. 502692e5dbf12901edacf14812a6fae25462920af42Steve Block displayWidth = originalWidth * pixelAspectRatioNumerator; 503692e5dbf12901edacf14812a6fae25462920af42Steve Block displayHeight = originalHeight * pixelAspectRatioDenominator; 504692e5dbf12901edacf14812a6fae25462920af42Steve Block 505692e5dbf12901edacf14812a6fae25462920af42Steve Block // Divide display width and height by their GCD to avoid possible overflows. 506692e5dbf12901edacf14812a6fae25462920af42Steve Block displayAspectRatioGCD = greatestCommonDivisor(displayWidth, displayHeight); 507692e5dbf12901edacf14812a6fae25462920af42Steve Block displayWidth /= displayAspectRatioGCD; 508692e5dbf12901edacf14812a6fae25462920af42Steve Block displayHeight /= displayAspectRatioGCD; 509692e5dbf12901edacf14812a6fae25462920af42Steve Block 510692e5dbf12901edacf14812a6fae25462920af42Steve Block // Apply DAR to original video size. This is the same behavior as in xvimagesink's setcaps function. 511692e5dbf12901edacf14812a6fae25462920af42Steve Block if (!(originalHeight % displayHeight)) { 512692e5dbf12901edacf14812a6fae25462920af42Steve Block LOG_VERBOSE(Media, "Keeping video original height"); 513692e5dbf12901edacf14812a6fae25462920af42Steve Block width = gst_util_uint64_scale_int(originalHeight, displayWidth, displayHeight); 5145af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke height = static_cast<guint64>(originalHeight); 515692e5dbf12901edacf14812a6fae25462920af42Steve Block } else if (!(originalWidth % displayWidth)) { 516692e5dbf12901edacf14812a6fae25462920af42Steve Block LOG_VERBOSE(Media, "Keeping video original width"); 517692e5dbf12901edacf14812a6fae25462920af42Steve Block height = gst_util_uint64_scale_int(originalWidth, displayHeight, displayWidth); 5185af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke width = static_cast<guint64>(originalWidth); 519692e5dbf12901edacf14812a6fae25462920af42Steve Block } else { 520692e5dbf12901edacf14812a6fae25462920af42Steve Block LOG_VERBOSE(Media, "Approximating while keeping original video height"); 521692e5dbf12901edacf14812a6fae25462920af42Steve Block width = gst_util_uint64_scale_int(originalHeight, displayWidth, displayHeight); 5225af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke height = static_cast<guint64>(originalHeight); 523692e5dbf12901edacf14812a6fae25462920af42Steve Block } 524692e5dbf12901edacf14812a6fae25462920af42Steve Block 5255af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke LOG_VERBOSE(Media, "Natural size: %" G_GUINT64_FORMAT "x%" G_GUINT64_FORMAT, width, height); 5265af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return IntSize(static_cast<int>(width), static_cast<int>(height)); 5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid MediaPlayerPrivateGStreamer::videoChanged() 5308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_videoTimerHandler) 5322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch g_source_remove(m_videoTimerHandler); 5332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_videoTimerHandler = g_timeout_add(0, reinterpret_cast<GSourceFunc>(mediaPlayerPrivateVideoChangeTimeoutCallback), this); 534f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 535f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 5362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid MediaPlayerPrivateGStreamer::notifyPlayerOfVideo() 537f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 5382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_videoTimerHandler = 0; 539f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 5402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch gint videoTracks = 0; 5418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_playBin) 5422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch g_object_get(m_playBin, "n-video", &videoTracks, NULL); 5432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 5442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_hasVideo = videoTracks > 0; 545f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_player->mediaPlayerClient()->mediaPlayerEngineUpdated(m_player); 546f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 547f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 5482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid MediaPlayerPrivateGStreamer::audioChanged() 549f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 5502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_audioTimerHandler) 5512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch g_source_remove(m_audioTimerHandler); 5522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_audioTimerHandler = g_timeout_add(0, reinterpret_cast<GSourceFunc>(mediaPlayerPrivateAudioChangeTimeoutCallback), this); 5538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid MediaPlayerPrivateGStreamer::notifyPlayerOfAudio() 556231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 5572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_audioTimerHandler = 0; 558f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 5592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch gint audioTracks = 0; 560231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_playBin) 5612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch g_object_get(m_playBin, "n-audio", &audioTracks, NULL); 5622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_hasAudio = audioTracks > 0; 563f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_player->mediaPlayerClient()->mediaPlayerEngineUpdated(m_player); 564231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 565231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 566dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::setVolume(float volume) 5678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 568231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!m_playBin) 569231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 570231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 57181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch gst_stream_volume_set_volume(GST_STREAM_VOLUME(m_playBin), GST_STREAM_VOLUME_FORMAT_CUBIC, 57281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch static_cast<double>(volume)); 5738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 575f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid MediaPlayerPrivateGStreamer::notifyPlayerOfVolumeChange() 5765e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 577f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_volumeTimerHandler = 0; 578f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 579f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!m_player || !m_playBin) 580f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return; 5815e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block double volume; 58281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch volume = gst_stream_volume_get_volume(GST_STREAM_VOLUME(m_playBin), GST_STREAM_VOLUME_FORMAT_CUBIC); 58381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // get_volume() can return values superior to 1.0 if the user 58481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // applies software user gain via third party application (GNOME 58581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch // volume control for instance). 58681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch volume = CLAMP(volume, 0.0, 1.0); 5875e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block m_player->volumeChanged(static_cast<float>(volume)); 5885e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 5895e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 590dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::volumeChanged() 591d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 592f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (m_volumeTimerHandler) 593f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch g_source_remove(m_volumeTimerHandler); 594f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_volumeTimerHandler = g_timeout_add(0, reinterpret_cast<GSourceFunc>(mediaPlayerPrivateVolumeChangeTimeoutCallback), this); 595d0825bca7fe65beaee391d30da42e937db621564Steve Block} 596d0825bca7fe65beaee391d30da42e937db621564Steve Block 597dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::setRate(float rate) 5988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 599d0825bca7fe65beaee391d30da42e937db621564Steve Block // Avoid useless playback rate update. 600d0825bca7fe65beaee391d30da42e937db621564Steve Block if (m_playbackRate == rate) 601d0825bca7fe65beaee391d30da42e937db621564Steve Block return; 602d0825bca7fe65beaee391d30da42e937db621564Steve Block 603643ca7872b450ea4efacab6188849e5aac2ba161Steve Block GstState state; 604643ca7872b450ea4efacab6188849e5aac2ba161Steve Block GstState pending; 605643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 606643ca7872b450ea4efacab6188849e5aac2ba161Steve Block gst_element_get_state(m_playBin, &state, &pending, 0); 607643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if ((state != GST_STATE_PLAYING && state != GST_STATE_PAUSED) 608643ca7872b450ea4efacab6188849e5aac2ba161Steve Block || (pending == GST_STATE_PAUSED)) 6098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 610231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 6118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_isStreaming) 6128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 6138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 614d0825bca7fe65beaee391d30da42e937db621564Steve Block m_playbackRate = rate; 615643ca7872b450ea4efacab6188849e5aac2ba161Steve Block m_changingRate = true; 6162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 6172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!rate) { 6182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch gst_element_set_state(m_playBin, GST_STATE_PAUSED); 6192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return; 6202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 6212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 6222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch float currentPosition = static_cast<float>(playbackPosition() * GST_SECOND); 623643ca7872b450ea4efacab6188849e5aac2ba161Steve Block GstSeekFlags flags = (GstSeekFlags)(GST_SEEK_FLAG_FLUSH); 624643ca7872b450ea4efacab6188849e5aac2ba161Steve Block gint64 start, end; 625643ca7872b450ea4efacab6188849e5aac2ba161Steve Block bool mute = false; 626643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 6278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_VERBOSE(Media, "Set Rate to %f", rate); 6282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (rate > 0) { 629643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // Mute the sound if the playback rate is too extreme. 630643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // TODO: in other cases we should perform pitch adjustments. 631643ca7872b450ea4efacab6188849e5aac2ba161Steve Block mute = (bool) (rate < 0.8 || rate > 2); 632643ca7872b450ea4efacab6188849e5aac2ba161Steve Block start = currentPosition; 633643ca7872b450ea4efacab6188849e5aac2ba161Steve Block end = GST_CLOCK_TIME_NONE; 634643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } else { 635643ca7872b450ea4efacab6188849e5aac2ba161Steve Block start = 0; 636643ca7872b450ea4efacab6188849e5aac2ba161Steve Block mute = true; 637643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 638643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // If we are at beginning of media, start from the end to 639643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // avoid immediate EOS. 640643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (currentPosition <= 0) 6415af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke end = static_cast<gint64>(duration() * GST_SECOND); 642643ca7872b450ea4efacab6188849e5aac2ba161Steve Block else 643643ca7872b450ea4efacab6188849e5aac2ba161Steve Block end = currentPosition; 644643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 645643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 646643ca7872b450ea4efacab6188849e5aac2ba161Steve Block LOG_VERBOSE(Media, "Need to mute audio: %d", (int) mute); 647643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 648643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!gst_element_seek(m_playBin, rate, GST_FORMAT_TIME, flags, 649643ca7872b450ea4efacab6188849e5aac2ba161Steve Block GST_SEEK_TYPE_SET, start, 650643ca7872b450ea4efacab6188849e5aac2ba161Steve Block GST_SEEK_TYPE_SET, end)) 651643ca7872b450ea4efacab6188849e5aac2ba161Steve Block LOG_VERBOSE(Media, "Set rate to %f failed", rate); 652643ca7872b450ea4efacab6188849e5aac2ba161Steve Block else 653643ca7872b450ea4efacab6188849e5aac2ba161Steve Block g_object_set(m_playBin, "mute", mute, NULL); 6548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 656dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockMediaPlayer::NetworkState MediaPlayerPrivateGStreamer::networkState() const 6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_networkState; 6598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 661dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockMediaPlayer::ReadyState MediaPlayerPrivateGStreamer::readyState() const 6628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_readyState; 6648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 666dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockPassRefPtr<TimeRanges> MediaPlayerPrivateGStreamer::buffered() const 6678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 668231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block RefPtr<TimeRanges> timeRanges = TimeRanges::create(); 669f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (m_errorOccured || m_isStreaming) 670f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return timeRanges.release(); 671f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 672f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if GST_CHECK_VERSION(0, 10, 31) 673f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch float mediaDuration(duration()); 674f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!mediaDuration || isinf(mediaDuration)) 675f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return timeRanges.release(); 676f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 677f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch GstQuery* query = gst_query_new_buffering(GST_FORMAT_PERCENT); 678f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 679f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!gst_element_query(m_playBin, query)) { 680f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch gst_query_unref(query); 681f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return timeRanges.release(); 682f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 683f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 684f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch gint64 rangeStart = 0, rangeStop = 0; 685f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch for (guint index = 0; index < gst_query_get_n_buffering_ranges(query); index++) { 686f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (gst_query_parse_nth_buffering_range(query, index, &rangeStart, &rangeStop)) 687f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch timeRanges->add(static_cast<float>((rangeStart * mediaDuration) / 100), 688f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch static_cast<float>((rangeStop * mediaDuration) / 100)); 689f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 690f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 691f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // Fallback to the more general maxTimeLoaded() if no range has 692f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // been found. 693f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!timeRanges->length()) 694f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (float loaded = maxTimeLoaded()) 695f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch timeRanges->add(0, loaded); 696f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 697f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch gst_query_unref(query); 698f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#else 699231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block float loaded = maxTimeLoaded(); 700231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!m_errorOccured && !m_isStreaming && loaded > 0) 701231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block timeRanges->add(0, loaded); 702f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif 703231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return timeRanges.release(); 7048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochgboolean MediaPlayerPrivateGStreamer::handleMessage(GstMessage* message) 7072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 7082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch GOwnPtr<GError> err; 7092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch GOwnPtr<gchar> debug; 7102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch MediaPlayer::NetworkState error; 7112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool issueError = true; 7122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch bool attemptNextLocation = false; 7132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 7142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (message->structure) { 7152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch const gchar* messageTypeName = gst_structure_get_name(message->structure); 7162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 7172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // Redirect messages are sent from elements, like qtdemux, to 7182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // notify of the new location(s) of the media. 7192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!g_strcmp0(messageTypeName, "redirect")) { 7202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch mediaLocationChanged(message); 7212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return TRUE; 7222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 7232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 7242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 7252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch switch (GST_MESSAGE_TYPE(message)) { 7262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case GST_MESSAGE_ERROR: 7272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_resetPipeline) 7282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch break; 7292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch gst_message_parse_error(message, &err.outPtr(), &debug.outPtr()); 7302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_VERBOSE(Media, "Error: %d, %s", err->code, err->message); 7312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 7322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch error = MediaPlayer::Empty; 7332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND 7342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch || err->code == GST_STREAM_ERROR_WRONG_TYPE 7352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch || err->code == GST_STREAM_ERROR_FAILED 7362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch || err->code == GST_CORE_ERROR_MISSING_PLUGIN 7372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch || err->code == GST_RESOURCE_ERROR_NOT_FOUND) 7382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch error = MediaPlayer::FormatError; 7392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch else if (err->domain == GST_STREAM_ERROR) { 7402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // Let the mediaPlayerClient handle the stream error, in 7412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // this case the HTMLMediaElement will emit a stalled 7422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // event. 7432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (err->code == GST_STREAM_ERROR_TYPE_NOT_FOUND) { 7442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_VERBOSE(Media, "Decode error, let the Media element emit a stalled event."); 7452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch break; 7462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 7472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch error = MediaPlayer::DecodeError; 7482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch attemptNextLocation = true; 7492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } else if (err->domain == GST_RESOURCE_ERROR) 7502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch error = MediaPlayer::NetworkError; 7512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 7522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (attemptNextLocation) 7532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch issueError = !loadNextLocation(); 7542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (issueError) 7552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch loadingFailed(error); 7562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch break; 7572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case GST_MESSAGE_EOS: 7582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_VERBOSE(Media, "End of Stream"); 7592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch didEnd(); 7602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch break; 7612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case GST_MESSAGE_STATE_CHANGED: 7622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // Ignore state changes if load is delayed (preload=none). The 7632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // player state will be updated once commitLoad() is called. 7642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_delayingLoad) { 7652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_VERBOSE(Media, "Media load has been delayed. Ignoring state changes for now"); 7662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch break; 7672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 7682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 7692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // Ignore state changes from internal elements. They are 7702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // forwarded to playbin2 anyway. 7712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (GST_MESSAGE_SRC(message) == reinterpret_cast<GstObject*>(m_playBin)) 7722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch updateStates(); 7732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch break; 7742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case GST_MESSAGE_BUFFERING: 7752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch processBufferingStats(message); 7762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch break; 7772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch case GST_MESSAGE_DURATION: 7782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_VERBOSE(Media, "Duration changed"); 7792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch durationChanged(); 7802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch break; 7812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch default: 7822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch LOG_VERBOSE(Media, "Unhandled GStreamer message type: %s", 7832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch GST_MESSAGE_TYPE_NAME(message)); 7842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch break; 7852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 7862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return TRUE; 7872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 7882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 789dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::processBufferingStats(GstMessage* message) 790692e5dbf12901edacf14812a6fae25462920af42Steve Block{ 791dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // This is the immediate buffering that needs to happen so we have 792dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // enough to play right now. 793dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_buffering = true; 794dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block const GstStructure *structure = gst_message_get_structure(message); 795dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gst_structure_get_int(structure, "buffer-percent", &m_bufferingPercentage); 796dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 797dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block LOG_VERBOSE(Media, "[Buffering] Buffering: %d%%.", m_bufferingPercentage); 798692e5dbf12901edacf14812a6fae25462920af42Steve Block 799dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block GstBufferingMode mode; 800692e5dbf12901edacf14812a6fae25462920af42Steve Block gst_message_parse_buffering_stats(message, &mode, 0, 0, 0); 801dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (mode != GST_BUFFERING_DOWNLOAD) { 802dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block updateStates(); 803692e5dbf12901edacf14812a6fae25462920af42Steve Block return; 804dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 805692e5dbf12901edacf14812a6fae25462920af42Steve Block 806dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // This is on-disk buffering, that allows us to download much more 807dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // than needed for right now. 808692e5dbf12901edacf14812a6fae25462920af42Steve Block if (!m_startedBuffering) { 809dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block LOG_VERBOSE(Media, "[Buffering] Starting on-disk buffering."); 810dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 811692e5dbf12901edacf14812a6fae25462920af42Steve Block m_startedBuffering = true; 812692e5dbf12901edacf14812a6fae25462920af42Steve Block 813dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (m_fillTimer.isActive()) 814dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_fillTimer.stop(); 815692e5dbf12901edacf14812a6fae25462920af42Steve Block 816dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_fillTimer.startRepeating(0.2); 817692e5dbf12901edacf14812a6fae25462920af42Steve Block } 818692e5dbf12901edacf14812a6fae25462920af42Steve Block} 819692e5dbf12901edacf14812a6fae25462920af42Steve Block 820dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::fillTimerFired(Timer<MediaPlayerPrivateGStreamer>*) 821692e5dbf12901edacf14812a6fae25462920af42Steve Block{ 822692e5dbf12901edacf14812a6fae25462920af42Steve Block GstQuery* query = gst_query_new_buffering(GST_FORMAT_PERCENT); 823692e5dbf12901edacf14812a6fae25462920af42Steve Block 824692e5dbf12901edacf14812a6fae25462920af42Steve Block if (!gst_element_query(m_playBin, query)) { 825692e5dbf12901edacf14812a6fae25462920af42Steve Block gst_query_unref(query); 826dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return; 827692e5dbf12901edacf14812a6fae25462920af42Steve Block } 828692e5dbf12901edacf14812a6fae25462920af42Steve Block 829692e5dbf12901edacf14812a6fae25462920af42Steve Block gint64 start, stop; 830dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gdouble fillStatus = 100.0; 831692e5dbf12901edacf14812a6fae25462920af42Steve Block 832692e5dbf12901edacf14812a6fae25462920af42Steve Block gst_query_parse_buffering_range(query, 0, &start, &stop, 0); 833692e5dbf12901edacf14812a6fae25462920af42Steve Block gst_query_unref(query); 834692e5dbf12901edacf14812a6fae25462920af42Steve Block 835692e5dbf12901edacf14812a6fae25462920af42Steve Block if (stop != -1) 836dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block fillStatus = 100.0 * stop / GST_FORMAT_PERCENT_MAX; 837692e5dbf12901edacf14812a6fae25462920af42Steve Block 838dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block LOG_VERBOSE(Media, "[Buffering] Download buffer filled up to %f%%", fillStatus); 839692e5dbf12901edacf14812a6fae25462920af42Steve Block 840692e5dbf12901edacf14812a6fae25462920af42Steve Block if (!m_mediaDuration) 841692e5dbf12901edacf14812a6fae25462920af42Steve Block durationChanged(); 842692e5dbf12901edacf14812a6fae25462920af42Steve Block 843692e5dbf12901edacf14812a6fae25462920af42Steve Block // Update maxTimeLoaded only if the media duration is 844692e5dbf12901edacf14812a6fae25462920af42Steve Block // available. Otherwise we can't compute it. 845692e5dbf12901edacf14812a6fae25462920af42Steve Block if (m_mediaDuration) { 846dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (fillStatus == 100.0) 847dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_maxTimeLoaded = m_mediaDuration; 848dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else 849dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_maxTimeLoaded = static_cast<float>((fillStatus * m_mediaDuration) / 100.0); 850dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block LOG_VERBOSE(Media, "[Buffering] Updated maxTimeLoaded: %f", m_maxTimeLoaded); 851692e5dbf12901edacf14812a6fae25462920af42Steve Block } 852692e5dbf12901edacf14812a6fae25462920af42Steve Block 853dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (fillStatus != 100.0) { 854692e5dbf12901edacf14812a6fae25462920af42Steve Block updateStates(); 855dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return; 856692e5dbf12901edacf14812a6fae25462920af42Steve Block } 857692e5dbf12901edacf14812a6fae25462920af42Steve Block 858692e5dbf12901edacf14812a6fae25462920af42Steve Block // Media is now fully loaded. It will play even if network 859692e5dbf12901edacf14812a6fae25462920af42Steve Block // connection is cut. Buffering is done, remove the fill source 860692e5dbf12901edacf14812a6fae25462920af42Steve Block // from the main loop. 861dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_fillTimer.stop(); 862692e5dbf12901edacf14812a6fae25462920af42Steve Block m_startedBuffering = false; 863692e5dbf12901edacf14812a6fae25462920af42Steve Block updateStates(); 864692e5dbf12901edacf14812a6fae25462920af42Steve Block} 865692e5dbf12901edacf14812a6fae25462920af42Steve Block 866dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockfloat MediaPlayerPrivateGStreamer::maxTimeSeekable() const 8678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 868231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_errorOccured) 8695af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return 0.0f; 870231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 8718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_VERBOSE(Media, "maxTimeSeekable"); 8728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // infinite duration means live stream 873692e5dbf12901edacf14812a6fae25462920af42Steve Block if (isinf(duration())) 8745af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return 0.0f; 875692e5dbf12901edacf14812a6fae25462920af42Steve Block 876e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke return duration(); 8778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 879dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockfloat MediaPlayerPrivateGStreamer::maxTimeLoaded() const 8808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 881231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_errorOccured) 8825af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return 0.0f; 883231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 884692e5dbf12901edacf14812a6fae25462920af42Steve Block float loaded = m_maxTimeLoaded; 885dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!loaded && !m_fillTimer.isActive()) 886692e5dbf12901edacf14812a6fae25462920af42Steve Block loaded = duration(); 887692e5dbf12901edacf14812a6fae25462920af42Steve Block LOG_VERBOSE(Media, "maxTimeLoaded: %f", loaded); 888692e5dbf12901edacf14812a6fae25462920af42Steve Block return loaded; 8898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 891dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockunsigned MediaPlayerPrivateGStreamer::bytesLoaded() const 8928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 893692e5dbf12901edacf14812a6fae25462920af42Steve Block if (!m_playBin) 8948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 895231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 896692e5dbf12901edacf14812a6fae25462920af42Steve Block if (!m_mediaDuration) 897692e5dbf12901edacf14812a6fae25462920af42Steve Block return 0; 898692e5dbf12901edacf14812a6fae25462920af42Steve Block 899692e5dbf12901edacf14812a6fae25462920af42Steve Block unsigned loaded = totalBytes() * maxTimeLoaded() / m_mediaDuration; 900692e5dbf12901edacf14812a6fae25462920af42Steve Block LOG_VERBOSE(Media, "bytesLoaded: %d", loaded); 901692e5dbf12901edacf14812a6fae25462920af42Steve Block return loaded; 9028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 904dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockunsigned MediaPlayerPrivateGStreamer::totalBytes() const 9058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 906231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!m_source) 9078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 9088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 909231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_errorOccured) 9108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 9118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 912231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block GstFormat fmt = GST_FORMAT_BYTES; 913231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block gint64 length = 0; 914cad810f21b803229eb11403f9209855525a25d57Steve Block if (gst_element_query_duration(m_source, &fmt, &length)) { 915cad810f21b803229eb11403f9209855525a25d57Steve Block LOG_VERBOSE(Media, "totalBytes %" G_GINT64_FORMAT, length); 916cad810f21b803229eb11403f9209855525a25d57Steve Block return static_cast<unsigned>(length); 917cad810f21b803229eb11403f9209855525a25d57Steve Block } 918cad810f21b803229eb11403f9209855525a25d57Steve Block 919cad810f21b803229eb11403f9209855525a25d57Steve Block // Fall back to querying the source pads manually. 920cad810f21b803229eb11403f9209855525a25d57Steve Block // See also https://bugzilla.gnome.org/show_bug.cgi?id=638749 921cad810f21b803229eb11403f9209855525a25d57Steve Block GstIterator* iter = gst_element_iterate_src_pads(m_source); 922cad810f21b803229eb11403f9209855525a25d57Steve Block bool done = false; 923cad810f21b803229eb11403f9209855525a25d57Steve Block while (!done) { 924cad810f21b803229eb11403f9209855525a25d57Steve Block gpointer data; 925cad810f21b803229eb11403f9209855525a25d57Steve Block 926cad810f21b803229eb11403f9209855525a25d57Steve Block switch (gst_iterator_next(iter, &data)) { 927cad810f21b803229eb11403f9209855525a25d57Steve Block case GST_ITERATOR_OK: { 928cad810f21b803229eb11403f9209855525a25d57Steve Block GstPad* pad = GST_PAD_CAST(data); 929cad810f21b803229eb11403f9209855525a25d57Steve Block gint64 padLength = 0; 930cad810f21b803229eb11403f9209855525a25d57Steve Block if (gst_pad_query_duration(pad, &fmt, &padLength) 931cad810f21b803229eb11403f9209855525a25d57Steve Block && padLength > length) 932cad810f21b803229eb11403f9209855525a25d57Steve Block length = padLength; 933cad810f21b803229eb11403f9209855525a25d57Steve Block gst_object_unref(pad); 934cad810f21b803229eb11403f9209855525a25d57Steve Block break; 935cad810f21b803229eb11403f9209855525a25d57Steve Block } 936cad810f21b803229eb11403f9209855525a25d57Steve Block case GST_ITERATOR_RESYNC: 937cad810f21b803229eb11403f9209855525a25d57Steve Block gst_iterator_resync(iter); 938cad810f21b803229eb11403f9209855525a25d57Steve Block break; 939cad810f21b803229eb11403f9209855525a25d57Steve Block case GST_ITERATOR_ERROR: 940cad810f21b803229eb11403f9209855525a25d57Steve Block // Fall through. 941cad810f21b803229eb11403f9209855525a25d57Steve Block case GST_ITERATOR_DONE: 942cad810f21b803229eb11403f9209855525a25d57Steve Block done = true; 943cad810f21b803229eb11403f9209855525a25d57Steve Block break; 944cad810f21b803229eb11403f9209855525a25d57Steve Block } 945cad810f21b803229eb11403f9209855525a25d57Steve Block } 946cad810f21b803229eb11403f9209855525a25d57Steve Block gst_iterator_free(iter); 947cad810f21b803229eb11403f9209855525a25d57Steve Block 948692e5dbf12901edacf14812a6fae25462920af42Steve Block LOG_VERBOSE(Media, "totalBytes %" G_GINT64_FORMAT, length); 9498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9505af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return static_cast<unsigned>(length); 9518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochunsigned MediaPlayerPrivateGStreamer::decodedFrameCount() const 9542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 9552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch guint64 decodedFrames = 0; 9562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_fpsSink) 9572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch g_object_get(m_fpsSink, "frames-rendered", &decodedFrames, NULL); 9582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return static_cast<unsigned>(decodedFrames); 9592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 9602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 9612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochunsigned MediaPlayerPrivateGStreamer::droppedFrameCount() const 9622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 9632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch guint64 framesDropped = 0; 9642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_fpsSink) 9652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch g_object_get(m_fpsSink, "frames-dropped", &framesDropped, NULL); 9662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return static_cast<unsigned>(framesDropped); 9672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 9682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 9692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochunsigned MediaPlayerPrivateGStreamer::audioDecodedByteCount() const 9702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 9712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch GstQuery* query = gst_query_new_position(GST_FORMAT_BYTES); 9722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch gint64 position = 0; 9732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 9742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_webkitAudioSink && gst_element_query(m_webkitAudioSink, query)) 9752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch gst_query_parse_position(query, 0, &position); 9762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 9772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch gst_query_unref(query); 9782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return static_cast<unsigned>(position); 9792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 9802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 9812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochunsigned MediaPlayerPrivateGStreamer::videoDecodedByteCount() const 9822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 9832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch GstQuery* query = gst_query_new_position(GST_FORMAT_BYTES); 9842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch gint64 position = 0; 9852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 9862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (gst_element_query(m_webkitVideoSink, query)) 9872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch gst_query_parse_position(query, 0, &position); 9882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 9892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch gst_query_unref(query); 9902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return static_cast<unsigned>(position); 9912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 9922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 9932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid MediaPlayerPrivateGStreamer::updateAudioSink() 9942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 9952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!m_playBin) 9962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return; 9972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 9982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch GOwnPtr<GstElement> element; 9992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 10002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch g_object_get(m_playBin, "audio-sink", &element.outPtr(), NULL); 10012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch gst_object_replace(reinterpret_cast<GstObject**>(&m_webkitAudioSink), 10022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch reinterpret_cast<GstObject*>(element.get())); 10032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 10042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 10052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 10062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid MediaPlayerPrivateGStreamer::sourceChanged() 10072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 10082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch GOwnPtr<GstElement> element; 10092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 10102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch g_object_get(m_playBin, "source", &element.outPtr(), NULL); 10112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch gst_object_replace(reinterpret_cast<GstObject**>(&m_source), 10122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch reinterpret_cast<GstObject*>(element.get())); 10132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 10142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (WEBKIT_IS_WEB_SRC(element.get())) { 10152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch Frame* frame = m_player->frameView() ? m_player->frameView()->frame() : 0; 10162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 10172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (frame) 10182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch webKitWebSrcSetFrame(WEBKIT_WEB_SRC(element.get()), frame); 10192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 10202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 10212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1022dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::cancelLoad() 10238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1024cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (m_networkState < MediaPlayer::Loading || m_networkState == MediaPlayer::Loaded) 1025cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return; 1026cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 1027cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (m_playBin) 1028cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block gst_element_set_state(m_playBin, GST_STATE_NULL); 10298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 10308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1031dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::updateStates() 10328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1033231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!m_playBin) 1034231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 1035231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1036231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_errorOccured) 1037231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 1038231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 10398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project MediaPlayer::NetworkState oldNetworkState = m_networkState; 10408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project MediaPlayer::ReadyState oldReadyState = m_readyState; 10418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project GstState state; 10428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project GstState pending; 10438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch GstStateChangeReturn ret = gst_element_get_state(m_playBin, 10458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project &state, &pending, 250 * GST_NSECOND); 10468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1047231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bool shouldUpdateAfterSeek = false; 10480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch switch (ret) { 10498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case GST_STATE_CHANGE_SUCCESS: 10508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_VERBOSE(Media, "State: %s, pending: %s", 10518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gst_element_state_get_name(state), 10528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gst_element_state_get_name(pending)); 10538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1054d0825bca7fe65beaee391d30da42e937db621564Steve Block m_resetPipeline = state <= GST_STATE_READY; 1055d0825bca7fe65beaee391d30da42e937db621564Steve Block 1056dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Try to figure out ready and network states. 1057dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (state == GST_STATE_READY) { 10585abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick m_readyState = MediaPlayer::HaveMetadata; 1059dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_networkState = MediaPlayer::Empty; 10605abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick // Cache the duration without emiting the durationchange 10615abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick // event because it's taken care of by the media element 10625abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick // in this precise case. 10635abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick cacheDuration(); 1064dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } else if (maxTimeLoaded() == duration()) { 1065dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_networkState = MediaPlayer::Loaded; 10668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_readyState = MediaPlayer::HaveEnoughData; 1067dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } else { 1068dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_readyState = currentTime() < maxTimeLoaded() ? MediaPlayer::HaveFutureData : MediaPlayer::HaveCurrentData; 1069dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_networkState = MediaPlayer::Loading; 1070dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 10710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1072dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (m_buffering && state != GST_STATE_READY) { 1073dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_readyState = MediaPlayer::HaveCurrentData; 1074dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_networkState = MediaPlayer::Loading; 1075dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 1076dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1077dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Now let's try to get the states in more detail using 1078dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // information from GStreamer, while we sync states where 1079dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // needed. 1080dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (state == GST_STATE_PAUSED) { 10812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!m_webkitAudioSink) 10822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch updateAudioSink(); 1083dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (m_buffering && m_bufferingPercentage == 100) { 1084dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_buffering = false; 1085dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_bufferingPercentage = 0; 1086dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_readyState = MediaPlayer::HaveEnoughData; 1087dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1088dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block LOG_VERBOSE(Media, "[Buffering] Complete."); 1089dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1090dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!m_paused) { 1091dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block LOG_VERBOSE(Media, "[Buffering] Restarting playback."); 1092dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gst_element_set_state(m_playBin, GST_STATE_PLAYING); 1093dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 1094dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } else if (!m_buffering && (currentTime() < duration())) { 1095dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_paused = true; 1096dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 1097dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } else if (state == GST_STATE_PLAYING) { 1098cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block m_readyState = MediaPlayer::HaveEnoughData; 1099231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_paused = false; 1100dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1101dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (m_buffering) { 1102dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_readyState = MediaPlayer::HaveCurrentData; 1103dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_networkState = MediaPlayer::Loading; 1104dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1105dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block LOG_VERBOSE(Media, "[Buffering] Pausing stream for buffering."); 1106dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1107dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gst_element_set_state(m_playBin, GST_STATE_PAUSED); 1108dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 1109cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } else 1110231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_paused = true; 1111231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1112692e5dbf12901edacf14812a6fae25462920af42Steve Block // Is on-disk buffering in progress? 1113dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (m_fillTimer.isActive()) 1114692e5dbf12901edacf14812a6fae25462920af42Steve Block m_networkState = MediaPlayer::Loading; 1115692e5dbf12901edacf14812a6fae25462920af42Steve Block 1116643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (m_changingRate) { 1117643ca7872b450ea4efacab6188849e5aac2ba161Steve Block m_player->rateChanged(); 1118643ca7872b450ea4efacab6188849e5aac2ba161Steve Block m_changingRate = false; 1119643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 1120643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 1121231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_seeking) { 1122231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block shouldUpdateAfterSeek = true; 1123231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_seeking = false; 1124231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 1125231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 11268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 11278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case GST_STATE_CHANGE_ASYNC: 11288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_VERBOSE(Media, "Async: State: %s, pending: %s", 11298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gst_element_state_get_name(state), 11308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gst_element_state_get_name(pending)); 11318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Change in progress 1132692e5dbf12901edacf14812a6fae25462920af42Steve Block 1133e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (!m_isStreaming && !m_buffering) 1134692e5dbf12901edacf14812a6fae25462920af42Steve Block return; 1135692e5dbf12901edacf14812a6fae25462920af42Steve Block 1136692e5dbf12901edacf14812a6fae25462920af42Steve Block if (m_seeking) { 1137692e5dbf12901edacf14812a6fae25462920af42Steve Block shouldUpdateAfterSeek = true; 1138692e5dbf12901edacf14812a6fae25462920af42Steve Block m_seeking = false; 1139692e5dbf12901edacf14812a6fae25462920af42Steve Block } 1140692e5dbf12901edacf14812a6fae25462920af42Steve Block break; 1141231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case GST_STATE_CHANGE_FAILURE: 1142231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block LOG_VERBOSE(Media, "Failure: State: %s, pending: %s", 1143231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block gst_element_state_get_name(state), 1144231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block gst_element_state_get_name(pending)); 1145231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Change failed 1146231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 11478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case GST_STATE_CHANGE_NO_PREROLL: 11488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_VERBOSE(Media, "No preroll: State: %s, pending: %s", 11498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gst_element_state_get_name(state), 11508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gst_element_state_get_name(pending)); 1151231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1152cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (state == GST_STATE_READY) 1153cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block m_readyState = MediaPlayer::HaveNothing; 1154692e5dbf12901edacf14812a6fae25462920af42Steve Block else if (state == GST_STATE_PAUSED) { 1155692e5dbf12901edacf14812a6fae25462920af42Steve Block m_readyState = MediaPlayer::HaveEnoughData; 1156692e5dbf12901edacf14812a6fae25462920af42Steve Block m_paused = true; 1157692e5dbf12901edacf14812a6fae25462920af42Steve Block // Live pipelines go in PAUSED without prerolling. 1158692e5dbf12901edacf14812a6fae25462920af42Steve Block m_isStreaming = true; 1159dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } else if (state == GST_STATE_PLAYING) 1160692e5dbf12901edacf14812a6fae25462920af42Steve Block m_paused = false; 1161692e5dbf12901edacf14812a6fae25462920af42Steve Block 1162692e5dbf12901edacf14812a6fae25462920af42Steve Block if (m_seeking) { 1163692e5dbf12901edacf14812a6fae25462920af42Steve Block shouldUpdateAfterSeek = true; 1164692e5dbf12901edacf14812a6fae25462920af42Steve Block m_seeking = false; 1165dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!m_paused) 1166692e5dbf12901edacf14812a6fae25462920af42Steve Block gst_element_set_state(m_playBin, GST_STATE_PLAYING); 1167dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } else if (!m_paused) 1168dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gst_element_set_state(m_playBin, GST_STATE_PLAYING); 11690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 11708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_networkState = MediaPlayer::Loading; 11718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 11728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project default: 11738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_VERBOSE(Media, "Else : %d", ret); 11748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 11758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (seeking()) 11788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_readyState = MediaPlayer::HaveNothing; 11798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1180231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (shouldUpdateAfterSeek) 1181231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block timeChanged(); 1182231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 11838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_networkState != oldNetworkState) { 11848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_VERBOSE(Media, "Network State Changed from %u to %u", 11858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project oldNetworkState, m_networkState); 11868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_player->networkStateChanged(); 11878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_readyState != oldReadyState) { 11898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_VERBOSE(Media, "Ready State Changed from %u to %u", 11908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project oldReadyState, m_readyState); 11918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_player->readyStateChanged(); 11928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 11948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1195dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::mediaLocationChanged(GstMessage* message) 1196d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 1197d0825bca7fe65beaee391d30da42e937db621564Steve Block if (m_mediaLocations) 1198d0825bca7fe65beaee391d30da42e937db621564Steve Block gst_structure_free(m_mediaLocations); 1199d0825bca7fe65beaee391d30da42e937db621564Steve Block 1200d0825bca7fe65beaee391d30da42e937db621564Steve Block if (message->structure) { 1201d0825bca7fe65beaee391d30da42e937db621564Steve Block // This structure can contain: 1202d0825bca7fe65beaee391d30da42e937db621564Steve Block // - both a new-location string and embedded locations structure 1203d0825bca7fe65beaee391d30da42e937db621564Steve Block // - or only a new-location string. 1204d0825bca7fe65beaee391d30da42e937db621564Steve Block m_mediaLocations = gst_structure_copy(message->structure); 1205d0825bca7fe65beaee391d30da42e937db621564Steve Block const GValue* locations = gst_structure_get_value(m_mediaLocations, "locations"); 1206d0825bca7fe65beaee391d30da42e937db621564Steve Block 1207d0825bca7fe65beaee391d30da42e937db621564Steve Block if (locations) 1208dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_mediaLocationCurrentIndex = static_cast<int>(gst_value_list_get_size(locations)) -1; 1209d0825bca7fe65beaee391d30da42e937db621564Steve Block 1210d0825bca7fe65beaee391d30da42e937db621564Steve Block loadNextLocation(); 1211d0825bca7fe65beaee391d30da42e937db621564Steve Block } 1212d0825bca7fe65beaee391d30da42e937db621564Steve Block} 1213d0825bca7fe65beaee391d30da42e937db621564Steve Block 1214dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool MediaPlayerPrivateGStreamer::loadNextLocation() 1215d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 1216d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!m_mediaLocations) 1217d0825bca7fe65beaee391d30da42e937db621564Steve Block return false; 1218d0825bca7fe65beaee391d30da42e937db621564Steve Block 1219d0825bca7fe65beaee391d30da42e937db621564Steve Block const GValue* locations = gst_structure_get_value(m_mediaLocations, "locations"); 1220d0825bca7fe65beaee391d30da42e937db621564Steve Block const gchar* newLocation = 0; 1221d0825bca7fe65beaee391d30da42e937db621564Steve Block 1222d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!locations) { 1223d0825bca7fe65beaee391d30da42e937db621564Steve Block // Fallback on new-location string. 1224d0825bca7fe65beaee391d30da42e937db621564Steve Block newLocation = gst_structure_get_string(m_mediaLocations, "new-location"); 1225d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!newLocation) 1226d0825bca7fe65beaee391d30da42e937db621564Steve Block return false; 1227d0825bca7fe65beaee391d30da42e937db621564Steve Block } 1228d0825bca7fe65beaee391d30da42e937db621564Steve Block 1229d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!newLocation) { 1230d0825bca7fe65beaee391d30da42e937db621564Steve Block if (m_mediaLocationCurrentIndex < 0) { 1231d0825bca7fe65beaee391d30da42e937db621564Steve Block m_mediaLocations = 0; 1232d0825bca7fe65beaee391d30da42e937db621564Steve Block return false; 1233d0825bca7fe65beaee391d30da42e937db621564Steve Block } 1234d0825bca7fe65beaee391d30da42e937db621564Steve Block 1235d0825bca7fe65beaee391d30da42e937db621564Steve Block const GValue* location = gst_value_list_get_value(locations, 1236d0825bca7fe65beaee391d30da42e937db621564Steve Block m_mediaLocationCurrentIndex); 1237d0825bca7fe65beaee391d30da42e937db621564Steve Block const GstStructure* structure = gst_value_get_structure(location); 1238d0825bca7fe65beaee391d30da42e937db621564Steve Block 1239d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!structure) { 1240d0825bca7fe65beaee391d30da42e937db621564Steve Block m_mediaLocationCurrentIndex--; 1241d0825bca7fe65beaee391d30da42e937db621564Steve Block return false; 1242d0825bca7fe65beaee391d30da42e937db621564Steve Block } 1243d0825bca7fe65beaee391d30da42e937db621564Steve Block 1244d0825bca7fe65beaee391d30da42e937db621564Steve Block newLocation = gst_structure_get_string(structure, "new-location"); 1245d0825bca7fe65beaee391d30da42e937db621564Steve Block } 1246d0825bca7fe65beaee391d30da42e937db621564Steve Block 1247d0825bca7fe65beaee391d30da42e937db621564Steve Block if (newLocation) { 1248d0825bca7fe65beaee391d30da42e937db621564Steve Block // Found a candidate. new-location is not always an absolute url 1249d0825bca7fe65beaee391d30da42e937db621564Steve Block // though. We need to take the base of the current url and 1250d0825bca7fe65beaee391d30da42e937db621564Steve Block // append the value of new-location to it. 1251d0825bca7fe65beaee391d30da42e937db621564Steve Block 1252d0825bca7fe65beaee391d30da42e937db621564Steve Block gchar* currentLocation = 0; 1253d0825bca7fe65beaee391d30da42e937db621564Steve Block g_object_get(m_playBin, "uri", ¤tLocation, NULL); 1254d0825bca7fe65beaee391d30da42e937db621564Steve Block 1255d0825bca7fe65beaee391d30da42e937db621564Steve Block KURL currentUrl(KURL(), currentLocation); 1256d0825bca7fe65beaee391d30da42e937db621564Steve Block g_free(currentLocation); 1257d0825bca7fe65beaee391d30da42e937db621564Steve Block 1258d0825bca7fe65beaee391d30da42e937db621564Steve Block KURL newUrl; 1259d0825bca7fe65beaee391d30da42e937db621564Steve Block 1260d0825bca7fe65beaee391d30da42e937db621564Steve Block if (gst_uri_is_valid(newLocation)) 1261d0825bca7fe65beaee391d30da42e937db621564Steve Block newUrl = KURL(KURL(), newLocation); 1262d0825bca7fe65beaee391d30da42e937db621564Steve Block else 1263d0825bca7fe65beaee391d30da42e937db621564Steve Block newUrl = KURL(KURL(), currentUrl.baseAsString() + newLocation); 1264d0825bca7fe65beaee391d30da42e937db621564Steve Block 1265d0825bca7fe65beaee391d30da42e937db621564Steve Block RefPtr<SecurityOrigin> securityOrigin = SecurityOrigin::create(currentUrl); 1266d0825bca7fe65beaee391d30da42e937db621564Steve Block if (securityOrigin->canRequest(newUrl)) { 1267d0825bca7fe65beaee391d30da42e937db621564Steve Block LOG_VERBOSE(Media, "New media url: %s", newUrl.string().utf8().data()); 1268d0825bca7fe65beaee391d30da42e937db621564Steve Block 1269d0825bca7fe65beaee391d30da42e937db621564Steve Block // Reset player states. 1270d0825bca7fe65beaee391d30da42e937db621564Steve Block m_networkState = MediaPlayer::Loading; 1271d0825bca7fe65beaee391d30da42e937db621564Steve Block m_player->networkStateChanged(); 1272d0825bca7fe65beaee391d30da42e937db621564Steve Block m_readyState = MediaPlayer::HaveNothing; 1273d0825bca7fe65beaee391d30da42e937db621564Steve Block m_player->readyStateChanged(); 1274d0825bca7fe65beaee391d30da42e937db621564Steve Block 1275d0825bca7fe65beaee391d30da42e937db621564Steve Block // Reset pipeline state. 1276d0825bca7fe65beaee391d30da42e937db621564Steve Block m_resetPipeline = true; 1277d0825bca7fe65beaee391d30da42e937db621564Steve Block gst_element_set_state(m_playBin, GST_STATE_READY); 1278d0825bca7fe65beaee391d30da42e937db621564Steve Block 1279d0825bca7fe65beaee391d30da42e937db621564Steve Block GstState state; 1280d0825bca7fe65beaee391d30da42e937db621564Steve Block gst_element_get_state(m_playBin, &state, 0, 0); 1281d0825bca7fe65beaee391d30da42e937db621564Steve Block if (state <= GST_STATE_READY) { 1282d0825bca7fe65beaee391d30da42e937db621564Steve Block // Set the new uri and start playing. 1283d0825bca7fe65beaee391d30da42e937db621564Steve Block g_object_set(m_playBin, "uri", newUrl.string().utf8().data(), NULL); 1284d0825bca7fe65beaee391d30da42e937db621564Steve Block gst_element_set_state(m_playBin, GST_STATE_PLAYING); 1285d0825bca7fe65beaee391d30da42e937db621564Steve Block return true; 1286d0825bca7fe65beaee391d30da42e937db621564Steve Block } 1287d0825bca7fe65beaee391d30da42e937db621564Steve Block } 1288d0825bca7fe65beaee391d30da42e937db621564Steve Block } 1289d0825bca7fe65beaee391d30da42e937db621564Steve Block m_mediaLocationCurrentIndex--; 1290d0825bca7fe65beaee391d30da42e937db621564Steve Block return false; 1291d0825bca7fe65beaee391d30da42e937db621564Steve Block 1292d0825bca7fe65beaee391d30da42e937db621564Steve Block} 1293d0825bca7fe65beaee391d30da42e937db621564Steve Block 1294dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::loadStateChanged() 12958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 12968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project updateStates(); 12978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 12988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1299dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::sizeChanged() 13008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 13018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project notImplemented(); 13028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 13038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1304dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::timeChanged() 13058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 13068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project updateStates(); 13078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_player->timeChanged(); 13088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 13098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1310dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::didEnd() 13118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1312d0825bca7fe65beaee391d30da42e937db621564Steve Block // EOS was reached but in case of reverse playback the position is 1313d0825bca7fe65beaee391d30da42e937db621564Steve Block // not always 0. So to not confuse the HTMLMediaElement we 1314d0825bca7fe65beaee391d30da42e937db621564Steve Block // synchronize position and duration values. 1315d0825bca7fe65beaee391d30da42e937db621564Steve Block float now = currentTime(); 1316692e5dbf12901edacf14812a6fae25462920af42Steve Block if (now > 0) { 1317d0825bca7fe65beaee391d30da42e937db621564Steve Block m_mediaDuration = now; 131821939df44de1705786c545cd1bf519d47250322dBen Murdoch m_mediaDurationKnown = true; 1319692e5dbf12901edacf14812a6fae25462920af42Steve Block m_player->durationChanged(); 1320692e5dbf12901edacf14812a6fae25462920af42Steve Block } 1321692e5dbf12901edacf14812a6fae25462920af42Steve Block 1322d0825bca7fe65beaee391d30da42e937db621564Steve Block gst_element_set_state(m_playBin, GST_STATE_PAUSED); 1323d0825bca7fe65beaee391d30da42e937db621564Steve Block 1324d0825bca7fe65beaee391d30da42e937db621564Steve Block timeChanged(); 13258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 13268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13275abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickvoid MediaPlayerPrivateGStreamer::cacheDuration() 13288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1329d0825bca7fe65beaee391d30da42e937db621564Steve Block // Reset cached media duration 1330d0825bca7fe65beaee391d30da42e937db621564Steve Block m_mediaDuration = 0; 1331d0825bca7fe65beaee391d30da42e937db621564Steve Block 1332d0825bca7fe65beaee391d30da42e937db621564Steve Block // And re-cache it if possible. 1333dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block GstState state; 1334dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gst_element_get_state(m_playBin, &state, 0, 0); 1335d0825bca7fe65beaee391d30da42e937db621564Steve Block float newDuration = duration(); 1336dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1337dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (state <= GST_STATE_READY) { 1338dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Don't set m_mediaDurationKnown yet if the pipeline is not 1339dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // paused. This allows duration() query to fail at least once 1340dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // before playback starts and duration becomes known. 1341dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!isinf(newDuration)) 1342dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_mediaDuration = newDuration; 1343dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } else { 1344dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_mediaDurationKnown = !isinf(newDuration); 1345dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (m_mediaDurationKnown) 1346dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_mediaDuration = newDuration; 1347dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 1348dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1349d0825bca7fe65beaee391d30da42e937db621564Steve Block if (!isinf(newDuration)) 1350d0825bca7fe65beaee391d30da42e937db621564Steve Block m_mediaDuration = newDuration; 13515abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick} 1352d0825bca7fe65beaee391d30da42e937db621564Steve Block 13535abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickvoid MediaPlayerPrivateGStreamer::durationChanged() 13545abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{ 13555abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick float previousDuration = m_mediaDuration; 13565abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 13575abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick cacheDuration(); 1358f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // Avoid emiting durationchanged in the case where the previous 1359f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // duration was 0 because that case is already handled by the 1360f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // HTMLMediaElement. 1361f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (previousDuration && m_mediaDuration != previousDuration) 13625abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick m_player->durationChanged(); 13638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 13648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1365dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool MediaPlayerPrivateGStreamer::supportsMuting() const 13665e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 13675e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block return true; 13685e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 13695e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 1370dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::setMuted(bool muted) 13715e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 13725e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block if (!m_playBin) 13735e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block return; 13745e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 13755e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block g_object_set(m_playBin, "mute", muted, NULL); 13765e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 13775e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 1378f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid MediaPlayerPrivateGStreamer::notifyPlayerOfMute() 13795e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 1380f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_muteTimerHandler = 0; 1381f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1382f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!m_player || !m_playBin) 1383f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return; 1384f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 13855e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block gboolean muted; 13865e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block g_object_get(m_playBin, "mute", &muted, NULL); 13875e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block m_player->muteChanged(static_cast<bool>(muted)); 13885e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 13895e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 1390dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::muteChanged() 13915e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 1392f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (m_muteTimerHandler) 1393f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch g_source_remove(m_muteTimerHandler); 1394f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_muteTimerHandler = g_timeout_add(0, reinterpret_cast<GSourceFunc>(mediaPlayerPrivateMuteChangeTimeoutCallback), this); 13955e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 13965e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 1397dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::loadingFailed(MediaPlayer::NetworkState error) 13988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1399231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_errorOccured = true; 1400231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_networkState != error) { 1401231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_networkState = error; 14028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_player->networkStateChanged(); 14038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 14048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (m_readyState != MediaPlayer::HaveNothing) { 14058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_readyState = MediaPlayer::HaveNothing; 14068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_player->readyStateChanged(); 14078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 14088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 14098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1410dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::setSize(const IntSize& size) 14118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 14128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_size = size; 14138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 14148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1415dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::setVisible(bool visible) 14168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 14178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 14188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 14202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid MediaPlayerPrivateGStreamer::triggerRepaint(GstBuffer* buffer) 14218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 14222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch g_return_if_fail(GST_IS_BUFFER(buffer)); 14232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch gst_buffer_replace(&m_buffer, buffer); 14248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_player->repaint(); 14258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 14268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1427dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::paint(GraphicsContext* context, const IntRect& rect) 14288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 14298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (context->paintingDisabled()) 14308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 14318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1432cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (!m_player->visible()) 14338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 14342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1435cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (!m_buffer) 1436cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return; 1437cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 1438dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block RefPtr<ImageGStreamer> gstImage = ImageGStreamer::createImage(m_buffer); 1439dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!gstImage) 1440dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return; 1441cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 1442a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch context->drawImage(reinterpret_cast<Image*>(gstImage->image().get()), ColorSpaceSRGB, 1443dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block rect, CompositeCopy, false); 14448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 14458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1446231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic HashSet<String> mimeTypeCache() 1447231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 1448231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1449d0825bca7fe65beaee391d30da42e937db621564Steve Block doGstInit(); 1450231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1451dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block DEFINE_STATIC_LOCAL(HashSet<String>, cache, ()); 1452231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block static bool typeListInitialized = false; 1453231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1454231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!typeListInitialized) { 1455643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // Build a whitelist of mime-types known to be supported by 1456643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // GStreamer. 1457643ca7872b450ea4efacab6188849e5aac2ba161Steve Block HashSet<String> handledApplicationSubtypes; 1458643ca7872b450ea4efacab6188849e5aac2ba161Steve Block handledApplicationSubtypes.add(String("ogg")); 1459643ca7872b450ea4efacab6188849e5aac2ba161Steve Block handledApplicationSubtypes.add(String("vnd.rn-realmedia")); 1460643ca7872b450ea4efacab6188849e5aac2ba161Steve Block handledApplicationSubtypes.add(String("x-pn-realaudio")); 1461231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1462231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block GList* factories = gst_type_find_factory_get_list(); 1463231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block for (GList* iterator = factories; iterator; iterator = iterator->next) { 1464231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block GstTypeFindFactory* factory = GST_TYPE_FIND_FACTORY(iterator->data); 1465231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block GstCaps* caps = gst_type_find_factory_get_caps(factory); 14665ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen gchar** extensions; 1467231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1468643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!caps) 1469643ca7872b450ea4efacab6188849e5aac2ba161Steve Block continue; 1470643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 1471643ca7872b450ea4efacab6188849e5aac2ba161Steve Block for (guint structureIndex = 0; structureIndex < gst_caps_get_size(caps); structureIndex++) { 1472643ca7872b450ea4efacab6188849e5aac2ba161Steve Block GstStructure* structure = gst_caps_get_structure(caps, structureIndex); 1473643ca7872b450ea4efacab6188849e5aac2ba161Steve Block const gchar* name = gst_structure_get_name(structure); 1474643ca7872b450ea4efacab6188849e5aac2ba161Steve Block bool cached = false; 1475643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 1476643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // These formats are supported by GStreamer, but not 1477643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // correctly advertised. 14782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (g_str_equal(name, "video/x-h264")) { 1479231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block cache.add(String("video/mp4")); 14802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block cached = true; 14812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 14822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 14832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (g_str_equal(name, "audio/x-m4a")) { 1484231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block cache.add(String("audio/aac")); 14850617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen cache.add(String("audio/mp4")); 14862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block cache.add(String("audio/x-m4a")); 1487643ca7872b450ea4efacab6188849e5aac2ba161Steve Block cached = true; 1488231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 1489231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1490cad810f21b803229eb11403f9209855525a25d57Steve Block if (g_str_equal(name, "application/x-3gp")) { 1491cad810f21b803229eb11403f9209855525a25d57Steve Block cache.add(String("audio/3gpp")); 1492cad810f21b803229eb11403f9209855525a25d57Steve Block cache.add(String("video/3gpp")); 1493cad810f21b803229eb11403f9209855525a25d57Steve Block cache.add(String("application/x-3gp")); 1494cad810f21b803229eb11403f9209855525a25d57Steve Block cached = true; 1495cad810f21b803229eb11403f9209855525a25d57Steve Block } 1496cad810f21b803229eb11403f9209855525a25d57Steve Block 1497643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (g_str_equal(name, "video/x-theora")) { 1498231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block cache.add(String("video/ogg")); 1499643ca7872b450ea4efacab6188849e5aac2ba161Steve Block cached = true; 1500643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 1501231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1502643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (g_str_equal(name, "audio/x-vorbis")) { 1503643ca7872b450ea4efacab6188849e5aac2ba161Steve Block cache.add(String("audio/ogg")); 15045abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick cache.add(String("audio/x-vorbis+ogg")); 1505643ca7872b450ea4efacab6188849e5aac2ba161Steve Block cached = true; 1506643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 1507231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1508643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (g_str_equal(name, "audio/x-wav")) { 1509643ca7872b450ea4efacab6188849e5aac2ba161Steve Block cache.add(String("audio/wav")); 15100617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen cache.add(String("audio/x-wav")); 1511643ca7872b450ea4efacab6188849e5aac2ba161Steve Block cached = true; 1512643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 1513231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1514643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (g_str_equal(name, "audio/mpeg")) { 1515643ca7872b450ea4efacab6188849e5aac2ba161Steve Block cache.add(String(name)); 15160617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen cache.add(String("audio/x-mpeg")); 1517643ca7872b450ea4efacab6188849e5aac2ba161Steve Block cached = true; 1518643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 1519643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // This is what we are handling: 1520643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // mpegversion=(int)1, layer=(int)[ 1, 3 ] 1521643ca7872b450ea4efacab6188849e5aac2ba161Steve Block gint mpegVersion = 0; 1522643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (gst_structure_get_int(structure, "mpegversion", &mpegVersion) && (mpegVersion == 1)) { 1523643ca7872b450ea4efacab6188849e5aac2ba161Steve Block const GValue* layer = gst_structure_get_value(structure, "layer"); 1524643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (G_VALUE_TYPE(layer) == GST_TYPE_INT_RANGE) { 1525643ca7872b450ea4efacab6188849e5aac2ba161Steve Block gint minLayer = gst_value_get_int_range_min(layer); 1526643ca7872b450ea4efacab6188849e5aac2ba161Steve Block gint maxLayer = gst_value_get_int_range_max(layer); 1527d0825bca7fe65beaee391d30da42e937db621564Steve Block if (minLayer <= 1 && 1 <= maxLayer) 1528231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block cache.add(String("audio/mp1")); 1529d0825bca7fe65beaee391d30da42e937db621564Steve Block if (minLayer <= 2 && 2 <= maxLayer) 1530231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block cache.add(String("audio/mp2")); 15310617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen if (minLayer <= 3 && 3 <= maxLayer) { 15320617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen cache.add(String("audio/x-mp3")); 1533231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block cache.add(String("audio/mp3")); 15340617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen } 1535231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 1536231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 1537643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 1538231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1539643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!cached) { 1540643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // GStreamer plugins can be capable of supporting 1541643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // types which WebKit supports by default. In that 1542643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // case, we should not consider these types 1543643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // supportable by GStreamer. Examples of what 1544643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // GStreamer can support but should not be added: 1545643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // text/plain, text/html, image/jpeg, 1546643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // application/xml 1547643ca7872b450ea4efacab6188849e5aac2ba161Steve Block gchar** mimetype = g_strsplit(name, "/", 2); 1548643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (g_str_equal(mimetype[0], "audio") 1549643ca7872b450ea4efacab6188849e5aac2ba161Steve Block || g_str_equal(mimetype[0], "video") 1550643ca7872b450ea4efacab6188849e5aac2ba161Steve Block || (g_str_equal(mimetype[0], "application") 1551643ca7872b450ea4efacab6188849e5aac2ba161Steve Block && handledApplicationSubtypes.contains(String(mimetype[1])))) 1552643ca7872b450ea4efacab6188849e5aac2ba161Steve Block cache.add(String(name)); 15532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch else if (g_str_equal(name, "application/x-hls")) 15542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch cache.add(String("application/vnd.apple.mpegurl")); 15552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 1556643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 1557643ca7872b450ea4efacab6188849e5aac2ba161Steve Block g_strfreev(mimetype); 1558231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 15595ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 15605ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // As a last resort try some special cases depending 15615ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // on the file extensions registered with the typefind 15625ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // factory. 15635ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (!cached && (extensions = gst_type_find_factory_get_extensions(factory))) { 15645ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen for (int index = 0; extensions[index]; index++) { 15655ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (g_str_equal(extensions[index], "m4v")) 15665ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen cache.add(String("video/x-m4v")); 15672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 15682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Workaround for 15692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // https://bugzilla.gnome.org/show_bug.cgi?id=640709. 15702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // typefindfunctions <= 0.10.32 doesn't 15712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // register the H264 typefinder correctly so 15722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // as a workaround we check the registered 15732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // file extensions for it. 15742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (g_str_equal(extensions[index], "h264")) 15752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block cache.add(String("video/mp4")); 15765ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen } 15775ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen } 1578231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 1579231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 1580231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1581231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block gst_plugin_feature_list_free(factories); 1582231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block typeListInitialized = true; 1583231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 1584231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1585231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return cache; 1586231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 1587231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1588dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::getSupportedTypes(HashSet<String>& types) 15898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1590231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block types = mimeTypeCache(); 15918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 15928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1593dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockMediaPlayer::SupportsType MediaPlayerPrivateGStreamer::supportsType(const String& type, const String& codecs) 15948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 1595231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (type.isNull() || type.isEmpty()) 1596231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return MediaPlayer::IsNotSupported; 1597231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1598231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // spec says we should not return "probably" if the codecs string is empty 1599231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (mimeTypeCache().contains(type)) 1600231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported; 1601231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return MediaPlayer::IsNotSupported; 1602231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 1603231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1604dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool MediaPlayerPrivateGStreamer::hasSingleSecurityOrigin() const 1605231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 1606231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return true; 1607231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 1608231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1609dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool MediaPlayerPrivateGStreamer::supportsFullscreen() const 1610231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 1611f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) 1612f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // See <rdar://problem/7389945> 1613f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return false; 1614f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#else 1615231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return true; 1616f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif 16178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 16188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1619e78cbe89e6f337f2f1fe40315be88f742b547151Steve BlockPlatformMedia MediaPlayerPrivateGStreamer::platformMedia() const 1620e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block{ 1621e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block PlatformMedia p; 1622e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block p.type = PlatformMedia::GStreamerGWorldType; 1623e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block p.media.gstreamerGWorld = m_gstGWorld.get(); 1624e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block return p; 1625e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block} 1626e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 1627dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::setPreload(MediaPlayer::Preload preload) 1628692e5dbf12901edacf14812a6fae25462920af42Steve Block{ 1629692e5dbf12901edacf14812a6fae25462920af42Steve Block ASSERT(m_playBin); 1630692e5dbf12901edacf14812a6fae25462920af42Steve Block 1631dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_preload = preload; 1632dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1633692e5dbf12901edacf14812a6fae25462920af42Steve Block GstPlayFlags flags; 1634692e5dbf12901edacf14812a6fae25462920af42Steve Block g_object_get(m_playBin, "flags", &flags, NULL); 1635dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (preload == MediaPlayer::None) 1636692e5dbf12901edacf14812a6fae25462920af42Steve Block g_object_set(m_playBin, "flags", flags & ~GST_PLAY_FLAG_DOWNLOAD, NULL); 1637dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else 1638dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block g_object_set(m_playBin, "flags", flags | GST_PLAY_FLAG_DOWNLOAD, NULL); 1639dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1640dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (m_delayingLoad && m_preload != MediaPlayer::None) { 1641dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_delayingLoad = false; 1642dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block commitLoad(); 1643dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 1644692e5dbf12901edacf14812a6fae25462920af42Steve Block} 1645692e5dbf12901edacf14812a6fae25462920af42Steve Block 1646dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid MediaPlayerPrivateGStreamer::createGSTPlayBin() 16478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 16488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!m_playBin); 1649231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_playBin = gst_element_factory_make("playbin2", "play"); 16508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1651e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block m_gstGWorld = GStreamerGWorld::createGWorld(m_playBin); 1652e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 16538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project GstBus* bus = gst_pipeline_get_bus(GST_PIPELINE(m_playBin)); 16548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gst_bus_add_signal_watch(bus); 1655cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block g_signal_connect(bus, "message", G_CALLBACK(mediaPlayerPrivateMessageCallback), this); 16568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gst_object_unref(bus); 16578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 165881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch g_object_set(m_playBin, "mute", m_player->muted(), NULL); 1659f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1660d0825bca7fe65beaee391d30da42e937db621564Steve Block g_signal_connect(m_playBin, "notify::volume", G_CALLBACK(mediaPlayerPrivateVolumeChangedCallback), this); 1661d0825bca7fe65beaee391d30da42e937db621564Steve Block g_signal_connect(m_playBin, "notify::source", G_CALLBACK(mediaPlayerPrivateSourceChangedCallback), this); 16625e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block g_signal_connect(m_playBin, "notify::mute", G_CALLBACK(mediaPlayerPrivateMuteChangedCallback), this); 16632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch g_signal_connect(m_playBin, "video-changed", G_CALLBACK(mediaPlayerPrivateVideoChangedCallback), this); 16642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch g_signal_connect(m_playBin, "audio-changed", G_CALLBACK(mediaPlayerPrivateAudioChangedCallback), this); 16658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 166606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen m_webkitVideoSink = webkit_video_sink_new(); 166706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 166806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen g_signal_connect(m_webkitVideoSink, "repaint-requested", G_CALLBACK(mediaPlayerPrivateRepaintCallback), this); 166906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 167006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen m_videoSinkBin = gst_bin_new("sink"); 167106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen GstElement* videoTee = gst_element_factory_make("tee", "videoTee"); 167206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen GstElement* queue = gst_element_factory_make("queue", 0); 16734576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang GstElement* identity = gst_element_factory_make("identity", "videoValve"); 1674231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 167506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen // Take ownership. 16764576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang gst_object_ref_sink(m_videoSinkBin); 167706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 167806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen // Build a new video sink consisting of a bin containing a tee 167906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen // (meant to distribute data to multiple video sinks) and our 168006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen // internal video sink. For fullscreen we create an autovideosink 168106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen // and initially block the data flow towards it and configure it 168206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 16834576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang gst_bin_add_many(GST_BIN(m_videoSinkBin), videoTee, queue, identity, NULL); 168406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 168506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen // Link a new src pad from tee to queue1. 168606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen GstPad* srcPad = gst_element_get_request_pad(videoTee, "src%d"); 168706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen GstPad* sinkPad = gst_element_get_static_pad(queue, "sink"); 168806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen gst_pad_link(srcPad, sinkPad); 168906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen gst_object_unref(GST_OBJECT(srcPad)); 169006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen gst_object_unref(GST_OBJECT(sinkPad)); 1691d0825bca7fe65beaee391d30da42e937db621564Steve Block 16922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch GstElement* actualVideoSink = 0; 16932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_fpsSink = gst_element_factory_make("fpsdisplaysink", "sink"); 16942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (m_fpsSink) { 16952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // The verbose property has been added in -bad 0.10.22. Making 16962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // this whole code depend on it because we don't want 16972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // fpsdiplaysink to spit data on stdout. 16982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch GstElementFactory* factory = GST_ELEMENT_FACTORY(GST_ELEMENT_GET_CLASS(m_fpsSink)->elementfactory); 16992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (gst_plugin_feature_check_version(GST_PLUGIN_FEATURE(factory), 0, 10, 22)) { 17002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch g_object_set(m_fpsSink, "silent", TRUE , NULL); 17012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // Turn off text overlay unless logging is enabled. 17032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch WTFLogChannel* channel = getChannelFromName("Media"); 17042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (channel->state != WTFLogChannelOn) 17052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch g_object_set(m_fpsSink, "text-overlay", FALSE , NULL); 17062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_fpsSink), "video-sink")) { 17082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch g_object_set(m_fpsSink, "video-sink", m_webkitVideoSink, NULL); 17092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch gst_bin_add(GST_BIN(m_videoSinkBin), m_fpsSink); 17102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch actualVideoSink = m_fpsSink; 17112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } else 17122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch m_fpsSink = 0; 17132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } else 1714d0825bca7fe65beaee391d30da42e937db621564Steve Block m_fpsSink = 0; 17152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 17162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (!m_fpsSink) { 171806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen gst_bin_add(GST_BIN(m_videoSinkBin), m_webkitVideoSink); 17192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch actualVideoSink = m_webkitVideoSink; 17202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 17212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch ASSERT(actualVideoSink); 1723f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if GST_CHECK_VERSION(0, 10, 30) 1724f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // Faster elements linking, if possible. 1725f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch gst_element_link_pads_full(queue, "src", identity, "sink", GST_PAD_LINK_CHECK_NOTHING); 17262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch gst_element_link_pads_full(identity, "src", actualVideoSink, "sink", GST_PAD_LINK_CHECK_NOTHING); 1727f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#else 17282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch gst_element_link_many(queue, identity, actualVideoSink, NULL); 1729f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif 173006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 173106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen // Add a ghostpad to the bin so it can proxy to tee. 173206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen GstPad* pad = gst_element_get_static_pad(videoTee, "sink"); 173306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen gst_element_add_pad(m_videoSinkBin, gst_ghost_pad_new("sink", pad)); 173406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen gst_object_unref(GST_OBJECT(pad)); 17358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 173606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen // Set the bin as video sink of playbin. 173706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen g_object_set(m_playBin, "video-sink", m_videoSinkBin, NULL); 17382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch pad = gst_element_get_static_pad(m_webkitVideoSink, "sink"); 17412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (pad) { 17422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch g_signal_connect(pad, "notify::caps", G_CALLBACK(mediaPlayerPrivateVideoSinkCapsChangedCallback), this); 17432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch gst_object_unref(GST_OBJECT(pad)); 17442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch } 17452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 17468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 17478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 17488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 17498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1750bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#endif // USE(GSTREAMER) 1751