Bug 1619258 [Wayland] Enable VA-API for all formats, r=jya
authorMartin Stransky <stransky@redhat.com>
Wed, 18 Mar 2020 07:01:27 +0000
changeset 519326 25fd7f65b4690129e71243a246bd3d49f0d7c807
parent 519325 e1b78dd147a1f3f5ccf3c13fdebf208db6c7e8ac
child 519327 1145a146e5d590a2a83eacb6cbed982108abc04b
push id110429
push userrgurzau@mozilla.com
push dateWed, 18 Mar 2020 07:15:40 +0000
treeherderautoland@25fd7f65b469 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1619258
milestone76.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1619258 [Wayland] Enable VA-API for all formats, r=jya Differential Revision: https://phabricator.services.mozilla.com/D65536
dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
@@ -37,16 +37,19 @@
 // Forward declare from va.h
 #ifdef MOZ_WAYLAND_USE_VAAPI
 typedef int VAStatus;
 #  define VA_EXPORT_SURFACE_READ_ONLY 0x0001
 #  define VA_EXPORT_SURFACE_SEPARATE_LAYERS 0x0004
 #  define VA_STATUS_SUCCESS 0x00000000
 #endif
 
+// Use some extra HW frames for potential rendering lags.
+#define EXTRA_HW_FRAMES 6
+
 typedef mozilla::layers::Image Image;
 typedef mozilla::layers::PlanarYCbCrImage PlanarYCbCrImage;
 
 namespace mozilla {
 
 using media::TimeUnit;
 
 /**
@@ -130,20 +133,16 @@ VAAPIFrameHolder::VAAPIFrameHolder(FFmpe
 
 VAAPIFrameHolder::~VAAPIFrameHolder() {
   mLib->av_buffer_unref(&mHWFrame);
   mLib->av_buffer_unref(&mAVHWFramesContext);
   mLib->av_buffer_unref(&mVAAPIDeviceContext);
 }
 
 AVCodec* FFmpegVideoDecoder<LIBAV_VER>::FindVAAPICodec() {
-  if (mCodecID != AV_CODEC_ID_H264) {
-    return nullptr;
-  }
-
   AVCodec* decoder = mLib->avcodec_find_decoder(mCodecID);
   for (int i = 0;; i++) {
     const AVCodecHWConfig* config = mLib->avcodec_get_hw_config(decoder, i);
     if (!config) {
       break;
     }
     if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX &&
         config->device_type == AV_HWDEVICE_TYPE_VAAPI) {
@@ -167,17 +166,16 @@ bool FFmpegVideoDecoder<LIBAV_VER>::Crea
   }
 
   mCodecContext->hw_device_ctx = mLib->av_buffer_ref(mVAAPIDeviceContext);
   return true;
 }
 
 MediaResult FFmpegVideoDecoder<LIBAV_VER>::InitVAAPIDecoder() {
   FFMPEG_LOG("Initialising VA-API FFmpeg decoder");
-  MOZ_ASSERT(mCodecID == AV_CODEC_ID_H264);
 
   if (!mLib->IsVAAPIAvailable()) {
     FFMPEG_LOG("libva library is missing");
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   if (!gfxPlatformGtk::GetPlatform()->UseWaylandHardwareVideoDecoding()) {
     FFMPEG_LOG("VA-API FFmpeg is disabled by platform");
@@ -277,21 +275,19 @@ FFmpegVideoDecoder<LIBAV_VER>::FFmpegVid
   mExtraData = new MediaByteBuffer;
   mExtraData->AppendElements(*aConfig.mExtraData);
 }
 
 RefPtr<MediaDataDecoder::InitPromise> FFmpegVideoDecoder<LIBAV_VER>::Init() {
   MediaResult rv;
 
 #ifdef MOZ_WAYLAND_USE_VAAPI
-  if (mCodecID == AV_CODEC_ID_H264) {
-    rv = InitVAAPIDecoder();
-    if (NS_SUCCEEDED(rv)) {
-      return InitPromise::CreateAndResolve(TrackInfo::kVideoTrack, __func__);
-    }
+  rv = InitVAAPIDecoder();
+  if (NS_SUCCEEDED(rv)) {
+    return InitPromise::CreateAndResolve(TrackInfo::kVideoTrack, __func__);
   }
 #endif
 
   rv = InitDecoder();
   if (NS_SUCCEEDED(rv)) {
     return InitPromise::CreateAndResolve(TrackInfo::kVideoTrack, __func__);
   }
 
@@ -333,17 +329,22 @@ void FFmpegVideoDecoder<LIBAV_VER>::Init
 }
 
 #ifdef MOZ_WAYLAND_USE_VAAPI
 void FFmpegVideoDecoder<LIBAV_VER>::InitVAAPICodecContext() {
   mCodecContext->width = mInfo.mImage.width;
   mCodecContext->height = mInfo.mImage.height;
   mCodecContext->thread_count = 1;
   mCodecContext->get_format = ChooseVAAPIPixelFormat;
-  mCodecContext->extra_hw_frames = H264::ComputeMaxRefFrames(mInfo.mExtraData);
+  if (mCodecID == AV_CODEC_ID_H264) {
+    mCodecContext->extra_hw_frames =
+        H264::ComputeMaxRefFrames(mInfo.mExtraData);
+  } else {
+    mCodecContext->extra_hw_frames = EXTRA_HW_FRAMES;
+  }
 }
 #endif
 
 MediaResult FFmpegVideoDecoder<LIBAV_VER>::DoDecode(
     MediaRawData* aSample, uint8_t* aData, int aSize, bool* aGotFrame,
     MediaDataDecoder::DecodedData& aResults) {
   AVPacket packet;
   mLib->av_init_packet(&packet);
@@ -692,9 +693,16 @@ void FFmpegVideoDecoder<LIBAV_VER>::Proc
 #ifdef MOZ_WAYLAND_USE_VAAPI
   if (mVAAPIDeviceContext) {
     mLib->av_buffer_unref(&mVAAPIDeviceContext);
   }
 #endif
   FFmpegDataDecoder<LIBAV_VER>::ProcessShutdown();
 }
 
+#ifdef MOZ_WAYLAND_USE_VAAPI
+bool FFmpegVideoDecoder<LIBAV_VER>::IsHardwareAccelerated(
+    nsACString& aFailureReason) const {
+  return !!mVAAPIDeviceContext;
+}
+#endif
+
 }  // namespace mozilla
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
@@ -87,16 +87,17 @@ class FFmpegVideoDecoder<LIBAV_VER>
   MediaResult CreateImage(int64_t aOffset, int64_t aPts, int64_t aDuration,
                           MediaDataDecoder::DecodedData& aResults);
 
 #ifdef MOZ_WAYLAND_USE_VAAPI
   MediaResult InitVAAPIDecoder();
   bool CreateVAAPIDeviceContext();
   void InitVAAPICodecContext();
   AVCodec* FindVAAPICodec();
+  bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
 
   MediaResult CreateImageVAAPI(int64_t aOffset, int64_t aPts, int64_t aDuration,
                                MediaDataDecoder::DecodedData& aResults);
 #endif
 
   /**
    * This method allocates a buffer for FFmpeg's decoder, wrapped in an Image.
    * Currently it only supports Planar YUV420, which appears to be the only