⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 192511 in webkit


Ignore:
Timestamp:
Nov 17, 2015, 1:57:42 AM (11 years ago)
Author:
Carlos Garcia Campos
Message:

[GStreamer] Use RunLoop instead of GMainLoop in AudioFileReaderGStreamer
​https://bugs.webkit.org/show_bug.cgi?id=151256

Reviewed by Žan Doberšek.

Use RunLoop instead of the platform specific code. The AudioBus
can be created from any thread, so we create a helper thread to
ensure we don't use the main RunLoop.

This patch also includes some code cleanups:

  • Uses smart pointers when possible.
  • Fixes uninitialized members in constructors.
  • Makes private members private.
  • Uses lambdas instead of static non-members functions.
  • nullptr instead of 0 in some places.
  • platform/audio/gstreamer/AudioFileReaderGStreamer.cpp:

(WebCore::AudioFileReader::createWeakPtr):
(WebCore::AudioFileReader::deinterleavePadAddedCallback):
(WebCore::AudioFileReader::deinterleaveReadyCallback):
(WebCore::AudioFileReader::decodebinPadAddedCallback):
(WebCore::AudioFileReader::AudioFileReader):
(WebCore::AudioFileReader::~AudioFileReader):
(WebCore::AudioFileReader::handleSample):
(WebCore::AudioFileReader::handleMessage):
(WebCore::AudioFileReader::handleNewDeinterleavePad):
(WebCore::AudioFileReader::deinterleavePadsConfigured):
(WebCore::AudioFileReader::plugDeinterleave):
(WebCore::AudioFileReader::decodeAudioForBusCreation):
(WebCore::AudioFileReader::createBus):
(WebCore::createBusFromAudioFile):
(WebCore::createBusFromInMemoryAudioFile):
(WebCore::onAppsinkPullRequiredCallback): Deleted.
(WebCore::messageCallback): Deleted.
(WebCore::onGStreamerDeinterleavePadAddedCallback): Deleted.
(WebCore::onGStreamerDeinterleaveReadyCallback): Deleted.
(WebCore::onGStreamerDecodebinPadAddedCallback): Deleted.

  • platform/graphics/gstreamer/GRefPtrGStreamer.cpp:

