⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mediaplayerprivategstreamer.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2007, 2009 Apple Inc.  All rights reserved. * Copyright (C) 2007 Collabora Ltd.  All rights reserved. * Copyright (C) 2007 Alp Toker <alp@atoker.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * aint with this library; see the file COPYING.LIB.  If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */#include "config.h"#if ENABLE(VIDEO)#include "MediaPlayerPrivateGStreamer.h"#include "VideoSinkGStreamer.h"#include "CString.h"#include "GraphicsContext.h"#include "IntRect.h"#include "KURL.h"#include "MIMETypeRegistry.h"#include "MediaPlayer.h"#include "NotImplemented.h"#include "ScrollView.h"#include "Widget.h"#include <wtf/GOwnPtr.h>#include <gdk/gdkx.h>#include <gst/base/gstbasesrc.h>#include <gst/gst.h>#include <gst/interfaces/mixer.h>#include <gst/interfaces/xoverlay.h>#include <gst/video/video.h>#include <limits>#include <math.h>using namespace std;namespace WebCore {gboolean mediaPlayerPrivateErrorCallback(GstBus* bus, GstMessage* message, gpointer data){    if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_ERROR)    {        GOwnPtr<GError> err;        GOwnPtr<gchar> debug;        gst_message_parse_error(message, &err.outPtr(), &debug.outPtr());        if (err->code == 3) {            LOG_VERBOSE(Media, "File not found");            MediaPlayerPrivate* mp = reinterpret_cast<MediaPlayerPrivate*>(data);            if (mp)                mp->loadingFailed();        } else            LOG_VERBOSE(Media, "Error: %d, %s", err->code,  err->message);    }    return true;}gboolean mediaPlayerPrivateEOSCallback(GstBus* bus, GstMessage* message, gpointer data){    if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_EOS)    {        LOG_VERBOSE(Media, "End of Stream");        MediaPlayerPrivate* mp = reinterpret_cast<MediaPlayerPrivate*>(data);        mp->didEnd();    }    return true;}gboolean mediaPlayerPrivateStateCallback(GstBus* bus, GstMessage* message, gpointer data){    if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_STATE_CHANGED)    {        MediaPlayerPrivate* mp = reinterpret_cast<MediaPlayerPrivate*>(data);        mp->updateStates();    }    return true;}gboolean mediaPlayerPrivateBufferingCallback(GstBus* bus, GstMessage* message, gpointer data){    if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_BUFFERING)    {        gint percent = 0;        gst_message_parse_buffering(message, &percent);        LOG_VERBOSE(Media, "Buffering %d", percent);    }    return true;}MediaPlayerPrivateInterface* MediaPlayerPrivate::create(MediaPlayer* player) {     return new MediaPlayerPrivate(player);}void MediaPlayerPrivate::registerMediaEngine(MediaEngineRegistrar registrar){    if (isAvailable())        registrar(create, getSupportedTypes, supportsType);}MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)    : m_player(player)    , m_playBin(0)    , m_videoSink(0)    , m_source(0)    , m_rate(1.0f)    , m_endTime(numeric_limits<float>::infinity())    , m_isEndReached(false)    , m_volume(0.5f)    , m_networkState(MediaPlayer::Empty)    , m_readyState(MediaPlayer::DataUnavailable)    , m_startedPlaying(false)    , m_isStreaming(false)    , m_size(IntSize())    , m_visible(true){    static bool gstInitialized = false;    // FIXME: We should pass the arguments from the command line    if (!gstInitialized) {        gst_init(0, NULL);        gstInitialized = true;    }    // FIXME: The size shouldn't be fixed here, this is just a quick hack.    m_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 640, 480);}MediaPlayerPrivate::~MediaPlayerPrivate(){    if (m_surface)        cairo_surface_destroy(m_surface);    if (m_playBin) {        gst_element_set_state(m_playBin, GST_STATE_NULL);        gst_object_unref(GST_OBJECT(m_playBin));    }}void MediaPlayerPrivate::load(const String& url){    LOG_VERBOSE(Media, "Load %s", url.utf8().data());    if (m_networkState != MediaPlayer::Loading) {        m_networkState = MediaPlayer::Loading;        m_player->networkStateChanged();    }    if (m_readyState != MediaPlayer::DataUnavailable) {        m_readyState = MediaPlayer::DataUnavailable;        m_player->readyStateChanged();    }    createGSTPlayBin(url);    pause();}void MediaPlayerPrivate::play(){    LOG_VERBOSE(Media, "Play");    // When end reached, rewind for Test video-seek-past-end-playing    if (m_isEndReached)        seek(0);    m_isEndReached = false;    gst_element_set_state(m_playBin, GST_STATE_PLAYING);    m_startedPlaying = true;}void MediaPlayerPrivate::pause(){    LOG_VERBOSE(Media, "Pause");    gst_element_set_state(m_playBin, GST_STATE_PAUSED);    m_startedPlaying = false;}float MediaPlayerPrivate::duration() const{    if (!m_playBin)        return 0.0;    GstFormat fmt = GST_FORMAT_TIME;    gint64 len = 0;    if (gst_element_query_duration(m_playBin, &fmt, &len))        LOG_VERBOSE(Media, "Duration: %" GST_TIME_FORMAT, GST_TIME_ARGS(len));    else        LOG_VERBOSE(Media, "Duration query failed ");    if ((GstClockTime)len == GST_CLOCK_TIME_NONE) {        m_isStreaming = true;        return numeric_limits<float>::infinity();    }    return (float) (len / 1000000000.0);    // FIXME: handle 3.14.9.5 properly}float MediaPlayerPrivate::currentTime() const{    if (!m_playBin)        return 0;    // Necessary as sometimes, gstreamer return 0:00 at the EOS    if (m_isEndReached)        return m_endTime;    float ret;    GstQuery* query = gst_query_new_position(GST_FORMAT_TIME);    if (gst_element_query(m_playBin, query)) {        gint64 position;        gst_query_parse_position(query, NULL, &position);        ret = (float) (position / 1000000000.0);        LOG_VERBOSE(Media, "Position %" GST_TIME_FORMAT, GST_TIME_ARGS(position));    } else {        LOG_VERBOSE(Media, "Position query failed...");        ret = 0.0;    }    gst_query_unref(query);    return ret;}void MediaPlayerPrivate::seek(float time){    GstClockTime sec = (GstClockTime)(time * GST_SECOND);    if (!m_playBin)        return;    if (m_isStreaming)        return;    LOG_VERBOSE(Media, "Seek: %" GST_TIME_FORMAT, GST_TIME_ARGS(sec));    // FIXME: What happens when the seeked position is not available?    if (!gst_element_seek( m_playBin, m_rate,            GST_FORMAT_TIME,            (GstSeekFlags)(GST_SEEK_FLAG_FLUSH),            GST_SEEK_TYPE_SET, sec,            GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE))        LOG_VERBOSE(Media, "Seek to %f failed", time);}void MediaPlayerPrivate::setEndTime(float time){    if (!m_playBin)        return;    if (m_isStreaming)        return;    if (m_endTime != time) {        m_endTime = time;        GstClockTime start = (GstClockTime)(currentTime() * GST_SECOND);        GstClockTime end   = (GstClockTime)(time * GST_SECOND);        LOG_VERBOSE(Media, "setEndTime: %" GST_TIME_FORMAT, GST_TIME_ARGS(end));        // FIXME: What happens when the seeked position is not available?        if (!gst_element_seek(m_playBin, m_rate,                GST_FORMAT_TIME,                (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE),                GST_SEEK_TYPE_SET, start,                GST_SEEK_TYPE_SET, end ))            LOG_VERBOSE(Media, "Seek to %f failed", time);    }}void MediaPlayerPrivate::startEndPointTimerIfNeeded(){    notImplemented();}void MediaPlayerPrivate::cancelSeek(){    notImplemented();}void MediaPlayerPrivate::endPointTimerFired(Timer<MediaPlayerPrivate>*){    notImplemented();}bool MediaPlayerPrivate::paused() const{    return !m_startedPlaying;}bool MediaPlayerPrivate::seeking() const{    return false;}// Returns the size of the videoIntSize MediaPlayerPrivate::naturalSize() const{    if (!hasVideo())        return IntSize();    int x = 0, y = 0;    if (GstPad* pad = gst_element_get_static_pad(m_videoSink, "sink")) {        gst_video_get_size(GST_PAD(pad), &x, &y);        gst_object_unref(GST_OBJECT(pad));    }    return IntSize(x, y);}bool MediaPlayerPrivate::hasVideo() const{    gint currentVideo = -1;    if (m_playBin)        g_object_get(G_OBJECT(m_playBin), "current-video", &currentVideo, NULL);    return currentVideo > -1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -