1 // Copyright (C) 2019 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include "host-common/MediaSnapshotState.h"
18 #include "host-common/MediaTexturePool.h"
19 #include "host-common/MediaVideoHelper.h"
20 #include "host-common/YuvConverter.h"
21 
22 #include <cstdint>
23 #include <list>
24 #include <mutex>
25 #include <string>
26 #include <vector>
27 
28 extern "C" {
29 #include "host-common/dynlink_cuda.h"
30 #include "host-common/dynlink_nvcuvid.h"
31 }
32 #include <stdio.h>
33 #include <string.h>
34 
35 #include <stddef.h>
36 
37 namespace android {
38 namespace emulation {
39 
40 class MediaCudaVideoHelper : public MediaVideoHelper {
41 public:
42     enum class FrameStorageMode {
43         USE_BYTE_BUFFER = 1,
44         USE_GPU_TEXTURE = 2,
45     };
46 
47     enum class OutputTreatmentMode {
48         IGNORE_RESULT = 1,
49         SAVE_RESULT = 2,
50     };
51 
52 public:
53     MediaCudaVideoHelper(OutputTreatmentMode outMode,
54                          FrameStorageMode fMode,
55                          cudaVideoCodec cudaVideoCodecType);
56     ~MediaCudaVideoHelper() override;
57 
58 public:
59     // return true if success; false otherwise
60     bool init() override;
61     void decode(const uint8_t* frame,
62                 size_t szBytes,
63                 uint64_t inputPts) override;
64     void flush() override;
65     void deInit() override;
66 
67     void resetTexturePool(MediaTexturePool* pool = nullptr) {
68         mTexturePool = pool;
69     }
70 
error()71     virtual int error() const override { return mErrorCode; }
good()72     virtual bool good() const override { return mIsGood; }
fatal()73     virtual bool fatal() const override { return false == s_isCudaDecoderGood; }
74 
75 private:
76     static bool s_isCudaDecoderGood;
77 
78     uint64_t mNumInputFrame{0};
79     uint64_t mNumOutputFrame{0};
80     int mErrorCode = 0;
81     bool mIsGood = true;
82     bool mUseGpuTexture = false;
83     // note: MediaCudaVideoHelper does not own the texture Pool
84     // don't delete it.
85     MediaTexturePool* mTexturePool = nullptr;
86     unsigned int mHeight = 0;
87     unsigned int mWidth = 0;
88     unsigned int mOutputHeight = 0;
89     unsigned int mOutputWidth = 0;
90     unsigned int mSurfaceHeight = 0;
91     unsigned int mBPP = 0;
92     unsigned int mSurfaceWidth = 0;
93     unsigned int mLumaWidth = 0;
94     unsigned int mLumaHeight = 0;
95     unsigned int mChromaHeight = 0;
96     unsigned int mOutBufferSize = 0;
97 
98     unsigned int mColorPrimaries = 2;
99     unsigned int mColorRange = 0;
100     unsigned int mColorTransfer = 2;
101     unsigned int mColorSpace = 2;
102 
103     std::mutex mFrameLock;
104 
105     // cuda stuff
106     CUcontext mCudaContext = nullptr;
107     CUvideoctxlock mCtxLock;
108     CUvideoparser mCudaParser = nullptr;
109     CUvideodecoder mCudaDecoder = nullptr;
110 
111     cudaVideoCodec mCudaVideoCodecType;
112 
113 private:
114     // cuda call back
HandleVideoSequenceProc(void * pUserData,CUVIDEOFORMAT * pVideoFormat)115     static int CUDAAPI HandleVideoSequenceProc(void* pUserData,
116                                                CUVIDEOFORMAT* pVideoFormat) {
117         return ((MediaCudaVideoHelper*)pUserData)
118                 ->HandleVideoSequence(pVideoFormat);
119     }
HandlePictureDecodeProc(void * pUserData,CUVIDPICPARAMS * pPicParams)120     static int CUDAAPI HandlePictureDecodeProc(void* pUserData,
121                                                CUVIDPICPARAMS* pPicParams) {
122         return ((MediaCudaVideoHelper*)pUserData)
123                 ->HandlePictureDecode(pPicParams);
124     }
125     static int CUDAAPI
HandlePictureDisplayProc(void * pUserData,CUVIDPARSERDISPINFO * pDispInfo)126     HandlePictureDisplayProc(void* pUserData, CUVIDPARSERDISPINFO* pDispInfo) {
127         return ((MediaCudaVideoHelper*)pUserData)
128                 ->HandlePictureDisplay(pDispInfo);
129     }
130 
131     int HandleVideoSequence(CUVIDEOFORMAT* pVideoFormat);
132 
133     int HandlePictureDecode(CUVIDPICPARAMS* pPicParams);
134 
135     int HandlePictureDisplay(CUVIDPARSERDISPINFO* pDispInfo);
136 
137 };  // MediaCudaVideoHelper
138 
139 }  // namespace emulation
140 }  // namespace android
141