~ubuntu-branches/ubuntu/natty/phonon/natty

« back to all changes in this revision

Viewing changes to gstreamer/audiodataoutput.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2011-01-24 10:12:11 UTC
  • mfrom: (0.5.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20110124101211-w9rew7q0dmwbwhqx
Tags: 4:4.7.0really4.4.4-0ubuntu1
* New upstream release
* Xine and GStreamer backends now split out source, remove build-deps and
  binary packages from debian/control
* Remove 02_no_rpath.patch, now upstream
* Disable kubuntu04_no_va_mangle.patch, no longer applies
* Remove kubuntu_05_gst_codec_installer_window_id.diff, kubuntu_06_forward_events.diff,
  kubuntu_07_include_fix.diff, gstreamer now separate

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  This file is part of the KDE project
2
 
    Copyright (C) 2006 Matthias Kretz <kretz@kde.org>
3
 
    Copyright (C) 2009 Martin Sandsmark <sandsmark@samfundet.no>
4
 
 
5
 
    This library is free software; you can redistribute it and/or
6
 
    modify it under the terms of the GNU Lesser General Public
7
 
    License as published by the Free Software Foundation; either
8
 
    version 2.1 of the License, or (at your option) version 3, or any
9
 
    later version accepted by the membership of KDE e.V. (or its
10
 
    successor approved by the membership of KDE e.V.), Nokia Corporation
11
 
    (or its successors, if any) and the KDE Free Qt Foundation, which shall
12
 
    act as a proxy defined in Section 6 of version 3 of the license.
13
 
 
14
 
    This library is distributed in the hope that it will be useful,
15
 
    but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 
    Lesser General Public License for more details.
18
 
 
19
 
    You should have received a copy of the GNU Lesser General Public
20
 
    License along with this library.  If not, see <http://www.gnu.org/licenses/>.
21
 
 
22
 
*/
23
 
 
24
 
#include "audiodataoutput.h"
25
 
#include "gsthelper.h"
26
 
#include "medianode.h"
27
 
#include "medianodeevent.h"
28
 
#include "mediaobject.h"
29
 
#include <QtCore/QVector>
30
 
#include <QtCore/QMap>
31
 
#include <phonon/audiooutput.h>
32
 
 
33
 
#include <gst/gstutils.h>
34
 
 
35
 
QT_BEGIN_HEADER
36
 
QT_BEGIN_NAMESPACE
37
 
 
38
 
namespace Phonon
39
 
{
40
 
namespace Gstreamer
41
 
{
42
 
AudioDataOutput::AudioDataOutput(Backend *backend, QObject *parent)
43
 
    : QObject(parent),
44
 
    MediaNode(backend, AudioSink | AudioSource)
45
 
{
46
 
    static int count = 0;
47
 
    m_name = "AudioDataOutput" + QString::number(count++);
48
 
 
49
 
    m_queue = gst_element_factory_make ("identity", NULL);
50
 
    gst_object_ref(m_queue);
51
 
    m_isValid = true;
52
 
}
53
 
 
54
 
AudioDataOutput::~AudioDataOutput()
55
 
{
56
 
    gst_element_set_state(m_queue, GST_STATE_NULL);
57
 
    gst_object_unref(m_queue);
58
 
}
59
 
 
60
 
int AudioDataOutput::dataSize() const
61
 
{
62
 
    return m_dataSize;
63
 
}
64
 
 
65
 
int AudioDataOutput::sampleRate() const
66
 
{
67
 
    return 44100;
68
 
}
69
 
 
70
 
void AudioDataOutput::setDataSize(int size)
71
 
{
72
 
    m_dataSize = size;
73
 
}
74
 
 
75
 
typedef QMap<Phonon::AudioDataOutput::Channel, QVector<float> > FloatMap;
76
 
typedef QMap<Phonon::AudioDataOutput::Channel, QVector<qint16> > IntMap;
77
 
 
78
 
inline void AudioDataOutput::convertAndEmit(const QVector<qint16> &leftBuffer, const QVector<qint16> &rightBuffer)
79
 
{
80
 
    //TODO: Floats
81
 
    IntMap map;
82
 
    map.insert(Phonon::AudioDataOutput::LeftChannel, leftBuffer);
83
 
    map.insert(Phonon::AudioDataOutput::RightChannel, rightBuffer);
84
 
    emit dataReady(map);
85
 
}
86
 
 
87
 
void AudioDataOutput::processBuffer(GstPad*, GstBuffer* buffer, gpointer gThat)
88
 
{
89
 
    // TODO emit endOfMedia
90
 
    AudioDataOutput *that = reinterpret_cast<AudioDataOutput*>(gThat);
91
 
 
92
 
    // determine the number of channels
93
 
    GstStructure* structure = gst_caps_get_structure (GST_BUFFER_CAPS(buffer), 0);
94
 
    gst_structure_get_int (structure, "channels", &that->m_channels);
95
 
 
96
 
    if (that->m_channels > 2 || that->m_channels < 0) {
97
 
        qWarning() << Q_FUNC_INFO << ": Number of channels not supported: " << that->m_channels;
98
 
        return;
99
 
    }
100
 
 
101
 
    gint16 *data = reinterpret_cast<gint16*>(GST_BUFFER_DATA(buffer));
102
 
    guint size = GST_BUFFER_SIZE(buffer) / sizeof(gint16);
103
 
 
104
 
    that->m_pendingData.reserve(that->m_pendingData.size() + size);
105
 
 
106
 
    for (uint i=0; i<size; i++) {
107
 
        // 8 bit? interleaved? yay for lacking documentation!
108
 
        that->m_pendingData.append(data[i]);
109
 
    }
110
 
 
111
 
    while (that->m_pendingData.size() > that->m_dataSize * that->m_channels) {
112
 
        if (that->m_channels == 1) {
113
 
            QVector<qint16> intBuffer(that->m_dataSize);
114
 
            memcpy(intBuffer.data(), that->m_pendingData.constData(), that->m_dataSize * sizeof(qint16));
115
 
 
116
 
            that->convertAndEmit(intBuffer, intBuffer);
117
 
            int newSize = that->m_pendingData.size() - that->m_dataSize;
118
 
            memmove(that->m_pendingData.data(), that->m_pendingData.constData() + that->m_dataSize, newSize * sizeof(qint16));
119
 
            that->m_pendingData.resize(newSize);
120
 
        } else {
121
 
            QVector<qint16> left(that->m_dataSize), right(that->m_dataSize);
122
 
            for (int i=0; i<that->m_dataSize; i++) {
123
 
                left[i] = that->m_pendingData[i*2];
124
 
                right[i] = that->m_pendingData[i*2+1];
125
 
            }
126
 
            that->m_pendingData.resize(that->m_pendingData.size() - that->m_dataSize*2);
127
 
            that->convertAndEmit(left, right);
128
 
        }
129
 
    }
130
 
}
131
 
 
132
 
void AudioDataOutput::mediaNodeEvent(const MediaNodeEvent *event)
133
 
{
134
 
    if (event->type() == MediaNodeEvent::MediaObjectConnected && root()) {
135
 
        g_object_set(G_OBJECT(audioElement()), "sync", true, (const char*)NULL);
136
 
        GstPad *audiopad = gst_element_get_pad (audioElement(), "src");
137
 
        gst_pad_add_buffer_probe (audiopad, G_CALLBACK(processBuffer), this);
138
 
        gst_object_unref (audiopad);
139
 
        return;
140
 
    }
141
 
 
142
 
    MediaNode::mediaNodeEvent(event);
143
 
}
144
 
 
145
 
}} //namespace Phonon::Gstreamer
146
 
 
147
 
QT_END_NAMESPACE
148
 
QT_END_HEADER
149
 
 
150
 
#include "moc_audiodataoutput.cpp"
151
 
// vim: sw=4 ts=4
152