Uploaded image for project: 'Qt Mobility'
  1. Qt Mobility
  2. QTMOBILITY-2025

QMediaPlayer::setPositions doesn't refresh every time the connected QVideoWidget when used with the Directshow backend

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • Not Evaluated
    • None
    • 1.2.0
    • Multimedia
    • None
    • Windows XP SP3 32-bit ; Qt libraries 4.7.3 for Windows (VS 2008) ; QtMobility opensource src 1.2 (only the module Multimedia was compiled) ; MSVC 2008.

    Description

      Reading videos under Windows using a QMediaPlayer object connected to a QVideoWidget object and using the method QMediaPlayer::play() works very well.

      But, if I try to read the same video, frame by frame (or position by position) using the QMediaPlayer::setPositions methods and a QTimer (timeout set every 40 ms: playback at 25Hz), then the content of the QVideoWidget object can freeze for a part of the video and play well for another part. In some case, the content is freezed every time.

      As using the same code under MacOS 10.5 with the Quicktime backend didn't have this problem, I looked in the code of the Directshow backend and especialy in the file plugins/multimedia/directshow/player/directshowplayerservice.cpp and the method DirectShowPlayerService::doSeek.

      Looking on the web, it seems that the method IMediaSeeking::seekPosition set the new position, but the media can be in an intermediate state (seeking to the given time?) and then has no the time to extract the frame before the next call of seekPosition().

      This problem doesn't occur every time. For example a video at 100 FPS has not this problem while a video at 25 FPS has it. In this case, the codec is the same (MS-MPEG4 v1).

      I proposed here a small fix which check the state of the media and wait until the media is not in an intermediate state.

       
      /* File plugins/multimedia/directshow/player/directshowplayerservice.cpp, line 914 */
              LONGLONG maximum = 0;
              m_playbackRange = SUCCEEDED(seeking->GetAvailable(&minimum, &maximum))
                      ? QMediaTimeRange(
                              minimum / qt_directShowTimeScale, maximum / qt_directShowTimeScale)
                      : QMediaTimeRange();
      
              locker->unlock();
              seeking->SetPositions(
                      &seekPosition, AM_SEEKING_AbsolutePositioning, 0, AM_SEEKING_NoPositioning);
              locker->relock();
              
      /* Suggested patch */
              if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) {
                  FILTER_STATE fs;
                  control->GetState(INFINITE, (OAFilterState*)&fs);
                  control->Release();
              }
      /* End patch*/
              
              seeking->GetCurrentPosition(&currentPosition);
              m_position = currentPosition / qt_directShowTimeScale;
      
              seeking->Release();
          } else {
              m_position = 0;
          }
      

      Attachments

        Activity

          People

            mgoddard Michael Goddard (closed Nokia identity) (Inactive)
            abarre Arnaud Barré
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated: