1 /*
2 * Copyright 2010 Samsung Electronics Co. LTD
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <stdlib.h>
18 #include <unistd.h>
19 #include <string.h>
20 #include <fcntl.h>
21
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <sys/ioctl.h>
25 #include <sys/mman.h>
26 #include <utils/Log.h>
27
28 #include "SsbSipMfcApi.h"
29 #include "mfc_interface.h"
30
31 #define _MFCLIB_MAGIC_NUMBER 0x92241001
32
SsbSipMfcEncOpen(void * value)33 void *SsbSipMfcEncOpen(void *value)
34 {
35 int hMFCOpen;
36 _MFCLIB *pCTX;
37 unsigned int mapped_addr;
38 mfc_common_args EncArg;
39 int ret_code;
40
41 hMFCOpen = open(S5PC110_MFC_DEV_NAME, O_RDWR | O_NDELAY);
42 if (hMFCOpen < 0) {
43 ALOGE("SsbSipMfcEncOpen: MFC Open failure\n");
44 return NULL;
45 }
46
47 pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB));
48 if (pCTX == NULL) {
49 ALOGE("SsbSipMfcEncOpen: malloc failed.\n");
50 close(hMFCOpen);
51 return NULL;
52 }
53
54 if (*(unsigned int *)value == NO_CACHE ||
55 *(unsigned int *)value == CACHE) {
56 EncArg.args.buf_type = *(unsigned int *)value;
57 ret_code = ioctl(hMFCOpen, IOCTL_MFC_BUF_CACHE, &EncArg);
58 if (EncArg.ret_code != MFC_RET_OK) {
59 ALOGE("SsbSipMfcDecOpenExt: IOCTL_MFC_BUF_CACHE (%d) failed\n", EncArg.ret_code);
60 }
61 } else {
62 ALOGE("SsbSipMfcDecOpenExt: value is invalid, value: %d\n", *(int *)value);
63 }
64
65 mapped_addr = (unsigned int)mmap(0, MMAP_BUFFER_SIZE_MMAP, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0);
66 if (!mapped_addr) {
67 ALOGE("SsbSipMfcEncOpen: FIMV5.0 driver address mapping failed\n");
68 return NULL;
69 }
70
71 memset(pCTX, 0, sizeof(_MFCLIB));
72
73 pCTX->magic = _MFCLIB_MAGIC_NUMBER;
74 pCTX->hMFC = hMFCOpen;
75 pCTX->mapped_addr = mapped_addr;
76 pCTX->inter_buff_status = MFC_USE_NONE;
77
78 return (void *)pCTX;
79 }
80
SsbSipMfcEncInit(void * openHandle,void * param)81 SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param)
82 {
83 int ret_code;
84 int dpbBufSize;
85
86 _MFCLIB *pCTX;
87 mfc_common_args EncArg;
88 mfc_common_args user_addr_arg, phys_addr_arg;
89 SSBSIP_MFC_ENC_H264_PARAM *h264_arg;
90 SSBSIP_MFC_ENC_MPEG4_PARAM *mpeg4_arg;
91 SSBSIP_MFC_ENC_H263_PARAM *h263_arg;
92 SSBSIP_MFC_CODEC_TYPE codec_type;
93
94 pCTX = (_MFCLIB *)openHandle;
95 memset(&EncArg, 0, sizeof(mfc_common_args));
96
97 ALOGV("SsbSipMfcEncInit: Encode Init start\n");
98
99 mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM *)param;
100 codec_type = mpeg4_arg->codecType;
101
102 if ((codec_type != MPEG4_ENC) &&
103 (codec_type != H264_ENC) &&
104 (codec_type != H263_ENC)) {
105 ALOGE("SsbSipMfcEncOpen: Undefined codec type.\n");
106 return MFC_RET_INVALID_PARAM;
107 }
108
109 pCTX->codec_type = codec_type;
110
111 switch (pCTX->codec_type) {
112 case MPEG4_ENC:
113 ALOGV("SsbSipMfcEncInit: MPEG4 Encode\n");
114 mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM *)param;
115
116 pCTX->width = mpeg4_arg->SourceWidth;
117 pCTX->height = mpeg4_arg->SourceHeight;
118 break;
119
120 case H263_ENC:
121 ALOGV("SsbSipMfcEncInit: H263 Encode\n");
122 h263_arg = (SSBSIP_MFC_ENC_H263_PARAM *)param;
123
124 pCTX->width = h263_arg->SourceWidth;
125 pCTX->height = h263_arg->SourceHeight;
126 break;
127
128 case H264_ENC:
129 ALOGV("SsbSipMfcEncInit: H264 Encode\n");
130 h264_arg = (SSBSIP_MFC_ENC_H264_PARAM *)param;
131
132 pCTX->width = h264_arg->SourceWidth;
133 pCTX->height = h264_arg->SourceHeight;
134 break;
135
136 default:
137 break;
138 }
139
140 switch (pCTX->codec_type) {
141 case MPEG4_ENC:
142 mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM*)param;
143
144 EncArg.args.enc_init_mpeg4.in_codec_type = pCTX->codec_type;
145 EncArg.args.enc_init_mpeg4.in_profile_level = ENC_PROFILE_LEVEL(mpeg4_arg->ProfileIDC, mpeg4_arg->LevelIDC);
146
147 EncArg.args.enc_init_mpeg4.in_width = mpeg4_arg->SourceWidth;
148 EncArg.args.enc_init_mpeg4.in_height = mpeg4_arg->SourceHeight;
149 EncArg.args.enc_init_mpeg4.in_gop_num = mpeg4_arg->IDRPeriod;
150 if (mpeg4_arg->DisableQpelME)
151 EncArg.args.enc_init_mpeg4.in_qpelME_enable = 0;
152 else
153 EncArg.args.enc_init_mpeg4.in_qpelME_enable = 1;
154
155 EncArg.args.enc_init_mpeg4.in_MS_mode = mpeg4_arg->SliceMode;
156 EncArg.args.enc_init_mpeg4.in_MS_size = mpeg4_arg->SliceArgument;
157
158 if (mpeg4_arg->NumberBFrames > 2) {
159 ALOGE("SsbSipMfcEncInit: No such BframeNum is supported.\n");
160 return MFC_RET_INVALID_PARAM;
161 }
162 EncArg.args.enc_init_mpeg4.in_BframeNum = mpeg4_arg->NumberBFrames;
163 EncArg.args.enc_init_mpeg4.in_mb_refresh = mpeg4_arg->RandomIntraMBRefresh;
164
165 /* rate control*/
166 EncArg.args.enc_init_mpeg4.in_RC_frm_enable = mpeg4_arg->EnableFRMRateControl;
167 if ((mpeg4_arg->QSCodeMin > 51) || (mpeg4_arg->QSCodeMax > 51)) {
168 ALOGE("SsbSipMfcEncInit: No such Min/Max QP is supported.\n");
169 return MFC_RET_INVALID_PARAM;
170 }
171 EncArg.args.enc_init_mpeg4.in_RC_qbound = ENC_RC_QBOUND(mpeg4_arg->QSCodeMin, mpeg4_arg->QSCodeMax);
172 EncArg.args.enc_init_mpeg4.in_RC_rpara = mpeg4_arg->CBRPeriodRf;
173
174 /* pad control */
175 EncArg.args.enc_init_mpeg4.in_pad_ctrl_on = mpeg4_arg->PadControlOn;
176 if ((mpeg4_arg->LumaPadVal > 255) || (mpeg4_arg->CbPadVal > 255) || (mpeg4_arg->CrPadVal > 255)) {
177 ALOGE("SsbSipMfcEncInit: No such Pad value is supported.\n");
178 return MFC_RET_INVALID_PARAM;
179 }
180 EncArg.args.enc_init_mpeg4.in_luma_pad_val = mpeg4_arg->LumaPadVal;
181 EncArg.args.enc_init_mpeg4.in_cb_pad_val = mpeg4_arg->CbPadVal;
182 EncArg.args.enc_init_mpeg4.in_cr_pad_val = mpeg4_arg->CrPadVal;
183 EncArg.args.enc_init_mpeg4.in_frame_map = mpeg4_arg->FrameMap;
184
185 EncArg.args.enc_init_mpeg4.in_time_increament_res = mpeg4_arg->TimeIncreamentRes;
186 EncArg.args.enc_init_mpeg4.in_time_vop_time_increament = mpeg4_arg->VopTimeIncreament;
187 EncArg.args.enc_init_mpeg4.in_RC_framerate = (mpeg4_arg->TimeIncreamentRes / mpeg4_arg->VopTimeIncreament);
188 EncArg.args.enc_init_mpeg4.in_RC_bitrate = mpeg4_arg->Bitrate;
189 if ((mpeg4_arg->FrameQp > 51) || (mpeg4_arg->FrameQp_P) > 51 || (mpeg4_arg->FrameQp_B > 51)) {
190 ALOGE("SsbSipMfcEncInit: No such FrameQp is supported.\n");
191 return MFC_RET_INVALID_PARAM;
192 }
193 EncArg.args.enc_init_mpeg4.in_frame_qp = mpeg4_arg->FrameQp;
194 if (mpeg4_arg->FrameQp_P)
195 EncArg.args.enc_init_mpeg4.in_frame_P_qp = mpeg4_arg->FrameQp_P;
196 else
197 EncArg.args.enc_init_mpeg4.in_frame_P_qp = mpeg4_arg->FrameQp;
198 if (mpeg4_arg->FrameQp_B)
199 EncArg.args.enc_init_mpeg4.in_frame_B_qp = mpeg4_arg->FrameQp_B;
200 else
201 EncArg.args.enc_init_mpeg4.in_frame_B_qp = mpeg4_arg->FrameQp;
202
203 break;
204
205 case H263_ENC:
206 h263_arg = (SSBSIP_MFC_ENC_H263_PARAM *)param;
207
208 EncArg.args.enc_init_mpeg4.in_codec_type = pCTX->codec_type;
209 EncArg.args.enc_init_mpeg4.in_profile_level = ENC_PROFILE_LEVEL(66, 40);
210 EncArg.args.enc_init_mpeg4.in_width = h263_arg->SourceWidth;
211 EncArg.args.enc_init_mpeg4.in_height = h263_arg->SourceHeight;
212 EncArg.args.enc_init_mpeg4.in_gop_num = h263_arg->IDRPeriod;
213 EncArg.args.enc_init_mpeg4.in_mb_refresh = h263_arg->RandomIntraMBRefresh;
214 EncArg.args.enc_init_mpeg4.in_MS_mode = h263_arg->SliceMode;
215 EncArg.args.enc_init_mpeg4.in_MS_size = 0;
216
217 /* rate control*/
218 EncArg.args.enc_init_mpeg4.in_RC_frm_enable = h263_arg->EnableFRMRateControl;
219 if ((h263_arg->QSCodeMin > 51) || (h263_arg->QSCodeMax > 51)) {
220 ALOGE("SsbSipMfcEncInit: No such Min/Max QP is supported.\n");
221 return MFC_RET_INVALID_PARAM;
222 }
223 EncArg.args.enc_init_mpeg4.in_RC_qbound = ENC_RC_QBOUND(h263_arg->QSCodeMin, h263_arg->QSCodeMax);
224 EncArg.args.enc_init_mpeg4.in_RC_rpara = h263_arg->CBRPeriodRf;
225
226 /* pad control */
227 EncArg.args.enc_init_mpeg4.in_pad_ctrl_on = h263_arg->PadControlOn;
228 if ((h263_arg->LumaPadVal > 255) || (h263_arg->CbPadVal > 255) || (h263_arg->CrPadVal > 255)) {
229 ALOGE("SsbSipMfcEncInit: No such Pad value is supported.\n");
230 return MFC_RET_INVALID_PARAM;
231 }
232 EncArg.args.enc_init_mpeg4.in_luma_pad_val = h263_arg->LumaPadVal;
233 EncArg.args.enc_init_mpeg4.in_cb_pad_val = h263_arg->CbPadVal;
234 EncArg.args.enc_init_mpeg4.in_cr_pad_val = h263_arg->CrPadVal;
235 EncArg.args.enc_init_mpeg4.in_frame_map = mpeg4_arg->FrameMap;
236
237 EncArg.args.enc_init_mpeg4.in_RC_framerate = h263_arg->FrameRate;
238 EncArg.args.enc_init_mpeg4.in_RC_bitrate = h263_arg->Bitrate;
239 if (h263_arg->FrameQp > 51) {
240 ALOGE("SsbSipMfcEncInit: No such FrameQp is supported.\n");
241 return MFC_RET_INVALID_PARAM;
242 }
243 EncArg.args.enc_init_mpeg4.in_frame_qp = h263_arg->FrameQp;
244 if (h263_arg->FrameQp_P)
245 EncArg.args.enc_init_mpeg4.in_frame_P_qp = h263_arg->FrameQp_P;
246 else
247 EncArg.args.enc_init_mpeg4.in_frame_P_qp = h263_arg->FrameQp;
248
249 break;
250
251 case H264_ENC:
252 h264_arg = (SSBSIP_MFC_ENC_H264_PARAM *)param;
253
254 EncArg.args.enc_init_h264.in_codec_type = H264_ENC;
255 EncArg.args.enc_init_h264.in_profile_level = ENC_PROFILE_LEVEL(h264_arg->ProfileIDC, h264_arg->LevelIDC);
256
257 EncArg.args.enc_init_h264.in_width = h264_arg->SourceWidth;
258 EncArg.args.enc_init_h264.in_height = h264_arg->SourceHeight;
259 EncArg.args.enc_init_h264.in_gop_num = h264_arg->IDRPeriod;
260
261 if ((h264_arg->NumberRefForPframes > 2) || (h264_arg->NumberReferenceFrames > 2)) {
262 ALOGE("SsbSipMfcEncInit: No such ref Num is supported.\n");
263 return MFC_RET_INVALID_PARAM;
264 }
265 EncArg.args.enc_init_h264.in_reference_num = h264_arg->NumberReferenceFrames;
266 EncArg.args.enc_init_h264.in_ref_num_p = h264_arg->NumberRefForPframes;
267
268 if ((h264_arg->SliceMode == 0) || (h264_arg->SliceMode == 1) ||
269 (h264_arg->SliceMode == 2) || (h264_arg->SliceMode == 4)) {
270 EncArg.args.enc_init_h264.in_MS_mode = h264_arg->SliceMode;
271 } else {
272 ALOGE("SsbSipMfcEncInit: No such slice mode is supported.\n");
273 return MFC_RET_INVALID_PARAM;
274 }
275 EncArg.args.enc_init_h264.in_MS_size = h264_arg->SliceArgument;
276
277 if (h264_arg->NumberBFrames > 2) {
278 ALOGE("SsbSipMfcEncInit: No such BframeNum is supported.\n");
279 return MFC_RET_INVALID_PARAM;
280 }
281 EncArg.args.enc_init_h264.in_BframeNum = h264_arg->NumberBFrames;
282
283 EncArg.args.enc_init_h264.in_deblock_filt = h264_arg->LoopFilterDisable;
284 if ((abs(h264_arg->LoopFilterAlphaC0Offset) > 6) || (abs(h264_arg->LoopFilterBetaOffset) > 6)) {
285 ALOGE("SsbSipMfcEncInit: No such AlphaC0Offset or BetaOffset is supported.\n");
286 return MFC_RET_INVALID_PARAM;
287 }
288 EncArg.args.enc_init_h264.in_deblock_alpha_C0 = h264_arg->LoopFilterAlphaC0Offset;
289 EncArg.args.enc_init_h264.in_deblock_beta = h264_arg->LoopFilterBetaOffset;
290
291 EncArg.args.enc_init_h264.in_symbolmode = h264_arg->SymbolMode;
292 EncArg.args.enc_init_h264.in_interlace_mode = h264_arg->PictureInterlace;
293 EncArg.args.enc_init_h264.in_transform8x8_mode = h264_arg->Transform8x8Mode;
294
295 EncArg.args.enc_init_h264.in_mb_refresh = h264_arg->RandomIntraMBRefresh;
296
297 /* pad control */
298 EncArg.args.enc_init_h264.in_pad_ctrl_on = h264_arg->PadControlOn;
299 if ((h264_arg->LumaPadVal > 255) || (h264_arg->CbPadVal > 255) || (h264_arg->CrPadVal > 255)) {
300 ALOGE("SsbSipMfcEncInit: No such Pad value is supported.\n");
301 return MFC_RET_INVALID_PARAM;
302 }
303 EncArg.args.enc_init_h264.in_luma_pad_val = h264_arg->LumaPadVal;
304 EncArg.args.enc_init_h264.in_cb_pad_val = h264_arg->CbPadVal;
305 EncArg.args.enc_init_h264.in_cr_pad_val = h264_arg->CrPadVal;
306 EncArg.args.enc_init_mpeg4.in_frame_map = mpeg4_arg->FrameMap;
307
308 /* rate control*/
309 EncArg.args.enc_init_h264.in_RC_frm_enable = h264_arg->EnableFRMRateControl;
310 EncArg.args.enc_init_h264.in_RC_mb_enable = h264_arg->EnableMBRateControl;
311 EncArg.args.enc_init_h264.in_RC_framerate = h264_arg->FrameRate;
312 EncArg.args.enc_init_h264.in_RC_bitrate = h264_arg->Bitrate;
313 if (h264_arg->FrameQp > 51) {
314 ALOGE("SsbSipMfcEncInit: No such FrameQp is supported.\n");
315 return MFC_RET_INVALID_PARAM;
316 }
317 EncArg.args.enc_init_h264.in_frame_qp = h264_arg->FrameQp;
318 if (h264_arg->FrameQp_P)
319 EncArg.args.enc_init_h264.in_frame_P_qp = h264_arg->FrameQp_P;
320 else
321 EncArg.args.enc_init_h264.in_frame_P_qp = h264_arg->FrameQp;
322 if (h264_arg->FrameQp_B)
323 EncArg.args.enc_init_h264.in_frame_B_qp = h264_arg->FrameQp_B;
324 else
325 EncArg.args.enc_init_h264.in_frame_B_qp = h264_arg->FrameQp;
326
327 if ((h264_arg->QSCodeMin > 51) || (h264_arg->QSCodeMax > 51)) {
328 ALOGE("SsbSipMfcEncInit: No such Min/Max QP is supported.\n");
329 return MFC_RET_INVALID_PARAM;
330 }
331 EncArg.args.enc_init_h264.in_RC_qbound = ENC_RC_QBOUND(h264_arg->QSCodeMin, h264_arg->QSCodeMax);
332 EncArg.args.enc_init_h264.in_RC_rpara = h264_arg->CBRPeriodRf;
333 EncArg.args.enc_init_h264.in_RC_mb_dark_disable = h264_arg->DarkDisable;
334 EncArg.args.enc_init_h264.in_RC_mb_smooth_disable = h264_arg->SmoothDisable;
335 EncArg.args.enc_init_h264.in_RC_mb_static_disable = h264_arg->StaticDisable;
336 EncArg.args.enc_init_h264.in_RC_mb_activity_disable = h264_arg->ActivityDisable;
337
338 /* default setting */
339 EncArg.args.enc_init_h264.in_md_interweight_pps = 0;
340 EncArg.args.enc_init_h264.in_md_intraweight_pps = 0;
341 break;
342
343 default:
344 break;
345 }
346
347 EncArg.args.enc_init_mpeg4.in_mapped_addr = pCTX->mapped_addr;
348
349 ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_ENC_INIT, &EncArg);
350 if (EncArg.ret_code != MFC_RET_OK) {
351 ALOGE("SsbSipMfcEncInit: IOCTL_MFC_ENC_INIT (%d) failed\n", EncArg.ret_code);
352 return MFC_RET_ENC_INIT_FAIL;
353 }
354
355 pCTX->virStrmBuf = EncArg.args.enc_init_mpeg4.out_u_addr.strm_ref_y;
356 pCTX->phyStrmBuf = EncArg.args.enc_init_mpeg4.out_p_addr.strm_ref_y;
357 pCTX->sizeStrmBuf = MAX_ENCODER_OUTPUT_BUFFER_SIZE;
358 pCTX->encodedHeaderSize = EncArg.args.enc_init_mpeg4.out_header_size;
359
360 pCTX->virMvRefYC = EncArg.args.enc_init_mpeg4.out_u_addr.mv_ref_yc;
361
362 pCTX->inter_buff_status |= MFC_USE_STRM_BUFF;
363
364 return MFC_RET_OK;
365 }
366
SsbSipMfcEncExe(void * openHandle)367 SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle)
368 {
369 int ret_code;
370 _MFCLIB *pCTX;
371 mfc_common_args EncArg;
372
373 if (openHandle == NULL) {
374 ALOGE("SsbSipMfcEncExe: openHandle is NULL\n");
375 return MFC_RET_INVALID_PARAM;
376 }
377
378 pCTX = (_MFCLIB *)openHandle;
379
380 memset(&EncArg, 0x00, sizeof(mfc_common_args));
381
382 EncArg.args.enc_exe.in_codec_type = pCTX->codec_type;
383 EncArg.args.enc_exe.in_Y_addr = (unsigned int)pCTX->phyFrmBuf.luma;
384 EncArg.args.enc_exe.in_CbCr_addr = (unsigned int)pCTX->phyFrmBuf.chroma;
385 EncArg.args.enc_exe.in_Y_addr_vir = (unsigned int)pCTX->virFrmBuf.luma;
386 EncArg.args.enc_exe.in_CbCr_addr_vir = (unsigned int)pCTX->virFrmBuf.chroma;
387 EncArg.args.enc_exe.in_strm_st = (unsigned int)pCTX->phyStrmBuf;
388 EncArg.args.enc_exe.in_strm_end = (unsigned int)pCTX->phyStrmBuf + pCTX->sizeStrmBuf;
389 EncArg.args.enc_exe.in_frametag = pCTX->in_frametag;
390 if (pCTX->encode_cnt == 0) {
391 EncArg.args.enc_exe.in_strm_st = (unsigned int)pCTX->phyStrmBuf;
392 EncArg.args.enc_exe.in_strm_end = (unsigned int)pCTX->phyStrmBuf + pCTX->sizeStrmBuf;
393 } else {
394 EncArg.args.enc_exe.in_strm_st = (unsigned int)pCTX->phyStrmBuf + (MAX_ENCODER_OUTPUT_BUFFER_SIZE/2);
395 EncArg.args.enc_exe.in_strm_end = (unsigned int)pCTX->phyStrmBuf + (MAX_ENCODER_OUTPUT_BUFFER_SIZE/2) + pCTX->sizeStrmBuf;
396 }
397
398 ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_ENC_EXE, &EncArg);
399 if (EncArg.ret_code != MFC_RET_OK) {
400 ALOGE("SsbSipMfcDecExe: IOCTL_MFC_ENC_EXE failed(ret : %d)\n", EncArg.ret_code);
401 return MFC_RET_ENC_EXE_ERR;
402 }
403
404 pCTX->encodedDataSize = EncArg.args.enc_exe.out_encoded_size;
405 pCTX->encodedframeType = EncArg.args.enc_exe.out_frame_type;
406 pCTX->encoded_Y_paddr = EncArg.args.enc_exe.out_encoded_Y_paddr;
407 pCTX->encoded_C_paddr = EncArg.args.enc_exe.out_encoded_C_paddr;
408 pCTX->out_frametag_top = EncArg.args.enc_exe.out_frametag_top;
409 pCTX->out_frametag_bottom = EncArg.args.enc_exe.out_frametag_bottom;
410
411 return MFC_RET_OK;
412 }
413
SsbSipMfcEncClose(void * openHandle)414 SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle)
415 {
416 int ret_code;
417 _MFCLIB *pCTX;
418 mfc_common_args free_arg;
419
420 if (openHandle == NULL) {
421 ALOGE("SsbSipMfcEncClose: openHandle is NULL\n");
422 return MFC_RET_INVALID_PARAM;
423 }
424
425 pCTX = (_MFCLIB *)openHandle;
426
427 if (pCTX->inter_buff_status & MFC_USE_YUV_BUFF) {
428 free_arg.args.mem_free.u_addr = pCTX->virFrmBuf.luma;
429 ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg);
430 }
431
432 if (pCTX->inter_buff_status & MFC_USE_STRM_BUFF) {
433 free_arg.args.mem_free.u_addr = pCTX->virStrmBuf;
434 ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg);
435 free_arg.args.mem_free.u_addr = pCTX->virMvRefYC;
436 ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg);
437 }
438
439 pCTX->inter_buff_status = MFC_USE_NONE;
440
441 munmap((void *)pCTX->mapped_addr, MMAP_BUFFER_SIZE_MMAP);
442 close(pCTX->hMFC);
443 free(pCTX);
444
445 return MFC_RET_OK;
446 }
447
SsbSipMfcEncSetSize(void * openHandle,SSBSIP_MFC_CODEC_TYPE codecType,int nWidth,int nHeight)448 SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetSize(void *openHandle, SSBSIP_MFC_CODEC_TYPE codecType, int nWidth, int nHeight)
449 {
450 _MFCLIB *pCTX = (_MFCLIB *)openHandle;
451
452 if (pCTX == NULL)
453 return MFC_RET_INVALID_PARAM;
454
455 if (nWidth <= 0 || nHeight <= 0)
456 return MFC_RET_INVALID_PARAM;
457 pCTX->width = nWidth;
458 pCTX->height = nHeight;
459
460 if ((H264_ENC != codecType) &&
461 (MPEG4_ENC != codecType) &&
462 (H263_ENC != codecType))
463 return MFC_RET_INVALID_PARAM;
464 pCTX->codec_type = codecType;
465
466 return MFC_RET_OK;
467 }
468
SsbSipMfcEncGetInBuf(void * openHandle,SSBSIP_MFC_ENC_INPUT_INFO * input_info)469 SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info)
470 {
471 int ret_code;
472 _MFCLIB *pCTX;
473 mfc_common_args user_addr_arg, phys_addr_arg;
474 int y_size, c_size;
475 int aligned_y_size, aligned_c_size;
476
477 if (openHandle == NULL) {
478 ALOGE("SsbSipMfcEncGetInBuf: openHandle is NULL\n");
479 return MFC_RET_INVALID_PARAM;
480 }
481
482 pCTX = (_MFCLIB *)openHandle;
483
484 user_addr_arg.args.mem_alloc.codec_type = pCTX->codec_type;
485
486 y_size = pCTX->width * pCTX->height;
487 c_size = (pCTX->width * pCTX->height) >> 1;
488
489 aligned_y_size = ALIGN_TO_8KB(ALIGN_TO_128B(pCTX->width) * ALIGN_TO_32B(pCTX->height));
490 aligned_c_size = ALIGN_TO_8KB(ALIGN_TO_128B(pCTX->width) * ALIGN_TO_32B(pCTX->height/2));
491
492 /* Allocate luma & chroma buf */
493 user_addr_arg.args.mem_alloc.buff_size = aligned_y_size + aligned_c_size;
494 user_addr_arg.args.mem_alloc.mapped_addr = pCTX->mapped_addr;
495 ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_IN_BUF, &user_addr_arg);
496 if (ret_code < 0) {
497 ALOGE("SsbSipMfcEncGetInBuf: IOCTL_MFC_GET_IN_BUF failed\n");
498 return MFC_RET_ENC_GET_INBUF_FAIL;
499 }
500 pCTX->virFrmBuf.luma = user_addr_arg.args.mem_alloc.out_uaddr;
501 pCTX->virFrmBuf.chroma = user_addr_arg.args.mem_alloc.out_uaddr + (unsigned int)aligned_y_size;
502 pCTX->phyFrmBuf.luma = user_addr_arg.args.mem_alloc.out_paddr;
503 pCTX->phyFrmBuf.chroma = user_addr_arg.args.mem_alloc.out_paddr + (unsigned int)aligned_y_size;
504
505 pCTX->sizeFrmBuf.luma = (unsigned int)y_size;
506 pCTX->sizeFrmBuf.chroma = (unsigned int)c_size;
507 pCTX->inter_buff_status |= MFC_USE_YUV_BUFF;
508
509 input_info->YPhyAddr = (void*)pCTX->phyFrmBuf.luma;
510 input_info->CPhyAddr = (void*)pCTX->phyFrmBuf.chroma;
511 input_info->YVirAddr = (void*)pCTX->virFrmBuf.luma;
512 input_info->CVirAddr = (void*)pCTX->virFrmBuf.chroma;
513
514 input_info->YSize = aligned_y_size;
515 input_info->CSize = aligned_c_size;
516
517 return MFC_RET_OK;
518 }
519
SsbSipMfcEncSetInBuf(void * openHandle,SSBSIP_MFC_ENC_INPUT_INFO * input_info)520 SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info)
521 {
522 _MFCLIB *pCTX;
523
524 if (openHandle == NULL) {
525 ALOGE("SsbSipMfcEncSetInBuf: openHandle is NULL\n");
526 return MFC_RET_INVALID_PARAM;
527 }
528
529 ALOGV("SsbSipMfcEncSetInBuf: input_info->YPhyAddr & input_info->CPhyAddr should be 64KB aligned\n");
530
531 pCTX = (_MFCLIB *)openHandle;
532
533 pCTX->phyFrmBuf.luma = (unsigned int)input_info->YPhyAddr;
534 pCTX->phyFrmBuf.chroma = (unsigned int)input_info->CPhyAddr;
535 pCTX->virFrmBuf.luma = (unsigned int)input_info->YVirAddr;
536 pCTX->virFrmBuf.chroma = (unsigned int)input_info->CVirAddr;
537
538 pCTX->sizeFrmBuf.luma = (unsigned int)input_info->YSize;
539 pCTX->sizeFrmBuf.chroma = (unsigned int)input_info->CSize;
540
541 return MFC_RET_OK;
542 }
543
SsbSipMfcEncGetOutBuf(void * openHandle,SSBSIP_MFC_ENC_OUTPUT_INFO * output_info)544 SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUTPUT_INFO *output_info)
545 {
546 _MFCLIB *pCTX;
547
548 if (openHandle == NULL) {
549 ALOGE("SsbSipMfcEncGetOutBuf: openHandle is NULL\n");
550 return MFC_RET_INVALID_PARAM;
551 }
552
553 pCTX = (_MFCLIB *)openHandle;
554
555 output_info->headerSize = pCTX->encodedHeaderSize;
556 output_info->dataSize = pCTX->encodedDataSize;
557
558 if (pCTX->encode_cnt == 0) {
559 output_info->StrmPhyAddr = (void *)pCTX->phyStrmBuf;
560 output_info->StrmVirAddr = (void *)pCTX->virStrmBuf;
561 } else {
562 output_info->StrmPhyAddr = (unsigned char *)pCTX->phyStrmBuf + (MAX_ENCODER_OUTPUT_BUFFER_SIZE/2);
563 output_info->StrmVirAddr = (unsigned char *)pCTX->virStrmBuf + (MAX_ENCODER_OUTPUT_BUFFER_SIZE/2);
564 }
565
566 pCTX->encode_cnt ++;
567 pCTX->encode_cnt %= 2;
568
569 if (pCTX->encodedframeType == 0)
570 output_info->frameType = MFC_FRAME_TYPE_NOT_CODED;
571 else if (pCTX->encodedframeType == 1)
572 output_info->frameType = MFC_FRAME_TYPE_I_FRAME;
573 else if (pCTX->encodedframeType == 2)
574 output_info->frameType = MFC_FRAME_TYPE_P_FRAME;
575 else if (pCTX->encodedframeType == 3)
576 output_info->frameType = MFC_FRAME_TYPE_B_FRAME;
577 else if (pCTX->encodedframeType == 4)
578 output_info->frameType = MFC_FRAME_TYPE_OTHERS;
579 else {
580 ALOGE("Strange encoded frame type = %d\n", pCTX->encodedframeType);
581 return MFC_RET_INVALID_PARAM;
582 }
583
584 output_info->encodedYPhyAddr = (void *)pCTX->encoded_Y_paddr;
585 output_info->encodedCPhyAddr = (void *)pCTX->encoded_C_paddr;
586
587 return MFC_RET_OK;
588 }
589
SsbSipMfcEncSetOutBuf(void * openHandle,void * phyOutbuf,void * virOutbuf,int outputBufferSize)590 SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetOutBuf(void *openHandle, void *phyOutbuf, void *virOutbuf, int outputBufferSize)
591 {
592 _MFCLIB *pCTX;
593
594 if (openHandle == NULL) {
595 ALOGE("SsbSipMfcEncSetOutBuf: openHandle is NULL\n");
596 return MFC_RET_INVALID_PARAM;
597 }
598
599 pCTX = (_MFCLIB *)openHandle;
600
601 pCTX->phyStrmBuf = (int)phyOutbuf;
602 pCTX->virStrmBuf = (int)virOutbuf;
603 pCTX->sizeStrmBuf = outputBufferSize;
604
605 return MFC_RET_OK;
606 }
607
SsbSipMfcEncSetConfig(void * openHandle,SSBSIP_MFC_ENC_CONF conf_type,void * value)608 SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value)
609 {
610 int ret_code;
611 _MFCLIB *pCTX;
612 mfc_common_args EncArg;
613
614 if (openHandle == NULL) {
615 ALOGE("SsbSipMfcEncSetConfig: openHandle is NULL\n");
616 return MFC_RET_INVALID_PARAM;
617 }
618
619 if (value == NULL) {
620 ALOGE("SsbSipMfcEncSetConfig: value is NULL\n");
621 return MFC_RET_INVALID_PARAM;
622 }
623
624 pCTX = (_MFCLIB *)openHandle;
625 memset(&EncArg, 0x00, sizeof(mfc_common_args));
626
627 switch (conf_type) {
628 case MFC_ENC_SETCONF_FRAME_TYPE:
629 case MFC_ENC_SETCONF_CHANGE_FRAME_RATE:
630 case MFC_ENC_SETCONF_CHANGE_BIT_RATE:
631 case MFC_ENC_SETCONF_ALLOW_FRAME_SKIP:
632 EncArg.args.set_config.in_config_param = conf_type;
633 EncArg.args.set_config.in_config_value[0] = *((unsigned int *) value);
634 EncArg.args.set_config.in_config_value[1] = 0;
635 break;
636
637 case MFC_ENC_SETCONF_FRAME_TAG:
638 pCTX->in_frametag = *((int *)value);
639 return MFC_RET_OK;
640
641 default:
642 ALOGE("SsbSipMfcEncSetConfig: No such conf_type is supported.\n");
643 return MFC_RET_INVALID_PARAM;
644 }
645
646 ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_SET_CONFIG, &EncArg);
647 if (EncArg.ret_code != MFC_RET_OK) {
648 ALOGE("SsbSipMfcEncSetConfig: IOCTL_MFC_SET_CONFIG failed(ret : %d)\n", EncArg.ret_code);
649 return MFC_RET_ENC_SET_CONF_FAIL;
650 }
651
652 return MFC_RET_OK;
653 }
654
SsbSipMfcEncGetConfig(void * openHandle,SSBSIP_MFC_ENC_CONF conf_type,void * value)655 SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value)
656 {
657 int ret_code;
658 _MFCLIB *pCTX;
659 mfc_common_args EncArg;
660
661 pCTX = (_MFCLIB *)openHandle;
662
663 if (openHandle == NULL) {
664 ALOGE("SsbSipMfcEncGetConfig: openHandle is NULL\n");
665 return MFC_RET_INVALID_PARAM;
666 }
667 if (value == NULL) {
668 ALOGE("SsbSipMfcEncGetConfig: value is NULL\n");
669 return MFC_RET_INVALID_PARAM;
670 }
671
672 pCTX = (_MFCLIB *)openHandle;
673 memset(&EncArg, 0x00, sizeof(mfc_common_args));
674
675 switch (conf_type) {
676 case MFC_ENC_GETCONF_FRAME_TAG:
677 *((unsigned int *)value) = pCTX->out_frametag_top;
678 break;
679
680 default:
681 ALOGE("SsbSipMfcEncGetConfig: No such conf_type is supported.\n");
682 return MFC_RET_INVALID_PARAM;
683 }
684
685 return MFC_RET_OK;
686 }
687