1 /* Copyright (c) 2013, The Linux Foundation. All rights reserved.
2  *
3  * Redistribution and use in source and binary forms, with or without
4  * modification, are permitted provided that the following conditions are
5  * met:
6  *     * Redistributions of source code must retain the above copyright
7  *       notice, this list of conditions and the following disclaimer.
8  *     * Redistributions in binary form must reproduce the above
9  *       copyright notice, this list of conditions and the following
10  *       disclaimer in the documentation and/or other materials provided
11  *       with the distribution.
12  *     * Neither the name of The Linux Foundation nor the names of its
13  *       contributors may be used to endorse or promote products derived
14  *       from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 
30 #include "mm_jpeg_interface.h"
31 #include "mm_jpeg_ionbuf.h"
32 #include <sys/time.h>
33 
34 /** DUMP_TO_FILE:
35  *  @filename: file name
36  *  @p_addr: address of the buffer
37  *  @len: buffer length
38  *
39  *  dump the image to the file
40  **/
41 #define DUMP_TO_FILE(filename, p_addr, len) ({ \
42   int rc = 0; \
43   FILE *fp = fopen(filename, "w+"); \
44   if (fp) { \
45     rc = fwrite(p_addr, 1, len, fp); \
46     fclose(fp); \
47   } else { \
48     CDBG_ERROR("%s:%d] cannot dump image", __func__, __LINE__); \
49   } \
50 })
51 
52 static int g_count = 1, g_i;
53 
54 typedef struct {
55   char *filename;
56   int width;
57   int height;
58   char *out_filename;
59 } jpeg_test_input_t;
60 
61 static jpeg_test_input_t jpeg_input[] = {
62   {"/data/test.yuv", 1280, 720, "/data/test.jpg"}
63 };
64 
65 typedef struct {
66   char *filename;
67   int width;
68   int height;
69   char *out_filename;
70   pthread_mutex_t lock;
71   pthread_cond_t cond;
72   buffer_test_t input;
73   buffer_test_t output;
74   int use_ion;
75   uint32_t handle;
76   mm_jpeg_ops_t ops;
77   uint32_t job_id[5];
78   mm_jpeg_encode_params_t params;
79   mm_jpeg_job_t job;
80   uint32_t session_id;
81 } mm_jpeg_intf_test_t;
82 
mm_jpeg_encode_callback(jpeg_job_status_t status,uint32_t client_hdl,uint32_t jobId,mm_jpeg_output_t * p_output,void * userData)83 static void mm_jpeg_encode_callback(jpeg_job_status_t status,
84   uint32_t client_hdl,
85   uint32_t jobId,
86   mm_jpeg_output_t *p_output,
87   void *userData)
88 {
89   mm_jpeg_intf_test_t *p_obj = (mm_jpeg_intf_test_t *)userData;
90 
91   if (status == JPEG_JOB_STATUS_ERROR) {
92     CDBG_ERROR("%s:%d] Encode error", __func__, __LINE__);
93   } else {
94     CDBG_ERROR("%s:%d] Encode success file%s addr %p len %d",
95       __func__, __LINE__, p_obj->out_filename,
96       p_output->buf_vaddr, p_output->buf_filled_len);
97     DUMP_TO_FILE(p_obj->out_filename, p_output->buf_vaddr, p_output->buf_filled_len);
98   }
99   g_i++;
100   if (g_i >= g_count) {
101     CDBG_ERROR("%s:%d] Signal the thread", __func__, __LINE__);
102     pthread_cond_signal(&p_obj->cond);
103   }
104 }
105 
mm_jpeg_test_alloc(buffer_test_t * p_buffer,int use_pmem)106 int mm_jpeg_test_alloc(buffer_test_t *p_buffer, int use_pmem)
107 {
108   int ret = 0;
109   /*Allocate buffers*/
110   if (use_pmem) {
111     p_buffer->addr = (uint8_t *)buffer_allocate(p_buffer);
112     if (NULL == p_buffer->addr) {
113       CDBG_ERROR("%s:%d] Error",__func__, __LINE__);
114       return -1;
115     }
116   } else {
117     /* Allocate heap memory */
118     p_buffer->addr = (uint8_t *)malloc(p_buffer->size);
119     if (NULL == p_buffer->addr) {
120       CDBG_ERROR("%s:%d] Error",__func__, __LINE__);
121       return -1;
122     }
123   }
124   return ret;
125 }
126 
mm_jpeg_test_free(buffer_test_t * p_buffer)127 void mm_jpeg_test_free(buffer_test_t *p_buffer)
128 {
129   if (p_buffer->addr == NULL)
130     return;
131 
132   if (p_buffer->p_pmem_fd > 0)
133     buffer_deallocate(p_buffer);
134   else
135     free(p_buffer->addr);
136 
137   memset(p_buffer, 0x0, sizeof(buffer_test_t));
138 }
139 
mm_jpeg_test_read(mm_jpeg_intf_test_t * p_obj)140 int mm_jpeg_test_read(mm_jpeg_intf_test_t *p_obj)
141 {
142   int rc = 0;
143   FILE *fp = NULL;
144   int file_size = 0;
145   fp = fopen(p_obj->filename, "rb");
146   if (!fp) {
147     CDBG_ERROR("%s:%d] error", __func__, __LINE__);
148     return -1;
149   }
150   fseek(fp, 0, SEEK_END);
151   file_size = ftell(fp);
152   fseek(fp, 0, SEEK_SET);
153   CDBG_ERROR("%s:%d] input file size is %d buf_size %ld",
154     __func__, __LINE__, file_size, p_obj->input.size);
155 
156   if (p_obj->input.size > file_size) {
157     CDBG_ERROR("%s:%d] error", __func__, __LINE__);
158     fclose(fp);
159     return -1;
160   }
161   fread(p_obj->input.addr, 1, p_obj->input.size, fp);
162   fclose(fp);
163   return 0;
164 }
165 
encode_init(jpeg_test_input_t * p_input,mm_jpeg_intf_test_t * p_obj)166 static int encode_init(jpeg_test_input_t *p_input, mm_jpeg_intf_test_t *p_obj)
167 {
168   int rc = -1;
169   int size = p_input->width * p_input->height;
170   mm_jpeg_encode_params_t *p_params = &p_obj->params;
171   mm_jpeg_encode_job_t *p_job_params = &p_obj->job.encode_job;
172 
173   p_obj->filename = p_input->filename;
174   p_obj->width = p_input->width;
175   p_obj->height = p_input->height;
176   p_obj->out_filename = p_input->out_filename;
177   p_obj->use_ion = 1;
178 
179   pthread_mutex_init(&p_obj->lock, NULL);
180   pthread_cond_init(&p_obj->cond, NULL);
181 
182   /* allocate buffers */
183   p_obj->input.size = size * 3/2;
184   rc = mm_jpeg_test_alloc(&p_obj->input, p_obj->use_ion);
185   if (rc) {
186     CDBG_ERROR("%s:%d] Error",__func__, __LINE__);
187     return -1;
188   }
189 
190   p_obj->output.size = size * 3/2;
191   rc = mm_jpeg_test_alloc(&p_obj->output, 0);
192   if (rc) {
193     CDBG_ERROR("%s:%d] Error",__func__, __LINE__);
194     return -1;
195   }
196 
197   rc = mm_jpeg_test_read(p_obj);
198   if (rc) {
199     CDBG_ERROR("%s:%d] Error",__func__, __LINE__);
200     return -1;
201   }
202 
203   /* set encode parameters */
204   p_params->jpeg_cb = mm_jpeg_encode_callback;
205   p_params->userdata = p_obj;
206   p_params->color_format = MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2;
207 
208   /* dest buffer config */
209   p_params->dest_buf[0].buf_size = p_obj->output.size;
210   p_params->dest_buf[0].buf_vaddr = p_obj->output.addr;
211   p_params->dest_buf[0].fd = p_obj->output.p_pmem_fd;
212   p_params->dest_buf[0].index = 0;
213   p_params->num_dst_bufs = 1;
214 
215   /* src buffer config*/
216   p_params->src_main_buf[0].buf_size = p_obj->input.size;
217   p_params->src_main_buf[0].buf_vaddr = p_obj->input.addr;
218   p_params->src_main_buf[0].fd = p_obj->input.p_pmem_fd;
219   p_params->src_main_buf[0].index = 0;
220   p_params->src_main_buf[0].format = MM_JPEG_FMT_YUV;
221   p_params->src_main_buf[0].offset.mp[0].len = size;
222   p_params->src_main_buf[0].offset.mp[1].len = size >> 1;
223   p_params->num_src_bufs = 1;
224 
225   p_params->encode_thumbnail = 1;
226   p_params->exif_info.numOfEntries = 0;
227   p_params->quality = 80;
228 
229   p_job_params->dst_index = 0;
230   p_job_params->src_index = 0;
231   p_job_params->rotation = 0;
232 
233   /* main dimension */
234   p_job_params->main_dim.src_dim.width = p_obj->width;
235   p_job_params->main_dim.src_dim.height = p_obj->height;
236   p_job_params->main_dim.dst_dim.width = p_obj->width;
237   p_job_params->main_dim.dst_dim.height = p_obj->height;
238   p_job_params->main_dim.crop.top = 0;
239   p_job_params->main_dim.crop.left = 0;
240   p_job_params->main_dim.crop.width = p_obj->width;
241   p_job_params->main_dim.crop.height = p_obj->height;
242 
243   /* thumb dimension */
244   p_job_params->thumb_dim.src_dim.width = p_obj->width;
245   p_job_params->thumb_dim.src_dim.height = p_obj->height;
246   p_job_params->thumb_dim.dst_dim.width = 512;
247   p_job_params->thumb_dim.dst_dim.height = 384;
248   p_job_params->thumb_dim.crop.top = 0;
249   p_job_params->thumb_dim.crop.left = 0;
250   p_job_params->thumb_dim.crop.width = p_obj->width;
251   p_job_params->thumb_dim.crop.height = p_obj->height;
252   return 0;
253 }
254 
encode_test(jpeg_test_input_t * p_input)255 static int encode_test(jpeg_test_input_t *p_input)
256 {
257   int rc = 0;
258   mm_jpeg_intf_test_t jpeg_obj;
259   int i = 0;
260 
261   memset(&jpeg_obj, 0x0, sizeof(jpeg_obj));
262   rc = encode_init(p_input, &jpeg_obj);
263   if (rc) {
264     CDBG_ERROR("%s:%d] Error",__func__, __LINE__);
265     return -1;
266   }
267 
268   jpeg_obj.handle = jpeg_open(&jpeg_obj.ops);
269   if (jpeg_obj.handle == 0) {
270     CDBG_ERROR("%s:%d] Error",__func__, __LINE__);
271     goto end;
272   }
273 
274   rc = jpeg_obj.ops.create_session(jpeg_obj.handle, &jpeg_obj.params,
275     &jpeg_obj.job.encode_job.session_id);
276   if (jpeg_obj.job.encode_job.session_id == 0) {
277     CDBG_ERROR("%s:%d] Error",__func__, __LINE__);
278     goto end;
279   }
280 
281   for (i = 0; i < g_count; i++) {
282     jpeg_obj.job.job_type = JPEG_JOB_TYPE_ENCODE;
283     rc = jpeg_obj.ops.start_job(&jpeg_obj.job, &jpeg_obj.job_id[i]);
284     if (rc) {
285       CDBG_ERROR("%s:%d] Error",__func__, __LINE__);
286       goto end;
287     }
288   }
289 
290   /*
291   usleep(5);
292   jpeg_obj.ops.abort_job(jpeg_obj.job_id[0]);
293   */
294   pthread_mutex_lock(&jpeg_obj.lock);
295   pthread_cond_wait(&jpeg_obj.cond, &jpeg_obj.lock);
296   pthread_mutex_unlock(&jpeg_obj.lock);
297 
298   jpeg_obj.ops.destroy_session(jpeg_obj.job.encode_job.session_id);
299 
300   jpeg_obj.ops.close(jpeg_obj.handle);
301 
302 
303 end:
304   mm_jpeg_test_free(&jpeg_obj.input);
305   mm_jpeg_test_free(&jpeg_obj.output);
306   return 0;
307 }
308 
309 /** main:
310  *
311  *  Arguments:
312  *    @argc
313  *    @argv
314  *
315  *  Return:
316  *       0 or -ve values
317  *
318  *  Description:
319  *       main function
320  *
321  **/
main(int argc,char * argv[])322 int main(int argc, char* argv[])
323 {
324   return encode_test(&jpeg_input[0]);
325 }
326 
327 
328