Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-117771

Qt6.5.3 QMediaPlayer play video an error on android 11

    XMLWordPrintable

Details

    • Android
    • 1f568e593 (dev), 703331817 (6.7), 2e6fd4010 (tqtc/lts-6.5)
    • 2024wk14FOQtforAndroid

    Description

      Android11,armv7a,qt6.5.3

       

      my code:
       
       
      void MyWidget::MyWidget(QWidget *parent) : QWidget(parent)

      { mPlayBtn = new QPushButton; mNextBtn = new QPushButton; mPlayBtn->setText("play"); mNextBtn->setText("next"); connect(mPlayBtn, &QPushButton::clicked, this, &MyWidget::play); connect(mNextBtn, &QPushButton::clicked, this, &MyWidget::playNext);   QWidget *w1 = new QWidget; QHBoxLayout *hLayout = new QHBoxLayout; hLayout->addWidget(mPlayBtn); hLayout->addWidget(mNextBtn); w1->setLayout(hLayout); w1->setFixedHeight(50);   QWidgt *w2 = new QWidget; mLayout = new QVBoxLayout;     mLayout->setContentsMargins(0,0,0,0);     w2->setLayout(mLayout);   QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addWidget(w1); mainLayout->addWidget(w2); setLayout(mainLayout);   mFileList<<"/sdcard/myvideo/1.mpg"<<"/sdcard/myvideo/2.mpg"<<"/sdcard/myvideo/3.mpg"<<"/sdcard/myvideo/4.mpg" <<"/sdcard/myvideo/5.mpg"<<"/sdcard/myvideo/6.mpg"; mIndex = 0; initPlayer(); mCurrentFilePath = mFileList.at(mIndex); play(); }

       
      void MyWidget::initPlayer()
      {
          qDebug()<<"\n===>init player\n";
       
          if (!mPlayer)

      {         mPlayer = new QMediaPlayer;     }

       
          if (!mAudioOutput)

      {         mAudioOutput = new QAudioOutput;     }

          mPlayer->setAudioOutput(mAudioOutput);
       
          if (!mVideoWidget)

      {         mVideoWidget = new QVideoWidget;     }

          mVideoWidget->setAspectRatioMode(Qt::IgnoreAspectRatio);
          mLayout->addWidget(mVideoWidget);
       
       
          mPlayer->setVideoOutput(mVideoWidget);
       
          connect(mPlayer, &QMediaPlayer::durationChanged, this, &MyWidget::onDurationChange);
          connect(mPlayer, &QMediaPlayer::positionChanged, this, &MyWidget::onPositionChange);
          connect(mPlayer, &QMediaPlayer::mediaStatusChanged, this, &MyWidget::onMediaStatusChanged);
          connect(mPlayer, &QMediaPlayer::playbackStateChanged, this, &MyWidget::onPlayerStateChanged);
          connect(mPlayer, &QMediaPlayer::errorChanged, this, &MyWidget::handleError);
          connect(mPlayer, &QMediaPlayer::tracksChanged, this, &MyWidget::tracksChanged);
      }
       
      void MyWidget::play()
      {
      if (mCurrentFilePath.isEmpty())

      { return; }
      mPlayer->stop();
      if (!mFile){ mFile = new QFile; }
      mFile->close();
      mFile->setFileName(mCurrentFilePath);
      if (!mFile->open(QIODeviceBase::ReadOnly)){ qDebug()<<"open file failed"; return; }
      mPlayer->setSourceDevice(mFile, QUrl::fromLocalFile(mCurrentFilePath));
      mPlayer->play();
      }
       
      void MyWidget::playNext()
      {
      if (mFileList.size() == 0){ return; }

      ++mIndex;
      if(mIndex >= mFileList.size())

      { mIndex=0; }

      mCurrentFilePath = mFileList.at(mIndex);
      play();
      }
       
      void MyWidget::onMediaStatusChanged(QMediaPlayer::MediaStatus status)
      {
          if (status == QMediaPlayer::EndOfMedia)

      {         playNext();     }

      }
       
      ......
       
       
      The following problem occurred:

      Using ffmpeg as the backend player.

      1. For example, I have 6 videos, and when I play the first video, it is normal. and the first video play finished and call onMediaStatusChanged() and the status== QMediaPlayer::EndOfMedia, and playNext, it's normal.

      2.  Returning to the previous section, when I was playing the first video and was playing it, I called playNext(), there was only sound and no image, and the log output error message:
      "Cannot create codec,Failed to open FFmpeg codec context Generic error in an external library "
      3. The first video is playing normally, but stop it and play the second video, it will error. And stop the second video and play the third video, it is normal. and stop the third video and play the fourth video, it will error and so on.

      the error message:

       

      "Cannot create codec,Failed to open FFmpeg codec context Generic error in an external library "

       

      in the source code may be here:

      qffmpegcodec.cpp

       

      QMaybe<Codec> Codec::create(AVStream *stream)
      {
          if (!stream)
              return { "Invalid stream" };
          const AVCodec *decoder = nullptr;
          std::unique_ptr<QFFmpeg::HWAccel> hwAccel;
          if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
              std::tie(decoder, hwAccel) = HWAccel::findDecoderWithHwAccel(stream->codecpar->codec_id);
          if (!decoder)
              decoder = QFFmpeg::findAVDecoder(stream->codecpar->codec_id);
          if (!decoder)
              return { "Failed to find a valid FFmpeg decoder" };
          qCDebug(qLcPlaybackEngineCodec) << "found decoder" << decoder->name << "for id" << decoder->id;
          AVCodecContextUPtr context(avcodec_alloc_context3(decoder));
          if (!context)
              return { "Failed to allocate a FFmpeg codec context" };
          if (hwAccel)
              context->hw_device_ctx = av_buffer_ref(hwAccel->hwDeviceContextAsBuffer());
          if (context->codec_type != AVMEDIA_TYPE_AUDIO && context->codec_type != AVMEDIA_TYPE_VIDEO
              && context->codec_type != AVMEDIA_TYPE_SUBTITLE) {
              return { "Unknown codec type" };
          }
          int ret = avcodec_parameters_to_context(context.get(), stream->codecpar);
          if (ret < 0)
              return { "Failed to set FFmpeg codec parameters" };
          // ### This still gives errors about wrong HW formats (as we accept all of them)
          // But it would be good to get so we can filter out pixel format we don't support natively
          context->get_format = QFFmpeg::getFormat;
          /* Init the decoder, with reference counting and threading */
          AVDictionaryHolder opts;
          av_dict_set(opts, "refcounted_frames", "1", 0);
          av_dict_set(opts, "threads", "auto", 0);
          ret = avcodec_open2(context.get(), decoder, opts);
          if (ret < 0)
              return QString("Failed to open FFmpeg codec context " + err2str(ret));
          return Codec(new Data(std::move(context), stream, std::move(hwAccel)));
      }
      

       

      please fix it, thanks.

      Attachments

        Issue Links

          For Gerrit Dashboard: QTBUG-117771
          # Subject Branch Project Status CR V

          Activity

            People

              bartlomiejmoskal Bartlomiej Moskal
              paulfan F jb
              Votes:
              2 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes