1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #if !defined(GonkVideoDecoderManager_h_)
8 #define GonkVideoDecoderManager_h_
9 
10 #include "nsRect.h"
11 #include "GonkMediaDataDecoder.h"
12 #include "mozilla/RefPtr.h"
13 #include "I420ColorConverterHelper.h"
14 #include "MediaCodecProxy.h"
15 #include "GonkNativeWindow.h"
16 #include "mozilla/layers/FenceUtils.h"
17 #include "mozilla/UniquePtr.h"
18 #include <ui/Fence.h>
19 
20 using namespace android;
21 
22 namespace android {
23 class MediaBuffer;
24 struct MOZ_EXPORT AString;
25 class GonkNativeWindow;
26 } // namespace android
27 
28 namespace mozilla {
29 
30 namespace layers {
31 class TextureClient;
32 class TextureClientRecycleAllocator;
33 } // namespace mozilla::layers
34 
35 class GonkVideoDecoderManager : public GonkDecoderManager {
36 typedef android::MediaCodecProxy MediaCodecProxy;
37 typedef mozilla::layers::TextureClient TextureClient;
38 
39 public:
40   GonkVideoDecoderManager(mozilla::layers::ImageContainer* aImageContainer,
41                           const VideoInfo& aConfig);
42 
43   virtual ~GonkVideoDecoderManager();
44 
45   RefPtr<InitPromise> Init() override;
46 
47   nsresult Output(int64_t aStreamOffset,
48                           RefPtr<MediaData>& aOutput) override;
49 
50   nsresult Shutdown() override;
51 
GetDescriptionName()52   const char* GetDescriptionName() const override
53   {
54     return "gonk video decoder";
55   }
56 
57   static void RecycleCallback(TextureClient* aClient, void* aClosure);
58 
59 protected:
60   // Bug 1199809: workaround to avoid sending the graphic buffer by making a
61   // copy of output buffer after calling flush(). Bug 1203859 was created to
62   // reimplementing Gonk PDM on top of OpenMax IL directly. Its buffer
63   // management will work better with Gecko and solve problems like this.
ProcessFlush()64   void ProcessFlush() override
65   {
66     mNeedsCopyBuffer = true;
67     GonkDecoderManager::ProcessFlush();
68   }
69 
70 private:
71   struct FrameInfo
72   {
73     int32_t mWidth = 0;
74     int32_t mHeight = 0;
75     int32_t mStride = 0;
76     int32_t mSliceHeight = 0;
77     int32_t mColorFormat = 0;
78     int32_t mCropLeft = 0;
79     int32_t mCropTop = 0;
80     int32_t mCropRight = 0;
81     int32_t mCropBottom = 0;
82   };
83 
84   void onMessageReceived(const android::sp<android::AMessage> &aMessage) override;
85 
86   bool SetVideoFormat();
87 
88   nsresult CreateVideoData(MediaBuffer* aBuffer, int64_t aStreamOffset, VideoData** aOutData);
89   already_AddRefed<VideoData> CreateVideoDataFromGraphicBuffer(android::MediaBuffer* aSource,
90                                                                gfx::IntRect& aPicture);
91   already_AddRefed<VideoData> CreateVideoDataFromDataBuffer(android::MediaBuffer* aSource,
92                                                             gfx::IntRect& aPicture);
93 
94   uint8_t* GetColorConverterBuffer(int32_t aWidth, int32_t aHeight);
95 
96   // For codec resource management
97   void codecReserved();
98   void codecCanceled();
99 
100   void ReleaseAllPendingVideoBuffers();
101   void PostReleaseVideoBuffer(android::MediaBuffer *aBuffer,
102                               layers::FenceHandle mReleaseFence);
103 
104   VideoInfo mConfig;
105 
106   RefPtr<layers::ImageContainer> mImageContainer;
107   RefPtr<layers::TextureClientRecycleAllocator> mCopyAllocator;
108 
109   MozPromiseRequestHolder<android::MediaCodecProxy::CodecPromise> mVideoCodecRequest;
110   FrameInfo mFrameInfo;
111 
112   // color converter
113   android::I420ColorConverterHelper mColorConverter;
114   UniquePtr<uint8_t[]> mColorConverterBuffer;
115   size_t mColorConverterBufferSize;
116 
117   android::sp<android::GonkNativeWindow> mNativeWindow;
118 #if ANDROID_VERSION >= 21
119   android::sp<android::IGraphicBufferProducer> mGraphicBufferProducer;
120 #endif
121 
122   enum {
123     kNotifyPostReleaseBuffer = 'nprb',
124   };
125 
126   struct ReleaseItem {
ReleaseItemReleaseItem127     ReleaseItem(android::MediaBuffer* aBuffer, layers::FenceHandle& aFence)
128     : mBuffer(aBuffer)
129     , mReleaseFence(aFence) {}
130     android::MediaBuffer* mBuffer;
131     layers::FenceHandle mReleaseFence;
132   };
133   nsTArray<ReleaseItem> mPendingReleaseItems;
134 
135   // The lock protects mPendingReleaseItems.
136   Mutex mPendingReleaseItemsLock;
137 
138   // This TaskQueue should be the same one in mDecodeCallback->OnReaderTaskQueue().
139   // It is for codec resource mangement, decoding task should not dispatch to it.
140   RefPtr<TaskQueue> mReaderTaskQueue;
141 
142   // Bug 1199809: do we need to make a copy of output buffer? Used only when
143   // the decoder outputs graphic buffers.
144   bool mNeedsCopyBuffer;
145 };
146 
147 } // namespace mozilla
148 
149 #endif // GonkVideoDecoderManager_h_
150