1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef MEDIA_GPU_VAAPI_VAAPI_IMAGE_DECODER_H_
6 #define MEDIA_GPU_VAAPI_VAAPI_IMAGE_DECODER_H_
7 
8 #include <stdint.h>
9 #include <va/va.h>
10 
11 #include <memory>
12 
13 #include "base/callback_forward.h"
14 #include "base/containers/span.h"
15 #include "base/macros.h"
16 #include "base/memory/scoped_refptr.h"
17 #include "gpu/config/gpu_info.h"
18 #include "third_party/skia/include/core/SkImageInfo.h"
19 
20 namespace gfx {
21 class NativePixmapDmaBuf;
22 }  // namespace gfx
23 
24 namespace media {
25 
26 struct NativePixmapAndSizeInfo;
27 class ScopedVASurface;
28 class VaapiWrapper;
29 
30 enum class VaapiFunctions;
31 using ReportErrorToUMACB = base::RepeatingCallback<void(VaapiFunctions)>;
32 
33 struct VAContextAndScopedVASurfaceDeleter {
34   void operator()(ScopedVASurface* scoped_va_surface) const;
35 };
36 
37 using ScopedVAContextAndSurface =
38     std::unique_ptr<ScopedVASurface, VAContextAndScopedVASurfaceDeleter>;
39 
40 enum class VaapiImageDecodeStatus : uint32_t {
41   kSuccess,
42   kParseFailed,
43   kUnsupportedImage,
44   kUnsupportedSubsampling,
45   kSurfaceCreationFailed,
46   kSubmitVABuffersFailed,
47   kExecuteDecodeFailed,
48   kUnsupportedSurfaceFormat,
49   kCannotGetImage,
50   kCannotExportSurface,
51   kInvalidState,
52 };
53 
54 // This class abstracts the idea of VA-API format-specific decoders. It is the
55 // responsibility of each subclass to initialize |vaapi_wrapper_| appropriately
56 // for the purpose of performing hardware-accelerated image decodes of a
57 // particular format (e.g. JPEG or WebP). Objects of this class are not
58 // thread-safe, but they are also not thread-affine, i.e., the caller is free to
59 // call the methods on any thread, but calls must be synchronized externally.
60 class VaapiImageDecoder {
61  public:
62   virtual ~VaapiImageDecoder();
63 
64   // Initializes |vaapi_wrapper_| in kDecode mode with the
65   // appropriate VAAPI profile and |error_uma_cb| for error reporting.
66   virtual bool Initialize(const ReportErrorToUMACB& error_uma_cb);
67 
68   // Decodes a picture. It will fill VA-API parameters and call the
69   // corresponding VA-API methods according to the image in |encoded_image|.
70   // The image will be decoded into an internally allocated ScopedVASurface.
71   // This VA surface will remain valid until the next Decode() call or
72   // destruction of this class. Returns a VaapiImageDecodeStatus that will
73   // indicate whether the decode succeeded or the reason it failed. Note that
74   // the internal ScopedVASurface is destroyed on failure.
75   virtual VaapiImageDecodeStatus Decode(
76       base::span<const uint8_t> encoded_image);
77 
78   // Returns a pointer to the internally managed ScopedVASurface.
79   virtual const ScopedVASurface* GetScopedVASurface() const;
80 
81   // Returns the type of image supported by this decoder.
82   virtual gpu::ImageDecodeAcceleratorType GetType() const = 0;
83 
84   // Returns the type of mapping needed to convert the NativePixmapDmaBuf
85   // returned by ExportAsNativePixmapDmaBuf() from YUV to RGB.
86   virtual SkYUVColorSpace GetYUVColorSpace() const = 0;
87 
88   // Returns the image profile supported by this decoder.
89   virtual gpu::ImageDecodeAcceleratorSupportedProfile GetSupportedProfile()
90       const;
91 
92   // Exports the decoded data from the last Decode() call as a
93   // gfx::NativePixmapDmaBuf. Returns nullptr on failure and sets *|status| to
94   // the reason for failure. On success, the image decoder gives up ownership of
95   // the buffer underlying the NativePixmapDmaBuf.
96   virtual std::unique_ptr<NativePixmapAndSizeInfo> ExportAsNativePixmapDmaBuf(
97       VaapiImageDecodeStatus* status);
98 
99  protected:
100   explicit VaapiImageDecoder(VAProfile va_profile);
101 
102   ScopedVAContextAndSurface scoped_va_context_and_surface_;
103 
104   scoped_refptr<VaapiWrapper> vaapi_wrapper_;
105 
106  private:
107   // Submits an image to the VA-API by filling its parameters and calling on the
108   // corresponding methods according to the image in |encoded_image|. Returns a
109   // VaapiImageDecodeStatus that will indicate whether the operation succeeded
110   // or the reason it failed.
111   virtual VaapiImageDecodeStatus AllocateVASurfaceAndSubmitVABuffers(
112       base::span<const uint8_t> encoded_image) = 0;
113 
114   // The VA profile used for the current image decoder.
115   const VAProfile va_profile_;
116 
117   DISALLOW_COPY_AND_ASSIGN(VaapiImageDecoder);
118 };
119 
120 }  // namespace media
121 
122 #endif  // MEDIA_GPU_VAAPI_VAAPI_IMAGE_DECODER_H_
123