Ticket #7214: 0001-Xilinx-NGcodec-hevc-ffmpeg-plugin.patch
| File 0001-Xilinx-NGcodec-hevc-ffmpeg-plugin.patch, 230.3 KB (added by , 8 years ago) |
|---|
-
new file .gitignore
From b1af22c4b962bccc57129b21c1eebd598f3ee494 Mon Sep 17 00:00:00 2001 From: John Nichols <jnichol@xilinx.com> Date: Fri, 20 Jul 2018 16:53:02 -0700 Subject: [PATCH] Xilinx NGcodec hevc ffmpeg plugin --- .gitignore | 46 ++ ffmpeg.c | 32 +- libavcodec/Makefile | 12 + libavcodec/allcodecs.c | 2 + libavcodec/xlnx_h264/Makefile | 4 + libavcodec/xlnx_h264/h264e_csregs.c | 453 +++++++++++ libavcodec/xlnx_h264/h264e_csregs.h | 35 + libavcodec/xlnx_h264/h264e_csregs_private.h | 440 +++++++++++ libavcodec/xlnx_h264/h264e_sdaccel.c | 875 +++++++++++++++++++++ libavcodec/xlnx_h264/h264e_sdaccel.h | 146 ++++ libavcodec/xlnx_h264/h264e_sdaccel_private.h | 107 +++ libavcodec/xlnx_h264/h264e_sdaccel_utils.c | 290 +++++++ libavcodec/xlnx_h264/h264e_sdaccel_utils.h | 29 + libavcodec/xlnx_h264/hw_h264.c | 105 +++ libavcodec/xlnx_h264/xlnx_h264_config.h | 67 ++ libavcodec/xlnx_h264_enc.c | 122 +++ libavcodec/xlnx_hevc/Makefile | 1 + libavcodec/xlnx_hevc/hw_hevc.c | 363 +++++++++ libavcodec/xlnx_hevc/xlnx_hevc_config.h | 50 ++ libavcodec/xlnx_hevc_enc.c | 271 +++++++ libavcodec/xlnx_hw/Makefile | 3 + libavcodec/xlnx_hw/common/inc/xcl.h | 28 + libavcodec/xlnx_hw/common/inc/xlnx_hrm.h | 12 + libavcodec/xlnx_hw/common/inc/xlnx_hw_defines.h | 34 + libavcodec/xlnx_hw/common/inc/xlnx_queue.h | 17 + libavcodec/xlnx_hw/common/inc/xlnx_ts_queue.h | 18 + .../xlnx_hw/common/inc/xlnx_types_internal.h | 49 ++ libavcodec/xlnx_hw/common/src/xcl.c | 478 +++++++++++ libavcodec/xlnx_hw/common/src/xlnx_hrm.c | 444 +++++++++++ libavcodec/xlnx_hw/common/src/xlnx_queue.c | 86 ++ libavcodec/xlnx_hw/common/src/xlnx_ts_queue.c | 107 +++ libavcodec/xlnx_hw/hevc/Makefile | 1 + libavcodec/xlnx_hw/hevc/enc_vu9p.c | 266 +++++++ libavcodec/xlnx_hw/hevc/enc_vu9p.h | 9 + libavcodec/xlnx_hw/hevc/enc_vu9p_2c.c | 793 +++++++++++++++++++ libavcodec/xlnx_hw/hevc/enc_vu9p_2c.h | 16 + libavcodec/xlnx_hw/hevc/ku115_hevc_enc_config.h | 13 + libavcodec/xlnx_hw/hevc/vu9p_hevc_enc_config.h | 24 + libavcodec/xlnx_hw/xlnx_hw.c | 49 ++ libavcodec/xlnx_hw/xlnx_hw.h | 14 + libavcodec/xlnx_hw/xlnx_hw_types.h | 55 ++ libavutil/opencl.c | 2 +- 42 files changed, 5961 insertions(+), 7 deletions(-) create mode 100644 .gitignore create mode 100644 libavcodec/xlnx_h264/Makefile create mode 100644 libavcodec/xlnx_h264/h264e_csregs.c create mode 100644 libavcodec/xlnx_h264/h264e_csregs.h create mode 100644 libavcodec/xlnx_h264/h264e_csregs_private.h create mode 100644 libavcodec/xlnx_h264/h264e_sdaccel.c create mode 100644 libavcodec/xlnx_h264/h264e_sdaccel.h create mode 100644 libavcodec/xlnx_h264/h264e_sdaccel_private.h create mode 100644 libavcodec/xlnx_h264/h264e_sdaccel_utils.c create mode 100644 libavcodec/xlnx_h264/h264e_sdaccel_utils.h create mode 100644 libavcodec/xlnx_h264/hw_h264.c create mode 100644 libavcodec/xlnx_h264/xlnx_h264_config.h create mode 100644 libavcodec/xlnx_h264_enc.c create mode 100644 libavcodec/xlnx_hevc/Makefile create mode 100644 libavcodec/xlnx_hevc/hw_hevc.c create mode 100644 libavcodec/xlnx_hevc/xlnx_hevc_config.h create mode 100644 libavcodec/xlnx_hevc_enc.c create mode 100644 libavcodec/xlnx_hw/Makefile create mode 100755 libavcodec/xlnx_hw/common/inc/xcl.h create mode 100644 libavcodec/xlnx_hw/common/inc/xlnx_hrm.h create mode 100644 libavcodec/xlnx_hw/common/inc/xlnx_hw_defines.h create mode 100644 libavcodec/xlnx_hw/common/inc/xlnx_queue.h create mode 100644 libavcodec/xlnx_hw/common/inc/xlnx_ts_queue.h create mode 100644 libavcodec/xlnx_hw/common/inc/xlnx_types_internal.h create mode 100755 libavcodec/xlnx_hw/common/src/xcl.c create mode 100644 libavcodec/xlnx_hw/common/src/xlnx_hrm.c create mode 100644 libavcodec/xlnx_hw/common/src/xlnx_queue.c create mode 100644 libavcodec/xlnx_hw/common/src/xlnx_ts_queue.c create mode 100644 libavcodec/xlnx_hw/hevc/Makefile create mode 100644 libavcodec/xlnx_hw/hevc/enc_vu9p.c create mode 100644 libavcodec/xlnx_hw/hevc/enc_vu9p.h create mode 100644 libavcodec/xlnx_hw/hevc/enc_vu9p_2c.c create mode 100644 libavcodec/xlnx_hw/hevc/enc_vu9p_2c.h create mode 100644 libavcodec/xlnx_hw/hevc/ku115_hevc_enc_config.h create mode 100644 libavcodec/xlnx_hw/hevc/vu9p_hevc_enc_config.h create mode 100644 libavcodec/xlnx_hw/xlnx_hw.c create mode 100755 libavcodec/xlnx_hw/xlnx_hw.h create mode 100644 libavcodec/xlnx_hw/xlnx_hw_types.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0736a38
- + 1 *.a 2 *.o 3 *.o.* 4 *.d 5 *.def 6 *.dll 7 *.dylib 8 *.exe 9 *.exp 10 *.gcda 11 *.gcno 12 *.h.c 13 *.ilk 14 *.lib 15 *.pc 16 *.pdb 17 *.so 18 *.so.* 19 *.swp 20 *.ver 21 *_g 22 \#* 23 .\#* 24 /.config 25 /.version 26 /ffmpeg 27 /ffplay 28 /ffprobe 29 /ffserver 30 /config.* 31 /coverage.info 32 /avversion.h 33 /lcov/ 34 /src 35 /mapfile 36 doc/* 37 bin/* 38 include/* 39 share/* 40 build/* 41 bavcodec/bsf_list.c 42 libavformat/protocol_list.c 43 libavutil/avconfig.h 44 libavutil/ffversion.h 45 libavcodec/bsf_list.c 46 ffmpeg_build/* -
ffmpeg.c
diff --git a/ffmpeg.c b/ffmpeg.c index ea03179..b0642eb 100644
a b static void do_video_out(OutputFile *of, 1175 1175 ost->last_dropped = nb_frames == nb0_frames && next_picture; 1176 1176 1177 1177 /* duplicates frame if needed */ 1178 if (ost->enc_ctx->codec->name) { 1179 if (0 == strcmp(ost->enc_ctx->codec->name, "xlnx_hevc_enc")) { 1180 nb_frames = 1; 1181 } 1182 } 1178 1183 for (i = 0; i < nb_frames; i++) { 1179 1184 AVFrame *in_picture; 1180 1185 av_init_packet(&pkt); … … static OutputStream *choose_output(void) 3800 3805 int i; 3801 3806 int64_t opts_min = INT64_MAX; 3802 3807 OutputStream *ost_min = NULL; 3803 3808 uint64_t frames_min = UINT64_MAX; 3809 static int frame_based = 1; 3810 int all_valid_ts = 1; 3804 3811 for (i = 0; i < nb_output_streams; i++) { 3805 3812 OutputStream *ost = output_streams[i]; 3806 3813 int64_t opts = ost->st->cur_dts == AV_NOPTS_VALUE ? INT64_MIN : … … static OutputStream *choose_output(void) 3809 3816 if (ost->st->cur_dts == AV_NOPTS_VALUE) 3810 3817 av_log(NULL, AV_LOG_DEBUG, "cur_dts is invalid (this is harmless if it occurs once at the start per stream)\n"); 3811 3818 3812 if (!ost->initialized && !ost->inputs_done) 3819 if (!ost->initialized && !ost->inputs_done) { 3813 3820 return ost; 3814 3815 if (!ost->finished && opts < opts_min) {3816 opts_min = opts;3817 ost_min = ost->unavailable ? NULL : ost;3818 3821 } 3822 if (frame_based && (!strcmp(ost->enc_ctx->codec->name, "xlnx_hevc_enc"))) { 3823 if (!ost->finished && ost->frames_encoded < frames_min) { 3824 frames_min = ost->frames_encoded; 3825 ost_min = ost->unavailable ? NULL : ost; 3826 } 3827 if (opts == INT64_MIN) { 3828 all_valid_ts = 0; 3829 } 3830 } else { 3831 if (!ost->finished && opts < opts_min) { 3832 opts_min = opts; 3833 ost_min = ost->unavailable ? NULL : ost; 3834 } 3835 } 3836 } 3837 if (frame_based && all_valid_ts) { 3838 frame_based = 0; 3819 3839 } 3820 3840 return ost_min; 3821 3841 } -
libavcodec/Makefile
diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 0dd0c7b..64b3cad 100644
a b OBJS = allcodecs.o \ 49 49 utils.o \ 50 50 vorbis_parser.o \ 51 51 xiph.o \ 52 xlnx_h264/hw_h264.o \ 53 xlnx_h264/h264e_csregs.o \ 54 xlnx_h264/h264e_sdaccel.o \ 55 xlnx_h264/h264e_sdaccel_utils.o 52 56 53 57 # subsystems 54 58 OBJS-$(CONFIG_AANDCTTABLES) += aandcttab.o … … OBJS-$(CONFIG_PBM_DECODER) += pnmdec.o pnm.o 454 458 OBJS-$(CONFIG_PBM_ENCODER) += pnmenc.o 455 459 OBJS-$(CONFIG_PCX_DECODER) += pcx.o 456 460 OBJS-$(CONFIG_PCX_ENCODER) += pcxenc.o 461 OBJS-$(CONFIG_XLNX_H264_ENCODER) += xlnx_h264_enc.o 457 462 OBJS-$(CONFIG_PGM_DECODER) += pnmdec.o pnm.o 458 463 OBJS-$(CONFIG_PGM_ENCODER) += pnmenc.o 459 464 OBJS-$(CONFIG_PGMYUV_DECODER) += pnmdec.o pnm.o … … OBJS-$(CONFIG_LIBX265_ENCODER) += libx265.o 916 921 OBJS-$(CONFIG_LIBXAVS_ENCODER) += libxavs.o 917 922 OBJS-$(CONFIG_LIBXVID_ENCODER) += libxvid.o 918 923 OBJS-$(CONFIG_LIBZVBI_TELETEXT_DECODER) += libzvbi-teletextdec.o ass.o 924 OBJS-$(CONFIG_XLNX_HEVC_ENCODER) += xlnx_hevc_enc.o xlnx_hw/xlnx_hw.o \ 925 xlnx_hw/common/src/xlnx_hrm.o \ 926 xlnx_hw/common/src/xcl.o \ 927 xlnx_hw/common/src/xlnx_queue.o \ 928 xlnx_hw/common/src/xlnx_ts_queue.o \ 929 xlnx_hw/hevc/enc_vu9p.o \ 930 xlnx_hw/hevc/enc_vu9p_2c.o 919 931 920 932 # parsers 921 933 OBJS-$(CONFIG_AAC_LATM_PARSER) += latm_parser.o -
libavcodec/allcodecs.c
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 4df4772..a20a76c 100644
a b static void register_all(void) 673 673 REGISTER_ENCODER(VP8_VAAPI, vp8_vaapi); 674 674 REGISTER_DECODER(VP9_CUVID, vp9_cuvid); 675 675 REGISTER_DECODER(VP9_MEDIACODEC, vp9_mediacodec); 676 REGISTER_ENCODER(XLNX_HEVC, xlnx_hevc); 677 REGISTER_ENCODER(XLNX_H264, xlnx_h264); 676 678 677 679 /* parsers */ 678 680 REGISTER_PARSER(AAC, aac); -
new file libavcodec/xlnx_h264/Makefile
diff --git a/libavcodec/xlnx_h264/Makefile b/libavcodec/xlnx_h264/Makefile new file mode 100644 index 0000000..7ca5338
- + 1 OBJS += xlnx_h264/hw_h264.o \ 2 xlnx_h264/h264e_csregs.o \ 3 xlnx_h264/h264e_sdaccel.o \ 4 xlnx_h264/h264e_sdaccel_utils.o -
new file libavcodec/xlnx_h264/h264e_csregs.c
diff --git a/libavcodec/xlnx_h264/h264e_csregs.c b/libavcodec/xlnx_h264/h264e_csregs.c new file mode 100644 index 0000000..dd35da0
- + 1 /* 2 -- Copyright notice: 3 -- Copyright (c) 2017 Alma Technologies S.A. 4 -- www.alma-technologies.com 5 -- All rights reserved worldwide. 6 7 -- This copy is made available under the terms of the GNU General Public 8 -- License version 2.1 as published by the Free Software Foundation; either 9 -- version 2.1 of the License, or (at your option) any later version. 10 -- 11 -- This copy is distributed in the hope that it will be useful, 12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of 13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Please See the GNU 14 -- General Public License for more details. 15 -- 16 -- You should have received a copy of the GNU General Public 17 -- License along with FFmpeg; if not, write to the Free Software 18 -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #include <stdio.h> 22 #include "h264e_csregs.h" 23 #include "h264e_csregs_private.h" 24 25 void h264eSetControlRegsDefaults(H264E_CFG_PVT* ph264eCFG); 26 void h264eSetReg(uint *puiRegFile, int regOffs, int regFieldHI, int regFieldLO, int regFieldVal); 27 uint h264eGetReg(uint *puiRegFile, int regOffs, int regFieldHI, int regFieldLO); 28 29 void h264ePrintStatusRegs(int* pRegFile) 30 { 31 for(int i = 0; i < 64; i++) 32 { 33 H264EMSG(printf("H264-E CORE STATUS[0x%.2X] = 0x%.8X\n", i, pRegFile[i])); 34 } 35 return; 36 } 37 38 void h264ePrintControlRegs(int* pRegFile) 39 { 40 for(int i = 0; i < 64; i++) 41 { 42 H264EMSG(printf("CREG[0x%.2X] = 0x%.8X\n", i, pRegFile[i])); 43 } 44 return; 45 } 46 47 int h264eGetNalSize(int* pRegFile) 48 { 49 return pRegFile[CSREG_PICLEN]; 50 } 51 52 int h264eGetErrorCode(int* pRegFile) 53 { 54 return pRegFile[CSREG_ERRID]; 55 } 56 57 int h264eGetDbgStatus(int* pRegFile) 58 { 59 return pRegFile[CSREG_DEBUG]; 60 } 61 62 void h264eSetControlRegs(H264E_USR* ph264eUsr, char* CRegsFile) 63 { 64 H264E_CFG_PVT h264eCFGPvt; 65 H264E_CFG_PVT* ph264eCFG; 66 if(!ph264eUsr->bUseUserContextAsCfg) 67 { 68 ph264eCFG = &h264eCFGPvt; 69 h264eSetControlRegsDefaults(ph264eCFG); 70 ph264eCFG->X = ph264eUsr->FrameX; 71 ph264eCFG->Y = ph264eUsr->FrameY; 72 if(ph264eUsr->HWOptimizeScanFormat) 73 { 74 ph264eCFG->VInputFormat = ph264eUsr->ScanFormat == H264E_MACROBLOCK ? 0 : 2; 75 } 76 else 77 { 78 ph264eCFG->VInputFormat = ph264eUsr->ScanFormat == H264E_MACROBLOCK ? 0 : 79 ph264eUsr->ScanFormat == H264E_PLANAR_PACKED ? 1 : 80 ph264eUsr->ScanFormat == H264E_PLANAR_SEPARATED ? 1 : 2; 81 } 82 ph264eCFG->Timescale = ph264eUsr->Timescale; 83 ph264eCFG->NUIT = ph264eUsr->Nuit; 84 ph264eCFG->Level = ph264eUsr->Level; 85 ph264eCFG->IPeriod = ph264eUsr->GOPLength == -1 ? ph264eCFG->IPeriod : ph264eUsr->GOPLength; 86 ph264eCFG->IRefColumns = ph264eUsr->IntraRefreshCol == -1 ? ph264eCFG->IRefColumns : ph264eUsr->IntraRefreshCol; 87 ph264eCFG->nMBRowsInSliceReq = ph264eUsr->MBRowsPerSlice == -1 ? ph264eCFG->nMBRowsInSliceReq : ph264eUsr->MBRowsPerSlice; 88 ph264eCFG->UseDeBlockingFilter = ph264eUsr->DeblockingFilter == -1 ? ph264eCFG->UseDeBlockingFilter : 89 ph264eUsr->DeblockingFilter == 0 ? 0 : 90 ph264eUsr->DBRestrict == 1 ? 2 : 1; 91 ph264eCFG->InterMVSliceRestrict = ph264eUsr->MVRestrict == -1 ? ph264eCFG->InterMVSliceRestrict : (bool)ph264eUsr->MVRestrict; 92 ph264eCFG->QPI = ph264eUsr->QPI == -1 ? ph264eCFG->QPI : ph264eUsr->QPI; 93 ph264eCFG->QPP = ph264eUsr->QPP == -1 ? ph264eCFG->QPP : ph264eUsr->QPP; 94 ph264eCFG->QPChrOffs = ph264eUsr->QPChrOffset == -1 ? ph264eCFG->QPChrOffs : ph264eUsr->QPChrOffset; 95 ph264eCFG->Rate = ph264eUsr->Bitrate; 96 ph264eCFG->nMBsInBasicUnit = ph264eUsr->BUSize == -1 ? ph264eCFG->nMBsInBasicUnit : ph264eUsr->BUSize; 97 ph264eCFG->FIFOSize = ph264eUsr->RCFIFOSize == -1 ? ph264eCFG->FIFOSize : ph264eUsr->RCFIFOSize; 98 ph264eCFG->bCABAC = ph264eUsr->UseCABAC == -1 ? ph264eCFG->bCABAC : (bool)ph264eUsr->UseCABAC; 99 } 100 else 101 { 102 ph264eCFG = (H264E_CFG_PVT*)ph264eUsr->UserContext; 103 if(ph264eUsr->HWOptimizeScanFormat) 104 { 105 ph264eCFG->VInputFormat = ph264eUsr->ScanFormat == H264E_MACROBLOCK ? 0 : 2; 106 } 107 if(ph264eCFG->VInputFormat == 2 && ph264eCFG->UseFrameBuffer) 108 { 109 ph264eCFG->VInputFormat = 3; 110 } 111 } 112 uint vidinres_reg; 113 uint vidinscan_reg; 114 uint vidints_reg; 115 uint vidinuit_reg; 116 uint vidinlevel_reg; 117 uint vidinvuist_reg; 118 uint gopattr_reg; 119 uint sliceattr_reg; 120 uint qpsliceattr_reg; 121 uint rcattr_reg; 122 uint rcqplims_reg; 123 uint rcxopts_reg; 124 uint predattr_reg; 125 uint encopts_reg; 126 uint xpredattr_reg; 127 uint xrcxopts_reg; 128 uint xrcxopts_pid_reg[5]; 129 uint instruction_reg; 130 uint xtmemptr_reg; 131 static const int LevelLUT[52] = { 132 0, 0, 0, 0, 0, 0, 0, 0, /* 0-7 */ 133 0, 1, 0, 2, /* 8-11 */ 134 3, 4, 0, 0, 0, 0, 0, 0, /* 12-19 */ 135 5, 6, 7, 0, 0, 0, 0, 0, /* 20-27 */ 136 0, 0, 8, 9,10, 0, 0, 0, /* 28-35 */ 137 0, 0, 0, 0,11,12,13, 0, /* 36-43 */ 138 0, 0, 0, 0, 0, 0,14,15 /* 44-51 */ 139 }; 140 vidinres_reg = 0; 141 h264eSetReg(&vidinres_reg, 0, FRAME_X_HI, FRAME_X_LO, ph264eCFG->X); 142 h264eSetReg(&vidinres_reg, 0, FRAME_Y_HI, FRAME_Y_LO, ph264eCFG->Y * (ph264eCFG->bInterlaced ? 2 : 1)); 143 vidinscan_reg = 0; 144 #ifdef USE_UHT_CORE 145 h264eSetReg(&vidinscan_reg, 0, SCAN_FORMAT_HI, SCAN_FORMAT_LO, ph264eCFG->csp); 146 #else 147 h264eSetReg(&vidinscan_reg, 0, SCAN_FORMAT_HI, SCAN_FORMAT_LO, (ph264eCFG->csp == YUV420 ? ph264eCFG->VInputFormat : 4 + ph264eCFG->VInputFormat)); 148 #endif 149 h264eSetReg(&vidinscan_reg, 0, PSP_HI, PSP_LO, ph264eCFG->bpp); 150 h264eSetReg(&vidinscan_reg, 0, FRAMEDROP_FLAG, FRAMEDROP_FLAG, (int) ph264eCFG->bFrameDrop); 151 vidints_reg = 0; 152 h264eSetReg(&vidints_reg, 0, TIMESCALE_HI, TIMESCALE_LO, ph264eCFG->Timescale); 153 vidinuit_reg = 0; 154 h264eSetReg(&vidinuit_reg, 0, NUIT_HI, NUIT_LO, ph264eCFG->NUIT); 155 vidinlevel_reg = 0; 156 h264eSetReg(&vidinlevel_reg, 0, LEVEL_HI, LEVEL_LO, LevelLUT[ph264eCFG->Level]); 157 vidinvuist_reg = 0; 158 h264eSetReg(&vidinvuist_reg, 0, V_VIDEO_SIGNAL_TYPE_PRESENT_FLAG, V_VIDEO_SIGNAL_TYPE_PRESENT_FLAG, (ph264eCFG->VUI_VideoFormat > 0 || ph264eCFG->VUI_VideoFullRangeFlag ? 1 : 0)); 159 h264eSetReg(&vidinvuist_reg, 0, V_VIDEO_FORMAT_HI, V_VIDEO_FORMAT_LO, (ph264eCFG->VUI_VideoFormat > 0 ? ph264eCFG->VUI_VideoFormat : 0)); 160 h264eSetReg(&vidinvuist_reg, 0, V_VIDEO_FULL_RANGE_FLAG, V_VIDEO_FULL_RANGE_FLAG, ph264eCFG->VUI_VideoFullRangeFlag); 161 gopattr_reg = 0; 162 if (ph264eCFG->IPeriod == 0xFFFFFFFF) 163 { 164 h264eSetReg(&gopattr_reg, 0, IPERIOD_HI, IPERIOD_LO, 0); 165 } 166 else 167 { 168 h264eSetReg(&gopattr_reg, 0, IPERIOD_HI, IPERIOD_LO, ph264eCFG->IPeriod); 169 } 170 h264eSetReg(&gopattr_reg, 0, IREFCOLS_HI, IREFCOLS_LO, ph264eCFG->IRefColumns); 171 sliceattr_reg = 0; 172 h264eSetReg(&sliceattr_reg, 0, SLICE_MBROWS_HI, SLICE_MBROWS_L0, ph264eCFG->nMBRowsInSliceReq); 173 h264eSetReg(&sliceattr_reg, 0, DB_EN_FLAG, DB_EN_FLAG, ph264eCFG->UseDeBlockingFilter > 0 ? 1 : 0); 174 #ifndef USE_UHT_CORE 175 h264eSetReg(&sliceattr_reg, 0, DB_SLCBNDRS_FLAG, DB_SLCBNDRS_FLAG, ph264eCFG->UseDeBlockingFilter == 2 ? 1 : 0); 176 #endif 177 h264eSetReg(&sliceattr_reg, 0, DB_ALPHA_HI, DB_ALPHA_LO, ph264eCFG->sliceAlphaOffset); 178 h264eSetReg(&sliceattr_reg, 0, DB_BETA_HI, DB_BETA_LO, ph264eCFG->sliceBetaOffset); 179 #ifndef USE_UHT_CORE 180 h264eSetReg(&sliceattr_reg, 0, INTERSLICECROSS_FLAG, INTERSLICECROSS_FLAG, (int) ph264eCFG->InterMVSliceRestrict); 181 #endif 182 qpsliceattr_reg = 0; 183 h264eSetReg(&qpsliceattr_reg, 0, QPINIT_I_HI, QPINIT_I_LO, ph264eCFG->QPI + ph264eCFG->QpBdOffset); 184 h264eSetReg(&qpsliceattr_reg, 0, QPINIT_P_HI, QPINIT_P_LO, ph264eCFG->QPP + ph264eCFG->QpBdOffset); 185 h264eSetReg(&qpsliceattr_reg, 0, QPCHROFFS_HI, QPCHROFFS_LO, ph264eCFG->QPChrOffs); 186 h264eSetReg(&qpsliceattr_reg, 0, QPTHR_HI, QPTHR_LO, ph264eCFG->bTQThresholding ? 1 : 0); 187 rcattr_reg = 0; 188 h264eSetReg(&rcattr_reg, 0, RCBITRATE_HI, RCBITRATE_LO, ph264eCFG->Rate >> 3); 189 h264eSetReg(&rcattr_reg, 0, RCMAXBITRATE_HI, RCMAXBITRATE_LO, ph264eCFG->MaxRate >> 3); 190 rcqplims_reg = 0; 191 h264eSetReg(&rcqplims_reg, 0, QPI_MIN_HI, QPI_MIN_LO, ph264eCFG->QPI_min + ph264eCFG->QpBdOffset); 192 h264eSetReg(&rcqplims_reg, 0, QPI_MAX_HI, QPI_MAX_LO, ph264eCFG->QPI_max + ph264eCFG->QpBdOffset); 193 h264eSetReg(&rcqplims_reg, 0, QPP_MIN_HI, QPP_MIN_LO, ph264eCFG->QPP_min + ph264eCFG->QpBdOffset); 194 h264eSetReg(&rcqplims_reg, 0, QPP_MAX_HI, QPP_MAX_LO, ph264eCFG->QPP_max + ph264eCFG->QpBdOffset); 195 rcxopts_reg = 0; 196 h264eSetReg(&rcxopts_reg, 0, BUSIZE_HI, BUSIZE_LO, (ph264eCFG->nMBsInBasicUnit < 0 ? 0 : ph264eCFG->nMBsInBasicUnit)); 197 if (ph264eCFG->RCMethod == RCM_PID) 198 { 199 h264eSetReg(&rcxopts_reg, 0, RCPERIOD_HI, RCPERIOD_LO, ph264eCFG->FIFOSize >> 3); 200 } 201 else 202 { 203 h264eSetReg(&rcxopts_reg, 0, RCPERIOD_HI, RCPERIOD_LO, ph264eCFG->RCPeriod); 204 } 205 encopts_reg = 0; 206 h264eSetReg(&encopts_reg, 0, CABAC_FLAG, CABAC_FLAG, (int) ph264eCFG->bCABAC); 207 h264eSetReg(&encopts_reg, 0, FLUSHFRAME_FLAG, FLUSHFRAME_FLAG, 1); 208 h264eSetReg(&encopts_reg, 0, NALTRZWORD_FLAG, NALTRZWORD_FLAG, (ph264eCFG->NALTrZeros == 2 ? 1 : 0)); 209 #ifdef USE_UHT_CORE 210 h264eSetReg(&encopts_reg, 0, ACTCENGS_HI, ACTCENGS_LO, (int) ph264eCFG->nCEngines); 211 #endif 212 predattr_reg = 0; 213 h264eSetReg(&predattr_reg, 0, MEVBS_P16X16_FLAG, MEVBS_P16X16_FLAG, ph264eCFG->bVBSEnableMask[0]); 214 h264eSetReg(&predattr_reg, 0, MEVBS_P16X8_FLAG, MEVBS_P16X8_FLAG, ph264eCFG->bInterVBSenable & ph264eCFG->bVBSEnableMask[1]); 215 h264eSetReg(&predattr_reg, 0, MEVBS_P8X16_FLAG, MEVBS_P8X16_FLAG, ph264eCFG->bInterVBSenable & ph264eCFG->bVBSEnableMask[2]); 216 h264eSetReg(&predattr_reg, 0, MEVBS_P8X8_FLAG, MEVBS_P8X8_FLAG, ph264eCFG->bInterVBSenable & ph264eCFG->bVBSEnableMask[3]); 217 h264eSetReg(&predattr_reg, 0, MEPXLAC_HI, MEPXLAC_LO, ph264eCFG->InterAccuracy/2); 218 h264eSetReg(&predattr_reg, 0, XTRACOST_FLAG, XTRACOST_FLAG, !ph264eCFG->bVBSOptions[VBS_USE_XTRA_PART_COST]); 219 h264eSetReg(&predattr_reg, 0, XTRACOSTP8x8_FLAG, XTRACOSTP8x8_FLAG, ph264eCFG->bVBSOptions[VBS_USE_XTRA_PART_COST_P8x8]); 220 h264eSetReg(&predattr_reg, 0, INTRA_IN_P_FLAG, INTRA_IN_P_FLAG, ph264eCFG->bUseIntraInInter); 221 h264eSetReg(&predattr_reg, 0, I16x16_FLAG, I16x16_FLAG, !ph264eCFG->bI16x16Dis); 222 h264eSetReg(&predattr_reg, 0, I4x4_FLAG, I4x4_FLAG, !ph264eCFG->bI4x4Dis); 223 int i, mask; 224 for (mask=0, i=0; i<4; i++) mask |= ((int) ph264eCFG->bIntraLuma16x16Mask[i]) << i; 225 h264eSetReg(&predattr_reg, 0, I16x16_MASK_HI, I16x16_MASK_LO, mask); 226 for (mask=0, i=0; i<4; i++) mask |= ((int) ph264eCFG->bIntraChromaMask[i]) << i; 227 h264eSetReg(&predattr_reg, 0, ICHR_MASK_HI, ICHR_MASK_LO, mask); 228 for (mask=0, i=0; i<9; i++) mask |= ((int) ph264eCFG->bIntraLuma4x4Mask[i]) << i; 229 h264eSetReg(&predattr_reg, 0, I4x4_MASK_HI, I4x4_MASK_LO, mask); 230 xpredattr_reg = 0; 231 h264eSetReg(&xpredattr_reg, 0, SRX_HI, SRX_LO, ph264eCFG->InterSearchRangeWidth/8); 232 h264eSetReg(&xpredattr_reg, 0, SRY_HI, SRY_LO, ph264eCFG->InterSearchRangeHeight/2); 233 h264eSetReg(&xpredattr_reg, 0, VIMPW_HI, VIMPW_LO, ph264eCFG->MPPriorities[0]); 234 h264eSetReg(&xpredattr_reg, 0, VIMPR_HI, VIMPR_LO, ph264eCFG->MPPriorities[1]); 235 h264eSetReg(&xpredattr_reg, 0, VOMPW_HI, VOMPW_LO, ph264eCFG->MPPriorities[2]); 236 h264eSetReg(&xpredattr_reg, 0, REFWR_HI, REFWR_LO, ph264eCFG->MPPriorities[3]); 237 xrcxopts_reg = 0; 238 h264eSetReg(&xrcxopts_reg, 0, QPADJSTRENGTH_HI, QPADJSTRENGTH_LO, ph264eCFG->AQStrength); 239 h264eSetReg(&xrcxopts_reg, 0, USEINITQP_FLAG, USEINITQP_FLAG, ph264eCFG->bRcExtraOpt[0]); 240 h264eSetReg(&xrcxopts_reg, 0, USESCENECUT_FLAG, USESCENECUT_FLAG, ph264eCFG->bRcExtraOpt[1]); 241 h264eSetReg(&xrcxopts_reg, 0, USERCOVERDUE_FLAG, USERCOVERDUE_FLAG, ph264eCFG->bRcExtraOpt[2]); 242 h264eSetReg(&xrcxopts_reg, 0, STRICTCBR_FLAG, STRICTCBR_FLAG, ph264eCFG->bRcExtraOpt[3]); 243 h264eSetReg(&xrcxopts_reg, 0, DISMADTH_FLAG, DISMADTH_FLAG, ph264eCFG->bRcExtraOpt[4]); 244 h264eSetReg(&xrcxopts_reg, 0, VBRF_HI, VBRF_LO, ph264eCFG->rcVbrFactor); 245 h264eSetReg(&xrcxopts_reg, 0, ICPBRDFR_HI, ICPBRDFR_LO, ph264eCFG->initialCbpRdInfr); 246 for (int i=0; i<5; i++) 247 { 248 xrcxopts_pid_reg[i] = ph264eCFG->xrcxopts_pid[i]; 249 } 250 instruction_reg = 0; 251 h264eSetReg(&instruction_reg, 0, SWCLR_FLAG, SWCLR_FLAG, 0); 252 h264eSetReg(&instruction_reg, 0, SWSUSPEND_FLAG, SWSUSPEND_FLAG, 0); 253 xtmemptr_reg = 0; 254 h264eSetReg(&xtmemptr_reg, 0, XTMEMPTR_HI, XTMEMPTR_LO, ph264eCFG->XtmemPtr); 255 h264eSetReg((uint*)CRegsFile, CSREG_VIDINRES, 31, 0, vidinres_reg); 256 h264eSetReg((uint*)CRegsFile, CSREG_VIDINSCAN, 31, 0, vidinscan_reg); 257 h264eSetReg((uint*)CRegsFile, CSREG_VIDINTS, 31, 0, vidints_reg); 258 h264eSetReg((uint*)CRegsFile, CSREG_VIDINUIT, 31, 0, vidinuit_reg); 259 h264eSetReg((uint*)CRegsFile, CSREG_VIDINLEVEL, 31, 0, vidinlevel_reg); 260 h264eSetReg((uint*)CRegsFile, CSREG_VIDINVUIST, 31, 0, vidinvuist_reg); 261 h264eSetReg((uint*)CRegsFile, CSREG_GOPATTR, 31, 0, gopattr_reg); 262 h264eSetReg((uint*)CRegsFile, CSREG_SLICEATTR, 31, 0, sliceattr_reg); 263 h264eSetReg((uint*)CRegsFile, CSREG_QPSLICEATTR, 31, 0, qpsliceattr_reg); 264 h264eSetReg((uint*)CRegsFile, CSREG_RCATTR, 31, 0, rcattr_reg); 265 h264eSetReg((uint*)CRegsFile, CSREG_RCQPLIMS, 31, 0, rcqplims_reg); 266 h264eSetReg((uint*)CRegsFile, CSREG_RCXOPTS, 31, 0, rcxopts_reg); 267 h264eSetReg((uint*)CRegsFile, CSREG_PREDATTR, 31, 0, predattr_reg); 268 h264eSetReg((uint*)CRegsFile, CSREG_ENCOPTS, 31, 0, encopts_reg); 269 h264eSetReg((uint*)CRegsFile, CSREG_XPREDATTR, 31, 0, xpredattr_reg); 270 h264eSetReg((uint*)CRegsFile, CSREG_XRCXOPTS, 31, 0, xrcxopts_reg); 271 h264eSetReg((uint*)CRegsFile, CSREG_INSTRUCTION, 31, 0, instruction_reg); 272 h264eSetReg((uint*)CRegsFile, CSREG_XTMEMPTR, 31, 0, xtmemptr_reg); 273 h264eSetReg((uint*)CRegsFile, CSREG_XRCXOPTS_PID0, 31, 0, xrcxopts_pid_reg[0]); 274 h264eSetReg((uint*)CRegsFile, CSREG_XRCXOPTS_PID1, 31, 0, xrcxopts_pid_reg[1]); 275 h264eSetReg((uint*)CRegsFile, CSREG_XRCXOPTS_PID2, 31, 0, xrcxopts_pid_reg[2]); 276 h264eSetReg((uint*)CRegsFile, CSREG_XRCXOPTS_PID3, 31, 0, xrcxopts_pid_reg[3]); 277 h264eSetReg((uint*)CRegsFile, CSREG_XRCXOPTS_PID4, 31, 0, xrcxopts_pid_reg[4]); 278 if(ph264eCFG->PrintControlRegisters) 279 { 280 h264ePrintControlRegs((int*)CRegsFile); 281 } 282 return; 283 } 284 285 void h264eSetControlRegsDefaults(H264E_CFG_PVT* ph264eCFG) 286 { 287 ph264eCFG->X = 1280; 288 ph264eCFG->Y = 720; 289 ph264eCFG->bInterlaced = false; 290 ph264eCFG->VInputFormat = VIPLANAR; 291 ph264eCFG->bpp = 8; 292 ph264eCFG->csp = YUV420; 293 ph264eCFG->Timescale = 50000; 294 ph264eCFG->NUIT = 1000; 295 ph264eCFG->Level = 31; 296 ph264eCFG->QPI = 25; 297 ph264eCFG->QPP = 25; 298 ph264eCFG->QPChrOffs = 0; 299 ph264eCFG->QpBdOffset = 0; 300 ph264eCFG->bTQThresholding = true; 301 ph264eCFG->UseDeBlockingFilter = 1; 302 ph264eCFG->sliceAlphaOffset = 0; 303 ph264eCFG->sliceBetaOffset = 0; 304 ph264eCFG->nMBRowsInSliceReq = 0; 305 ph264eCFG->InterSearchRangeWidth = 32; 306 ph264eCFG->InterSearchRangeHeight = 20; 307 ph264eCFG->InterAccuracy = 4; 308 ph264eCFG->InterMVSliceRestrict = false; 309 ph264eCFG->bInterVBSenable = true; 310 ph264eCFG->bUseIntraInInter = true; 311 ph264eCFG->NALTrZeros = 0; 312 ph264eCFG->NALFlushOnFrame = 1; 313 ph264eCFG->bFrameDrop = false; 314 ph264eCFG->VUI_VideoFormat = -1; 315 ph264eCFG->VUI_VideoFullRangeFlag = 0; 316 #ifdef USE_CABAC 317 ph264eCFG->bCABAC = true; 318 #else 319 ph264eCFG->bCABAC = false; 320 #endif 321 ph264eCFG->AQStrength = 4; 322 ph264eCFG->XtmemPtr = 0; 323 ph264eCFG->nCEngines = 1; 324 ph264eCFG->MPPriorities[0] = 3; 325 ph264eCFG->MPPriorities[1] = 2; 326 ph264eCFG->MPPriorities[2] = 1; 327 ph264eCFG->MPPriorities[3] = 1; 328 ph264eCFG->Rate = 0; 329 ph264eCFG->FIFOSize = 0; 330 ph264eCFG->MaxRate = 0; 331 ph264eCFG->nMBsInBasicUnit = 0; 332 ph264eCFG->RCPeriod = 0; 333 ph264eCFG->QPI_min = 0; 334 ph264eCFG->QPI_max = 51; 335 ph264eCFG->QPP_min = 0; 336 ph264eCFG->QPP_max = 51; 337 ph264eCFG->IPeriod = 30; 338 ph264eCFG->IRefColumns = 0; 339 ph264eCFG->RCMethod = RCM_PID; 340 ph264eCFG->initialCbpRdInfr = 0; 341 ph264eCFG->rcVbrFactor = 16; 342 for (int i = 1; i < RC_EXTRA_OPT_MASK_WIDTH; i++) 343 { 344 ph264eCFG->bRcExtraOpt[i] = false; 345 } 346 for(int i = 0; i < 7; i++) 347 { 348 if(i < 4) 349 { 350 ph264eCFG->bVBSEnableMask[i] = true; 351 } 352 else 353 { 354 ph264eCFG->bVBSEnableMask[i] = false; 355 } 356 if(i < 5) 357 { 358 ph264eCFG->bVBSOptions[i] = true; 359 } 360 else 361 { 362 ph264eCFG->bVBSOptions[i] = false; 363 } 364 } 365 ph264eCFG->bVBSOptions[3] = false; 366 ph264eCFG->bI16x16Dis = 0; 367 ph264eCFG->bI4x4Dis = false; 368 for(int i = 0; i < 9; i++) 369 { 370 if(i < 4) 371 { 372 ph264eCFG->bIntraLuma16x16Mask[i] = true; 373 ph264eCFG->bIntraChromaMask[i] = true; 374 } 375 ph264eCFG->bIntraLuma4x4Mask[i] = true; 376 } 377 h264eSetReg(&ph264eCFG->xrcxopts_pid[0], 0, PID_KU_IONPY_HI, PID_KU_IONPY_LO, PID_KU_IONPY); 378 h264eSetReg(&ph264eCFG->xrcxopts_pid[0], 0, PID_KU_IP_HI, PID_KU_IP_LO, PID_KU_IP); 379 h264eSetReg(&ph264eCFG->xrcxopts_pid[0], 0, PID_KI_UPD_IONPY_HI, PID_KI_UPD_IONPY_LO, PID_KI_UPD_IONPY); 380 h264eSetReg(&ph264eCFG->xrcxopts_pid[0], 0, PID_KI_UPD_IP_HI, PID_KI_UPD_IP_LO, PID_KI_UPD_IP); 381 h264eSetReg(&ph264eCFG->xrcxopts_pid[0], 0, PID_USE_IBU_THR_FLAG, PID_USE_IBU_THR_FLAG, PID_USE_IBU_THR); 382 h264eSetReg(&ph264eCFG->xrcxopts_pid[0], 0, PID_FIFO_STATUS_TARGET_HI, PID_FIFO_STATUS_TARGET_LO, PID_FIFO_STATUS_TARGET); 383 h264eSetReg(&ph264eCFG->xrcxopts_pid[1], 0, PID_USE_COLOCATED_FLAG, PID_USE_COLOCATED_FLAG, PID_USE_COLOCATED); 384 h264eSetReg(&ph264eCFG->xrcxopts_pid[1], 0, PID_IFRAME_BUFFER_FACTOR_HI, PID_IFRAME_BUFFER_FACTOR_LO, PID_IFRAME_BUFFER_FACTOR); 385 h264eSetReg(&ph264eCFG->xrcxopts_pid[1], 0, PID_QP_STEP_FR_HI, PID_QP_STEP_FR_LO, PID_QP_STEP_FR); 386 h264eSetReg(&ph264eCFG->xrcxopts_pid[1], 0, PID_QP_STEP_IBU_HI, PID_QP_STEP_IBU_LO, PID_QP_STEP_IBU); 387 h264eSetReg(&ph264eCFG->xrcxopts_pid[1], 0, PID_FSTATUS_0_HI, PID_FSTATUS_0_LO, PID_FSTATUS_0); 388 h264eSetReg(&ph264eCFG->xrcxopts_pid[1], 0, PID_THRFRMLIM_0_FLAG, PID_THRFRMLIM_0_FLAG, PID_THRFRMLIM_0); 389 h264eSetReg(&ph264eCFG->xrcxopts_pid[1], 0, PID_FSTATUS_1_HI, PID_FSTATUS_1_LO, PID_FSTATUS_1); 390 h264eSetReg(&ph264eCFG->xrcxopts_pid[1], 0, PID_THRFRMLIM_1_FLAG, PID_THRFRMLIM_1_FLAG, PID_THRFRMLIM_1); 391 h264eSetReg(&ph264eCFG->xrcxopts_pid[2], 0, PID_FSTATUS_2_HI, PID_FSTATUS_2_LO, PID_FSTATUS_2); 392 h264eSetReg(&ph264eCFG->xrcxopts_pid[2], 0, PID_THRFRMLIM_2_FLAG, PID_THRFRMLIM_2_FLAG, PID_THRFRMLIM_2); 393 h264eSetReg(&ph264eCFG->xrcxopts_pid[2], 0, PID_FSTATUS_3_HI, PID_FSTATUS_3_LO, PID_FSTATUS_3); 394 h264eSetReg(&ph264eCFG->xrcxopts_pid[2], 0, PID_THRFRMLIM_3_FLAG, PID_THRFRMLIM_3_FLAG, PID_THRFRMLIM_3); 395 h264eSetReg(&ph264eCFG->xrcxopts_pid[2], 0, PID_FSTATUS_4_HI, PID_FSTATUS_4_LO, PID_FSTATUS_4); 396 h264eSetReg(&ph264eCFG->xrcxopts_pid[2], 0, PID_THRFRMLIM_4_FLAG, PID_THRFRMLIM_4_FLAG, PID_THRFRMLIM_4); 397 h264eSetReg(&ph264eCFG->xrcxopts_pid[2], 0, PID_QP_STEP_0_HI, PID_QP_STEP_0_LO, PID_QP_STEP_0); 398 h264eSetReg(&ph264eCFG->xrcxopts_pid[2], 0, PID_QP_THR_0_HI, PID_QP_THR_0_LO, PID_QP_THR_0); 399 h264eSetReg(&ph264eCFG->xrcxopts_pid[3], 0, PID_QP_STEP_1_HI, PID_QP_STEP_1_LO, PID_QP_STEP_1); 400 h264eSetReg(&ph264eCFG->xrcxopts_pid[3], 0, PID_QP_THR_1_HI, PID_QP_THR_1_LO, PID_QP_THR_1); 401 h264eSetReg(&ph264eCFG->xrcxopts_pid[3], 0, PID_QP_STEP_2_HI, PID_QP_STEP_2_LO, PID_QP_STEP_2); 402 h264eSetReg(&ph264eCFG->xrcxopts_pid[3], 0, PID_QP_THR_2_HI, PID_QP_THR_2_LO, PID_QP_THR_2); 403 h264eSetReg(&ph264eCFG->xrcxopts_pid[3], 0, PID_QP_STEP_3_HI, PID_QP_STEP_3_LO, PID_QP_STEP_3); 404 h264eSetReg(&ph264eCFG->xrcxopts_pid[3], 0, PID_QP_THR_3_HI, PID_QP_THR_3_LO, PID_QP_THR_3); 405 h264eSetReg(&ph264eCFG->xrcxopts_pid[3], 0, PID_QP_STEP_4_HI, PID_QP_STEP_4_LO, PID_QP_STEP_4); 406 h264eSetReg(&ph264eCFG->xrcxopts_pid[3], 0, PID_QP_THR_4_HI, PID_QP_THR_4_LO, PID_QP_THR_4); 407 h264eSetReg(&ph264eCFG->xrcxopts_pid[4], 0, PID_RAMP_METHOD_HI, PID_RAMP_METHOD_LO, PID_RAMP_METHOD); 408 h264eSetReg(&ph264eCFG->xrcxopts_pid[4], 0, PID_USE_KD_FLAG, PID_USE_KD_FLAG, PID_USE_KD); 409 h264eSetReg(&ph264eCFG->xrcxopts_pid[4], 0, PID_USE_KI_UPD_FLAG, PID_USE_KI_UPD_FLAG, PID_USE_KI_UPD); 410 h264eSetReg(&ph264eCFG->xrcxopts_pid[4], 0, PID_USE_KI_UPDM_FLAG, PID_USE_KI_UPDM_FLAG, PID_USE_KI_UPDM); 411 h264eSetReg(&ph264eCFG->xrcxopts_pid[4], 0, PID_USE_SCENE_THR_FLAG, PID_USE_SCENE_THR_FLAG, PID_USE_SCENE_THR); 412 h264eSetReg(&ph264eCFG->xrcxopts_pid[4], 0, PID_USE_AVG_QP_THR_FLAG, PID_USE_AVG_QP_THR_FLAG, PID_USE_AVG_QP_THR); 413 h264eSetReg(&ph264eCFG->xrcxopts_pid[4], 0, PID_AVG_QP_THR_HI, PID_AVG_QP_THR_LO, PID_AVG_QP_THR); 414 h264eSetReg(&ph264eCFG->xrcxopts_pid[4], 0, PID_SCENE_THR_HI, PID_SCENE_THR_LO, PID_SCENE_THR); 415 return; 416 } 417 418 void h264eSetReg(uint *puiRegFile, 419 int regOffs, 420 int regFieldHI, 421 int regFieldLO, 422 int regFieldVal) 423 { 424 uint FieldMask; 425 uint regVal; 426 uint regFieldValP; 427 FieldMask = 0xFFFFFFFF; 428 FieldMask >>= ((8*sizeof(uint)) - (regFieldHI - regFieldLO + 1)); 429 regFieldValP = regFieldVal & FieldMask; 430 FieldMask <<= regFieldLO; 431 regFieldValP <<= regFieldLO; 432 FieldMask = ~FieldMask; 433 regVal = puiRegFile[regOffs]; 434 regVal &= FieldMask; 435 regVal |= regFieldValP; 436 puiRegFile[regOffs] = regVal; 437 return; 438 } 439 440 uint h264eGetReg(uint *puiRegFile, 441 int regOffs, 442 int regFieldHI, 443 int regFieldLO) 444 { 445 uint retval; 446 uint FieldMask; 447 FieldMask = 0xFFFFFFFF; 448 FieldMask >>= ((8*sizeof(uint)) - (regFieldHI - regFieldLO + 1)); 449 retval = puiRegFile[regOffs]; 450 retval >>= regFieldLO; 451 retval &= FieldMask; 452 return retval; 453 } -
new file libavcodec/xlnx_h264/h264e_csregs.h
diff --git a/libavcodec/xlnx_h264/h264e_csregs.h b/libavcodec/xlnx_h264/h264e_csregs.h new file mode 100644 index 0000000..43556b1
- + 1 /* 2 -- Copyright notice: 3 -- Copyright (c) 2017 Alma Technologies S.A. 4 -- www.alma-technologies.com 5 -- All rights reserved worldwide. 6 7 -- This copy is made available under the terms of the GNU General Public 8 -- License version 2.1 as published by the Free Software Foundation; either 9 -- version 2.1 of the License, or (at your option) any later version. 10 -- 11 -- This copy is distributed in the hope that it will be useful, 12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of 13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Please See the GNU 14 -- General Public License for more details. 15 -- 16 -- You should have received a copy of the GNU General Public 17 -- License along with FFmpeg; if not, write to the Free Software 18 -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #ifndef _H264E_SDACCEL_CSREGS_H_ 22 #define _H264E_SDACCEL_CSREGS_H_ 23 24 #include "h264e_sdaccel.h" 25 26 void h264eSetControlRegs (H264E_USR* ph264eUsr, char* CRegsFile); 27 void h264ePrintStatusRegs (int* pRegFile); 28 void h264ePrintControlRegs (int* pRegFile); 29 int h264eGetNalSize (int* pRegFile); 30 int h264eGetErrorCode (int* pRegFile); 31 int h264eGetDbgStatus (int* pRegFile); 32 33 #endif // _H264E_SDACCEL_CSREGS_H_ 34 35 -
new file libavcodec/xlnx_h264/h264e_csregs_private.h
diff --git a/libavcodec/xlnx_h264/h264e_csregs_private.h b/libavcodec/xlnx_h264/h264e_csregs_private.h new file mode 100644 index 0000000..64e796b
- + 1 /* 2 -- Copyright notice: 3 -- Copyright (c) 2017 Alma Technologies S.A. 4 -- www.alma-technologies.com 5 -- All rights reserved worldwide. 6 7 -- This copy is made available under the terms of the GNU General Public 8 -- License version 2.1 as published by the Free Software Foundation; either 9 -- version 2.1 of the License, or (at your option) any later version. 10 -- 11 -- This copy is distributed in the hope that it will be useful, 12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of 13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Please See the GNU 14 -- General Public License for more details. 15 -- 16 -- You should have received a copy of the GNU General Public 17 -- License along with FFmpeg; if not, write to the Free Software 18 -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #ifndef _H264E_CSREGS_PRIVATE_H_ 22 #define _H264E_CSREGS_PRIVATE_H_ 23 24 #include <stdbool.h> 25 26 typedef unsigned int uint; 27 28 typedef struct _QPs { 29 30 int QPIPic; 31 int QPPPic; 32 int dQPISlice; 33 int dQPPSlice; 34 int dQPIMB; 35 int dQPPMB; 36 int QPEffectiveI; 37 int QPEffectiveP; 38 int QpBdOffset; 39 40 } QPs; 41 42 #define RC_EXTRA_OPT_MASK_WIDTH 5 43 44 typedef struct _H264E_CFG_PVT { 45 46 int X; 47 int Y; 48 int nMBRowsInSlice; 49 int nMBRowsInSliceReq; 50 int QPI; 51 int QPP; 52 int QPChrOffs; 53 int QpBdOffset; 54 bool bTQThresholding; 55 unsigned IPeriod; 56 unsigned IRefColumns; 57 int UseDeBlockingFilter; 58 int sliceAlphaOffset; 59 int sliceBetaOffset; 60 float FrameRate; 61 unsigned Timescale; 62 unsigned NUIT; 63 int nMBsInBasicUnit; 64 unsigned RCMethod; 65 int RCPeriod; 66 int Rate; 67 int MaxRate; 68 int FIFOSize; 69 int QPI_min; 70 int QPI_max; 71 int QPP_min; 72 int QPP_max; 73 int FramesToBeEncoded; 74 bool bInputFromPipe; 75 int pipeType; 76 int InterSearchAlgorithm; 77 int InterSearchRangeWidth; 78 int InterSearchRangeHeight; 79 int InterSRWOriginPolicy; 80 int InterAccuracy; 81 int InterQPELWindow; 82 int InterPSKIPPolicy; 83 int InterSADBits; 84 bool InterMVSliceRestrict; 85 int InterIMENeighborA; 86 int InterFMENeighborA; 87 int MPPriorities[4]; 88 bool bInterUseP0; 89 bool bInterQP2S; 90 bool bInterVBSenable; 91 bool bVBSEnableMask[7]; 92 bool bVBSOptions[7]; 93 int bI16x16Dis; 94 bool bIntraLuma16x16Mask[4]; 95 bool bI4x4Dis; 96 bool bIntraLuma4x4Mask[9]; 97 bool bIntraChromaMask[4]; 98 bool bUseIntraInInter; 99 bool bForceIPCMInIntra; 100 int NALTrZeros; 101 int NALFlushOnFrame; 102 bool bFrameDrop; 103 QPs h264eQPs; 104 int VInputFormat; 105 int bpp; 106 int csp; 107 int subWidthC; 108 int subHeightC; 109 int endianess; 110 int Level; 111 unsigned XtmemPtr; 112 int TBA; 113 bool TBASMask[9]; 114 void* pPFIFile; 115 char cClipInfo[2048]; 116 int Profile; 117 bool bCABAC; 118 bool bInterlaced; 119 bool bIsTopFieldYUV; 120 bool bBatch; 121 bool bRcExtraOpt[RC_EXTRA_OPT_MASK_WIDTH]; 122 char rcExtraOpt[512]; 123 unsigned rcVbrFactor; 124 unsigned estatsLevel; 125 char rcRegsFileName[512]; 126 FILE* rcRegsFile; 127 bool bUseSMAPData; 128 bool bHrdEnable; 129 bool bCbr; 130 uint cpbSizeInKbps; 131 uint initialCbpRdIn90Khz; 132 uint initialCbpRdInfr; 133 bool bRcHrd; 134 int AQStrength; 135 uint xrcxopts_pid[5]; 136 bool bDumpIOFrames; 137 uint nNALOutWidth; 138 uint nCEngines; 139 uint YSecNomPad16; 140 int TBDBG; 141 int VUI_VideoFormat; 142 int VUI_VideoFullRangeFlag; 143 int UseHW; 144 char KernelFile[2048]; 145 char TargetDevice[2048]; 146 char KernelName[2048]; 147 FILE* pYUVFile; 148 int UsePlanarSeparated; 149 int PackPlanarSeparated; 150 int PlanarToInterleavedInHW; 151 int HWBench; 152 int UseFrameBuffer; 153 int FrameOffset; 154 int PrintControlRegisters; 155 156 } H264E_CFG_PVT; 157 158 #define CSREG_VIDINRES 0x00 159 #define CSREG_VIDINSCAN 0x01 160 #define CSREG_VIDINTS 0x02 161 #define CSREG_VIDINUIT 0x03 162 #define CSREG_VIDINLEVEL 0x04 163 #define CSREG_VIDINVUIST 0x05 164 #define CSREG_GOPATTR 0x10 165 #define CSREG_SLICEATTR 0x11 166 #define CSREG_QPSLICEATTR 0x12 167 #define CSREG_RCATTR 0x13 168 #define CSREG_RCQPLIMS 0x14 169 #define CSREG_RCXOPTS 0x15 170 #define CSREG_PREDATTR 0x16 171 #define CSREG_ENCOPTS 0x17 172 #define CSREG_XPREDATTR 0x3F 173 #define CSREG_XRCXOPTS 0x3E 174 #define CSREG_COREVER 0x3D 175 #define CSREG_CORECFG 0x3C 176 #define CSREG_XRCXOPTS_PID0 0x3B 177 #define CSREG_XRCXOPTS_PID1 0x3A 178 #define CSREG_XRCXOPTS_PID2 0x39 179 #define CSREG_XRCXOPTS_PID3 0x38 180 #define CSREG_XRCXOPTS_PID4 0x37 181 #define CSREG_RCSTATUS 0x36 182 #define CSREG_INSTRUCTION 0x20 183 #define CSREG_STATUS 0x21 184 #define CSREG_ERRID 0x22 185 #define CSREG_IDRCNT 0x23 186 #define CSREG_FRAMECNT 0x24 187 #define CSREG_SEQLEN 0x25 188 #define CSREG_PICLEN 0x26 189 #define CSREG_SLICELEN 0x27 190 #define CSREG_FRAMEDROPCNT 0x28 191 #define CSREG_XTMEMPTR 0x30 192 #define CSREG_DEBUG 0x3F 193 #define FRAME_X_LO 0 194 #define FRAME_X_HI 15 195 #define FRAME_Y_LO 16 196 #define FRAME_Y_HI 31 197 #define SCAN_FORMAT_LO 0 198 #define SCAN_FORMAT_HI 3 199 #define PSP_LO 4 200 #define PSP_HI 7 201 #define FRAMEDROP_FLAG 16 202 #define TIMESCALE_LO 0 203 #define TIMESCALE_HI 31 204 #define NUIT_LO 0 205 #define NUIT_HI 31 206 #define LEVEL_LO 0 207 #define LEVEL_HI 4 208 #define V_VIDEO_SIGNAL_TYPE_PRESENT_FLAG 0 209 #define V_VIDEO_FORMAT_LO 4 210 #define V_VIDEO_FORMAT_HI 7 211 #define V_VIDEO_FULL_RANGE_FLAG 8 212 #define IPERIOD_LO 0 213 #define IPERIOD_HI 15 214 #define IREFCOLS_LO 16 215 #define IREFCOLS_HI 31 216 #define SLICE_MBROWS_L0 0 217 #define SLICE_MBROWS_HI 15 218 #define DB_EN_FLAG 16 219 #define DB_SLCBNDRS_FLAG 17 220 #define DB_ALPHA_LO 20 221 #define DB_ALPHA_HI 23 222 #define DB_BETA_LO 24 223 #define DB_BETA_HI 27 224 #define INTERSLICECROSS_FLAG 28 225 #define QPINIT_I_LO 0 226 #define QPINIT_I_HI 7 227 #define QPINIT_P_LO 8 228 #define QPINIT_P_HI 15 229 #define QPCHROFFS_LO 16 230 #define QPCHROFFS_HI 23 231 #define QPTHR_LO 24 232 #define QPTHR_HI 25 233 #define RCBITRATE_LO 0 234 #define RCBITRATE_HI 15 235 #define RCMAXBITRATE_LO 16 236 #define RCMAXBITRATE_HI 31 237 #define QPI_MIN_LO 0 238 #define QPI_MIN_HI 7 239 #define QPI_MAX_LO 8 240 #define QPI_MAX_HI 15 241 #define QPP_MIN_LO 16 242 #define QPP_MIN_HI 23 243 #define QPP_MAX_LO 24 244 #define QPP_MAX_HI 31 245 #define BUSIZE_LO 0 246 #define BUSIZE_HI 15 247 #define RCPERIOD_LO 16 248 #define RCPERIOD_HI 31 249 #define CABAC_FLAG 0 250 #define FLUSHFRAME_FLAG 4 251 #define NALTRZWORD_FLAG 8 252 #define ACTCENGS_LO 12 253 #define ACTCENGS_HI 15 254 #define MEVBS_P16X16_FLAG 0 255 #define MEVBS_P16X8_FLAG 1 256 #define MEVBS_P8X16_FLAG 2 257 #define MEVBS_P8X8_FLAG 3 258 #define MEPXLAC_LO 4 259 #define MEPXLAC_HI 5 260 #define XTRACOST_FLAG 6 261 #define XTRACOSTP8x8_FLAG 7 262 #define INTRA_IN_P_FLAG 8 263 #define I16x16_FLAG 9 264 #define I4x4_FLAG 10 265 #define I16x16_MASK_LO 12 266 #define I16x16_MASK_HI 15 267 #define ICHR_MASK_LO 16 268 #define ICHR_MASK_HI 19 269 #define I4x4_MASK_LO 20 270 #define I4x4_MASK_HI 28 271 #define SRX_LO 0 272 #define SRX_HI 7 273 #define SRY_LO 8 274 #define SRY_HI 15 275 #define VIMPW_LO 16 276 #define VIMPW_HI 19 277 #define VIMPR_LO 20 278 #define VIMPR_HI 23 279 #define VOMPW_LO 24 280 #define VOMPW_HI 27 281 #define REFWR_LO 28 282 #define REFWR_HI 31 283 #define QPADJSTRENGTH_LO 0 284 #define QPADJSTRENGTH_HI 3 285 #define USEINITQP_FLAG 4 286 #define USESCENECUT_FLAG 5 287 #define USERCOVERDUE_FLAG 6 288 #define STRICTCBR_FLAG 7 289 #define DISMADTH_FLAG 8 290 #define VBRF_LO 9 291 #define VBRF_HI 15 292 #define ICPBRDFR_LO 16 293 #define ICPBRDFR_HI 23 294 #define SWCLR_FLAG 0 295 #define SWSUSPEND_FLAG 1 296 #define XTMEMPTR_LO 0 297 #define XTMEMPTR_HI 31 298 #define PID_KU_IONPY_LO 0 299 #define PID_KU_IONPY_HI 3 300 #define PID_KU_IP_LO 4 301 #define PID_KU_IP_HI 7 302 #define PID_KI_UPD_IONPY_LO 8 303 #define PID_KI_UPD_IONPY_HI 15 304 #define PID_KI_UPD_IP_LO 16 305 #define PID_KI_UPD_IP_HI 23 306 #define PID_FIFO_STATUS_TARGET_LO 24 307 #define PID_FIFO_STATUS_TARGET_HI 29 308 #define PID_USE_COLOCATED_FLAG 30 309 #define PID_USE_IBU_THR_FLAG 31 310 #define PID_IFRAME_BUFFER_FACTOR_LO 0 311 #define PID_IFRAME_BUFFER_FACTOR_HI 7 312 #define PID_QP_STEP_FR_LO 8 313 #define PID_QP_STEP_FR_HI 11 314 #define PID_QP_STEP_IBU_LO 12 315 #define PID_QP_STEP_IBU_HI 15 316 #define PID_FSTATUS_0_LO 16 317 #define PID_FSTATUS_0_HI 22 318 #define PID_THRFRMLIM_0_FLAG 23 319 #define PID_FSTATUS_1_LO 24 320 #define PID_FSTATUS_1_HI 30 321 #define PID_THRFRMLIM_1_FLAG 31 322 #define PID_FSTATUS_2_LO 0 323 #define PID_FSTATUS_2_HI 6 324 #define PID_THRFRMLIM_2_FLAG 7 325 #define PID_FSTATUS_3_LO 8 326 #define PID_FSTATUS_3_HI 14 327 #define PID_THRFRMLIM_3_FLAG 15 328 #define PID_FSTATUS_4_LO 16 329 #define PID_FSTATUS_4_HI 22 330 #define PID_THRFRMLIM_4_FLAG 23 331 #define PID_QP_STEP_0_LO 24 332 #define PID_QP_STEP_0_HI 27 333 #define PID_QP_THR_0_LO 28 334 #define PID_QP_THR_0_HI 31 335 #define PID_QP_STEP_1_LO 0 336 #define PID_QP_STEP_1_HI 3 337 #define PID_QP_THR_1_LO 4 338 #define PID_QP_THR_1_HI 7 339 #define PID_QP_STEP_2_LO 8 340 #define PID_QP_STEP_2_HI 11 341 #define PID_QP_THR_2_LO 12 342 #define PID_QP_THR_2_HI 15 343 #define PID_QP_STEP_3_LO 16 344 #define PID_QP_STEP_3_HI 19 345 #define PID_QP_THR_3_LO 20 346 #define PID_QP_THR_3_HI 23 347 #define PID_QP_STEP_4_LO 24 348 #define PID_QP_STEP_4_HI 27 349 #define PID_QP_THR_4_LO 28 350 #define PID_QP_THR_4_HI 31 351 #define PID_RAMP_METHOD_LO 0 352 #define PID_RAMP_METHOD_HI 1 353 #define PID_USE_KD_FLAG 2 354 #define PID_USE_KI_UPD_FLAG 3 355 #define PID_USE_KI_UPDM_FLAG 4 356 #define PID_USE_SCENE_THR_FLAG 5 357 #define PID_USE_AVG_QP_THR_FLAG 6 358 #define PID_AVG_QP_THR_LO 16 359 #define PID_AVG_QP_THR_HI 23 360 #define PID_SCENE_THR_LO 24 361 #define PID_SCENE_THR_HI 31 362 #define PID_USE_COLOCATED 0 363 #define PID_RAMP_METHOD 1 364 #define PID_KU_IONPY 8 365 #define PID_KU_IP 4 366 #define PID_KI_UPD_IONPY 16 367 #define PID_KI_UPD_IP 8 368 #define PID_USE_KP 1 369 #define PID_USE_KI 1 370 #define PID_USE_KD 1 371 #define PID_USE_KI_UPD 1 372 #define PID_USE_KI_UPDM 1 373 #define PID_USE_IBU_THR 1 374 #define PID_USE_AVG_QP_THR 1 375 #define PID_USE_SCENE_THR 1 376 #define PID_AVG_QP_THR 16 377 #define PID_SCENE_THR 64 378 #define PID_FIFO_STATUS_TARGET 25 379 #define PID_IFRAME_BUFFER_FACTOR 65 380 #define PID_QP_STEP_FR 3 381 #define PID_QP_STEP_IBU 2 382 #define PID_FSTATUS_4 0 383 #define PID_QP_STEP_4 4 384 #define PID_QP_THR_4 12 385 #define PID_THRFRMLIM_4 0 386 #define PID_FSTATUS_3 50 387 #define PID_QP_STEP_3 3 388 #define PID_QP_THR_3 9 389 #define PID_THRFRMLIM_3 0 390 #define PID_FSTATUS_2 37 391 #define PID_QP_STEP_2 2 392 #define PID_QP_THR_2 6 393 #define PID_THRFRMLIM_2 1 394 #define PID_FSTATUS_1 12 395 #define PID_QP_STEP_1 1 396 #define PID_QP_THR_1 3 397 #define PID_THRFRMLIM_1 1 398 #define PID_FSTATUS_0 5 399 #define PID_QP_STEP_0 0 400 #define PID_QP_THR_0 0 401 #define PID_THRFRMLIM_0 1 402 #define VBS_DIFF_8x16_16x8_PREDICTOR 0 403 #define VBS_DIFF_8x8_PREDICTOR 1 404 #define VBS_USE_XTRA_PART_COST 2 405 #define VBS_USE_XTRA_PART_COST_P8x8 3 406 #define PSKIP_USE_HIGH_COST 4 407 #define VIMBPLANAR 0 408 #define VIPLANAR 1 409 #define VIINTERLEAVED 2 410 #define VIINTERLEAVEDF 3 411 #define TBA_DISABLE 0 412 #define TBA_INIT 1 413 #define TBA_APPEND 2 414 #define TBA_FINISH 3 415 #define TBA_SINGLE 4 416 #define BASELINE 66 417 #define MAIN 77 418 #define HIGH 100 419 #define HIGH10P 110 420 #define HIGH422 122 421 #define HIGH444 244 422 #define YUV400 0 423 #define YUV420 1 424 #define YUV422 2 425 #define YUV444 3 426 #define RC_MASK_SMARTINIT_QP 0 427 #define RC_MASK_SCENE_CUT_DETECT 1 428 #define RC_MASK_DISOVERDUE 2 429 #define RC_MASK_STRICTCBR 3 430 #define RC_MASK_DISMATH 4 431 #define RCM_PID 0 432 #define RCM_M1 1 433 #define RCM_M0 2 434 #define RCM_M2 3 435 436 static const int SUB_WIDTH_C_PVT[4] = {0, 2, 2, 1}; 437 static const int SUB_HEIGHT_C_PVT[4] = {0, 2, 1, 1}; 438 439 440 #endif // _H264E_CSREGS_PRIVATE_H_ -
new file libavcodec/xlnx_h264/h264e_sdaccel.c
diff --git a/libavcodec/xlnx_h264/h264e_sdaccel.c b/libavcodec/xlnx_h264/h264e_sdaccel.c new file mode 100644 index 0000000..6b0b8e4
- + 1 /* 2 -- Copyright notice: 3 -- Copyright (c) 2017 Alma Technologies S.A. 4 -- www.alma-technologies.com 5 -- All rights reserved worldwide. 6 7 -- This copy is made available under the terms of the GNU General Public 8 -- License version 2.1 as published by the Free Software Foundation; either 9 -- version 2.1 of the License, or (at your option) any later version. 10 -- 11 -- This copy is distributed in the hope that it will be useful, 12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of 13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Please See the GNU 14 -- General Public License for more details. 15 -- 16 -- You should have received a copy of the GNU General Public 17 -- License along with FFmpeg; if not, write to the Free Software 18 -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #include <stdio.h> 22 #include <stdlib.h> 23 #include <string.h> 24 #include <time.h> 25 #include <CL/opencl.h> 26 #include <CL/cl_ext.h> 27 #include "libavutil/atomic.h" 28 #include "h264e_sdaccel.h" 29 #include "h264e_sdaccel_private.h" 30 #include "h264e_sdaccel_utils.h" 31 #include "h264e_csregs.h" 32 33 static int kernel_number = -1; 34 static const int kernel_ddr_map[] = { 35 XCL_MEM_DDR_BANK0, 36 XCL_MEM_DDR_BANK0, 37 XCL_MEM_DDR_BANK1, 38 XCL_MEM_DDR_BANK1, 39 XCL_MEM_DDR_BANK2, 40 XCL_MEM_DDR_BANK2, 41 XCL_MEM_DDR_BANK3, 42 XCL_MEM_DDR_BANK3 43 }; 44 45 static const int kernel_map[] = {0,2,4,6,1,3,5,7}; 46 47 int h264eInitSW(H264E_KCFG* ph264eKCFG); 48 int h264eEndSW (H264E_KCFG* ph264eKCFG); 49 int h264eInitHW(H264E_KCFG* ph264eKCFG); 50 int h264eEndHW (H264E_KCFG* ph264eKCFG); 51 int h264eClear (H264E_KCFG* ph264eKCFG); 52 53 int h264eWriteDeviceBuffer(H264E_CL* ph264eCL, 54 char* pHostBuffer, 55 cl_mem DeviceBuffer, 56 int HostOffset, 57 int DeviceOffset, 58 int ByteSize, 59 bool bSync 60 ); 61 62 int h264eReadDeviceBuffer(H264E_CL* ph264eCL, 63 char* pHostBuffer, 64 cl_mem DeviceBuffer, 65 int HostOffset, 66 int DeviceOffset, 67 int ByteSize 68 ); 69 70 int h264eSetKernelArguments(H264E_KCFG* ph264eKCFG, 71 int KernelRunType 72 ); 73 74 int h264eExecuteKernel(H264E_CL* ph264eCL, cl_event *event); 75 76 77 int h264eWriteYUV(H264E_KERNEL_HANDLE h264eKernelHandle, 78 char* pHostYBuffer, 79 char* pHostUBuffer, 80 char* pHostVBuffer); 81 82 void *h264eEncoderThread(void *h264eKernelHandle); 83 84 void h264eUpdateStats(H264E_TIME* ph264eTime); 85 void h264eReportDebugStatus(int DebugStatus); 86 87 H264E_KERNEL_HANDLE h264eInit(const H264E_USR* pch264eUsr) 88 { 89 H264E_KCFG* ph264eKCFG; 90 int ans; 91 if(pch264eUsr == NULL) return NULL; 92 ph264eKCFG = malloc(sizeof(H264E_KCFG)); 93 if(ph264eKCFG == NULL) return NULL; 94 H264E_CL* ph264eCL = &ph264eKCFG->h264eCL; 95 H264E_USR* ph264eUsr = &ph264eKCFG->h264eUsr; 96 H264E_CNTX* ph264eCntx = &ph264eKCFG->h264eCntx; 97 memcpy(ph264eUsr, pch264eUsr, sizeof(H264E_USR)); 98 ans = h264eInitSW(ph264eKCFG); 99 ans |= h264eInitHW(ph264eKCFG); 100 if(ans < 0) 101 { 102 h264eEndSW(ph264eKCFG); 103 h264eEndHW(ph264eKCFG); 104 105 free(ph264eKCFG); 106 return NULL; 107 } 108 memset(ph264eCntx->CRegsFile, 0, sizeof(ph264eCntx->CRegsFile)); 109 memset(ph264eCntx->SRegsFile, 0, sizeof(ph264eCntx->SRegsFile)); 110 h264eSetControlRegs(ph264eUsr, ph264eCntx->CRegsFile); 111 ans = h264eWriteDeviceBuffer(ph264eCL, 112 ph264eCntx->CRegsFile, 113 ph264eCntx->DeviceBuffer, 114 0, 115 ph264eCntx->CRegsPtr, 116 sizeof(ph264eCntx->CRegsFile), 117 true 118 ); 119 ans |= h264eSetKernelArguments(ph264eKCFG, CONTROL_RT); 120 ans |= h264eExecuteKernel(ph264eCL, NULL); 121 ans |= h264eSetKernelArguments(ph264eKCFG, STATUS_RT); 122 ans |= h264eExecuteKernel(ph264eCL, NULL); 123 if(ans < 0) 124 { 125 h264eEndSW(ph264eKCFG); 126 h264eEndHW(ph264eKCFG); 127 free(ph264eKCFG); 128 return NULL; 129 } 130 ans = h264eReadDeviceBuffer(ph264eCL, 131 ph264eKCFG->h264eCntx.SRegsFile, 132 ph264eKCFG->h264eCntx.DeviceBuffer, 133 0, 134 ph264eKCFG->h264eCntx.SRegsPtr, 135 sizeof(ph264eKCFG->h264eCntx.SRegsFile) 136 ); 137 if(ans < 0) 138 { 139 h264eEndSW(ph264eKCFG); 140 h264eEndHW(ph264eKCFG); 141 142 free(ph264eKCFG); 143 return NULL; 144 } 145 int ErrID = h264eGetErrorCode((int*)ph264eKCFG->h264eCntx.SRegsFile); 146 if(ErrID) 147 { 148 H264EMSG(printf("ERROR: H.264 core programming error\n")); 149 h264eClear(ph264eKCFG); 150 h264eEndSW(ph264eKCFG); 151 h264eEndHW(ph264eKCFG); 152 free(ph264eKCFG); 153 return NULL; 154 } 155 else 156 { 157 return (void*)ph264eKCFG; 158 } 159 } 160 161 int h264eEnd(H264E_KERNEL_HANDLE h264eKernelHandle) 162 { 163 int ans; 164 if(h264eKernelHandle == NULL) 165 { 166 H264EMSG(printf("ERROR: Invalid kernel handle\n")); 167 return H264E_BAD_KERNEL_HANDLE; 168 } 169 H264E_KCFG* ph264eKCFG = (H264E_KCFG*)h264eKernelHandle; 170 ans = h264eEndSW(ph264eKCFG); 171 ans |= h264eEndHW(ph264eKCFG); 172 if(ans < 0) 173 { 174 return H264E_END_ERR; 175 } 176 else 177 { 178 return H264E_OK; 179 } 180 } 181 182 int h264eWriteYUV(H264E_KERNEL_HANDLE h264eKernelHandle, 183 char* pHostYBuffer, 184 char* pHostUBuffer, 185 char* pHostVBuffer) 186 { 187 H264E_KCFG* ph264eKCFG = (H264E_KCFG*)h264eKernelHandle; 188 int YSizeInBytes = 0; 189 int ChrSizeInBytes = 0; 190 int FrameSizeInBytes = 0; 191 int VDataIdx = 0; 192 H264E_CL* ph264eCL = &ph264eKCFG->h264eCL; 193 H264E_CNTX *ph264eCNTX = &ph264eKCFG->h264eCntx; 194 VDataIdx = ph264eCNTX->VDataIdx; 195 H264ETIME(timespec tss); 196 H264ETIME(timespec tse); 197 H264ETIME(clock_gettime(CLOCK_MONOTONIC_RAW, &tss)); 198 if(ph264eKCFG->h264eUsr.ScanFormat == H264E_PLANAR_SEPARATED) 199 { 200 if(pHostYBuffer == NULL || pHostUBuffer == NULL || pHostVBuffer == NULL) 201 { 202 H264EMSG(printf("ERROR: Invalid Y, U or V data pointer(s)\n")); 203 return H264E_BAD_COMP_PTR; 204 } 205 YSizeInBytes = ph264eKCFG->h264eUsr.FrameX * ph264eKCFG->h264eUsr.FrameY; 206 ChrSizeInBytes = (ph264eKCFG->h264eUsr.FrameX * ph264eKCFG->h264eUsr.FrameY) / 4; 207 FrameSizeInBytes = YSizeInBytes + 2*ChrSizeInBytes; 208 if(ph264eKCFG->h264eUsr.PackPlanarSeparated) 209 { 210 memcpy(ph264eKCFG->h264eCntx.pPackedPlanarHostBuffer, pHostYBuffer, YSizeInBytes); 211 memcpy(ph264eKCFG->h264eCntx.pPackedPlanarHostBuffer + YSizeInBytes, pHostUBuffer, ChrSizeInBytes); 212 memcpy(ph264eKCFG->h264eCntx.pPackedPlanarHostBuffer + YSizeInBytes + ChrSizeInBytes, pHostVBuffer, ChrSizeInBytes); 213 h264eWriteDeviceBuffer(ph264eCL, 214 ph264eKCFG->h264eCntx.pPackedPlanarHostBuffer, 215 ph264eKCFG->h264eCntx.DeviceBuffer, 216 0, 217 ph264eKCFG->h264eCntx.VDataPtr[VDataIdx], 218 FrameSizeInBytes, 219 true 220 ); 221 if(ph264eCL->bWRDeviceBufferFailed) return H264E_DEVBUFF_WR_ERR; 222 } 223 else 224 { 225 h264eWriteDeviceBuffer(ph264eCL, 226 pHostYBuffer, 227 ph264eKCFG->h264eCntx.DeviceBuffer, 228 0, 229 ph264eKCFG->h264eCntx.VDataPtr[VDataIdx], 230 YSizeInBytes, 231 true 232 ); 233 if(ph264eCL->bWRDeviceBufferFailed) return H264E_DEVBUFF_WR_ERR; 234 h264eWriteDeviceBuffer(ph264eCL, 235 pHostUBuffer, 236 ph264eKCFG->h264eCntx.DeviceBuffer, 237 0, 238 ph264eKCFG->h264eCntx.VDataPtr[VDataIdx] + YSizeInBytes, 239 ChrSizeInBytes, 240 true 241 ); 242 if(ph264eCL->bWRDeviceBufferFailed) return H264E_DEVBUFF_WR_ERR; 243 h264eWriteDeviceBuffer(ph264eCL, 244 pHostVBuffer, 245 ph264eKCFG->h264eCntx.DeviceBuffer, 246 0, 247 ph264eKCFG->h264eCntx.VDataPtr[VDataIdx] + YSizeInBytes + ChrSizeInBytes, 248 ChrSizeInBytes, 249 true 250 ); 251 if(ph264eCL->bWRDeviceBufferFailed) return H264E_DEVBUFF_WR_ERR; 252 } 253 254 if(ph264eKCFG->h264eUsr.HWOptimizeScanFormat) 255 { 256 ph264eKCFG->h264eCntx.Format = PLANAR_TO_INTERLEAVED_FRMT; 257 } 258 else 259 { 260 ph264eKCFG->h264eCntx.Format = NO_CHANGE_FRMT; 261 } 262 } 263 else 264 { 265 if(pHostYBuffer == NULL) 266 { 267 H264EMSG(printf("ERROR: Invalid Y data pointer\n")); 268 return H264E_BAD_COMP_PTR; 269 } 270 if(ph264eKCFG->h264eUsr.ScanFormat == H264E_PLANAR_PACKED) 271 { 272 YSizeInBytes = ph264eKCFG->h264eUsr.FrameX * ph264eKCFG->h264eUsr.FrameY; 273 ChrSizeInBytes = (ph264eKCFG->h264eUsr.FrameX * ph264eKCFG->h264eUsr.FrameY) / 4; 274 FrameSizeInBytes = YSizeInBytes + 2*ChrSizeInBytes; 275 if(ph264eKCFG->h264eUsr.HWOptimizeScanFormat) 276 { 277 ph264eKCFG->h264eCntx.Format = PLANAR_TO_INTERLEAVED_FRMT; 278 } 279 else 280 { 281 ph264eKCFG->h264eCntx.Format = NO_CHANGE_FRMT; 282 } 283 } 284 else if(ph264eKCFG->h264eUsr.ScanFormat == H264E_INTERLEAVED_YC) 285 { 286 YSizeInBytes = ph264eKCFG->h264eUsr.FrameX * ph264eKCFG->h264eUsr.FrameY; 287 ChrSizeInBytes = (ph264eKCFG->h264eUsr.FrameX * ph264eKCFG->h264eUsr.FrameY) / 4; 288 FrameSizeInBytes = YSizeInBytes + 2*ChrSizeInBytes; 289 ph264eKCFG->h264eCntx.Format = NO_CHANGE_FRMT; 290 } 291 else if(ph264eKCFG->h264eUsr.ScanFormat == H264E_INTERLEAVED_CY) 292 { 293 YSizeInBytes = ph264eKCFG->h264eUsr.FrameX * ph264eKCFG->h264eUsr.FrameY; 294 ChrSizeInBytes = (ph264eKCFG->h264eUsr.FrameX * ph264eKCFG->h264eUsr.FrameY) / 4; 295 FrameSizeInBytes = YSizeInBytes + 2*ChrSizeInBytes; 296 ph264eKCFG->h264eCntx.Format = NO_CHANGE_FRMT; 297 } 298 else if(ph264eKCFG->h264eUsr.ScanFormat == H264E_MACROBLOCK) 299 { 300 int FrameX = ph264eKCFG->h264eUsr.FrameX; 301 int FrameY = ph264eKCFG->h264eUsr.FrameY; 302 FrameX = ((FrameX + 15) / 16) * 16; 303 FrameY = ((FrameY + 15) / 16) * 16; 304 YSizeInBytes = FrameX * FrameY; 305 ChrSizeInBytes = (FrameX * FrameY) / 4; 306 FrameSizeInBytes = YSizeInBytes + 2*ChrSizeInBytes; 307 ph264eKCFG->h264eCntx.Format = NO_CHANGE_FRMT; 308 } 309 h264eWriteDeviceBuffer(ph264eCL, 310 pHostYBuffer, 311 ph264eKCFG->h264eCntx.DeviceBuffer, 312 0, 313 ph264eKCFG->h264eCntx.VDataPtr[VDataIdx], 314 FrameSizeInBytes, 315 true 316 ); 317 if(ph264eCL->bWRDeviceBufferFailed) return H264E_DEVBUFF_WR_ERR; 318 } 319 H264ETIME(clock_gettime(CLOCK_MONOTONIC_RAW, &tse)); 320 H264ETIME(ph264eKCFG->h264eTime.WriteDeviceBufferTime = tse.tv_nsec - tss.tv_nsec); 321 return H264E_OK; 322 } 323 324 int h264eEncodeFrame(H264E_KERNEL_HANDLE h264eKernelHandle, 325 char* pHostYBuffer, 326 char* pHostUBuffer, 327 char* pHostVBuffer, 328 char* pHostNALBuffer, 329 int frame_count 330 ) 331 { 332 int rc; 333 int NalSizeInBytes = 0; 334 if(h264eKernelHandle == NULL) 335 { 336 H264EMSG(printf("ERROR: Invalid kernel handle\n")); 337 return H264E_BAD_KERNEL_HANDLE; 338 } 339 if(pHostNALBuffer == NULL) 340 { 341 H264EMSG(printf("ERROR: Invalid NAL pointer\n")); 342 return H264E_BAD_NAL_PTR; 343 } 344 H264E_KCFG* ph264eKCFG = (H264E_KCFG*)h264eKernelHandle; 345 H264E_CL* ph264eCL = &ph264eKCFG->h264eCL; 346 H264ETIME(timespec tss); 347 H264ETIME(timespec tse); 348 H264ETIME(clock_gettime(CLOCK_MONOTONIC_RAW, &tss)); 349 rc = h264eWriteYUV(h264eKernelHandle, 350 pHostYBuffer, 351 pHostUBuffer, 352 pHostVBuffer); 353 if (rc != H264E_OK) return rc; 354 if (frame_count == 0) 355 { 356 H264ETIME(clock_gettime(CLOCK_MONOTONIC_RAW, &tss)); 357 h264eSetKernelArguments(ph264eKCFG, ENCODE_RT); 358 if(ph264eCL->bSetKernelArgsFailed) return H264E_ARGSET_ERR; 359 h264eExecuteKernel(ph264eCL, &ph264eCL->kernel_event); 360 if(ph264eCL->bExecuteKernelFailed) return H264E_EXEC_ERR; 361 return H264E_DEFER_DATA; 362 } 363 else 364 { 365 clWaitForEvents(1, &ph264eCL->kernel_event); 366 H264ETIME(clock_gettime(CLOCK_MONOTONIC_RAW, &tss)); 367 h264eReadDeviceBuffer(ph264eCL, 368 ph264eKCFG->h264eCntx.SRegsFile, 369 ph264eKCFG->h264eCntx.DeviceBuffer, 370 0, 371 ph264eKCFG->h264eCntx.SRegsPtr, 372 sizeof(ph264eKCFG->h264eCntx.SRegsFile) 373 ); 374 if(ph264eCL->bRDDeviceBufferFailed) return H264E_DEVBUFF_RD_ERR; 375 H264ETIME(clock_gettime(CLOCK_MONOTONIC_RAW, &tse)); 376 H264ETIME(ph264eKCFG->h264eTime.EncodeAndReadNALSizeTime = tse.tv_nsec - tss.tv_nsec); 377 NalSizeInBytes = h264eGetNalSize((int*)ph264eKCFG->h264eCntx.SRegsFile); 378 if(NalSizeInBytes == 0) 379 { 380 H264EMSG(printf("ERROR: H.264 core returned 0 NAL size\n")); 381 return H264E_CORE_ERR; 382 } 383 H264ETIME(clock_gettime(CLOCK_MONOTONIC_RAW, &tss)); 384 h264eReadDeviceBuffer(ph264eCL, 385 pHostNALBuffer, 386 ph264eKCFG->h264eCntx.DeviceBuffer, 387 0, 388 ph264eKCFG->h264eCntx.NALPtr, 389 NalSizeInBytes 390 ); 391 if(ph264eCL->bRDDeviceBufferFailed) return H264E_DEVBUFF_RD_ERR; 392 H264ETIME(clock_gettime(CLOCK_MONOTONIC_RAW, &tse)); 393 H264ETIME(ph264eKCFG->h264eTime.ReadNALBufferTime = tse.tv_nsec - tss.tv_nsec); 394 H264ETIME(h264eUpdateStats(&ph264eKCFG->h264eTime)); 395 H264ETIME(clock_gettime(CLOCK_MONOTONIC_RAW, &tss)); 396 h264eSetKernelArguments(ph264eKCFG, ENCODE_RT); 397 if(ph264eCL->bSetKernelArgsFailed) return H264E_ARGSET_ERR; 398 h264eExecuteKernel(ph264eCL, &ph264eCL->kernel_event); 399 if(ph264eCL->bExecuteKernelFailed) return H264E_EXEC_ERR; 400 H264ETIME(clock_gettime(CLOCK_MONOTONIC_RAW, &tse)); 401 H264ETIME(ph264eKCFG->h264eTime.ExecuteKernelTime = tse.tv_nsec - tss.tv_nsec); 402 rc = NalSizeInBytes; 403 } 404 return rc; 405 } 406 407 int h264eInitSW(H264E_KCFG* ph264eKCFG) 408 { 409 int rc = 0; 410 int IPCoreMemSizeInBytes; 411 int CRegsSizeInBytes; 412 int SRegsSizeInBytes; 413 int VDataSizeInBytes; 414 int NALSizeInBytes; 415 H264E_USR* ph264eUsr = &ph264eKCFG->h264eUsr; 416 H264E_CNTX* ph264eCntx = &ph264eKCFG->h264eCntx; 417 CRegsSizeInBytes = 64 * 4; 418 SRegsSizeInBytes = 64 * 4; 419 VDataSizeInBytes = ph264eUsr->FrameX * ph264eUsr->FrameY * 1.5; 420 IPCoreMemSizeInBytes = VDataSizeInBytes * 4; 421 NALSizeInBytes = VDataSizeInBytes; 422 IPCoreMemSizeInBytes *= 1.1; 423 VDataSizeInBytes *= 1.1; 424 NALSizeInBytes *= 1.1; 425 IPCoreMemSizeInBytes = ((IPCoreMemSizeInBytes / 4096) + 1) * 4096; 426 CRegsSizeInBytes = ((CRegsSizeInBytes / 4096) + 1) * 4096; 427 SRegsSizeInBytes = ((SRegsSizeInBytes / 4096) + 1) * 4096; 428 VDataSizeInBytes = ((VDataSizeInBytes / 4096) + 1) * 4096; 429 NALSizeInBytes = ((NALSizeInBytes / 4096) + 1) * 4096; 430 ph264eCntx->NALPtr = IPCoreMemSizeInBytes; 431 ph264eCntx->SRegsPtr = ph264eCntx->NALPtr + NALSizeInBytes; 432 ph264eCntx->CRegsPtr = ph264eCntx->SRegsPtr + SRegsSizeInBytes; 433 ph264eCntx->VDataPtr[0] = ph264eCntx->CRegsPtr + CRegsSizeInBytes; 434 ph264eCntx->VDataPtr[1] = ph264eCntx->VDataPtr[0] + VDataSizeInBytes; 435 ph264eCntx->VDataIdx = 0; 436 ph264eCntx->Format = 0; 437 ph264eCntx->DeviceBuffer = 0; 438 ph264eCntx->DeviceBufferSizeInBytes = ph264eCntx->VDataPtr[1] + VDataSizeInBytes; 439 memset(&ph264eKCFG->h264eTime, 0, sizeof(H264E_TIME)); 440 ph264eCntx->pPackedPlanarHostBuffer = NULL; 441 if(ph264eUsr->ScanFormat == H264E_PLANAR_SEPARATED && ph264eUsr->PackPlanarSeparated) 442 { 443 ph264eCntx->pPackedPlanarHostBuffer = malloc(ph264eUsr->FrameX * 444 ph264eUsr->FrameY * 445 2); 446 if(ph264eCntx->pPackedPlanarHostBuffer == NULL) 447 { 448 H264EMSG(printf("ERROR: Failed to allocate host buffer for packing planar separated input\n")); 449 return H264E_INITSW_ERR; 450 } 451 } 452 if(ph264eUsr->PackPlanarSeparated < 0 || ph264eUsr->PackPlanarSeparated > 0) ph264eUsr->PackPlanarSeparated = 1; 453 if(ph264eUsr->HWOptimizeScanFormat < 0 || ph264eUsr->HWOptimizeScanFormat > 0) ph264eUsr->HWOptimizeScanFormat = 1; 454 printf("Creating request message queue\n"); 455 rc = av_thread_message_queue_alloc(&ph264eKCFG->h264eReqMsgQ, 1, sizeof(H264E_REQ_MSG)); 456 printf("Creating response message queue\n"); 457 rc |= av_thread_message_queue_alloc(&ph264eKCFG->h264eRspMsgQ, 458 5, sizeof(H264E_RSP_MSG)); 459 if (rc < 0) 460 { 461 printf("Failed to allocate message queue\n"); 462 exit(1); 463 } 464 rc = pthread_create(&ph264eKCFG->h264eThread, NULL, 465 h264eEncoderThread, ph264eKCFG); 466 return H264E_OK; 467 } 468 469 int h264eEndSW(H264E_KCFG* ph264eKCFG) 470 { 471 H264E_REQ_MSG reqMsg; 472 reqMsg.endThread = 1; 473 av_thread_message_queue_send(ph264eKCFG->h264eReqMsgQ, &reqMsg, 0); 474 pthread_join(ph264eKCFG->h264eThread, NULL); 475 av_thread_message_queue_free(&ph264eKCFG->h264eReqMsgQ); 476 av_thread_message_queue_free(&ph264eKCFG->h264eRspMsgQ); 477 if(ph264eKCFG->h264eCntx.pPackedPlanarHostBuffer != NULL) 478 { 479 free(ph264eKCFG->h264eCntx.pPackedPlanarHostBuffer); 480 ph264eKCFG->h264eCntx.pPackedPlanarHostBuffer = NULL; 481 } 482 H264EMSG(printf("\n")); 483 H264EMSG(printf("\t\t======================================================\n")); 484 H264EMSG(printf("\t\tTotal Write Device Buffer Run-Time : %8.2f sec\n", ph264eKCFG->h264eTime.WriteDeviceBufferTotalTimeMS / 1000.0)); 485 H264EMSG(printf("\t\tTotal Execute Kernel Run-Time : %8.2f sec\n", ph264eKCFG->h264eTime.ExecuteKernelTotalTimeMS / 1000.0)); 486 H264EMSG(printf("\t\tTotal Encode & Read NAL Size Run-Time : %8.2f sec\n", ph264eKCFG->h264eTime.EncodeAndReadNALSizeTotalTimeMS / 1000.0)); 487 H264EMSG(printf("\t\tTotal Read NAL Buffer Run-Time : %8.2f sec\n", ph264eKCFG->h264eTime.ReadNALBufferTotalTimeMS / 1000.0)); 488 H264ETIME( 489 double TotalCLTime; 490 TotalCLTime = ph264eKCFG->h264eTime.WriteDeviceBufferTotalTimeMS + 491 ph264eKCFG->h264eTime.ExecuteKernelTotalTimeMS + 492 ph264eKCFG->h264eTime.EncodeAndReadNALSizeTotalTimeMS + 493 ph264eKCFG->h264eTime.ReadNALBufferTotalTimeMS; 494 TotalCLTime /= 1000.0; 495 ); 496 H264EMSG(printf("\t\t======================================================\n")); 497 H264EMSG(printf("\t\tTotal CL Run-Time : %8.2f sec\n", TotalCLTime)); 498 H264EMSG(printf("\t\t======================================================\n")); 499 H264EMSG(printf("\n")); 500 return H264E_OK; 501 } 502 503 int h264eInitHW(H264E_KCFG* ph264eKCFG) 504 { 505 int k_num; 506 if(!ph264eKCFG->h264eUsr.bCLIsOK) 507 { 508 k_num = avpriv_atomic_int_add_and_fetch(&kernel_number, 1); 509 ph264eKCFG->h264eCL.kernel_num = kernel_map[k_num]; 510 ph264eKCFG->h264eCL.pDeviceName = ph264eKCFG->h264eUsr.pDeviceName; 511 ph264eKCFG->h264eCL.pKernelBinFileName = ph264eKCFG->h264eUsr.pKernelBinFileName; 512 snprintf(ph264eKCFG->h264eCL.pKernelName, 64, "%s_%d", 513 ph264eKCFG->h264eUsr.pKernelName, 514 ph264eKCFG->h264eCL.kernel_num); 515 h264e_cl_init(&ph264eKCFG->h264eCL); 516 if(!ph264eKCFG->h264eCL.bCLIsOK) 517 { 518 H264EMSG(printf("ERROR: Failed to initialize CL\n")); 519 return H264E_INITHW_ERR; 520 } 521 } 522 else 523 { 524 ph264eKCFG->h264eCL.commands = ph264eKCFG->h264eUsr.commands; 525 ph264eKCFG->h264eCL.context = ph264eKCFG->h264eUsr.context; 526 ph264eKCFG->h264eCL.kernel = ph264eKCFG->h264eUsr.kernel; 527 } 528 cl_mem_ext_ptr_t cl_mem_ptr; 529 cl_mem_ptr.obj = 0; 530 cl_mem_ptr.param = 0; 531 cl_mem_ptr.flags = kernel_ddr_map[ph264eKCFG->h264eCL.kernel_num]; 532 ph264eKCFG->h264eCntx.DeviceBuffer = clCreateBuffer(ph264eKCFG->h264eCL.context, 533 CL_MEM_READ_WRITE | CL_MEM_EXT_PTR_XILINX, 534 ph264eKCFG->h264eCntx.DeviceBufferSizeInBytes, 535 &cl_mem_ptr, 536 NULL); 537 if(!ph264eKCFG->h264eCntx.DeviceBuffer) 538 { 539 H264EMSG(printf("ERROR: Failed to allocate device memory\n")); 540 return H264E_DEVBUFF_ERR; 541 } 542 return H264E_OK; 543 } 544 545 int h264eEndHW(H264E_KCFG* ph264eKCFG) 546 { 547 int err; 548 int ans; 549 int retval = H264E_OK; 550 if(ph264eKCFG->h264eCntx.DeviceBuffer) 551 { 552 err = clReleaseMemObject(ph264eKCFG->h264eCntx.DeviceBuffer); 553 if(err != CL_SUCCESS) 554 { 555 H264EMSG(printf("ERROR: Failed to release device buffer\n")); 556 retval = H264E_DEVBUFF_ERR; 557 } 558 } 559 if(ph264eKCFG->h264eCL.bCLIsOK && !ph264eKCFG->h264eUsr.bCLIsOK) 560 { 561 ans = h264e_cl_end(&(ph264eKCFG->h264eCL)); 562 if(ans < 0) retval = ans; 563 } 564 return retval; 565 } 566 567 int h264eWriteDeviceBuffer(H264E_CL* ph264eCL, 568 char* pHostBuffer, 569 cl_mem DeviceBuffer, 570 int HostOffset, 571 int DeviceOffset, 572 int ByteSize, 573 bool bSync 574 ) 575 { 576 int err; 577 cl_event writeevent; 578 if(bSync) 579 { 580 err = clEnqueueWriteBuffer(ph264eCL->commands, 581 DeviceBuffer, 582 CL_TRUE, 583 DeviceOffset, 584 ByteSize, 585 pHostBuffer + HostOffset, 586 0, 587 NULL, 588 &writeevent 589 ); 590 } 591 else 592 { 593 err = clEnqueueWriteBuffer(ph264eCL->commands, 594 DeviceBuffer, 595 CL_TRUE, 596 DeviceOffset, 597 ByteSize, 598 pHostBuffer + HostOffset, 599 0, 600 NULL, 601 NULL 602 ); 603 } 604 if(err != CL_SUCCESS) 605 { 606 H264EMSG(printf("ERROR: Failed to write to device buffer\n")); 607 ph264eCL->bWRDeviceBufferFailed = true; 608 return H264E_DEVBUFF_WR_ERR; 609 } 610 if(bSync) 611 { 612 clWaitForEvents(1, &writeevent); 613 } 614 ph264eCL->bWRDeviceBufferFailed = false; 615 return H264E_OK; 616 } 617 618 int h264eReadDeviceBuffer(H264E_CL* ph264eCL, 619 char* pHostBuffer, 620 cl_mem DeviceBuffer, 621 int HostOffset, 622 int DeviceOffset, 623 int ByteSize) 624 { 625 int err; 626 cl_event readevent; 627 err = clEnqueueReadBuffer(ph264eCL->commands, 628 DeviceBuffer, 629 CL_TRUE, 630 DeviceOffset, 631 ByteSize, 632 pHostBuffer + HostOffset, 633 0, 634 NULL, 635 &readevent 636 ); 637 if(err != CL_SUCCESS) 638 { 639 H264EMSG(printf("ERROR: Failed to read device buffer (error %d)\n", err)); 640 ph264eCL->bRDDeviceBufferFailed = true; 641 return H264E_DEVBUFF_RD_ERR; 642 } 643 clWaitForEvents(1, &readevent); 644 ph264eCL->bRDDeviceBufferFailed = false; 645 return H264E_OK; 646 } 647 648 int h264eSetKernelArguments(H264E_KCFG* ph264eKCFG, 649 int KernelRunType 650 ) 651 { 652 int err; 653 H264E_CL* ph264eCL = &ph264eKCFG->h264eCL; 654 H264E_USR* ph264eUsr = &ph264eKCFG->h264eUsr; 655 H264E_CNTX* ph264eCntx = &ph264eKCFG->h264eCntx; 656 int CRegsPtr = ph264eCntx->CRegsPtr; 657 int SRegsPtr = ph264eCntx->SRegsPtr; 658 int VDataPtr = ph264eCntx->VDataPtr[ph264eCntx->VDataIdx]; 659 int NALPtr = ph264eCntx->NALPtr; 660 int Format = ph264eCntx->Format; 661 int FrameX = ph264eUsr->FrameX; 662 int FrameY = ph264eUsr->FrameY; 663 if(ph264eUsr->ScanFormat == H264E_MACROBLOCK) 664 { 665 FrameX = ((FrameX + 15) / 16) * 16; 666 FrameY = ((FrameY + 15) / 16) * 16; 667 } 668 cl_kernel kernel = ph264eCL->kernel; 669 cl_mem DeviceBuffer = ph264eCntx->DeviceBuffer; 670 err = 0; 671 err = clSetKernelArg(kernel, 0, sizeof(cl_mem), &DeviceBuffer); 672 err |= clSetKernelArg(kernel, 1, sizeof(int), &CRegsPtr); 673 err |= clSetKernelArg(kernel, 2, sizeof(int), &SRegsPtr); 674 err |= clSetKernelArg(kernel, 3, sizeof(int), &VDataPtr); 675 err |= clSetKernelArg(kernel, 4, sizeof(int), &NALPtr); 676 err |= clSetKernelArg(kernel, 5, sizeof(int), &FrameX); 677 err |= clSetKernelArg(kernel, 6, sizeof(int), &FrameY); 678 err |= clSetKernelArg(kernel, 7, sizeof(int), &Format); 679 err |= clSetKernelArg(kernel, 8, sizeof(int), &KernelRunType); 680 if(err != CL_SUCCESS) 681 { 682 H264EMSG(printf("ERROR: Failed to set kernel arguments (error %d)\n", err)); 683 ph264eKCFG->h264eCL.bSetKernelArgsFailed = true; 684 return H264E_ARGSET_ERR; 685 } 686 ph264eKCFG->h264eCL.bSetKernelArgsFailed = false; 687 return H264E_OK; 688 } 689 690 int h264eExecuteKernel(H264E_CL* ph264eCL, cl_event *event) 691 { 692 int err; 693 cl_event execwait; 694 cl_event *pEvent; 695 if (event) 696 pEvent = event; 697 else 698 pEvent = &execwait; 699 err = clEnqueueTask(ph264eCL->commands, ph264eCL->kernel, 0, NULL, pEvent); 700 if(err != CL_SUCCESS) 701 { 702 H264EMSG(printf("ERROR: Failed to execute kernel (error %d)\n", err)); 703 ph264eCL->bExecuteKernelFailed = true; 704 return H264E_EXEC_ERR; 705 } 706 if (event == NULL) 707 { 708 clWaitForEvents(1, &execwait); 709 ph264eCL->bExecuteKernelFailed = false; 710 } 711 return H264E_OK; 712 } 713 714 const char* h264eReadStatusRegs(H264E_KERNEL_HANDLE h264eKernelHandle) 715 { 716 if(h264eKernelHandle == NULL) 717 { 718 H264EMSG(printf("ERROR: Invalid kernel handle\n")); 719 return NULL; 720 } 721 H264E_KCFG* ph264eKCFG = (H264E_KCFG*)h264eKernelHandle; 722 h264eSetKernelArguments(ph264eKCFG, STATUS_RT); 723 if(ph264eKCFG->h264eCL.bSetKernelArgsFailed) return NULL; 724 725 h264eExecuteKernel(&ph264eKCFG->h264eCL, NULL); 726 if(ph264eKCFG->h264eCL.bExecuteKernelFailed) return NULL; 727 h264eReadDeviceBuffer(&ph264eKCFG->h264eCL, 728 ph264eKCFG->h264eCntx.SRegsFile, 729 ph264eKCFG->h264eCntx.DeviceBuffer, 730 0, 731 ph264eKCFG->h264eCntx.SRegsPtr, 732 sizeof(ph264eKCFG->h264eCntx.SRegsFile) 733 ); 734 if(ph264eKCFG->h264eCL.bRDDeviceBufferFailed) return NULL; 735 return ph264eKCFG->h264eCntx.SRegsFile; 736 } 737 738 int h264eClear(H264E_KCFG* ph264eKCFG) 739 { 740 h264eSetKernelArguments(ph264eKCFG, CLEAR_RT); 741 if(ph264eKCFG->h264eCL.bSetKernelArgsFailed) return H264E_ARGSET_ERR; 742 h264eExecuteKernel(&ph264eKCFG->h264eCL, NULL); 743 if(ph264eKCFG->h264eCL.bExecuteKernelFailed) return H264E_EXEC_ERR; 744 return H264E_OK; 745 } 746 747 int h264eSetUserContext(H264E_KERNEL_HANDLE h264eKernelHandle, void* Context) 748 { 749 if(h264eKernelHandle == NULL) 750 { 751 H264EMSG(printf("ERROR: Invalid kernel handle\n")); 752 return H264E_BAD_KERNEL_HANDLE; 753 } 754 H264E_KCFG* ph264eKCFG = (H264E_KCFG*)h264eKernelHandle; 755 ph264eKCFG->h264eUsr.UserContext = Context; 756 return H264E_OK; 757 } 758 759 void* h264eGetUserContext(H264E_KERNEL_HANDLE h264eKernelHandle) 760 { 761 if(h264eKernelHandle == NULL) 762 { 763 H264EMSG(printf("ERROR: Invalid kernel handle\n")); 764 return NULL; 765 } 766 H264E_KCFG* ph264eKCFG = (H264E_KCFG*)h264eKernelHandle; 767 return ph264eKCFG->h264eUsr.UserContext; 768 } 769 770 void h264eUpdateStats(H264E_TIME* ph264eTime) 771 { 772 ph264eTime->nFrames++; 773 ph264eTime->WriteDeviceBufferTimeMS = (double)ph264eTime->WriteDeviceBufferTime / 1E6; 774 ph264eTime->ExecuteKernelTimeMS = (double)ph264eTime->ExecuteKernelTime / 1E6; 775 ph264eTime->EncodeAndReadNALSizeTimeMS = (double)ph264eTime->EncodeAndReadNALSizeTime / 1E6; 776 ph264eTime->ReadNALBufferTimeMS = (double)ph264eTime->ReadNALBufferTime / 1E6; 777 if(ph264eTime->WriteDeviceBufferTimeMS < 0) ph264eTime->WriteDeviceBufferTimeMS += 1000.0; 778 if(ph264eTime->ExecuteKernelTimeMS < 0) ph264eTime->ExecuteKernelTimeMS += 1000.0; 779 if(ph264eTime->EncodeAndReadNALSizeTimeMS < 0) ph264eTime->EncodeAndReadNALSizeTimeMS += 1000.0; 780 if(ph264eTime->ReadNALBufferTimeMS < 0) ph264eTime->ReadNALBufferTimeMS += 1000.0; 781 ph264eTime->WriteDeviceBufferTotalTimeMS += ph264eTime->WriteDeviceBufferTimeMS; 782 ph264eTime->ExecuteKernelTotalTimeMS += ph264eTime->ExecuteKernelTimeMS; 783 ph264eTime->EncodeAndReadNALSizeTotalTimeMS += ph264eTime->EncodeAndReadNALSizeTimeMS; 784 ph264eTime->ReadNALBufferTotalTimeMS += ph264eTime->ReadNALBufferTimeMS; 785 return; 786 } 787 788 const H264E_TIME* h264eGetStats(H264E_KERNEL_HANDLE h264eKernelHandle) 789 { 790 if(h264eKernelHandle == NULL) 791 { 792 H264EMSG(printf("ERROR: Invalid kernel handle\n")); 793 return NULL; 794 } 795 H264E_KCFG* ph264eKCFG = (H264E_KCFG*)h264eKernelHandle; 796 return &ph264eKCFG->h264eTime; 797 } 798 799 void h264eReportDebugStatus(int DebugStatus) 800 { 801 int i = 0; 802 printf("TIMEOUT: xtmem_req_val = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 803 printf("TIMEOUT: xtmem_req_rdy = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 804 printf("TIMEOUT: xtmem_wdata_val = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 805 printf("TIMEOUT: xtmem_wdata_rdy = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 806 printf("TIMEOUT: xtmem_rdata_val = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 807 printf("TIMEOUT: xtmem_rdata_rdy = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 808 printf("TIMEOUT: sreg_wrreq_val = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 809 printf("TIMEOUT: sreg_wrreq_rdy = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 810 printf("TIMEOUT: vdata_rdreq_val = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 811 printf("TIMEOUT: vdata_rdreq_rdy = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 812 printf("TIMEOUT: nal_wrreq_val = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 813 printf("TIMEOUT: nal_wrreq_rdy = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 814 printf("TIMEOUT: xtmemin_wrreq_val = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 815 printf("TIMEOUT: xtmemin_wrreq_rdy = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 816 printf("TIMEOUT: xtmemin_rdreq_val = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 817 printf("TIMEOUT: xtmemin_rdreq_rdy = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 818 printf("TIMEOUT: vdata_rdata_val = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 819 printf("TIMEOUT: vdata_rdata_rdy = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 820 printf("TIMEOUT: nal_wdata_val = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 821 printf("TIMEOUT: nal_wdata_rdy = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 822 printf("TIMEOUT: xtmemin_wdata_val = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 823 printf("TIMEOUT: xtmemin_wdata_rdy = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 824 printf("TIMEOUT: xtmemin_rdata_val = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 825 printf("TIMEOUT: xtmemin_rdata_rdy = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 826 printf("TIMEOUT: vdata_dout_val = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 827 printf("TIMEOUT: vdata_dout_rdy = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 828 printf("TIMEOUT: vdata_val = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 829 printf("TIMEOUT: vdata_rdy = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 830 printf("TIMEOUT: nal_val = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 831 printf("TIMEOUT: nal_rdy = %d\n", DebugStatus & (0x20000000 >> i++) ? 1 : 0); 832 return; 833 } 834 835 void *h264eEncoderThread(void *h264eKernelHandle) 836 { 837 H264E_KCFG* ph264eKCFG = (H264E_KCFG*)h264eKernelHandle; 838 H264E_CNTX *ph264eCNTX = &ph264eKCFG->h264eCntx; 839 H264E_CL *ph264eCL = &ph264eKCFG->h264eCL; 840 AVThreadMessageQueue *reqMq = ph264eKCFG->h264eReqMsgQ; 841 AVThreadMessageQueue *rspMq = ph264eKCFG->h264eRspMsgQ; 842 H264E_REQ_MSG reqMsg; 843 H264E_RSP_MSG rspMsg; 844 int frame_count = 0; 845 int NalSizeInBytes; 846 printf("Starting thread for kernel %d\n", ph264eCL->kernel_num); 847 printf("Using latest version of Alma plugin\n"); 848 while(1) 849 { 850 ph264eCNTX->VDataIdx = frame_count & 1; 851 av_thread_message_queue_recv(reqMq, &reqMsg, 0); 852 if (reqMsg.endThread) 853 { 854 clWaitForEvents(1, &ph264eCL->kernel_event); 855 break; 856 } 857 else 858 { 859 NalSizeInBytes = h264eEncodeFrame(ph264eKCFG, 860 reqMsg.pHostYBuffer, 861 reqMsg.pHostUBuffer, 862 reqMsg.pHostVBuffer, 863 reqMsg.pHostNALBuffer, 864 frame_count); 865 frame_count++; 866 if (NalSizeInBytes == H264E_DEFER_DATA) 867 continue; 868 rspMsg.NalSizeInBytes = NalSizeInBytes; 869 rspMsg.pHostNALBuffer = reqMsg.pHostNALBuffer; 870 rspMsg.pFrame = reqMsg.pFrame; 871 av_thread_message_queue_send(rspMq, &rspMsg, 0); 872 } 873 } 874 pthread_exit(NULL); 875 } -
new file libavcodec/xlnx_h264/h264e_sdaccel.h
diff --git a/libavcodec/xlnx_h264/h264e_sdaccel.h b/libavcodec/xlnx_h264/h264e_sdaccel.h new file mode 100644 index 0000000..d79116f
- + 1 /* 2 -- Copyright notice: 3 -- Copyright (c) 2017 Alma Technologies S.A. 4 -- www.alma-technologies.com 5 -- All rights reserved worldwide. 6 7 -- This copy is made available under the terms of the GNU General Public 8 -- License version 2.1 as published by the Free Software Foundation; either 9 -- version 2.1 of the License, or (at your option) any later version. 10 -- 11 -- This copy is distributed in the hope that it will be useful, 12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of 13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Please See the GNU 14 -- General Public License for more details. 15 -- 16 -- You should have received a copy of the GNU General Public 17 -- License along with FFmpeg; if not, write to the Free Software 18 -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #ifndef _H264E_SDACCEL_H_ 22 #define _H264E_SDACCEL_H_ 23 24 #include <stdbool.h> 25 #include <CL/opencl.h> 26 #include <CL/cl_ext.h> 27 #include "libavcodec/avcodec.h" 28 29 struct _H264E_RSP_MSG; 30 typedef struct _H264E_RSP_MSG H264E_RSP_MSG; 31 32 #ifdef H264E_DEBUG 33 #define H264E_PROFILING 34 #define H264EMSG(s) s 35 #else 36 #define H264EMSG(s) ; 37 #endif 38 39 #ifdef H264E_PROFILING 40 #define H264ETIME(s) s 41 #else 42 #define H264ETIME(s) ; 43 #endif 44 45 typedef void* H264E_KERNEL_HANDLE; 46 #define H264E_PLANAR_PACKED 0 47 #define H264E_PLANAR_SEPARATED 1 48 #define H264E_INTERLEAVED_YC 2 49 #define H264E_INTERLEAVED_CY 3 50 #define H264E_MACROBLOCK 4 51 52 typedef struct _H264E_USR { 53 char* pKernelBinFileName; 54 char* pDeviceName; 55 char* pKernelName; 56 bool bCLIsOK; 57 cl_context context; 58 cl_command_queue commands; 59 cl_kernel kernel; 60 int FrameX; 61 int FrameY; 62 int ScanFormat; 63 int PackPlanarSeparated; 64 int HWOptimizeScanFormat; 65 int Timescale; 66 int Nuit; 67 int Level; 68 int GOPLength; 69 int IntraRefreshCol; 70 int MBRowsPerSlice; 71 int DeblockingFilter; 72 int DBRestrict; 73 int MVRestrict; 74 int QPI; 75 int QPP; 76 int QPChrOffset; 77 int Bitrate; 78 int BUSize; 79 int RCFIFOSize; 80 int UseCABAC; 81 void* UserContext; 82 bool bUseUserContextAsCfg; 83 84 } H264E_USR; 85 86 typedef struct _H264E_TIME { 87 88 long int WriteDeviceBufferTime; 89 long int ExecuteKernelTime; 90 long int EncodeAndReadNALSizeTime; 91 long int ReadNALBufferTime; 92 93 double WriteDeviceBufferTimeMS; 94 double ExecuteKernelTimeMS; 95 double EncodeAndReadNALSizeTimeMS; 96 double ReadNALBufferTimeMS; 97 98 double WriteDeviceBufferTotalTimeMS; 99 double ExecuteKernelTotalTimeMS; 100 double EncodeAndReadNALSizeTotalTimeMS; 101 double ReadNALBufferTotalTimeMS; 102 103 unsigned long int nFrames; 104 105 } H264E_TIME; 106 107 H264E_KERNEL_HANDLE h264eInit(const H264E_USR* ph264eUsr); 108 int h264eEnd (H264E_KERNEL_HANDLE h264eKernelHandle); 109 110 int h264eEncodeFrame(H264E_KERNEL_HANDLE h264eKernelHandle, 111 char* pHostYBuffer, 112 char* pHostUBuffer, 113 char* pHostVBuffer, 114 char* pHostNALBuffer, 115 int frame_count 116 ); 117 118 void h264eSendEncodeFrame(H264E_KERNEL_HANDLE h264eKernelHandle, 119 AVFrame *pic, char *pCurrentBuffer); 120 121 int h264eRecvEncodeFrame(H264E_KERNEL_HANDLE h264eKernelHandle, 122 H264E_RSP_MSG *rspMsg); 123 124 const char* h264eReadStatusRegs(H264E_KERNEL_HANDLE h264eKernelHandle); 125 int h264eSetUserContext(H264E_KERNEL_HANDLE h264eKernelHandle, void* Context); 126 void* h264eGetUserContext(H264E_KERNEL_HANDLE h264eKernelHandle); 127 const H264E_TIME* h264eGetStats (H264E_KERNEL_HANDLE h264eKernelHandle); 128 129 #define H264E_OK 0 130 #define H264E_END_ERR -1 131 #define H264E_BAD_KERNEL_HANDLE -2 132 #define H264E_BAD_COMP_PTR -3 133 #define H264E_BAD_NAL_PTR -4 134 #define H264E_CORE_ERR -5 135 #define H264E_INITSW_ERR -6 136 #define H264E_INITHW_ERR -7 137 #define H264E_DEVBUFF_ERR -8 138 #define H264E_DEVBUFF_WR_ERR -9 139 #define H264E_DEVBUFF_RD_ERR -10 140 #define H264E_ARGSET_ERR -11 141 #define H264E_EXEC_ERR -12 142 #define H264E_CL_INIT_ERR -13 143 #define H264E_CL_END_ERR -14 144 #define H264E_DEFER_DATA -15 145 146 #endif // _H264E_SDACCEL_H_ -
new file libavcodec/xlnx_h264/h264e_sdaccel_private.h
diff --git a/libavcodec/xlnx_h264/h264e_sdaccel_private.h b/libavcodec/xlnx_h264/h264e_sdaccel_private.h new file mode 100644 index 0000000..e9db942
- + 1 /* 2 -- Copyright notice: 3 -- Copyright (c) 2017 Alma Technologies S.A. 4 -- www.alma-technologies.com 5 -- All rights reserved worldwide. 6 7 -- This copy is made available under the terms of the GNU General Public 8 -- License version 2.1 as published by the Free Software Foundation; either 9 -- version 2.1 of the License, or (at your option) any later version. 10 -- 11 -- This copy is distributed in the hope that it will be useful, 12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of 13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Please See the GNU 14 -- General Public License for more details. 15 -- 16 -- You should have received a copy of the GNU General Public 17 -- License along with FFmpeg; if not, write to the Free Software 18 -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #ifndef _H264E_SDACCEL_PRIVATE_H_ 22 #define _H264E_SDACCEL_PRIVATE_H_ 23 24 #include <CL/opencl.h> 25 #include <pthread.h> 26 #include <libavutil/threadmessage.h> 27 #include "libavcodec/avcodec.h" 28 #include "h264e_sdaccel.h" 29 30 #define CLEAR_RT 0 31 #define CONTROL_RT 1 32 #define STATUS_RT 2 33 #define CONTROL_STATUS_RT 3 34 #define CONTROL_ENCODE_RT 4 35 #define ENCODE_RT 5 36 #define TEST0_RT 6 37 #define TEST1_RT 7 38 #define NO_CHANGE_FRMT 0 39 #define PLANAR_TO_INTERLEAVED_FRMT 1 40 #define INTERLEAVED_YC_TO_INTERLEAVED_FRMT 2 41 #define INTERLEAVED_CY_TO_INTERLEAVED_FRMT 3 42 43 typedef struct _H264E_CL { 44 45 char* pDeviceName; 46 char* pKernelBinFileName; 47 char pKernelName[64]; 48 cl_platform_id platform_id; 49 cl_device_id device_id; 50 cl_context context; 51 cl_command_queue commands; 52 cl_program program; 53 cl_kernel kernel; 54 cl_event kernel_event; 55 int kernel_num; 56 bool bCLIsOK; 57 bool bWRDeviceBufferFailed; 58 bool bRDDeviceBufferFailed; 59 bool bSetKernelArgsFailed; 60 bool bExecuteKernelFailed; 61 62 } H264E_CL; 63 64 typedef struct _H264E_CNTX { 65 66 cl_mem DeviceBuffer; 67 int DeviceBufferSizeInBytes; 68 int CRegsPtr; 69 int SRegsPtr; 70 int VDataIdx; 71 int VDataPtr[2]; 72 int NALPtr; 73 int Format; 74 char CRegsFile[256]; 75 char SRegsFile[256]; 76 char* pPackedPlanarHostBuffer; 77 78 } H264E_CNTX; 79 80 typedef struct _H264E_KCFG { 81 82 H264E_USR h264eUsr; 83 H264E_CL h264eCL; 84 H264E_CNTX h264eCntx; 85 H264E_TIME h264eTime; 86 pthread_t h264eThread; 87 AVThreadMessageQueue *h264eReqMsgQ; 88 AVThreadMessageQueue *h264eRspMsgQ; 89 90 } H264E_KCFG; 91 92 typedef struct _H264E_REQ_MSG { 93 char *pHostYBuffer; 94 char *pHostUBuffer; 95 char *pHostVBuffer; 96 char *pHostNALBuffer; 97 AVFrame *pFrame; 98 int endThread; 99 } H264E_REQ_MSG; 100 101 typedef struct _H264E_RSP_MSG { 102 int NalSizeInBytes; 103 char *pHostNALBuffer; 104 AVFrame *pFrame; 105 } H264E_RSP_MSG; 106 107 #endif // _H264E_SDACCEL_PRIVATE_H_ -
new file libavcodec/xlnx_h264/h264e_sdaccel_utils.c
diff --git a/libavcodec/xlnx_h264/h264e_sdaccel_utils.c b/libavcodec/xlnx_h264/h264e_sdaccel_utils.c new file mode 100644 index 0000000..562a395
- + 1 /* 2 -- Copyright notice: 3 -- Copyright (c) 2017 Alma Technologies S.A. 4 -- www.alma-technologies.com 5 -- All rights reserved worldwide. 6 7 -- This copy is made available under the terms of the GNU General Public 8 -- License version 2.1 as published by the Free Software Foundation; either 9 -- version 2.1 of the License, or (at your option) any later version. 10 -- 11 -- This copy is distributed in the hope that it will be useful, 12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of 13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Please See the GNU 14 -- General Public License for more details. 15 -- 16 -- You should have received a copy of the GNU General Public 17 -- License along with FFmpeg; if not, write to the Free Software 18 -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #include <stdio.h> 22 #include <stdlib.h> 23 #include <string.h> 24 #include <pthread.h> 25 #include "libavutil/log.h" 26 #include "h264e_sdaccel.h" 27 #include "h264e_sdaccel_utils.h" 28 29 static pthread_mutex_t g_cl_mutex = PTHREAD_MUTEX_INITIALIZER; 30 static cl_program g_cl_program; 31 static int g_is_loaded = 0; 32 33 #define TARGET_DEVICE "xilinx:xil-accel-rd-vu9p:4ddr-xpr:4.1" 34 35 #if defined(SDX_PLATFORM) && !defined(TARGET_DEVICE) 36 #define STR_VALUE(arg) #arg 37 #define GET_STRING(name) STR_VALUE(name) 38 #define TARGET_DEVICE GET_STRING(SDX_PLATFORM) 39 #endif 40 41 int load_file_to_memory(const char *filename, unsigned char **result); 42 43 int h264e_cl_init(H264E_CL* ph264eCL) 44 { 45 char cl_platform_vendor[1001]; 46 char target_device_name[2048]; 47 char kernel_name[2048]; 48 cl_platform_id platform_id; 49 cl_device_id device_id; 50 cl_context context; 51 cl_command_queue commands; 52 cl_kernel kernel; 53 cl_int err; 54 const char* default_target_device_name = TARGET_DEVICE; 55 const char* default_kernel_name = "ALMA_H264_E_KERNEL"; 56 ph264eCL->bCLIsOK = false; 57 if(ph264eCL->pDeviceName != NULL) 58 { 59 strcpy(target_device_name, ph264eCL->pDeviceName); 60 } 61 else 62 { 63 strcpy(target_device_name, default_target_device_name); 64 } 65 if(ph264eCL->pKernelName != NULL) 66 { 67 strcpy(kernel_name, ph264eCL->pKernelName); 68 } 69 else 70 { 71 strcpy(kernel_name, default_kernel_name); 72 } 73 cl_platform_id platforms[16]; 74 cl_uint platform_count; 75 int platform_found = 0; 76 err = clGetPlatformIDs(16, platforms, &platform_count); 77 if(err != CL_SUCCESS) 78 { 79 H264EMSG(printf("ERROR: Failed to find an OpenCL platform\n")); 80 return H264E_CL_INIT_ERR; 81 } 82 H264EMSG(printf("INFO: Found %d platforms\n", platform_count)); 83 for(unsigned int iplat=0; iplat<platform_count; iplat++) 84 { 85 err = clGetPlatformInfo(platforms[iplat], CL_PLATFORM_VENDOR, 1000, (void *)cl_platform_vendor,NULL); 86 87 if(err != CL_SUCCESS) 88 { 89 H264EMSG(printf("ERROR: clGetPlatformInfo(CL_PLATFORM_VENDOR) failed\n")); 90 return H264E_CL_INIT_ERR; 91 } 92 93 if(strcmp(cl_platform_vendor, "Xilinx") == 0) 94 { 95 H264EMSG(printf("INFO: Selected platform %d from %s\n", iplat, cl_platform_vendor)); 96 platform_id = platforms[iplat]; 97 platform_found = 1; 98 } 99 } 100 if(!platform_found) 101 { 102 H264EMSG(printf("ERROR: Platform Xilinx not found\n")); 103 return H264E_CL_INIT_ERR; 104 } 105 cl_uint num_devices; 106 unsigned int device_found = 0; 107 cl_device_id devices[16]; 108 char cl_device_name[1001]; 109 err = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_ACCELERATOR, 16, devices, &num_devices); 110 if(err != CL_SUCCESS) 111 { 112 H264EMSG(printf("ERROR: Failed to create a device group\n")); 113 return H264E_CL_INIT_ERR; 114 } 115 for(unsigned int i=0; i<num_devices; i++) 116 { 117 err = clGetDeviceInfo(devices[i], CL_DEVICE_NAME, 1024, cl_device_name, 0); 118 119 if(err != CL_SUCCESS) 120 { 121 H264EMSG(printf("ERROR: Failed to get device name for device %d\n", i)); 122 return H264E_CL_INIT_ERR; 123 } 124 else 125 { 126 H264EMSG(printf("INFO: CL_DEVICE_NAME[%d / %d] = %s\n", i, num_devices, cl_device_name)); 127 } 128 129 if(strcmp(cl_device_name, target_device_name) == 0) 130 { 131 device_id = devices[i]; 132 device_found = 1; 133 H264EMSG(printf("INFO: Selected %s as the target device\n", cl_device_name)); 134 } 135 } 136 if(!device_found) 137 { 138 H264EMSG(printf("ERROR: Target device %s not found\n", target_device_name)); 139 return H264E_CL_INIT_ERR; 140 } 141 context = clCreateContext(0, 1, &device_id, NULL, NULL, &err); 142 if(!context) 143 { 144 H264EMSG(printf("ERROR: Failed to create a compute context\n")); 145 return H264E_CL_INIT_ERR; 146 } 147 commands = clCreateCommandQueue(context, device_id, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &err); 148 if(!commands) 149 { 150 H264EMSG(printf("ERROR: Failed to create commands queue\n")); 151 return H264E_CL_INIT_ERR; 152 } 153 pthread_mutex_lock(&g_cl_mutex); 154 cl_int status; 155 unsigned char *kernelbinary; 156 if (!g_is_loaded) 157 { 158 H264EMSG(printf("INFO: loading kernel binary %s\n", ph264eCL->pKernelFileName)); 159 int n_i0 = load_file_to_memory(ph264eCL->pKernelBinFileName, (unsigned char **) &kernelbinary); 160 if(n_i0 < 0) 161 { 162 H264EMSG(printf("ERROR: failed to load kernel binary from: %s\n", ph264eCL->pKernelBinFileName)); 163 return H264E_CL_INIT_ERR; 164 } 165 size_t n0 = n_i0; 166 g_cl_program = clCreateProgramWithBinary(context, 167 1, 168 &device_id, 169 &n0, 170 (const unsigned char **) &kernelbinary, 171 &status, 172 &err); 173 if((!g_cl_program) || (err!=CL_SUCCESS)) 174 { 175 H264EMSG(printf("ERROR: Failed to create compute program from binary %d\n", err)); 176 return H264E_CL_INIT_ERR; 177 } 178 free(kernelbinary); 179 err = clBuildProgram(g_cl_program, 0, NULL, NULL, NULL, NULL); 180 if(err != CL_SUCCESS) 181 { 182 size_t len; 183 char buffer[2048]; 184 185 H264EMSG(printf("ERROR: Failed to build program executable\n")); 186 clGetProgramBuildInfo(g_cl_program, device_id, CL_PROGRAM_BUILD_LOG, sizeof(buffer), buffer, &len); 187 H264EMSG(printf("%s\n", buffer)); 188 return H264E_CL_INIT_ERR; 189 } 190 g_is_loaded = 1; 191 } 192 else 193 { 194 clRetainProgram(g_cl_program); 195 } 196 pthread_mutex_unlock(&g_cl_mutex); 197 kernel = clCreateKernel(g_cl_program, ph264eCL->pKernelName, &err); 198 if(!kernel || err != CL_SUCCESS) 199 { 200 H264EMSG(printf("ERROR: Failed to create compute kernel\n")); 201 return -1; 202 } 203 ph264eCL->platform_id = platform_id; 204 ph264eCL->device_id = device_id; 205 ph264eCL->context = context; 206 ph264eCL->commands = commands; 207 ph264eCL->program = g_cl_program; 208 ph264eCL->kernel = kernel; 209 ph264eCL->bCLIsOK = true; 210 return H264E_OK; 211 } 212 213 int h264e_cl_end(H264E_CL* ph264eCL) 214 { 215 cl_int err; 216 int retval = H264E_OK; 217 err = clReleaseProgram(ph264eCL->program); 218 if(err != CL_SUCCESS) 219 { 220 H264EMSG(printf("ERROR: Failed to release program\n")); 221 retval = H264E_CL_END_ERR; 222 } 223 else 224 { 225 H264EMSG(printf("INFO: Released program\n")); 226 } 227 clReleaseKernel(ph264eCL->kernel); 228 if(err != CL_SUCCESS) 229 { 230 H264EMSG(printf("ERROR: Failed to release kernel\n")); 231 retval = H264E_CL_END_ERR; 232 } 233 else 234 { 235 H264EMSG(printf("INFO: Released kernel\n")); 236 } 237 clReleaseCommandQueue(ph264eCL->commands); 238 if(err != CL_SUCCESS) 239 { 240 H264EMSG(printf("ERROR: Failed to release commands queue\n")); 241 retval = H264E_CL_END_ERR; 242 } 243 else 244 { 245 H264EMSG(printf("INFO: Released commands queue\n")); 246 } 247 clReleaseContext(ph264eCL->context); 248 if(err != CL_SUCCESS) 249 { 250 H264EMSG(printf("ERROR: Failed to release context\n")); 251 retval = H264E_CL_END_ERR; 252 } 253 else 254 { 255 H264EMSG(printf("INFO: Released context\n")); 256 } 257 clReleaseDevice(ph264eCL->device_id); 258 if(err != CL_SUCCESS) 259 { 260 H264EMSG(printf("ERROR: Failed to release device\n")); 261 retval = H264E_CL_END_ERR; 262 } 263 else 264 { 265 H264EMSG(printf("INFO: Released device\n")); 266 } 267 return retval; 268 } 269 270 int load_file_to_memory(const char *filename, unsigned char **result) 271 { 272 int size = 0; 273 FILE *f = fopen(filename, "rb"); 274 if(f == NULL) 275 { 276 *result = NULL; 277 return -1; // -1 means file opening fail 278 } 279 fseek(f, 0, SEEK_END); 280 size = ftell(f); 281 fseek(f, 0, SEEK_SET); 282 *result = malloc(size); 283 if(size != fread(*result, sizeof(char), size, f)) 284 { 285 free(*result); 286 return -2; // -2 means file reading fail 287 } 288 fclose(f); 289 return size; 290 } -
new file libavcodec/xlnx_h264/h264e_sdaccel_utils.h
diff --git a/libavcodec/xlnx_h264/h264e_sdaccel_utils.h b/libavcodec/xlnx_h264/h264e_sdaccel_utils.h new file mode 100644 index 0000000..ebaad55
- + 1 /* 2 -- Copyright notice: 3 -- Copyright (c) 2017 Alma Technologies S.A. 4 -- www.alma-technologies.com 5 -- All rights reserved worldwide. 6 7 -- This copy is made available under the terms of the GNU General Public 8 -- License version 2.1 as published by the Free Software Foundation; either 9 -- version 2.1 of the License, or (at your option) any later version. 10 -- 11 -- This copy is distributed in the hope that it will be useful, 12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of 13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Please See the GNU 14 -- General Public License for more details. 15 -- 16 -- You should have received a copy of the GNU General Public 17 -- License along with FFmpeg; if not, write to the Free Software 18 -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #ifndef _H264E_SDACCEL_UTILS_H_ 22 #define _H264E_SDACCEL_UTILS_H_ 23 24 #include "h264e_sdaccel_private.h" 25 26 int h264e_cl_init(H264E_CL* ph264eCL); 27 int h264e_cl_end (H264E_CL* ph264eCL); 28 29 #endif // _H264E_SDACCEL_UTILS_H_ -
new file libavcodec/xlnx_h264/hw_h264.c
diff --git a/libavcodec/xlnx_h264/hw_h264.c b/libavcodec/xlnx_h264/hw_h264.c new file mode 100644 index 0000000..e2571f0
- + 1 /* 2 -- Copyright notice: 3 -- Copyright (c) 2017 Alma Technologies S.A. 4 -- www.alma-technologies.com 5 -- All rights reserved worldwide. 6 7 -- This copy is made available under the terms of the GNU General Public 8 -- License version 2.1 as published by the Free Software Foundation; either 9 -- version 2.1 of the License, or (at your option) any later version. 10 -- 11 -- This copy is distributed in the hope that it will be useful, 12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of 13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Please See the GNU 14 -- General Public License for more details. 15 -- 16 -- You should have received a copy of the GNU General Public 17 -- License along with FFmpeg; if not, write to the Free Software 18 -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #include <inttypes.h> 22 #include <stdlib.h> 23 #include <linux/limits.h> 24 #include <unistd.h> 25 #include <string.h> 26 #include <assert.h> 27 #include "libavutil/opencl.h" 28 #include "libavutil/log.h" 29 #include "h264e_sdaccel.h" 30 #include "h264e_sdaccel_private.h" 31 #include "h264e_csregs.h" 32 #include "xlnx_h264_config.h" 33 34 void ff_init_h264_xlnx_hw(AVCodecContext *avctx) 35 { 36 H264E_USR h264eUsr; 37 unsigned char* xcl_path = getenv("XLNX_XCLBIN_PATH"); 38 if (NULL == xcl_path) 39 { 40 av_log(NULL, AV_LOG_INFO, " * XLNX_XCLBIN_PATH not found\n"); 41 return; 42 } 43 char *xcl_fullpath = malloc(PATH_MAX); 44 snprintf(xcl_fullpath, PATH_MAX, "%s/h264_8k1c.xclbin", xcl_path); 45 h264eUsr.pKernelBinFileName = xcl_fullpath; 46 h264eUsr.pDeviceName = "xilinx:xil-accel-rd-vu9p:4ddr-xpr:4.1"; 47 h264eUsr.pKernelName = "ALMA_H264_E_KERNEL"; 48 h264eUsr.bCLIsOK = false; 49 h264eUsr.FrameX = avctx->width; 50 h264eUsr.FrameY = avctx->height; 51 h264eUsr.ScanFormat = H264E_PLANAR_SEPARATED; 52 h264eUsr.PackPlanarSeparated = 0; 53 h264eUsr.HWOptimizeScanFormat = 1; 54 h264eUsr.Timescale = 60000; 55 h264eUsr.Nuit = 1000; 56 h264eUsr.Level = 42; 57 h264eUsr.GOPLength = avctx->gop_size; 58 h264eUsr.IntraRefreshCol = -1; 59 h264eUsr.MBRowsPerSlice = -1; 60 h264eUsr.DeblockingFilter = -1; 61 h264eUsr.DBRestrict = -1; 62 h264eUsr.MVRestrict = -1; 63 h264eUsr.QPI = avctx->global_quality; 64 h264eUsr.QPP = avctx->global_quality; 65 h264eUsr.QPChrOffset = -1; 66 h264eUsr.Bitrate = (avctx->bit_rate)/1000; 67 h264eUsr.BUSize = -1; 68 h264eUsr.RCFIFOSize = -1; 69 h264eUsr.UseCABAC = -1; 70 h264eUsr.bUseUserContextAsCfg = false; 71 avctx->priv_data = h264eInit(&h264eUsr); 72 } 73 74 void h264eSendEncodeFrame(H264E_KERNEL_HANDLE h264eKernelHandle, 75 AVFrame *pic, char *pCurrentBuffer) 76 { 77 H264E_KCFG *ph264eKCFG = (H264E_KCFG*)h264eKernelHandle; 78 H264E_REQ_MSG reqMsg; 79 reqMsg.pHostYBuffer = pic->data[Y]; 80 reqMsg.pHostUBuffer = pic->data[U]; 81 reqMsg.pHostVBuffer = pic->data[V]; 82 reqMsg.pHostNALBuffer = pCurrentBuffer; 83 reqMsg.pFrame = pic; 84 reqMsg.endThread = 0; 85 av_thread_message_queue_send(ph264eKCFG->h264eReqMsgQ, &reqMsg, 0); 86 } 87 88 int h264eRecvEncodeFrame(H264E_KERNEL_HANDLE h264eKernelHandle, 89 H264E_RSP_MSG *rsp) 90 { 91 H264E_KCFG *ph264eKCFG = (H264E_KCFG*)h264eKernelHandle; 92 int rc; 93 rc = av_thread_message_queue_recv(ph264eKCFG->h264eRspMsgQ, rsp, 94 AV_THREAD_MESSAGE_NONBLOCK); 95 if (rc == AVERROR(EAGAIN)) 96 return 0; 97 return 1; 98 } 99 100 void ff_uninit_h264_xlnx_hw(AVCodecContext *avctx) 101 { 102 h264eEnd(avctx->priv_data); 103 } 104 105 -
new file libavcodec/xlnx_h264/xlnx_h264_config.h
diff --git a/libavcodec/xlnx_h264/xlnx_h264_config.h b/libavcodec/xlnx_h264/xlnx_h264_config.h new file mode 100644 index 0000000..517b3e5
- + 1 /* 2 -- Copyright notice: 3 -- Copyright (c) 2017 Alma Technologies S.A. 4 -- www.alma-technologies.com 5 -- All rights reserved worldwide. 6 7 -- This copy is made available under the terms of the GNU General Public 8 -- License version 2.1 as published by the Free Software Foundation; either 9 -- version 2.1 of the License, or (at your option) any later version. 10 -- 11 -- This copy is distributed in the hope that it will be useful, 12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of 13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Please See the GNU 14 -- General Public License for more details. 15 -- 16 -- You should have received a copy of the GNU General Public 17 -- License along with FFmpeg; if not, write to the Free Software 18 -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #ifndef _XLNX_H264_CONFIG_H_ 22 #define _XLNX_H264_CONFIG_H_ 23 24 #include "libavcodec/avcodec.h" 25 26 #define OCLCHECK(method, ... ) \ 27 do { \ 28 status = method(__VA_ARGS__); \ 29 if (status != CL_SUCCESS) { \ 30 av_log(NULL, AV_LOG_ERROR, # method " error '%s'\n", \ 31 av_opencl_errstr(status)); \ 32 return; \ 33 } \ 34 } while (0) 35 36 #define OCLCHECK1(method, ... ) \ 37 do { \ 38 status = method(__VA_ARGS__); \ 39 if (status != CL_SUCCESS) { \ 40 av_log(NULL, AV_LOG_ERROR, # method " error '%s'\n", \ 41 av_opencl_errstr(status)); \ 42 return AVERROR_EXTERNAL; \ 43 } \ 44 } while (0) 45 46 #define CREATEBUF(out, flags, size) \ 47 do { \ 48 out = clCreateBuffer(cl_env->context, flags, size, NULL, &status); \ 49 if (status != CL_SUCCESS) { \ 50 av_log(NULL, AV_LOG_ERROR, "Could not create OpenCL buffer\n"); \ 51 return; \ 52 } \ 53 } while (0) 54 55 typedef enum 56 { 57 Y = 0, 58 U = 1, 59 V = 2 60 }col_fmt_t; 61 62 void ff_init_h264_xlnx_hw(AVCodecContext *c); 63 void ff_uninit_h264_xlnx_hw(AVCodecContext *c); 64 uint8_t *ff_h264_xlnx_hw(AVCodecContext *avctx, AVFrame *pic, 65 char *pCurrentBuffer, uint32_t *dstSize); 66 67 #endif //_XLNX_H264_CONFIG_H_ -
new file libavcodec/xlnx_h264_enc.c
diff --git a/libavcodec/xlnx_h264_enc.c b/libavcodec/xlnx_h264_enc.c new file mode 100644 index 0000000..97f85a5
- + 1 /* 2 * Xilinx H.264 Alma encoder 3 * 4 * Copyright (C) 2017 Xilinx Inc. 5 * 6 * This file is part of FFmpeg. 7 * 8 * FFmpeg is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * FFmpeg is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with FFmpeg; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 #include <stdio.h> 23 #include "avcodec.h" 24 #include "internal.h" 25 #include "xlnx_h264/xlnx_h264_config.h" 26 #include "xlnx_h264/h264e_sdaccel_private.h" 27 28 static int xlnx_h264_encode_init(AVCodecContext *avctx) 29 { 30 //printf("xlnx_h264_encode_init IN\n"); 31 switch(avctx->pix_fmt) 32 { 33 case AV_PIX_FMT_YUV420P: 34 avctx->bits_per_raw_sample = 8; 35 break; 36 default: 37 av_log(NULL, AV_LOG_ERROR,"ERROR: Pixel format not supported...\n"); 38 return AVERROR(EINVAL); 39 break; 40 } 41 ff_init_h264_xlnx_hw(avctx); 42 return 0; 43 } 44 45 static int xlnx_h264_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pic, int *got_packet) 46 { 47 48 //av_log(NULL, AV_LOG_DEBUG, "xlnx_h264_encode_frame IN\n"); 49 int EntrySize = avctx->bits_per_raw_sample == 8 ? 1 : 2; 50 int EntryCount = 0; 51 uint64_t EncodeBuffSize = 0; 52 uint8_t *pBuffer = NULL; 53 AVFrame *pFrame; 54 H264E_RSP_MSG rspMsg; 55 int rc; 56 57 if (!pic) 58 { 59 *got_packet = 0; 60 return 0; 61 } 62 63 switch(pic->format) 64 { 65 case AV_PIX_FMT_YUV420P: 66 EntryCount = 2; 67 break; 68 default: 69 av_log(NULL, AV_LOG_ERROR,"Error. Encoding unknown pixel format.\n"); 70 return AVERROR_INVALIDDATA; 71 break; 72 } 73 74 pFrame = av_frame_clone(pic); 75 EncodeBuffSize = EntryCount * (pic->width) * (pic->height) * EntrySize; 76 77 pBuffer = av_malloc(EncodeBuffSize); 78 79 // Send the encode request 80 h264eSendEncodeFrame(avctx->priv_data, pFrame, pBuffer); 81 82 // Check if the encode has completed 83 rc = h264eRecvEncodeFrame(avctx->priv_data, &rspMsg); 84 85 if (rc == 1) 86 { 87 *got_packet = 1; 88 av_packet_from_data(pkt, rspMsg.pHostNALBuffer, 89 rspMsg.NalSizeInBytes); 90 pkt->pts = pkt->dts = (int64_t)rspMsg.pFrame->pts; 91 av_frame_unref(rspMsg.pFrame); 92 av_frame_free(&rspMsg.pFrame); 93 } 94 else 95 { 96 *got_packet = 0; 97 } 98 99 return 0; 100 } 101 102 static int xlnx_h264_encode_close(AVCodecContext *avctx) 103 { 104 printf("xlnx_h264_encode_close IN\n"); 105 ff_uninit_h264_xlnx_hw(avctx); 106 return 0; 107 } 108 109 AVCodec ff_xlnx_h264_encoder = { 110 .name = "xlnx_h264_enc", 111 .long_name = NULL_IF_CONFIG_SMALL("Xilinx Advanced Video Codec (H.264) Encoder"), 112 .type = AVMEDIA_TYPE_VIDEO, 113 .id = AV_CODEC_ID_H264, 114 .priv_data_size = sizeof(H264E_KCFG), 115 .init = xlnx_h264_encode_init, 116 .encode2 = xlnx_h264_encode_frame, 117 .close = xlnx_h264_encode_close, 118 .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY, 119 .pix_fmts = (const enum AVPixelFormat[]) { 120 AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE 121 }, 122 }; -
new file libavcodec/xlnx_hevc/Makefile
diff --git a/libavcodec/xlnx_hevc/Makefile b/libavcodec/xlnx_hevc/Makefile new file mode 100644 index 0000000..b32df98
- + 1 OBJS += xlnx_hevc/hw_hevc.o -
new file libavcodec/xlnx_hevc/hw_hevc.c
diff --git a/libavcodec/xlnx_hevc/hw_hevc.c b/libavcodec/xlnx_hevc/hw_hevc.c new file mode 100644 index 0000000..a35da42
- + 1 // 2 // NOTE: currently using ICD for DSA 2.0 50Mhz ... 3 // TODO: update this when new DSA is available 4 // 5 6 #include <inttypes.h> 7 #include <stdlib.h> 8 #include <linux/limits.h> 9 #include <unistd.h> 10 #include "libavutil/opencl.h" 11 #include "libavutil/log.h" 12 #include "xlnx_hevc_config.h" 13 14 // Header based loading 15 //#include "opencl_image.h" 16 17 //Globals - for opencl 18 static AVOpenCLExternalEnv *cl_env; 19 static cl_kernel kernel = NULL; 20 static cl_program program = NULL; 21 22 // OpenCL Buffers 23 static cl_mem CSR3_INPUT_FP_Y_V; 24 static cl_mem CSR4_INPUT_FP_U_V; 25 static cl_mem CSR5_INPUT_FP_V_V; 26 static cl_mem CSR6_NEXT_FP_Y_V; 27 static cl_mem CSR7_NEXT_FP_U_V; 28 static cl_mem CSR8_NEXT_FP_V_V; 29 static cl_mem CSR12_RECON_BASE_V; 30 static cl_mem CSR13_BITSTREAM_BASE_V; 31 static cl_mem CSR14_BITSTREAM_LEN_V; 32 33 static cl_int status; 34 static unsigned int CurSourceImageSize[3] = { 0, 0, 0 }; 35 static unsigned int EncodedFrameSize = 0; 36 static unsigned int EncodedFrameLengthSize = 0; 37 static int frameNumber = 0; 38 39 int load_file_to_memory_hevc(const char *filename, unsigned char **result); 40 41 // 42 // HEVC init function 43 // 44 void ff_init_hevc_xlnx_hw(AVCodecContext *avctx) 45 { 46 unsigned char *kernelbinary = 0; 47 size_t kernel_len = 0; 48 AVOpenCLDeviceList *device_list; 49 AVOpenCLDeviceNode *device_node = NULL; 50 cl_context_properties cps[3]; 51 int i; 52 int nb_devices; 53 int arg = 0; 54 // Header based loading (opencl_image.h) 55 //kernelbinary = hevc_xclbin; 56 //kernel_len = hevc_xclbin_len; 57 58 // 59 // Setup NGCodec HEVC core defaults 60 // 61 unsigned int CSR1_FRAME_WIDTH_V = avctx->width; 62 unsigned int CSR2_FRAME_HEIGHT_V = avctx->height; 63 unsigned int CSR9_BITRATE_V = 0; 64 unsigned int CSR10_FIXED_QP_V = 0; 65 unsigned int CSR11_INTRA_PERIOD_V = avctx->gop_size; 66 unsigned int CSR15_RESET_ENCODER_V = 0; 67 68 av_log(NULL, AV_LOG_INFO, " * Xilinx HEVC HW accelerator init ***\n"); 69 if (avctx->bit_rate > 0) 70 { 71 // Constant bitrate mode 72 CSR9_BITRATE_V = avctx->bit_rate; 73 av_log(NULL, AV_LOG_INFO, " * Encoding in constant bitrate mode***\n"); 74 } 75 else 76 { 77 // Fixed QP mode 78 CSR10_FIXED_QP_V = avctx->global_quality; 79 av_log(NULL, AV_LOG_INFO, " * Encoding in fixed QP mode***\n"); 80 } 81 82 // 83 // Setup OpenCL context 84 // 85 cl_env = av_opencl_alloc_external_env(); 86 cl_platform_id platforms[16] = { 0 }; 87 cl_device_id devices[16]; 88 char platformName[256]; 89 char deviceName[256]; 90 cl_uint platformCount = 0; 91 cl_int err = clGetPlatformIDs(0, 0, &platformCount); 92 err = clGetPlatformIDs(16, platforms, &platformCount); 93 if (err != CL_SUCCESS) { 94 //printf("%s\n", oclErrorCode(err)); 95 return;// hardware; 96 } 97 cl_env->device_type = CL_DEVICE_TYPE_ACCELERATOR; 98 for (cl_uint i = 0; i < platformCount; i++) { 99 err = clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME, 256, platformName, 0); 100 if (err != CL_SUCCESS) { 101 //printf("%s\n", oclErrorCode(err)); 102 return;// hardware; 103 } 104 cl_uint deviceCount = 0; 105 err = clGetDeviceIDs(platforms[i], cl_env->device_type, 16, devices, &deviceCount); 106 if ((err != CL_SUCCESS) || (deviceCount == 0)) { 107 continue; 108 } 109 110 err = clGetDeviceInfo(devices[0], CL_DEVICE_NAME, 256, deviceName, 0); 111 if (err != CL_SUCCESS) { 112 //printf("%s\n", oclErrorCode(err)); 113 return;// hardware; 114 } 115 116 cl_context_properties contextData[3] = {CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i], 0}; 117 cl_context context = clCreateContextFromType(contextData, cl_env->device_type, 0, 0, &err); 118 if (err != CL_SUCCESS) { 119 continue; 120 } 121 cl_command_queue queue = clCreateCommandQueue(context, devices[0], 0, &err); 122 if (err != CL_SUCCESS) { 123 //printf("%s\n", oclErrorCode(err)); 124 return; //hardware; 125 } 126 cl_env->platform_id = platforms[i]; 127 cl_env->context = context; 128 cl_env->command_queue = queue; 129 cl_env->device_type = CL_DEVICE_TYPE_ACCELERATOR; 130 cl_env->device_id = devices[0]; 131 break; 132 } 133 134 // 135 // Create the program 136 // 137 unsigned char* xcl_path = getenv("XLNX_XCLBIN_PATH"); 138 if (NULL == xcl_path) 139 { 140 av_log(NULL, AV_LOG_INFO, " * XLNX_XCLBIN_PATH not found\n"); 141 return; 142 } 143 144 char xcl_fullpath[PATH_MAX]; 145 snprintf(xcl_fullpath, sizeof(xcl_fullpath), "%s/hevc_1k1c.xclbin", xcl_path); 146 av_log(NULL, AV_LOG_INFO, " * loading kernel from file %s\n", xcl_fullpath); 147 load_file_to_memory_hevc(xcl_fullpath, &kernelbinary); 148 program = clCreateProgramWithBinary(cl_env->context, 1, &(cl_env->device_id), 149 &kernel_len, (const unsigned char**)&kernelbinary, &status, NULL); 150 if( status != CL_SUCCESS || !program ) 151 { 152 av_log(NULL, AV_LOG_ERROR, "OpenCL unable to create fpga accelerator program\n"); 153 return; 154 } 155 156 // 157 // Build the program 158 // 159 av_log(NULL, AV_LOG_INFO," * Building the program\n"); 160 status = clBuildProgram(program, 1, &(cl_env->device_id), NULL, NULL, NULL); 161 if( status != CL_SUCCESS ) 162 { 163 av_log(NULL, AV_LOG_ERROR, "OpenCL unable to build program\n"); 164 return; 165 } 166 167 // 168 // Create the kernel 169 // 170 av_log(NULL, AV_LOG_INFO," * Creating the HEVC kernel\n"); 171 kernel = clCreateKernel(program, "krnl_ngcodec_hevc_0", &status); //"HEVC_kernel" 172 if( status != CL_SUCCESS ) 173 { 174 av_log(NULL, AV_LOG_ERROR, "OpenCL unable to create kernel\n"); 175 return; 176 } 177 178 // 179 // Setup Source and EncodedFrame Buffers 180 // 181 CurSourceImageSize[Y] = (avctx->width * avctx->height); 182 CurSourceImageSize[U] = (avctx->width * avctx->height) >> 2; 183 CurSourceImageSize[V] = (avctx->width * avctx->height) >> 2; 184 185 // Encoded Frame data size - hard code to allocate host memory as this varies! 186 EncodedFrameSize = (avctx->width * avctx->height * 3) >> 1; 187 EncodedFrameLengthSize = 1; 188 // av_log(NULL, AV_LOG_INFO," * Image Sizes: Source[YUV]=[%d,%d,%d] EncodedFrame=%d\n", 189 // CurSourceImageSize[Y], CurSourceImageSize[U], CurSourceImageSize[V], EncodedFrameSize); 190 191 // 192 // Setup OpenCL Buffers and Kernel Parameters 193 // 194 // av_log(NULL, AV_LOG_INFO," * Creating the kernel buffers\n"); 195 CREATEBUF(CSR3_INPUT_FP_Y_V, CL_MEM_READ_ONLY, CurSourceImageSize[Y] * sizeof(unsigned char)); 196 CREATEBUF(CSR4_INPUT_FP_U_V, CL_MEM_READ_ONLY, CurSourceImageSize[U] * sizeof(unsigned char)); 197 CREATEBUF(CSR5_INPUT_FP_V_V, CL_MEM_READ_ONLY, CurSourceImageSize[V] * sizeof(unsigned char)); 198 CREATEBUF(CSR6_NEXT_FP_Y_V, CL_MEM_READ_ONLY, CurSourceImageSize[Y] * sizeof(unsigned char)); 199 CREATEBUF(CSR7_NEXT_FP_U_V, CL_MEM_READ_ONLY, CurSourceImageSize[U] * sizeof(unsigned char)); 200 // Padding to make reference base pointer of reconstructed picture 128KB aligned 201 CREATEBUF(CSR8_NEXT_FP_V_V, CL_MEM_READ_ONLY, (CurSourceImageSize[V]+ 48*128*1024-1920*1080*3) * sizeof(unsigned char)); 202 // Reference frame requires at least 16MB space in DDR 203 CREATEBUF(CSR12_RECON_BASE_V, CL_MEM_READ_WRITE, 16*1024*1024); 204 CREATEBUF(CSR13_BITSTREAM_BASE_V, CL_MEM_WRITE_ONLY, EncodedFrameSize * sizeof(unsigned char)); 205 CREATEBUF(CSR14_BITSTREAM_LEN_V, CL_MEM_WRITE_ONLY, EncodedFrameLengthSize * sizeof(unsigned long long)); 206 207 // 208 // Send Kernel Parameters 209 // 210 // av_log(NULL, AV_LOG_INFO," * Sending parameters to HEVC kernel\n"); 211 // av_log(NULL, AV_LOG_INFO," * CSR1_FRAME_WIDTH_V: 0x%08x\n", CSR1_FRAME_WIDTH_V); 212 // av_log(NULL, AV_LOG_INFO," * CSR2_FRAME_HEIGHT_V: 0x%08x\n", CSR2_FRAME_HEIGHT_V); 213 // av_log(NULL, AV_LOG_INFO," * CSR3_INPUT_FP_Y_V addr %p\n", &CSR3_INPUT_FP_Y_V); 214 // av_log(NULL, AV_LOG_INFO," * CSR4_INPUT_FP_U_V addr %p\n", &CSR4_INPUT_FP_U_V); 215 // av_log(NULL, AV_LOG_INFO," * CSR5_INPUT_FP_V_V addr %p\n", &CSR5_INPUT_FP_V_V); 216 // av_log(NULL, AV_LOG_INFO," * CSR6_NEXT_FP_Y_V addr %p\n", &CSR6_NEXT_FP_Y_V); 217 // av_log(NULL, AV_LOG_INFO," * CSR7_NEXT_FP_U_V addr %p\n", &CSR7_NEXT_FP_U_V); 218 // av_log(NULL, AV_LOG_INFO," * CSR8_NEXT_FP_V_V addr %p\n", &CSR8_NEXT_FP_V_V); 219 // av_log(NULL, AV_LOG_INFO," * CSR9_BITRATE_V: 0x%08x\n", CSR9_BITRATE_V); 220 // av_log(NULL, AV_LOG_INFO," * CSR10_FIXED_QP_V: 0x%08x\n", CSR10_FIXED_QP_V); 221 // av_log(NULL, AV_LOG_INFO," * CSR11_INTRA_PERIOD_V: 0x%08x\n", CSR11_INTRA_PERIOD_V); 222 // av_log(NULL, AV_LOG_INFO," * CSR12_RECON_BASE_V addr %p\n", &CSR12_RECON_BASE_V); 223 // av_log(NULL, AV_LOG_INFO," * CSR13_BITSTREAM_BASE_V addr %p\n", &CSR13_BITSTREAM_BASE_V); 224 // av_log(NULL, AV_LOG_INFO," * CSR14_BITSTREAM_LEN_V addr %p\n", &CSR14_BITSTREAM_LEN_V); 225 // av_log(NULL, AV_LOG_INFO," * CSR15_RESET_ENCODER_V: 0x%08x\n", CSR15_RESET_ENCODER_V); 226 227 OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(unsigned int), &CSR1_FRAME_WIDTH_V); 228 OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(unsigned int), &CSR2_FRAME_HEIGHT_V); 229 OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &CSR3_INPUT_FP_Y_V); 230 OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &CSR4_INPUT_FP_U_V); 231 OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &CSR5_INPUT_FP_V_V); 232 OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &CSR6_NEXT_FP_Y_V); 233 OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &CSR7_NEXT_FP_U_V); 234 OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &CSR8_NEXT_FP_V_V); 235 OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(unsigned int), &CSR9_BITRATE_V); 236 OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(unsigned int), &CSR10_FIXED_QP_V); 237 OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(unsigned int), &CSR11_INTRA_PERIOD_V); 238 OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &CSR12_RECON_BASE_V); 239 OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &CSR13_BITSTREAM_BASE_V); 240 OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &CSR14_BITSTREAM_LEN_V); 241 OCLCHECK(clSetKernelArg, kernel, arg++, sizeof(unsigned int), &CSR15_RESET_ENCODER_V); 242 return; 243 } 244 245 // 246 // HEVC opencl run function 247 // 248 int ff_hevc_xlnx_hw(AVCodecContext *avctx, AVFrame *pic, uint8_t *dst, uint32_t *dstSize) 249 { 250 size_t global_work_size_1d[1] = {1}; 251 size_t local_work_size_1d[1] = {1}; 252 253 if (frameNumber == 0) 254 { 255 OCLCHECK1(clEnqueueWriteBuffer, cl_env->command_queue, CSR3_INPUT_FP_Y_V, CL_TRUE, 0, CurSourceImageSize[Y] * sizeof(unsigned char), pic->data[Y], 0, NULL, NULL); 256 OCLCHECK1(clEnqueueWriteBuffer, cl_env->command_queue, CSR4_INPUT_FP_U_V, CL_TRUE, 0, CurSourceImageSize[U] * sizeof(unsigned char), pic->data[U], 0, NULL, NULL); 257 OCLCHECK1(clEnqueueWriteBuffer, cl_env->command_queue, CSR5_INPUT_FP_V_V, CL_TRUE, 0, CurSourceImageSize[V] * sizeof(unsigned char), pic->data[V], 0, NULL, NULL); 258 // av_log(NULL, AV_LOG_INFO," * Loading frame %d\n", frameNumber); 259 frameNumber++; 260 return 0; 261 } 262 else if (frameNumber == 1) 263 { 264 OCLCHECK1(clEnqueueWriteBuffer, cl_env->command_queue, CSR6_NEXT_FP_Y_V, CL_TRUE, 0, CurSourceImageSize[Y] * sizeof(unsigned char), pic->data[Y], 0, NULL, NULL); 265 OCLCHECK1(clEnqueueWriteBuffer, cl_env->command_queue, CSR7_NEXT_FP_U_V, CL_TRUE, 0, CurSourceImageSize[U] * sizeof(unsigned char), pic->data[U], 0, NULL, NULL); 266 OCLCHECK1(clEnqueueWriteBuffer, cl_env->command_queue, CSR8_NEXT_FP_V_V, CL_TRUE, 0, CurSourceImageSize[V] * sizeof(unsigned char), pic->data[V], 0, NULL, NULL); 267 // av_log(NULL, AV_LOG_INFO," * Loading frame %d\n", frameNumber); 268 frameNumber++; 269 } 270 else 271 { 272 // Ping-pong buffers used; switch cur and nxt buffer pointer for kernel 273 if (frameNumber%2 == 0) 274 { 275 OCLCHECK1(clSetKernelArg, kernel, 2, sizeof(cl_mem), &CSR6_NEXT_FP_Y_V); 276 OCLCHECK1(clSetKernelArg, kernel, 3, sizeof(cl_mem), &CSR7_NEXT_FP_U_V); 277 OCLCHECK1(clSetKernelArg, kernel, 4, sizeof(cl_mem), &CSR8_NEXT_FP_V_V); 278 OCLCHECK1(clSetKernelArg, kernel, 5, sizeof(cl_mem), &CSR3_INPUT_FP_Y_V); 279 OCLCHECK1(clSetKernelArg, kernel, 6, sizeof(cl_mem), &CSR4_INPUT_FP_U_V); 280 OCLCHECK1(clSetKernelArg, kernel, 7, sizeof(cl_mem), &CSR5_INPUT_FP_V_V); 281 OCLCHECK1(clEnqueueWriteBuffer, cl_env->command_queue, CSR3_INPUT_FP_Y_V, CL_TRUE, 0, CurSourceImageSize[Y] * sizeof(unsigned char), pic->data[Y], 0, NULL, NULL); 282 OCLCHECK1(clEnqueueWriteBuffer, cl_env->command_queue, CSR4_INPUT_FP_U_V, CL_TRUE, 0, CurSourceImageSize[U] * sizeof(unsigned char), pic->data[U], 0, NULL, NULL); 283 OCLCHECK1(clEnqueueWriteBuffer, cl_env->command_queue, CSR5_INPUT_FP_V_V, CL_TRUE, 0, CurSourceImageSize[V] * sizeof(unsigned char), pic->data[V], 0, NULL, NULL); 284 // av_log(NULL, AV_LOG_INFO," * Loading frame %d\n", frameNumber); 285 } 286 else 287 { 288 OCLCHECK1(clSetKernelArg, kernel, 2, sizeof(cl_mem), &CSR3_INPUT_FP_Y_V); 289 OCLCHECK1(clSetKernelArg, kernel, 3, sizeof(cl_mem), &CSR4_INPUT_FP_U_V); 290 OCLCHECK1(clSetKernelArg, kernel, 4, sizeof(cl_mem), &CSR5_INPUT_FP_V_V); 291 OCLCHECK1(clSetKernelArg, kernel, 5, sizeof(cl_mem), &CSR6_NEXT_FP_Y_V); 292 OCLCHECK1(clSetKernelArg, kernel, 6, sizeof(cl_mem), &CSR7_NEXT_FP_U_V); 293 OCLCHECK1(clSetKernelArg, kernel, 7, sizeof(cl_mem), &CSR8_NEXT_FP_V_V); 294 OCLCHECK1(clEnqueueWriteBuffer, cl_env->command_queue, CSR6_NEXT_FP_Y_V, CL_TRUE, 0, CurSourceImageSize[Y] * sizeof(unsigned char), pic->data[Y], 0, NULL, NULL); 295 OCLCHECK1(clEnqueueWriteBuffer, cl_env->command_queue, CSR7_NEXT_FP_U_V, CL_TRUE, 0, CurSourceImageSize[U] * sizeof(unsigned char), pic->data[U], 0, NULL, NULL); 296 OCLCHECK1(clEnqueueWriteBuffer, cl_env->command_queue, CSR8_NEXT_FP_V_V, CL_TRUE, 0, CurSourceImageSize[V] * sizeof(unsigned char), pic->data[V], 0, NULL, NULL); 297 // av_log(NULL, AV_LOG_INFO," * Loading frame %d\n", frameNumber); 298 } 299 frameNumber++; 300 } 301 OCLCHECK1(clEnqueueNDRangeKernel, cl_env->command_queue, kernel, 1, NULL, global_work_size_1d, local_work_size_1d, 0, NULL, NULL); 302 303 // 304 // Wait for the hw accelerator to complete 305 // 306 clFinish(cl_env->command_queue); 307 //av_log(NULL, AV_LOG_INFO," * Finished the xlnx hw accelerator kernel\n"); 308 309 // 310 // Read the result 311 // Get the length of the Encoded Frame first as this varies! 312 // 313 // av_log(NULL, AV_LOG_INFO," * Enqueuing Read Buffer - CSR14_BITSTREAM_LEN_V\n"); 314 OCLCHECK1(clEnqueueReadBuffer, cl_env->command_queue, CSR14_BITSTREAM_LEN_V, CL_TRUE, 0, EncodedFrameLengthSize * sizeof(unsigned int), dstSize, 0, NULL, NULL); 315 // av_log(NULL, AV_LOG_INFO," * Encoded Frame Length = %d\n", *dstSize); 316 //*dstSize = *dstSize * 4; 317 318 // av_log(NULL, AV_LOG_INFO," * Enqueuing Read Buffer - CSR13_BITSTREAM_BASE_V\n"); 319 OCLCHECK1(clEnqueueReadBuffer, cl_env->command_queue, CSR13_BITSTREAM_BASE_V, CL_TRUE, 0, (*dstSize) * sizeof(unsigned char), dst, 0, NULL, NULL); 320 321 return 0; 322 } 323 324 // 325 // HEVC exit function 326 // 327 void ff_uninit_hevc_xlnx_hw(AVCodecContext *avctx) 328 { 329 // av_log(NULL, AV_LOG_INFO," * Tidying up ... releasing OpenCL Objects\n"); 330 clReleaseKernel(kernel); 331 clReleaseProgram(program); 332 clReleaseMemObject(CSR3_INPUT_FP_Y_V); 333 clReleaseMemObject(CSR4_INPUT_FP_U_V); 334 clReleaseMemObject(CSR5_INPUT_FP_V_V); 335 clReleaseMemObject(CSR6_NEXT_FP_Y_V); 336 clReleaseMemObject(CSR7_NEXT_FP_U_V); 337 clReleaseMemObject(CSR8_NEXT_FP_V_V); 338 clReleaseMemObject(CSR13_BITSTREAM_BASE_V); 339 clReleaseMemObject(CSR14_BITSTREAM_LEN_V); 340 } 341 342 int load_file_to_memory_hevc(const char *filename, unsigned char **result) 343 { 344 int size = 0; 345 FILE *f = fopen(filename, "rb"); 346 if(f == NULL) 347 { 348 *result = NULL; 349 return -1; // -1 means file opening fail 350 } 351 fseek(f, 0, SEEK_END); 352 size = ftell(f); 353 fseek(f, 0, SEEK_SET); 354 *result = malloc(size); 355 if(size != fread(*result, sizeof(char), size, f)) 356 { 357 free(*result); 358 return -2; // -2 means file reading fail 359 } 360 fclose(f); 361 return size; 362 } 363 -
new file libavcodec/xlnx_hevc/xlnx_hevc_config.h
diff --git a/libavcodec/xlnx_hevc/xlnx_hevc_config.h b/libavcodec/xlnx_hevc/xlnx_hevc_config.h new file mode 100644 index 0000000..18dd33e
- + 1 #ifndef _XLNX_HEVC_CONFIG_H_ 2 #define _XLNX_HEVC_CONFIG_H_ 3 4 #include "libavcodec/avcodec.h" 5 6 //Macros 7 #define OCLCHECK(method, ... ) \ 8 do { \ 9 status = method(__VA_ARGS__); \ 10 if (status != CL_SUCCESS) { \ 11 av_log(NULL, AV_LOG_ERROR, # method " error '%s'\n", \ 12 av_opencl_errstr(status)); \ 13 return; \ 14 } \ 15 } while (0) 16 17 #define OCLCHECK1(method, ... ) \ 18 do { \ 19 status = method(__VA_ARGS__); \ 20 if (status != CL_SUCCESS) { \ 21 av_log(NULL, AV_LOG_ERROR, # method " error '%s'\n", \ 22 av_opencl_errstr(status)); \ 23 return AVERROR_EXTERNAL; \ 24 } \ 25 } while (0) 26 27 #define CREATEBUF(out, flags, size) \ 28 do { \ 29 out = clCreateBuffer(cl_env->context, flags, size, NULL, &status); \ 30 if (status != CL_SUCCESS) { \ 31 av_log(NULL, AV_LOG_ERROR, "Could not create OpenCL buffer\n"); \ 32 return; \ 33 } \ 34 } while (0) 35 36 //Typedefs 37 typedef enum 38 { 39 Y = 0, 40 U = 1, 41 V = 2 42 }col_fmt_t; 43 44 //Function Prototypes 45 void ff_init_hevc_xlnx_hw(AVCodecContext *c); 46 void ff_uninit_hevc_xlnx_hw(AVCodecContext *c); 47 int ff_hevc_xlnx_hw(AVCodecContext *avctx, AVFrame *pic, uint8_t *dst, uint32_t *dstSize); 48 49 #endif //_XLNX_HEVC_CONFIG_H_ 50 -
new file libavcodec/xlnx_hevc_enc.c
diff --git a/libavcodec/xlnx_hevc_enc.c b/libavcodec/xlnx_hevc_enc.c new file mode 100644 index 0000000..93c5d5b
- + 1 /* 2 * Xilinx HEVC NGCodec encoder 3 * 4 * Copyright (C) 2015 Xilinx Inc. 5 * 6 * This file is part of FFmpeg. 7 * 8 * FFmpeg is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * FFmpeg is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with FFmpeg; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 #include <stdio.h> 23 #include "avcodec.h" 24 #include "internal.h" 25 #include "xlnx_hw/xlnx_hw.h" 26 #include "pthread.h" 27 #include <sys/types.h> 28 #include <sys/syscall.h> 29 #include "xlnx_hw/common/inc/xlnx_queue.h" 30 #include "xlnx_hw/common/inc/xlnx_hw_defines.h" 31 32 typedef struct EncodeRequest { 33 xlnx_cmp_buf iBuf; 34 xlnx_hw_buf iBufHdr; 35 xlnx_data_buf out; 36 xlnx_hw_buf oBufHdr; 37 AVFrame* pic; 38 } 39 EncodeRequest; 40 41 typedef struct XlnxHevcContext { 42 xlnx_hw hw; 43 HevcEncParam params; 44 xlnx_queue* rQ; 45 int frame; 46 } 47 XlnxHevcContext; 48 49 static EncodeRequest* createEncReq(const AVFrame* pic, size_t aEncodeSize) { 50 EncodeRequest* req; 51 xlnx_data_buf* tmp; 52 req = av_mallocz(sizeof(EncodeRequest)); 53 if (NULL == req) { 54 av_log(NULL, AV_LOG_ERROR,"Error: Cannot allocate memory %s at %d\n", __FILE__, __LINE__); 55 return NULL; 56 } 57 //input 58 req->iBufHdr.type = ERAW; 59 req->oBufHdr.type = EDATA; 60 if (pic != NULL) { 61 req->pic = av_frame_clone(pic); 62 if (NULL == req->pic) { 63 av_log(NULL, AV_LOG_ERROR,"Error: Cannot allocate memory %s at %d\n", __FILE__, __LINE__); 64 av_free(req); 65 return NULL; 66 } 67 tmp = (xlnx_data_buf*)&req->iBuf; 68 for (int i = 0; i < 3; i++) { 69 tmp[i].pDATA = req->pic->data[i]; 70 tmp[i].offset = 0; 71 tmp[i].size = req->pic->linesize[i] * req->pic->height; 72 } 73 req->iBufHdr.ptr = &req->iBuf; 74 // output 75 req->out.pDATA = av_malloc(aEncodeSize); 76 if (NULL == req->out.pDATA) { 77 av_log(NULL, AV_LOG_ERROR,"Error: Cannot allocate memory %s at %d\n", __FILE__, __LINE__); 78 av_frame_unref(req->pic); 79 return NULL; 80 } 81 req->out.size = aEncodeSize; 82 req->oBufHdr.ptr = &req->out; 83 } else { 84 req->iBufHdr.ptr = NULL; 85 req->oBufHdr.ptr = NULL; 86 } 87 88 return req; 89 } 90 91 static void destroyEncInput(EncodeRequest* aReq) { 92 if (aReq->pic) { 93 av_frame_unref(aReq->pic); 94 av_frame_free(&aReq->pic); 95 } 96 } 97 98 static void destroyEncOut(EncodeRequest* aReq) { 99 if(aReq->out.pDATA) av_free(aReq->out.pDATA); 100 } 101 102 static int destroyEncReq(EncodeRequest* aReq) { 103 destroyEncInput(aReq); 104 destroyEncOut(aReq); 105 av_free(aReq); 106 return 0; 107 } 108 109 static void hevc_init_params(AVCodecContext *avctx, HevcEncParam* params) { 110 params->width = avctx->width; 111 params->height = avctx->height; 112 params->ip = avctx->gop_size; 113 params->bitrate = avctx->bit_rate; 114 params->qp = avctx->global_quality; 115 if (params->qp > 51) { 116 // Constant bitrate mode 117 av_log(NULL, AV_LOG_INFO, " * Encoding in constant bitrate mode***\n"); 118 } else { 119 // Fixed QP mode 120 av_log(NULL, AV_LOG_INFO, " * Encoding in fixed QP mode***\n"); 121 } 122 params->reset = 0; 123 return; 124 } 125 static int isSupported(AVCodecContext *avctx) { 126 //Supported 1080p60, 8bits 127 // height and width should be a multiple of 4 128 // minimum resolution is 352x288 129 int width, height; 130 width = avctx->width; 131 height = avctx->height; 132 if (((width & 3) != 0) || ((height & 3) != 0)) { 133 av_log(NULL, AV_LOG_ERROR,"ERROR:height and width should be a multiple of 4\n"); 134 return -1; 135 } 136 if ((width < 352 || height < 288) && 137 (width < 288 || height < 352)) { 138 av_log(NULL, AV_LOG_ERROR,"ERROR: min resolution supported is 352x288\n"); 139 return -1; 140 } 141 switch(avctx->pix_fmt) { 142 case AV_PIX_FMT_YUV420P: 143 avctx->bits_per_raw_sample = 8; 144 break; 145 default: 146 av_log(NULL, AV_LOG_ERROR,"ERROR: Pixel format not supported...\n"); 147 return -1; 148 break; 149 } 150 return 0; 151 } 152 153 static int xlnx_hevc_encode_init(AVCodecContext *avctx) { 154 XlnxHevcContext* hevc; 155 HevcEncParam* params; 156 if (isSupported(avctx) < 0) { 157 return AVERROR(ENOSYS); 158 } 159 hevc = (XlnxHevcContext*)avctx->priv_data; 160 params = &hevc->params; 161 hevc_init_params(avctx, params); 162 hevc->rQ = createQueue(HEVC_ENC_OUT_Q_CAPACITY); 163 if (NULL == hevc->rQ) return -1; 164 hevc->hw = xlnx_hw_get(EHevcEnc, params); 165 if (NULL == hevc->hw) { 166 av_log(NULL, AV_LOG_ERROR,"ERROR: Failed to get EHevcEnc handle\n"); 167 return AVERROR(EINVAL); 168 } 169 return 0; 170 } 171 172 static int xlnx_hevc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pic, int *got_packet) { 173 XlnxHevcContext* hevc = (XlnxHevcContext*)avctx->priv_data; 174 int EntrySize = avctx->bits_per_raw_sample == 8 ? 1 : 2; 175 int ret; 176 int EntryCount = 0; 177 uint64_t EncodeBuffSize = 0; 178 int width, height, format; 179 EncodeRequest* req; 180 xlnx_hw_buf* outBuf; 181 void* nullptr; 182 HevcEncParam* params = &hevc->params; 183 if (NULL == pic) { 184 av_log(NULL, AV_LOG_DEBUG, "xlnx_hevc_encode_frame EOS Received\n"); 185 if (params->reset == 0) { 186 params->reset = 1; 187 } else if (params->reset == 2) { 188 *got_packet = 0; 189 return 0; 190 } 191 width = avctx->width; 192 height = avctx->height; 193 format = avctx->pix_fmt; 194 } else { 195 width = pic->width; 196 height = pic->height; 197 format = pic->format; 198 } 199 200 switch(format) { 201 case AV_PIX_FMT_YUV420P: 202 EntryCount = 2; 203 break; 204 default: 205 av_log(NULL, AV_LOG_ERROR,"Error. Encoding unknown pixel format.\n"); 206 return AVERROR_INVALIDDATA; 207 break; 208 } 209 210 EncodeBuffSize = EntryCount * width * height * EntrySize; 211 212 req = createEncReq(pic, EncodeBuffSize); 213 if (req == NULL) { 214 return -1; 215 } 216 outBuf = &req->oBufHdr; 217 nullptr = NULL; 218 ret = xlnx_hw_process_async(hevc->hw, &hevc->params, &req->iBufHdr, &outBuf, &nullptr); 219 if (ret < 0) { 220 *got_packet = 0; 221 destroyEncReq(req); 222 return AVERROR(EINVAL); 223 } else if (ret == 0) { 224 *got_packet = 0; 225 enqueue(hevc->rQ, (XItem)req); 226 return 0; 227 } else if (ret == 1) { 228 EncodeRequest* tmpReq = (EncodeRequest*)dequeue(hevc->rQ); 229 xlnx_data_buf* ptr = outBuf->ptr; 230 assert(tmpReq->out.pDATA == ptr->pDATA); 231 av_packet_from_data(pkt, ptr->pDATA, ptr->size); 232 pkt->pts = pkt->dts = (int64_t)tmpReq->pic->pts; 233 destroyEncInput(tmpReq); 234 av_free(tmpReq); 235 enqueue(hevc->rQ, (XItem)req); 236 *got_packet = 1; 237 } else if (ret == 2) { 238 *got_packet = 0; 239 params->reset = 2; 240 } 241 return 0; 242 } 243 244 static int xlnx_hevc_encode_close(AVCodecContext *avctx) { 245 XlnxHevcContext* hevc = (XlnxHevcContext*)avctx->priv_data; 246 xlnx_hw_release(hevc->hw); 247 if (hevc->rQ) { 248 while(!isEmpty(hevc->rQ)) { 249 EncodeRequest* req = (EncodeRequest*)dequeue(hevc->rQ); 250 destroyEncReq(req); 251 } 252 destroyQueue(hevc->rQ); 253 } 254 return 0; 255 } 256 257 AVCodec ff_xlnx_hevc_encoder = { 258 .name = "xlnx_hevc_enc", 259 .long_name = NULL_IF_CONFIG_SMALL("Xilinx High Efficiency Video Codec (H.265) Encoder"), 260 .type = AVMEDIA_TYPE_VIDEO, 261 .id = AV_CODEC_ID_HEVC, 262 .priv_data_size = sizeof(XlnxHevcContext), 263 .init = xlnx_hevc_encode_init, 264 .encode2 = xlnx_hevc_encode_frame, 265 .close = xlnx_hevc_encode_close, 266 .capabilities = CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, 267 .pix_fmts = (const enum AVPixelFormat[]) { 268 AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE 269 }, 270 }; 271 -
new file libavcodec/xlnx_hw/Makefile
diff --git a/libavcodec/xlnx_hw/Makefile b/libavcodec/xlnx_hw/Makefile new file mode 100644 index 0000000..dddd044
- + 1 OBJS += xlnx_hw/xlnx_hw.o 2 OBJS += xlnx_hw/xlnx_hrm.o 3 OBJS += xlnx_hw/xcl.o -
new file libavcodec/xlnx_hw/common/inc/xcl.h
diff --git a/libavcodec/xlnx_hw/common/inc/xcl.h b/libavcodec/xlnx_hw/common/inc/xcl.h new file mode 100755 index 0000000..327837c
- + 1 #ifndef XCL_H 2 #define XCL_H 3 4 #include <CL/opencl.h> 5 #include "xlnx_types_internal.h" 6 7 int xcl_GetPlatform(const char* platform, cl_platform_id* id); 8 int xcl_CreateContextFromType(const cl_platform_id* id, cl_device_type aType, 9 cl_context* aContext); 10 int xcl_ReleaseContext(cl_context* aContext); 11 int xcl_GetDeviceList(const cl_platform_id* id, cl_device_type aType, 12 xlnx_device** aDeviceList, cl_uint* aNumDevices); 13 int xcl_FreeDeviceList(xlnx_device* aDeviceList, cl_uint aNumDevices); 14 int xcl_IsDeviceAvailable(cl_device_id aDevice); 15 int xcl_ImportBinaryHeader(cl_context* aContext, cl_device_id* aDevice, 16 const char *xclbin, size_t aBinaryLength, cl_program* aProgram); 17 int xcl_ImportBinary(cl_context* aContext, cl_device_id* aDevice, 18 const char *xclbin_file_name, cl_program* aProgram); 19 int xcl_ReleaseProgram(cl_program* aProgram); 20 int xcl_CreateKernels(cl_context* aContext, cl_device_id* aDevice, 21 cl_program* aProgram, const char** aKernelNames, uint32_t aNumKernels, 22 xlnx_kernel** aKernelList); 23 int xcl_CreateKernels2(cl_context* aContext, cl_device_id* aDevice, 24 cl_program* aProgram, const KRNL_CONFIG* aKernelConfig, uint32_t aNumKernels, 25 xlnx_kernel** aKernelList); 26 int xcl_FreeKernels(xlnx_kernel* aKernelList, uint32_t aNumKernels); 27 28 #endif //XCL_H 29 No newline at end of file -
new file libavcodec/xlnx_hw/common/inc/xlnx_hrm.h
diff --git a/libavcodec/xlnx_hw/common/inc/xlnx_hrm.h b/libavcodec/xlnx_hw/common/inc/xlnx_hrm.h new file mode 100644 index 0000000..1f38d58
- + 1 #ifndef XLNX_HRM_H 2 #define XLNX_HRM_H 3 4 #include "../../xlnx_hw_types.h" 5 #include "../inc/xlnx_types_internal.h" 6 7 int xlnx_hrm_init(const char* aCfgFileName, xlnx_hw_id aHWID); 8 int xlnx_hrm_deinit(void); 9 xlnx_host* xlnx_hrm_get_host(xlnx_hw_id aHWID, xlnx_hw_params aParams); 10 int xlnx_hrm_release_host(xlnx_host* aHost); 11 12 #endif //XLNX_HRM_H -
new file libavcodec/xlnx_hw/common/inc/xlnx_hw_defines.h
diff --git a/libavcodec/xlnx_hw/common/inc/xlnx_hw_defines.h b/libavcodec/xlnx_hw/common/inc/xlnx_hw_defines.h new file mode 100644 index 0000000..deb7913
- + 1 #ifndef XLNX_HW_DEFINES_H 2 #define XLNX_HW_DEFINES_H 3 4 #define RESET_UPPER_16 0x0000FFFF 5 #define RESET_LOWER_16 0xFFFF0000 6 7 #define FILE_PATH_LENGTH 1024 8 #define LOAD_BINARY_FROM_HEADER 0 9 #define VU9P_HEVC_ENC_2_K 1 10 #define VU9P_HEVC_ENC_NUM_CH 2 11 12 #define HEVC_KRNL_CH_Q_CAPACITY 3 13 #define HEVC_ENC_IN_Q_CAPACITY 2 14 #define HEVC_ENC_OUT_Q_CAPACITY (HEVC_ENC_IN_Q_CAPACITY + HEVC_KRNL_CH_Q_CAPACITY + 1) 15 16 #define OCLCHECK(method, ... ) \ 17 do { \ 18 status = method(__VA_ARGS__); \ 19 if (status != CL_SUCCESS) { \ 20 printf( # method " error '%d'\n", status); \ 21 return -1; \ 22 } \ 23 } while (0) 24 25 #define ENQUEUEBUF(method, dst) \ 26 do { \ 27 status = method(cmdQ, dst, CL_TRUE, 0, size, iHBuf[i].pDATA, 0, NULL, NULL);\ 28 if (CL_SUCCESS != status) { \ 29 printf(# method " failed, error %d\n", status); \ 30 return -1; \ 31 } \ 32 } while (0) 33 34 #endif //XLNX_HW_DEFINES_H 35 No newline at end of file -
new file libavcodec/xlnx_hw/common/inc/xlnx_queue.h
diff --git a/libavcodec/xlnx_hw/common/inc/xlnx_queue.h b/libavcodec/xlnx_hw/common/inc/xlnx_queue.h new file mode 100644 index 0000000..a995c45
- + 1 #ifndef XLNX_QUEUE_H 2 #define XLNX_QUEUE_H 3 4 typedef void* XItem; 5 typedef struct xlnx_queue xlnx_queue; 6 7 xlnx_queue* createQueue(size_t capacity); 8 void destroyQueue(xlnx_queue* queue); 9 int isFull(xlnx_queue* queue); 10 int isEmpty(xlnx_queue* queue); 11 size_t getSize(xlnx_queue* queue); 12 int enqueue(xlnx_queue* queue, XItem item); 13 XItem dequeue(xlnx_queue* queue); 14 XItem front(xlnx_queue* queue); 15 XItem rear(xlnx_queue* queue); 16 17 #endif // XLNX_QUEUE_H 18 No newline at end of file -
new file libavcodec/xlnx_hw/common/inc/xlnx_ts_queue.h
diff --git a/libavcodec/xlnx_hw/common/inc/xlnx_ts_queue.h b/libavcodec/xlnx_hw/common/inc/xlnx_ts_queue.h new file mode 100644 index 0000000..ff66fc7
- + 1 #ifndef XLNX_TS_QUEUE_H 2 #define XLNX_TS_QUEUE_H 3 4 #include "xlnx_queue.h" 5 6 typedef struct xlnx_ts_queue xlnx_ts_queue; 7 8 xlnx_ts_queue* createTSQ(size_t capacity); 9 void destroyTSQ(xlnx_ts_queue* queue); 10 int isFullTSQ(xlnx_ts_queue* queue); 11 int isEmptyTSQ(xlnx_ts_queue* queue); 12 size_t getSizeTSQ(xlnx_ts_queue* queue); 13 int enqueueTSQ(xlnx_ts_queue* queue, XItem item); 14 XItem dequeueTSQ(xlnx_ts_queue* queue); 15 XItem frontTSQ(xlnx_ts_queue* queue); 16 XItem rearTSQ(xlnx_ts_queue* queue); 17 18 #endif // XLNX_TS_QUEUE_H 19 No newline at end of file -
new file libavcodec/xlnx_hw/common/inc/xlnx_types_internal.h
diff --git a/libavcodec/xlnx_hw/common/inc/xlnx_types_internal.h b/libavcodec/xlnx_hw/common/inc/xlnx_types_internal.h new file mode 100644 index 0000000..174a793
- + 1 #ifndef XLNX_TYPES_INTERNAL_H 2 #define XLNX_TYPES_INTERNAL_H 3 4 #include <CL/opencl.h> 5 #include "../../xlnx_hw_types.h" 6 7 typedef struct { 8 char* devName; 9 cl_device_id device; 10 uint32_t majorV; 11 uint32_t minorV; 12 void* privData; 13 } xlnx_device; 14 15 typedef struct xlnx_kernel { 16 cl_context* context; 17 cl_command_queue cmdQ; 18 cl_kernel kernel; 19 U32 prfBank; 20 void* appData; 21 void* privData; 22 } xlnx_kernel; 23 24 typedef struct xlnx_host xlnx_host; 25 typedef int (*Run)(xlnx_host* aHost, xlnx_hw_params aParams, xlnx_hw_buf* aInput, xlnx_hw_buf* aOutput); 26 typedef int (*RunAsync)(xlnx_host* aHost, xlnx_hw_params aParams, xlnx_hw_buf* aInput, xlnx_hw_buf** aOutput, XContext* aContext); 27 28 struct xlnx_host { 29 int ch; 30 Run process; 31 RunAsync processAsync; 32 int eosRcv; 33 void* appData; 34 void* privData; 35 }; 36 37 typedef enum { 38 Y = 0, 39 U = 1, 40 V = 2 41 } xlnx_col_fmt; 42 43 typedef struct { 44 const char* krnl_name; 45 U32 prfBank; 46 } KRNL_CONFIG; 47 48 49 #endif //XLNX_TYPES_INTERNAL_H 50 No newline at end of file -
new file libavcodec/xlnx_hw/common/src/xcl.c
diff --git a/libavcodec/xlnx_hw/common/src/xcl.c b/libavcodec/xlnx_hw/common/src/xcl.c new file mode 100755 index 0000000..9e2eaf1
- + 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <limits.h> 5 #include <string.h> 6 7 #include "../inc/xcl.h" 8 #include "CL/cl_ext.h" 9 10 // Wrap any OpenCL API calls that return error code(cl_int) 11 // with the below macro to quickly check for an error 12 #define OCL_CHECK(call) \ 13 do { \ 14 cl_int err = call; \ 15 if (err != CL_SUCCESS) { \ 16 printf("Error from " #call ", error code is %d\n", err); \ 17 return err; \ 18 } \ 19 } while (0); 20 21 static void* smalloc(size_t size) { 22 void* ptr; 23 ptr = malloc(size); 24 if (ptr == NULL) { 25 printf("Error: Cannot allocate memory %s at %d\n", __FILE__, __LINE__); 26 return NULL; 27 } 28 return ptr; 29 } 30 31 static int load_file_to_memory(const char *filename, char **result) { 32 unsigned int size; 33 FILE* f; 34 35 f = fopen(filename, "rb"); 36 if (f == NULL) { 37 *result = NULL; 38 printf("Error: Could not read file %s\n", filename); 39 return -1; 40 } 41 42 fseek(f, 0, SEEK_END); 43 size = ftell(f); 44 fseek(f, 0, SEEK_SET); 45 46 *result = (char *) smalloc(sizeof(char)*(size+1)); 47 48 if (size != fread(*result, sizeof(char), size, f)) { 49 free(*result); 50 fclose(f); 51 printf("Error: read of kernel failed\n"); 52 return -1; 53 } 54 55 fclose(f); 56 (*result)[size] = 0; 57 58 return size; 59 } 60 // 61 // Get device version 62 // 63 static int getDeviceVersion(cl_device_id* aDevice, uint32_t* aMajor, uint32_t* aMinor) 64 { 65 char versionString[512]; 66 size_t size = 0; 67 uint32_t major = 0; 68 uint32_t minor = 0; 69 uint32_t state = 0; 70 cl_int err; 71 err = clGetDeviceInfo(*aDevice, CL_DEVICE_VERSION, 511, versionString, &size); 72 if ( err != CL_SUCCESS) { 73 printf("clGetDeviceInfo(CL_DEVICE_VERSION) Failed\n"); 74 return -1; 75 } 76 size = strlen(versionString); 77 for (size_t i = 0; i < size; i++) { 78 if (versionString[i] == ' ') { 79 if (0 == state) 80 state++; 81 else 82 break; 83 continue; 84 } 85 if (versionString[i] == '.') { 86 state++; 87 continue; 88 } 89 if (state == 0) { 90 continue; 91 } 92 if (state == 1) { 93 major *= 10; 94 major += (versionString[i] - '0'); 95 continue; 96 } 97 if (state == 2) { 98 minor *= 10; 99 minor += (versionString[i] - '0'); 100 continue; 101 } 102 break; 103 } 104 *aMajor = major; 105 *aMinor = minor; 106 return -1; 107 } 108 109 int xcl_GetPlatform(const char* platform, cl_platform_id* id) { 110 int err = -1; 111 cl_uint num_platforms = 0; 112 cl_platform_id* platform_ids; 113 size_t i; 114 char* platform_name; 115 116 if ((platform == NULL) || (id == NULL)) return -1; 117 118 err = clGetPlatformIDs(0, NULL, &num_platforms); 119 if (err != CL_SUCCESS) { 120 printf("Error: no platforms available or OpenCL install broken\n"); 121 return err; 122 } 123 124 platform_ids = (cl_platform_id *) malloc(num_platforms * sizeof(cl_platform_id)); 125 if (platform_ids == NULL) { 126 printf("Error: Out of Memory %s at %d\n", __FILE__, __LINE__); 127 return -1; 128 } 129 130 err = clGetPlatformIDs(num_platforms, platform_ids, NULL); 131 if (err != CL_SUCCESS) { 132 printf("Error: Failed to find an OpenCL platform!\n"); 133 free(platform_ids); 134 return err; 135 } 136 137 for(i = 0; i < num_platforms; i++) { 138 size_t platform_name_size; 139 err = clGetPlatformInfo(platform_ids[i], CL_PLATFORM_NAME, 140 0, NULL, &platform_name_size); 141 if( err != CL_SUCCESS) { 142 printf("Error: Could not determine platform name!\n"); 143 return err; 144 } 145 146 platform_name = (char*) malloc(sizeof(char)*platform_name_size); 147 if(platform_name == NULL) { 148 printf("Error: out of memory! %s at %d\n", __FILE__, __LINE__); 149 free(platform_ids); 150 return -1; 151 } 152 153 err = clGetPlatformInfo(platform_ids[i], CL_PLATFORM_NAME, 154 platform_name_size, platform_name, NULL); 155 if(err != CL_SUCCESS) { 156 free(platform_ids); 157 free(platform_name); 158 printf("Error: could not determine platform name!\n"); 159 return err; 160 } 161 162 if (!strcmp(platform_name, platform)) { 163 free(platform_name); 164 *id = platform_ids[i]; 165 break; 166 } 167 168 free(platform_name); 169 } 170 171 free(platform_ids); 172 173 if (i == num_platforms) { 174 printf("Error: Failed to find Xilinx platform\n"); 175 return -1; 176 } 177 return 0; 178 } 179 180 int xcl_CreateContextFromType(const cl_platform_id* id, cl_device_type aType, cl_context* aContext) { 181 int err; 182 cl_context_properties contextData[3]; 183 184 if ((id == NULL) || (aContext == NULL)) return -1; 185 err = -1; 186 contextData[0] = CL_CONTEXT_PLATFORM; 187 contextData[1] = (cl_context_properties)*id; 188 contextData[2] = 0; 189 *aContext = clCreateContextFromType(contextData, aType, 0, 0, &err); 190 if (err != CL_SUCCESS) { 191 return -1; 192 } 193 return 0; 194 } 195 196 int xcl_ReleaseContext(cl_context* aContext) { 197 if (aContext == NULL) return -1; 198 OCL_CHECK(clReleaseContext(*aContext)); 199 return 0; 200 } 201 202 int xcl_GetDeviceList(const cl_platform_id* id, cl_device_type aType, xlnx_device** aDeviceList, cl_uint* aNumDevices) { 203 int err; 204 int i; 205 cl_uint num_devices; 206 xlnx_device* devices; 207 cl_device_id* deviceIDs; 208 size_t device_name_size; 209 210 if ((id) == NULL || (aDeviceList == NULL) || (aNumDevices == NULL)) return -1; 211 err = -1; 212 num_devices = 0; 213 214 err = clGetDeviceIDs(*id, aType, 0, NULL, &num_devices); 215 if (err != CL_SUCCESS) { 216 printf("Error: no ACCELERATOR devices available\n"); 217 return err; 218 } 219 220 deviceIDs = (cl_device_id *) malloc(sizeof(cl_device_id) * num_devices); 221 if (deviceIDs == NULL) { 222 printf("Error: Out of Memory %s at %d\n", __FILE__, __LINE__); 223 return -1; 224 } 225 226 err = clGetDeviceIDs(*id, aType, num_devices, deviceIDs, NULL); 227 if (err != CL_SUCCESS) { 228 free(deviceIDs); 229 printf("Error: could not get device ids\n"); 230 return err; 231 } 232 233 234 devices = (xlnx_device *) calloc(num_devices, sizeof(xlnx_device)); 235 if (devices == NULL) { 236 free(deviceIDs); 237 printf("Error: Out of Memory %s at %d\n", __FILE__, __LINE__); 238 return -1; 239 } 240 241 for (i = 0; i < num_devices; i++) { 242 err = clGetDeviceInfo(deviceIDs[i], CL_DEVICE_NAME, 243 0, NULL, &device_name_size); 244 if(err != CL_SUCCESS) { 245 free(deviceIDs); 246 if (i>0) { 247 xcl_FreeDeviceList(devices, i); 248 } 249 printf("Error: could not determine device name\n"); 250 return err; 251 } 252 253 devices[i].devName = (char*) malloc(sizeof(char)*device_name_size); 254 if(devices[i].devName == NULL) { 255 free(deviceIDs); 256 xcl_FreeDeviceList(devices, i+1); 257 printf("Error: Out of Memory! %s at %d\n", __FILE__, __LINE__); 258 return -1; 259 } 260 261 err = clGetDeviceInfo(deviceIDs[i], CL_DEVICE_NAME, 262 device_name_size, devices[i].devName, NULL); 263 if(err != CL_SUCCESS) { 264 free(deviceIDs); 265 xcl_FreeDeviceList(devices, i+1); 266 printf("Error: could not determine device name\n"); 267 return err; 268 } 269 getDeviceVersion(&deviceIDs[i], &devices[i].majorV, &devices[i].minorV); 270 printf("Found %s : version %d.%d\n", devices[i].devName, devices[i].majorV, devices[i].minorV); 271 devices[i].device = deviceIDs[i]; 272 } 273 free(deviceIDs); 274 *aNumDevices = num_devices; 275 *aDeviceList = devices; 276 return 0; 277 } 278 279 int xcl_FreeDeviceList(xlnx_device* aDeviceList, cl_uint aNumDevices) { 280 if (aDeviceList == NULL) return -1; 281 for (int i=0; i<aNumDevices; i++) { 282 if (aDeviceList[i].devName) 283 free(aDeviceList[i].devName); 284 } 285 free(aDeviceList); 286 return 0; 287 } 288 289 int xcl_IsDeviceAvailable(cl_device_id aDevice) { 290 cl_bool avail = CL_TRUE; 291 OCL_CHECK(clGetDeviceInfo(aDevice, CL_DEVICE_AVAILABLE, 292 sizeof(cl_bool), &avail, NULL)); 293 if (avail == CL_FALSE) { 294 printf("Error: device busy!!\n"); 295 return 0; 296 } 297 return 1; 298 } 299 300 int xcl_ImportBinaryHeader(cl_context* aContext, cl_device_id* aDevice, 301 const char *xclbin, size_t aBinaryLength, cl_program* aProgram) { 302 int err; 303 cl_program program; 304 size_t len; 305 char buffer[2048]; 306 if ((aContext == NULL) || (aDevice == NULL) || (xclbin == NULL ) || 307 (aBinaryLength == 0) || (aProgram == NULL)) 308 return -1; 309 310 err = -1; 311 program = clCreateProgramWithBinary(*aContext, 1, 312 aDevice, &aBinaryLength, 313 (const unsigned char **) &xclbin, 314 NULL, &err); 315 if ((!program) || (err!=CL_SUCCESS)) { 316 printf("Error: Failed to create compute program from binary %d!\n", err); 317 return -1; 318 } 319 320 err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL); 321 if (err != CL_SUCCESS) { 322 xcl_ReleaseProgram(&program); 323 324 clGetProgramBuildInfo(program, *aDevice, CL_PROGRAM_BUILD_LOG, 325 sizeof(buffer), buffer, &len); 326 printf("%s\n", buffer); 327 printf("Error: Failed to build program executable!\n"); 328 return -1; 329 } 330 *aProgram = program; 331 return 0; 332 } 333 334 int xcl_ImportBinary(cl_context* aContext, cl_device_id* aDevice, 335 const char *xclbin_file_name, cl_program* aProgram) { 336 int err; 337 char* krnl_bin; 338 size_t krnl_size; 339 cl_program program; 340 size_t len; 341 char buffer[2048]; 342 343 if ((aContext == NULL) || (aDevice == NULL) || 344 (xclbin_file_name == NULL ) || (aProgram == NULL)) 345 return -1; 346 347 if(access(xclbin_file_name, R_OK) != 0) { 348 printf("ERROR: %s xclbin not available please build\n", xclbin_file_name); 349 return -1; 350 } 351 352 krnl_size = load_file_to_memory(xclbin_file_name, &krnl_bin); 353 program = clCreateProgramWithBinary(*aContext, 1, 354 aDevice, &krnl_size, 355 (const unsigned char**) &krnl_bin, 356 NULL, &err); 357 if ((!program) || (err!=CL_SUCCESS)) { 358 free(krnl_bin); 359 printf("Error: Failed to create compute program from binary %d!\n", 360 err); 361 return -1; 362 } 363 364 err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL); 365 if (err != CL_SUCCESS) { 366 xcl_ReleaseProgram(&program); 367 free(krnl_bin); 368 369 clGetProgramBuildInfo(program, *aDevice, CL_PROGRAM_BUILD_LOG, 370 sizeof(buffer), buffer, &len); 371 printf("%s\n", buffer); 372 printf("Error: Failed to build program executable!\n"); 373 return -1; 374 } 375 *aProgram = program; 376 free(krnl_bin); 377 378 return 0; 379 } 380 381 int xcl_ReleaseProgram(cl_program* aProgram) { 382 if (aProgram == NULL) { return -1;} 383 OCL_CHECK(clReleaseProgram(*aProgram)); 384 return 0; 385 } 386 387 int xcl_CreateKernels(cl_context* aContext, cl_device_id* aDevice, 388 cl_program* aProgram, const char** aKernelNames, uint32_t aNumKernels, 389 xlnx_kernel** aKernelList) { 390 int err = -1; 391 xlnx_kernel* kList; 392 int i; 393 394 if ((aContext == NULL) || (aDevice == NULL) || 395 (aProgram == NULL ) || (aKernelNames == NULL) || (aNumKernels == 0)) { 396 return -1; 397 } 398 err = -1; 399 kList = (xlnx_kernel*)calloc(aNumKernels, sizeof(xlnx_kernel)); 400 if (kList == NULL) { 401 printf("Error: Out of Memory! %s at %d\n", __FILE__, __LINE__); 402 return -1; 403 } 404 for (i = 0; i < aNumKernels; i++) { 405 kList[i].kernel = clCreateKernel(*aProgram, aKernelNames[i], &err); 406 if (err != CL_SUCCESS) { 407 xcl_FreeKernels(kList, i); 408 printf("Error: OpenCL unable to create kernel %s\n", aKernelNames[i]); 409 return -1; 410 } 411 412 if (!strcmp(aKernelNames[i], "krnl_ngcodec_hevc_0")) { 413 printf("%s bank %d\n", aKernelNames[i], XCL_MEM_DDR_BANK0); 414 kList[i].prfBank = XCL_MEM_DDR_BANK0; 415 } else if (!strcmp(aKernelNames[i], "krnl_ngcodec_hevc_1")) { 416 printf("%s bank %d\n", aKernelNames[i], XCL_MEM_DDR_BANK3); 417 kList[i].prfBank = XCL_MEM_DDR_BANK3; 418 } 419 420 kList[i].cmdQ = clCreateCommandQueue(*aContext, *aDevice, 0, &err); 421 if (err != CL_SUCCESS) { 422 xcl_FreeKernels(kList, i+1); 423 printf("Error: OpenCL unable to create CommandQueue\n"); 424 return -1; 425 } 426 kList[i].context = aContext; 427 } 428 *aKernelList = kList; 429 return 0; 430 } 431 432 int xcl_CreateKernels2(cl_context* aContext, cl_device_id* aDevice, 433 cl_program* aProgram, const KRNL_CONFIG* aKernelConfig, uint32_t aNumKernels, 434 xlnx_kernel** aKernelList) { 435 int err; 436 xlnx_kernel* kList; 437 if ((aContext == NULL) || (aDevice == NULL) || 438 (aProgram == NULL ) || (aKernelConfig == NULL) || (aNumKernels == 0)) { 439 return -1; 440 } 441 err = -1; 442 kList = (xlnx_kernel*)calloc(aNumKernels, sizeof(xlnx_kernel)); 443 if (kList == NULL) { 444 printf("Error: Out of Memory! %s at %d\n", __FILE__, __LINE__); 445 return -1; 446 } 447 for (int i = 0; i < aNumKernels; i++) { 448 kList[i].kernel = clCreateKernel(*aProgram, aKernelConfig[i].krnl_name, &err); 449 if (err != CL_SUCCESS) { 450 xcl_FreeKernels(kList, i); 451 printf("Error: OpenCL unable to create kernel %s\n", aKernelConfig[i].krnl_name); 452 return -1; 453 } 454 kList[i].prfBank = aKernelConfig[i].prfBank; 455 kList[i].cmdQ = clCreateCommandQueue(*aContext, *aDevice, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &err); 456 //kList[i].cmdQ = clCreateCommandQueue(*aContext, *aDevice, 0, &err); 457 if (err != CL_SUCCESS) { 458 xcl_FreeKernels(kList, i+1); 459 printf("Error: OpenCL unable to create CommandQueue\n"); 460 return -1; 461 } 462 kList[i].context = aContext; 463 } 464 *aKernelList = kList; 465 return 0; 466 } 467 468 int xcl_FreeKernels(xlnx_kernel* aKernelList, uint32_t aNumKernels) { 469 if (aKernelList == NULL) return -1; 470 for (int i = 0; i < aNumKernels; i++) { 471 if (aKernelList[i].kernel) 472 clReleaseKernel(aKernelList[i].kernel); 473 if (aKernelList[i].cmdQ) 474 clReleaseCommandQueue(aKernelList[i].cmdQ); 475 } 476 free(aKernelList); 477 return 0; 478 } -
new file libavcodec/xlnx_hw/common/src/xlnx_hrm.c
diff --git a/libavcodec/xlnx_hw/common/src/xlnx_hrm.c b/libavcodec/xlnx_hw/common/src/xlnx_hrm.c new file mode 100644 index 0000000..90671f6
- + 1 #include <string.h> 2 #include <stdio.h> 3 #include <pthread.h> 4 #include <assert.h> 5 #include "../inc/xcl.h" 6 #include "../inc/xlnx_hrm.h" 7 #include "../inc/xlnx_hw_defines.h" 8 #include "../../xlnx_hw_types.h" 9 #include "../..//hevc/ku115_hevc_enc_config.h" 10 #include "../../hevc/vu9p_hevc_enc_config.h" 11 12 #include "../../hevc/enc_vu9p.h" 13 #include "../../hevc/enc_vu9p_2c.h" 14 15 // Wrap any OpenCL API calls that return error code(cl_int) 16 // with the below macro to quickly check for an error 17 #define XCL_CHECK(call) \ 18 do { \ 19 int err = call; \ 20 if (err != 0) { \ 21 printf("Error from " #call ", error code is %d\n", err); \ 22 destroy_hrm(); \ 23 return err; \ 24 } \ 25 } while (0); 26 27 static pthread_mutex_t * volatile atomic_hrm_lock = NULL; 28 #define LOCK_HRM pthread_mutex_lock(atomic_hrm_lock) 29 #define UNLOCK_HRM pthread_mutex_unlock(atomic_hrm_lock) 30 31 static uint32_t xlnx_init_count = 0; 32 33 typedef struct xlnx_krnl_info { 34 const char* kName; 35 xlnx_hw_id hwID; 36 uint32_t numCh; 37 // Can hold status for Max 32 channels 38 uint32_t chStatus; 39 uint32_t refCount; 40 } xlnx_krnl_info; 41 42 typedef struct xlnx_dev_info { 43 cl_program program; 44 uint32_t nKernels; 45 xlnx_kernel* kernelList; 46 xlnx_krnl_info* krnlInfo; 47 } xlnx_dev_info; 48 49 typedef enum xlnx_dev_type { 50 ENONE, 51 EKU115, 52 EVU9P 53 } xlnx_dev_type; 54 55 typedef struct xlnx_hrm { 56 cl_platform_id platform_id; 57 cl_context context; 58 cl_uint nDevices; 59 xlnx_device* deviceList; 60 } xlnx_hrm; 61 62 static xlnx_hrm* gHRM = NULL; 63 64 static int clear_device_info(xlnx_dev_info* aDevInfo) { 65 if (aDevInfo == NULL) return -1; 66 if (aDevInfo->krnlInfo) free(aDevInfo->krnlInfo); 67 if (aDevInfo->kernelList) xcl_FreeKernels(aDevInfo->kernelList, aDevInfo->nKernels); 68 if (aDevInfo->program) xcl_ReleaseProgram(&aDevInfo->program); 69 free(aDevInfo); 70 return 0; 71 } 72 73 static int clear_device_list(void) { 74 int i; 75 xlnx_dev_info* temp; 76 if (gHRM->deviceList == NULL) return 0; 77 for (i = 0; i < gHRM->nDevices; i++) { 78 if (gHRM->deviceList[i].privData != NULL) { 79 temp = (xlnx_dev_info*)gHRM->deviceList[i].privData; 80 clear_device_info(temp); 81 gHRM->deviceList[i].privData = NULL; 82 } 83 } 84 xcl_FreeDeviceList(gHRM->deviceList, gHRM->nDevices); 85 return 0; 86 } 87 88 static int setup_KU115(xlnx_device* aDevice, xlnx_hw_id aHWID) { 89 //@ToDo parsing of config and loading of appropriate binary 90 //Assume the profile 1K1C/KU115 = kernel binary 91 int ret = -1; 92 xlnx_dev_info* devInfo; 93 int nK; 94 xlnx_krnl_info* info; 95 printf("setup_KU115\n"); 96 devInfo = (xlnx_dev_info*) calloc(1, sizeof(xlnx_dev_info)); 97 if (devInfo == NULL) { 98 printf("Error: OOM %s at %d\n", __FILE__, __LINE__); 99 return -1; 100 } 101 if (aHWID == EHevcEnc) { 102 // Header based loading 103 #if LOAD_BINARY_FROM_HEADER 104 ret = xcl_ImportBinaryHeader(&gHRM->context, &aDevice->device, hevc_xclbin, hevc_xclbin_len, &devInfo->program); 105 #else 106 ret = xcl_ImportBinary(&gHRM->context, &aDevice->device, KU115_HEVC_ENC_BINARY, &devInfo->program); 107 #endif //LOAD_BINARY_FROM_HEADER 108 if (ret < 0) { 109 free(devInfo); 110 return -1; 111 } 112 nK = sizeof(KU115_HEVC_KRNL_NAME)/sizeof(char*); 113 ret = xcl_CreateKernels(&gHRM->context, &aDevice->device, &devInfo->program, KU115_HEVC_KRNL_NAME, nK, 114 &devInfo->kernelList); 115 if (ret < 0) { 116 clear_device_info(devInfo); 117 return -1; 118 } 119 devInfo->nKernels = nK; 120 devInfo->krnlInfo = (xlnx_krnl_info*) calloc(nK, sizeof(xlnx_krnl_info)); 121 if (NULL == devInfo->krnlInfo) { 122 clear_device_info(devInfo); 123 return -1; 124 } 125 info = devInfo->krnlInfo; 126 for (int i = 0; i < nK; i++) { 127 info[i].kName = KU115_HEVC_KRNL_NAME[i]; 128 info[i].hwID = EHevcEnc; 129 info[i].refCount = 0; 130 } 131 } 132 aDevice->privData = (void*)devInfo; 133 return 0; 134 } 135 136 static int setup_VU9P(xlnx_device* aDevice, xlnx_hw_id aHWID) { 137 int ret = -1; 138 xlnx_dev_info* devInfo; 139 char* xcl_fullpath; 140 unsigned char* xcl_path; 141 int nK; 142 int i; 143 xlnx_krnl_info* info; 144 uint32_t numCh = VU9P_HEVC_ENC_NUM_CH; 145 unsigned char* numch; 146 147 printf("Setup VU9P\n"); 148 devInfo = (xlnx_dev_info*) calloc(1, sizeof(xlnx_dev_info)); 149 if (devInfo == NULL) { 150 printf("Error: OOM %s at %d\n", __FILE__, __LINE__); 151 return -1; 152 } 153 if (aHWID == EHevcEnc) { 154 // Header based loading 155 #if LOAD_BINARY_FROM_HEADER 156 ret = xcl_ImportBinaryHeader(&gHRM->context, &aDevice->device, hevc_enc_vu9p_2k2c_xclbin, hevc_enc_vu9p_2k2c_xclbin_len, &devInfo->program); 157 #else 158 xcl_fullpath = malloc(FILE_PATH_LENGTH); 159 xcl_path = getenv("XLNX_XCLBIN_PATH"); 160 if (NULL != xcl_path) { 161 snprintf(xcl_fullpath, FILE_PATH_LENGTH, "%s/%s", xcl_path, VU9P_HEVC_ENC_BINARY); 162 } else { 163 printf(" * XLNX_XCLBIN_PATH not found\n"); 164 snprintf(xcl_fullpath, FILE_PATH_LENGTH, "%s", VU9P_HEVC_ENC_BINARY); 165 } 166 ret = xcl_ImportBinary(&gHRM->context, &aDevice->device, xcl_fullpath, &devInfo->program); 167 free(xcl_fullpath); 168 #endif //LOAD_BINARY_FROM_HEADER 169 if (ret < 0) { 170 free(devInfo); 171 return -1; 172 } 173 nK = sizeof(VU9P_HEVC_CONFIG)/sizeof(KRNL_CONFIG); 174 ret = xcl_CreateKernels2(&gHRM->context, &aDevice->device, &devInfo->program, VU9P_HEVC_CONFIG, nK, 175 &devInfo->kernelList); 176 if (ret < 0) { 177 clear_device_info(devInfo); 178 return -1; 179 } 180 devInfo->nKernels = nK; 181 devInfo->krnlInfo = (xlnx_krnl_info*) calloc(nK, sizeof(xlnx_krnl_info)); 182 if (NULL == devInfo->krnlInfo) { 183 clear_device_info(devInfo); 184 return -1; 185 } 186 info = devInfo->krnlInfo; 187 for (i = 0; i < nK; i++) { 188 // @Todo load info from some source 189 // for now, hardcore infor for hevc 2k2c 190 info[i].kName = VU9P_HEVC_CONFIG[i].krnl_name; 191 info[i].hwID = EHevcEnc; 192 numCh = VU9P_HEVC_ENC_NUM_CH; 193 numch = getenv("VU9P_HEVC_ENC_NUM_CH"); 194 if (NULL != numch) { 195 numCh = atoi(numch); 196 printf(" * VU9P_HEVC_ENC_NUM_CH set to = %d\n", VU9P_HEVC_ENC_NUM_CH); 197 } else { 198 printf(" * VU9P_HEVC_ENC_NUM_CH not set. Default = %d\n", VU9P_HEVC_ENC_NUM_CH); 199 } 200 info[i].numCh = numCh; 201 info[i].chStatus = 0; 202 info[i].refCount = 0; 203 devInfo->kernelList[i].privData = (void*)&info[i]; 204 } 205 } 206 aDevice->privData = (void*)devInfo; 207 return 0; 208 } 209 210 static xlnx_dev_type get_device_type(const xlnx_device* device) { 211 assert(device != NULL); 212 if (!strncmp(device->devName, KU115_BOARD, strlen(KU115_BOARD))) { 213 return EKU115; 214 } else if (!strncmp(device->devName, VU9P_BOARD, strlen(VU9P_BOARD))) { 215 return EVU9P; 216 } 217 return ENONE; 218 } 219 220 static int setup_devices(const char* aCfgFileName, xlnx_hw_id aHWID) { 221 //@Todo depending upon the config file or environment variable settings, 222 //create context and load binaries here or at a later stage 223 // for now just assume HEVC encoder config only. 224 int ret = -1; 225 xlnx_device* device = NULL; 226 /* seems CL_DEVICE_AVAILABLE not implemented in runtime 227 for (int i = 0; i < gHRM->nDevices; i++) { 228 if (xcl_IsDeviceAvailable(gHRM->deviceList[i].device)) { 229 device = &gHRM->deviceList[i]; 230 break; 231 } 232 }*/ 233 //So choose the first available device 234 // @TODO setup for all the available devices 235 236 device = &gHRM->deviceList[0]; 237 if (NULL == device) { 238 return -1; 239 } 240 switch (get_device_type(device)) { 241 case EKU115: 242 ret = setup_KU115(device, aHWID); 243 break; 244 case EVU9P: 245 ret = setup_VU9P(device, aHWID); 246 break; 247 case ENONE: 248 default: 249 return -1; 250 } 251 return ret; 252 } 253 254 static void destroy_hrm(void) { 255 printf("destroy_hrm\n"); 256 assert(gHRM != NULL); 257 if (gHRM->deviceList) 258 clear_device_list(); 259 gHRM->deviceList = NULL; 260 if (gHRM->context) 261 xcl_ReleaseContext(&gHRM->context); 262 gHRM->context = 0; 263 free(gHRM); 264 gHRM = NULL; 265 printf("destroyed hrm\n"); 266 } 267 268 static int create_hrm(const char* aCfgFileName, xlnx_hw_id aHWID) { 269 //@Todo parse aCfgFileName 270 // For now aCfgFileName is the URI of the Kernal binary file 271 printf("create_hrm\n"); 272 assert(gHRM == NULL); 273 gHRM = calloc(1, sizeof(xlnx_hrm)); 274 if (!gHRM) { 275 printf("Error: OOM %s at %d\n", __FILE__, __LINE__); 276 return -1; 277 } 278 XCL_CHECK(xcl_GetPlatform("Xilinx", &gHRM->platform_id)); 279 XCL_CHECK(xcl_CreateContextFromType(&gHRM->platform_id, CL_DEVICE_TYPE_ACCELERATOR, &gHRM->context)); 280 XCL_CHECK(xcl_GetDeviceList(&gHRM->platform_id, CL_DEVICE_TYPE_ACCELERATOR, &gHRM->deviceList, &gHRM->nDevices)); 281 //If aHWID is known, then setup the devices here 282 if (ENone != aHWID) { 283 XCL_CHECK(setup_devices(aCfgFileName, aHWID)); 284 } 285 printf("created hrm\n"); 286 return 0; 287 } 288 289 static inline int init_hrm_mtx(void) { 290 if (!atomic_hrm_lock) { 291 int err; 292 pthread_mutex_t *tmp = malloc(sizeof(pthread_mutex_t)); 293 if (!tmp) 294 return -1; 295 if ((err = pthread_mutex_init(tmp, NULL))) { 296 free(tmp); 297 return err; 298 } 299 if (__sync_val_compare_and_swap((void * volatile *)&atomic_hrm_lock, NULL, tmp)) { 300 pthread_mutex_destroy(tmp); 301 free(tmp); 302 } 303 } 304 return 0; 305 } 306 307 static inline int deinit_hrm_mtx(void) { 308 if (atomic_hrm_lock) { 309 pthread_mutex_t *tmp = atomic_hrm_lock; 310 UNLOCK_HRM; 311 pthread_mutex_destroy(atomic_hrm_lock); 312 atomic_hrm_lock = NULL; 313 free(tmp); 314 } 315 return 0; 316 } 317 318 int xlnx_hrm_init(const char* aCfgFileName, xlnx_hw_id aHWID) { 319 int ret = init_hrm_mtx(); 320 if (ret < 0) 321 return ret; 322 323 LOCK_HRM; 324 325 if (xlnx_init_count == 0) { 326 ret = create_hrm(aCfgFileName, aHWID); 327 if (ret < 0) { 328 deinit_hrm_mtx(); 329 return -1; 330 } 331 } 332 xlnx_init_count++; 333 334 UNLOCK_HRM; 335 return xlnx_init_count; 336 } 337 338 int xlnx_hrm_deinit() { 339 LOCK_HRM; 340 xlnx_init_count--; 341 if (xlnx_init_count == 0) { 342 destroy_hrm(); 343 } else { 344 uint32_t count = xlnx_init_count; 345 UNLOCK_HRM; 346 return count; 347 } 348 deinit_hrm_mtx(); 349 return 0; 350 } 351 352 static int allocChannel(int aNumCh, int* aChStatus) { 353 for(int i = 0; i < aNumCh; i++) { 354 if ((*aChStatus & (1 << i)) == 0) { 355 *aChStatus = *aChStatus | (1<<i); 356 return i; 357 } 358 } 359 return -1; 360 } 361 362 static int alloc_xKernel(xlnx_dev_info* devInfo, xlnx_hw_id aHWID, int* aIndex, int* aChannel) { 363 for (int i = 0; i < devInfo->nKernels; i++) { 364 xlnx_krnl_info* kInfo = &devInfo->krnlInfo[i]; 365 if ((kInfo->hwID == aHWID) && (kInfo->refCount < kInfo->numCh)) { 366 int ch = allocChannel(kInfo->numCh, &kInfo->chStatus); 367 if (ch < 0) return ch; 368 kInfo->refCount++; 369 *aChannel = ch; 370 *aIndex = i; 371 return 0; 372 } 373 } 374 return -1; 375 } 376 377 static int free_xKernel(xlnx_krnl_info* aKrnlInfo, int aChannel) { 378 if (aKrnlInfo) { 379 aKrnlInfo->refCount--; 380 assert(aKrnlInfo->chStatus & (1 << aChannel)); 381 aKrnlInfo->chStatus &= ~(1 << aChannel); 382 } 383 else 384 return -1; 385 return 0; 386 } 387 388 xlnx_host* xlnx_hrm_get_host(xlnx_hw_id aHWID, xlnx_hw_params aParams) { 389 // @TODO 390 // Device setup can be delayed to this point as well 391 // It will either be done as part of hrm init(if aHWID is known) or delayed till this point. 392 // hrm is being initialized from here in the current case, so it does not make a difference 393 xlnx_host* host = NULL; 394 xlnx_dev_info* devInfo; 395 int kIndex, ch, ret; 396 397 if (aHWID == ENONE) return host; 398 if (xlnx_hrm_init(NULL, aHWID) < 0) { 399 return host; 400 } 401 LOCK_HRM; 402 //@TODO check the whole devicelist 403 devInfo = (xlnx_dev_info*)gHRM->deviceList[0].privData; 404 if (devInfo == NULL) { 405 // Should not happen as hrm init i sdone with xlnx_hw_id 406 // Other wise setup_devices() should be done here 407 UNLOCK_HRM; 408 return host; 409 } 410 411 ret = alloc_xKernel(devInfo, aHWID, &kIndex, &ch); 412 if (ret < 0) { 413 UNLOCK_HRM; 414 return host; 415 } 416 // ONLY HEVC ENc host available right now!! 417 //@Todo update when other hosts are available 418 if (aHWID == EHevcEnc) { 419 host = createHevcEnc2C(&devInfo->kernelList[kIndex], ch, aParams); 420 if (host == NULL) { 421 free_xKernel(&devInfo->krnlInfo[kIndex], ch); 422 UNLOCK_HRM; 423 printf("Error: Cannot allocate memory for xlnx_host %s at %d\n", __FILE__, __LINE__); 424 return host; 425 } 426 } else { 427 UNLOCK_HRM; 428 return host; 429 } 430 431 host->appData = (void*) &devInfo->krnlInfo[kIndex]; 432 UNLOCK_HRM; 433 return host; 434 } 435 436 int xlnx_hrm_release_host(xlnx_host* aHost) { 437 xlnx_krnl_info* krnlInfo; 438 if (NULL == aHost) return -1; 439 krnlInfo = (xlnx_krnl_info*)aHost->appData; 440 if (free_xKernel(krnlInfo, aHost->ch) < 0) return -1; 441 destroyHevcEnc2C(aHost); 442 xlnx_hrm_deinit(); 443 return 0; 444 } -
new file libavcodec/xlnx_hw/common/src/xlnx_queue.c
diff --git a/libavcodec/xlnx_hw/common/src/xlnx_queue.c b/libavcodec/xlnx_hw/common/src/xlnx_queue.c new file mode 100644 index 0000000..3233cf3
- + 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <assert.h> 4 #include "../inc/xlnx_queue.h" 5 6 struct xlnx_queue { 7 int front, rear; 8 size_t size, capacity; 9 XItem* pItem; 10 }; 11 12 xlnx_queue* createQueue(size_t capacity) { 13 xlnx_queue* queue = (xlnx_queue*) malloc(sizeof(xlnx_queue)); 14 if (NULL == queue) { 15 printf("Error: Out of Memory! %s at %d\n", __FILE__, __LINE__); 16 return queue; 17 } 18 queue->capacity = capacity; 19 queue->front = queue->size = 0; 20 queue->rear = -1; 21 queue->pItem = (XItem*)malloc(queue->capacity * sizeof(XItem)); 22 if (NULL == queue->pItem) { 23 printf("Error: Out of Memory! %s at %d\n", __FILE__, __LINE__); 24 free(queue); 25 return NULL; 26 } 27 return queue; 28 } 29 30 void destroyQueue(xlnx_queue* queue) { 31 if (NULL == queue) return; 32 free(queue->pItem); 33 free(queue); 34 return; 35 } 36 37 int isFull(xlnx_queue* queue) { 38 assert(queue != NULL); 39 return (queue->size == queue->capacity); 40 } 41 42 int isEmpty(xlnx_queue* queue) { 43 assert(queue != NULL); 44 return (queue->size == 0); 45 } 46 47 size_t getSize(xlnx_queue* queue) { 48 assert(queue != NULL); 49 return queue->size; 50 } 51 52 int enqueue(xlnx_queue* queue, XItem item) { 53 assert(queue != NULL); 54 if (isFull(queue)) 55 return -1; 56 queue->rear = (queue->rear + 1)%queue->capacity; 57 queue->pItem[queue->rear] = item; 58 queue->size++; 59 return 0; 60 } 61 62 XItem dequeue(xlnx_queue* queue) { 63 XItem item; 64 assert(queue != NULL); 65 if (isEmpty(queue)) 66 return NULL; 67 item = queue->pItem[queue->front]; 68 queue->pItem[queue->front] = 0; 69 queue->front = (queue->front + 1)%queue->capacity; 70 queue->size = queue->size - 1; 71 return item; 72 } 73 74 XItem front(xlnx_queue* queue) { 75 assert(queue != NULL); 76 if (isEmpty(queue)) 77 return NULL; 78 return queue->pItem[queue->front]; 79 } 80 81 XItem rear(xlnx_queue* queue) { 82 assert(queue != NULL); 83 if (isEmpty(queue)) 84 return NULL; 85 return queue->pItem[queue->rear]; 86 } 87 No newline at end of file -
new file libavcodec/xlnx_hw/common/src/xlnx_ts_queue.c
diff --git a/libavcodec/xlnx_hw/common/src/xlnx_ts_queue.c b/libavcodec/xlnx_hw/common/src/xlnx_ts_queue.c new file mode 100644 index 0000000..507040a
- + 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <assert.h> 4 #include <pthread.h> 5 6 #include "../inc/xlnx_ts_queue.h" 7 8 #define LOCK_Q pthread_mutex_lock(&queue->lock) 9 #define UNLOCK_Q pthread_mutex_unlock(&queue->lock) 10 11 struct xlnx_ts_queue { 12 pthread_mutex_t lock; 13 xlnx_queue* q; 14 }; 15 16 xlnx_ts_queue* createTSQ(size_t capacity) { 17 xlnx_queue* queue; 18 xlnx_ts_queue* q = calloc(1, sizeof(xlnx_ts_queue)); 19 if (NULL == q) { 20 printf("Error: Out of Memory! %s at %d\n", __FILE__, __LINE__); 21 return q; 22 } 23 queue = createQueue(capacity); 24 if (NULL == queue) { 25 printf("Error: Out of Memory! %s at %d\n", __FILE__, __LINE__); 26 free(q); 27 return NULL; 28 } 29 q->q = queue; 30 if (pthread_mutex_init(&q->lock, NULL) < 0) { 31 destroyQueue(queue); 32 free(q); 33 return NULL; 34 } 35 return q; 36 } 37 38 void destroyTSQ(xlnx_ts_queue* queue) { 39 if (NULL == queue) return; 40 pthread_mutex_destroy(&queue->lock); 41 destroyQueue(queue->q); 42 free(queue); 43 return; 44 } 45 46 int isFullTSQ(xlnx_ts_queue* queue) { 47 int ret; 48 assert(queue != NULL); 49 LOCK_Q; 50 ret = isFull(queue->q); 51 UNLOCK_Q; 52 return ret; 53 } 54 55 int isEmptyTSQ(xlnx_ts_queue* queue) { 56 int ret; 57 assert(queue != NULL); 58 LOCK_Q; 59 ret = isEmpty(queue->q); 60 UNLOCK_Q; 61 return ret; 62 } 63 64 size_t getSizeTSQ(xlnx_ts_queue* queue) { 65 size_t size; 66 assert(queue != NULL); 67 LOCK_Q; 68 size = getSize(queue->q); 69 UNLOCK_Q; 70 return size; 71 } 72 73 int enqueueTSQ(xlnx_ts_queue* queue, XItem item) { 74 int ret; 75 assert(queue != NULL); 76 LOCK_Q; 77 ret = enqueue(queue->q, item); 78 UNLOCK_Q; 79 return ret; 80 } 81 82 XItem dequeueTSQ(xlnx_ts_queue* queue) { 83 XItem item; 84 assert(queue != NULL); 85 LOCK_Q; 86 item = dequeue(queue->q); 87 UNLOCK_Q; 88 return item; 89 } 90 91 XItem frontTSQ(xlnx_ts_queue* queue) { 92 XItem item; 93 assert(queue != NULL); 94 LOCK_Q; 95 item = front(queue->q); 96 UNLOCK_Q; 97 return item; 98 } 99 100 XItem rearTSQ(xlnx_ts_queue* queue) { 101 XItem item; 102 assert(queue != NULL); 103 LOCK_Q; 104 item = rear(queue->q); 105 UNLOCK_Q; 106 return item; 107 } 108 No newline at end of file -
new file libavcodec/xlnx_hw/hevc/Makefile
diff --git a/libavcodec/xlnx_hw/hevc/Makefile b/libavcodec/xlnx_hw/hevc/Makefile new file mode 100644 index 0000000..2c49c2b
- + 1 OBJS += xlnx_hw/hevc/enc_vu9p.o -
new file libavcodec/xlnx_hw/hevc/enc_vu9p.c
diff --git a/libavcodec/xlnx_hw/hevc/enc_vu9p.c b/libavcodec/xlnx_hw/hevc/enc_vu9p.c new file mode 100644 index 0000000..19c41d1
- + 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <limits.h> 5 #include <string.h> 6 #include <assert.h> 7 #include <CL/opencl.h> 8 #include "enc_vu9p.h" 9 #include "../common/inc/xlnx_hw_defines.h" 10 11 //Macros 12 13 #define OCLCHECKI(method, ... ) \ 14 do { \ 15 status = method(__VA_ARGS__); \ 16 if (status != CL_SUCCESS) { \ 17 printf( # method " error '%d'\n", status); \ 18 KDD_deinit(aKDD); \ 19 return -1; \ 20 } \ 21 } while (0) 22 23 #define CREATEBUF(out, flags, size) \ 24 do { \ 25 out = clCreateBuffer(*context, flags, size, NULL, &status); \ 26 if (status != CL_SUCCESS) { \ 27 printf("Could not create OpenCL buffer\n"); \ 28 KDD_deinit(aKDD); \ 29 return -1; \ 30 } \ 31 } while (0) 32 33 typedef struct KernelDeviceData { 34 // CSR3/CSR4/CSR5 35 cl_mem InCur[3]; 36 // CSR6/CSR7/CSR8 37 cl_mem inNxt[3]; 38 cl_mem CSR12_RECON_BASE_V; 39 cl_mem CSR13_BITSTREAM_BASE_V; 40 cl_mem CSR14_BITSTREAM_LEN_V; 41 U32 CurImgSize[3]; 42 U32 EncodedFrameSize; 43 U32 EncodedFrameLengthSize; 44 HevcEncParam* params; 45 } KernelDeviceData; 46 typedef KernelDeviceData KDD; 47 48 typedef struct HevcEnc { 49 //KHD khd; 50 KDD kdd; 51 HevcEncParam params; 52 xlnx_kernel* xKernel; 53 U32 frameNumber; 54 } HevcEnc; 55 56 static int KDD_deinit(KDD* aKDD) { 57 if (aKDD->InCur[Y]) clReleaseMemObject(aKDD->InCur[Y]); 58 if (aKDD->InCur[U]) clReleaseMemObject(aKDD->InCur[U]); 59 if (aKDD->InCur[V]) clReleaseMemObject(aKDD->InCur[V]); 60 if (aKDD->inNxt[Y]) clReleaseMemObject(aKDD->inNxt[Y]); 61 if (aKDD->inNxt[U]) clReleaseMemObject(aKDD->inNxt[U]); 62 if (aKDD->inNxt[V]) clReleaseMemObject(aKDD->inNxt[V]); 63 if (aKDD->CSR12_RECON_BASE_V) clReleaseMemObject(aKDD->CSR12_RECON_BASE_V); 64 if (aKDD->CSR13_BITSTREAM_BASE_V) clReleaseMemObject(aKDD->CSR13_BITSTREAM_BASE_V); 65 if (aKDD->CSR14_BITSTREAM_LEN_V) clReleaseMemObject(aKDD->CSR14_BITSTREAM_LEN_V); 66 memset(aKDD, 0, sizeof(KDD)); 67 return 0; 68 } 69 70 static int KDD_init(KDD* aKDD, HevcEnc* aEnc) { 71 cl_int status; 72 U32 width, height; 73 cl_kernel kernel; 74 cl_context* context; 75 int arg = 0; 76 if ((aKDD == NULL) || (aEnc == NULL)) return -1; 77 status = -1; 78 aKDD->params = &aEnc->params; 79 width = aKDD->params->width; 80 height = aKDD->params->height; 81 aKDD->CurImgSize[Y] = width * height; 82 aKDD->CurImgSize[U] = (width * height) >> 2; 83 aKDD->CurImgSize[V] = (width * height) >> 2; 84 85 // Encoded Frame data size - hard code to allocate host memory as this varies! 86 aKDD->EncodedFrameSize = (width * height * 3) >> 1; 87 aKDD->EncodedFrameLengthSize = 1; 88 89 // Setup the CSR registers 90 kernel = aEnc->xKernel->kernel; 91 context = aEnc->xKernel->context; 92 CREATEBUF(aKDD->InCur[Y], CL_MEM_READ_ONLY, aKDD->CurImgSize[Y] * sizeof(U8)); 93 CREATEBUF(aKDD->InCur[U], CL_MEM_READ_ONLY, aKDD->CurImgSize[U] * sizeof(U8)); 94 CREATEBUF(aKDD->InCur[V], CL_MEM_READ_ONLY, aKDD->CurImgSize[V] * sizeof(U8)); 95 CREATEBUF(aKDD->inNxt[Y], CL_MEM_READ_ONLY, aKDD->CurImgSize[Y] * sizeof(U8)); 96 CREATEBUF(aKDD->inNxt[U], CL_MEM_READ_ONLY, aKDD->CurImgSize[U] * sizeof(U8)); 97 // Padding to make reference base pointer of reconstructed picture 128KB aligned 98 CREATEBUF(aKDD->inNxt[V], CL_MEM_READ_ONLY, (aKDD->CurImgSize[V]+ 48*128*1024-1920*1080*3) * sizeof(U8)); 99 // Reference frame requires at least 16MB space in DDR 100 CREATEBUF(aKDD->CSR12_RECON_BASE_V, CL_MEM_READ_WRITE, 16*1024*1024); 101 CREATEBUF(aKDD->CSR13_BITSTREAM_BASE_V, CL_MEM_WRITE_ONLY, aKDD->EncodedFrameSize * sizeof(U8)); 102 CREATEBUF(aKDD->CSR14_BITSTREAM_LEN_V, CL_MEM_WRITE_ONLY, aKDD->EncodedFrameLengthSize * sizeof(U64)); 103 104 OCLCHECKI(clSetKernelArg, kernel, arg++, sizeof(U32), &aKDD->params->width); 105 OCLCHECKI(clSetKernelArg, kernel, arg++, sizeof(U32), &aKDD->params->height); 106 OCLCHECKI(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &aKDD->InCur[Y]); 107 OCLCHECKI(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &aKDD->InCur[U]); 108 OCLCHECKI(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &aKDD->InCur[V]); 109 OCLCHECKI(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &aKDD->inNxt[Y]); 110 OCLCHECKI(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &aKDD->inNxt[U]); 111 OCLCHECKI(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &aKDD->inNxt[V]); 112 OCLCHECKI(clSetKernelArg, kernel, arg++, sizeof(U32), &aKDD->params->bitrate); 113 OCLCHECKI(clSetKernelArg, kernel, arg++, sizeof(U32), &aKDD->params->qp); 114 OCLCHECKI(clSetKernelArg, kernel, arg++, sizeof(U32), &aKDD->params->ip); 115 OCLCHECKI(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &aKDD->CSR12_RECON_BASE_V); 116 OCLCHECKI(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &aKDD->CSR13_BITSTREAM_BASE_V); 117 OCLCHECKI(clSetKernelArg, kernel, arg++, sizeof(cl_mem), &aKDD->CSR14_BITSTREAM_LEN_V); 118 OCLCHECKI(clSetKernelArg, kernel, arg++, sizeof(U32), &aKDD->params->reset); 119 return 0; 120 } 121 122 static int hevc_encode(xlnx_host* aHost, xlnx_hw_params aParams, xlnx_hw_buf* aInput, xlnx_hw_buf* aOutput) { 123 cl_command_queue cmdQ; 124 cl_kernel kernel; 125 xlnx_data_buf* iHBuf; 126 xlnx_data_buf* oBuf; 127 size_t global_work_size_1d[1]; 128 size_t local_work_size_1d[1]; 129 int size; 130 cl_int status = -1; 131 HevcEnc* enc = (HevcEnc*)aHost->privData; 132 KDD kdd = enc->kdd; 133 HevcEncParam* params = (HevcEncParam*) aParams; 134 xlnx_kernel* xKernel = enc->xKernel; 135 U32 frameNumber = enc->frameNumber; 136 137 if ((frameNumber == 0) && (aInput->ptr == NULL)) { return -1;} 138 139 cmdQ = xKernel->cmdQ; 140 kernel = xKernel->kernel; 141 142 assert(aInput->type == ERAW); 143 assert(aOutput->type == EDATA); 144 iHBuf = aInput->ptr; 145 oBuf = aOutput->ptr; 146 147 global_work_size_1d[0] = 1; 148 local_work_size_1d[0] = 1; 149 size = 0; 150 151 if (frameNumber == 0) { 152 for (int i = 0; i < 3; i++) { 153 size = kdd.CurImgSize[i] * sizeof(U8); 154 ENQUEUEBUF(clEnqueueWriteBuffer, kdd.InCur[i]); 155 } 156 enc->frameNumber++; 157 oBuf->size = 0; 158 return 0; 159 } else if (frameNumber == 1) { 160 if (aInput->ptr != NULL) { 161 for (int i = 0; i < 3; i++) { 162 size = kdd.CurImgSize[i] * sizeof(U8); 163 ENQUEUEBUF(clEnqueueWriteBuffer, kdd.inNxt[i]); 164 } 165 } else { 166 OCLCHECK(clSetKernelArg, kernel, 14, sizeof(U32), ¶ms->reset); 167 } 168 // av_log(NULL, AV_LOG_INFO," * Loading frame %d\n", frameNumber); 169 enc->frameNumber++; 170 } else { 171 // Ping-pong buffers used; switch cur and nxt buffer pointer for kernel 172 if (frameNumber%2 == 0) { 173 OCLCHECK(clSetKernelArg, kernel, 2, sizeof(cl_mem), &kdd.inNxt[Y]); 174 OCLCHECK(clSetKernelArg, kernel, 3, sizeof(cl_mem), &kdd.inNxt[U]); 175 OCLCHECK(clSetKernelArg, kernel, 4, sizeof(cl_mem), &kdd.inNxt[V]); 176 OCLCHECK(clSetKernelArg, kernel, 5, sizeof(cl_mem), &kdd.InCur[Y]); 177 OCLCHECK(clSetKernelArg, kernel, 6, sizeof(cl_mem), &kdd.InCur[U]); 178 OCLCHECK(clSetKernelArg, kernel, 7, sizeof(cl_mem), &kdd.InCur[V]); 179 if (aInput->ptr != NULL) { 180 for (int i = 0; i < 3; i++) { 181 size = kdd.CurImgSize[i] * sizeof(U8); 182 ENQUEUEBUF(clEnqueueWriteBuffer, kdd.InCur[i]); 183 } 184 } else { 185 OCLCHECK(clSetKernelArg, kernel, 14, sizeof(U32), ¶ms->reset); 186 } 187 } else { 188 OCLCHECK(clSetKernelArg, kernel, 2, sizeof(cl_mem), &kdd.InCur[Y]); 189 OCLCHECK(clSetKernelArg, kernel, 3, sizeof(cl_mem), &kdd.InCur[U]); 190 OCLCHECK(clSetKernelArg, kernel, 4, sizeof(cl_mem), &kdd.InCur[V]); 191 OCLCHECK(clSetKernelArg, kernel, 5, sizeof(cl_mem), &kdd.inNxt[Y]); 192 OCLCHECK(clSetKernelArg, kernel, 6, sizeof(cl_mem), &kdd.inNxt[U]); 193 OCLCHECK(clSetKernelArg, kernel, 7, sizeof(cl_mem), &kdd.inNxt[V]); 194 if (aInput->ptr != NULL) { 195 for (int i = 0; i < 3; i++) { 196 size = kdd.CurImgSize[i] * sizeof(U8); 197 ENQUEUEBUF(clEnqueueWriteBuffer, kdd.inNxt[i]); 198 } 199 } else { 200 OCLCHECK(clSetKernelArg, kernel, 14, sizeof(U32), ¶ms->reset); 201 } 202 } 203 enc->frameNumber++; 204 } 205 OCLCHECK(clEnqueueNDRangeKernel, cmdQ, kernel, 1, NULL, global_work_size_1d, local_work_size_1d, 0, NULL, NULL); 206 207 // 208 // Wait for the hw accelerator to complete 209 // 210 clFinish(cmdQ); 211 //av_log(NULL, AV_LOG_INFO," * Finished the xlnx hw accelerator kernel\n"); 212 213 // 214 // Read the result 215 // Get the length of the Encoded Frame first as this varies! 216 // 217 // av_log(NULL, AV_LOG_INFO," * Enqueuing Read Buffer - CSR14_BITSTREAM_LEN_V\n"); 218 OCLCHECK(clEnqueueReadBuffer, cmdQ, kdd.CSR14_BITSTREAM_LEN_V, CL_TRUE, 0, kdd.EncodedFrameLengthSize * sizeof(U64), &oBuf->size, 0, NULL, NULL); 219 // av_log(NULL, AV_LOG_INFO," * Encoded Frame Length = %d\n", *dstSize); 220 //*dstSize = *dstSize * 4; 221 printf(" * Encoded Frame Length = %llu enc->frameNumber=%u\n", oBuf->size, enc->frameNumber); 222 223 // av_log(NULL, AV_LOG_INFO," * Enqueuing Read Buffer - CSR13_BITSTREAM_BASE_V\n"); 224 OCLCHECK(clEnqueueReadBuffer, cmdQ, kdd.CSR13_BITSTREAM_BASE_V, CL_TRUE, 0, oBuf->size * sizeof(U8), oBuf->pDATA, 0, NULL, NULL); 225 return 0; 226 } 227 228 xlnx_host* createHevcEnc(xlnx_kernel* aKernel, xlnx_hw_params aParams) { 229 HevcEnc* enc; 230 xlnx_host* host; 231 int err; 232 if (aKernel == NULL) return NULL; 233 enc = (HevcEnc*)calloc(1, sizeof(HevcEnc)); 234 if (enc == NULL) { 235 printf("Error: Cannot allocate memory %s at %d\n", __FILE__, __LINE__); 236 return NULL; 237 } 238 memcpy(&enc->params, aParams, sizeof(HevcEncParam)); 239 enc->xKernel = aKernel; 240 err = KDD_init(&enc->kdd, enc); 241 if (err < 0) { 242 printf("Error: createHevcEnc Failed\n"); 243 free(enc); 244 return NULL; 245 } 246 enc->frameNumber = 0; 247 host = (xlnx_host*) calloc(1, sizeof(xlnx_host)); 248 if (host == NULL) { 249 printf("Error: Cannot allocate memory %s at %d\n", __FILE__, __LINE__); 250 return NULL; 251 } 252 host->privData = (void*) enc; 253 host->process = &hevc_encode; 254 return host; 255 } 256 257 int destroyHevcEnc(xlnx_host* aHost) { 258 HevcEnc* enc; 259 if (aHost == NULL) return -1; 260 enc = (HevcEnc*)aHost->privData; 261 if (enc == NULL) return -1; 262 KDD_deinit(&enc->kdd); 263 free(enc); 264 free(aHost); 265 return 0; 266 } -
new file libavcodec/xlnx_hw/hevc/enc_vu9p.h
diff --git a/libavcodec/xlnx_hw/hevc/enc_vu9p.h b/libavcodec/xlnx_hw/hevc/enc_vu9p.h new file mode 100644 index 0000000..4423f53
- + 1 #ifndef HEVC_ENC_VU9P_H 2 #define HEVC_ENC_VU9P_H 3 4 #include "../common/inc/xlnx_types_internal.h" 5 6 xlnx_host* createHevcEnc(xlnx_kernel* aKernel, xlnx_hw_params aParams); 7 int destroyHevcEnc(xlnx_host* aHost); 8 9 #endif //HEVC_ENC_VU9P_H 10 No newline at end of file -
new file libavcodec/xlnx_hw/hevc/enc_vu9p_2c.c
diff --git a/libavcodec/xlnx_hw/hevc/enc_vu9p_2c.c b/libavcodec/xlnx_hw/hevc/enc_vu9p_2c.c new file mode 100644 index 0000000..e441aec
- + 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <limits.h> 5 #include <string.h> 6 #include <assert.h> 7 #include <CL/opencl.h> 8 #include "pthread.h" 9 10 //@TODO implement own msg queue and remove libavutil dependency 11 #include "libavutil/atomic.h" 12 #include "libavutil/threadmessage.h" 13 #include "libavutil/error.h" 14 15 #include "../common/inc/xlnx_hw_defines.h" 16 #include "../common/inc/xlnx_ts_queue.h" 17 #include "enc_vu9p_2c.h" 18 19 #define OCLCHECKI(method, ... ) \ 20 do { \ 21 status = method(__VA_ARGS__); \ 22 if (status != CL_SUCCESS) { \ 23 printf( # method " error '%d'\n", status); \ 24 return -1; \ 25 } \ 26 } while (0) 27 28 #define OCLCHECKI2(method, ... ) \ 29 do { \ 30 status = method(__VA_ARGS__); \ 31 if (status != CL_SUCCESS) { \ 32 printf( # method " error '%d'\n", status); \ 33 KDD2_deinit(kdd, ch, refcount); \ 34 return -1; \ 35 } \ 36 } while (0) 37 38 #define CREATEBUF2(out, flags, size) \ 39 do { \ 40 out = clCreateBuffer(*context, flags, size, &ext, &status); \ 41 if (status != CL_SUCCESS) { \ 42 printf("Could not create OpenCL buffer\n"); \ 43 KDD2_deinit(aKDD, ch, aRefcount); \ 44 return -1; \ 45 } \ 46 OCLCHECKI2(clEnqueueMigrateMemObjects, cmdQ, 1, &out, migflags, 0, NULL, NULL);\ 47 } while (0) 48 49 #define OCLCHECKCB(method, ... ) \ 50 do { \ 51 status = method(__VA_ARGS__); \ 52 if (status != CL_SUCCESS) { \ 53 printf( # method " error '%d'\n", status); \ 54 break; \ 55 } \ 56 } while (0) 57 58 #define WAIT_IF_EMPTY(Q) while (isEmptyTSQ(Q)) usleep(1000) 59 60 61 typedef struct HevcEnc2 HevcEnc2; 62 63 typedef enum HevcEncState { 64 EInit, 65 ESendIp, 66 EEncode, 67 EReadOpSize, 68 ECopyOp 69 } HevcEncState; 70 71 typedef struct HevcKDCtx { 72 cl_mem* inD; 73 cl_mem* outD; 74 xlnx_hw_buf* outH; 75 void* appCtx; 76 } HevcKDCtx; 77 78 typedef struct HevcEncCtx { 79 HevcEnc2* enc; 80 HevcKDCtx kdCtx[VU9P_HEVC_ENC_NUM_CH]; 81 HevcEncState state; 82 cl_event lEncode; 83 } HevcEncCtx; 84 85 typedef struct HevcEncParam2 { 86 U32 wh[2]; 87 U32 br; 88 U32 qp; 89 U32 ip; 90 U32 reset; 91 } HevcEncParam2; 92 93 typedef struct KernelDeviceData2 { 94 // CSR3/CSR4/CSR5 95 // CSR6/CSR7/CSR8 96 cl_mem InCur[VU9P_HEVC_ENC_NUM_CH][3]; 97 // CSR9/CSR10/CSR11 98 cl_mem inNxt[3]; 99 xlnx_ts_queue* inQ[VU9P_HEVC_ENC_NUM_CH]; 100 cl_mem CSR15_RECON_BASE_V; 101 // CSR 16 & 18 + CSR 17 & 19 102 xlnx_ts_queue* outQ[VU9P_HEVC_ENC_NUM_CH]; 103 U32 CurImgSize[VU9P_HEVC_ENC_NUM_CH][3]; 104 U32 EncodedFrameSize[VU9P_HEVC_ENC_NUM_CH]; 105 //CSR20 106 U32 isDualCh; 107 HevcEncParam2* params; 108 } KernelDeviceData2; 109 110 typedef KernelDeviceData2 KDD2; 111 112 struct HevcEnc2 { 113 KDD2 kdd; 114 HevcEncParam2 params; 115 xlnx_kernel* xKernel; 116 U32 frameNumber[VU9P_HEVC_ENC_NUM_CH]; 117 int refCount; 118 pthread_t encThread; 119 AVThreadMessageQueue* reqQ[VU9P_HEVC_ENC_NUM_CH]; 120 AVThreadMessageQueue* rspQ[VU9P_HEVC_ENC_NUM_CH]; 121 xlnx_ts_queue* ctxQ; 122 HevcEncCtx* curCtx; 123 }; 124 125 typedef enum { 126 EProcess, 127 EEOS 128 } HevcMsgType; 129 130 typedef struct HevcEncReq { 131 HevcMsgType type; 132 xlnx_host* host; 133 xlnx_hw_params params; 134 xlnx_hw_buf* in; 135 xlnx_hw_buf* out; 136 void* appCtx; 137 } HevcEncReq; 138 139 typedef struct HevcEncRsp { 140 HevcMsgType type; 141 xlnx_hw_buf* out; 142 void* appCtx; 143 } HevcEncRsp; 144 145 static int KDD2_deinit(KDD2* aKDD, uint32_t aChannel, int aRefcount); 146 147 static int hevc_prepare(HevcEnc2* aEnc, HevcEncReq* aReq) { 148 cl_int status = -1; 149 int ch; 150 HevcEnc2* enc = aEnc; 151 KDD2* kdd = &enc->kdd; 152 int refcount = enc->refCount; 153 xlnx_kernel* xKernel = enc->xKernel; 154 cl_command_queue cmdQ; 155 cl_kernel kernel; 156 int size; 157 xlnx_data_buf* iHBuf; 158 xlnx_host* host = aReq->host; 159 xlnx_hw_buf* inHost = aReq->in; 160 HevcEncCtx* ctx; 161 HevcKDCtx* kdCtx; 162 int arg; 163 U32 frameNumber; 164 cl_mem* inFBuf = NULL; 165 166 iHBuf = inHost->ptr; 167 ch = host->ch; 168 frameNumber = enc->frameNumber[ch]; 169 if ((frameNumber == 0) && (iHBuf == NULL)) { return -1;} 170 assert(inHost->type == ERAW); 171 172 cmdQ = xKernel->cmdQ; 173 kernel = xKernel->kernel; 174 175 size = 0; 176 if (ch == 0) { 177 if (frameNumber == 0) { 178 arg = 2; 179 inFBuf = (cl_mem*)dequeueTSQ(kdd->inQ[ch]); 180 for (int i = 0; i < 3; i++) { 181 size = kdd->CurImgSize[ch][i] * sizeof(U8); 182 ENQUEUEBUF(clEnqueueWriteBuffer, inFBuf[i]); 183 OCLCHECKI2(clSetKernelArg, kernel, arg, sizeof(cl_mem),&inFBuf[i]); 184 arg++; 185 } 186 enc->frameNumber[ch]++; 187 ctx = enc->curCtx = dequeueTSQ(enc->ctxQ); 188 ctx->state = ESendIp; 189 kdCtx = &ctx->kdCtx[ch]; 190 kdCtx->inD = inFBuf; 191 kdCtx->outH = aReq->out; 192 kdCtx->appCtx = aReq->appCtx; 193 return 0; 194 } else if (frameNumber == 1) { 195 if (iHBuf != NULL) { 196 inFBuf = (cl_mem*)dequeueTSQ(kdd->inQ[ch]); 197 arg = 8; 198 for (int i = 0; i < 3; i++) { 199 size = kdd->CurImgSize[ch][i] * sizeof(U8); 200 ENQUEUEBUF(clEnqueueWriteBuffer, inFBuf[i]); 201 OCLCHECKI2(clSetKernelArg, kernel, arg, sizeof(cl_mem), &inFBuf[i]); 202 arg++; 203 } 204 } 205 enc->frameNumber[ch]++; 206 ctx = frontTSQ(enc->ctxQ); 207 kdCtx = &ctx->kdCtx[ch]; 208 kdCtx->inD = inFBuf; 209 kdCtx->outH = aReq->out; 210 kdCtx->appCtx = aReq->appCtx; 211 } else { 212 WAIT_IF_EMPTY(enc->ctxQ); 213 ctx = enc->curCtx = dequeueTSQ(enc->ctxQ); 214 ctx->state = ESendIp; 215 kdCtx = &ctx->kdCtx[ch]; 216 inFBuf = kdCtx->inD; 217 arg = 2; 218 for (int i = 0; i < 3; i++) { 219 OCLCHECKI2(clSetKernelArg, kernel, arg, sizeof(cl_mem),&inFBuf[i]); 220 arg++; 221 } 222 if (iHBuf != NULL) { 223 WAIT_IF_EMPTY(kdd->inQ[ch]); 224 inFBuf = (cl_mem*)dequeueTSQ(kdd->inQ[ch]); 225 arg = 8; 226 for (int i = 0; i < 3; i++) { 227 size = kdd->CurImgSize[ch][i] * sizeof(U8); 228 ENQUEUEBUF(clEnqueueWriteBuffer, inFBuf[i]); 229 OCLCHECKI2(clSetKernelArg, kernel, arg, sizeof(cl_mem), &inFBuf[i]); 230 arg++; 231 } 232 } 233 enc->frameNumber[ch]++; 234 WAIT_IF_EMPTY(enc->ctxQ); 235 ctx = frontTSQ(enc->ctxQ); 236 kdCtx = &ctx->kdCtx[ch]; 237 kdCtx->inD = inFBuf; 238 kdCtx->outH = aReq->out; 239 kdCtx->appCtx = aReq->appCtx; 240 } 241 } else if (ch == 1) { 242 if (iHBuf != NULL) { 243 ctx = enc->curCtx; 244 assert(ctx->state == ESendIp); 245 kdCtx = &ctx->kdCtx[ch]; 246 WAIT_IF_EMPTY(kdd->inQ[ch]); 247 inFBuf = (cl_mem*)dequeueTSQ(kdd->inQ[ch]); 248 arg = 5; 249 for (int i = 0; i < 3; i++) { 250 size = kdd->CurImgSize[ch][i] * sizeof(U8); 251 ENQUEUEBUF(clEnqueueWriteBuffer, inFBuf[i]); 252 OCLCHECKI2(clSetKernelArg, kernel, arg, sizeof(cl_mem), &inFBuf[i]); 253 arg++; 254 } 255 kdCtx = &ctx->kdCtx[ch]; 256 kdCtx->inD = inFBuf; 257 kdCtx->outH = aReq->out; 258 kdCtx->appCtx = aReq->appCtx; 259 } else { 260 U32 wh = 0; 261 OCLCHECKI2(clSetKernelArg, kernel, 1, sizeof(U32), &wh); 262 OCLCHECKI2(clSetKernelArg, kernel, 5, sizeof(cl_mem), NULL); 263 OCLCHECKI2(clSetKernelArg, kernel, 6, sizeof(cl_mem), NULL); 264 OCLCHECKI2(clSetKernelArg, kernel, 7, sizeof(cl_mem), NULL); 265 OCLCHECKI2(clSetKernelArg, kernel, 17, sizeof(cl_mem), NULL); 266 OCLCHECKI2(clSetKernelArg, kernel, 18, sizeof(cl_mem), NULL); 267 } 268 enc->frameNumber[ch]++; 269 } 270 return 0; 271 } 272 273 static void CL_CALLBACK notify_callback(cl_event event, cl_int event_command_exec_status, void* user_data) { 274 cl_int status = -1; 275 HevcEncCtx* ctx; 276 HevcKDCtx* kdCtx; 277 HevcEnc2* enc; 278 KDD2* kdd; 279 int isDualCh; 280 cl_command_queue cmdQ; 281 cl_event eventRead; 282 xlnx_hw_buf* outH; 283 xlnx_data_buf* oHBuf; 284 cl_mem* oFBuf; 285 HevcEncRsp rspMsg; 286 287 ctx = (HevcEncCtx*)user_data; 288 kdCtx = &ctx->kdCtx[0]; 289 outH = kdCtx->outH; 290 oHBuf = outH->ptr; 291 oFBuf = kdCtx->outD; 292 enc = ctx->enc; 293 cmdQ = enc->xKernel->cmdQ; 294 kdd = &enc->kdd; 295 isDualCh = kdd->isDualCh; 296 297 switch (ctx->state) { 298 case EEncode: 299 oHBuf->size = 0; 300 OCLCHECKCB(clEnqueueReadBuffer, cmdQ, oFBuf[1], CL_FALSE, 0, sizeof(U64), &oHBuf->size, 0, NULL, &eventRead); 301 enqueueTSQ(kdd->inQ[0], kdCtx->inD); 302 kdCtx->inD = NULL; 303 ctx->state = EReadOpSize; 304 if (isDualCh) { 305 kdCtx = &ctx->kdCtx[1]; 306 oFBuf = kdCtx->outD; 307 outH = kdCtx->outH; 308 oHBuf = outH->ptr; 309 OCLCHECKCB(clEnqueueReadBuffer, cmdQ, oFBuf[1], CL_FALSE, 0, sizeof(U64), &oHBuf->size, 1, &eventRead, &ctx->lEncode); 310 enqueueTSQ(kdd->inQ[1], kdCtx->inD); 311 kdCtx->inD = NULL; 312 OCLCHECKCB(clSetEventCallback, ctx->lEncode, CL_COMPLETE, ¬ify_callback, ctx); 313 } else { 314 OCLCHECKCB(clSetEventCallback, eventRead, CL_COMPLETE, ¬ify_callback, ctx); 315 } 316 break; 317 case EReadOpSize: 318 OCLCHECKCB(clEnqueueReadBuffer, cmdQ, oFBuf[0], CL_FALSE, 0, oHBuf->size * sizeof(U8), oHBuf->pDATA, 0, NULL, &eventRead); 319 ctx->state = ECopyOp; 320 if (isDualCh) { 321 kdCtx = &ctx->kdCtx[1]; 322 oFBuf = kdCtx->outD; 323 outH = kdCtx->outH; 324 oHBuf = outH->ptr; 325 OCLCHECKCB(clEnqueueReadBuffer, cmdQ, oFBuf[0], CL_FALSE, 0, oHBuf->size * sizeof(U8), oHBuf->pDATA, 1, &eventRead, &ctx->lEncode); 326 OCLCHECKCB(clSetEventCallback, ctx->lEncode, CL_COMPLETE, ¬ify_callback, ctx); 327 } else { 328 OCLCHECKCB(clSetEventCallback, eventRead, CL_COMPLETE, ¬ify_callback, ctx); 329 } 330 break; 331 case ECopyOp: 332 rspMsg.type = EProcess; 333 rspMsg.out = kdCtx->outH; 334 rspMsg.appCtx = kdCtx->appCtx; 335 av_thread_message_queue_send(enc->rspQ[0], &rspMsg, 0); 336 kdd = &enc->kdd; 337 enqueueTSQ(kdd->outQ[0], oFBuf); 338 kdCtx->outD = NULL; 339 kdCtx->outH = NULL; 340 if (isDualCh) { 341 kdCtx = &ctx->kdCtx[1]; 342 rspMsg.out = kdCtx->outH; 343 rspMsg.appCtx = kdCtx->appCtx; 344 oFBuf = kdCtx->outD; 345 av_thread_message_queue_send(enc->rspQ[1], &rspMsg, 0); 346 enqueueTSQ(kdd->outQ[1], oFBuf); 347 kdCtx->outD = NULL; 348 kdCtx->outH = NULL; 349 } 350 ctx->state = EInit; 351 enqueueTSQ(enc->ctxQ, ctx); 352 break; 353 default: 354 printf("Error: Unknown STATE!!\n"); 355 break; 356 } 357 } 358 359 static int hevc_encode(HevcEnc2* aEnc) { 360 cl_int status = -1; 361 HevcEnc2* enc; 362 HevcEncCtx* ctx; 363 xlnx_hw_buf* outH0; 364 xlnx_data_buf* oHBuf0; 365 //xlnx_data_buf* oHBuf1; 366 KDD2* kdd; 367 int isDualCh; 368 xlnx_kernel* xKernel; 369 cl_command_queue cmdQ; 370 cl_kernel kernel; 371 size_t global_work_size_1d[1]; 372 size_t local_work_size_1d[1]; 373 cl_event event; 374 HevcKDCtx* kdCtx; 375 cl_mem* oFBuf; 376 enc = aEnc; 377 ctx = enc->curCtx; 378 assert(ctx != NULL); 379 kdCtx = &ctx->kdCtx[0]; 380 outH0 = kdCtx->outH; 381 assert(outH0->type == EDATA); 382 oHBuf0 = outH0->ptr; 383 kdd = &enc->kdd; 384 xKernel = enc->xKernel; 385 cmdQ = xKernel->cmdQ; 386 kernel = xKernel->kernel; 387 isDualCh = kdd->isDualCh; 388 389 WAIT_IF_EMPTY(kdd->outQ[0]); 390 oFBuf = dequeueTSQ(kdd->outQ[0]); 391 OCLCHECKI(clSetKernelArg, kernel, 15, sizeof(cl_mem), &oFBuf[0]); 392 OCLCHECKI(clSetKernelArg, kernel, 16, sizeof(cl_mem), &oFBuf[1]); 393 kdCtx->outD = oFBuf; 394 if(isDualCh) { 395 kdCtx = &ctx->kdCtx[1]; 396 WAIT_IF_EMPTY(kdd->outQ[1]); 397 oFBuf = dequeueTSQ(kdd->outQ[1]); 398 OCLCHECKI(clSetKernelArg, kernel, 17, sizeof(cl_mem), &oFBuf[0]); 399 OCLCHECKI(clSetKernelArg, kernel, 18, sizeof(cl_mem), &oFBuf[1]); 400 kdCtx->outD = oFBuf; 401 } 402 global_work_size_1d[0] = 1; 403 local_work_size_1d[0] = 1; 404 if (ctx->lEncode != 0) { 405 OCLCHECK(clEnqueueNDRangeKernel, cmdQ, kernel, 1, NULL, global_work_size_1d, local_work_size_1d, 1, &ctx->lEncode, &event); 406 } else { 407 OCLCHECK(clEnqueueNDRangeKernel, cmdQ, kernel, 1, NULL, global_work_size_1d, local_work_size_1d, 0, NULL, &event); 408 } 409 ctx->state = EEncode; 410 OCLCHECK(clSetEventCallback, event, CL_COMPLETE, ¬ify_callback, ctx); 411 enc->curCtx = NULL; 412 WAIT_IF_EMPTY(enc->ctxQ); 413 ctx = frontTSQ(enc->ctxQ); 414 ctx->lEncode = event; 415 if (kdd->params->reset == 1) { 416 kdd->params->reset = 0; 417 OCLCHECKI(clSetKernelArg, kernel, 20, sizeof(U32), &kdd->params->reset); 418 } 419 return 0; 420 } 421 422 423 static void* process(void* aEnc) { 424 HevcEnc2* enc; 425 AVThreadMessageQueue* reqQ; 426 AVThreadMessageQueue* rspQ; 427 AVThreadMessageQueue* reqQ1; 428 AVThreadMessageQueue* rspQ1; 429 HevcEncReq reqMsg; 430 HevcEncRsp rspMsg; 431 HevcEncReq reqMsg1; 432 HevcEncRsp rspMsg1; 433 int ret, isDualCh; 434 435 printf("Thread started\n"); 436 enc = (HevcEnc2*)aEnc; 437 reqQ = enc->reqQ[0]; 438 rspQ = enc->rspQ[0]; 439 rspMsg.type = EProcess; 440 441 reqQ1 = NULL; 442 rspQ1 = NULL; 443 rspMsg1.out = NULL; 444 rspMsg1.appCtx = NULL; 445 isDualCh = 0; 446 447 av_thread_message_queue_recv(reqQ, &reqMsg, 0); 448 ret = hevc_prepare(enc, &reqMsg); 449 if (ret < 0) { 450 printf("Error: Prepare failed, Exit Thread aEnc=%p\n", aEnc); 451 pthread_exit(NULL); 452 } 453 while(1) { 454 av_thread_message_queue_recv(reqQ, &reqMsg, 0); 455 ret = hevc_prepare(enc, &reqMsg); 456 if (ret < 0) break; 457 458 isDualCh = enc->kdd.isDualCh; 459 if (isDualCh) { 460 reqQ1 = enc->reqQ[1]; 461 rspQ1 = enc->rspQ[1]; 462 av_thread_message_queue_recv(reqQ1, &reqMsg1, 0); 463 if (reqMsg1.type == EEOS) { 464 while (!isFullTSQ(enc->ctxQ)) usleep(1000); 465 break; 466 } 467 ret = hevc_prepare(enc, &reqMsg1); 468 if (ret < 0) break; 469 } 470 ret = hevc_encode(aEnc); 471 if (ret < 0) break; 472 if (reqMsg.type == EEOS) { 473 while (!isFullTSQ(enc->ctxQ)) usleep(1000); 474 break; 475 } 476 } 477 rspMsg.type = EEOS; 478 av_thread_message_queue_send(rspQ, &rspMsg, 0); 479 av_thread_message_queue_recv(reqQ, &reqMsg, AV_THREAD_MESSAGE_NONBLOCK); 480 if (isDualCh) { 481 av_thread_message_queue_recv(reqQ1, &reqMsg1, 0); 482 assert(reqMsg1.type == EEOS); 483 rspMsg1.type = EEOS; 484 av_thread_message_queue_send(rspQ1, &rspMsg1, 0); 485 } 486 printf("Exit Thread aEnc=%p\n", aEnc); 487 pthread_exit(NULL); 488 } 489 490 int KDD2_deinit(KDD2* aKDD, uint32_t aChannel, int aRefcount) { 491 int ch = aChannel; 492 cl_mem* mem; 493 xlnx_ts_queue* inQ = aKDD->inQ[ch]; 494 xlnx_ts_queue* outQ = aKDD->outQ[ch]; 495 if (inQ) { 496 while(!isEmptyTSQ(inQ)) { 497 mem = (cl_mem*)dequeueTSQ(inQ); 498 if (mem) { 499 for (int i = 0; i < 3; i++) { 500 clReleaseMemObject(mem[i]); 501 } 502 free(mem); 503 } 504 } 505 destroyTSQ(inQ); 506 aKDD->inQ[ch] = NULL; 507 } 508 if (outQ) { 509 while(!isEmptyTSQ(outQ)) { 510 mem = (cl_mem*)dequeueTSQ(outQ); 511 if (mem) { 512 for (int i = 0; i < 2; i++) { 513 clReleaseMemObject(mem[i]); 514 } 515 free(mem); 516 } 517 } 518 destroyTSQ(outQ); 519 aKDD->outQ[ch] = NULL; 520 } 521 for (int i = 0; i < 3; i++) { 522 if (aKDD->InCur[ch][i]) clReleaseMemObject(aKDD->InCur[ch][i]); 523 if ((ch == 0) && (aKDD->inNxt[i])) clReleaseMemObject(aKDD->inNxt[i]); 524 aKDD->CurImgSize[ch][i] = 0; 525 } 526 if ((aRefcount == 0) && aKDD->CSR15_RECON_BASE_V) clReleaseMemObject(aKDD->CSR15_RECON_BASE_V); 527 aKDD->EncodedFrameSize[ch] = 0; 528 aKDD->isDualCh = 0; 529 return 0; 530 } 531 532 static int KDD2_init(KDD2* aKDD, HevcEnc2* aEnc, uint32_t aChannel, int aRefcount) { 533 cl_int status = -1; 534 KDD2* kdd = aKDD; 535 int refcount = aRefcount; 536 int ch = aChannel; 537 U32 width, height; 538 cl_kernel kernel; 539 cl_context* context; 540 U32 ddrBank; 541 cl_mem_ext_ptr_t ext; 542 cl_mem* mem; 543 xlnx_ts_queue* inQ; 544 xlnx_ts_queue* outQ; 545 cl_command_queue cmdQ; 546 cl_mem_migration_flags migflags; 547 548 if ((aKDD == NULL) || (aEnc == NULL)) return -1; 549 550 aKDD->params = &aEnc->params; 551 width = aKDD->params->wh[ch] >> 16; 552 height = aKDD->params->wh[ch] & RESET_UPPER_16; 553 aKDD->CurImgSize[ch][Y] = width * height; 554 aKDD->CurImgSize[ch][U] = (width * height) >> 2; 555 aKDD->CurImgSize[ch][V] = (width * height) >> 2; 556 557 // Encoded Frame data size - hard code to allocate host memory as this varies! 558 aKDD->EncodedFrameSize[ch] = (width * height * 3) >> 1; 559 560 // Setup the CSR registers 561 kernel = aEnc->xKernel->kernel; 562 context = aEnc->xKernel->context; 563 ddrBank = aEnc->xKernel->prfBank; 564 cmdQ = aEnc->xKernel->cmdQ; 565 ext.obj = NULL; 566 ext.param = 0; 567 ext.flags = ddrBank; 568 migflags = 0; 569 570 if (aRefcount == 1) { 571 CREATEBUF2(aKDD->CSR15_RECON_BASE_V, CL_MEM_READ_WRITE | CL_MEM_EXT_PTR_XILINX | CL_MEM_HOST_NO_ACCESS, 32*1024*1024 * sizeof(U8)); 572 } else { 573 aKDD->isDualCh = 1; 574 } 575 inQ = createTSQ(HEVC_KRNL_CH_Q_CAPACITY); 576 outQ = createTSQ(HEVC_KRNL_CH_Q_CAPACITY); 577 if ((NULL == aKDD->outQ) || (NULL == aKDD->inQ)) { 578 if (aKDD->inQ) free(aKDD->inQ); 579 return -1; 580 } 581 aKDD->inQ[ch] = inQ; 582 aKDD->outQ[ch] = outQ; 583 for (int j = 0; j < HEVC_KRNL_CH_Q_CAPACITY; j++) { 584 mem = calloc(3, sizeof(cl_mem)); 585 if (NULL == mem) return -1; 586 CREATEBUF2(mem[Y], CL_MEM_READ_ONLY | CL_MEM_EXT_PTR_XILINX, aKDD->CurImgSize[ch][Y] * sizeof(U8)); 587 CREATEBUF2(mem[U], CL_MEM_READ_ONLY | CL_MEM_EXT_PTR_XILINX, aKDD->CurImgSize[ch][U] * sizeof(U8)); 588 CREATEBUF2(mem[V], CL_MEM_READ_ONLY | CL_MEM_EXT_PTR_XILINX, aKDD->CurImgSize[ch][V] * sizeof(U8)); 589 enqueueTSQ(inQ, mem); 590 mem = calloc(2, sizeof(cl_mem)); 591 if (NULL == mem) return -1; 592 CREATEBUF2(mem[0], CL_MEM_WRITE_ONLY | CL_MEM_EXT_PTR_XILINX, aKDD->EncodedFrameSize[ch] * sizeof(U8)); 593 CREATEBUF2(mem[1], CL_MEM_WRITE_ONLY | CL_MEM_EXT_PTR_XILINX, sizeof(U64)); 594 enqueueTSQ(outQ, mem); 595 } 596 597 if (ch == 0) { 598 OCLCHECKI2(clSetKernelArg, kernel, 0, sizeof(U32), &aKDD->params->wh[0]); 599 OCLCHECKI2(clSetKernelArg, kernel, 14, sizeof(cl_mem), &aKDD->CSR15_RECON_BASE_V); 600 if (aRefcount == 1) { 601 U32 wh = 0; 602 OCLCHECKI2(clSetKernelArg, kernel, 1, sizeof(U32), &wh); 603 OCLCHECKI2(clSetKernelArg, kernel, 5, sizeof(cl_mem), NULL); 604 OCLCHECKI2(clSetKernelArg, kernel, 6, sizeof(cl_mem), NULL); 605 OCLCHECKI2(clSetKernelArg, kernel, 7, sizeof(cl_mem), NULL); 606 OCLCHECKI2(clSetKernelArg, kernel, 17, sizeof(cl_mem), NULL); 607 OCLCHECKI2(clSetKernelArg, kernel, 18, sizeof(cl_mem), NULL); 608 } 609 } else if (ch == 1) { 610 OCLCHECKI2(clSetKernelArg, kernel, 1, sizeof(U32), &aKDD->params->wh[1]); 611 } 612 613 OCLCHECKI2(clSetKernelArg, kernel, 11, sizeof(U32), &aKDD->params->br); 614 OCLCHECKI2(clSetKernelArg, kernel, 12, sizeof(U32), &aKDD->params->qp); 615 OCLCHECKI2(clSetKernelArg, kernel, 13, sizeof(U32), &aKDD->params->ip); 616 OCLCHECKI2(clSetKernelArg, kernel, 19, sizeof(U32), &aKDD->isDualCh); 617 OCLCHECKI2(clSetKernelArg, kernel, 20, sizeof(U32), &aKDD->params->reset); 618 return 0; 619 } 620 621 static int hevc_process(xlnx_host* aHost, xlnx_hw_params aParams, xlnx_hw_buf* aInput, xlnx_hw_buf** aOutput, XContext* aContext) { 622 HevcEncReq reqMsg; 623 HevcEncRsp rspMsg; 624 int ret; 625 HevcEnc2* enc; 626 int ch = aHost->ch; 627 628 reqMsg.host = aHost; 629 reqMsg.params = aParams; 630 reqMsg.in = aInput; 631 reqMsg.out = *aOutput; 632 reqMsg.appCtx = *aContext; 633 reqMsg.type = EProcess; 634 if ((aInput->ptr == NULL) && (aHost->eosRcv == 0)) { 635 reqMsg.type = EEOS; 636 } 637 638 enc = (HevcEnc2*)aHost->privData; 639 640 // Send a request to encode the frame 641 if (aHost->eosRcv == 0) { 642 av_thread_message_queue_send(enc->reqQ[ch], &reqMsg, 0); 643 } 644 645 // Check if there is a response to return from a previous invocation 646 if (aInput->ptr == NULL) { 647 aHost->eosRcv = 1; 648 ret = av_thread_message_queue_recv(enc->rspQ[ch], &rspMsg, 0); 649 } else { 650 ret = av_thread_message_queue_recv(enc->rspQ[ch], &rspMsg, AV_THREAD_MESSAGE_NONBLOCK); 651 } 652 if (ret == AVERROR(EAGAIN)) { 653 *aOutput = NULL; 654 return 0; 655 } 656 if (rspMsg.type == EEOS) { 657 *aOutput = NULL; 658 return 2; 659 } 660 *aOutput = rspMsg.out; 661 *aContext = rspMsg.appCtx; 662 return 1; 663 } 664 665 static int setEnc2CParams(HevcEncParam2* dParames, uint32_t aChannel, HevcEncParam* sParams) { 666 int ch = aChannel; 667 dParames->wh[ch] = (sParams->width << 16) + sParams->height; 668 if (ch == 0) { 669 dParames->qp = (dParames->qp & RESET_LOWER_16) + sParams->qp; 670 dParames->ip = (dParames->ip & RESET_LOWER_16) + sParams->ip; 671 dParames->br = (dParames->br & RESET_LOWER_16) + sParams->bitrate; 672 } else { 673 dParames->qp = (dParames->qp & RESET_UPPER_16) + (sParams->qp << 16); 674 dParames->ip = (dParames->ip & RESET_UPPER_16) + (sParams->ip << 16); 675 dParames->br = (dParames->br & RESET_UPPER_16) + (sParams->bitrate << 16); 676 } 677 dParames->reset = 1; 678 return 0; 679 } 680 681 xlnx_host* createHevcEnc2C(xlnx_kernel* aKernel, uint32_t aChannel, xlnx_hw_params aParams) { 682 HevcEnc2* enc; 683 int err; 684 xlnx_host* host; 685 xlnx_ts_queue* ctxQ; 686 HevcEncCtx* ctx; 687 688 if (aKernel == NULL) return NULL; 689 assert((aChannel == 0) || ((aChannel == 1) && (aKernel->appData != NULL))); 690 691 if (aChannel == 0) { 692 enc = (HevcEnc2*)calloc(1, sizeof(HevcEnc2)); 693 ctxQ = createTSQ(HEVC_KRNL_CH_Q_CAPACITY); 694 if ((enc == NULL) || (ctxQ == NULL)) { 695 if (enc) free(enc); 696 printf("Error: Cannot allocate memory %s at %d\n", __FILE__, __LINE__); 697 return NULL; 698 } 699 enc->refCount = 0; 700 for (int i = 0; i < HEVC_KRNL_CH_Q_CAPACITY; i++) { 701 ctx = calloc(1, sizeof(HevcEncCtx)); 702 if (ctx == NULL) { 703 free(enc); 704 while(!isEmptyTSQ(enc->ctxQ)) { 705 free(dequeueTSQ(enc->ctxQ)); 706 } 707 destroyTSQ(ctxQ); 708 printf("Error: Cannot allocate memory %s at %d\n", __FILE__, __LINE__); 709 return NULL; 710 } 711 ctx->enc = enc; 712 ctx->state = EInit; 713 ctx->lEncode = 0; 714 enqueueTSQ(ctxQ, ctx); 715 } 716 enc->ctxQ = ctxQ; 717 } else if (aChannel == 1) { 718 enc = (HevcEnc2*)aKernel->appData; 719 } 720 721 setEnc2CParams(&enc->params, aChannel, aParams); 722 enc->xKernel = aKernel; 723 enc->refCount++; 724 err = KDD2_init(&enc->kdd, enc, aChannel, enc->refCount); 725 if (err < 0) { 726 printf("Error: createHevcEnc Failed\n"); 727 free(enc); 728 return NULL; 729 } 730 enc->frameNumber[aChannel] = 0; 731 host = (xlnx_host*) calloc(1, sizeof(xlnx_host)); 732 if (host == NULL) { 733 printf("Error: Cannot allocate memory %s at %d\n", __FILE__, __LINE__); 734 return NULL; 735 } 736 host->privData = (void*) enc; 737 host->ch = aChannel; 738 host->processAsync = &hevc_process; 739 host->eosRcv = 0; 740 // Create the message queues 741 printf("Creating request message queue ch[%d]\n", aChannel); 742 err = av_thread_message_queue_alloc(&enc->reqQ[aChannel], 743 HEVC_ENC_IN_Q_CAPACITY, sizeof(HevcEncReq)); 744 printf("Creating response message queue ch[%d]\n", aChannel); 745 err |= av_thread_message_queue_alloc(&enc->rspQ[aChannel], 746 HEVC_ENC_OUT_Q_CAPACITY, sizeof(HevcEncRsp)); 747 748 if (err < 0) 749 { 750 printf("Error: Cannot allocate memory %s at %d\n", __FILE__, __LINE__); 751 destroyHevcEnc2C(host); 752 return NULL; 753 } 754 755 if (aChannel == 0) { 756 printf("create Thread for enc=%p host=%p\n", enc, host); 757 aKernel->appData = (void*) enc; 758 if (pthread_create(&enc->encThread, NULL, process, enc) < 0) { 759 printf("Error: Thread Creation Failed!!\n"); 760 destroyHevcEnc2C(host); 761 return NULL; 762 } 763 } 764 return host; 765 } 766 767 int destroyHevcEnc2C(xlnx_host* aHost) { 768 HevcEnc2* enc; 769 if (aHost == NULL) return -1; 770 enc = (HevcEnc2*)aHost->privData; 771 if (enc == NULL) return -1; 772 enc->refCount--; 773 KDD2_deinit(&enc->kdd, aHost->ch, enc->refCount); 774 if (enc->refCount == 0) { 775 // @Todo Terminate the thread for sure 776 pthread_join(enc->encThread, NULL); 777 778 // Free the message queues 779 for (int i = 0; i < VU9P_HEVC_ENC_NUM_CH; i++) { 780 av_thread_message_queue_free(&enc->reqQ[i]); 781 av_thread_message_queue_free(&enc->rspQ[i]); 782 } 783 if (enc->ctxQ) { 784 while(!isEmptyTSQ(enc->ctxQ)) { 785 free(dequeueTSQ(enc->ctxQ)); 786 } 787 destroyTSQ(enc->ctxQ); 788 } 789 free(enc); 790 } 791 free(aHost); 792 return 0; 793 } -
new file libavcodec/xlnx_hw/hevc/enc_vu9p_2c.h
diff --git a/libavcodec/xlnx_hw/hevc/enc_vu9p_2c.h b/libavcodec/xlnx_hw/hevc/enc_vu9p_2c.h new file mode 100644 index 0000000..2fabc5c
- + 1 #ifndef HEVC_ENC_VU9P_2C_H 2 #define HEVC_ENC_VU9P_2C_H 3 4 #include "../common/inc/xlnx_types_internal.h" 5 6 /* 7 Restrictions for dual channel mode: 8 1. Both the channels must have same framerate 9 2. Parameters like height/width do not change once encoder is initialized 10 3. Both the channels need to be setup (createHevcEnc2C), before the second process 11 request arrives for the first channel(0) 12 */ 13 xlnx_host* createHevcEnc2C(xlnx_kernel* aKernel, uint32_t aChannel, xlnx_hw_params aParams); 14 int destroyHevcEnc2C(xlnx_host* aHost); 15 16 #endif //HEVC_ENC_VU9P_2C_H 17 No newline at end of file -
new file libavcodec/xlnx_hw/hevc/ku115_hevc_enc_config.h
diff --git a/libavcodec/xlnx_hw/hevc/ku115_hevc_enc_config.h b/libavcodec/xlnx_hw/hevc/ku115_hevc_enc_config.h new file mode 100644 index 0000000..68897ee
- + 1 #ifndef KU115_HEVC_ENC_CONFIG 2 #define KU115_HEVC_ENC_CONFIG 3 4 #if LOAD_BINARY_FROM_HEADER 5 #include "hevc_enc_ku115_bin.h" 6 #else 7 static const char* KU115_HEVC_ENC_BINARY = "sdxl_hevc.xclbin"; 8 #endif //LOAD_BINARY_FROM_HEADER 9 // KU115 10 static const char* KU115_BOARD = "xilinx:xil-accel-rd-ku115:4ddr-xpr"; 11 static const char* KU115_HEVC_KRNL_NAME[] = {"sdxl_hevc"}; 12 13 #endif //KU115_HEVC_ENC_CONFIG 14 No newline at end of file -
new file libavcodec/xlnx_hw/hevc/vu9p_hevc_enc_config.h
diff --git a/libavcodec/xlnx_hw/hevc/vu9p_hevc_enc_config.h b/libavcodec/xlnx_hw/hevc/vu9p_hevc_enc_config.h new file mode 100644 index 0000000..7ab4e5b
- + 1 #ifndef VU9P_HEVC_ENC_CONFIG 2 #define VU9P_HEVC_ENC_CONFIG 3 4 #include "../common/inc/xlnx_types_internal.h" 5 6 #if LOAD_BINARY_FROM_HEADER 7 #include "hevc_enc_vu9p_bin.h" 8 #include "hevc_enc_vu9p_2k2c_bin.h" 9 #else 10 static const char* VU9P_HEVC_ENC_BINARY = "hevc_enc_vu9p_2k2c.aws.awsxclbin"; 11 #endif //LOAD_BINARY_FROM_HEADER 12 13 // VU9P 14 static const char* VU9P_BOARD = "xilinx:aws-vu9p-f1:4ddr-xpr-2pr"; 15 16 static KRNL_CONFIG VU9P_HEVC_CONFIG[] = { 17 {"krnl_ngcodec_hevc_f1_0", XCL_MEM_DDR_BANK3}, 18 #if 0 19 {"krnl_ngcodec_hevc_1", XCL_MEM_DDR_BANK3} 20 #endif //VU9P_HEVC_ENC_2_K 21 }; 22 23 24 #endif //VU9P_HEVC_ENC_CONFIG -
new file libavcodec/xlnx_hw/xlnx_hw.c
diff --git a/libavcodec/xlnx_hw/xlnx_hw.c b/libavcodec/xlnx_hw/xlnx_hw.c new file mode 100644 index 0000000..712400d
- + 1 #include "stdio.h" 2 #include "stddef.h" 3 #include "xlnx_hw.h" 4 #include "common/inc/xlnx_hrm.h" 5 #include "common/inc/xlnx_types_internal.h" 6 7 int xlnx_hw_init(const char* aConfigFile, xlnx_hw_id aHWID) { 8 return xlnx_hrm_init(aConfigFile, aHWID); 9 } 10 11 int xlnx_hw_deinit(void) { 12 return xlnx_hrm_deinit(); 13 } 14 15 xlnx_hw xlnx_hw_get(xlnx_hw_id aHW, xlnx_hw_params aParams) { 16 return (xlnx_hw)xlnx_hrm_get_host(aHW, aParams); 17 } 18 19 int xlnx_hw_process(xlnx_hw aHW, xlnx_hw_params aParams, xlnx_hw_buf* aInput, xlnx_hw_buf* aOutput) { 20 int err; 21 xlnx_host* host; 22 err = -1; 23 host = (xlnx_host*)aHW; 24 if (host->process) { 25 err = host->process(host, aParams, aInput, aOutput); 26 } else { 27 printf("Error: Not Implemented"); 28 } 29 return err; 30 } 31 32 int xlnx_hw_process_async(xlnx_hw aHW, xlnx_hw_params aParams, xlnx_hw_buf* aInput, xlnx_hw_buf** aOutput, XContext* aContext) { 33 int err; 34 xlnx_host* host; 35 err = -1; 36 host = (xlnx_host*)aHW; 37 if (host->processAsync) { 38 err = host->processAsync(host, aParams, aInput, aOutput, aContext); 39 } else { 40 printf("Error: Not Implemented"); 41 } 42 return err; 43 } 44 45 int xlnx_hw_release(xlnx_hw aHW) { 46 return xlnx_hrm_release_host((xlnx_host*) aHW); 47 } 48 49 -
new file libavcodec/xlnx_hw/xlnx_hw.h
diff --git a/libavcodec/xlnx_hw/xlnx_hw.h b/libavcodec/xlnx_hw/xlnx_hw.h new file mode 100755 index 0000000..ea5fc41
- + 1 #ifndef XLNX_HW_H 2 #define XLNX_HW_H 3 #include "xlnx_hw_types.h" 4 5 int xlnx_hw_init(const char* aConfigFile, xlnx_hw_id aHWID); 6 int xlnx_hw_deinit(void); 7 8 xlnx_hw xlnx_hw_get(xlnx_hw_id aHWID, xlnx_hw_params aParams); 9 int xlnx_hw_process(xlnx_hw aHW, xlnx_hw_params aParams, xlnx_hw_buf* aInput, xlnx_hw_buf* aOutput); 10 //@TODO Async API added for POC. Aync API with callback to be added later 11 int xlnx_hw_process_async(xlnx_hw aHW, xlnx_hw_params aParams, xlnx_hw_buf* aInput, xlnx_hw_buf** aOutput, XContext* aContext); 12 int xlnx_hw_release(xlnx_hw aHW); 13 14 #endif // XLNX_HW_H -
new file libavcodec/xlnx_hw/xlnx_hw_types.h
diff --git a/libavcodec/xlnx_hw/xlnx_hw_types.h b/libavcodec/xlnx_hw/xlnx_hw_types.h new file mode 100644 index 0000000..14da602
- + 1 #ifndef XLNX_HW_TYPES_H 2 #define XLNX_HW_TYPES_H 3 4 //@TODO define informative error codes 5 #define XLNX_MAX_COMPONENTS 3 6 typedef unsigned char U8; 7 typedef unsigned int U32; 8 typedef unsigned long long U64; 9 10 11 typedef void* xlnx_hw; 12 typedef void* xlnx_hw_params; 13 typedef void* XBUF; 14 typedef void* XDATA; 15 typedef void* XContext; 16 17 typedef enum { 18 EDATA, 19 ERAW 20 } xlnx_buf_type; 21 22 typedef struct xlnx_hw_buf { 23 xlnx_buf_type type; 24 XBUF ptr; 25 void* user_priv; 26 void* priv; 27 } xlnx_hw_buf; 28 29 //EDATA 30 typedef struct xlnx_data { 31 XDATA pDATA; 32 U64 offset; 33 U64 size; 34 } xlnx_data_buf; 35 36 //ERAW (YUV, RGB etc) 37 typedef struct { 38 xlnx_data_buf data[XLNX_MAX_COMPONENTS]; 39 } xlnx_cmp_buf; 40 41 typedef enum xlnx_hw_id { 42 ENone, 43 EHevcEnc 44 } xlnx_hw_id; 45 46 typedef struct HevcEncParam { 47 U32 width; 48 U32 height; 49 U32 bitrate; 50 U32 qp; // quantization parameter 51 U32 ip; // intra period 52 U32 reset; 53 } HevcEncParam; 54 55 #endif //XLNX_HW_TYPES_H 56 No newline at end of file -
libavutil/opencl.c
diff --git a/libavutil/opencl.c b/libavutil/opencl.c index af35770..00992b4 100644
a b static const AVClass openclutils_class = { 88 88 89 89 static OpenclContext opencl_ctx = {&openclutils_class}; 90 90 91 static const cl_device_type device_type[] = {CL_DEVICE_TYPE_GPU, CL_DEVICE_TYPE_CPU };91 static const cl_device_type device_type[] = {CL_DEVICE_TYPE_GPU, CL_DEVICE_TYPE_CPU, CL_DEVICE_TYPE_ACCELERATOR}; 92 92 93 93 typedef struct { 94 94 int err_code;
