• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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