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 ...