Changeset 53617 in webkit


Ignore:
Timestamp:
Jan 21, 2010 1:43:18 AM (14 years ago)
Author:
Philippe Normand
Message:

2010-01-13 Philippe Normand <pnormand@igalia.com>

Reviewed by Oliver Hunt.

[GTK] handle media redirections
https://bugs.webkit.org/show_bug.cgi?id=33539

Media redirections support.

  • platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp: (WebCore::mediaPlayerPrivateMessageCallback): (WebCore::MediaPlayerPrivate::MediaPlayerPrivate): (WebCore::MediaPlayerPrivate::~MediaPlayerPrivate): (WebCore::MediaPlayerPrivate::mediaLocationChanged): (WebCore::MediaPlayerPrivate::loadNextLocation):
  • platform/graphics/gtk/MediaPlayerPrivateGStreamer.h: (WebCore::MediaPlayerPrivate::pipelineReset):
Location:
trunk/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r53611 r53617  
     12010-01-13  Philippe Normand  <pnormand@igalia.com>
     2
     3        Reviewed by Oliver Hunt.
     4
     5        [GTK] handle media redirections
     6        https://bugs.webkit.org/show_bug.cgi?id=33539
     7
     8        Media redirections support.
     9
     10        * platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp:
     11        (WebCore::mediaPlayerPrivateMessageCallback):
     12        (WebCore::MediaPlayerPrivate::MediaPlayerPrivate):
     13        (WebCore::MediaPlayerPrivate::~MediaPlayerPrivate):
     14        (WebCore::MediaPlayerPrivate::mediaLocationChanged):
     15        (WebCore::MediaPlayerPrivate::loadNextLocation):
     16        * platform/graphics/gtk/MediaPlayerPrivateGStreamer.h:
     17        (WebCore::MediaPlayerPrivate::pipelineReset):
     18
    1192010-01-21  No'am Rosenthal  <noam.rosenthal@nokia.com>
    220
  • trunk/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp

    r53329 r53617  
    3737#include "NotImplemented.h"
    3838#include "ScrollView.h"
     39#include "SecurityOrigin.h"
    3940#include "TimeRanges.h"
    4041#include "VideoSinkGStreamer.h"
     
    6061    MediaPlayerPrivate* mp = reinterpret_cast<MediaPlayerPrivate*>(data);
    6162    gint percent = 0;
     63    bool issueError = true;
     64    bool attemptNextLocation = false;
     65
     66    if (message->structure) {
     67        const gchar* messageTypeName = gst_structure_get_name(message->structure);
     68
     69        // Redirect messages are sent from elements, like qtdemux, to
     70        // notify of the new location(s) of the media.
     71        if (!g_strcmp0(messageTypeName, "redirect")) {
     72            mp->mediaLocationChanged(message);
     73            return true;
     74        }
     75    }
    6276
    6377    switch (GST_MESSAGE_TYPE(message)) {
    6478    case GST_MESSAGE_ERROR:
     79        if (mp && mp->pipelineReset())
     80            break;
    6581        gst_message_parse_error(message, &err.outPtr(), &debug.outPtr());
    6682        LOG_VERBOSE(Media, "Error: %d, %s", err->code,  err->message);
     
    7389            || err->code == GST_RESOURCE_ERROR_NOT_FOUND)
    7490            error = MediaPlayer::FormatError;
    75         else if (err->domain == GST_STREAM_ERROR)
     91        else if (err->domain == GST_STREAM_ERROR) {
    7692            error = MediaPlayer::DecodeError;
    77         else if (err->domain == GST_RESOURCE_ERROR)
     93            attemptNextLocation = true;
     94        } else if (err->domain == GST_RESOURCE_ERROR)
    7895            error = MediaPlayer::NetworkError;
    7996
    80         if (mp)
    81             mp->loadingFailed(error);
     97        if (mp) {
     98            if (attemptNextLocation)
     99                issueError = !mp->loadNextLocation();
     100            if (issueError)
     101                mp->loadingFailed(error);
     102        }
    82103        break;
    83104    case GST_MESSAGE_EOS:
     
    209230    , m_size(IntSize())
    210231    , m_buffer(0)
     232    , m_mediaLocations(0)
     233    , m_mediaLocationCurrentIndex(0)
     234    , m_resetPipeline(false)
    211235    , m_paused(true)
    212236    , m_seeking(false)
     
    228252        gst_buffer_unref(m_buffer);
    229253    m_buffer = 0;
     254
     255    if (m_mediaLocations) {
     256        gst_structure_free(m_mediaLocations);
     257        m_mediaLocations = 0;
     258    }
    230259
    231260    if (m_playBin) {
     
    629658            gst_element_state_get_name(pending));
    630659
     660        m_resetPipeline = state <= GST_STATE_READY;
     661
    631662        if (state == GST_STATE_READY)
    632663            m_readyState = MediaPlayer::HaveNothing;
     
    701732        m_player->readyStateChanged();
    702733    }
     734}
     735
     736void MediaPlayerPrivate::mediaLocationChanged(GstMessage* message)
     737{
     738    if (m_mediaLocations)
     739        gst_structure_free(m_mediaLocations);
     740
     741    if (message->structure) {
     742        // This structure can contain:
     743        // - both a new-location string and embedded locations structure
     744        // - or only a new-location string.
     745        m_mediaLocations = gst_structure_copy(message->structure);
     746        const GValue* locations = gst_structure_get_value(m_mediaLocations, "locations");
     747
     748        if (locations)
     749            m_mediaLocationCurrentIndex = gst_value_list_get_size(locations) -1;
     750
     751        loadNextLocation();
     752    }
     753}
     754
     755bool MediaPlayerPrivate::loadNextLocation()
     756{
     757    if (!m_mediaLocations)
     758        return false;
     759
     760    const GValue* locations = gst_structure_get_value(m_mediaLocations, "locations");
     761    const gchar* newLocation = 0;
     762
     763    if (!locations) {
     764        // Fallback on new-location string.
     765        newLocation = gst_structure_get_string(m_mediaLocations, "new-location");
     766        if (!newLocation)
     767            return false;
     768    }
     769
     770    if (!newLocation) {
     771        if (m_mediaLocationCurrentIndex < 0) {
     772            m_mediaLocations = 0;
     773            return false;
     774        }
     775
     776        const GValue* location = gst_value_list_get_value(locations,
     777                                                          m_mediaLocationCurrentIndex);
     778        const GstStructure* structure = gst_value_get_structure(location);
     779
     780        if (!structure) {
     781            m_mediaLocationCurrentIndex--;
     782            return false;
     783        }
     784
     785        newLocation = gst_structure_get_string(structure, "new-location");
     786    }
     787
     788    if (newLocation) {
     789        // Found a candidate. new-location is not always an absolute url
     790        // though. We need to take the base of the current url and
     791        // append the value of new-location to it.
     792
     793        gchar* currentLocation = 0;
     794        g_object_get(m_playBin, "uri", &currentLocation, NULL);
     795
     796        KURL currentUrl(KURL(), currentLocation);
     797        g_free(currentLocation);
     798
     799        KURL newUrl;
     800
     801        if (gst_uri_is_valid(newLocation))
     802            newUrl = KURL(KURL(), newLocation);
     803        else
     804            newUrl = KURL(KURL(), currentUrl.baseAsString() + newLocation);
     805
     806        RefPtr<SecurityOrigin> securityOrigin = SecurityOrigin::create(currentUrl);
     807        if (securityOrigin->canRequest(newUrl)) {
     808            LOG_VERBOSE(Media, "New media url: %s", newUrl.string().utf8().data());
     809
     810            // Reset player states.
     811            m_networkState = MediaPlayer::Loading;
     812            m_player->networkStateChanged();
     813            m_readyState = MediaPlayer::HaveNothing;
     814            m_player->readyStateChanged();
     815
     816            // Reset pipeline state.
     817            m_resetPipeline = true;
     818            gst_element_set_state(m_playBin, GST_STATE_READY);
     819
     820            GstState state;
     821            gst_element_get_state(m_playBin, &state, 0, 0);
     822            if (state <= GST_STATE_READY) {
     823                // Set the new uri and start playing.
     824                g_object_set(m_playBin, "uri", newUrl.string().utf8().data(), NULL);
     825                gst_element_set_state(m_playBin, GST_STATE_PLAYING);
     826                return true;
     827            }
     828        }
     829    }
     830    m_mediaLocationCurrentIndex--;
     831    return false;
     832
    703833}
    704834
  • trunk/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h

    r53255 r53617  
    6262            void load(const String &url);
    6363            void cancelLoad();
     64            bool loadNextLocation();
    6465
    6566            void play();
     
    9293            void setSize(const IntSize&);
    9394
     95            void mediaLocationChanged(GstMessage*);
    9496            void loadStateChanged();
    9597            void sizeChanged();
     
    105107
    106108            bool supportsFullscreen() const;
     109
     110            bool pipelineReset() const { return m_resetPipeline; }
    107111
    108112        private:
     
    139143            IntSize m_size;
    140144            GstBuffer* m_buffer;
    141 
     145            GstStructure* m_mediaLocations;
     146            gint m_mediaLocationCurrentIndex;
     147            bool m_resetPipeline;
    142148            bool m_paused;
    143149            bool m_seeking;
Note: See TracChangeset for help on using the changeset viewer.