(WTF::adoptGRef):
(WTF::refGPtr<GstBufferList>):
(WTF::derefGPtr<GstBufferList>):

  • platform/graphics/gstreamer/GRefPtrGStreamer.h:
Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r192503 r192511  
     12015-11-17  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GStreamer] Use RunLoop instead of GMainLoop in AudioFileReaderGStreamer
     4        https://bugs.webkit.org/show_bug.cgi?id=151256
     5
     6        Reviewed by Žan Doberšek.
     7
     8        Use RunLoop instead of the platform specific code. The AudioBus
     9        can be created from any thread, so we create a helper thread to
     10        ensure we don't use the main RunLoop.
     11
     12        This patch also includes some code cleanups:
     13          - Uses smart pointers when possible.
     14          - Fixes uninitialized members in constructors.
     15          - Makes private members private.
     16          - Uses lambdas instead of static non-members functions.
     17          - nullptr instead of 0 in some places.
     18
     19        * platform/audio/gstreamer/AudioFileReaderGStreamer.cpp:
     20        (WebCore::AudioFileReader::createWeakPtr):
     21        (WebCore::AudioFileReader::deinterleavePadAddedCallback):
     22        (WebCore::AudioFileReader::deinterleaveReadyCallback):
     23        (WebCore::AudioFileReader::decodebinPadAddedCallback):
     24        (WebCore::AudioFileReader::AudioFileReader):
     25        (WebCore::AudioFileReader::~AudioFileReader):
     26        (WebCore::AudioFileReader::handleSample):
     27        (WebCore::AudioFileReader::handleMessage):
     28        (WebCore::AudioFileReader::handleNewDeinterleavePad):
     29        (WebCore::AudioFileReader::deinterleavePadsConfigured):
     30        (WebCore::AudioFileReader::plugDeinterleave):
     31        (WebCore::AudioFileReader::decodeAudioForBusCreation):
     32        (WebCore::AudioFileReader::createBus):
     33        (WebCore::createBusFromAudioFile):
     34        (WebCore::createBusFromInMemoryAudioFile):
     35        (WebCore::onAppsinkPullRequiredCallback): Deleted.
     36        (WebCore::messageCallback): Deleted.
     37        (WebCore::onGStreamerDeinterleavePadAddedCallback): Deleted.
     38        (WebCore::onGStreamerDeinterleaveReadyCallback): Deleted.
     39        (WebCore::onGStreamerDecodebinPadAddedCallback): Deleted.
     40        * platform/graphics/gstreamer/GRefPtrGStreamer.cpp:
     41        (WTF::adoptGRef):
     42        (WTF::refGPtr<GstBufferList>):
     43        (WTF::derefGPtr<GstBufferList>):
     44        * platform/graphics/gstreamer/GRefPtrGStreamer.h:
     45
    1462015-11-16  Eric Carlson  <eric.carlson@apple.com>
    247
  • trunk/Source/WebCore/platform/audio/gstreamer/AudioFileReaderGStreamer.cpp

    r190562 r192511  
    2323
    2424#include "AudioFileReader.h"
    25 
    2625#include "AudioBus.h"
    27 
     26#include "GRefPtrGStreamer.h"
    2827#include <gio/gio.h>
    2928#include <gst/app/gstappsink.h>
    3029#include <gst/audio/audio-info.h>
    3130#include <gst/gst.h>
     31#include <wtf/MainThread.h>
    3232#include <wtf/Noncopyable.h>
     33#include <wtf/RunLoop.h>
     34#include <wtf/Threading.h>
     35#include <wtf/WeakPtr.h>
    3336#include <wtf/glib/GRefPtr.h>
    34 #include <wtf/glib/GThreadSafeMainLoopSource.h>
    3537#include <wtf/glib/GUniquePtr.h>
    3638
    … …  
    4648    PassRefPtr<AudioBus> createBus(float sampleRate, bool mixToMono);
    4749
    48     GstFlowReturn handleSample(GstAppSink*);
    49     gboolean handleMessage(GstMessage*);
     50private:
     51    WeakPtr<AudioFileReader> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
     52
     53    static void deinterleavePadAddedCallback(AudioFileReader*, GstPad*);
     54    static void deinterleaveReadyCallback(AudioFileReader*);
     55    static void decodebinPadAddedCallback(AudioFileReader*, GstPad*);
     56
     57    void handleMessage(GstMessage*);
    5058    void handleNewDeinterleavePad(GstPad*);
    5159    void deinterleavePadsConfigured();
    5260    void plugDeinterleave(GstPad*);
    5361    void decodeAudioForBusCreation();
    54 
    55 private:
    56     const void* m_data;
    57     size_t m_dataSize;
    58     const char* m_filePath;
    59 
    60     float m_sampleRate;
    61     int m_channels;
    62     GstBufferList* m_frontLeftBuffers;
    63     GstBufferList* m_frontRightBuffers;
    64 
    65     GstElement* m_pipeline;
    66     unsigned m_channelSize;
     62    GstFlowReturn handleSample(GstAppSink*);
     63
     64    WeakPtrFactory<AudioFileReader> m_weakPtrFactory;
     65    RunLoop& m_runLoop;
     66    const void* m_data { nullptr };
     67    size_t m_dataSize { 0 };
     68    const char* m_filePath { nullptr };
     69
     70    float m_sampleRate { 0 };
     71    int m_channels { 0 };
     72    GRefPtr<GstBufferList> m_frontLeftBuffers;
     73    GRefPtr<GstBufferList> m_frontRightBuffers;
     74
     75    GRefPtr<GstElement> m_pipeline;
     76    unsigned m_channelSize { 0 };
    6777    GRefPtr<GstElement> m_decodebin;
    6878    GRefPtr<GstElement> m_deInterleave;
    69     GRefPtr<GMainLoop> m_loop;
    70     bool m_errorOccurred;
     79    bool m_errorOccurred { false };
    7180};
    7281
    … …  
    8493}
    8594
    86 static GstFlowReturn onAppsinkPullRequiredCallback(GstAppSink* sink, gpointer userData)
    87 {
    88     return static_cast<AudioFileReader*>(userData)->handleSample(sink);
    89 }
    90 
    91 gboolean messageCallback(GstBus*, GstMessage* message, AudioFileReader* reader)
    92 {
    93     return reader->handleMessage(message);
    94 }
    95 
    96 static void onGStreamerDeinterleavePadAddedCallback(GstElement*, GstPad* pad, AudioFileReader* reader)
     95void AudioFileReader::deinterleavePadAddedCallback(AudioFileReader* reader, GstPad* pad)
    9796{
    9897    reader->handleNewDeinterleavePad(pad);
    9998}
    10099
    101 static void onGStreamerDeinterleaveReadyCallback(GstElement*, AudioFileReader* reader)
     100void AudioFileReader::deinterleaveReadyCallback(AudioFileReader* reader)
    102101{
    103102    reader->deinterleavePadsConfigured();
    104103}
    105104
    106 static void onGStreamerDecodebinPadAddedCallback(GstElement*, GstPad* pad, AudioFileReader* reader)
     105void AudioFileReader::decodebinPadAddedCallback(AudioFileReader* reader, GstPad* pad)
    107106{
    108107    reader->plugDeinterleave(pad);
    … …  
    110109
    111110AudioFileReader::AudioFileReader(const char* filePath)
    112     : m_data(0)
    113     , m_dataSize(0)
     111    : m_weakPtrFactory(this)
     112    , m_runLoop(RunLoop::current())
    114113    , m_filePath(filePath)
    115     , m_channelSize(0)
    116     , m_errorOccurred(false)
    117114{
    118115}
    119116
    120117AudioFileReader::AudioFileReader(const void* data, size_t dataSize)
    121     : m_data(data)
     118    : m_weakPtrFactory(this)
     119    , m_runLoop(RunLoop::current())
     120    , m_data(data)
    122121    , m_dataSize(dataSize)
    123     , m_filePath(0)
    124     , m_channelSize(0)
    125     , m_errorOccurred(false)
    126122{
    127123}
    … …  
    130126{
    131127    if (m_pipeline) {
    132         GRefPtr<GstBus> bus = adoptGRef(gst_pipeline_get_bus(GST_PIPELINE(m_pipeline)));
     128        GRefPtr<GstBus> bus = adoptGRef(gst_pipeline_get_bus(GST_PIPELINE(m_pipeline.get())));
    133129        ASSERT(bus);
    134         g_signal_handlers_disconnect_by_func(bus.get(), reinterpret_cast<gpointer>(messageCallback), this);
    135 
    136         gst_element_set_state(m_pipeline, GST_STATE_NULL);
    137         gst_object_unref(GST_OBJECT(m_pipeline));
     130        gst_bus_set_sync_handler(bus.get(), nullptr, nullptr, nullptr);
     131
     132        gst_element_set_state(m_pipeline.get(), GST_STATE_NULL);
     133        m_pipeline = nullptr;
    138134    }
    139135
    140136    if (m_decodebin) {
    141         g_signal_handlers_disconnect_by_func(m_decodebin.get(), reinterpret_cast<gpointer>(onGStreamerDecodebinPadAddedCallback), this);
    142         m_decodebin.clear();
     137        g_signal_handlers_disconnect_matched(m_decodebin.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
     138        m_decodebin = nullptr;
    143139    }
    144140
    145141    if (m_deInterleave) {
    146         g_signal_handlers_disconnect_by_func(m_deInterleave.get(), reinterpret_cast<gpointer>(onGStreamerDeinterleavePadAddedCallback), this);
    147         g_signal_handlers_disconnect_by_func(m_deInterleave.get(), reinterpret_cast<gpointer>(onGStreamerDeinterleaveReadyCallback), this);
    148         m_deInterleave.clear();
    149     }
    150 
    151     gst_buffer_list_unref(m_frontLeftBuffers);
    152     gst_buffer_list_unref(m_frontRightBuffers);
     142        g_signal_handlers_disconnect_matched(m_deInterleave.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
     143        m_deInterleave = nullptr;
     144    }
    153145}
    154146
    155147GstFlowReturn AudioFileReader::handleSample(GstAppSink* sink)
    156148{
    157     GstSample* sample = gst_app_sink_pull_sample(sink);
     149    GRefPtr<GstSample> sample = adoptGRef(gst_app_sink_pull_sample(sink));
    158150    if (!sample)
    159151        return GST_FLOW_ERROR;
    160152
    161     GstBuffer* buffer = gst_sample_get_buffer(sample);
    162     if (!buffer) {
    163         gst_sample_unref(sample);
     153    GstBuffer* buffer = gst_sample_get_buffer(sample.get());
     154    if (!buffer)
    164155        return GST_FLOW_ERROR;
    165     }
    166 
    167     GstCaps* caps = gst_sample_get_caps(sample);
    168     if (!caps) {
    169         gst_sample_unref(sample);
     156
     157    GstCaps* caps = gst_sample_get_caps(sample.get());
     158    if (!caps)
    170159        return GST_FLOW_ERROR;
    171     }
    172160
    173161    GstAudioInfo info;
    … …  
    180168    case GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT:
    181169    case GST_AUDIO_CHANNEL_POSITION_MONO:
    182         gst_buffer_list_add(m_frontLeftBuffers, gst_buffer_ref(buffer));
     170        gst_buffer_list_add(m_frontLeftBuffers.get(), gst_buffer_ref(buffer));
    183171        m_channelSize += frames;
    184172        break;
    185173    case GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT:
    186         gst_buffer_list_add(m_frontRightBuffers, gst_buffer_ref(buffer));
     174        gst_buffer_list_add(m_frontRightBuffers.get(), gst_buffer_ref(buffer));
    187175        break;
    188176    default:
    … …  
    190178    }
    191179
    192     gst_sample_unref(sample);
    193180    return GST_FLOW_OK;
    194181}
    195182
    196 gboolean AudioFileReader::handleMessage(GstMessage* message)
    197 {
     183void AudioFileReader::handleMessage(GstMessage* message)
     184{
     185    ASSERT(&m_runLoop == &RunLoop::current());
     186
    198187    GUniqueOutPtr<GError> error;
    199188    GUniqueOutPtr<gchar> debug;
    … …  
    201190    switch (GST_MESSAGE_TYPE(message)) {
    202191    case GST_MESSAGE_EOS:
    203         g_main_loop_quit(m_loop.get());
     192        m_runLoop.stop();
    204193        break;
    205194    case GST_MESSAGE_WARNING:
    … …  
    211200        g_warning("Error: %d, %s. Debug output: %s", error->code,  error->message, debug.get());
    212201        m_errorOccurred = true;
    213         gst_element_set_state(m_pipeline, GST_STATE_NULL);
    214         g_main_loop_quit(m_loop.get());
     202        gst_element_set_state(m_pipeline.get(), GST_STATE_NULL);
     203        m_runLoop.stop();
    215204        break;
    216205    default:
    217206        break;
    218207    }
    219     return TRUE;
    220208}
    221209
    … …  
    229217    GstElement* sink = gst_element_factory_make("appsink", 0);
    230218
    231     GstAppSinkCallbacks callbacks;
    232     callbacks.eos = 0;
    233     callbacks.new_preroll = 0;
    234     callbacks.new_sample = onAppsinkPullRequiredCallback;
     219    static GstAppSinkCallbacks callbacks = {
     220        nullptr, // eos
     221        nullptr, // new_preroll
     222        // new_sample
     223        [](GstAppSink* sink, gpointer userData) -> GstFlowReturn {
     224            return static_cast<AudioFileReader*>(userData)->handleSample(sink);
     225        },
     226        { nullptr }
     227    };
    235228    gst_app_sink_set_callbacks(GST_APP_SINK(sink), &callbacks, this, 0);
    236229
    237230    g_object_set(sink, "sync", FALSE, NULL);
    238231
    239     gst_bin_add_many(GST_BIN(m_pipeline), queue, sink, NULL);
    240 
    241     GstPad* sinkPad = gst_element_get_static_pad(queue, "sink");
    242     gst_pad_link_full(pad, sinkPad, GST_PAD_LINK_CHECK_NOTHING);
    243     gst_object_unref(GST_OBJECT(sinkPad));
     232    gst_bin_add_many(GST_BIN(m_pipeline.get()), queue, sink, nullptr);
     233
     234    GRefPtr<GstPad> sinkPad = adoptGRef(gst_element_get_static_pad(queue, "sink"));
     235    gst_pad_link_full(pad, sinkPad.get(), GST_PAD_LINK_CHECK_NOTHING);
    244236
    245237    gst_element_link_pads_full(queue, "src", sink, "sink", GST_PAD_LINK_CHECK_NOTHING);
    … …  
    253245    // All deinterleave src pads are now available, let's roll to
    254246    // PLAYING so data flows towards the sinks and it can be retrieved.
    255     gst_element_set_state(m_pipeline, GST_STATE_PLAYING);
     247    gst_element_set_state(m_pipeline.get(), GST_STATE_PLAYING);
    256248}
    257249
    … …  
    271263
    272264    g_object_set(m_deInterleave.get(), "keep-positions", TRUE, NULL);
    273     g_signal_connect(m_deInterleave.get(), "pad-added", G_CALLBACK(onGStreamerDeinterleavePadAddedCallback), this);
    274     g_signal_connect(m_deInterleave.get(), "no-more-pads", G_CALLBACK(onGStreamerDeinterleaveReadyCallback), this);
    275 
    276     GstCaps* caps = gst_caps_new_simple("audio/x-raw",
     265    g_signal_connect_swapped(m_deInterleave.get(), "pad-added", G_CALLBACK(deinterleavePadAddedCallback), this);
     266    g_signal_connect_swapped(m_deInterleave.get(), "no-more-pads", G_CALLBACK(deinterleaveReadyCallback), this);
     267
     268    GRefPtr<GstCaps> caps = adoptGRef(gst_caps_new_simple("audio/x-raw",
    277269        "rate", G_TYPE_INT, static_cast<int>(m_sampleRate),
    278270        "channels", G_TYPE_INT, m_channels,
    279271        "format", G_TYPE_STRING, GST_AUDIO_NE(F32),
    280         "layout", G_TYPE_STRING, "interleaved", nullptr);
    281     g_object_set(capsFilter, "caps", caps, NULL);
    282     gst_caps_unref(caps);
    283 
    284     gst_bin_add_many(GST_BIN(m_pipeline), audioConvert, audioResample, capsFilter, m_deInterleave.get(), NULL);
    285 
    286     GstPad* sinkPad = gst_element_get_static_pad(audioConvert, "sink");
    287     gst_pad_link_full(pad, sinkPad, GST_PAD_LINK_CHECK_NOTHING);
    288     gst_object_unref(GST_OBJECT(sinkPad));
     272        "layout", G_TYPE_STRING, "interleaved", nullptr));
     273    g_object_set(capsFilter, "caps", caps.get(), nullptr);
     274
     275    gst_bin_add_many(GST_BIN(m_pipeline.get()), audioConvert, audioResample, capsFilter, m_deInterleave.get(), nullptr);
     276
     277    GRefPtr<GstPad> sinkPad = adoptGRef(gst_element_get_static_pad(audioConvert, "sink"));
     278    gst_pad_link_full(pad, sinkPad.get(), GST_PAD_LINK_CHECK_NOTHING);
    289279
    290280    gst_element_link_pads_full(audioConvert, "src", audioResample, "sink", GST_PAD_LINK_CHECK_NOTHING);
    … …  
    300290void AudioFileReader::decodeAudioForBusCreation()
    301291{
     292    ASSERT(&m_runLoop == &RunLoop::current());
     293
    302294    // Build the pipeline (giostreamsrc | filesrc) ! decodebin2
    303295    // A deinterleave element is added once a src pad becomes available in decodebin.
    304     m_pipeline = gst_pipeline_new(0);
    305 
    306     GRefPtr<GstBus> bus = adoptGRef(gst_pipeline_get_bus(GST_PIPELINE(m_pipeline)));
     296    m_pipeline = gst_pipeline_new(nullptr);
     297
     298    GRefPtr<GstBus> bus = adoptGRef(gst_pipeline_get_bus(GST_PIPELINE(m_pipeline.get())));
    307299    ASSERT(bus);
    308     gst_bus_add_signal_watch(bus.get());
    309     g_signal_connect(bus.get(), "message", G_CALLBACK(messageCallback), this);
     300    gst_bus_set_sync_handler(bus.get(), [](GstBus*, GstMessage* message, gpointer userData) {
     301        auto& reader = *static_cast<AudioFileReader*>(userData);
     302        if (&reader.m_runLoop == &RunLoop::current())
     303            reader.handleMessage(message);
     304        else {
     305            GRefPtr<GstMessage> protectMessage(message);
     306            auto weakThis = reader.createWeakPtr();
     307            reader.m_runLoop.dispatch([weakThis, protectMessage] {
     308                if (weakThis)
     309                    weakThis->handleMessage(protectMessage.get());
     310            });
     311        }
     312        gst_message_unref(message);
     313        return GST_BUS_DROP;
     314    }, this, nullptr);
    310315
    311316    GstElement* source;
    … …  
    321326
    322327    m_decodebin = gst_element_factory_make("decodebin", "decodebin");
    323     g_signal_connect(m_decodebin.get(), "pad-added", G_CALLBACK(onGStreamerDecodebinPadAddedCallback), this);
    324 
    325     gst_bin_add_many(GST_BIN(m_pipeline), source, m_decodebin.get(), NULL);
     328    g_signal_connect_swapped(m_decodebin.get(), "pad-added", G_CALLBACK(decodebinPadAddedCallback), this);
     329
     330    gst_bin_add_many(GST_BIN(m_pipeline.get()), source, m_decodebin.get(), NULL);
    326331    gst_element_link_pads_full(source, "src", m_decodebin.get(), "sink", GST_PAD_LINK_CHECK_NOTHING);
    327332
    328     // Catch errors here immediately, there might not be an error message if
    329     // we're unlucky.
    330     if (gst_element_set_state(m_pipeline, GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE) {
     333    // Catch errors here immediately, there might not be an error message if we're unlucky.
     334    if (gst_element_set_state(m_pipeline.get(), GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE) {
    331335        g_warning("Error: Failed to set pipeline to PAUSED");
    332336        m_errorOccurred = true;
    333         g_main_loop_quit(m_loop.get());
     337        m_runLoop.stop();
    334338    }
    335339}
    … …  
    340344    m_channels = mixToMono ? 1 : 2;
    341345
    342     m_frontLeftBuffers = gst_buffer_list_new();
    343     m_frontRightBuffers = gst_buffer_list_new();
    344 
    345     GRefPtr<GMainContext> context = adoptGRef(g_main_context_new());
    346     g_main_context_push_thread_default(context.get());
    347     m_loop = adoptGRef(g_main_loop_new(context.get(), FALSE));
     346    m_frontLeftBuffers = adoptGRef(gst_buffer_list_new());
     347    m_frontRightBuffers = adoptGRef(gst_buffer_list_new());
    348348
    349349    // Start the pipeline processing just after the loop is started.
    350     GThreadSafeMainLoopSource source;
    351     source.schedule("[WebKit] AudioFileReader::decodeAudioForBusCreation", [this] { decodeAudioForBusCreation(); }, G_PRIORITY_DEFAULT, nullptr, context.get());
    352 
    353     g_main_loop_run(m_loop.get());
    354     g_main_context_pop_thread_default(context.get());
     350    m_runLoop.dispatch([this] { decodeAudioForBusCreation(); });
     351    m_runLoop.run();
    355352
    356353    // Set pipeline to GST_STATE_NULL state here already ASAP to
    357354    // release any resources that might still be used.
    358     gst_element_set_state(m_pipeline, GST_STATE_NULL);
     355    gst_element_set_state(m_pipeline.get(), GST_STATE_NULL);
    359356
    360357    if (m_errorOccurred)
    361         return 0;
     358        return nullptr;
    362359
    363360    RefPtr<AudioBus> audioBus = AudioBus::create(m_channels, m_channelSize, true);
    364361    audioBus->setSampleRate(m_sampleRate);
    365362
    366     copyGstreamerBuffersToAudioChannel(m_frontLeftBuffers, audioBus->channel(0));
     363    copyGstreamerBuffersToAudioChannel(m_frontLeftBuffers.get(), audioBus->channel(0));
    367364    if (!mixToMono)
    368         copyGstreamerBuffersToAudioChannel(m_frontRightBuffers, audioBus->channel(1));
     365        copyGstreamerBuffersToAudioChannel(m_frontRightBuffers.get(), audioBus->channel(1));
    369366
    370367    return audioBus;
    … …  
    373370PassRefPtr<AudioBus> createBusFromAudioFile(const char* filePath, bool mixToMono, float sampleRate)
    374371{
    375     return AudioFileReader(filePath).createBus(sampleRate, mixToMono);
     372    RefPtr<AudioBus> returnValue;
     373    auto threadID = createThread("AudioFileReader", [&returnValue, filePath, mixToMono, sampleRate] {
     374        returnValue = AudioFileReader(filePath).createBus(sampleRate, mixToMono);
     375    });
     376    waitForThreadCompletion(threadID);
     377    return returnValue;
    376378}
    377379
    378380PassRefPtr<AudioBus> createBusFromInMemoryAudioFile(const void* data, size_t dataSize, bool mixToMono, float sampleRate)
    379381{
    380     return AudioFileReader(data, dataSize).createBus(sampleRate, mixToMono);
     382    RefPtr<AudioBus> returnValue;
     383    auto threadID = createThread("AudioFileReader", [&returnValue, data, dataSize, mixToMono, sampleRate] {
     384        returnValue = AudioFileReader(data, dataSize).createBus(sampleRate, mixToMono);
     385    });
     386    waitForThreadCompletion(threadID);
     387    return returnValue;
    381388}
    382389
  • trunk/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.cpp

    r191948 r192511  
    184184}
    185185
     186template<> GRefPtr<GstBufferList> adoptGRef(GstBufferList* ptr)
     187{
     188    return GRefPtr<GstBufferList>(ptr, GRefPtrAdopt);
     189}
     190
     191template<> GstBufferList* refGPtr<GstBufferList>(GstBufferList* ptr)
     192{
     193    if (ptr)
     194        gst_buffer_list_ref(ptr);
     195
     196    return ptr;
     197}
     198
     199template<> void derefGPtr<GstBufferList>(GstBufferList* ptr)
     200{
     201    if (ptr)
     202        gst_buffer_list_unref(ptr);
     203}
     204
    186205template<> GRefPtr<GstSample> adoptGRef(GstSample* ptr)
    187206{
  • trunk/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.h

    r191948 r192511  
    3232typedef struct _GstElementFactory GstElementFactory;
    3333typedef struct _GstBuffer GstBuffer;
     34typedef struct _GstBufferList GstBufferList;
    3435typedef struct _GstSample GstSample;
    3536typedef struct _GstTagList GstTagList;
    … …  
    7475template<> void derefGPtr<GstBuffer>(GstBuffer* ptr);
    7576
     77template<> GRefPtr<GstBufferList> adoptGRef(GstBufferList*);
     78template<> GstBufferList* refGPtr<GstBufferList>(GstBufferList*);
     79template<> void derefGPtr<GstBufferList>(GstBufferList*);
     80
    7681template<> GRefPtr<GstSample> adoptGRef(GstSample* ptr);
    7782template<> GstSample* refGPtr<GstSample>(GstSample* ptr);
Note: See TracChangeset for help on using the changeset viewer.