├── Makefile ├── doc ├── 1122_GTC09.pdf ├── NVDEC_DA-06209-001_v08.pdf ├── NVDEC_VideoDecoder_API_ProgGuide.pdf ├── NVENC_DA-06209-001_v08.pdf ├── NVENC_VideoEncoder_API_ProgGuide.pdf ├── NVIDIA_Video_Codec_SDK_Samples_Guide.pdf ├── NvEncodeAPI_v.7.1.chm ├── NvEncodeAPI_v.7.1.chw ├── NvEncodeAPI_v.7.1.pdf ├── Nvenc内存拷贝方案性能测试.docx └── S4654-detailed-overview-nvenc-encoder-api.pdf ├── include ├── NvEncoder.h ├── NvHWEncoder.h ├── dynlink_cuda.h ├── dynlink_cuda_cuda.h ├── h264_log.h ├── h264_route.h ├── nvCPUOPSys.h ├── nvEncodeAPI.h ├── nvFileIO.h ├── nvUtils.h ├── pixman-version.h └── pixman.h └── src ├── NvEncoder.cpp ├── NvHWEncoder.cpp ├── dynlink_cuda.cpp ├── h264_log.cpp ├── h264_route.cpp └── h264_test.c /Makefile: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # 3 | # Copyright 1993-2014 NVIDIA Corporation. All rights reserved. 4 | # 5 | # NOTICE TO USER: 6 | # 7 | # This source code is subject to NVIDIA ownership rights under U.S. and 8 | # international Copyright laws. 9 | # 10 | # NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE 11 | # CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR 12 | # IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH 13 | # REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF 14 | # MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE. 15 | # IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, 16 | # OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 17 | # OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 18 | # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE 19 | # OR PERFORMANCE OF THIS SOURCE CODE. 20 | # 21 | # U.S. Government End Users. This source code is a "commercial item" as 22 | # that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of 23 | # "commercial computer software" and "commercial computer software 24 | # documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995) 25 | # and is provided to the U.S. Government only as a commercial end item. 26 | # Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through 27 | # 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the 28 | # source code with only those rights set forth herein. 29 | # 30 | ################################################################################ 31 | # 32 | # Makefile project only supported on Mac OSX and Linux Platforms) 33 | # 34 | ################################################################################ 35 | 36 | # OS Name (Linux or Darwin) 37 | OSUPPER = $(shell uname -s 2>/dev/null | tr [:lower:] [:upper:]) 38 | OSLOWER = $(shell uname -s 2>/dev/null | tr [:upper:] [:lower:]) 39 | 40 | # Flags to detect 32-bit or 64-bit OS platform 41 | OS_SIZE = $(shell uname -m | sed -e "s/i.86/32/" -e "s/x86_64/64/") 42 | OS_ARCH = $(shell uname -m | sed -e "s/i386/i686/") 43 | 44 | # These flags will override any settings 45 | ifeq ($(i386),1) 46 | OS_SIZE = 32 47 | OS_ARCH = i686 48 | endif 49 | 50 | ifeq ($(x86_64),1) 51 | OS_SIZE = 64 52 | OS_ARCH = x86_64 53 | endif 54 | 55 | # Flags to detect either a Linux system (linux) or Mac OSX (darwin) 56 | DARWIN = $(strip $(findstring DARWIN, $(OSUPPER))) 57 | 58 | # Common binaries 59 | GCC ?= g++ 60 | 61 | # OS-specific build flags 62 | ifneq ($(DARWIN),) 63 | CCFLAGS := -arch $(OS_ARCH) 64 | else 65 | ifeq ($(OS_SIZE),32) 66 | LDFLAGS += -L/usr/lib64 -lnvidia-encode -ldl -lpthread 67 | CCFLAGS := -Wall -m32 -fpic -shared 68 | else 69 | LDFLAGS += -L/usr/lib64 -lnvidia-encode -ldl -lpthread 70 | CCFLAGS := -Wall -m64 -fpic -shared 71 | endif 72 | endif 73 | 74 | # Debug build flags 75 | ifeq ($(dbg),1) 76 | CCFLAGS += -g 77 | TARGET := debug 78 | else 79 | TARGET := release 80 | endif 81 | 82 | # Common includes and paths for CUDA 83 | INCLUDES := -I /usr/include/pixman-1/ 84 | 85 | # Target rules 86 | all: build 87 | 88 | build: libh264_route.so 89 | 90 | dynlink_cuda.o: dynlink_cuda.cpp 91 | $(GCC) $(CCFLAGS) $(INCLUDES) -o $@ -c $< 92 | 93 | NvHWEncoder.o: NvHWEncoder.cpp NvHWEncoder.h 94 | $(GCC) $(CCFLAGS) $(EXTRA_CCFLAGS) $(INCLUDES) -o $@ -c $< 95 | 96 | NvEncoder.o: NvEncoder.cpp NvEncoder.h nvEncodeAPI.h 97 | $(GCC) $(CCFLAGS) $(EXTRA_CCFLAGS) $(INCLUDES) -o $@ -c $< 98 | 99 | h264_route.o: h264_route.cpp 100 | $(GCC) $(CCFLAGS) $(EXTRA_CCFLAGS) $(INCLUDES) -o $@ -c $< 101 | 102 | h264_log.o: h264_log.cpp 103 | $(GCC) $(CCFLAGS) $(EXTRA_CCFLAGS) $(INCLUDES) -o $@ -c $< 104 | 105 | libh264_route.so: NvHWEncoder.o NvEncoder.o dynlink_cuda.o h264_route.o h264_log.o 106 | $(GCC) $(CCFLAGS) -o $@ $+ $(LDFLAGS) $(EXTRA_LDFLAGS) 107 | 108 | install: build 109 | cp -rf h264_route.h /usr/include/ 110 | cp -rf h264_route.so /usr/lib64/ 111 | 112 | clean: 113 | rm -rf libh264_route.so NvHWEncoder.o NvEncoder.o dynlink_cuda.o h264_route.o h264_log.o -------------------------------------------------------------------------------- /doc/1122_GTC09.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarkRepo/NvencEncoder/f8856544c1d267a7255675837dd3cb9d237c39bb/doc/1122_GTC09.pdf -------------------------------------------------------------------------------- /doc/NVDEC_DA-06209-001_v08.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarkRepo/NvencEncoder/f8856544c1d267a7255675837dd3cb9d237c39bb/doc/NVDEC_DA-06209-001_v08.pdf -------------------------------------------------------------------------------- /doc/NVDEC_VideoDecoder_API_ProgGuide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarkRepo/NvencEncoder/f8856544c1d267a7255675837dd3cb9d237c39bb/doc/NVDEC_VideoDecoder_API_ProgGuide.pdf -------------------------------------------------------------------------------- /doc/NVENC_DA-06209-001_v08.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarkRepo/NvencEncoder/f8856544c1d267a7255675837dd3cb9d237c39bb/doc/NVENC_DA-06209-001_v08.pdf -------------------------------------------------------------------------------- /doc/NVENC_VideoEncoder_API_ProgGuide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarkRepo/NvencEncoder/f8856544c1d267a7255675837dd3cb9d237c39bb/doc/NVENC_VideoEncoder_API_ProgGuide.pdf -------------------------------------------------------------------------------- /doc/NVIDIA_Video_Codec_SDK_Samples_Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarkRepo/NvencEncoder/f8856544c1d267a7255675837dd3cb9d237c39bb/doc/NVIDIA_Video_Codec_SDK_Samples_Guide.pdf -------------------------------------------------------------------------------- /doc/NvEncodeAPI_v.7.1.chm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarkRepo/NvencEncoder/f8856544c1d267a7255675837dd3cb9d237c39bb/doc/NvEncodeAPI_v.7.1.chm -------------------------------------------------------------------------------- /doc/NvEncodeAPI_v.7.1.chw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarkRepo/NvencEncoder/f8856544c1d267a7255675837dd3cb9d237c39bb/doc/NvEncodeAPI_v.7.1.chw -------------------------------------------------------------------------------- /doc/NvEncodeAPI_v.7.1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarkRepo/NvencEncoder/f8856544c1d267a7255675837dd3cb9d237c39bb/doc/NvEncodeAPI_v.7.1.pdf -------------------------------------------------------------------------------- /doc/Nvenc内存拷贝方案性能测试.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarkRepo/NvencEncoder/f8856544c1d267a7255675837dd3cb9d237c39bb/doc/Nvenc内存拷贝方案性能测试.docx -------------------------------------------------------------------------------- /doc/S4654-detailed-overview-nvenc-encoder-api.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarkRepo/NvencEncoder/f8856544c1d267a7255675837dd3cb9d237c39bb/doc/S4654-detailed-overview-nvenc-encoder-api.pdf -------------------------------------------------------------------------------- /include/NvEncoder.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright 1993-2014 NVIDIA Corporation. All rights reserved. 4 | // 5 | // Please refer to the NVIDIA end user license agreement (EULA) associated 6 | // with this source code for terms and conditions that govern your use of 7 | // this software. Any use, reproduction, disclosure, or distribution of 8 | // this software and related documentation outside the terms of the EULA 9 | // is strictly prohibited. 10 | // 11 | //////////////////////////////////////////////////////////////////////////// 12 | 13 | #if defined(NV_WINDOWS) 14 | #include 15 | #include 16 | #include 17 | #pragma warning(disable : 4996) 18 | #endif 19 | 20 | #include "NvHWEncoder.h" 21 | #include "h264_route.h" 22 | 23 | #define MAX_ENCODE_QUEUE 32 24 | #define FRAME_QUEUE 240 25 | #define WIDTH_DEFAULT 1920 26 | #define HEIGHT_DEFAULT 1080 27 | 28 | #define SET_VER(configStruct, type) {configStruct.version = type##_VER;} 29 | #define __cu(a) do { CUresult ret; if ((ret = (a)) != CUDA_SUCCESS) { NvLog("%s has returned CUDA error %d", #a, ret); return ret;}} while(0) 30 | #define __cur(a,r) do { CUresult ret; if ((ret = (a)) != CUDA_SUCCESS) { NvLog("%s has returned CUDA error %d", #a, ret); return (r);}} while(0) 31 | #define __nv(a) do { NVENCSTATUS ret; if ((ret = (a)) != NV_ENC_SUCCESS) { NvLog("%s has returned NvEnc error %d", #a, ret); return ret;}} while(0) 32 | #define __nvr(a,r) do { NVENCSTATUS ret; if ((ret = (a)) != NV_ENC_SUCCESS) { NvLog("%s has returned NvEnc error %d", #a, ret); return (r);}} while(0) 33 | 34 | 35 | template 36 | class CNvQueue { 37 | T** m_pBuffer; 38 | unsigned int m_uSize; 39 | unsigned int m_uPendingCount; 40 | unsigned int m_uAvailableIdx; 41 | unsigned int m_uPendingndex; 42 | public: 43 | CNvQueue(): m_pBuffer(NULL), m_uSize(0), m_uPendingCount(0), m_uAvailableIdx(0), 44 | m_uPendingndex(0) 45 | { 46 | } 47 | 48 | ~CNvQueue() 49 | { 50 | delete[] m_pBuffer; 51 | } 52 | 53 | bool Initialize(T *pItems, unsigned int uSize) 54 | { 55 | m_uSize = uSize; 56 | m_uPendingCount = 0; 57 | m_uAvailableIdx = 0; 58 | m_uPendingndex = 0; 59 | m_pBuffer = new T *[m_uSize]; 60 | for (unsigned int i = 0; i < m_uSize; i++) 61 | { 62 | m_pBuffer[i] = &pItems[i]; 63 | } 64 | return true; 65 | } 66 | 67 | 68 | T * GetAvailable() 69 | { 70 | T *pItem = NULL; 71 | if (m_uPendingCount == m_uSize) 72 | { 73 | return NULL; 74 | } 75 | pItem = m_pBuffer[m_uAvailableIdx]; 76 | m_uAvailableIdx = (m_uAvailableIdx+1)%m_uSize; 77 | m_uPendingCount += 1; 78 | return pItem; 79 | } 80 | 81 | T* GetPending() 82 | { 83 | if (m_uPendingCount == 0) 84 | { 85 | return NULL; 86 | } 87 | 88 | T *pItem = m_pBuffer[m_uPendingndex]; 89 | m_uPendingndex = (m_uPendingndex+1)%m_uSize; 90 | m_uPendingCount -= 1; 91 | return pItem; 92 | } 93 | }; 94 | 95 | typedef struct _EncodeFrameConfig 96 | { 97 | uint8_t *yuv[3]; 98 | NVENC_BGRA* bgra; 99 | uint32_t stride[3]; 100 | uint32_t width; 101 | uint32_t height; 102 | }EncodeFrameConfig; 103 | 104 | typedef enum 105 | { 106 | NV_ENC_DX9 = 0, 107 | NV_ENC_DX11 = 1, 108 | NV_ENC_CUDA = 2, 109 | NV_ENC_DX10 = 3, 110 | } NvEncodeDeviceType; 111 | 112 | class CCudaAutoLock 113 | { 114 | private: 115 | CUcontext m_pCtx; 116 | public: 117 | CCudaAutoLock(CUcontext pCtx) :m_pCtx(pCtx) { cuCtxPushCurrent(m_pCtx); }; 118 | ~CCudaAutoLock() { CUcontext cuLast = NULL; cuCtxPopCurrent(&cuLast); }; 119 | }; 120 | 121 | 122 | class CNvEncoder 123 | { 124 | public: 125 | CNvEncoder(); 126 | virtual ~CNvEncoder(); 127 | // int EncoderInit(uint32_t ip, uint16_t port, int argc, ...); 128 | int EncoderInit(const int argc, ...); 129 | int EncoderInitZC(const int max_number_surface); 130 | NVENCSTATUS Deinitialize(); 131 | NVENCSTATUS DeinitializeZC(); 132 | NVENCSTATUS EncodeFrame(const void* pData, bool bFlush=false, uint32_t width=0, uint32_t height=0); 133 | NVENCSTATUS EncodeFrameZC(const int id); 134 | 135 | public: 136 | CNvHWEncoder *m_pNvHWEncoder; 137 | uint32_t m_uEncodeBufferCount; 138 | uint32_t m_uPicStruct; 139 | CUcontext m_pDevice; 140 | uint32_t m_numFramesEncoded; 141 | #if defined(NV_WINDOWS) 142 | IDirect3D9 *m_pD3D; 143 | #endif 144 | 145 | EncodeConfig m_stEncoderInput; 146 | int m_currentUseId; 147 | H264_INPUT_BUFFER_TYPE m_currentBufferType; 148 | int m_stEncodeBufferPtrCnt; 149 | EncodeBufferPtr* m_stEncodeBufferPtrArr; 150 | EncodeBuffer m_stEncodeBuffer[MAX_ENCODE_QUEUE]; 151 | MotionEstimationBuffer m_stMVBuffer[MAX_ENCODE_QUEUE]; 152 | CNvQueue m_EncodeBufferQueue; 153 | CNvQueue m_MVBufferQueue; 154 | EncodeOutputBuffer m_stEOSOutputBfr; 155 | 156 | protected: 157 | 158 | NVENCSTATUS InitD3D9(uint32_t deviceID = 0); 159 | NVENCSTATUS InitD3D11(uint32_t deviceID = 0); 160 | NVENCSTATUS InitD3D10(uint32_t deviceID = 0); 161 | NVENCSTATUS InitCuda(uint32_t deviceID = 0); 162 | NVENCSTATUS AllocateIOBuffers(uint32_t uInputWidth, uint32_t uInputHeight, NV_ENC_BUFFER_FORMAT inputFormat); 163 | 164 | NVENCSTATUS AllocateOutPutBuffersZC(uint32_t uInputWidth, uint32_t uInputHeight, NV_ENC_BUFFER_FORMAT inputFormat); 165 | NVENCSTATUS AllocateMVIOBuffers(uint32_t uInputWidth, uint32_t uInputHeight, NV_ENC_BUFFER_FORMAT inputFormat); 166 | NVENCSTATUS ReleaseIOBuffers(); 167 | NVENCSTATUS ReleaseIOBuffersZC(); 168 | NVENCSTATUS ReleaseMVIOBuffers(); 169 | unsigned char* LockInputBuffer(void * hInputSurface, uint32_t *pLockedPitch); 170 | NVENCSTATUS FlushEncoder(); 171 | void FlushMVOutputBuffer(); 172 | NVENCSTATUS RunMotionEstimationOnly(MEOnlyConfig *pMEOnly, bool bFlush); 173 | }; 174 | 175 | // NVEncodeAPI entry point 176 | typedef NVENCSTATUS (NVENCAPI *MYPROC)(NV_ENCODE_API_FUNCTION_LIST*); 177 | -------------------------------------------------------------------------------- /include/NvHWEncoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1993-2015 NVIDIA Corporation. All rights reserved. 3 | * 4 | * Please refer to the NVIDIA end user license agreement (EULA) associated 5 | * with this source code for terms and conditions that govern your use of 6 | * this software. Any use, reproduction, disclosure, or distribution of 7 | * this software and related documentation outside the terms of the EULA 8 | * is strictly prohibited. 9 | * 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include /* sockaddr_in{} and other Internet defns */ 17 | #include /* inet(3) functions */ 18 | #include 19 | #include 20 | #include 21 | #include "h264_log.h" 22 | 23 | 24 | #include "dynlink_cuda.h" // 25 | 26 | #include "nvEncodeAPI.h" 27 | #include "nvUtils.h" 28 | 29 | #define SET_VER(configStruct, type) {configStruct.version = type##_VER;} 30 | 31 | #if defined (NV_WINDOWS) 32 | #include "d3d9.h" 33 | #define NVENCAPI __stdcall 34 | #pragma warning(disable : 4996) 35 | #elif defined (NV_UNIX) 36 | #include 37 | #include 38 | #define NVENCAPI 39 | #endif 40 | 41 | #define DEFAULT_I_QFACTOR -0.8f 42 | #define DEFAULT_B_QFACTOR 1.25f 43 | #define DEFAULT_I_QOFFSET 0.f 44 | #define DEFAULT_B_QOFFSET 1.25f 45 | 46 | typedef struct frame_data_header_s 47 | { 48 | uint32_t length; 49 | uint32_t width; 50 | uint32_t height; 51 | }frame_data_header_t; 52 | 53 | 54 | typedef struct _EncodeConfig 55 | { 56 | int width; 57 | int height; 58 | int maxWidth; 59 | int maxHeight; 60 | int fps; 61 | int bitrate; 62 | int vbvMaxBitrate; 63 | int vbvSize; 64 | int rcMode; 65 | int qp; 66 | float i_quant_factor; 67 | float b_quant_factor; 68 | float i_quant_offset; 69 | float b_quant_offset; 70 | GUID presetGUID; 71 | FILE *fOutput; 72 | int codec; 73 | int invalidateRefFramesEnableFlag; 74 | int intraRefreshEnableFlag; 75 | int intraRefreshPeriod; 76 | int intraRefreshDuration; 77 | int deviceType; 78 | int startFrameIdx; 79 | int endFrameIdx; 80 | int gopLength; 81 | int numB; 82 | int pictureStruct; 83 | int deviceID; 84 | NV_ENC_BUFFER_FORMAT inputFormat; 85 | char *qpDeltaMapFile; 86 | char* inputFileName; 87 | char* outputFileName; 88 | char* encoderPreset; 89 | char* inputFilePath; 90 | char *encCmdFileName; 91 | int enableMEOnly; 92 | int enableAsyncMode; 93 | int preloadedFrameCount; 94 | int enableTemporalAQ; 95 | uint32_t sip; 96 | uint16_t sport; 97 | }EncodeConfig; 98 | 99 | typedef struct _EncodeInputBuffer 100 | { 101 | int surfaceId; 102 | unsigned int dwWidth; 103 | unsigned int dwHeight; 104 | #if defined (NV_WINDOWS) 105 | IDirect3DSurface9 *pNV12Surface; 106 | #endif 107 | CUdeviceptr pNV12devPtr; 108 | uint32_t uNV12Stride; 109 | CUdeviceptr pNV12TempdevPtr; 110 | uint32_t uNV12TempStride; 111 | uint8_t* pRGBHostPtr; 112 | void* nvRegisteredResource; 113 | NV_ENC_INPUT_PTR hInputSurface; 114 | NV_ENC_BUFFER_FORMAT bufferFmt; 115 | }EncodeInputBuffer; 116 | 117 | typedef struct _EncodeOutputBuffer 118 | { 119 | unsigned int dwBitstreamBufferSize; 120 | NV_ENC_OUTPUT_PTR hBitstreamBuffer; 121 | HANDLE hOutputEvent; 122 | bool bWaitOnEvent; 123 | bool bEOSFlag; 124 | }EncodeOutputBuffer; 125 | 126 | typedef struct _EncodeBuffer 127 | { 128 | EncodeOutputBuffer stOutputBfr; 129 | EncodeInputBuffer stInputBfr; 130 | }EncodeBuffer; 131 | 132 | typedef EncodeBuffer* EncodeBufferPtr; 133 | 134 | typedef struct _MotionEstimationBuffer 135 | { 136 | EncodeOutputBuffer stOutputBfr; 137 | EncodeInputBuffer stInputBfr[2]; 138 | unsigned int inputFrameIndex; 139 | unsigned int referenceFrameIndex; 140 | }MotionEstimationBuffer; 141 | 142 | typedef struct _NvEncPictureCommand 143 | { 144 | bool bResolutionChangePending; 145 | bool bBitrateChangePending; 146 | bool bForceIDR; 147 | bool bForceIntraRefresh; 148 | bool bInvalidateRefFrames; 149 | 150 | uint32_t newWidth; 151 | uint32_t newHeight; 152 | 153 | uint32_t newBitrate; 154 | uint32_t newVBVSize; 155 | 156 | uint32_t intraRefreshDuration; 157 | 158 | uint32_t numRefFramesToInvalidate; 159 | uint32_t refFrameNumbers[16]; 160 | }NvEncPictureCommand; 161 | 162 | enum 163 | { 164 | NV_ENC_H264 = 0, 165 | NV_ENC_HEVC = 1, 166 | }; 167 | 168 | struct MEOnlyConfig 169 | { 170 | unsigned char *yuv[2][3]; 171 | unsigned int stride[3]; 172 | unsigned int width; 173 | unsigned int height; 174 | unsigned int inputFrameIndex; 175 | unsigned int referenceFrameIndex; 176 | }; 177 | 178 | class CNvHWEncoder 179 | { 180 | public: 181 | uint32_t m_EncodeIdx; 182 | FILE *m_fOutput; 183 | uint32_t m_uMaxWidth; 184 | uint32_t m_uMaxHeight; 185 | uint32_t m_uCurWidth; 186 | uint32_t m_uCurHeight; 187 | unsigned long long m_sum_en_time; 188 | unsigned long long m_process_time; 189 | uint32_t m_frm_idx; 190 | uint32_t m_frm_cnt; 191 | uint8_t* m_out_buffer; 192 | // uint8_t m_sockfd; 193 | int m_listenfd; 194 | int m_connfd; 195 | 196 | public: 197 | bool m_bEncoderInitialized; 198 | GUID codecGUID; 199 | 200 | NV_ENCODE_API_FUNCTION_LIST* m_pEncodeAPI; 201 | HINSTANCE m_hinstLib; 202 | void *m_hEncoder; 203 | NV_ENC_INITIALIZE_PARAMS m_stCreateEncodeParams; 204 | NV_ENC_CONFIG m_stEncodeConfig; 205 | 206 | public: 207 | NVENCSTATUS NvEncOpenEncodeSession(void* device, uint32_t deviceType); 208 | NVENCSTATUS NvEncGetEncodeGUIDCount(uint32_t* encodeGUIDCount); 209 | NVENCSTATUS NvEncGetEncodeProfileGUIDCount(GUID encodeGUID, uint32_t* encodeProfileGUIDCount); 210 | NVENCSTATUS NvEncGetEncodeProfileGUIDs(GUID encodeGUID, GUID* profileGUIDs, uint32_t guidArraySize, uint32_t* GUIDCount); 211 | NVENCSTATUS NvEncGetEncodeGUIDs(GUID* GUIDs, uint32_t guidArraySize, uint32_t* GUIDCount); 212 | NVENCSTATUS NvEncGetInputFormatCount(GUID encodeGUID, uint32_t* inputFmtCount); 213 | NVENCSTATUS NvEncGetInputFormats(GUID encodeGUID, NV_ENC_BUFFER_FORMAT* inputFmts, uint32_t inputFmtArraySize, uint32_t* inputFmtCount); 214 | NVENCSTATUS NvEncGetEncodeCaps(GUID encodeGUID, NV_ENC_CAPS_PARAM* capsParam, int* capsVal); 215 | NVENCSTATUS NvEncGetEncodePresetCount(GUID encodeGUID, uint32_t* encodePresetGUIDCount); 216 | NVENCSTATUS NvEncGetEncodePresetGUIDs(GUID encodeGUID, GUID* presetGUIDs, uint32_t guidArraySize, uint32_t* encodePresetGUIDCount); 217 | NVENCSTATUS NvEncGetEncodePresetConfig(GUID encodeGUID, GUID presetGUID, NV_ENC_PRESET_CONFIG* presetConfig); 218 | NVENCSTATUS NvEncCreateInputBuffer(uint32_t width, uint32_t height, void** inputBuffer, NV_ENC_BUFFER_FORMAT inputFormat); 219 | NVENCSTATUS NvEncDestroyInputBuffer(NV_ENC_INPUT_PTR inputBuffer); 220 | NVENCSTATUS NvEncCreateBitstreamBuffer(uint32_t size, void** bitstreamBuffer); 221 | NVENCSTATUS NvEncDestroyBitstreamBuffer(NV_ENC_OUTPUT_PTR bitstreamBuffer); 222 | NVENCSTATUS NvEncCreateMVBuffer(uint32_t size, void** bitstreamBuffer); 223 | NVENCSTATUS NvEncDestroyMVBuffer(NV_ENC_OUTPUT_PTR bitstreamBuffer); 224 | NVENCSTATUS NvRunMotionEstimationOnly(MotionEstimationBuffer *pMEBuffer, MEOnlyConfig *pMEOnly); 225 | NVENCSTATUS NvEncLockBitstream(NV_ENC_LOCK_BITSTREAM* lockBitstreamBufferParams); 226 | NVENCSTATUS NvEncUnlockBitstream(NV_ENC_OUTPUT_PTR bitstreamBuffer); 227 | NVENCSTATUS NvEncLockInputBuffer(void* inputBuffer, void** bufferDataPtr, uint32_t* pitch); 228 | NVENCSTATUS NvEncUnlockInputBuffer(NV_ENC_INPUT_PTR inputBuffer); 229 | NVENCSTATUS NvEncGetEncodeStats(NV_ENC_STAT* encodeStats); 230 | NVENCSTATUS NvEncGetSequenceParams(NV_ENC_SEQUENCE_PARAM_PAYLOAD* sequenceParamPayload); 231 | NVENCSTATUS NvEncRegisterAsyncEvent(void** completionEvent); 232 | NVENCSTATUS NvEncUnregisterAsyncEvent(void* completionEvent); 233 | NVENCSTATUS NvEncMapInputResource(void* registeredResource, void** mappedResource); 234 | NVENCSTATUS NvEncUnmapInputResource(NV_ENC_INPUT_PTR mappedInputBuffer); 235 | NVENCSTATUS NvEncDestroyEncoder(); 236 | NVENCSTATUS NvEncInvalidateRefFrames(const NvEncPictureCommand *pEncPicCommand); 237 | NVENCSTATUS NvEncOpenEncodeSessionEx(void* device, NV_ENC_DEVICE_TYPE deviceType); 238 | NVENCSTATUS NvEncRegisterResource(NV_ENC_INPUT_RESOURCE_TYPE resourceType, void* resourceToRegister, uint32_t width, uint32_t height, uint32_t pitch, void** registeredResource); 239 | NVENCSTATUS NvEncUnregisterResource(NV_ENC_REGISTERED_PTR registeredRes); 240 | NVENCSTATUS NvEncReconfigureEncoder(const NvEncPictureCommand *pEncPicCommand); 241 | NVENCSTATUS NvEncFlushEncoderQueue(void *hEOSEvent); 242 | 243 | CNvHWEncoder(); 244 | virtual ~CNvHWEncoder(); 245 | NVENCSTATUS Initialize(void* device, NV_ENC_DEVICE_TYPE deviceType); 246 | NVENCSTATUS Deinitialize(); 247 | // int Init_tcp_connect(); 248 | int Init_tcp_serv(); 249 | NVENCSTATUS NvEncEncodeFrame(EncodeBuffer *pEncodeBuffer, NvEncPictureCommand *encPicCommand, 250 | uint32_t width, uint32_t height, 251 | NV_ENC_PIC_STRUCT ePicStruct = NV_ENC_PIC_STRUCT_FRAME, 252 | int8_t *qpDeltaMapArray = NULL, uint32_t qpDeltaMapArraySize = 0); 253 | NVENCSTATUS CreateEncoder(EncodeConfig *pEncCfg); 254 | GUID GetPresetGUID(char* encoderPreset, int codec); 255 | NVENCSTATUS ProcessOutput(const EncodeBuffer *pEncodeBuffer); 256 | NVENCSTATUS ProcessMVOutput(const MotionEstimationBuffer *pEncodeBuffer); 257 | NVENCSTATUS FlushEncoder(); 258 | NVENCSTATUS ValidateEncodeGUID(GUID inputCodecGuid); 259 | NVENCSTATUS ValidatePresetGUID(GUID presetCodecGuid, GUID inputCodecGuid); 260 | static NVENCSTATUS ParseArguments(EncodeConfig *encodeConfig, int argc, char *argv[]); 261 | }; 262 | 263 | typedef NVENCSTATUS (NVENCAPI *MYPROC)(NV_ENCODE_API_FUNCTION_LIST*); 264 | -------------------------------------------------------------------------------- /include/dynlink_cuda.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1993-2015 NVIDIA Corporation. All rights reserved. 3 | * 4 | * Please refer to the NVIDIA end user license agreement (EULA) associated 5 | * with this source code for terms and conditions that govern your use of 6 | * this software. Any use, reproduction, disclosure, or distribution of 7 | * this software and related documentation outside the terms of the EULA 8 | * is strictly prohibited. 9 | * 10 | */ 11 | 12 | #ifndef __cuda_h__ 13 | #define __cuda_h__ 14 | 15 | /** 16 | * CUDA API version support 17 | */ 18 | 19 | #include "dynlink_cuda_cuda.h" 20 | 21 | #endif //__cuda_h__ 22 | -------------------------------------------------------------------------------- /include/h264_log.h: -------------------------------------------------------------------------------- 1 | #ifndef _H264_LOG_H_ 2 | #define _H264_LOG_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | //#define H264_DEBUGGING 10 | 11 | extern char gLogFileName[]; 12 | 13 | void H264_VLog(const char* file, int line, const char *format, va_list args); 14 | void H264_Log(const char* file, int line, const char *format, ...); 15 | void H264_DebugLog(const char* file, int line, const char *format, ...); 16 | void H264_LogInitFile(char *fileName); 17 | void H264_LogCloseFile(); 18 | 19 | #define NvLog(format, args...) H264_Log(__FILE__, __LINE__, format, ##args) 20 | 21 | #ifdef H264_DEBUGGING 22 | #define NvDebugLog(format, args...) H264_DebugLog(__FILE__, __LINE__, format, ##args) 23 | #else 24 | #define NvDebugLog(format, args...) 25 | #endif 26 | 27 | #endif -------------------------------------------------------------------------------- /include/h264_route.h: -------------------------------------------------------------------------------- 1 | #ifndef _H264_ROUTE_H_ 2 | #define _H264_ROUTE_H_ 3 | 4 | #include 5 | #include 6 | 7 | typedef enum { 8 | INVALID_BUFFER_TYPE = 0, 9 | NVENC_INPUT_BUFFER = 1, 10 | CUDA_DEVICE_BUFFER = 2, 11 | CUDA_HOST_BUFFER = 3, 12 | }H264_INPUT_BUFFER_TYPE; 13 | 14 | #ifdef _cplusplus 15 | extern "C" 16 | { 17 | #endif 18 | 19 | extern int h264_init(const int argc, ...); 20 | extern int h264_route(const pixman_image_t* ppi, const int argc, ...); 21 | extern int h264_release(); 22 | 23 | // zero-copy interface 24 | extern int h264_init_zc(const int max_number_surface); 25 | extern void* h264_create_mem_zc(const int stride, const int height, const int id); 26 | extern int h264_destroy_mem_zc(const int id); 27 | extern int h264_route_zc(const int id); 28 | extern int h264_release_zc(); 29 | 30 | //unify interface 31 | extern int nvenc_init(const int max_number_surface, const H264_INPUT_BUFFER_TYPE buffer_type); 32 | extern void* nvenc_create_mem(const int stride, const int height, const int id); 33 | extern int nvenc_destroy_mem(const int id); 34 | extern int nvenc_route(const int id); 35 | extern int nvenc_release(); 36 | 37 | #ifdef _cplusplus 38 | } 39 | #endif 40 | 41 | #endif 42 | 43 | -------------------------------------------------------------------------------- /include/nvCPUOPSys.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1993-2015 NVIDIA Corporation. All rights reserved. 3 | * 4 | * Please refer to the NVIDIA end user license agreement (EULA) associated 5 | * with this source code for terms and conditions that govern your use of 6 | * this software. Any use, reproduction, disclosure, or distribution of 7 | * this software and related documentation outside the terms of the EULA 8 | * is strictly prohibited. 9 | * 10 | */ 11 | 12 | #ifndef NVCPUOPSYS_H 13 | #define NVCPUOPSYS_H 14 | 15 | 16 | #if defined(_WIN32) || defined(_WIN16) 17 | # define NV_WINDOWS 18 | #endif 19 | 20 | #if (defined(__unix__) || defined(__unix) ) && !defined(nvmacosx) && !defined(vxworks) && !defined(__DJGPP__) && !defined(NV_UNIX) && !defined(__QNX__) && !defined(__QNXNTO__)/* XXX until removed from Makefiles */ 21 | # define NV_UNIX 22 | #endif /* defined(__unix__) */ 23 | 24 | #if defined(__linux__) && !defined(NV_LINUX) && !defined(NV_VMWARE) 25 | # define NV_LINUX 26 | #endif /* defined(__linux__) */ 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /include/nvFileIO.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1993-2015 NVIDIA Corporation. All rights reserved. 3 | * 4 | * Please refer to the NVIDIA end user license agreement (EULA) associated 5 | * with this source code for terms and conditions that govern your use of 6 | * this software. Any use, reproduction, disclosure, or distribution of 7 | * this software and related documentation outside the terms of the EULA 8 | * is strictly prohibited. 9 | * 10 | */ 11 | 12 | #ifndef NVFILE_IO_H 13 | #define NVFILE_IO_H 14 | 15 | #if defined __linux__ 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | typedef void * HANDLE; 27 | typedef void *HINSTANCE; 28 | typedef unsigned long DWORD, *LPDWORD; 29 | typedef DWORD FILE_SIZE; 30 | 31 | #define FALSE 0 32 | #define TRUE 1 33 | #define INFINITE UINT_MAX 34 | 35 | #define FILE_BEGIN SEEK_SET 36 | #define INVALID_SET_FILE_POINTER (-1) 37 | #define INVALID_HANDLE_VALUE ((void *)(-1)) 38 | 39 | #else 40 | #include 41 | #include 42 | #endif 43 | 44 | #include "nvCPUOPSys.h" 45 | 46 | typedef unsigned long long U64; 47 | typedef unsigned int U32; 48 | 49 | inline U32 nvSetFilePointer(HANDLE hInputFile, U32 fileOffset, U32 *moveFilePointer, U32 flag) 50 | { 51 | #if defined (NV_WINDOWS) 52 | return SetFilePointer(hInputFile, fileOffset, NULL, flag); 53 | #elif defined __linux || defined __APPLE_ || defined __MACOSX 54 | return fseek((FILE *)hInputFile, fileOffset, flag); 55 | #endif 56 | } 57 | 58 | inline U32 nvSetFilePointer64(HANDLE hInputFile, U64 fileOffset, U64 *moveFilePointer, U32 flag) 59 | { 60 | #if defined (NV_WINDOWS) 61 | return SetFilePointer(hInputFile, ((U32 *)&fileOffset)[0], (PLONG)&((U32 *)&fileOffset)[1], flag); 62 | #elif defined __linux || defined __APPLE__ || defined __MACOSX 63 | return fseek((FILE *)hInputFile, (long int)fileOffset, flag); 64 | #endif 65 | } 66 | 67 | inline bool nvReadFile(HANDLE hInputFile, void *buf, U32 bytes_to_read, U32 *bytes_read, void *operlapped) 68 | { 69 | #if defined (NV_WINDOWS) 70 | ReadFile(hInputFile, buf, bytes_to_read, (LPDWORD)bytes_read, NULL); 71 | return true; 72 | #elif defined __linux || defined __APPLE__ || defined __MACOSX 73 | U32 elems_read; 74 | elems_read = fread(buf, bytes_to_read, 1, (FILE *)hInputFile); 75 | 76 | if (bytes_read) 77 | { 78 | *bytes_read = elems_read > 0 ? bytes_to_read : 0; 79 | } 80 | return true; 81 | #endif 82 | } 83 | 84 | inline void nvGetFileSize(HANDLE hInputFile, DWORD *pFilesize) 85 | { 86 | #if defined (NV_WINDOWS) 87 | LARGE_INTEGER file_size; 88 | 89 | if (hInputFile != INVALID_HANDLE_VALUE) 90 | { 91 | file_size.LowPart = GetFileSize(hInputFile, (LPDWORD)&file_size.HighPart); 92 | printf("[ Input Filesize] : %ld bytes\n", ((LONGLONG) file_size.HighPart << 32) + (LONGLONG)file_size.LowPart); 93 | 94 | if (pFilesize != NULL) *pFilesize = file_size.LowPart; 95 | } 96 | 97 | #elif defined __linux || defined __APPLE__ || defined __MACOSX 98 | FILE_SIZE file_size; 99 | 100 | if (hInputFile != NULL) 101 | { 102 | nvSetFilePointer64(hInputFile, 0, NULL, SEEK_END); 103 | file_size = ftell((FILE *)hInputFile); 104 | nvSetFilePointer64(hInputFile, 0, NULL, SEEK_SET); 105 | printf("Input Filesize: %ld bytes\n", file_size); 106 | 107 | if (pFilesize != NULL) *pFilesize = file_size; 108 | } 109 | 110 | #endif 111 | } 112 | 113 | inline HANDLE nvOpenFile(const char *input_file) 114 | { 115 | HANDLE hInput = NULL; 116 | 117 | #if defined (NV_WINDOWS) 118 | hInput = CreateFileA(input_file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL, NULL); 119 | 120 | if (hInput == INVALID_HANDLE_VALUE) 121 | { 122 | fprintf(stderr, "nvOpenFile Failed to open \"%s\"\n", input_file); 123 | exit(EXIT_FAILURE); 124 | } 125 | 126 | #elif defined __linux || defined __APPLE_ || defined __MACOSX 127 | hInput = fopen(input_file, "rb"); 128 | 129 | if (hInput == NULL) 130 | { 131 | fprintf(stderr, "nvOpenFile Failed to open \"%s\"\n", input_file); 132 | exit(EXIT_FAILURE); 133 | } 134 | 135 | #endif 136 | return hInput; 137 | } 138 | 139 | inline HANDLE nvOpenFileWrite(const char *output_file) 140 | { 141 | HANDLE hOutput = NULL; 142 | 143 | #if defined (NV_WINDOWS) 144 | hOutput = CreateFileA(output_file, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL, NULL); 145 | 146 | if (hOutput == INVALID_HANDLE_VALUE) 147 | { 148 | fprintf(stderr, "nvOpenFileWrite Failed to open \"%s\"\n", output_file); 149 | exit(EXIT_FAILURE); 150 | } 151 | 152 | #elif defined __linux || defined __APPLE_ || defined __MACOSX 153 | hOutput = fopen(output_file, "wb+"); 154 | 155 | if (hOutput == NULL) 156 | { 157 | fprintf(stderr, "nvOpenFileWrite Failed to open \"%s\"\n", output_file); 158 | exit(EXIT_FAILURE); 159 | } 160 | 161 | #endif 162 | return hOutput; 163 | } 164 | 165 | inline void nvCloseFile(HANDLE hFileHandle) 166 | { 167 | if (hFileHandle) 168 | { 169 | #if defined (NV_WINDOWS) 170 | CloseHandle(hFileHandle); 171 | #else 172 | fclose((FILE *)hFileHandle); 173 | #endif 174 | } 175 | } 176 | 177 | #endif 178 | -------------------------------------------------------------------------------- /include/nvUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1993-2015 NVIDIA Corporation. All rights reserved. 3 | * 4 | * Please refer to the NVIDIA end user license agreement (EULA) associated 5 | * with this source code for terms and conditions that govern your use of 6 | * this software. Any use, reproduction, disclosure, or distribution of 7 | * this software and related documentation outside the terms of the EULA 8 | * is strictly prohibited. 9 | * 10 | */ 11 | 12 | #ifndef NVUTILS_H 13 | #define NVUTILS_H 14 | 15 | #include "nvCPUOPSys.h" 16 | //#include "nvFileIO.h" 17 | #include 18 | 19 | 20 | #if defined (NV_WINDOWS) 21 | #include 22 | 23 | #elif defined NV_UNIX 24 | #include 25 | #include 26 | 27 | #define FALSE 0 28 | #define TRUE 1 29 | #define S_OK 0 30 | #define INFINITE UINT_MAX 31 | #define stricmp strcasecmp 32 | #define FILE_BEGIN SEEK_SET 33 | #define INVALID_SET_FILE_POINTER (-1) 34 | #define INVALID_HANDLE_VALUE ((void *)(-1)) 35 | 36 | typedef void* HANDLE; 37 | typedef void* HINSTANCE; 38 | typedef unsigned long DWORD, *LPWORD; 39 | typedef DWORD FILE_SIZE; 40 | typedef DWORD HRESULT; 41 | 42 | #endif 43 | 44 | #define MAX(a, b) ((a) > (b) ? (a) : (b)) 45 | #define MIN(a, b) ((a) < (b) ? (a) : (b)) 46 | #define FABS(a) ((a) >= 0 ? (a) : -(a)) 47 | 48 | inline bool NvSleep(unsigned int mSec) 49 | { 50 | #if defined (NV_WINDOWS) 51 | Sleep(mSec); 52 | #elif defined NV_UNIX 53 | usleep(mSec * 1000); 54 | #else 55 | #error NvSleep function unknown for this platform. 56 | #endif 57 | return true; 58 | } 59 | 60 | inline bool NvQueryPerformanceFrequency(unsigned long long *freq) 61 | { 62 | *freq = 0; 63 | #if defined (NV_WINDOWS) 64 | LARGE_INTEGER lfreq; 65 | if (!QueryPerformanceFrequency(&lfreq)) { 66 | return false; 67 | } 68 | *freq = lfreq.QuadPart; 69 | #elif defined NV_UNIX 70 | // We use system's gettimeofday() to return timer ticks in uSec 71 | *freq = 1000000000; 72 | #else 73 | #error NvQueryPerformanceFrequency function not defined for this platform. 74 | #endif 75 | 76 | return true; 77 | } 78 | 79 | #define SEC_TO_NANO_ULL(sec) ((unsigned long long)sec * 1000000000) 80 | #define MICRO_TO_NANO_ULL(sec) ((unsigned long long)sec * 1000) 81 | 82 | inline bool NvQueryPerformanceCounter(unsigned long long *counter) 83 | { 84 | *counter = 0; 85 | #if defined (NV_WINDOWS) 86 | LARGE_INTEGER lcounter; 87 | if (!QueryPerformanceCounter(&lcounter)) { 88 | return false; 89 | } 90 | *counter = lcounter.QuadPart; 91 | #elif defined NV_UNIX 92 | struct timeval tv; 93 | int ret; 94 | 95 | ret = gettimeofday(&tv, NULL); 96 | if (ret != 0) { 97 | return false; 98 | } 99 | 100 | *counter = SEC_TO_NANO_ULL(tv.tv_sec) + MICRO_TO_NANO_ULL(tv.tv_usec); 101 | #else 102 | #error NvQueryPerformanceCounter function not defined for this platform. 103 | #endif 104 | return true; 105 | } 106 | 107 | #if defined NV_UNIX 108 | __inline bool operator==(const GUID &guid1, const GUID &guid2) 109 | { 110 | if (guid1.Data1 == guid2.Data1 && 111 | guid1.Data2 == guid2.Data2 && 112 | guid1.Data3 == guid2.Data3 && 113 | guid1.Data4[0] == guid2.Data4[0] && 114 | guid1.Data4[1] == guid2.Data4[1] && 115 | guid1.Data4[2] == guid2.Data4[2] && 116 | guid1.Data4[3] == guid2.Data4[3] && 117 | guid1.Data4[4] == guid2.Data4[4] && 118 | guid1.Data4[5] == guid2.Data4[5] && 119 | guid1.Data4[6] == guid2.Data4[6] && 120 | guid1.Data4[7] == guid2.Data4[7]) 121 | { 122 | return true; 123 | } 124 | 125 | return false; 126 | } 127 | __inline bool operator!=(const GUID &guid1, const GUID &guid2) 128 | { 129 | return !(guid1 == guid2); 130 | } 131 | #endif 132 | #endif 133 | 134 | #define PRINTERR(message, ...) \ 135 | fprintf(stderr, "%s line %d: " message, __FILE__, __LINE__, ##__VA_ARGS__) 136 | -------------------------------------------------------------------------------- /include/pixman-version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2008 Red Hat, Inc. 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, copy, 8 | * modify, merge, publish, distribute, sublicense, and/or sell copies 9 | * of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | * Author: Carl D. Worth 25 | */ 26 | 27 | #ifndef PIXMAN_VERSION_H__ 28 | #define PIXMAN_VERSION_H__ 29 | 30 | #ifndef PIXMAN_H__ 31 | # error pixman-version.h should only be included by pixman.h 32 | #endif 33 | 34 | #define PIXMAN_VERSION_MAJOR 0 35 | #define PIXMAN_VERSION_MINOR 32 36 | #define PIXMAN_VERSION_MICRO 8 37 | 38 | #define PIXMAN_VERSION_STRING "0.32.8" 39 | 40 | #define PIXMAN_VERSION_ENCODE(major, minor, micro) ( \ 41 | ((major) * 10000) \ 42 | + ((minor) * 100) \ 43 | + ((micro) * 1)) 44 | 45 | #define PIXMAN_VERSION PIXMAN_VERSION_ENCODE( \ 46 | PIXMAN_VERSION_MAJOR, \ 47 | PIXMAN_VERSION_MINOR, \ 48 | PIXMAN_VERSION_MICRO) 49 | 50 | #endif /* PIXMAN_VERSION_H__ */ 51 | -------------------------------------------------------------------------------- /include/pixman.h: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | 3 | Copyright 1987, 1998 The Open Group 4 | 5 | Permission to use, copy, modify, distribute, and sell this software and its 6 | documentation for any purpose is hereby granted without fee, provided that 7 | the above copyright notice appear in all copies and that both that 8 | copyright notice and this permission notice appear in supporting 9 | documentation. 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | 21 | Except as contained in this notice, the name of The Open Group shall not be 22 | used in advertising or otherwise to promote the sale, use or other dealings 23 | in this Software without prior written authorization from The Open Group. 24 | 25 | Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. 26 | 27 | All Rights Reserved 28 | 29 | Permission to use, copy, modify, and distribute this software and its 30 | documentation for any purpose and without fee is hereby granted, 31 | provided that the above copyright notice appear in all copies and that 32 | both that copyright notice and this permission notice appear in 33 | supporting documentation, and that the name of Digital not be 34 | used in advertising or publicity pertaining to distribution of the 35 | software without specific, written prior permission. 36 | 37 | DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 38 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 39 | DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 40 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 41 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 42 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 43 | SOFTWARE. 44 | 45 | ******************************************************************/ 46 | /* 47 | * Copyright © 1998, 2004 Keith Packard 48 | * Copyright 2007 Red Hat, Inc. 49 | * 50 | * Permission to use, copy, modify, distribute, and sell this software and its 51 | * documentation for any purpose is hereby granted without fee, provided that 52 | * the above copyright notice appear in all copies and that both that 53 | * copyright notice and this permission notice appear in supporting 54 | * documentation, and that the name of Keith Packard not be used in 55 | * advertising or publicity pertaining to distribution of the software without 56 | * specific, written prior permission. Keith Packard makes no 57 | * representations about the suitability of this software for any purpose. It 58 | * is provided "as is" without express or implied warranty. 59 | * 60 | * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 61 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 62 | * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 63 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 64 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 65 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 66 | * PERFORMANCE OF THIS SOFTWARE. 67 | */ 68 | 69 | #ifndef PIXMAN_H__ 70 | #define PIXMAN_H__ 71 | 72 | #include 73 | 74 | #ifdef __cplusplus 75 | #define PIXMAN_BEGIN_DECLS extern "C" { 76 | #define PIXMAN_END_DECLS } 77 | #else 78 | #define PIXMAN_BEGIN_DECLS 79 | #define PIXMAN_END_DECLS 80 | #endif 81 | 82 | PIXMAN_BEGIN_DECLS 83 | 84 | /* 85 | * Standard integers 86 | */ 87 | 88 | #if !defined (PIXMAN_DONT_DEFINE_STDINT) 89 | 90 | #if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || defined (_sgi) || defined (__sun) || defined (sun) || defined (__digital__) || defined (__HP_cc) 91 | # include 92 | /* VS 2010 (_MSC_VER 1600) has stdint.h */ 93 | #elif defined (_MSC_VER) && _MSC_VER < 1600 94 | typedef __int8 int8_t; 95 | typedef unsigned __int8 uint8_t; 96 | typedef __int16 int16_t; 97 | typedef unsigned __int16 uint16_t; 98 | typedef __int32 int32_t; 99 | typedef unsigned __int32 uint32_t; 100 | typedef __int64 int64_t; 101 | typedef unsigned __int64 uint64_t; 102 | #elif defined (_AIX) 103 | # include 104 | #else 105 | # include 106 | #endif 107 | 108 | #endif 109 | 110 | /* 111 | * Boolean 112 | */ 113 | typedef int pixman_bool_t; 114 | 115 | /* 116 | * Fixpoint numbers 117 | */ 118 | typedef int64_t pixman_fixed_32_32_t; 119 | typedef pixman_fixed_32_32_t pixman_fixed_48_16_t; 120 | typedef uint32_t pixman_fixed_1_31_t; 121 | typedef uint32_t pixman_fixed_1_16_t; 122 | typedef int32_t pixman_fixed_16_16_t; 123 | typedef pixman_fixed_16_16_t pixman_fixed_t; 124 | 125 | #define pixman_fixed_e ((pixman_fixed_t) 1) 126 | #define pixman_fixed_1 (pixman_int_to_fixed(1)) 127 | #define pixman_fixed_1_minus_e (pixman_fixed_1 - pixman_fixed_e) 128 | #define pixman_fixed_minus_1 (pixman_int_to_fixed(-1)) 129 | #define pixman_fixed_to_int(f) ((int) ((f) >> 16)) 130 | #define pixman_int_to_fixed(i) ((pixman_fixed_t) ((i) << 16)) 131 | #define pixman_fixed_to_double(f) (double) ((f) / (double) pixman_fixed_1) 132 | #define pixman_double_to_fixed(d) ((pixman_fixed_t) ((d) * 65536.0)) 133 | #define pixman_fixed_frac(f) ((f) & pixman_fixed_1_minus_e) 134 | #define pixman_fixed_floor(f) ((f) & ~pixman_fixed_1_minus_e) 135 | #define pixman_fixed_ceil(f) pixman_fixed_floor ((f) + pixman_fixed_1_minus_e) 136 | #define pixman_fixed_fraction(f) ((f) & pixman_fixed_1_minus_e) 137 | #define pixman_fixed_mod_2(f) ((f) & (pixman_fixed1 | pixman_fixed_1_minus_e)) 138 | #define pixman_max_fixed_48_16 ((pixman_fixed_48_16_t) 0x7fffffff) 139 | #define pixman_min_fixed_48_16 (-((pixman_fixed_48_16_t) 1 << 31)) 140 | 141 | /* 142 | * Misc structs 143 | */ 144 | typedef struct pixman_color pixman_color_t; 145 | typedef struct pixman_point_fixed pixman_point_fixed_t; 146 | typedef struct pixman_line_fixed pixman_line_fixed_t; 147 | typedef struct pixman_vector pixman_vector_t; 148 | typedef struct pixman_transform pixman_transform_t; 149 | 150 | struct pixman_color 151 | { 152 | uint16_t red; 153 | uint16_t green; 154 | uint16_t blue; 155 | uint16_t alpha; 156 | }; 157 | 158 | struct pixman_point_fixed 159 | { 160 | pixman_fixed_t x; 161 | pixman_fixed_t y; 162 | }; 163 | 164 | struct pixman_line_fixed 165 | { 166 | pixman_point_fixed_t p1, p2; 167 | }; 168 | 169 | /* 170 | * Fixed point matrices 171 | */ 172 | 173 | struct pixman_vector 174 | { 175 | pixman_fixed_t vector[3]; 176 | }; 177 | 178 | struct pixman_transform 179 | { 180 | pixman_fixed_t matrix[3][3]; 181 | }; 182 | 183 | /* forward declaration (sorry) */ 184 | struct pixman_box16; 185 | typedef union pixman_image pixman_image_t; 186 | 187 | void pixman_transform_init_identity (struct pixman_transform *matrix); 188 | pixman_bool_t pixman_transform_point_3d (const struct pixman_transform *transform, 189 | struct pixman_vector *vector); 190 | pixman_bool_t pixman_transform_point (const struct pixman_transform *transform, 191 | struct pixman_vector *vector); 192 | pixman_bool_t pixman_transform_multiply (struct pixman_transform *dst, 193 | const struct pixman_transform *l, 194 | const struct pixman_transform *r); 195 | void pixman_transform_init_scale (struct pixman_transform *t, 196 | pixman_fixed_t sx, 197 | pixman_fixed_t sy); 198 | pixman_bool_t pixman_transform_scale (struct pixman_transform *forward, 199 | struct pixman_transform *reverse, 200 | pixman_fixed_t sx, 201 | pixman_fixed_t sy); 202 | void pixman_transform_init_rotate (struct pixman_transform *t, 203 | pixman_fixed_t cos, 204 | pixman_fixed_t sin); 205 | pixman_bool_t pixman_transform_rotate (struct pixman_transform *forward, 206 | struct pixman_transform *reverse, 207 | pixman_fixed_t c, 208 | pixman_fixed_t s); 209 | void pixman_transform_init_translate (struct pixman_transform *t, 210 | pixman_fixed_t tx, 211 | pixman_fixed_t ty); 212 | pixman_bool_t pixman_transform_translate (struct pixman_transform *forward, 213 | struct pixman_transform *reverse, 214 | pixman_fixed_t tx, 215 | pixman_fixed_t ty); 216 | pixman_bool_t pixman_transform_bounds (const struct pixman_transform *matrix, 217 | struct pixman_box16 *b); 218 | pixman_bool_t pixman_transform_invert (struct pixman_transform *dst, 219 | const struct pixman_transform *src); 220 | pixman_bool_t pixman_transform_is_identity (const struct pixman_transform *t); 221 | pixman_bool_t pixman_transform_is_scale (const struct pixman_transform *t); 222 | pixman_bool_t pixman_transform_is_int_translate (const struct pixman_transform *t); 223 | pixman_bool_t pixman_transform_is_inverse (const struct pixman_transform *a, 224 | const struct pixman_transform *b); 225 | 226 | /* 227 | * Floating point matrices 228 | */ 229 | typedef struct pixman_f_transform pixman_f_transform_t; 230 | typedef struct pixman_f_vector pixman_f_vector_t; 231 | 232 | struct pixman_f_vector 233 | { 234 | double v[3]; 235 | }; 236 | 237 | struct pixman_f_transform 238 | { 239 | double m[3][3]; 240 | }; 241 | 242 | pixman_bool_t pixman_transform_from_pixman_f_transform (struct pixman_transform *t, 243 | const struct pixman_f_transform *ft); 244 | void pixman_f_transform_from_pixman_transform (struct pixman_f_transform *ft, 245 | const struct pixman_transform *t); 246 | pixman_bool_t pixman_f_transform_invert (struct pixman_f_transform *dst, 247 | const struct pixman_f_transform *src); 248 | pixman_bool_t pixman_f_transform_point (const struct pixman_f_transform *t, 249 | struct pixman_f_vector *v); 250 | void pixman_f_transform_point_3d (const struct pixman_f_transform *t, 251 | struct pixman_f_vector *v); 252 | void pixman_f_transform_multiply (struct pixman_f_transform *dst, 253 | const struct pixman_f_transform *l, 254 | const struct pixman_f_transform *r); 255 | void pixman_f_transform_init_scale (struct pixman_f_transform *t, 256 | double sx, 257 | double sy); 258 | pixman_bool_t pixman_f_transform_scale (struct pixman_f_transform *forward, 259 | struct pixman_f_transform *reverse, 260 | double sx, 261 | double sy); 262 | void pixman_f_transform_init_rotate (struct pixman_f_transform *t, 263 | double cos, 264 | double sin); 265 | pixman_bool_t pixman_f_transform_rotate (struct pixman_f_transform *forward, 266 | struct pixman_f_transform *reverse, 267 | double c, 268 | double s); 269 | void pixman_f_transform_init_translate (struct pixman_f_transform *t, 270 | double tx, 271 | double ty); 272 | pixman_bool_t pixman_f_transform_translate (struct pixman_f_transform *forward, 273 | struct pixman_f_transform *reverse, 274 | double tx, 275 | double ty); 276 | pixman_bool_t pixman_f_transform_bounds (const struct pixman_f_transform *t, 277 | struct pixman_box16 *b); 278 | void pixman_f_transform_init_identity (struct pixman_f_transform *t); 279 | 280 | typedef enum 281 | { 282 | PIXMAN_REPEAT_NONE, 283 | PIXMAN_REPEAT_NORMAL, 284 | PIXMAN_REPEAT_PAD, 285 | PIXMAN_REPEAT_REFLECT 286 | } pixman_repeat_t; 287 | 288 | typedef enum 289 | { 290 | PIXMAN_FILTER_FAST, 291 | PIXMAN_FILTER_GOOD, 292 | PIXMAN_FILTER_BEST, 293 | PIXMAN_FILTER_NEAREST, 294 | PIXMAN_FILTER_BILINEAR, 295 | PIXMAN_FILTER_CONVOLUTION, 296 | 297 | /* The SEPARABLE_CONVOLUTION filter takes the following parameters: 298 | * 299 | * width: integer given as 16.16 fixpoint number 300 | * height: integer given as 16.16 fixpoint number 301 | * x_phase_bits: integer given as 16.16 fixpoint 302 | * y_phase_bits: integer given as 16.16 fixpoint 303 | * xtables: (1 << x_phase_bits) tables of size width 304 | * ytables: (1 << y_phase_bits) tables of size height 305 | * 306 | * When sampling at (x, y), the location is first rounded to one of 307 | * n_x_phases * n_y_phases subpixel positions. These subpixel positions 308 | * determine an xtable and a ytable to use. 309 | * 310 | * Conceptually a width x height matrix is then formed in which each entry 311 | * is the product of the corresponding entries in the x and y tables. 312 | * This matrix is then aligned with the image pixels such that its center 313 | * is as close as possible to the subpixel location chosen earlier. Then 314 | * the image is convolved with the matrix and the resulting pixel returned. 315 | */ 316 | PIXMAN_FILTER_SEPARABLE_CONVOLUTION 317 | } pixman_filter_t; 318 | 319 | typedef enum 320 | { 321 | PIXMAN_OP_CLEAR = 0x00, 322 | PIXMAN_OP_SRC = 0x01, 323 | PIXMAN_OP_DST = 0x02, 324 | PIXMAN_OP_OVER = 0x03, 325 | PIXMAN_OP_OVER_REVERSE = 0x04, 326 | PIXMAN_OP_IN = 0x05, 327 | PIXMAN_OP_IN_REVERSE = 0x06, 328 | PIXMAN_OP_OUT = 0x07, 329 | PIXMAN_OP_OUT_REVERSE = 0x08, 330 | PIXMAN_OP_ATOP = 0x09, 331 | PIXMAN_OP_ATOP_REVERSE = 0x0a, 332 | PIXMAN_OP_XOR = 0x0b, 333 | PIXMAN_OP_ADD = 0x0c, 334 | PIXMAN_OP_SATURATE = 0x0d, 335 | 336 | PIXMAN_OP_DISJOINT_CLEAR = 0x10, 337 | PIXMAN_OP_DISJOINT_SRC = 0x11, 338 | PIXMAN_OP_DISJOINT_DST = 0x12, 339 | PIXMAN_OP_DISJOINT_OVER = 0x13, 340 | PIXMAN_OP_DISJOINT_OVER_REVERSE = 0x14, 341 | PIXMAN_OP_DISJOINT_IN = 0x15, 342 | PIXMAN_OP_DISJOINT_IN_REVERSE = 0x16, 343 | PIXMAN_OP_DISJOINT_OUT = 0x17, 344 | PIXMAN_OP_DISJOINT_OUT_REVERSE = 0x18, 345 | PIXMAN_OP_DISJOINT_ATOP = 0x19, 346 | PIXMAN_OP_DISJOINT_ATOP_REVERSE = 0x1a, 347 | PIXMAN_OP_DISJOINT_XOR = 0x1b, 348 | 349 | PIXMAN_OP_CONJOINT_CLEAR = 0x20, 350 | PIXMAN_OP_CONJOINT_SRC = 0x21, 351 | PIXMAN_OP_CONJOINT_DST = 0x22, 352 | PIXMAN_OP_CONJOINT_OVER = 0x23, 353 | PIXMAN_OP_CONJOINT_OVER_REVERSE = 0x24, 354 | PIXMAN_OP_CONJOINT_IN = 0x25, 355 | PIXMAN_OP_CONJOINT_IN_REVERSE = 0x26, 356 | PIXMAN_OP_CONJOINT_OUT = 0x27, 357 | PIXMAN_OP_CONJOINT_OUT_REVERSE = 0x28, 358 | PIXMAN_OP_CONJOINT_ATOP = 0x29, 359 | PIXMAN_OP_CONJOINT_ATOP_REVERSE = 0x2a, 360 | PIXMAN_OP_CONJOINT_XOR = 0x2b, 361 | 362 | PIXMAN_OP_MULTIPLY = 0x30, 363 | PIXMAN_OP_SCREEN = 0x31, 364 | PIXMAN_OP_OVERLAY = 0x32, 365 | PIXMAN_OP_DARKEN = 0x33, 366 | PIXMAN_OP_LIGHTEN = 0x34, 367 | PIXMAN_OP_COLOR_DODGE = 0x35, 368 | PIXMAN_OP_COLOR_BURN = 0x36, 369 | PIXMAN_OP_HARD_LIGHT = 0x37, 370 | PIXMAN_OP_SOFT_LIGHT = 0x38, 371 | PIXMAN_OP_DIFFERENCE = 0x39, 372 | PIXMAN_OP_EXCLUSION = 0x3a, 373 | PIXMAN_OP_HSL_HUE = 0x3b, 374 | PIXMAN_OP_HSL_SATURATION = 0x3c, 375 | PIXMAN_OP_HSL_COLOR = 0x3d, 376 | PIXMAN_OP_HSL_LUMINOSITY = 0x3e 377 | 378 | #ifdef PIXMAN_USE_INTERNAL_API 379 | , 380 | PIXMAN_N_OPERATORS, 381 | PIXMAN_OP_NONE = PIXMAN_N_OPERATORS 382 | #endif 383 | } pixman_op_t; 384 | 385 | /* 386 | * Regions 387 | */ 388 | typedef struct pixman_region16_data pixman_region16_data_t; 389 | typedef struct pixman_box16 pixman_box16_t; 390 | typedef struct pixman_rectangle16 pixman_rectangle16_t; 391 | typedef struct pixman_region16 pixman_region16_t; 392 | 393 | struct pixman_region16_data { 394 | long size; 395 | long numRects; 396 | /* pixman_box16_t rects[size]; in memory but not explicitly declared */ 397 | }; 398 | 399 | struct pixman_rectangle16 400 | { 401 | int16_t x, y; 402 | uint16_t width, height; 403 | }; 404 | 405 | struct pixman_box16 406 | { 407 | int16_t x1, y1, x2, y2; 408 | }; 409 | 410 | struct pixman_region16 411 | { 412 | pixman_box16_t extents; 413 | pixman_region16_data_t *data; 414 | }; 415 | 416 | typedef enum 417 | { 418 | PIXMAN_REGION_OUT, 419 | PIXMAN_REGION_IN, 420 | PIXMAN_REGION_PART 421 | } pixman_region_overlap_t; 422 | 423 | /* This function exists only to make it possible to preserve 424 | * the X ABI - it should go away at first opportunity. 425 | */ 426 | void pixman_region_set_static_pointers (pixman_box16_t *empty_box, 427 | pixman_region16_data_t *empty_data, 428 | pixman_region16_data_t *broken_data); 429 | 430 | /* creation/destruction */ 431 | void pixman_region_init (pixman_region16_t *region); 432 | void pixman_region_init_rect (pixman_region16_t *region, 433 | int x, 434 | int y, 435 | unsigned int width, 436 | unsigned int height); 437 | pixman_bool_t pixman_region_init_rects (pixman_region16_t *region, 438 | const pixman_box16_t *boxes, 439 | int count); 440 | void pixman_region_init_with_extents (pixman_region16_t *region, 441 | pixman_box16_t *extents); 442 | void pixman_region_init_from_image (pixman_region16_t *region, 443 | pixman_image_t *image); 444 | void pixman_region_fini (pixman_region16_t *region); 445 | 446 | 447 | /* manipulation */ 448 | void pixman_region_translate (pixman_region16_t *region, 449 | int x, 450 | int y); 451 | pixman_bool_t pixman_region_copy (pixman_region16_t *dest, 452 | pixman_region16_t *source); 453 | pixman_bool_t pixman_region_intersect (pixman_region16_t *new_reg, 454 | pixman_region16_t *reg1, 455 | pixman_region16_t *reg2); 456 | pixman_bool_t pixman_region_union (pixman_region16_t *new_reg, 457 | pixman_region16_t *reg1, 458 | pixman_region16_t *reg2); 459 | pixman_bool_t pixman_region_union_rect (pixman_region16_t *dest, 460 | pixman_region16_t *source, 461 | int x, 462 | int y, 463 | unsigned int width, 464 | unsigned int height); 465 | pixman_bool_t pixman_region_intersect_rect (pixman_region16_t *dest, 466 | pixman_region16_t *source, 467 | int x, 468 | int y, 469 | unsigned int width, 470 | unsigned int height); 471 | pixman_bool_t pixman_region_subtract (pixman_region16_t *reg_d, 472 | pixman_region16_t *reg_m, 473 | pixman_region16_t *reg_s); 474 | pixman_bool_t pixman_region_inverse (pixman_region16_t *new_reg, 475 | pixman_region16_t *reg1, 476 | pixman_box16_t *inv_rect); 477 | pixman_bool_t pixman_region_contains_point (pixman_region16_t *region, 478 | int x, 479 | int y, 480 | pixman_box16_t *box); 481 | pixman_region_overlap_t pixman_region_contains_rectangle (pixman_region16_t *region, 482 | pixman_box16_t *prect); 483 | pixman_bool_t pixman_region_not_empty (pixman_region16_t *region); 484 | pixman_box16_t * pixman_region_extents (pixman_region16_t *region); 485 | int pixman_region_n_rects (pixman_region16_t *region); 486 | pixman_box16_t * pixman_region_rectangles (pixman_region16_t *region, 487 | int *n_rects); 488 | pixman_bool_t pixman_region_equal (pixman_region16_t *region1, 489 | pixman_region16_t *region2); 490 | pixman_bool_t pixman_region_selfcheck (pixman_region16_t *region); 491 | void pixman_region_reset (pixman_region16_t *region, 492 | pixman_box16_t *box); 493 | void pixman_region_clear (pixman_region16_t *region); 494 | /* 495 | * 32 bit regions 496 | */ 497 | typedef struct pixman_region32_data pixman_region32_data_t; 498 | typedef struct pixman_box32 pixman_box32_t; 499 | typedef struct pixman_rectangle32 pixman_rectangle32_t; 500 | typedef struct pixman_region32 pixman_region32_t; 501 | 502 | struct pixman_region32_data { 503 | long size; 504 | long numRects; 505 | /* pixman_box32_t rects[size]; in memory but not explicitly declared */ 506 | }; 507 | 508 | struct pixman_rectangle32 509 | { 510 | int32_t x, y; 511 | uint32_t width, height; 512 | }; 513 | 514 | struct pixman_box32 515 | { 516 | int32_t x1, y1, x2, y2; 517 | }; 518 | 519 | struct pixman_region32 520 | { 521 | pixman_box32_t extents; 522 | pixman_region32_data_t *data; 523 | }; 524 | 525 | /* creation/destruction */ 526 | void pixman_region32_init (pixman_region32_t *region); 527 | void pixman_region32_init_rect (pixman_region32_t *region, 528 | int x, 529 | int y, 530 | unsigned int width, 531 | unsigned int height); 532 | pixman_bool_t pixman_region32_init_rects (pixman_region32_t *region, 533 | const pixman_box32_t *boxes, 534 | int count); 535 | void pixman_region32_init_with_extents (pixman_region32_t *region, 536 | pixman_box32_t *extents); 537 | void pixman_region32_init_from_image (pixman_region32_t *region, 538 | pixman_image_t *image); 539 | void pixman_region32_fini (pixman_region32_t *region); 540 | 541 | 542 | /* manipulation */ 543 | void pixman_region32_translate (pixman_region32_t *region, 544 | int x, 545 | int y); 546 | pixman_bool_t pixman_region32_copy (pixman_region32_t *dest, 547 | pixman_region32_t *source); 548 | pixman_bool_t pixman_region32_intersect (pixman_region32_t *new_reg, 549 | pixman_region32_t *reg1, 550 | pixman_region32_t *reg2); 551 | pixman_bool_t pixman_region32_union (pixman_region32_t *new_reg, 552 | pixman_region32_t *reg1, 553 | pixman_region32_t *reg2); 554 | pixman_bool_t pixman_region32_intersect_rect (pixman_region32_t *dest, 555 | pixman_region32_t *source, 556 | int x, 557 | int y, 558 | unsigned int width, 559 | unsigned int height); 560 | pixman_bool_t pixman_region32_union_rect (pixman_region32_t *dest, 561 | pixman_region32_t *source, 562 | int x, 563 | int y, 564 | unsigned int width, 565 | unsigned int height); 566 | pixman_bool_t pixman_region32_subtract (pixman_region32_t *reg_d, 567 | pixman_region32_t *reg_m, 568 | pixman_region32_t *reg_s); 569 | pixman_bool_t pixman_region32_inverse (pixman_region32_t *new_reg, 570 | pixman_region32_t *reg1, 571 | pixman_box32_t *inv_rect); 572 | pixman_bool_t pixman_region32_contains_point (pixman_region32_t *region, 573 | int x, 574 | int y, 575 | pixman_box32_t *box); 576 | pixman_region_overlap_t pixman_region32_contains_rectangle (pixman_region32_t *region, 577 | pixman_box32_t *prect); 578 | pixman_bool_t pixman_region32_not_empty (pixman_region32_t *region); 579 | pixman_box32_t * pixman_region32_extents (pixman_region32_t *region); 580 | int pixman_region32_n_rects (pixman_region32_t *region); 581 | pixman_box32_t * pixman_region32_rectangles (pixman_region32_t *region, 582 | int *n_rects); 583 | pixman_bool_t pixman_region32_equal (pixman_region32_t *region1, 584 | pixman_region32_t *region2); 585 | pixman_bool_t pixman_region32_selfcheck (pixman_region32_t *region); 586 | void pixman_region32_reset (pixman_region32_t *region, 587 | pixman_box32_t *box); 588 | void pixman_region32_clear (pixman_region32_t *region); 589 | 590 | 591 | /* Copy / Fill / Misc */ 592 | pixman_bool_t pixman_blt (uint32_t *src_bits, 593 | uint32_t *dst_bits, 594 | int src_stride, 595 | int dst_stride, 596 | int src_bpp, 597 | int dst_bpp, 598 | int src_x, 599 | int src_y, 600 | int dest_x, 601 | int dest_y, 602 | int width, 603 | int height); 604 | pixman_bool_t pixman_fill (uint32_t *bits, 605 | int stride, 606 | int bpp, 607 | int x, 608 | int y, 609 | int width, 610 | int height, 611 | uint32_t _xor); 612 | 613 | int pixman_version (void); 614 | const char* pixman_version_string (void); 615 | 616 | /* 617 | * Images 618 | */ 619 | typedef struct pixman_indexed pixman_indexed_t; 620 | typedef struct pixman_gradient_stop pixman_gradient_stop_t; 621 | 622 | typedef uint32_t (* pixman_read_memory_func_t) (const void *src, int size); 623 | typedef void (* pixman_write_memory_func_t) (void *dst, uint32_t value, int size); 624 | 625 | typedef void (* pixman_image_destroy_func_t) (pixman_image_t *image, void *data); 626 | 627 | struct pixman_gradient_stop { 628 | pixman_fixed_t x; 629 | pixman_color_t color; 630 | }; 631 | 632 | #define PIXMAN_MAX_INDEXED 256 /* XXX depth must be <= 8 */ 633 | 634 | #if PIXMAN_MAX_INDEXED <= 256 635 | typedef uint8_t pixman_index_type; 636 | #endif 637 | 638 | struct pixman_indexed 639 | { 640 | pixman_bool_t color; 641 | uint32_t rgba[PIXMAN_MAX_INDEXED]; 642 | pixman_index_type ent[32768]; 643 | }; 644 | 645 | /* 646 | * While the protocol is generous in format support, the 647 | * sample implementation allows only packed RGB and GBR 648 | * representations for data to simplify software rendering, 649 | */ 650 | #define PIXMAN_FORMAT(bpp,type,a,r,g,b) (((bpp) << 24) | \ 651 | ((type) << 16) | \ 652 | ((a) << 12) | \ 653 | ((r) << 8) | \ 654 | ((g) << 4) | \ 655 | ((b))) 656 | 657 | #define PIXMAN_FORMAT_BPP(f) (((f) >> 24) ) 658 | #define PIXMAN_FORMAT_TYPE(f) (((f) >> 16) & 0xff) 659 | #define PIXMAN_FORMAT_A(f) (((f) >> 12) & 0x0f) 660 | #define PIXMAN_FORMAT_R(f) (((f) >> 8) & 0x0f) 661 | #define PIXMAN_FORMAT_G(f) (((f) >> 4) & 0x0f) 662 | #define PIXMAN_FORMAT_B(f) (((f) ) & 0x0f) 663 | #define PIXMAN_FORMAT_RGB(f) (((f) ) & 0xfff) 664 | #define PIXMAN_FORMAT_VIS(f) (((f) ) & 0xffff) 665 | #define PIXMAN_FORMAT_DEPTH(f) (PIXMAN_FORMAT_A(f) + \ 666 | PIXMAN_FORMAT_R(f) + \ 667 | PIXMAN_FORMAT_G(f) + \ 668 | PIXMAN_FORMAT_B(f)) 669 | 670 | #define PIXMAN_TYPE_OTHER 0 671 | #define PIXMAN_TYPE_A 1 672 | #define PIXMAN_TYPE_ARGB 2 673 | #define PIXMAN_TYPE_ABGR 3 674 | #define PIXMAN_TYPE_COLOR 4 675 | #define PIXMAN_TYPE_GRAY 5 676 | #define PIXMAN_TYPE_YUY2 6 677 | #define PIXMAN_TYPE_YV12 7 678 | #define PIXMAN_TYPE_BGRA 8 679 | #define PIXMAN_TYPE_RGBA 9 680 | #define PIXMAN_TYPE_ARGB_SRGB 10 681 | 682 | #define PIXMAN_FORMAT_COLOR(f) \ 683 | (PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ARGB || \ 684 | PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ABGR || \ 685 | PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_BGRA || \ 686 | PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_RGBA) 687 | 688 | /* 32bpp formats */ 689 | typedef enum { 690 | PIXMAN_a8r8g8b8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,8,8,8,8), 691 | PIXMAN_x8r8g8b8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,0,8,8,8), 692 | PIXMAN_a8b8g8r8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,8,8,8,8), 693 | PIXMAN_x8b8g8r8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,0,8,8,8), 694 | PIXMAN_b8g8r8a8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_BGRA,8,8,8,8), 695 | PIXMAN_b8g8r8x8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_BGRA,0,8,8,8), 696 | PIXMAN_r8g8b8a8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_RGBA,8,8,8,8), 697 | PIXMAN_r8g8b8x8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_RGBA,0,8,8,8), 698 | PIXMAN_x14r6g6b6 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,0,6,6,6), 699 | PIXMAN_x2r10g10b10 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,0,10,10,10), 700 | PIXMAN_a2r10g10b10 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,2,10,10,10), 701 | PIXMAN_x2b10g10r10 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,0,10,10,10), 702 | PIXMAN_a2b10g10r10 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,2,10,10,10), 703 | 704 | /* sRGB formats */ 705 | PIXMAN_a8r8g8b8_sRGB = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB_SRGB,8,8,8,8), 706 | 707 | /* 24bpp formats */ 708 | PIXMAN_r8g8b8 = PIXMAN_FORMAT(24,PIXMAN_TYPE_ARGB,0,8,8,8), 709 | PIXMAN_b8g8r8 = PIXMAN_FORMAT(24,PIXMAN_TYPE_ABGR,0,8,8,8), 710 | 711 | /* 16bpp formats */ 712 | PIXMAN_r5g6b5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,0,5,6,5), 713 | PIXMAN_b5g6r5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,0,5,6,5), 714 | 715 | PIXMAN_a1r5g5b5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,1,5,5,5), 716 | PIXMAN_x1r5g5b5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,0,5,5,5), 717 | PIXMAN_a1b5g5r5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,1,5,5,5), 718 | PIXMAN_x1b5g5r5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,0,5,5,5), 719 | PIXMAN_a4r4g4b4 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,4,4,4,4), 720 | PIXMAN_x4r4g4b4 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,0,4,4,4), 721 | PIXMAN_a4b4g4r4 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,4,4,4,4), 722 | PIXMAN_x4b4g4r4 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,0,4,4,4), 723 | 724 | /* 8bpp formats */ 725 | PIXMAN_a8 = PIXMAN_FORMAT(8,PIXMAN_TYPE_A,8,0,0,0), 726 | PIXMAN_r3g3b2 = PIXMAN_FORMAT(8,PIXMAN_TYPE_ARGB,0,3,3,2), 727 | PIXMAN_b2g3r3 = PIXMAN_FORMAT(8,PIXMAN_TYPE_ABGR,0,3,3,2), 728 | PIXMAN_a2r2g2b2 = PIXMAN_FORMAT(8,PIXMAN_TYPE_ARGB,2,2,2,2), 729 | PIXMAN_a2b2g2r2 = PIXMAN_FORMAT(8,PIXMAN_TYPE_ABGR,2,2,2,2), 730 | 731 | PIXMAN_c8 = PIXMAN_FORMAT(8,PIXMAN_TYPE_COLOR,0,0,0,0), 732 | PIXMAN_g8 = PIXMAN_FORMAT(8,PIXMAN_TYPE_GRAY,0,0,0,0), 733 | 734 | PIXMAN_x4a4 = PIXMAN_FORMAT(8,PIXMAN_TYPE_A,4,0,0,0), 735 | 736 | PIXMAN_x4c4 = PIXMAN_FORMAT(8,PIXMAN_TYPE_COLOR,0,0,0,0), 737 | PIXMAN_x4g4 = PIXMAN_FORMAT(8,PIXMAN_TYPE_GRAY,0,0,0,0), 738 | 739 | /* 4bpp formats */ 740 | PIXMAN_a4 = PIXMAN_FORMAT(4,PIXMAN_TYPE_A,4,0,0,0), 741 | PIXMAN_r1g2b1 = PIXMAN_FORMAT(4,PIXMAN_TYPE_ARGB,0,1,2,1), 742 | PIXMAN_b1g2r1 = PIXMAN_FORMAT(4,PIXMAN_TYPE_ABGR,0,1,2,1), 743 | PIXMAN_a1r1g1b1 = PIXMAN_FORMAT(4,PIXMAN_TYPE_ARGB,1,1,1,1), 744 | PIXMAN_a1b1g1r1 = PIXMAN_FORMAT(4,PIXMAN_TYPE_ABGR,1,1,1,1), 745 | 746 | PIXMAN_c4 = PIXMAN_FORMAT(4,PIXMAN_TYPE_COLOR,0,0,0,0), 747 | PIXMAN_g4 = PIXMAN_FORMAT(4,PIXMAN_TYPE_GRAY,0,0,0,0), 748 | 749 | /* 1bpp formats */ 750 | PIXMAN_a1 = PIXMAN_FORMAT(1,PIXMAN_TYPE_A,1,0,0,0), 751 | 752 | PIXMAN_g1 = PIXMAN_FORMAT(1,PIXMAN_TYPE_GRAY,0,0,0,0), 753 | 754 | /* YUV formats */ 755 | PIXMAN_yuy2 = PIXMAN_FORMAT(16,PIXMAN_TYPE_YUY2,0,0,0,0), 756 | PIXMAN_yv12 = PIXMAN_FORMAT(12,PIXMAN_TYPE_YV12,0,0,0,0) 757 | } pixman_format_code_t; 758 | 759 | /* Querying supported format values. */ 760 | pixman_bool_t pixman_format_supported_destination (pixman_format_code_t format); 761 | pixman_bool_t pixman_format_supported_source (pixman_format_code_t format); 762 | 763 | /* Constructors */ 764 | pixman_image_t *pixman_image_create_solid_fill (const pixman_color_t *color); 765 | pixman_image_t *pixman_image_create_linear_gradient (const pixman_point_fixed_t *p1, 766 | const pixman_point_fixed_t *p2, 767 | const pixman_gradient_stop_t *stops, 768 | int n_stops); 769 | pixman_image_t *pixman_image_create_radial_gradient (const pixman_point_fixed_t *inner, 770 | const pixman_point_fixed_t *outer, 771 | pixman_fixed_t inner_radius, 772 | pixman_fixed_t outer_radius, 773 | const pixman_gradient_stop_t *stops, 774 | int n_stops); 775 | pixman_image_t *pixman_image_create_conical_gradient (const pixman_point_fixed_t *center, 776 | pixman_fixed_t angle, 777 | const pixman_gradient_stop_t *stops, 778 | int n_stops); 779 | pixman_image_t *pixman_image_create_bits (pixman_format_code_t format, 780 | int width, 781 | int height, 782 | uint32_t *bits, 783 | int rowstride_bytes); 784 | pixman_image_t *pixman_image_create_bits_no_clear (pixman_format_code_t format, 785 | int width, 786 | int height, 787 | uint32_t * bits, 788 | int rowstride_bytes); 789 | 790 | /* Destructor */ 791 | pixman_image_t *pixman_image_ref (pixman_image_t *image); 792 | pixman_bool_t pixman_image_unref (pixman_image_t *image); 793 | 794 | void pixman_image_set_destroy_function (pixman_image_t *image, 795 | pixman_image_destroy_func_t function, 796 | void *data); 797 | void * pixman_image_get_destroy_data (pixman_image_t *image); 798 | 799 | /* Set properties */ 800 | pixman_bool_t pixman_image_set_clip_region (pixman_image_t *image, 801 | pixman_region16_t *region); 802 | pixman_bool_t pixman_image_set_clip_region32 (pixman_image_t *image, 803 | pixman_region32_t *region); 804 | void pixman_image_set_has_client_clip (pixman_image_t *image, 805 | pixman_bool_t clien_clip); 806 | pixman_bool_t pixman_image_set_transform (pixman_image_t *image, 807 | const pixman_transform_t *transform); 808 | void pixman_image_set_repeat (pixman_image_t *image, 809 | pixman_repeat_t repeat); 810 | pixman_bool_t pixman_image_set_filter (pixman_image_t *image, 811 | pixman_filter_t filter, 812 | const pixman_fixed_t *filter_params, 813 | int n_filter_params); 814 | void pixman_image_set_source_clipping (pixman_image_t *image, 815 | pixman_bool_t source_clipping); 816 | void pixman_image_set_alpha_map (pixman_image_t *image, 817 | pixman_image_t *alpha_map, 818 | int16_t x, 819 | int16_t y); 820 | void pixman_image_set_component_alpha (pixman_image_t *image, 821 | pixman_bool_t component_alpha); 822 | pixman_bool_t pixman_image_get_component_alpha (pixman_image_t *image); 823 | void pixman_image_set_accessors (pixman_image_t *image, 824 | pixman_read_memory_func_t read_func, 825 | pixman_write_memory_func_t write_func); 826 | void pixman_image_set_indexed (pixman_image_t *image, 827 | const pixman_indexed_t *indexed); 828 | uint32_t *pixman_image_get_data (pixman_image_t *image); 829 | int pixman_image_get_width (pixman_image_t *image); 830 | int pixman_image_get_height (pixman_image_t *image); 831 | int pixman_image_get_stride (pixman_image_t *image); /* in bytes */ 832 | int pixman_image_get_depth (pixman_image_t *image); 833 | pixman_format_code_t pixman_image_get_format (pixman_image_t *image); 834 | 835 | typedef enum 836 | { 837 | PIXMAN_KERNEL_IMPULSE, 838 | PIXMAN_KERNEL_BOX, 839 | PIXMAN_KERNEL_LINEAR, 840 | PIXMAN_KERNEL_CUBIC, 841 | PIXMAN_KERNEL_GAUSSIAN, 842 | PIXMAN_KERNEL_LANCZOS2, 843 | PIXMAN_KERNEL_LANCZOS3, 844 | PIXMAN_KERNEL_LANCZOS3_STRETCHED /* Jim Blinn's 'nice' filter */ 845 | } pixman_kernel_t; 846 | 847 | /* Create the parameter list for a SEPARABLE_CONVOLUTION filter 848 | * with the given kernels and scale parameters. 849 | */ 850 | pixman_fixed_t * 851 | pixman_filter_create_separable_convolution (int *n_values, 852 | pixman_fixed_t scale_x, 853 | pixman_fixed_t scale_y, 854 | pixman_kernel_t reconstruct_x, 855 | pixman_kernel_t reconstruct_y, 856 | pixman_kernel_t sample_x, 857 | pixman_kernel_t sample_y, 858 | int subsample_bits_x, 859 | int subsample_bits_y); 860 | 861 | pixman_bool_t pixman_image_fill_rectangles (pixman_op_t op, 862 | pixman_image_t *image, 863 | const pixman_color_t *color, 864 | int n_rects, 865 | const pixman_rectangle16_t *rects); 866 | pixman_bool_t pixman_image_fill_boxes (pixman_op_t op, 867 | pixman_image_t *dest, 868 | const pixman_color_t *color, 869 | int n_boxes, 870 | const pixman_box32_t *boxes); 871 | 872 | /* Composite */ 873 | pixman_bool_t pixman_compute_composite_region (pixman_region16_t *region, 874 | pixman_image_t *src_image, 875 | pixman_image_t *mask_image, 876 | pixman_image_t *dest_image, 877 | int16_t src_x, 878 | int16_t src_y, 879 | int16_t mask_x, 880 | int16_t mask_y, 881 | int16_t dest_x, 882 | int16_t dest_y, 883 | uint16_t width, 884 | uint16_t height); 885 | void pixman_image_composite (pixman_op_t op, 886 | pixman_image_t *src, 887 | pixman_image_t *mask, 888 | pixman_image_t *dest, 889 | int16_t src_x, 890 | int16_t src_y, 891 | int16_t mask_x, 892 | int16_t mask_y, 893 | int16_t dest_x, 894 | int16_t dest_y, 895 | uint16_t width, 896 | uint16_t height); 897 | void pixman_image_composite32 (pixman_op_t op, 898 | pixman_image_t *src, 899 | pixman_image_t *mask, 900 | pixman_image_t *dest, 901 | int32_t src_x, 902 | int32_t src_y, 903 | int32_t mask_x, 904 | int32_t mask_y, 905 | int32_t dest_x, 906 | int32_t dest_y, 907 | int32_t width, 908 | int32_t height); 909 | 910 | /* Executive Summary: This function is a no-op that only exists 911 | * for historical reasons. 912 | * 913 | * There used to be a bug in the X server where it would rely on 914 | * out-of-bounds accesses when it was asked to composite with a 915 | * window as the source. It would create a pixman image pointing 916 | * to some bogus position in memory, but then set a clip region 917 | * to the position where the actual bits were. 918 | * 919 | * Due to a bug in old versions of pixman, where it would not clip 920 | * against the image bounds when a clip region was set, this would 921 | * actually work. So when the pixman bug was fixed, a workaround was 922 | * added to allow certain out-of-bound accesses. This function disabled 923 | * those workarounds. 924 | * 925 | * Since 0.21.2, pixman doesn't do these workarounds anymore, so now this 926 | * function is a no-op. 927 | */ 928 | void pixman_disable_out_of_bounds_workaround (void); 929 | 930 | /* 931 | * Glyphs 932 | */ 933 | typedef struct pixman_glyph_cache_t pixman_glyph_cache_t; 934 | typedef struct 935 | { 936 | int x, y; 937 | const void *glyph; 938 | } pixman_glyph_t; 939 | 940 | pixman_glyph_cache_t *pixman_glyph_cache_create (void); 941 | void pixman_glyph_cache_destroy (pixman_glyph_cache_t *cache); 942 | void pixman_glyph_cache_freeze (pixman_glyph_cache_t *cache); 943 | void pixman_glyph_cache_thaw (pixman_glyph_cache_t *cache); 944 | const void * pixman_glyph_cache_lookup (pixman_glyph_cache_t *cache, 945 | void *font_key, 946 | void *glyph_key); 947 | const void * pixman_glyph_cache_insert (pixman_glyph_cache_t *cache, 948 | void *font_key, 949 | void *glyph_key, 950 | int origin_x, 951 | int origin_y, 952 | pixman_image_t *glyph_image); 953 | void pixman_glyph_cache_remove (pixman_glyph_cache_t *cache, 954 | void *font_key, 955 | void *glyph_key); 956 | void pixman_glyph_get_extents (pixman_glyph_cache_t *cache, 957 | int n_glyphs, 958 | pixman_glyph_t *glyphs, 959 | pixman_box32_t *extents); 960 | pixman_format_code_t pixman_glyph_get_mask_format (pixman_glyph_cache_t *cache, 961 | int n_glyphs, 962 | const pixman_glyph_t *glyphs); 963 | void pixman_composite_glyphs (pixman_op_t op, 964 | pixman_image_t *src, 965 | pixman_image_t *dest, 966 | pixman_format_code_t mask_format, 967 | int32_t src_x, 968 | int32_t src_y, 969 | int32_t mask_x, 970 | int32_t mask_y, 971 | int32_t dest_x, 972 | int32_t dest_y, 973 | int32_t width, 974 | int32_t height, 975 | pixman_glyph_cache_t *cache, 976 | int n_glyphs, 977 | const pixman_glyph_t *glyphs); 978 | void pixman_composite_glyphs_no_mask (pixman_op_t op, 979 | pixman_image_t *src, 980 | pixman_image_t *dest, 981 | int32_t src_x, 982 | int32_t src_y, 983 | int32_t dest_x, 984 | int32_t dest_y, 985 | pixman_glyph_cache_t *cache, 986 | int n_glyphs, 987 | const pixman_glyph_t *glyphs); 988 | 989 | /* 990 | * Trapezoids 991 | */ 992 | typedef struct pixman_edge pixman_edge_t; 993 | typedef struct pixman_trapezoid pixman_trapezoid_t; 994 | typedef struct pixman_trap pixman_trap_t; 995 | typedef struct pixman_span_fix pixman_span_fix_t; 996 | typedef struct pixman_triangle pixman_triangle_t; 997 | 998 | /* 999 | * An edge structure. This represents a single polygon edge 1000 | * and can be quickly stepped across small or large gaps in the 1001 | * sample grid 1002 | */ 1003 | struct pixman_edge 1004 | { 1005 | pixman_fixed_t x; 1006 | pixman_fixed_t e; 1007 | pixman_fixed_t stepx; 1008 | pixman_fixed_t signdx; 1009 | pixman_fixed_t dy; 1010 | pixman_fixed_t dx; 1011 | 1012 | pixman_fixed_t stepx_small; 1013 | pixman_fixed_t stepx_big; 1014 | pixman_fixed_t dx_small; 1015 | pixman_fixed_t dx_big; 1016 | }; 1017 | 1018 | struct pixman_trapezoid 1019 | { 1020 | pixman_fixed_t top, bottom; 1021 | pixman_line_fixed_t left, right; 1022 | }; 1023 | 1024 | struct pixman_triangle 1025 | { 1026 | pixman_point_fixed_t p1, p2, p3; 1027 | }; 1028 | 1029 | /* whether 't' is a well defined not obviously empty trapezoid */ 1030 | #define pixman_trapezoid_valid(t) \ 1031 | ((t)->left.p1.y != (t)->left.p2.y && \ 1032 | (t)->right.p1.y != (t)->right.p2.y && \ 1033 | ((t)->bottom > (t)->top)) 1034 | 1035 | struct pixman_span_fix 1036 | { 1037 | pixman_fixed_t l, r, y; 1038 | }; 1039 | 1040 | struct pixman_trap 1041 | { 1042 | pixman_span_fix_t top, bot; 1043 | }; 1044 | 1045 | pixman_fixed_t pixman_sample_ceil_y (pixman_fixed_t y, 1046 | int bpp); 1047 | pixman_fixed_t pixman_sample_floor_y (pixman_fixed_t y, 1048 | int bpp); 1049 | void pixman_edge_step (pixman_edge_t *e, 1050 | int n); 1051 | void pixman_edge_init (pixman_edge_t *e, 1052 | int bpp, 1053 | pixman_fixed_t y_start, 1054 | pixman_fixed_t x_top, 1055 | pixman_fixed_t y_top, 1056 | pixman_fixed_t x_bot, 1057 | pixman_fixed_t y_bot); 1058 | void pixman_line_fixed_edge_init (pixman_edge_t *e, 1059 | int bpp, 1060 | pixman_fixed_t y, 1061 | const pixman_line_fixed_t *line, 1062 | int x_off, 1063 | int y_off); 1064 | void pixman_rasterize_edges (pixman_image_t *image, 1065 | pixman_edge_t *l, 1066 | pixman_edge_t *r, 1067 | pixman_fixed_t t, 1068 | pixman_fixed_t b); 1069 | void pixman_add_traps (pixman_image_t *image, 1070 | int16_t x_off, 1071 | int16_t y_off, 1072 | int ntrap, 1073 | const pixman_trap_t *traps); 1074 | void pixman_add_trapezoids (pixman_image_t *image, 1075 | int16_t x_off, 1076 | int y_off, 1077 | int ntraps, 1078 | const pixman_trapezoid_t *traps); 1079 | void pixman_rasterize_trapezoid (pixman_image_t *image, 1080 | const pixman_trapezoid_t *trap, 1081 | int x_off, 1082 | int y_off); 1083 | void pixman_composite_trapezoids (pixman_op_t op, 1084 | pixman_image_t * src, 1085 | pixman_image_t * dst, 1086 | pixman_format_code_t mask_format, 1087 | int x_src, 1088 | int y_src, 1089 | int x_dst, 1090 | int y_dst, 1091 | int n_traps, 1092 | const pixman_trapezoid_t * traps); 1093 | void pixman_composite_triangles (pixman_op_t op, 1094 | pixman_image_t * src, 1095 | pixman_image_t * dst, 1096 | pixman_format_code_t mask_format, 1097 | int x_src, 1098 | int y_src, 1099 | int x_dst, 1100 | int y_dst, 1101 | int n_tris, 1102 | const pixman_triangle_t * tris); 1103 | void pixman_add_triangles (pixman_image_t *image, 1104 | int32_t x_off, 1105 | int32_t y_off, 1106 | int n_tris, 1107 | const pixman_triangle_t *tris); 1108 | 1109 | PIXMAN_END_DECLS 1110 | 1111 | #endif /* PIXMAN_H__ */ 1112 | -------------------------------------------------------------------------------- /src/NvEncoder.cpp: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright 1993-2014 NVIDIA Corporation. All rights reserved. 4 | // 5 | // Please refer to the NVIDIA end user license agreement (EULA) associated 6 | // with this source code for terms and conditions that govern your use of 7 | // this software. Any use, reproduction, disclosure, or distribution of 8 | // this software and related documentation outside the terms of the EULA 9 | // is strictly prohibited. 10 | // 11 | //////////////////////////////////////////////////////////////////////////// 12 | 13 | #include "nvCPUOPSys.h" 14 | #include "nvEncodeAPI.h" 15 | #include "nvUtils.h" 16 | #include "NvEncoder.h" 17 | #include "h264_log.h" 18 | #include 19 | #include 20 | 21 | #define BITSTREAM_BUFFER_SIZE 2 * 1024 * 1024 22 | extern FILE* rgba; 23 | 24 | void convertBGRApitchtoARGB(const void* pFrameBGRA, uint8_t* pInputSurface, int width, int height, int srcStride, int dstStride) 25 | { 26 | //int y, x; 27 | //static int k = 0; 28 | //for(y=0; y>1)]; 86 | nv12_chroma[(y*dstStride) +(x+1)] = yuv_cr[((srcStride/2)*y) + (x >>1)]; 87 | } 88 | } 89 | } 90 | 91 | void convertYUV10pitchtoP010PL(unsigned short *yuv_luma, unsigned short *yuv_cb, unsigned short *yuv_cr, 92 | unsigned short *nv12_luma, unsigned short *nv12_chroma, int width, int height, int srcStride, int dstStride) 93 | { 94 | int x, y; 95 | 96 | for (y = 0; y < height; y++) 97 | { 98 | for (x = 0; x < width; x++) 99 | { 100 | nv12_luma[(y*dstStride / 2) + x] = yuv_luma[(srcStride*y) + x] << 6; 101 | } 102 | } 103 | 104 | for (y = 0; y < height / 2; y++) 105 | { 106 | for (x = 0; x < width; x = x + 2) 107 | { 108 | nv12_chroma[(y*dstStride / 2) + x] = yuv_cb[((srcStride / 2)*y) + (x >> 1)] << 6; 109 | nv12_chroma[(y*dstStride / 2) + (x + 1)] = yuv_cr[((srcStride / 2)*y) + (x >> 1)] << 6; 110 | } 111 | } 112 | } 113 | 114 | void convertYUVpitchtoYUV444(unsigned char *yuv_luma, unsigned char *yuv_cb, unsigned char *yuv_cr, 115 | unsigned char *surf_luma, unsigned char *surf_cb, unsigned char *surf_cr, int width, int height, int srcStride, int dstStride) 116 | { 117 | int h; 118 | 119 | for (h = 0; h < height; h++) 120 | { 121 | memcpy(surf_luma + dstStride * h, yuv_luma + srcStride * h, width); 122 | memcpy(surf_cb + dstStride * h, yuv_cb + srcStride * h, width); 123 | memcpy(surf_cr + dstStride * h, yuv_cr + srcStride * h, width); 124 | } 125 | } 126 | 127 | void convertYUV10pitchtoYUV444(unsigned short *yuv_luma, unsigned short *yuv_cb, unsigned short *yuv_cr, 128 | unsigned short *surf_luma, unsigned short *surf_cb, unsigned short *surf_cr, 129 | int width, int height, int srcStride, int dstStride) 130 | { 131 | int x, y; 132 | 133 | for (y = 0; y < height; y++) 134 | { 135 | for (x = 0; x < width; x++) 136 | { 137 | surf_luma[(y*dstStride / 2) + x] = yuv_luma[(srcStride*y) + x] << 6; 138 | surf_cb[(y*dstStride / 2) + x] = yuv_cb[(srcStride*y) + x] << 6; 139 | surf_cr[(y*dstStride / 2) + x] = yuv_cr[(srcStride*y) + x] << 6; 140 | } 141 | } 142 | } 143 | 144 | CNvEncoder::CNvEncoder() 145 | { 146 | m_pNvHWEncoder = new CNvHWEncoder; 147 | m_pDevice = NULL; 148 | #if defined (NV_WINDOWS) 149 | m_pD3D = NULL; 150 | #endif 151 | // m_cuContext = NULL; 152 | 153 | m_uEncodeBufferCount = 0; 154 | memset(&m_stEncoderInput, 0, sizeof(m_stEncoderInput)); 155 | memset(&m_stEOSOutputBfr, 0, sizeof(m_stEOSOutputBfr)); 156 | memset(&m_stMVBuffer, 0, sizeof(m_stMVBuffer)); 157 | //memset(&m_stEncodeBuffer, 0, sizeof(m_stEncodeBuffer)); 158 | m_stEncodeBufferPtrArr = NULL; 159 | m_stEncodeBufferPtrCnt = 0; 160 | m_currentUseId = -1; 161 | m_currentBufferType = INVALID_BUFFER_TYPE; 162 | m_numFramesEncoded = 0; 163 | } 164 | 165 | CNvEncoder::~CNvEncoder() 166 | { 167 | if (m_pNvHWEncoder) 168 | { 169 | delete m_pNvHWEncoder; 170 | m_pNvHWEncoder = NULL; 171 | } 172 | for(int i = 0; i< m_stEncodeBufferPtrCnt; i++){ 173 | if(m_stEncodeBufferPtrArr[i] != NULL) 174 | free(m_stEncodeBufferPtrArr[i]); 175 | } 176 | free(m_stEncodeBufferPtrArr); 177 | } 178 | 179 | NVENCSTATUS CNvEncoder::InitCuda(uint32_t deviceID) 180 | { 181 | CUresult cuResult; 182 | CUdevice device; 183 | CUcontext cuContextCurr; 184 | int deviceCount = 0; 185 | int SMminor = 0, SMmajor = 0; 186 | 187 | #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) 188 | typedef HMODULE CUDADRIVER; 189 | #else 190 | typedef void *CUDADRIVER; 191 | #endif 192 | CUDADRIVER hHandleDriver = 0; 193 | cuResult = cuInit(0, __CUDA_API_VERSION, hHandleDriver); 194 | if (cuResult != CUDA_SUCCESS) 195 | { 196 | NvDebugLog("cuInit error:0x%x", cuResult); 197 | return NV_ENC_ERR_NO_ENCODE_DEVICE; 198 | } 199 | 200 | cuResult = cuDeviceGetCount(&deviceCount); 201 | //printf("deviceCount : %d\n", deviceCount); 202 | if (cuResult != CUDA_SUCCESS) 203 | { 204 | NvDebugLog("cuDeviceGetCount error:0x%x", cuResult); 205 | return NV_ENC_ERR_NO_ENCODE_DEVICE; 206 | } 207 | 208 | // If dev is negative value, we clamp to 0 209 | if ((int)deviceID < 0) 210 | deviceID = 0; 211 | 212 | if (deviceID >(unsigned int)deviceCount - 1) 213 | { 214 | NvDebugLog("Invalid Device Id = %d", deviceID); 215 | return NV_ENC_ERR_INVALID_ENCODERDEVICE; 216 | } 217 | 218 | cuResult = cuDeviceGet(&device, deviceID); 219 | if (cuResult != CUDA_SUCCESS) 220 | { 221 | NvDebugLog("cuDeviceGet error:0x%x", cuResult); 222 | return NV_ENC_ERR_NO_ENCODE_DEVICE; 223 | } 224 | 225 | cuResult = cuDeviceComputeCapability(&SMmajor, &SMminor, deviceID); 226 | if (cuResult != CUDA_SUCCESS) 227 | { 228 | NvDebugLog("cuDeviceComputeCapability error:0x%x", cuResult); 229 | return NV_ENC_ERR_NO_ENCODE_DEVICE; 230 | } 231 | 232 | if (((SMmajor << 4) + SMminor) < 0x30) 233 | { 234 | NvDebugLog("GPU %d does not have NVENC capabilities exiting", deviceID); 235 | return NV_ENC_ERR_NO_ENCODE_DEVICE; 236 | } 237 | 238 | cuResult = cuCtxCreate((CUcontext*)(&m_pDevice), CU_CTX_MAP_HOST, device); 239 | if (cuResult != CUDA_SUCCESS) 240 | { 241 | NvDebugLog("cuCtxCreate error:0x%x", cuResult); 242 | return NV_ENC_ERR_NO_ENCODE_DEVICE; 243 | } 244 | 245 | cuResult = cuCtxPopCurrent(&cuContextCurr); 246 | if (cuResult != CUDA_SUCCESS) 247 | { 248 | NvDebugLog("cuCtxPopCurrent error:0x%x", cuResult); 249 | return NV_ENC_ERR_NO_ENCODE_DEVICE; 250 | } 251 | return NV_ENC_SUCCESS; 252 | } 253 | 254 | #if defined(NV_WINDOWS) 255 | NVENCSTATUS CNvEncoder::InitD3D9(uint32_t deviceID) 256 | { 257 | D3DPRESENT_PARAMETERS d3dpp; 258 | D3DADAPTER_IDENTIFIER9 adapterId; 259 | unsigned int iAdapter = NULL; // Our adapter 260 | HRESULT hr = S_OK; 261 | 262 | m_pD3D = Direct3DCreate9(D3D_SDK_VERSION); 263 | if (m_pD3D == NULL) 264 | { 265 | assert(m_pD3D); 266 | return NV_ENC_ERR_OUT_OF_MEMORY;; 267 | } 268 | 269 | if (deviceID >= m_pD3D->GetAdapterCount()) 270 | { 271 | PRINTERR("Invalid Device Id = %d\n. Please use DX10/DX11 to detect headless video devices.\n", deviceID); 272 | return NV_ENC_ERR_INVALID_ENCODERDEVICE; 273 | } 274 | 275 | hr = m_pD3D->GetAdapterIdentifier(deviceID, 0, &adapterId); 276 | if (hr != S_OK) 277 | { 278 | PRINTERR("Invalid Device Id = %d\n", deviceID); 279 | return NV_ENC_ERR_INVALID_ENCODERDEVICE; 280 | } 281 | 282 | ZeroMemory(&d3dpp, sizeof(d3dpp)); 283 | d3dpp.Windowed = TRUE; 284 | d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; 285 | d3dpp.BackBufferWidth = 640; 286 | d3dpp.BackBufferHeight = 480; 287 | d3dpp.BackBufferCount = 1; 288 | d3dpp.SwapEffect = D3DSWAPEFFECT_COPY; 289 | d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; 290 | d3dpp.Flags = D3DPRESENTFLAG_VIDEO;//D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; 291 | DWORD dwBehaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_MULTITHREADED | D3DCREATE_HARDWARE_VERTEXPROCESSING; 292 | 293 | hr = m_pD3D->CreateDevice(deviceID, 294 | D3DDEVTYPE_HAL, 295 | GetDesktopWindow(), 296 | dwBehaviorFlags, 297 | &d3dpp, 298 | (IDirect3DDevice9**)(&m_pDevice)); 299 | 300 | if (FAILED(hr)) 301 | return NV_ENC_ERR_OUT_OF_MEMORY; 302 | 303 | return NV_ENC_SUCCESS; 304 | } 305 | 306 | NVENCSTATUS CNvEncoder::InitD3D10(uint32_t deviceID) 307 | { 308 | HRESULT hr; 309 | IDXGIFactory * pFactory = NULL; 310 | IDXGIAdapter * pAdapter; 311 | 312 | if (CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory) != S_OK) 313 | { 314 | return NV_ENC_ERR_GENERIC; 315 | } 316 | 317 | if (pFactory->EnumAdapters(deviceID, &pAdapter) != DXGI_ERROR_NOT_FOUND) 318 | { 319 | hr = D3D10CreateDevice(pAdapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, 320 | D3D10_SDK_VERSION, (ID3D10Device**)(&m_pDevice)); 321 | if (FAILED(hr)) 322 | { 323 | PRINTERR("Problem while creating %d D3d10 device \n", deviceID); 324 | return NV_ENC_ERR_OUT_OF_MEMORY; 325 | } 326 | } 327 | else 328 | { 329 | PRINTERR("Invalid Device Id = %d\n", deviceID); 330 | return NV_ENC_ERR_INVALID_ENCODERDEVICE; 331 | } 332 | 333 | return NV_ENC_SUCCESS; 334 | } 335 | 336 | NVENCSTATUS CNvEncoder::InitD3D11(uint32_t deviceID) 337 | { 338 | HRESULT hr; 339 | IDXGIFactory * pFactory = NULL; 340 | IDXGIAdapter * pAdapter; 341 | 342 | if (CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory) != S_OK) 343 | { 344 | return NV_ENC_ERR_GENERIC; 345 | } 346 | 347 | if (pFactory->EnumAdapters(deviceID, &pAdapter) != DXGI_ERROR_NOT_FOUND) 348 | { 349 | hr = D3D11CreateDevice(pAdapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, 350 | NULL, 0, D3D11_SDK_VERSION, (ID3D11Device**)(&m_pDevice), NULL, NULL); 351 | if (FAILED(hr)) 352 | { 353 | PRINTERR("Problem while creating %d D3d11 device \n", deviceID); 354 | return NV_ENC_ERR_OUT_OF_MEMORY; 355 | } 356 | } 357 | else 358 | { 359 | PRINTERR("Invalid Device Id = %d\n", deviceID); 360 | return NV_ENC_ERR_INVALID_ENCODERDEVICE; 361 | } 362 | 363 | return NV_ENC_SUCCESS; 364 | } 365 | #endif 366 | 367 | NVENCSTATUS CNvEncoder::AllocateIOBuffers(uint32_t uInputWidth, uint32_t uInputHeight, NV_ENC_BUFFER_FORMAT inputFormat) 368 | { 369 | NVENCSTATUS nvStatus = NV_ENC_SUCCESS; 370 | 371 | m_EncodeBufferQueue.Initialize(m_stEncodeBuffer, m_uEncodeBufferCount); 372 | for (uint32_t i = 0; i < m_uEncodeBufferCount; i++) 373 | { 374 | nvStatus = m_pNvHWEncoder->NvEncCreateInputBuffer(uInputWidth, uInputHeight, &m_stEncodeBuffer[i].stInputBfr.hInputSurface, inputFormat); 375 | if (nvStatus != NV_ENC_SUCCESS) 376 | return nvStatus; 377 | 378 | m_stEncodeBuffer[i].stInputBfr.bufferFmt = inputFormat; 379 | m_stEncodeBuffer[i].stInputBfr.dwWidth = uInputWidth; 380 | m_stEncodeBuffer[i].stInputBfr.dwHeight = uInputHeight; 381 | nvStatus = m_pNvHWEncoder->NvEncCreateBitstreamBuffer(BITSTREAM_BUFFER_SIZE, &m_stEncodeBuffer[i].stOutputBfr.hBitstreamBuffer); 382 | if (nvStatus != NV_ENC_SUCCESS) 383 | return nvStatus; 384 | m_stEncodeBuffer[i].stOutputBfr.dwBitstreamBufferSize = BITSTREAM_BUFFER_SIZE; 385 | if (m_stEncoderInput.enableAsyncMode) 386 | { 387 | nvStatus = m_pNvHWEncoder->NvEncRegisterAsyncEvent(&m_stEncodeBuffer[i].stOutputBfr.hOutputEvent); 388 | if (nvStatus != NV_ENC_SUCCESS) 389 | return nvStatus; 390 | m_stEncodeBuffer[i].stOutputBfr.bWaitOnEvent = true; 391 | } 392 | else 393 | m_stEncodeBuffer[i].stOutputBfr.hOutputEvent = NULL; 394 | } 395 | 396 | m_stEOSOutputBfr.bEOSFlag = TRUE; 397 | 398 | if (m_stEncoderInput.enableAsyncMode) 399 | { 400 | nvStatus = m_pNvHWEncoder->NvEncRegisterAsyncEvent(&m_stEOSOutputBfr.hOutputEvent); 401 | if (nvStatus != NV_ENC_SUCCESS) 402 | return nvStatus; 403 | } 404 | else 405 | m_stEOSOutputBfr.hOutputEvent = NULL; 406 | 407 | return NV_ENC_SUCCESS; 408 | } 409 | 410 | NVENCSTATUS CNvEncoder::AllocateMVIOBuffers(uint32_t uInputWidth, uint32_t uInputHeight, NV_ENC_BUFFER_FORMAT inputFormat) 411 | { 412 | NVENCSTATUS nvStatus = NV_ENC_SUCCESS; 413 | 414 | m_MVBufferQueue.Initialize(m_stMVBuffer, m_uEncodeBufferCount); 415 | for (uint32_t i = 0; i < m_uEncodeBufferCount; i++) 416 | { 417 | // Allocate Input, Reference surface 418 | for (uint32_t j = 0; j < 2; j++) 419 | { 420 | nvStatus = m_pNvHWEncoder->NvEncCreateInputBuffer(uInputWidth, uInputHeight, &m_stMVBuffer[i].stInputBfr[j].hInputSurface, inputFormat); 421 | if (nvStatus != NV_ENC_SUCCESS) 422 | return nvStatus; 423 | m_stMVBuffer[i].stInputBfr[j].bufferFmt = inputFormat; 424 | m_stMVBuffer[i].stInputBfr[j].dwWidth = uInputWidth; 425 | m_stMVBuffer[i].stInputBfr[j].dwHeight = uInputHeight; 426 | } 427 | //Allocate output surface 428 | uint32_t encodeWidthInMbs = (uInputWidth + 15) >> 4; 429 | uint32_t encodeHeightInMbs = (uInputHeight + 15) >> 4; 430 | uint32_t dwSize = encodeWidthInMbs * encodeHeightInMbs * 64; 431 | nvStatus = m_pNvHWEncoder->NvEncCreateMVBuffer(dwSize, &m_stMVBuffer[i].stOutputBfr.hBitstreamBuffer); 432 | if (nvStatus != NV_ENC_SUCCESS) 433 | { 434 | PRINTERR("nvEncCreateMVBuffer error:0x%x\n", nvStatus); 435 | return nvStatus; 436 | } 437 | m_stMVBuffer[i].stOutputBfr.dwBitstreamBufferSize = dwSize; 438 | if (m_stEncoderInput.enableAsyncMode) 439 | { 440 | nvStatus = m_pNvHWEncoder->NvEncRegisterAsyncEvent(&m_stMVBuffer[i].stOutputBfr.hOutputEvent); 441 | if (nvStatus != NV_ENC_SUCCESS) 442 | return nvStatus; 443 | m_stMVBuffer[i].stOutputBfr.bWaitOnEvent = true; 444 | } 445 | else 446 | m_stMVBuffer[i].stOutputBfr.hOutputEvent = NULL; 447 | } 448 | return NV_ENC_SUCCESS; 449 | } 450 | 451 | NVENCSTATUS CNvEncoder::ReleaseIOBuffers() 452 | { 453 | for (uint32_t i = 0; i < m_uEncodeBufferCount; i++) 454 | { 455 | m_pNvHWEncoder->NvEncDestroyInputBuffer(m_stEncodeBuffer[i].stInputBfr.hInputSurface); 456 | m_stEncodeBuffer[i].stInputBfr.hInputSurface = NULL; 457 | m_pNvHWEncoder->NvEncDestroyBitstreamBuffer(m_stEncodeBuffer[i].stOutputBfr.hBitstreamBuffer); 458 | m_stEncodeBuffer[i].stOutputBfr.hBitstreamBuffer = NULL; 459 | if (m_stEncoderInput.enableAsyncMode) 460 | { 461 | m_pNvHWEncoder->NvEncUnregisterAsyncEvent(m_stEncodeBuffer[i].stOutputBfr.hOutputEvent); 462 | //nvCloseFile(m_stEncodeBuffer[i].stOutputBfr.hOutputEvent); 463 | m_stEncodeBuffer[i].stOutputBfr.hOutputEvent = NULL; 464 | } 465 | } 466 | 467 | if (m_stEOSOutputBfr.hOutputEvent) 468 | { 469 | if (m_stEncoderInput.enableAsyncMode) 470 | { 471 | m_pNvHWEncoder->NvEncUnregisterAsyncEvent(m_stEOSOutputBfr.hOutputEvent); 472 | //nvCloseFile(m_stEOSOutputBfr.hOutputEvent); 473 | m_stEOSOutputBfr.hOutputEvent = NULL; 474 | } 475 | } 476 | 477 | return NV_ENC_SUCCESS; 478 | } 479 | 480 | NVENCSTATUS CNvEncoder::ReleaseIOBuffersZC() 481 | { 482 | //NVENCSTATUS nvStatus = NV_ENC_SUCCESS; 483 | CCudaAutoLock cuLock(m_pDevice); 484 | 485 | if(m_stEncodeBufferPtrArr != NULL){ 486 | for(int i = 0; i< m_stEncodeBufferPtrCnt; i++){ 487 | if(m_stEncodeBufferPtrArr[i] != NULL){ 488 | switch(m_currentBufferType) 489 | { 490 | case NVENC_INPUT_BUFFER: 491 | __nv(m_pNvHWEncoder->NvEncDestroyInputBuffer(m_stEncodeBufferPtrArr[i]->stInputBfr.hInputSurface)); 492 | //free(m_stEncodeBufferPtrArr[i]->stInputBfr.pRGBHostPtr); 493 | break; 494 | case CUDA_DEVICE_BUFFER: 495 | break; 496 | case CUDA_HOST_BUFFER: 497 | __nv(m_pNvHWEncoder->NvEncUnregisterResource(m_stEncodeBufferPtrArr[i]->stInputBfr.nvRegisteredResource)); 498 | cuMemFreeHost(m_stEncodeBufferPtrArr[i]->stInputBfr.pRGBHostPtr); 499 | break; 500 | default: 501 | break; 502 | } 503 | 504 | __nv(m_pNvHWEncoder->NvEncDestroyBitstreamBuffer(m_stEncodeBufferPtrArr[i]->stOutputBfr.hBitstreamBuffer)); 505 | m_stEncodeBufferPtrArr[i]->stOutputBfr.hBitstreamBuffer = NULL; 506 | free(m_stEncodeBufferPtrArr[i]); 507 | m_stEncodeBufferPtrArr[i] = NULL; 508 | } 509 | } 510 | } 511 | free(m_stEncodeBufferPtrArr); 512 | return NV_ENC_SUCCESS; 513 | } 514 | 515 | NVENCSTATUS CNvEncoder::ReleaseMVIOBuffers() 516 | { 517 | for (uint32_t i = 0; i < m_uEncodeBufferCount; i++) 518 | { 519 | for (uint32_t j = 0; j < 2; j++) 520 | { 521 | m_pNvHWEncoder->NvEncDestroyInputBuffer(m_stMVBuffer[i].stInputBfr[j].hInputSurface); 522 | m_stMVBuffer[i].stInputBfr[j].hInputSurface = NULL; 523 | } 524 | m_pNvHWEncoder->NvEncDestroyMVBuffer(m_stMVBuffer[i].stOutputBfr.hBitstreamBuffer); 525 | m_stMVBuffer[i].stOutputBfr.hBitstreamBuffer = NULL; 526 | if (m_stEncoderInput.enableAsyncMode) 527 | { 528 | m_pNvHWEncoder->NvEncUnregisterAsyncEvent(m_stMVBuffer[i].stOutputBfr.hOutputEvent); 529 | //nvCloseFile(m_stMVBuffer[i].stOutputBfr.hOutputEvent); 530 | m_stMVBuffer[i].stOutputBfr.hOutputEvent = NULL; 531 | } 532 | } 533 | 534 | return NV_ENC_SUCCESS; 535 | } 536 | 537 | void CNvEncoder::FlushMVOutputBuffer() 538 | { 539 | MotionEstimationBuffer *pMEBufer = m_MVBufferQueue.GetPending(); 540 | 541 | while (pMEBufer) 542 | { 543 | m_pNvHWEncoder->ProcessMVOutput(pMEBufer); 544 | pMEBufer = m_MVBufferQueue.GetPending(); 545 | } 546 | } 547 | 548 | NVENCSTATUS CNvEncoder::FlushEncoder() 549 | { 550 | NVENCSTATUS nvStatus = m_pNvHWEncoder->NvEncFlushEncoderQueue(m_stEOSOutputBfr.hOutputEvent); 551 | if (nvStatus != NV_ENC_SUCCESS) 552 | { 553 | NvDebugLog("hwencoder nvencFlushEncoderQueue failed. nvStatus: %d", nvStatus); 554 | return nvStatus; 555 | } 556 | 557 | EncodeBuffer *pEncodeBufer = m_EncodeBufferQueue.GetPending(); 558 | while (pEncodeBufer) 559 | { 560 | m_pNvHWEncoder->ProcessOutput(pEncodeBufer); 561 | pEncodeBufer = m_EncodeBufferQueue.GetPending(); 562 | } 563 | 564 | return nvStatus; 565 | } 566 | 567 | NVENCSTATUS CNvEncoder::Deinitialize() 568 | { 569 | NVENCSTATUS nvStatus = NV_ENC_SUCCESS; 570 | ReleaseIOBuffers(); 571 | nvStatus = m_pNvHWEncoder->NvEncDestroyEncoder(); 572 | 573 | CUresult cuResult = CUDA_SUCCESS; 574 | cuResult = cuCtxDestroy((CUcontext)m_pDevice); 575 | if (cuResult != CUDA_SUCCESS) 576 | NvDebugLog("cuCtxDestroy error:0x%x", cuResult); 577 | m_pDevice = NULL; 578 | return nvStatus; 579 | } 580 | 581 | NVENCSTATUS CNvEncoder::DeinitializeZC() 582 | { 583 | NVENCSTATUS nvStatus = NV_ENC_SUCCESS; 584 | ReleaseIOBuffersZC(); 585 | nvStatus = m_pNvHWEncoder->NvEncDestroyEncoder(); 586 | 587 | CUresult cuResult = CUDA_SUCCESS; 588 | cuResult = cuCtxDestroy((CUcontext)m_pDevice); 589 | if (cuResult != CUDA_SUCCESS) 590 | NvDebugLog("cuCtxDestroy error:0x%x", cuResult); 591 | m_pDevice = NULL; 592 | return nvStatus; 593 | } 594 | 595 | 596 | #if 0 597 | NVENCSTATUS loadframe(uint8_t *yuvInput[3], HANDLE hInputYUVFile, uint32_t frmIdx, uint32_t width, uint32_t height, uint32_t &numBytesRead, NV_ENC_BUFFER_FORMAT inputFormat) 598 | { 599 | uint64_t fileOffset; 600 | uint32_t result; 601 | //Set size depending on whether it is YUV 444 or YUV 420 602 | uint32_t dwInFrameSize = 0; 603 | int anFrameSize[3] = {}; 604 | switch (inputFormat) { 605 | default: 606 | case NV_ENC_BUFFER_FORMAT_NV12: 607 | dwInFrameSize = width * height * 3 / 2; 608 | anFrameSize[0] = width * height; 609 | anFrameSize[1] = anFrameSize[2] = width * height / 4; 610 | break; 611 | case NV_ENC_BUFFER_FORMAT_YUV444: 612 | dwInFrameSize = width * height * 3; 613 | anFrameSize[0] = anFrameSize[1] = anFrameSize[2] = width * height; 614 | break; 615 | case NV_ENC_BUFFER_FORMAT_YUV420_10BIT: 616 | dwInFrameSize = width * height * 3; 617 | anFrameSize[0] = width * height * 2; 618 | anFrameSize[1] = anFrameSize[2] = width * height / 2; 619 | break; 620 | case NV_ENC_BUFFER_FORMAT_YUV444_10BIT: 621 | dwInFrameSize = width * height * 6; 622 | anFrameSize[0] = anFrameSize[1] = anFrameSize[2] = width * height * 2; 623 | break; 624 | } 625 | fileOffset = (uint64_t)dwInFrameSize * frmIdx; 626 | result = nvSetFilePointer64(hInputYUVFile, fileOffset, NULL, FILE_BEGIN); 627 | if (result == INVALID_SET_FILE_POINTER) 628 | { 629 | return NV_ENC_ERR_INVALID_PARAM; 630 | } 631 | nvReadFile(hInputYUVFile, yuvInput[0], anFrameSize[0], &numBytesRead, NULL); 632 | nvReadFile(hInputYUVFile, yuvInput[1], anFrameSize[1], &numBytesRead, NULL); 633 | nvReadFile(hInputYUVFile, yuvInput[2], anFrameSize[2], &numBytesRead, NULL); 634 | return NV_ENC_SUCCESS; 635 | } 636 | #endif 637 | void PrintHelp() 638 | { 639 | printf("Usage : NvEncoder \n" 640 | "-i Specify input yuv420 file\n" 641 | "-o Specify output bitstream file\n" 642 | "-size Specify input resolution \n" 643 | "\n### Optional parameters ###\n" 644 | "-codec Specify the codec \n" 645 | " 0: H264\n" 646 | " 1: HEVC\n" 647 | "-preset Specify the preset for encoder settings\n" 648 | " hq : nvenc HQ \n" 649 | " hp : nvenc HP \n" 650 | " lowLatencyHP : nvenc low latency HP \n" 651 | " lowLatencyHQ : nvenc low latency HQ \n" 652 | " lossless : nvenc Lossless HP \n" 653 | "-startf Specify start index for encoding. Default is 0\n" 654 | "-endf Specify end index for encoding. Default is end of file\n" 655 | "-fps Specify encoding frame rate\n" 656 | "-goplength Specify gop length\n" 657 | "-numB Specify number of B frames\n" 658 | "-bitrate Specify the encoding average bitrate\n" 659 | "-vbvMaxBitrate Specify the vbv max bitrate\n" 660 | "-vbvSize Specify the encoding vbv/hrd buffer size\n" 661 | "-rcmode Specify the rate control mode\n" 662 | " 0: Constant QP\n" 663 | " 1: Single pass VBR\n" 664 | " 2: Single pass CBR\n" 665 | " 4: Single pass VBR minQP\n" 666 | " 8: Two pass frame quality\n" 667 | " 16: Two pass frame size cap\n" 668 | " 32: Two pass VBR\n" 669 | "-qp Specify qp for Constant QP mode\n" 670 | "-i_qfactor Specify qscale difference between I-frames and P-frames\n" 671 | "-b_qfactor Specify qscale difference between P-frames and B-frames\n" 672 | "-i_qoffset Specify qscale offset between I-frames and P-frames\n" 673 | "-b_qoffset Specify qscale offset between P-frames and B-frames\n" 674 | "-picStruct Specify the picture structure\n" 675 | " 1: Progressive frame\n" 676 | " 2: Field encoding top field first\n" 677 | " 3: Field encoding bottom field first\n" 678 | "-devicetype Specify devicetype used for encoding\n" 679 | " 0: DX9\n" 680 | " 1: DX11\n" 681 | " 2: Cuda\n" 682 | " 3: DX10\n" 683 | "-inputFormat Specify the input format\n" 684 | " 0: YUV 420\n" 685 | " 1: YUV 444\n" 686 | " 2: YUV 420 10-bit\n" 687 | " 3: YUV 444 10-bit\n" 688 | "-deviceID Specify the GPU device on which encoding will take place\n" 689 | "-meonly Specify Motion estimation only(permissive value 1 and 2) to generates motion vectors and Mode information\n" 690 | " 1: Motion estimation between startf and endf\n" 691 | " 2: Motion estimation for all consecutive frames from startf to endf\n" 692 | "-preloadedFrameCount Specify number of frame to load in memory(default value=240) with min value 2(1 frame for ref, 1 frame for input)\n" 693 | "-temporalAQ 1: Enable TemporalAQ\n" 694 | "-help Prints Help Information\n\n" 695 | ); 696 | } 697 | 698 | //int CNvEncoder::EncoderInit(uint32_t ip, uint16_t port, int argc, ...) 699 | 700 | int CNvEncoder::EncoderInit(const int argc, ...) 701 | { 702 | NVENCSTATUS nvStatus = NV_ENC_SUCCESS; 703 | int result = 0; 704 | EncodeConfig encodeConfig; 705 | memset(&encodeConfig, 0, sizeof(EncodeConfig)); 706 | 707 | encodeConfig.endFrameIdx = INT_MAX; 708 | encodeConfig.bitrate = 5000000; 709 | encodeConfig.rcMode = NV_ENC_PARAMS_RC_CONSTQP; 710 | encodeConfig.gopLength = NVENC_INFINITE_GOPLENGTH; 711 | encodeConfig.deviceType = NV_ENC_CUDA; 712 | encodeConfig.codec = NV_ENC_H264; 713 | encodeConfig.fps = 30; 714 | encodeConfig.qp = 28; 715 | encodeConfig.i_quant_factor = DEFAULT_I_QFACTOR; 716 | encodeConfig.b_quant_factor = DEFAULT_B_QFACTOR; 717 | encodeConfig.i_quant_offset = DEFAULT_I_QOFFSET; 718 | encodeConfig.b_quant_offset = DEFAULT_B_QOFFSET; 719 | encodeConfig.presetGUID = NV_ENC_PRESET_DEFAULT_GUID; 720 | encodeConfig.pictureStruct = NV_ENC_PIC_STRUCT_FRAME; 721 | encodeConfig.inputFormat = NV_ENC_BUFFER_FORMAT_ARGB; 722 | encodeConfig.height = HEIGHT_DEFAULT; 723 | encodeConfig.width = WIDTH_DEFAULT; 724 | encodeConfig.codec = 0; 725 | //encodeConfig.sip = ip; 726 | //encodeConfig.sport = port; 727 | 728 | //result = m_pNvHWEncoder->Init_tcp_connect(); 729 | result = m_pNvHWEncoder->Init_tcp_serv(); 730 | if(result < 0){ 731 | NvDebugLog("tcp serv init failed, result: %d", result); 732 | return -1; 733 | } 734 | 735 | nvStatus = InitCuda(encodeConfig.deviceID); 736 | if(nvStatus != NV_ENC_SUCCESS){ 737 | NvDebugLog("initcuda failed, nvStatus: %d", nvStatus); 738 | return -1; 739 | } 740 | 741 | nvStatus = m_pNvHWEncoder->Initialize(m_pDevice, NV_ENC_DEVICE_TYPE_CUDA); 742 | if (nvStatus != NV_ENC_SUCCESS){ 743 | NvDebugLog("hwencoder initialize failed, nvstatus: %d", nvStatus); 744 | return -1; 745 | } 746 | 747 | encodeConfig.presetGUID = m_pNvHWEncoder->GetPresetGUID(encodeConfig.encoderPreset, encodeConfig.codec); 748 | nvStatus = m_pNvHWEncoder->CreateEncoder(&encodeConfig); 749 | if (nvStatus != NV_ENC_SUCCESS){ 750 | NvDebugLog("create encoder failed, nvstatus: %d",nvStatus); 751 | return -1; 752 | } 753 | 754 | encodeConfig.maxWidth = encodeConfig.maxWidth ? encodeConfig.maxWidth : encodeConfig.width; 755 | encodeConfig.maxHeight = encodeConfig.maxHeight ? encodeConfig.maxHeight : encodeConfig.height; 756 | m_stEncoderInput.enableAsyncMode = encodeConfig.enableAsyncMode; 757 | 758 | m_uEncodeBufferCount = 1; 759 | m_uPicStruct = encodeConfig.pictureStruct; 760 | nvStatus = AllocateIOBuffers(encodeConfig.width, encodeConfig.height, encodeConfig.inputFormat); 761 | if (nvStatus != NV_ENC_SUCCESS){ 762 | NvDebugLog("AllocateIOBuffers call failed, nvstatus: %d", nvStatus); 763 | return -1; 764 | } 765 | //NvDebugLog("Encoder init success."); 766 | return 0; 767 | } 768 | 769 | int CNvEncoder::EncoderInitZC(const int max_number_surface) 770 | { 771 | int result = 0; 772 | m_stEncodeBufferPtrArr = (EncodeBufferPtr*)malloc(max_number_surface * sizeof(EncodeBufferPtr)); 773 | if(!m_stEncodeBufferPtrArr) 774 | { 775 | NvDebugLog("m_stEncoderBufferPtrArr malloc error."); 776 | return -1; 777 | } 778 | memset(m_stEncodeBufferPtrArr, 0, max_number_surface*sizeof(EncodeBufferPtr)); 779 | m_stEncodeBufferPtrCnt = max_number_surface; 780 | EncodeConfig encodeConfig; 781 | memset(&encodeConfig, 0, sizeof(EncodeConfig)); 782 | 783 | encodeConfig.endFrameIdx = INT_MAX; 784 | encodeConfig.bitrate = 5000000; 785 | encodeConfig.rcMode = NV_ENC_PARAMS_RC_CONSTQP; 786 | encodeConfig.gopLength = NVENC_INFINITE_GOPLENGTH; 787 | encodeConfig.deviceType = NV_ENC_CUDA; 788 | encodeConfig.codec = NV_ENC_H264; 789 | encodeConfig.fps = 30; 790 | encodeConfig.qp = 28; 791 | encodeConfig.i_quant_factor = DEFAULT_I_QFACTOR; 792 | encodeConfig.b_quant_factor = DEFAULT_B_QFACTOR; 793 | encodeConfig.i_quant_offset = DEFAULT_I_QOFFSET; 794 | encodeConfig.b_quant_offset = DEFAULT_B_QOFFSET; 795 | encodeConfig.presetGUID = NV_ENC_PRESET_DEFAULT_GUID; 796 | encodeConfig.pictureStruct = NV_ENC_PIC_STRUCT_FRAME; 797 | encodeConfig.inputFormat = NV_ENC_BUFFER_FORMAT_ARGB; 798 | encodeConfig.height = HEIGHT_DEFAULT; 799 | encodeConfig.width = WIDTH_DEFAULT; 800 | encodeConfig.codec = 0; 801 | 802 | result = m_pNvHWEncoder->Init_tcp_serv(); 803 | if(result < 0){ 804 | NvDebugLog("tcp serv init failed, result: %d", result); 805 | return -1; 806 | } 807 | 808 | __nv(InitCuda(encodeConfig.deviceID)); 809 | __nv(m_pNvHWEncoder->Initialize(m_pDevice, NV_ENC_DEVICE_TYPE_CUDA)); 810 | encodeConfig.presetGUID = m_pNvHWEncoder->GetPresetGUID(encodeConfig.encoderPreset, encodeConfig.codec); 811 | __nv(m_pNvHWEncoder->CreateEncoder(&encodeConfig)); 812 | 813 | encodeConfig.maxWidth = encodeConfig.maxWidth ? encodeConfig.maxWidth : encodeConfig.width; 814 | encodeConfig.maxHeight = encodeConfig.maxHeight ? encodeConfig.maxHeight : encodeConfig.height; 815 | m_stEncoderInput.enableAsyncMode = encodeConfig.enableAsyncMode; 816 | m_uPicStruct = encodeConfig.pictureStruct; 817 | m_stEOSOutputBfr.bEOSFlag = TRUE; 818 | m_stEOSOutputBfr.hOutputEvent = NULL; 819 | NvDebugLog("init zc success."); 820 | 821 | return 0; 822 | } 823 | 824 | NVENCSTATUS CNvEncoder::RunMotionEstimationOnly(MEOnlyConfig *pMEOnly, bool bFlush) 825 | { 826 | //uint8_t *pInputSurface = NULL; 827 | //uint8_t *pInputSurfaceCh = NULL; 828 | uint32_t lockedPitch = 0; 829 | //uint32_t dwSurfHeight = 0; 830 | static unsigned int dwCurWidth = 0; 831 | static unsigned int dwCurHeight = 0; 832 | //HRESULT hr = S_OK; 833 | NVENCSTATUS nvStatus = NV_ENC_SUCCESS; 834 | MotionEstimationBuffer *pMEBuffer = NULL; 835 | 836 | if (bFlush) 837 | { 838 | FlushMVOutputBuffer(); 839 | return NV_ENC_SUCCESS; 840 | } 841 | 842 | if (!pMEOnly) 843 | { 844 | assert(0); 845 | return NV_ENC_ERR_INVALID_PARAM; 846 | } 847 | 848 | pMEBuffer = m_MVBufferQueue.GetAvailable(); 849 | if(!pMEBuffer) 850 | { 851 | m_pNvHWEncoder->ProcessMVOutput(m_MVBufferQueue.GetPending()); 852 | pMEBuffer = m_MVBufferQueue.GetAvailable(); 853 | } 854 | pMEBuffer->inputFrameIndex = pMEOnly->inputFrameIndex; 855 | pMEBuffer->referenceFrameIndex = pMEOnly->referenceFrameIndex; 856 | dwCurWidth = pMEOnly->width; 857 | dwCurHeight = pMEOnly->height; 858 | 859 | for (int i = 0; i < 2; i++) 860 | { 861 | unsigned char *pInputSurface = NULL; 862 | unsigned char *pInputSurfaceCh = NULL; 863 | nvStatus = m_pNvHWEncoder->NvEncLockInputBuffer(pMEBuffer->stInputBfr[i].hInputSurface, (void**)&pInputSurface, &lockedPitch); 864 | if (nvStatus != NV_ENC_SUCCESS) 865 | return nvStatus; 866 | 867 | if (pMEBuffer->stInputBfr[i].bufferFmt == NV_ENC_BUFFER_FORMAT_NV12_PL) 868 | { 869 | pInputSurfaceCh = pInputSurface + (pMEBuffer->stInputBfr[i].dwHeight*lockedPitch); 870 | convertYUVpitchtoNV12(pMEOnly->yuv[i][0], pMEOnly->yuv[i][1], pMEOnly->yuv[i][2], pInputSurface, pInputSurfaceCh, dwCurWidth, dwCurHeight, dwCurWidth, lockedPitch); 871 | } 872 | else if (pMEBuffer->stInputBfr[i].bufferFmt == NV_ENC_BUFFER_FORMAT_YUV444) 873 | { 874 | unsigned char *pInputSurfaceCb = pInputSurface + (pMEBuffer->stInputBfr[i].dwHeight * lockedPitch); 875 | unsigned char *pInputSurfaceCr = pInputSurfaceCb + (pMEBuffer->stInputBfr[i].dwHeight * lockedPitch); 876 | convertYUVpitchtoYUV444(pMEOnly->yuv[i][0], pMEOnly->yuv[i][1], pMEOnly->yuv[i][2], pInputSurface, pInputSurfaceCb, pInputSurfaceCr, dwCurWidth, dwCurHeight, dwCurWidth, lockedPitch); 877 | } 878 | else if (pMEBuffer->stInputBfr[i].bufferFmt == NV_ENC_BUFFER_FORMAT_YUV420_10BIT) 879 | { 880 | unsigned char *pInputSurfaceCh = pInputSurface + (pMEBuffer->stInputBfr[i].dwHeight*lockedPitch); 881 | convertYUV10pitchtoP010PL((uint16_t *)pMEOnly->yuv[i][0], (uint16_t *)pMEOnly->yuv[i][1], (uint16_t *)pMEOnly->yuv[i][2], (uint16_t *)pInputSurface, (uint16_t *)pInputSurfaceCh, dwCurWidth, dwCurHeight, dwCurWidth, lockedPitch); 882 | } 883 | else 884 | { 885 | unsigned char *pInputSurfaceCb = pInputSurface + (pMEBuffer->stInputBfr[i].dwHeight * lockedPitch); 886 | unsigned char *pInputSurfaceCr = pInputSurfaceCb + (pMEBuffer->stInputBfr[i].dwHeight * lockedPitch); 887 | convertYUV10pitchtoYUV444((uint16_t *)pMEOnly->yuv[i][0], (uint16_t *)pMEOnly->yuv[i][1], (uint16_t *)pMEOnly->yuv[i][2], (uint16_t *)pInputSurface, (uint16_t *)pInputSurfaceCb, (uint16_t *)pInputSurfaceCr, dwCurWidth, dwCurHeight, dwCurWidth, lockedPitch); 888 | } 889 | nvStatus = m_pNvHWEncoder->NvEncUnlockInputBuffer(pMEBuffer->stInputBfr[i].hInputSurface); 890 | if (nvStatus != NV_ENC_SUCCESS) 891 | return nvStatus; 892 | } 893 | 894 | nvStatus = m_pNvHWEncoder->NvRunMotionEstimationOnly(pMEBuffer, pMEOnly); 895 | if (nvStatus != NV_ENC_SUCCESS) 896 | { 897 | PRINTERR("nvEncRunMotionEstimationOnly error:0x%x\n", nvStatus); 898 | assert(0); 899 | } 900 | return nvStatus; 901 | 902 | } 903 | 904 | NVENCSTATUS CNvEncoder::EncodeFrame(const void* pData, bool bFlush, uint32_t width, uint32_t height) 905 | { 906 | NVENCSTATUS nvStatus = NV_ENC_SUCCESS; 907 | uint32_t lockedPitch = 0; 908 | EncodeBuffer *pEncodeBuffer = NULL; 909 | 910 | if (bFlush) 911 | { 912 | FlushEncoder(); 913 | return NV_ENC_SUCCESS; 914 | } 915 | 916 | pEncodeBuffer = m_EncodeBufferQueue.GetAvailable(); 917 | if(!pEncodeBuffer) 918 | { 919 | m_pNvHWEncoder->ProcessOutput(m_EncodeBufferQueue.GetPending()); 920 | pEncodeBuffer = m_EncodeBufferQueue.GetAvailable(); 921 | } 922 | 923 | unsigned char *pInputSurface; 924 | m_pNvHWEncoder->NvEncLockInputBuffer(pEncodeBuffer->stInputBfr.hInputSurface, (void**)&pInputSurface, &lockedPitch); 925 | 926 | if(pEncodeBuffer->stInputBfr.bufferFmt == NV_ENC_BUFFER_FORMAT_ARGB) 927 | { 928 | convertBGRApitchtoARGB(pData, pInputSurface, width, height, width, lockedPitch); 929 | } 930 | else if(pEncodeBuffer->stInputBfr.bufferFmt == NV_ENC_BUFFER_FORMAT_ABGR) 931 | { 932 | convertBGRApitchtoABGR(pData, pInputSurface, width, height, width, lockedPitch); 933 | } 934 | 935 | m_pNvHWEncoder->NvEncUnlockInputBuffer(pEncodeBuffer->stInputBfr.hInputSurface); 936 | nvStatus = m_pNvHWEncoder->NvEncEncodeFrame(pEncodeBuffer, NULL, width, height, (NV_ENC_PIC_STRUCT)m_uPicStruct); 937 | if(!bFlush) 938 | m_numFramesEncoded++; 939 | 940 | pEncodeBuffer = m_EncodeBufferQueue.GetPending(); 941 | if(pEncodeBuffer) 942 | { 943 | m_pNvHWEncoder->ProcessOutput(pEncodeBuffer); 944 | } 945 | return nvStatus; 946 | } 947 | 948 | NVENCSTATUS CNvEncoder::EncodeFrameZC(const int id) 949 | { 950 | static int write_cnt = 0; 951 | EncodeBufferPtr pEncodeBuffer = NULL; 952 | pEncodeBuffer = m_stEncodeBufferPtrArr[id]; 953 | CCudaAutoLock cuLock(m_pDevice); 954 | uint32_t lockedPitch = 0; 955 | unsigned char *pInputSurface; 956 | int curWidth = pEncodeBuffer->stInputBfr.dwWidth; 957 | int curHeight = pEncodeBuffer->stInputBfr.dwHeight; 958 | 959 | switch(m_currentBufferType) 960 | { 961 | case NVENC_INPUT_BUFFER: 962 | //__nv(m_pNvHWEncoder->NvEncLockInputBuffer(pEncodeBuffer->stInputBfr.hInputSurface, (void**)&pInputSurface, &lockedPitch)); 963 | //convertBGRApitchtoARGB(pEncodeBuffer->stInputBfr.pRGBHostPtr, pInputSurface, curWidth, curHeight, curWidth, lockedPitch); 964 | #if 0 965 | if(m_numFramesEncoded % 30 == 0 && write_cnt < 500){ 966 | fwrite(pEncodeBuffer->stInputBfr.pRGBHostPtr, curWidth*curHeight*4, 1, rgba); 967 | write_cnt++; 968 | } 969 | #endif 970 | __nv(m_pNvHWEncoder->NvEncUnlockInputBuffer(pEncodeBuffer->stInputBfr.hInputSurface)); 971 | __nv(m_pNvHWEncoder->NvEncEncodeFrame(pEncodeBuffer, NULL, curWidth, curHeight, (NV_ENC_PIC_STRUCT)m_uPicStruct)); 972 | __nv(m_pNvHWEncoder->ProcessOutput(pEncodeBuffer)); 973 | __nv(m_pNvHWEncoder->NvEncLockInputBuffer(pEncodeBuffer->stInputBfr.hInputSurface, (void**)&pEncodeBuffer->stInputBfr.pRGBHostPtr, &lockedPitch)); 974 | //NvLog("pRgbHostPtr: %p", pEncodeBuffer->stInputBfr.pRGBHostPtr); 975 | break; 976 | case CUDA_DEVICE_BUFFER: 977 | break; 978 | case CUDA_HOST_BUFFER: 979 | __nv( m_pNvHWEncoder->NvEncMapInputResource(pEncodeBuffer->stInputBfr.nvRegisteredResource, &pEncodeBuffer->stInputBfr.hInputSurface)); 980 | __nv( m_pNvHWEncoder->NvEncEncodeFrame(pEncodeBuffer, NULL, curWidth, curHeight)); 981 | __nv( m_pNvHWEncoder->ProcessOutput(pEncodeBuffer)); 982 | __nv( m_pNvHWEncoder->NvEncUnmapInputResource(pEncodeBuffer->stInputBfr.hInputSurface)); 983 | break; 984 | default: 985 | break; 986 | } 987 | 988 | m_numFramesEncoded++; 989 | return NV_ENC_SUCCESS; 990 | } 991 | 992 | -------------------------------------------------------------------------------- /src/dynlink_cuda.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1993-2015 NVIDIA Corporation. All rights reserved. 3 | * 4 | * Please refer to the NVIDIA end user license agreement (EULA) associated 5 | * with this source code for terms and conditions that govern your use of 6 | * this software. Any use, reproduction, disclosure, or distribution of 7 | * this software and related documentation outside the terms of the EULA 8 | * is strictly prohibited. 9 | * 10 | */ 11 | 12 | 13 | // With these flags defined, this source file will dynamically 14 | // load the corresponding functions. Disabled by default. 15 | #define __CUDA_API_VERSION 4000 16 | 17 | #include 18 | #include 19 | #include "dynlink_cuda.h" 20 | 21 | #if INIT_CUDA_GL 22 | #include "../inc/dynlink_cudaGL.h" 23 | #endif 24 | #if INIT_CUDA_D3D9 25 | #include "../inc/dynlink_cudaD3D9.h" 26 | #endif 27 | #if INIT_CUDA_D3D11 28 | #include "../inc/dynlink_cudaD3D11.h" 29 | #endif 30 | 31 | tcuInit *_cuInit; 32 | tcuDriverGetVersion *cuDriverGetVersion; 33 | tcuDeviceGet *cuDeviceGet; 34 | tcuDeviceGetCount *cuDeviceGetCount; 35 | tcuDeviceGetName *cuDeviceGetName; 36 | tcuDeviceComputeCapability *cuDeviceComputeCapability; 37 | tcuDeviceTotalMem *cuDeviceTotalMem; 38 | tcuDeviceGetProperties *cuDeviceGetProperties; 39 | tcuDeviceGetAttribute *cuDeviceGetAttribute; 40 | tcuCtxCreate *cuCtxCreate; 41 | tcuCtxDestroy *cuCtxDestroy; 42 | tcuCtxAttach *cuCtxAttach; 43 | tcuCtxDetach *cuCtxDetach; 44 | tcuCtxPushCurrent *cuCtxPushCurrent; 45 | tcuCtxPopCurrent *cuCtxPopCurrent; 46 | tcuCtxGetCurrent *cuCtxGetCurrent; 47 | tcuCtxSetCurrent *cuCtxSetCurrent; 48 | tcuCtxGetDevice *cuCtxGetDevice; 49 | tcuCtxSynchronize *cuCtxSynchronize; 50 | tcuModuleLoad *cuModuleLoad; 51 | tcuModuleLoadData *cuModuleLoadData; 52 | tcuModuleLoadDataEx *cuModuleLoadDataEx; 53 | tcuModuleLoadFatBinary *cuModuleLoadFatBinary; 54 | tcuModuleUnload *cuModuleUnload; 55 | tcuModuleGetFunction *cuModuleGetFunction; 56 | tcuModuleGetGlobal *cuModuleGetGlobal; 57 | tcuModuleGetTexRef *cuModuleGetTexRef; 58 | tcuModuleGetSurfRef *cuModuleGetSurfRef; 59 | tcuMemGetInfo *cuMemGetInfo; 60 | tcuMemAlloc *cuMemAlloc; 61 | tcuMemAllocPitch *cuMemAllocPitch; 62 | tcuMemFree *cuMemFree; 63 | tcuMemGetAddressRange *cuMemGetAddressRange; 64 | tcuMemAllocHost *cuMemAllocHost; 65 | tcuMemFreeHost *cuMemFreeHost; 66 | tcuMemHostAlloc *cuMemHostAlloc; 67 | tcuMemHostGetDevicePointer *cuMemHostGetDevicePointer; 68 | tcuMemHostRegister *cuMemHostRegister; 69 | tcuMemHostUnregister *cuMemHostUnregister; 70 | tcuMemcpyHtoD *cuMemcpyHtoD; 71 | tcuMemcpyDtoH *cuMemcpyDtoH; 72 | tcuMemcpyDtoD *cuMemcpyDtoD; 73 | tcuMemcpyDtoA *cuMemcpyDtoA; 74 | tcuMemcpyAtoD *cuMemcpyAtoD; 75 | tcuMemcpyHtoA *cuMemcpyHtoA; 76 | tcuMemcpyAtoH *cuMemcpyAtoH; 77 | tcuMemcpyAtoA *cuMemcpyAtoA; 78 | tcuMemcpy2D *cuMemcpy2D; 79 | tcuMemcpy2DUnaligned *cuMemcpy2DUnaligned; 80 | tcuMemcpy3D *cuMemcpy3D; 81 | tcuMemcpyHtoDAsync *cuMemcpyHtoDAsync; 82 | tcuMemcpyDtoHAsync *cuMemcpyDtoHAsync; 83 | tcuMemcpyDtoDAsync *cuMemcpyDtoDAsync; 84 | tcuMemcpyHtoAAsync *cuMemcpyHtoAAsync; 85 | tcuMemcpyAtoHAsync *cuMemcpyAtoHAsync; 86 | tcuMemcpy2DAsync *cuMemcpy2DAsync; 87 | tcuMemcpy3DAsync *cuMemcpy3DAsync; 88 | tcuMemcpy *cuMemcpy; 89 | tcuMemcpyPeer *cuMemcpyPeer; 90 | tcuMemsetD8 *cuMemsetD8; 91 | tcuMemsetD16 *cuMemsetD16; 92 | tcuMemsetD32 *cuMemsetD32; 93 | tcuMemsetD2D8 *cuMemsetD2D8; 94 | tcuMemsetD2D16 *cuMemsetD2D16; 95 | tcuMemsetD2D32 *cuMemsetD2D32; 96 | tcuFuncSetBlockShape *cuFuncSetBlockShape; 97 | tcuFuncSetSharedSize *cuFuncSetSharedSize; 98 | tcuFuncGetAttribute *cuFuncGetAttribute; 99 | tcuFuncSetCacheConfig *cuFuncSetCacheConfig; 100 | tcuLaunchKernel *cuLaunchKernel; 101 | tcuArrayCreate *cuArrayCreate; 102 | tcuArrayGetDescriptor *cuArrayGetDescriptor; 103 | tcuArrayDestroy *cuArrayDestroy; 104 | tcuArray3DCreate *cuArray3DCreate; 105 | tcuArray3DGetDescriptor *cuArray3DGetDescriptor; 106 | tcuTexRefCreate *cuTexRefCreate; 107 | tcuTexRefDestroy *cuTexRefDestroy; 108 | tcuTexRefSetArray *cuTexRefSetArray; 109 | tcuTexRefSetAddress *cuTexRefSetAddress; 110 | tcuTexRefSetAddress2D *cuTexRefSetAddress2D; 111 | tcuTexRefSetFormat *cuTexRefSetFormat; 112 | tcuTexRefSetAddressMode *cuTexRefSetAddressMode; 113 | tcuTexRefSetFilterMode *cuTexRefSetFilterMode; 114 | tcuTexRefSetFlags *cuTexRefSetFlags; 115 | tcuTexRefGetAddress *cuTexRefGetAddress; 116 | tcuTexRefGetArray *cuTexRefGetArray; 117 | tcuTexRefGetAddressMode *cuTexRefGetAddressMode; 118 | tcuTexRefGetFilterMode *cuTexRefGetFilterMode; 119 | tcuTexRefGetFormat *cuTexRefGetFormat; 120 | tcuTexRefGetFlags *cuTexRefGetFlags; 121 | tcuSurfRefSetArray *cuSurfRefSetArray; 122 | tcuSurfRefGetArray *cuSurfRefGetArray; 123 | tcuParamSetSize *cuParamSetSize; 124 | tcuParamSeti *cuParamSeti; 125 | tcuParamSetf *cuParamSetf; 126 | tcuParamSetv *cuParamSetv; 127 | tcuParamSetTexRef *cuParamSetTexRef; 128 | tcuLaunch *cuLaunch; 129 | tcuLaunchGrid *cuLaunchGrid; 130 | tcuLaunchGridAsync *cuLaunchGridAsync; 131 | tcuEventCreate *cuEventCreate; 132 | tcuEventRecord *cuEventRecord; 133 | tcuEventQuery *cuEventQuery; 134 | tcuEventSynchronize *cuEventSynchronize; 135 | tcuEventDestroy *cuEventDestroy; 136 | tcuEventElapsedTime *cuEventElapsedTime; 137 | tcuStreamCreate *cuStreamCreate; 138 | tcuStreamQuery *cuStreamQuery; 139 | tcuStreamSynchronize *cuStreamSynchronize; 140 | tcuStreamDestroy *cuStreamDestroy; 141 | tcuGraphicsUnregisterResource *cuGraphicsUnregisterResource; 142 | tcuGraphicsSubResourceGetMappedArray *cuGraphicsSubResourceGetMappedArray; 143 | tcuGraphicsResourceGetMappedPointer *cuGraphicsResourceGetMappedPointer; 144 | tcuGraphicsResourceSetMapFlags *cuGraphicsResourceSetMapFlags; 145 | tcuGraphicsMapResources *cuGraphicsMapResources; 146 | tcuGraphicsUnmapResources *cuGraphicsUnmapResources; 147 | tcuGetExportTable *cuGetExportTable; 148 | tcuCtxSetLimit *cuCtxSetLimit; 149 | tcuCtxGetLimit *cuCtxGetLimit; 150 | tcuMemHostGetFlags *cuMemHostGetFlags; 151 | 152 | #if INIT_CUDA_GL 153 | // GL/CUDA interop 154 | #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) 155 | tcuWGLGetDevice *cuWGLGetDevice; 156 | #endif 157 | 158 | //#if __CUDA_API_VERSION >= 3020 159 | tcuGLCtxCreate *cuGLCtxCreate; 160 | tcuGLCtxCreate *cuGLCtxCreate_v2; 161 | tcuGLMapBufferObject *cuGLMapBufferObject; 162 | tcuGLMapBufferObject *cuGLMapBufferObject_v2; 163 | tcuGLMapBufferObjectAsync *cuGLMapBufferObjectAsync; 164 | //#endif 165 | 166 | #if __CUDA_API_VERSION >= 6050 167 | tcuGLGetDevices *cuGLGetDevices; 168 | #endif 169 | 170 | tcuGLInit *cuGLInit; // deprecated in CUDA 3.0 171 | tcuGraphicsGLRegisterBuffer *cuGraphicsGLRegisterBuffer; 172 | tcuGraphicsGLRegisterImage *cuGraphicsGLRegisterImage; 173 | tcuGLSetBufferObjectMapFlags *cuGLSetBufferObjectMapFlags; 174 | tcuGLRegisterBufferObject *cuGLRegisterBufferObject; 175 | 176 | tcuGLUnmapBufferObject *cuGLUnmapBufferObject; 177 | tcuGLUnmapBufferObjectAsync *cuGLUnmapBufferObjectAsync; 178 | 179 | tcuGLUnregisterBufferObject *cuGLUnregisterBufferObject; 180 | tcuGLGetDevices *cuGLGetDevices; // CUDA 6.5 only 181 | #endif 182 | 183 | #if INIT_CUDA_D3D9 184 | // D3D9/CUDA interop (CUDA 1.x compatible API). These functions 185 | // are deprecated; please use the ones below 186 | tcuD3D9Begin *cuD3D9Begin; 187 | tcuD3D9End *cuD3D9End; 188 | 189 | // D3D9/CUDA interop (CUDA 2.x compatible) 190 | tcuD3D9GetDirect3DDevice *cuD3D9GetDirect3DDevice; 191 | tcuD3D9RegisterResource *cuD3D9RegisterResource; 192 | tcuD3D9UnregisterResource *cuD3D9UnregisterResource; 193 | tcuD3D9MapResources *cuD3D9MapResources; 194 | tcuD3D9UnmapResources *cuD3D9UnmapResources; 195 | tcuD3D9ResourceSetMapFlags *cuD3D9ResourceSetMapFlags; 196 | tcuD3D9ResourceGetSurfaceDimensions *cuD3D9ResourceGetSurfaceDimensions; 197 | tcuD3D9ResourceGetMappedArray *cuD3D9ResourceGetMappedArray; 198 | tcuD3D9ResourceGetMappedPointer *cuD3D9ResourceGetMappedPointer; 199 | tcuD3D9ResourceGetMappedSize *cuD3D9ResourceGetMappedSize; 200 | tcuD3D9ResourceGetMappedPitch *cuD3D9ResourceGetMappedPitch; 201 | 202 | // D3D9/CUDA interop (CUDA 2.0+) 203 | tcuD3D9GetDevice *cuD3D9GetDevice; 204 | tcuD3D9GetDevice *cuD3D9GetDevices; 205 | tcuD3D9GetDevice *cuD3D9GetDevice_v2; 206 | tcuD3D9CtxCreate *cuD3D9CtxCreate; 207 | tcuD3D9CtxCreate *cuD3D9CtxCreate_v2; 208 | tcuGraphicsD3D9RegisterResource *cuGraphicsD3D9RegisterResource; 209 | tcuGraphicsD3D9RegisterResource *cuGraphicsD3D9RegisterResource_v2; 210 | #endif 211 | 212 | #ifdef INIT_CUDA_D3D11 213 | tcuD3D11GetDevice *cuD3D11GetDevice; 214 | tcuD3D11GetDevices *cuD3D11GetDevices; 215 | tcuGraphicsD3D11RegisterResource *cuGraphicsD3D11RegisterResource; 216 | tcuD3D11CtxCreate *cuD3D11CtxCreate; 217 | tcuD3D11CtxCreateOnDevice *cuD3D11CtxCreateOnDevice; 218 | tcuD3D11GetDirect3DDevice *cuD3D11GetDirect3DDevice; 219 | #endif 220 | 221 | #define STRINGIFY(X) #X 222 | 223 | #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) 224 | #include 225 | 226 | #ifdef UNICODE 227 | static LPCWSTR __CudaLibName = L"nvcuda.dll"; 228 | #else 229 | static LPCSTR __CudaLibName = "nvcuda.dll"; 230 | #endif 231 | 232 | typedef HMODULE CUDADRIVER; 233 | 234 | static CUresult LOAD_LIBRARY(CUDADRIVER *pInstance) 235 | { 236 | *pInstance = LoadLibrary(__CudaLibName); 237 | 238 | if (*pInstance == NULL) 239 | { 240 | printf("LoadLibrary \"%s\" failed!\n", __CudaLibName); 241 | return CUDA_ERROR_UNKNOWN; 242 | } 243 | 244 | return CUDA_SUCCESS; 245 | } 246 | 247 | #define GET_PROC_EX(name, alias, required) \ 248 | alias = (t##name *)GetProcAddress(CudaDrvLib, #name); \ 249 | if (alias == NULL && required) { \ 250 | printf("Failed to find required function \"%s\" in %s\n", \ 251 | #name, __CudaLibName); \ 252 | } 253 | 254 | #define GET_PROC_EX_V2(name, alias, required) \ 255 | alias = (t##name *)GetProcAddress(CudaDrvLib, STRINGIFY(name##_v2));\ 256 | if (alias == NULL && required) { \ 257 | printf("Failed to find required function \"%s\" in %s\n", \ 258 | STRINGIFY(name##_v2), __CudaLibName); \ 259 | } 260 | 261 | #elif defined(__unix__) || defined(__APPLE__) || defined(__MACOSX) 262 | 263 | #include 264 | 265 | #if defined(__APPLE__) || defined(__MACOSX) 266 | static char __CudaLibName[] = "/usr/local/cuda/lib/libcuda.dylib"; 267 | #else 268 | static char __CudaLibName[] = "libcuda.so"; 269 | #endif 270 | 271 | typedef void *CUDADRIVER; 272 | 273 | static CUresult LOAD_LIBRARY(CUDADRIVER *pInstance) 274 | { 275 | *pInstance = dlopen(__CudaLibName, RTLD_NOW); 276 | 277 | if (*pInstance == NULL) 278 | { 279 | printf("dlopen \"%s\" failed!\n", __CudaLibName); 280 | return CUDA_ERROR_UNKNOWN; 281 | } 282 | 283 | return CUDA_SUCCESS; 284 | } 285 | 286 | #define GET_PROC_EX(name, alias, required) \ 287 | alias = (t##name *)dlsym(CudaDrvLib, #name); \ 288 | if (alias == NULL && required) { \ 289 | printf("Failed to find required function \"%s\" in %s\n", \ 290 | #name, __CudaLibName); \ 291 | } 292 | 293 | #define GET_PROC_EX_V2(name, alias, required) \ 294 | alias = (t##name *)dlsym(CudaDrvLib, STRINGIFY(name##_v2)); \ 295 | if (alias == NULL && required) { \ 296 | printf("Failed to find required function \"%s\" in %s\n", \ 297 | STRINGIFY(name##_v2), __CudaLibName); \ 298 | } 299 | 300 | #else 301 | #error unsupported platform 302 | #endif 303 | 304 | #define CHECKED_CALL(call) \ 305 | do { \ 306 | CUresult result = (call); \ 307 | if (CUDA_SUCCESS != result) { \ 308 | return result; \ 309 | } \ 310 | } while(0) 311 | 312 | #define GET_PROC_REQUIRED(name) GET_PROC_EX(name,name,1) 313 | #define GET_PROC_OPTIONAL(name) GET_PROC_EX(name,name,0) 314 | #define GET_PROC(name) GET_PROC_REQUIRED(name) 315 | #define GET_PROC_V2(name) GET_PROC_EX_V2(name,name,1) 316 | 317 | #if INIT_CUDA_GL 318 | inline CUresult CUDAAPI cuInitGL(unsigned int Flags, int cudaVersion, CUDADRIVER &CudaDrvLib) 319 | { 320 | if (cudaVersion >= 2010) 321 | { 322 | GET_PROC(cuGLCtxCreate); 323 | GET_PROC(cuGraphicsGLRegisterBuffer); 324 | GET_PROC(cuGraphicsGLRegisterImage); 325 | #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) 326 | GET_PROC(cuWGLGetDevice); 327 | #endif 328 | } 329 | if (cudaVersion >= 2030) 330 | { 331 | GET_PROC(cuGraphicsGLRegisterBuffer); 332 | GET_PROC(cuGraphicsGLRegisterImage); 333 | } 334 | if (cudaVersion >= 3000) 335 | { 336 | GET_PROC(cuGLGetDevices); 337 | #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) 338 | GET_PROC(cuWGLGetDevice); 339 | #endif 340 | GET_PROC_V2(cuGLCtxCreate); 341 | 342 | GET_PROC_V2(cuGLMapBufferObject); 343 | GET_PROC(cuGLUnmapBufferObject); 344 | GET_PROC(cuGLMapBufferObjectAsync); 345 | GET_PROC(cuGLUnmapBufferObjectAsync); 346 | GET_PROC(cuGLRegisterBufferObject); 347 | GET_PROC(cuGLUnregisterBufferObject); 348 | GET_PROC(cuGLSetBufferObjectMapFlags); 349 | } 350 | 351 | return CUDA_SUCCESS; 352 | } 353 | #endif 354 | 355 | #ifdef INIT_CUDA_D3D9 356 | inline CUresult CUDAAPI cuInitD3D9(unsigned int Flags, int cudaVersion, CUDADRIVER &CudaDrvLib) 357 | { 358 | // D3D9/CUDA (CUDA 1.x compatible API) 359 | GET_PROC(cuD3D9Begin); 360 | GET_PROC(cuD3D9End); 361 | 362 | // D3D9/CUDA (CUDA 2.x compatible API) 363 | GET_PROC(cuD3D9GetDirect3DDevice); 364 | GET_PROC(cuD3D9RegisterResource); 365 | GET_PROC(cuD3D9UnregisterResource); 366 | GET_PROC(cuD3D9MapResources); 367 | GET_PROC(cuD3D9UnmapResources); 368 | GET_PROC(cuD3D9ResourceSetMapFlags); 369 | 370 | // D3D9/CUDA (CUDA 2.0+ compatible API) 371 | GET_PROC(cuD3D9GetDevice); 372 | GET_PROC(cuGraphicsD3D9RegisterResource); 373 | 374 | GET_PROC_V2(cuD3D9CtxCreate); 375 | GET_PROC_V2(cuD3D9ResourceGetSurfaceDimensions); 376 | GET_PROC_V2(cuD3D9ResourceGetMappedPointer); 377 | GET_PROC_V2(cuD3D9ResourceGetMappedSize); 378 | GET_PROC_V2(cuD3D9ResourceGetMappedPitch); 379 | // GET_PROC_V2(cuD3D9ResourceGetMappedArray); 380 | 381 | return CUDA_SUCCESS; 382 | } 383 | #endif 384 | 385 | #ifdef INIT_CUDA_D3D10 386 | inline CUresult CUDAAPI cuInitD3D10(unsigned int Flags, int cudaVersion, CUDADRIVER &CudaDrvLib) 387 | { 388 | if (cudaVersion >= 2030) 389 | { 390 | GET_PROC(cuD3D10GetDevice); 391 | GET_PROC(cuD3D10CtxCreate); 392 | GET_PROC(cuGraphicsD3D10RegisterResource); 393 | } 394 | return CUDA_SUCCESS; 395 | } 396 | #endif 397 | 398 | #ifdef INIT_CUDA_D3D11 399 | inline CUresult CUDAAPI cuInitD3D11(unsigned int Flags, int cudaVersion, CUDADRIVER &CudaDrvLib) 400 | { 401 | if (cudaVersion >= 3000) 402 | { 403 | GET_PROC(cuD3D11GetDevice); 404 | GET_PROC(cuD3D11CtxCreate); 405 | GET_PROC(cuGraphicsD3D11RegisterResource); 406 | } 407 | 408 | return CUDA_SUCCESS; 409 | } 410 | #endif 411 | 412 | 413 | CUresult CUDAAPI cuInit(unsigned int Flags, int cudaVersion, void *pHandleDriver) 414 | { 415 | CUDADRIVER CudaDrvLib; 416 | int driverVer = 1000; 417 | 418 | CHECKED_CALL(LOAD_LIBRARY(&CudaDrvLib)); 419 | if (pHandleDriver != NULL) 420 | { 421 | memcpy(pHandleDriver, &CudaDrvLib, sizeof(CUDADRIVER)); 422 | } 423 | 424 | // cuInit is required; alias it to _cuInit 425 | GET_PROC_EX(cuInit, _cuInit, 1); 426 | CHECKED_CALL(_cuInit(Flags)); 427 | 428 | // available since 2.2. if not present, version 1.0 is assumed 429 | GET_PROC_OPTIONAL(cuDriverGetVersion); 430 | 431 | if (cuDriverGetVersion) 432 | { 433 | CHECKED_CALL(cuDriverGetVersion(&driverVer)); 434 | } 435 | 436 | // fetch all function pointers 437 | GET_PROC(cuDeviceGet); 438 | GET_PROC(cuDeviceGetCount); 439 | GET_PROC(cuDeviceGetName); 440 | GET_PROC(cuDeviceComputeCapability); 441 | GET_PROC(cuDeviceGetProperties); 442 | GET_PROC(cuDeviceGetAttribute); 443 | GET_PROC(cuCtxDestroy); 444 | GET_PROC(cuCtxAttach); 445 | GET_PROC(cuCtxDetach); 446 | GET_PROC(cuCtxPushCurrent); 447 | GET_PROC(cuCtxPopCurrent); 448 | GET_PROC(cuCtxGetDevice); 449 | GET_PROC(cuCtxSynchronize); 450 | GET_PROC(cuModuleLoad); 451 | GET_PROC(cuModuleLoadData); 452 | GET_PROC(cuModuleUnload); 453 | GET_PROC(cuModuleGetFunction); 454 | GET_PROC(cuModuleGetTexRef); 455 | GET_PROC(cuMemFreeHost); 456 | GET_PROC(cuMemHostAlloc); 457 | GET_PROC(cuFuncSetBlockShape); 458 | GET_PROC(cuFuncSetSharedSize); 459 | GET_PROC(cuFuncGetAttribute); 460 | GET_PROC(cuArrayDestroy); 461 | GET_PROC(cuTexRefCreate); 462 | GET_PROC(cuTexRefDestroy); 463 | GET_PROC(cuTexRefSetArray); 464 | GET_PROC(cuTexRefSetFormat); 465 | GET_PROC(cuTexRefSetAddressMode); 466 | GET_PROC(cuTexRefSetFilterMode); 467 | GET_PROC(cuTexRefSetFlags); 468 | GET_PROC(cuTexRefGetArray); 469 | GET_PROC(cuTexRefGetAddressMode); 470 | GET_PROC(cuTexRefGetFilterMode); 471 | GET_PROC(cuTexRefGetFormat); 472 | GET_PROC(cuTexRefGetFlags); 473 | GET_PROC(cuParamSetSize); 474 | GET_PROC(cuParamSeti); 475 | GET_PROC(cuParamSetf); 476 | GET_PROC(cuParamSetv); 477 | GET_PROC(cuParamSetTexRef); 478 | GET_PROC(cuLaunch); 479 | GET_PROC(cuLaunchGrid); 480 | GET_PROC(cuLaunchGridAsync); 481 | GET_PROC(cuEventCreate); 482 | GET_PROC(cuEventRecord); 483 | GET_PROC(cuEventQuery); 484 | GET_PROC(cuEventSynchronize); 485 | GET_PROC(cuEventDestroy); 486 | GET_PROC(cuEventElapsedTime); 487 | GET_PROC(cuStreamCreate); 488 | GET_PROC(cuStreamQuery); 489 | GET_PROC(cuStreamSynchronize); 490 | GET_PROC(cuStreamDestroy); 491 | 492 | // These could be _v2 interfaces 493 | if (cudaVersion >= 4000) 494 | { 495 | GET_PROC_V2(cuCtxDestroy); 496 | GET_PROC_V2(cuCtxPopCurrent); 497 | GET_PROC_V2(cuCtxPushCurrent); 498 | GET_PROC_V2(cuStreamDestroy); 499 | GET_PROC_V2(cuEventDestroy); 500 | } 501 | 502 | if (cudaVersion >= 3020) 503 | { 504 | GET_PROC_V2(cuDeviceTotalMem); 505 | GET_PROC_V2(cuCtxCreate); 506 | GET_PROC_V2(cuModuleGetGlobal); 507 | GET_PROC_V2(cuMemGetInfo); 508 | GET_PROC_V2(cuMemAlloc); 509 | GET_PROC_V2(cuMemAllocPitch); 510 | GET_PROC_V2(cuMemFree); 511 | GET_PROC_V2(cuMemGetAddressRange); 512 | GET_PROC_V2(cuMemAllocHost); 513 | GET_PROC_V2(cuMemHostGetDevicePointer); 514 | GET_PROC_V2(cuMemcpyHtoD); 515 | GET_PROC_V2(cuMemcpyDtoH); 516 | GET_PROC_V2(cuMemcpyDtoD); 517 | GET_PROC_V2(cuMemcpyDtoA); 518 | GET_PROC_V2(cuMemcpyAtoD); 519 | GET_PROC_V2(cuMemcpyHtoA); 520 | GET_PROC_V2(cuMemcpyAtoH); 521 | GET_PROC_V2(cuMemcpyAtoA); 522 | GET_PROC_V2(cuMemcpy2D); 523 | GET_PROC_V2(cuMemcpy2DUnaligned); 524 | GET_PROC_V2(cuMemcpy3D); 525 | GET_PROC_V2(cuMemcpyHtoDAsync); 526 | GET_PROC_V2(cuMemcpyDtoHAsync); 527 | GET_PROC_V2(cuMemcpyHtoAAsync); 528 | GET_PROC_V2(cuMemcpyAtoHAsync); 529 | GET_PROC_V2(cuMemcpy2DAsync); 530 | GET_PROC_V2(cuMemcpy3DAsync); 531 | GET_PROC_V2(cuMemsetD8); 532 | GET_PROC_V2(cuMemsetD16); 533 | GET_PROC_V2(cuMemsetD32); 534 | GET_PROC_V2(cuMemsetD2D8); 535 | GET_PROC_V2(cuMemsetD2D16); 536 | GET_PROC_V2(cuMemsetD2D32); 537 | GET_PROC_V2(cuArrayCreate); 538 | GET_PROC_V2(cuArrayGetDescriptor); 539 | GET_PROC_V2(cuArray3DCreate); 540 | GET_PROC_V2(cuArray3DGetDescriptor); 541 | GET_PROC_V2(cuTexRefSetAddress); 542 | GET_PROC_V2(cuTexRefSetAddress2D); 543 | GET_PROC_V2(cuTexRefGetAddress); 544 | } 545 | else 546 | { 547 | GET_PROC(cuDeviceTotalMem); 548 | GET_PROC(cuCtxCreate); 549 | GET_PROC(cuModuleGetGlobal); 550 | GET_PROC(cuMemGetInfo); 551 | GET_PROC(cuMemAlloc); 552 | GET_PROC(cuMemAllocPitch); 553 | GET_PROC(cuMemFree); 554 | GET_PROC(cuMemGetAddressRange); 555 | GET_PROC(cuMemAllocHost); 556 | GET_PROC(cuMemHostGetDevicePointer); 557 | GET_PROC(cuMemcpyHtoD); 558 | GET_PROC(cuMemcpyDtoH); 559 | GET_PROC(cuMemcpyDtoD); 560 | GET_PROC(cuMemcpyDtoA); 561 | GET_PROC(cuMemcpyAtoD); 562 | GET_PROC(cuMemcpyHtoA); 563 | GET_PROC(cuMemcpyAtoH); 564 | GET_PROC(cuMemcpyAtoA); 565 | GET_PROC(cuMemcpy2D); 566 | GET_PROC(cuMemcpy2DUnaligned); 567 | GET_PROC(cuMemcpy3D); 568 | GET_PROC(cuMemcpyHtoDAsync); 569 | GET_PROC(cuMemcpyDtoHAsync); 570 | GET_PROC(cuMemcpyHtoAAsync); 571 | GET_PROC(cuMemcpyAtoHAsync); 572 | GET_PROC(cuMemcpy2DAsync); 573 | GET_PROC(cuMemcpy3DAsync); 574 | GET_PROC(cuMemsetD8); 575 | GET_PROC(cuMemsetD16); 576 | GET_PROC(cuMemsetD32); 577 | GET_PROC(cuMemsetD2D8); 578 | GET_PROC(cuMemsetD2D16); 579 | GET_PROC(cuMemsetD2D32); 580 | GET_PROC(cuArrayCreate); 581 | GET_PROC(cuArrayGetDescriptor); 582 | GET_PROC(cuArray3DCreate); 583 | GET_PROC(cuArray3DGetDescriptor); 584 | GET_PROC(cuTexRefSetAddress); 585 | GET_PROC(cuTexRefSetAddress2D); 586 | GET_PROC(cuTexRefGetAddress); 587 | } 588 | 589 | // The following functions are specific to CUDA versions 590 | if (driverVer >= 2010) 591 | { 592 | GET_PROC(cuModuleLoadDataEx); 593 | GET_PROC(cuModuleLoadFatBinary); 594 | } 595 | 596 | if (driverVer >= 2030) 597 | { 598 | GET_PROC(cuMemHostGetFlags); 599 | } 600 | 601 | if (driverVer >= 3000) 602 | { 603 | GET_PROC(cuMemcpyDtoDAsync); 604 | GET_PROC(cuFuncSetCacheConfig); 605 | 606 | GET_PROC(cuGraphicsUnregisterResource); 607 | GET_PROC(cuGraphicsSubResourceGetMappedArray); 608 | 609 | #if (__CUDA_API_VERSION >= 3020) 610 | if (cudaVersion >= 3020) 611 | { 612 | GET_PROC_V2(cuGraphicsResourceGetMappedPointer); 613 | } 614 | else 615 | { 616 | GET_PROC(cuGraphicsResourceGetMappedPointer); 617 | } 618 | #endif 619 | GET_PROC(cuGraphicsResourceSetMapFlags); 620 | GET_PROC(cuGraphicsMapResources); 621 | GET_PROC(cuGraphicsUnmapResources); 622 | GET_PROC(cuGetExportTable); 623 | } 624 | 625 | if (driverVer >= 3010) 626 | { 627 | GET_PROC(cuModuleGetSurfRef); 628 | GET_PROC(cuSurfRefSetArray); 629 | GET_PROC(cuSurfRefGetArray); 630 | GET_PROC(cuCtxSetLimit); 631 | GET_PROC(cuCtxGetLimit); 632 | } 633 | 634 | if (driverVer >= 4000) 635 | { 636 | GET_PROC(cuCtxSetCurrent); 637 | GET_PROC(cuCtxGetCurrent); 638 | GET_PROC(cuMemHostRegister); 639 | GET_PROC(cuMemHostUnregister); 640 | GET_PROC(cuMemcpy); 641 | GET_PROC(cuMemcpyPeer); 642 | GET_PROC(cuLaunchKernel); 643 | } 644 | 645 | #if INIT_CUDA_GL 646 | if (cuInitGL(0, __CUDA_API_VERSION, CudaDrvLib) != CUDA_SUCCESS) 647 | return CUDA_ERROR_INVALID_DEVICE; 648 | #endif 649 | 650 | #if INIT_CUDA_D3D9 651 | if (cuInitD3D9(0, __CUDA_API_VERSION, CudaDrvLib) != CUDA_SUCCESS) 652 | return CUDA_ERROR_INVALID_DEVICE; 653 | #endif 654 | 655 | #if INIT_CUDA_D3D10 656 | if (cuInitD3D10(0, __CUDA_API_VERSION, CudaDrvLib) != CUDA_SUCCESS) 657 | return CUDA_ERROR_INVALID_DEVICE; 658 | #endif 659 | 660 | #if INIT_CUDA_D3D11 661 | if (cuInitD3D11(0, __CUDA_API_VERSION, CudaDrvLib) != CUDA_SUCCESS) 662 | return CUDA_ERROR_INVALID_DEVICE; 663 | #endif 664 | 665 | return CUDA_SUCCESS; 666 | } 667 | 668 | -------------------------------------------------------------------------------- /src/h264_log.cpp: -------------------------------------------------------------------------------- 1 | #include "h264_log.h" 2 | 3 | static FILE *gLogFile = NULL; 4 | 5 | char gLogFileName[] = "/var/log/h264_route.log"; 6 | 7 | void H264_LogInitFile(char *fileName) { 8 | if(fileName == NULL) { 9 | printf("log filename is NULL!\n"); 10 | exit(1); 11 | } 12 | if((gLogFile = fopen(fileName, "w")) == NULL) { 13 | printf("open log file error!\n"); 14 | exit(1); 15 | } 16 | } 17 | 18 | void H264_LogCloseFile() 19 | { 20 | fclose(gLogFile); 21 | } 22 | 23 | void H264_VLog(const char* file, int line, const char *format, va_list args) { 24 | char *logStr = NULL; 25 | if(format == NULL) 26 | return; 27 | logStr = (char*)malloc(strlen(format) + 128); 28 | if(logStr) 29 | sprintf(logStr, "[FILE: %s, LINE: %d]\t\t %s\n", file, line, format); 30 | 31 | if(gLogFile != NULL) { 32 | char fileLine[256]; 33 | vsnprintf(fileLine, 255, logStr, args); 34 | fwrite(fileLine, strlen(fileLine), 1, gLogFile); 35 | fflush(gLogFile); 36 | } 37 | 38 | free(logStr); 39 | } 40 | 41 | void H264_Log(const char* file, int line, const char *format, ...) { 42 | va_list args; 43 | va_start(args, format); 44 | H264_VLog(file, line, format, args); 45 | va_end(args); 46 | } 47 | 48 | void H264_DebugLog(const char* file, int line, const char *format, ...) { 49 | #ifdef H264_DEBUGGING 50 | va_list args; 51 | va_start(args, format); 52 | H264_VLog(file, line, format, args); 53 | va_end(args); 54 | #endif 55 | } 56 | 57 | -------------------------------------------------------------------------------- /src/h264_route.cpp: -------------------------------------------------------------------------------- 1 | #ifndef _cplusplus 2 | #define _cplusplus 3 | #endif 4 | 5 | #include "h264_route.h" 6 | #include "NvEncoder.h" 7 | #include "h264_log.h" 8 | 9 | static CNvEncoder gNvEncoder; 10 | FILE* rgba = NULL; 11 | FILE* h264 = NULL; 12 | char rgbafilename[] = "/var/log/rgb"; 13 | char h264filename[] = "/var/log/h264"; 14 | //extern volatile int a; 15 | 16 | #define BITSTREAM_BUFFER_SIZE 2 * 1024 * 1024 17 | 18 | int h264_init(const int argc, ...) 19 | { 20 | #if 1 21 | if( (rgba = fopen(rgbafilename, "w")) == NULL){ 22 | NvDebugLog("foepn rgbafile error"); 23 | return -1; 24 | } 25 | if( (h264 = fopen(h264filename, "w")) == NULL){ 26 | NvDebugLog("fopen h264file error."); 27 | return -1; 28 | } 29 | #endif 30 | H264_LogInitFile(gLogFileName); 31 | return gNvEncoder.EncoderInit(argc); 32 | } 33 | 34 | int h264_route(const pixman_image_t* ppi, int argc, ...) 35 | { 36 | static int call_cnt = 0; 37 | //static unsigned long long lasttime = 0; 38 | call_cnt++; 39 | NVENCSTATUS nvStatus = NV_ENC_SUCCESS; 40 | uint8_t *pData; 41 | int curWidth = 0, curHeight = 0, oldWidth = 0, oldHeight = 0, stride = 0; 42 | unsigned long long eStart = 0, eEnd = 0, Freq = 0; 43 | NvQueryPerformanceCounter(&eStart); 44 | NvQueryPerformanceFrequency(&Freq); 45 | pixman_image_t * ncppi = const_cast(ppi); 46 | pData = (uint8_t*)pixman_image_get_data(ncppi); 47 | curWidth = pixman_image_get_width(ncppi); 48 | curHeight = pixman_image_get_height(ncppi); 49 | stride = pixman_image_get_stride(ncppi); 50 | if(!pData){ 51 | //NvDebugLog("pixman_image_get_data is NULL, curWidth:%d, curHeight:%d", curWidth, curHeight); 52 | return 0; 53 | } 54 | 55 | if(stride < 0){ 56 | pData += stride*(curHeight-1); 57 | } 58 | 59 | //NvDebugLog("curWidth: %d, curHeight: %d, stride: %d", curWidth, curHeight, stride); 60 | oldWidth = gNvEncoder.m_pNvHWEncoder->m_stCreateEncodeParams.encodeWidth; 61 | oldHeight = gNvEncoder.m_pNvHWEncoder->m_stCreateEncodeParams.encodeHeight; 62 | if(curWidth != oldWidth || curHeight != oldHeight){ 63 | //reconfig 64 | #if 0 65 | NvEncPictureCommand encPicCommand; 66 | memset(&encPicCommand, 0, sizeof(NvEncPictureCommand)); 67 | encPicCommand.bResolutionChangePending = true; 68 | encPicCommand.newWidth = curWidth; 69 | encPicCommand.newHeight = curHeight; 70 | nvStatus = gNvEncoder.m_pNvHWEncoder->NvEncReconfigureEncoder(&encPicCommand); 71 | if (nvStatus != NV_ENC_SUCCESS) 72 | { 73 | NvDebugLog("Call NvEncReconfigEncoder failed, nvStatus: %d", nvStatus); 74 | return -1; 75 | } 76 | #endif 77 | return 0; 78 | } 79 | 80 | #if 0 81 | if(call_cnt % 30 == 0){ 82 | fwrite((uint8_t *)pData, curWidth*curHeight*4, 1, rgba); 83 | } 84 | #endif 85 | nvStatus = gNvEncoder.EncodeFrame(pData, false, curWidth, curHeight); 86 | if(nvStatus != NV_ENC_SUCCESS){ 87 | NvDebugLog("EncoderFrame failed, nvStatus: %d", nvStatus); 88 | return -1; 89 | } 90 | NvQueryPerformanceCounter(&eEnd); 91 | #if 0 92 | double elapstime = (double)(eEnd-eStart); 93 | double elapstime2 = (double)((eStart-lasttime)*1000.0)/Freq; 94 | lasttime = eStart; 95 | //NvDebugLog("EncodeFrame idx: %d,FrameComeTime: %6.2fms, elapstime: %6.2fms.", call_cnt, elapstime2,(elapstime*1000.0)/Freq); 96 | printf("elapstime: %6.2fms\n", (elapstime*1000.0)/Freq); 97 | #endif 98 | return 0; 99 | } 100 | 101 | int h264_release() 102 | { 103 | NVENCSTATUS nvStatus = NV_ENC_SUCCESS; 104 | int width = 0, height = 0; 105 | width = gNvEncoder.m_pNvHWEncoder->m_stCreateEncodeParams.encodeWidth; 106 | height = gNvEncoder.m_pNvHWEncoder->m_stCreateEncodeParams.encodeHeight; 107 | nvStatus = gNvEncoder.EncodeFrame(NULL, true, width, height); 108 | if(nvStatus != NV_ENC_SUCCESS) 109 | return -1; 110 | if ( (nvStatus = gNvEncoder.Deinitialize()) != NV_ENC_SUCCESS) 111 | return -1; 112 | H264_LogCloseFile(); 113 | return 0; 114 | } 115 | 116 | int h264_init_zc(const int max_number_surface) 117 | { 118 | #if 0 119 | if( (rgba = fopen(rgbafilename, "w")) == NULL){ 120 | NvDebugLog("foepn rgbafile error"); 121 | return -1; 122 | } 123 | 124 | if( (h264 = fopen(h264filename, "w")) == NULL){ 125 | NvDebugLog("fopen h264file error."); 126 | return -1; 127 | } 128 | #endif 129 | H264_LogInitFile(gLogFileName); 130 | return gNvEncoder.EncoderInitZC(max_number_surface); 131 | } 132 | 133 | void* h264_create_mem_zc(const int stride, const int height, const int id) 134 | { 135 | NvDebugLog("create mem zc stride: %d, height: %d, id: %d", stride, height, id); 136 | //CUresult result = CUDA_SUCCESS; 137 | //NVENCSTATUS nvStatus = NV_ENC_SUCCESS; 138 | if(id >= gNvEncoder.m_stEncodeBufferPtrCnt || id < 0) 139 | { 140 | NvDebugLog("Invalid id: %d", id); 141 | return NULL; 142 | } 143 | 144 | if(gNvEncoder.m_stEncodeBufferPtrArr[id]){ 145 | NvDebugLog("this ID EncodeBuffer exit, start destroy resource."); 146 | h264_destroy_mem_zc(id); 147 | } 148 | 149 | CCudaAutoLock cuLock(gNvEncoder.m_pDevice); 150 | gNvEncoder.m_stEncodeBufferPtrArr[id] = (EncodeBufferPtr)malloc(sizeof(EncodeBuffer)); 151 | EncodeBufferPtr ebPtr = gNvEncoder.m_stEncodeBufferPtrArr[id]; 152 | if(!ebPtr) 153 | { 154 | NvDebugLog("malloc EncodeBuffer error."); 155 | return NULL; 156 | } 157 | 158 | int wstride = (stride > 0) ? stride : (-1*stride); 159 | ebPtr->stInputBfr.surfaceId = id; 160 | ebPtr->stInputBfr.dwWidth = wstride / 4; 161 | ebPtr->stInputBfr.dwHeight = height; 162 | ebPtr->stInputBfr.bufferFmt = NV_ENC_BUFFER_FORMAT_ARGB; 163 | 164 | __cur(cuMemHostAlloc((void**)&ebPtr->stInputBfr.pRGBHostPtr, wstride*height, CU_MEMHOSTALLOC_DEVICEMAP |CU_MEMHOSTALLOC_WRITECOMBINED), NULL); 165 | __cur(cuMemHostGetDevicePointer(&ebPtr->stInputBfr.pNV12devPtr, ebPtr->stInputBfr.pRGBHostPtr, 0), NULL); 166 | __nvr(gNvEncoder.m_pNvHWEncoder->NvEncRegisterResource(NV_ENC_INPUT_RESOURCE_TYPE_CUDADEVICEPTR, (void*)ebPtr->stInputBfr.pNV12devPtr, 167 | wstride*height, 1, wstride, &ebPtr->stInputBfr.nvRegisteredResource), NULL); 168 | __nvr(gNvEncoder.m_pNvHWEncoder->NvEncCreateBitstreamBuffer(BITSTREAM_BUFFER_SIZE, &ebPtr->stOutputBfr.hBitstreamBuffer), NULL); 169 | 170 | ebPtr->stOutputBfr.dwBitstreamBufferSize = BITSTREAM_BUFFER_SIZE; 171 | ebPtr->stOutputBfr.hOutputEvent = NULL; 172 | NvDebugLog("create mem success, pRGBHostPtr: %p", ebPtr->stInputBfr.pRGBHostPtr); 173 | return (void*)ebPtr->stInputBfr.pRGBHostPtr; 174 | } 175 | 176 | 177 | int h264_destroy_mem_zc(const int id) 178 | { 179 | NvDebugLog("destroy id: %d mem zc, currentUseId: %d", id, gNvEncoder.m_currentUseId); 180 | if( id < 0 || id >= gNvEncoder.m_stEncodeBufferPtrCnt){ 181 | NvDebugLog("Invalid id: %d", id); 182 | return -1; 183 | } 184 | 185 | EncodeBufferPtr ebPtr = gNvEncoder.m_stEncodeBufferPtrArr[id]; 186 | if(ebPtr == NULL){ 187 | NvDebugLog("this id's EncoderBufferPtr is NULL, return -1"); 188 | return -1; 189 | } 190 | 191 | if(id == gNvEncoder.m_currentUseId) 192 | gNvEncoder.m_currentUseId = -1; 193 | 194 | //NVENCSTATUS nvStatus = NV_ENC_SUCCESS; 195 | //CUresult result = CUDA_SUCCESS; 196 | CCudaAutoLock cuLock(gNvEncoder.m_pDevice); 197 | 198 | __nv(gNvEncoder.m_pNvHWEncoder->NvEncUnregisterResource(ebPtr->stInputBfr.nvRegisteredResource)); 199 | 200 | if(ebPtr->stInputBfr.pRGBHostPtr){ 201 | __cu(cuMemFreeHost(ebPtr->stInputBfr.pRGBHostPtr)); 202 | ebPtr->stInputBfr.pRGBHostPtr = NULL; 203 | } 204 | __nv(gNvEncoder.m_pNvHWEncoder->NvEncDestroyBitstreamBuffer(ebPtr->stOutputBfr.hBitstreamBuffer)); 205 | ebPtr->stOutputBfr.hBitstreamBuffer = NULL; 206 | 207 | free(ebPtr); 208 | gNvEncoder.m_stEncodeBufferPtrArr[id] = NULL; 209 | 210 | return 0; 211 | 212 | } 213 | 214 | int h264_route_zc(const int id) 215 | { 216 | static unsigned long long lasttime = 0; 217 | unsigned long long eStart = 0, eEnd = 0, Freq = 0; 218 | NvQueryPerformanceCounter(&eStart); 219 | NvQueryPerformanceFrequency(&Freq); 220 | NvDebugLog("h264 route zc, id: %d, currentUseId: %d", id, gNvEncoder.m_currentUseId); 221 | if(id >= gNvEncoder.m_stEncodeBufferPtrCnt || id < 0) 222 | { 223 | NvDebugLog("Invalid id: %d", id); 224 | return -1; 225 | } 226 | 227 | EncodeBufferPtr ebPtr = gNvEncoder.m_stEncodeBufferPtrArr[id]; 228 | if(ebPtr == NULL){ 229 | NvDebugLog("m_stEncodeBufferPtrArr[id] is NULL."); 230 | return -1; 231 | } 232 | 233 | if( id != gNvEncoder.m_currentUseId){ 234 | if(ebPtr->stInputBfr.dwWidth == gNvEncoder.m_pNvHWEncoder->m_uCurWidth && 235 | ebPtr->stInputBfr.dwHeight == gNvEncoder.m_pNvHWEncoder->m_uCurHeight){ 236 | NvDebugLog("id is not equal currentId, width and height not change. just make currentUseId equal id."); 237 | gNvEncoder.m_currentUseId = id; 238 | } 239 | else{ 240 | #if 0 241 | NvEncPictureCommand encPicCommand; 242 | memset(&encPicCommand, 0, sizeof(NvEncPictureCommand)); 243 | encPicCommand.bResolutionChangePending = true; 244 | encPicCommand.newWidth = ebPtr->stInputBfr.dwWidth; 245 | encPicCommand.newHeight = ebPtr->stInputBfr.dwHeight; 246 | NvDebugLog("NvEncReconfigureEncoder, width:%d, height:%d", ebPtr->stInputBfr.dwWidth, ebPtr->stInputBfr.dwHeight); 247 | __nv( gNvEncoder.m_pNvHWEncoder->NvEncReconfigureEncoder(&encPicCommand)); 248 | gNvEncoder.m_currentUseId = id; 249 | #endif 250 | return 0; 251 | } 252 | } 253 | 254 | #if 0 255 | static int i = 0; 256 | if(i<200){ 257 | fwrite((uint8_t *)ebPtr->stInputBfr.pRGBHostPtr, 1920*1080*4, 1, rgba); 258 | i++; 259 | } 260 | #endif 261 | if(gNvEncoder.m_pNvHWEncoder->m_connfd > 0) 262 | __nv(gNvEncoder.EncodeFrameZC(id)); 263 | NvDebugLog("route success."); 264 | 265 | NvQueryPerformanceCounter(&eEnd); 266 | #if 1 267 | double elapstime = (double)((eEnd-eStart)*1000.0)/Freq; 268 | double elapstime2 = (double)((eStart-lasttime)*1000.0)/Freq; 269 | lasttime = eStart; 270 | NvLog("LastFrameTime: %6.2fms, elapstime: %6.2fms.", elapstime2, elapstime); 271 | //printf("elapstime: %6.2fms\n", (elapstime*1000.0)/Freq); 272 | #endif 273 | return 0; 274 | } 275 | 276 | int h264_release_zc() 277 | { 278 | __nv( gNvEncoder.m_pNvHWEncoder->NvEncFlushEncoderQueue(gNvEncoder.m_stEOSOutputBfr.hOutputEvent)); 279 | __nv( gNvEncoder.DeinitializeZC()); 280 | H264_LogCloseFile(); 281 | return 0; 282 | } 283 | 284 | int nvenc_init(const int max_number_surface,const H264_INPUT_BUFFER_TYPE buffer_type) 285 | { 286 | #if 0 287 | char rgb_file_path[128] = {0}; 288 | char h264_file_path[128] = {0}; 289 | snprintf(rgb_file_path, 127, "/ovpdatastore/rgb_%d.rgb32", getpid()); 290 | snprintf(h264_file_path, 127, "/ovpdatastore/h264_%d.h264", getpid()); 291 | if( (rgba = fopen(rgb_file_path, "w")) == NULL){ 292 | NvDebugLog("foepn rgbafile error"); 293 | return -1; 294 | } 295 | if( (h264 = fopen(h264_file_path, "w")) == NULL){ 296 | NvDebugLog("fopen h264file error."); 297 | return -1; 298 | } 299 | #endif 300 | 301 | H264_LogInitFile(gLogFileName); 302 | gNvEncoder.m_currentBufferType = buffer_type; 303 | return gNvEncoder.EncoderInitZC(max_number_surface); 304 | } 305 | 306 | void* nvenc_create_mem(const int stride,const int height,const int id) 307 | { 308 | uint32_t lockedPitch = 0; 309 | NvDebugLog("create mem zc stride: %d, height: %d, id: %d", stride, height, id); 310 | //CUresult result = CUDA_SUCCESS; 311 | //NVENCSTATUS nvStatus = NV_ENC_SUCCESS; 312 | if(id >= gNvEncoder.m_stEncodeBufferPtrCnt || id < 0) 313 | { 314 | NvDebugLog("Invalid id: %d", id); 315 | return NULL; 316 | } 317 | 318 | if(gNvEncoder.m_stEncodeBufferPtrArr[id]){ 319 | NvDebugLog("this ID EncodeBuffer exit, start destroy resource."); 320 | h264_destroy_mem_zc(id); 321 | } 322 | 323 | CCudaAutoLock cuLock(gNvEncoder.m_pDevice); 324 | gNvEncoder.m_stEncodeBufferPtrArr[id] = (EncodeBufferPtr)malloc(sizeof(EncodeBuffer)); 325 | EncodeBufferPtr ebPtr = gNvEncoder.m_stEncodeBufferPtrArr[id]; 326 | if(!ebPtr) 327 | { 328 | NvDebugLog("malloc EncodeBuffer error."); 329 | return NULL; 330 | } 331 | 332 | int wstride = (stride > 0) ? stride : (-1*stride); 333 | ebPtr->stInputBfr.surfaceId = id; 334 | ebPtr->stInputBfr.dwWidth = wstride / 4; 335 | ebPtr->stInputBfr.dwHeight = height; 336 | ebPtr->stInputBfr.pRGBHostPtr = NULL; 337 | ebPtr->stInputBfr.bufferFmt = NV_ENC_BUFFER_FORMAT_ARGB; 338 | switch(gNvEncoder.m_currentBufferType) 339 | { 340 | case NVENC_INPUT_BUFFER: 341 | #if 0 342 | ebPtr->stInputBfr.pRGBHostPtr = (uint8_t*)malloc(wstride*height); 343 | if(!(ebPtr->stInputBfr.pRGBHostPtr)){ 344 | NvDebugLog("pRgbHostPtr malloc error."); 345 | return NULL; 346 | } 347 | __nvr(gNvEncoder.m_pNvHWEncoder->NvEncCreateInputBuffer(wstride/4, height, &ebPtr->stInputBfr.hInputSurface, ebPtr->stInputBfr.bufferFmt), NULL); 348 | #endif 349 | __nvr(gNvEncoder.m_pNvHWEncoder->NvEncCreateInputBuffer(wstride/4, height, &ebPtr->stInputBfr.hInputSurface, ebPtr->stInputBfr.bufferFmt), NULL); 350 | __nvr(gNvEncoder.m_pNvHWEncoder->NvEncLockInputBuffer(ebPtr->stInputBfr.hInputSurface, (void**)&ebPtr->stInputBfr.pRGBHostPtr, &lockedPitch),NULL); 351 | //NvLog("pRGBHostPtr: %p", ebPtr->stInputBfr.pRGBHostPtr); 352 | break; 353 | case CUDA_DEVICE_BUFFER: 354 | break; 355 | case CUDA_HOST_BUFFER: 356 | __cur(cuMemHostAlloc((void**)&ebPtr->stInputBfr.pRGBHostPtr, wstride*height, CU_MEMHOSTALLOC_DEVICEMAP |CU_MEMHOSTALLOC_WRITECOMBINED), NULL); 357 | __cur(cuMemHostGetDevicePointer(&ebPtr->stInputBfr.pNV12devPtr, ebPtr->stInputBfr.pRGBHostPtr, 0), NULL); 358 | __nvr(gNvEncoder.m_pNvHWEncoder->NvEncRegisterResource(NV_ENC_INPUT_RESOURCE_TYPE_CUDADEVICEPTR, (void*)ebPtr->stInputBfr.pNV12devPtr, 359 | wstride*height, 1, wstride, &ebPtr->stInputBfr.nvRegisteredResource), NULL); 360 | break; 361 | default: 362 | break; 363 | } 364 | 365 | __nvr(gNvEncoder.m_pNvHWEncoder->NvEncCreateBitstreamBuffer(BITSTREAM_BUFFER_SIZE, &ebPtr->stOutputBfr.hBitstreamBuffer), NULL); 366 | ebPtr->stOutputBfr.dwBitstreamBufferSize = BITSTREAM_BUFFER_SIZE; 367 | ebPtr->stOutputBfr.hOutputEvent = NULL; 368 | NvDebugLog("create mem success, pRGBHostPtr: %p", ebPtr->stInputBfr.pRGBHostPtr); 369 | return (void*)ebPtr->stInputBfr.pRGBHostPtr; 370 | } 371 | 372 | int nvenc_destroy_mem(const int id) 373 | { 374 | NvDebugLog("destroy id: %d mem zc, currentUseId: %d", id, gNvEncoder.m_currentUseId); 375 | if( id < 0 || id >= gNvEncoder.m_stEncodeBufferPtrCnt){ 376 | NvDebugLog("Invalid id: %d", id); 377 | return -1; 378 | } 379 | 380 | EncodeBufferPtr ebPtr = gNvEncoder.m_stEncodeBufferPtrArr[id]; 381 | if(ebPtr == NULL){ 382 | NvDebugLog("this id's EncoderBufferPtr is NULL, return -1"); 383 | return -1; 384 | } 385 | 386 | if(id == gNvEncoder.m_currentUseId) 387 | gNvEncoder.m_currentUseId = -1; 388 | 389 | //NVENCSTATUS nvStatus = NV_ENC_SUCCESS; 390 | //CUresult result = CUDA_SUCCESS; 391 | CCudaAutoLock cuLock(gNvEncoder.m_pDevice); 392 | 393 | switch(gNvEncoder.m_currentBufferType) 394 | { 395 | case NVENC_INPUT_BUFFER: 396 | __nv(gNvEncoder.m_pNvHWEncoder->NvEncDestroyInputBuffer(ebPtr->stInputBfr.hInputSurface)); 397 | //free(ebPtr->stInputBfr.pRGBHostPtr); 398 | break; 399 | case CUDA_DEVICE_BUFFER: 400 | break; 401 | case CUDA_HOST_BUFFER: 402 | __nv(gNvEncoder.m_pNvHWEncoder->NvEncUnregisterResource(ebPtr->stInputBfr.nvRegisteredResource)); 403 | __cu(cuMemFreeHost(ebPtr->stInputBfr.pRGBHostPtr)); 404 | break; 405 | default: 406 | break; 407 | } 408 | 409 | __nv(gNvEncoder.m_pNvHWEncoder->NvEncDestroyBitstreamBuffer(ebPtr->stOutputBfr.hBitstreamBuffer)); 410 | ebPtr->stOutputBfr.hBitstreamBuffer = NULL; 411 | 412 | free(ebPtr); 413 | gNvEncoder.m_stEncodeBufferPtrArr[id] = NULL; 414 | 415 | return 0; 416 | 417 | } 418 | 419 | 420 | int nvenc_route(const int id) 421 | { 422 | return h264_route_zc(id); 423 | } 424 | 425 | int nvenc_release() 426 | { 427 | __nv( gNvEncoder.m_pNvHWEncoder->NvEncFlushEncoderQueue(gNvEncoder.m_stEOSOutputBfr.hOutputEvent)); 428 | __nv( gNvEncoder.DeinitializeZC()); 429 | H264_LogCloseFile(); 430 | fclose(rgba); 431 | fclose(h264); 432 | return 0; 433 | } 434 | 435 | 436 | 437 | -------------------------------------------------------------------------------- /src/h264_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "h264_route.h" 5 | #include "nvFileIO.h" 6 | 7 | int main(int argc, char** argv) 8 | { 9 | char* filename = argv[1]; 10 | HANDLE hInput; 11 | DWORD filesize; 12 | struct sockaddr_in servaddr; 13 | bzero(&servaddr, sizeof(struct sockaddr_in)); 14 | inet_pton(AF_INET, "192.168.2.50", &servaddr.sin_addr); 15 | uint32_t sip = ntohl(servaddr.sin_addr.s_addr); 16 | uint16_t sport = 8000; 17 | int totalFrames = 0, width = 0, height = 0; 18 | sscanf(argv[2], "%d", &width); 19 | sscanf(argv[3], "%d", &height); 20 | hInput = nvOpenFile(filename); 21 | if (hInput == INVALID_HANDLE_VALUE) 22 | { 23 | printf("Failed to open \"%s\"\n", filename); 24 | return 1; 25 | } 26 | 27 | nvGetFileSize(hInput,&filesize); 28 | totalFrames = filesize/(width*height*4); 29 | 30 | h264_init(sip, sport, 0); 31 | 32 | int frmIdx = 0; 33 | pixman_image_t pImage; 34 | for(frmIdx = 0; frmIdx < totalFrames; frmIdx++){ 35 | 36 | } 37 | 38 | return 0; 39 | } 40 | --------------------------------------------------------------------------------