File indexing completed on 2024-04-28 04:43:22
0001 namespace Phonon 0002 { 0003 0004 0005 class MediaNode 0006 { 0007 public: 0008 // must be connected to the backend to get information about the format 0009 QList<Port> inputPorts(MediaStreamType type = Phonon::AllMedia); 0010 0011 QList<Port> outputPorts(MediaStreamType type = Phonon::AllMedia); 0012 0013 0014 }; 0015 0016 class MediaSource 0017 { 0018 //the parameter is used to filter 0019 QList<SubStreamDescription> subStreams(MediaStreamType = AllMedia) 0020 { 0021 //this just asks the source to give us back ots substream information 0022 } 0023 }; 0024 0025 class MediaObject : public QObject 0026 { 0027 Q_OBJECT 0028 public: 0029 MediaObject(const MediaSource &, QObject *parent); 0030 QList<DecoderParameter> decoderParameters(const Port &port); 0031 /** 0032 * Returns 0 if there are no parameters for the given port/decoder. 0033 * 0034 * \code 0035 * media = new MediaObject; 0036 * media->setCurrentSource("/music/file.ogg"); 0037 * output = new AudioOutput(Phonon::Music); 0038 * Path path(media, output); 0039 * QWidget *w = media->decoderParameterWidget(path.sourcePort()); 0040 * if (w) { 0041 * w->setParent(this); 0042 * // or 0043 * // w->show(); 0044 * } 0045 * \endcode 0046 */ 0047 QWidget *decoderParameterWidget(const Port &port); 0048 0049 //the parameter is used to filter 0050 QList<SubStreamDescription> currentSubStreams(MediaStreamType = AllMedia) 0051 { 0052 //this just asks the source to give us back ots substream information 0053 } 0054 0055 0056 0057 bool selectSubstream(SubStreamDescription, const Port &port = Port()) 0058 { 0059 //check the type of the port... 0060 //if the port is invalid, it will do so for every suitable open ports 0061 } 0062 0063 /* 0064 * returns an invalid Port in case of errors. 0065 * format is optional and can be defined later when the connection is done 0066 */ 0067 Port openPort(MediaStreamType type, const char *format = 0) 0068 { 0069 //it gets the default stream 0070 } 0071 0072 bool closePort(const Port &) 0073 { 0074 } 0075 0076 bool isPortValid(const Port &p) 0077 { 0078 //checks if the port description can correspond to a port in this mediaobject 0079 //will most likely be used a lot internally 0080 } 0081 }; 0082 0083 class Path 0084 { 0085 0086 //addition for the ports 0087 0088 Phonon::MediaStreamTypes types(); 0089 QList<Port> inputPorts, outputPorts; 0090 }; 0091 0092 0093 // post 4.0: 0094 class Port 0095 { 0096 //the real identifier of a port is its index ? 0097 //then the format is just information you either give when creating the port 0098 //or information you can retrieve once a connection is established 0099 0100 public: 0101 // a null format means that any might be used and one is automatically selected when 0102 // a connection is set up 0103 Port(MediaStreamTypes types, int index = 0, const char *format = 0) : m_supportedTypes(types), 0104 m_index(index), m_format(format), m_type(0) 0105 { 0106 } 0107 0108 Port(int index = -1) : m_supportedTypes(AllMedia), m_index(index), m_format(0), m_type(0) 0109 { 0110 //gets the port whatever the mediatype is 0111 } 0112 0113 int isValid() const { return index != -1; } 0114 0115 MediaStreamType type() const { return m_type; } 0116 int index() const { return m_index; } 0117 char *format() const { return m_format; } 0118 0119 private: 0120 const MediaStreamTypes m_supportedtypes; 0121 MediaStreamType m_type; 0122 const int m_index; //index (depends on the media type?) 0123 const char * const m_format; 0124 }; 0125 0126 Path createPath(MediaNode *source, const Port &srcport, MediaNode *sink, const Port &sinkport = Port(AllMedia)) 0127 { 0128 // if there's already a path to sink then return invalid Path 0129 } 0130 0131 } // namespace Phonon 0132 0133 MediaObject *media; 0134 { 0135 media = new MediaObject("/video/foo.ogm"); 0136 // post 4.0: 0137 /* 0138 Path p = Phonon::createPath(media, Port(Phonon::Audio, 0, "pcm"), writer); 0139 Path p = Phonon::createPath(media, writer); 0140 p.mediaStreamTypes() & (Phonon::Audio | Phonon::Video) 0141 0142 //ports must always be valid... but they might be 'unconnectable' (depnding on the current source) 0143 Port audio_port = media.openPort(Phonon::Audio, "pcm"); 0144 Port audio_port2 = media.openPort(Phonon::Audio); 0145 0146 0147 //pb: when to call this 0148 //is substream referring to the mediasource? Then you could possibly bind it any time? 0149 media.selectSubStream(src.subStream(Phonon::Audio).first(), audio_port); <- selects the auid stream for the specified audio_port 0150 media.selectSubStream(src.subStream(Phonon::Audio).first()); <-- does it for every audio port (of course only applies to 'src') 0151 0152 //do this for every source? is the way it works obvious? 0153 //example 0154 MediaObject o; 0155 o.enqueue( QList<QUrl>() <<... 0156 foreach(const MediaSource &src, o.queue()) { 0157 // 'attach' would be better but what to do in case there is no port specified 0158 media.selectSubStream( src.substream(Phonon::Audio)[1] ); 0159 } 0160 0161 0162 0163 0164 0165 //do we want to have so many formats or are the formats basically raw or decoded (with a specific format)? 0166 0167 AudioOutput *audioOut = new AudioOutput(Phonon::Music); 0168 Path p = Phonon::createPath(media, audio_port2, writer); // <-- the format of audioport2 is selected to coded? 0169 //shouldn't the port object be changed to reflect the port format has actually been set 0170 Path p = Phonon::createPath(media, audio_port2, audioOut); // <-- this will fail 0171 Path p = Phonon::createPath(media, media.outputPorts(Phonon::Video)[0], writer); 0172 0173 */ 0174 0175 AudioOutput *audioOut = new AudioOutput(Phonon::Music); 0176 Path audioPath = Phonon::createPath(media, audioOut); 0177 Effect *audioEffect = new Effect(audioEffectDescription, this); 0178 audioPath.insertEffect(audioEffect); 0179 0180 VideoWidget *videoWidget = new VideoWidget; 0181 Path videoPath = Phonon::createPath(media, videoWidget); 0182 Effect *videoEffect = videoPath.insertEffect(videoEffectDescription); 0183 0184 videoPath.disconnect(); 0185 0186 media->play(); 0187 0188 // post 4.0: 0189 QList<SubtitleStreamDescription> l = media->availableSubtitleStreams(); 0190 media->setCurrentSubtitleStream(l.first()); 0191 Port port = media->openPort(Phonon::Subtitles); 0192 media->setCurrentSubtitleStream(l.first(), port); 0193 } 0194 // Paths are not gone 0195 delete media; 0196 // Paths are gone now 0197 0198 // Mixing a second media 0199 // ===================== 0200 // _____________ 0201 // | o | 0202 // |audio1 in | 0203 // | o | 0204 // | audio out| 0205 // | o | 0206 // |audio2 in | 0207 // |_____________| 0208 MediaObject *media2 = new MediaObject("/music/foo2.ogg"); 0209 AudioMixer *amix = new AudioMixer; 0210 Path *audioPath2 = new Path(media2, /*"audio",*/ amix); 0211 0212 Path *audioPath3 = new Path(amix, audioOut); // this unplugs audioPath from audioOut, otherwise this Path would not be possible 0213 audioPath->changeOutput(amix); // and here we plug the audioPath back in, but into amix 0214 0215 media2->play(); 0216 0217 0218 // Writing to a file 0219 // ================= 0220 // ____________ 0221 // | o | 0222 // |audio in | 0223 // | | 0224 // | o | 0225 // |video in | 0226 // |____________| 0227 FileWriter *writer = new FileWriter; 0228 writer->setContainerFormat(...); 0229 Encoder *audioEnc = writer->createAudioStream("name", ...); 0230 Encoder *audioEnc2 = writer->createAudioStream("name", ...); 0231 Encoder *videoEnc = writer->createVideoStream(...); 0232 Path *writerAudioPath = new Path(media, audioEnc); 0233 Path *writerAudioPath2 = new Path(media, audioEnc2); 0234 Path *writerVideoPath = new Path(media, videoEnc); 0235 writerAudioPath->insertEffect(audioEffect); 0236 writerVideoPath->insertEffect(videoEffect); 0237 media->setCurrentAudioStream(streamDesc, writerAudioPath); 0238 media->setCurrentAudioStream(streamDesc2, writerAudioPath2); 0239 0240 0241 // Visualization 0242 // ============= 0243 // ____________ 0244 // | | 0245 // | | 0246 // | o o | 0247 // |audio video| 0248 // | in out | 0249 // |____________| 0250 VideoWidget *visWidget = new VideoWidget; 0251 Visualization *vis = new Visualization; 0252 Path *visAudioInPath = new Path(media, vis); 0253 Path *visVideoOutPath = new Path(vis, visWidget); 0254 0255 0256 // Synchronizing two MediaObjects 0257 // ============================== 0258 Synchronizer *sync = new Synchronizer; 0259 sync->addMediaObject(media); 0260 sync->addMediaObject(media2); 0261 media->pause();// ? 0262 sync->pause(); 0263 // media->state() == Phonon::PausedState == media2->state() 0264 sync->play(); 0265 // media->state() == Phonon::PlayingState == media2->state() 0266 ...