qtmobility/plugins/multimedia/gstreamer/mediaplayer/qgstreamerplayersession.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 5 453da2cfceef
equal deleted inserted replaced
1:2b40d63a9c3d 4:90517678cc4f
    54 #endif
    54 #endif
    55 
    55 
    56 QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
    56 QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
    57     :QObject(parent),
    57     :QObject(parent),
    58      m_state(QMediaPlayer::StoppedState),
    58      m_state(QMediaPlayer::StoppedState),
    59      m_mediaStatus(QMediaPlayer::UnknownMediaStatus),
       
    60      m_busHelper(0),
    59      m_busHelper(0),
    61      m_playbin(0),
    60      m_playbin(0),
    62      m_nullVideoOutput(0),
    61      m_nullVideoOutput(0),
    63      m_bus(0),
    62      m_bus(0),
    64      m_renderer(0),
    63      m_renderer(0),
    89         m_busHelper = new QGstreamerBusHelper(m_bus, this);
    88         m_busHelper = new QGstreamerBusHelper(m_bus, this);
    90         connect(m_busHelper, SIGNAL(message(QGstreamerMessage)), SLOT(busMessage(QGstreamerMessage)));
    89         connect(m_busHelper, SIGNAL(message(QGstreamerMessage)), SLOT(busMessage(QGstreamerMessage)));
    91         m_busHelper->installSyncEventFilter(this);
    90         m_busHelper->installSyncEventFilter(this);
    92 
    91 
    93         m_nullVideoOutput = gst_element_factory_make("fakesink", NULL);
    92         m_nullVideoOutput = gst_element_factory_make("fakesink", NULL);
       
    93         gst_object_ref(GST_OBJECT(m_nullVideoOutput));
    94         g_object_set(G_OBJECT(m_playbin), "video-sink", m_nullVideoOutput, NULL);
    94         g_object_set(G_OBJECT(m_playbin), "video-sink", m_nullVideoOutput, NULL);
    95 
    95 
    96         // Initial volume
    96         // Initial volume
    97         double volume = 1.0;
    97         double volume = 1.0;
    98         g_object_get(G_OBJECT(m_playbin), "volume", &volume, NULL);
    98         g_object_get(G_OBJECT(m_playbin), "volume", &volume, NULL);
   106         stop();
   106         stop();
   107 
   107 
   108         delete m_busHelper;
   108         delete m_busHelper;
   109         gst_object_unref(GST_OBJECT(m_bus));
   109         gst_object_unref(GST_OBJECT(m_bus));
   110         gst_object_unref(GST_OBJECT(m_playbin));
   110         gst_object_unref(GST_OBJECT(m_playbin));
       
   111         gst_object_unref(GST_OBJECT(m_nullVideoOutput));
   111     }
   112     }
   112 }
   113 }
   113 
   114 
   114 void QGstreamerPlayerSession::load(const QUrl &url)
   115 void QGstreamerPlayerSession::load(const QUrl &url)
   115 {
   116 {
   116     m_url = url;
   117     m_url = url;
       
   118 
   117     if (m_playbin) {
   119     if (m_playbin) {
   118         m_tags.clear();
   120         m_tags.clear();
   119         emit tagsChanged();
   121         emit tagsChanged();
   120 
   122 
   121         g_object_set(G_OBJECT(m_playbin), "uri", m_url.toString().toLocal8Bit().constData(), NULL);
   123         g_object_set(G_OBJECT(m_playbin), "uri", m_url.toEncoded().constData(), NULL);
   122 
   124 
   123         if (!m_streamTypes.isEmpty()) {
   125         if (!m_streamTypes.isEmpty()) {
   124             m_streamProperties.clear();
   126             m_streamProperties.clear();
   125             m_streamTypes.clear();
   127             m_streamTypes.clear();
   126 
   128 
   256 bool QGstreamerPlayerSession::isSeekable() const
   258 bool QGstreamerPlayerSession::isSeekable() const
   257 {
   259 {
   258     return m_seekable;
   260     return m_seekable;
   259 }
   261 }
   260 
   262 
   261 void QGstreamerPlayerSession::play()
   263 bool QGstreamerPlayerSession::play()
   262 {
   264 {
   263     if (m_playbin) {
   265     if (m_playbin) {
   264         if (gst_element_set_state(m_playbin, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
   266         if (gst_element_set_state(m_playbin, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
   265             qWarning() << "GStreamer; Unable to play -" << m_url.toString();
   267             qWarning() << "GStreamer; Unable to play -" << m_url.toString();
       
   268             m_state = QMediaPlayer::StoppedState;            
       
   269 
       
   270             emit stateChanged(m_state);
       
   271             emit error(int(QMediaPlayer::ResourceError), tr("Unable to play %1").arg(m_url.path()));
       
   272         } else
       
   273             return true;
       
   274     }
       
   275 
       
   276     return false;
       
   277 }
       
   278 
       
   279 bool QGstreamerPlayerSession::pause()
       
   280 {
       
   281     if (m_playbin) {
       
   282         if (gst_element_set_state(m_playbin, GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE) {
       
   283             qWarning() << "GStreamer; Unable to play -" << m_url.toString();
   266             m_state = QMediaPlayer::StoppedState;
   284             m_state = QMediaPlayer::StoppedState;
   267             m_mediaStatus = QMediaPlayer::InvalidMedia;
       
   268 
   285 
   269             emit stateChanged(m_state);
   286             emit stateChanged(m_state);
   270             emit mediaStatusChanged(m_mediaStatus);
   287             emit error(int(QMediaPlayer::ResourceError), tr("Unable to play %1").arg(m_url.path()));
   271         }
   288         } else
   272     }
   289             return true;
   273 }
   290     }
   274 
   291 
   275 void QGstreamerPlayerSession::pause()
   292     return false;
   276 {
       
   277     if (m_playbin)
       
   278         gst_element_set_state(m_playbin, GST_STATE_PAUSED);
       
   279 }
   293 }
   280 
   294 
   281 void QGstreamerPlayerSession::stop()
   295 void QGstreamerPlayerSession::stop()
   282 {
   296 {
   283     if (m_playbin) {
   297     if (m_playbin) {
   287         if (m_state != QMediaPlayer::StoppedState)
   301         if (m_state != QMediaPlayer::StoppedState)
   288             emit stateChanged(m_state = QMediaPlayer::StoppedState);
   302             emit stateChanged(m_state = QMediaPlayer::StoppedState);
   289     }
   303     }
   290 }
   304 }
   291 
   305 
   292 void QGstreamerPlayerSession::seek(qint64 ms)
   306 bool QGstreamerPlayerSession::seek(qint64 ms)
   293 {
   307 {
   294     if (m_playbin && m_state != QMediaPlayer::StoppedState) {
   308     if (m_playbin && m_state != QMediaPlayer::StoppedState) {
   295         gint64  position = (gint64)ms * 1000000;
   309         gint64  position = (gint64)ms * 1000000;
   296         gst_element_seek_simple(m_playbin, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, position);
   310         return gst_element_seek_simple(m_playbin, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, position);
   297     }
   311     }
       
   312 
       
   313     return false;
   298 }
   314 }
   299 
   315 
   300 void QGstreamerPlayerSession::setVolume(int volume)
   316 void QGstreamerPlayerSession::setVolume(int volume)
   301 {
   317 {
   302     m_volume = volume;
   318     if (m_volume != volume) {
   303     emit volumeChanged(m_volume);
   319         m_volume = volume;
   304 
   320 
   305     if (!m_muted && m_playbin)
   321         if (m_playbin) {
   306         g_object_set(G_OBJECT(m_playbin), "volume", m_volume/100.0, NULL);
   322 #ifndef USE_PLAYBIN2
   307 
   323             if(!m_muted)
       
   324 #endif
       
   325                 g_object_set(G_OBJECT(m_playbin), "volume", m_volume/100.0, NULL);
       
   326         }
       
   327 
       
   328         emit volumeChanged(m_volume);
       
   329     }
   308 }
   330 }
   309 
   331 
   310 void QGstreamerPlayerSession::setMuted(bool muted)
   332 void QGstreamerPlayerSession::setMuted(bool muted)
   311 {
   333 {
   312     m_muted = muted;
   334     if (m_muted != muted) {
   313 
   335         m_muted = muted;
   314     g_object_set(G_OBJECT(m_playbin), "volume", (m_muted ? 0 : m_volume/100.0), NULL);
   336 
   315 
   337 #ifdef USE_PLAYBIN2
   316     emit mutedStateChanged(m_muted);
   338         g_object_set(G_OBJECT(m_playbin), "mute", m_muted, NULL);
       
   339 #else
       
   340         g_object_set(G_OBJECT(m_playbin), "volume", (m_muted ? 0 : m_volume/100.0), NULL);
       
   341 #endif
       
   342         emit mutedStateChanged(m_muted);
       
   343     }
   317 }
   344 }
   318 
   345 
   319 static void addTagToMap(const GstTagList *list,
   346 static void addTagToMap(const GstTagList *list,
   320                         const gchar *tag,
   347                         const gchar *tag,
   321                         gpointer user_data)
   348                         gpointer user_data)
   383         m_seekable = seekable;
   410         m_seekable = seekable;
   384         emit seekableChanged(m_seekable);
   411         emit seekableChanged(m_seekable);
   385     }
   412     }
   386 }
   413 }
   387 
   414 
   388 void QGstreamerPlayerSession::setMediaStatus(QMediaPlayer::MediaStatus status)
       
   389 {
       
   390     if (m_mediaStatus != status) {
       
   391         m_mediaStatus = status;
       
   392         emit mediaStatusChanged(status);
       
   393     }
       
   394 }
       
   395 
       
   396 bool QGstreamerPlayerSession::processSyncMessage(const QGstreamerMessage &message)
   415 bool QGstreamerPlayerSession::processSyncMessage(const QGstreamerMessage &message)
   397 {
   416 {
   398     GstMessage* gm = message.rawMessage();
   417     GstMessage* gm = message.rawMessage();
   399 
   418 
   400     if (gm &&
   419     if (gm &&
   420         if (newPos/1000 != m_lastPosition) {
   439         if (newPos/1000 != m_lastPosition) {
   421             m_lastPosition = newPos/1000;
   440             m_lastPosition = newPos/1000;
   422             emit positionChanged(newPos);
   441             emit positionChanged(newPos);
   423         }
   442         }
   424 
   443 
       
   444         double volume = 1.0;
       
   445         g_object_get(G_OBJECT(m_playbin), "volume", &volume, NULL);
       
   446         if (m_volume != int(volume*100)) {
       
   447             m_volume = int(volume*100);
       
   448             emit volumeChanged(m_volume);
       
   449         }
       
   450 
   425     } else {
   451     } else {
   426         //tag message comes from elements inside playbin, not from playbin itself
   452         //tag message comes from elements inside playbin, not from playbin itself
   427         if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_TAG) {
   453         if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_TAG) {
   428             //qDebug() << "tag message";
   454             //qDebug() << "tag message";
   429             GstTagList *tag_list;
   455             GstTagList *tag_list;
   435             emit tagsChanged();
   461             emit tagsChanged();
   436         }
   462         }
   437 
   463 
   438         if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_playbin)) {
   464         if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_playbin)) {
   439             switch (GST_MESSAGE_TYPE(gm))  {
   465             switch (GST_MESSAGE_TYPE(gm))  {
   440             case GST_MESSAGE_DURATION:
       
   441                 break;
       
   442 
       
   443             case GST_MESSAGE_STATE_CHANGED:
   466             case GST_MESSAGE_STATE_CHANGED:
   444                 {
   467                 {
   445                     GstState    oldState;
   468                     GstState    oldState;
   446                     GstState    newState;
   469                     GstState    newState;
   447                     GstState    pending;
   470                     GstState    pending;
   457                             .arg(states[pending]);*/
   480                             .arg(states[pending]);*/
   458 
   481 
   459                     switch (newState) {
   482                     switch (newState) {
   460                     case GST_STATE_VOID_PENDING:
   483                     case GST_STATE_VOID_PENDING:
   461                     case GST_STATE_NULL:
   484                     case GST_STATE_NULL:
   462                         setMediaStatus(QMediaPlayer::UnknownMediaStatus);
       
   463                         setSeekable(false);
   485                         setSeekable(false);
   464                         if (m_state != QMediaPlayer::StoppedState)
   486                         if (m_state != QMediaPlayer::StoppedState)
   465                             emit stateChanged(m_state = QMediaPlayer::StoppedState);
   487                             emit stateChanged(m_state = QMediaPlayer::StoppedState);
   466                         break;
   488                         break;
   467                     case GST_STATE_READY:
   489                     case GST_STATE_READY:
   468                         setMediaStatus(QMediaPlayer::LoadedMedia);
       
   469                         setSeekable(false);
   490                         setSeekable(false);
   470                         if (m_state != QMediaPlayer::StoppedState)
   491                         if (m_state != QMediaPlayer::StoppedState)
   471                             emit stateChanged(m_state = QMediaPlayer::StoppedState);
   492                             emit stateChanged(m_state = QMediaPlayer::StoppedState);
   472                         break;
   493                         break;
   473                     case GST_STATE_PAUSED:
   494                     case GST_STATE_PAUSED:
   474                         //don't emit state changes for intermediate states
   495                         if (m_state != QMediaPlayer::PausedState)
   475                         if (m_state != QMediaPlayer::PausedState && pending == GST_STATE_VOID_PENDING)
       
   476                             emit stateChanged(m_state = QMediaPlayer::PausedState);
   496                             emit stateChanged(m_state = QMediaPlayer::PausedState);
   477 
       
   478                         setMediaStatus(QMediaPlayer::LoadedMedia);
       
   479 
   497 
   480                         //check for seekable
   498                         //check for seekable
   481                         if (oldState == GST_STATE_READY) {
   499                         if (oldState == GST_STATE_READY) {
   482                             /*
   500                             /*
   483                                 //gst_element_seek_simple doesn't work reliably here, have to find a better solution
   501                                 //gst_element_seek_simple doesn't work reliably here, have to find a better solution
   508                         if (oldState == GST_STATE_PAUSED)
   526                         if (oldState == GST_STATE_PAUSED)
   509                             getStreamsInfo();
   527                             getStreamsInfo();
   510 
   528 
   511                         if (m_state != QMediaPlayer::PlayingState)
   529                         if (m_state != QMediaPlayer::PlayingState)
   512                             emit stateChanged(m_state = QMediaPlayer::PlayingState);
   530                             emit stateChanged(m_state = QMediaPlayer::PlayingState);
       
   531 
   513                         break;
   532                         break;
   514                     }
   533                     }
   515                 }
   534                 }
   516                 break;
   535                 break;
   517 
   536 
   518             case GST_MESSAGE_EOS:
   537             case GST_MESSAGE_EOS:
   519                 if (m_state != QMediaPlayer::StoppedState)
       
   520                     emit stateChanged(m_state = QMediaPlayer::StoppedState);
       
   521 
       
   522                 setMediaStatus(QMediaPlayer::EndOfMedia);
       
   523 
       
   524                 emit playbackFinished();
   538                 emit playbackFinished();
   525                 break;
   539                 break;
   526 
   540 
   527             case GST_MESSAGE_TAG:
   541             case GST_MESSAGE_TAG:
   528             case GST_MESSAGE_STREAM_STATUS:
   542             case GST_MESSAGE_STREAM_STATUS:
   529             case GST_MESSAGE_UNKNOWN:
   543             case GST_MESSAGE_UNKNOWN:
       
   544                 break;
   530             case GST_MESSAGE_ERROR:
   545             case GST_MESSAGE_ERROR:
       
   546                 {
       
   547                     GError *err;
       
   548                     gchar *debug;
       
   549                     gst_message_parse_error (gm, &err, &debug);
       
   550                     emit error(int(QMediaPlayer::ResourceError), QString::fromUtf8(err->message));
       
   551                     qWarning() << "Error:" << QString::fromUtf8(err->message);
       
   552                     g_error_free (err);
       
   553                     g_free (debug);
       
   554                 }
       
   555                 break;
   531             case GST_MESSAGE_WARNING:
   556             case GST_MESSAGE_WARNING:
   532             case GST_MESSAGE_INFO:
   557             case GST_MESSAGE_INFO:
   533                 break;
   558                 break;
   534             case GST_MESSAGE_BUFFERING:
   559             case GST_MESSAGE_BUFFERING:
   535                 setMediaStatus(QMediaPlayer::BufferingMedia);
   560                 {
       
   561                     int progress = 0;
       
   562                     gst_message_parse_buffering(gm, &progress);
       
   563                     emit bufferingProgressChanged(progress);
       
   564                 }
   536                 break;
   565                 break;
   537             case GST_MESSAGE_STATE_DIRTY:
   566             case GST_MESSAGE_STATE_DIRTY:
   538             case GST_MESSAGE_STEP_DONE:
   567             case GST_MESSAGE_STEP_DONE:
   539             case GST_MESSAGE_CLOCK_PROVIDE:
   568             case GST_MESSAGE_CLOCK_PROVIDE:
   540             case GST_MESSAGE_CLOCK_LOST:
   569             case GST_MESSAGE_CLOCK_LOST:
   541             case GST_MESSAGE_NEW_CLOCK:
   570             case GST_MESSAGE_NEW_CLOCK:
   542             case GST_MESSAGE_STRUCTURE_CHANGE:
   571             case GST_MESSAGE_STRUCTURE_CHANGE:
   543             case GST_MESSAGE_APPLICATION:
   572             case GST_MESSAGE_APPLICATION:
   544             case GST_MESSAGE_ELEMENT:
   573             case GST_MESSAGE_ELEMENT:
       
   574                 break;
   545             case GST_MESSAGE_SEGMENT_START:
   575             case GST_MESSAGE_SEGMENT_START:
       
   576                 {
       
   577                     const GstStructure *structure = gst_message_get_structure(gm);
       
   578                     qint64 position = g_value_get_int64(gst_structure_get_value(structure, "position"));
       
   579                     position /= 1000000;
       
   580                     m_lastPosition = position;
       
   581                     emit positionChanged(position);
       
   582                 }
       
   583                 break;
   546             case GST_MESSAGE_SEGMENT_DONE:
   584             case GST_MESSAGE_SEGMENT_DONE:
       
   585                 break;
       
   586             case GST_MESSAGE_DURATION:
       
   587                 {
       
   588                     GstFormat   format = GST_FORMAT_TIME;
       
   589                     gint64      duration = 0;
       
   590 
       
   591                     if (gst_element_query_duration(m_playbin, &format, &duration)) {
       
   592                         int newDuration = duration / 1000000;
       
   593                         if (m_duration != newDuration) {
       
   594                             m_duration = newDuration;
       
   595                             emit durationChanged(m_duration);
       
   596                         }
       
   597                     }
       
   598                 }
       
   599                 break;
   547             case GST_MESSAGE_LATENCY:
   600             case GST_MESSAGE_LATENCY:
   548 #if (GST_VERSION_MAJOR >= 0) &&  (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 13)
   601 #if (GST_VERSION_MAJOR >= 0) &&  (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 13)
   549             case GST_MESSAGE_ASYNC_START:
   602             case GST_MESSAGE_ASYNC_START:
   550             case GST_MESSAGE_ASYNC_DONE:
   603             case GST_MESSAGE_ASYNC_DONE:
   551 #if GST_VERSION_MICRO >= 23
   604 #if GST_VERSION_MICRO >= 23