Changed a way to use device memory.
[platform/adaptation/emulator/gst-plugins-emulator.git] / src / gstemulapi.c
1 /*
2  * GStreamer codec plugin for Tizen Emulator.
3  *
4  * Copyright (C) 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:
7  * KiTae Kim <kt920.kim@samsung.com>
8  * SeokYeon Hwang <syeon.hwang@samsung.com>
9  * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Library General Public
13  * License as published by the Free Software Foundation; either
14  * version 2 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Library General Public License for more details.
20  *
21  * You should have received a copy of the GNU Library General Public
22  * License along with this library; if not, write to the
23  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24  * Boston, MA 02111-1307, USA.
25  *
26  * Contributors:
27  * - S-Core Co., Ltd
28  *
29  */
30
31 #include "gstemulcommon.h"
32 #include "gstemulapi.h"
33 #include "gstemulapi2.h"
34 #include "gstemuldev.h"
35
36 void emul_codec_write_to_qemu (int ctx_index, int api_index, CodecDevice *dev)
37 {
38   CodecIOParams ioparam;
39
40 //  memset(&ioparam, 0, sizeof(ioparam));
41   ioparam.api_index = api_index;
42   ioparam.ctx_index = ctx_index;
43   ioparam.mem_offset = dev->mem_info.offset;
44   if (write (dev->fd, &ioparam, 1) < 0) {
45     printf ("[%s:%d] failed to copy data.\n", __func__, __LINE__);
46   }
47   CODEC_LOG (DEBUG, "[%s] mem_offset = 0x%x\n", __func__, ioparam.mem_offset);
48 }
49
50 extern int device_fd;
51 extern gpointer device_mem;
52
53 struct mem_info {
54     gpointer start;
55     uint32_t offset;
56 };
57
58 static struct mem_info secure_device_mem()
59 {
60   uint32_t mem_offset = 0;
61   struct mem_info info;
62
63   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
64
65   ioctl(device_fd, CODEC_CMD_SECURE_MEMORY, &mem_offset);
66   info.start = (gpointer)((uint32_t)device_mem + mem_offset);
67   info.offset = mem_offset;
68
69   CODEC_LOG (DEBUG, "leave: %s\n", __func__);
70   CODEC_LOG (DEBUG, "caramis0 = 0x%x\n", mem_offset);
71
72   return info;
73 }
74
75 static void release_device_mem(gpointer start)
76 {
77   uint32_t offset = start - device_mem;
78   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
79
80   ioctl(device_fd, CODEC_CMD_RELEASE_MEMORY, &offset);
81
82   CODEC_LOG (DEBUG, "leave: %s\n", __func__);
83 }
84
85 static void emul_buffer_free(gpointer start)
86 {
87   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
88
89   release_device_mem(start);
90
91   CODEC_LOG (DEBUG, "leave: %s\n", __func__);
92 }
93
94 GstFlowReturn emul_buffer_alloc(GstPad *pad, guint64 offset, guint size, GstCaps *caps, GstBuffer **buf)
95 {
96   struct mem_info info;
97
98   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
99
100   *buf = gst_buffer_new ();
101
102   info = secure_device_mem();
103
104   CODEC_LOG (DEBUG, "[%s] start: 0x%x, offset 0x%x\n", __func__, info.start, info.offset);
105
106   GST_BUFFER_DATA (*buf) = GST_BUFFER_MALLOCDATA (*buf) = info.start;
107   GST_BUFFER_SIZE (*buf) = size;
108   GST_BUFFER_FREE_FUNC (*buf) = emul_buffer_free;
109
110   GST_BUFFER_OFFSET (*buf) = offset;
111
112   if (caps) {
113     gst_buffer_set_caps (*buf, caps);
114   }
115
116   CODEC_LOG (DEBUG, "leave: %s\n", __func__);
117   return GST_FLOW_OK;
118 }
119
120 int
121 emul_avcodec_init (CodecContext *ctx, CodecElement *codec, CodecDevice *dev)
122 {
123   int fd;
124   uint8_t *mmapbuf;
125   int ret = 0;
126   uint32_t mem_offset = 0;
127
128   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
129
130   fd = dev->fd;
131   if (fd < 0) {
132     GST_ERROR ("failed to get %s fd.\n", CODEC_DEV);
133     return -1;
134   }
135
136   mmapbuf = (uint8_t *)dev->buf;
137   if (!mmapbuf) {
138     GST_ERROR ("failed to get mmaped memory address.\n");
139     return -1;
140   }
141
142   ioctl(fd, CODEC_CMD_GET_CONTEXT_INDEX, &ctx->index);
143   CODEC_LOG (DEBUG, "recv context index: %d\n", ctx->index);
144
145   ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &mem_offset);
146   emul_avcodec_init_to (ctx, codec, mmapbuf + mem_offset);
147   dev->mem_info.offset = mem_offset;
148   emul_codec_write_to_qemu (ctx->index, CODEC_INIT, dev);
149
150
151   ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &mem_offset);
152   ret = emul_avcodec_init_from (ctx, codec, mmapbuf + mem_offset);
153
154   ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &mem_offset);
155
156   CODEC_LOG (DEBUG, "leave: %s, ret: %d\n", __func__, ret);
157   return ret;
158 }
159
160 void
161 emul_avcodec_deinit (CodecContext *ctx, CodecDevice *dev)
162 {
163   int fd;
164   void *mmapbuf = NULL;
165
166   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
167
168   fd = dev->fd;
169   if (fd < 0) {
170     GST_ERROR ("failed to get %s fd.\n", CODEC_DEV);
171     return;
172   }
173
174   mmapbuf = dev->buf;
175   if (!mmapbuf) {
176     GST_ERROR ("failed to get mmaped memory address.\n");
177     return;
178   }
179
180   emul_codec_write_to_qemu (ctx->index, CODEC_DEINIT, dev);
181
182   CODEC_LOG (DEBUG, "leave: %s\n", __func__);
183 }
184
185 int
186 emul_avcodec_decode_video (CodecContext *ctx, uint8_t *in_buf, int in_size,
187                           gint idx, gint64 in_offset, GstBuffer **out_buf,
188                           int *got_picture_ptr, CodecDevice *dev)
189 {
190   int fd;
191   uint8_t *mmapbuf = NULL;
192   int len = 0;
193 //  int copyback, usable;
194   uint32_t mem_offset = 0;
195
196   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
197
198   fd = dev->fd;
199   if (fd < 0) {
200     GST_ERROR ("failed to get %s fd\n", CODEC_DEV);
201     return -1;
202   }
203
204   mmapbuf = (uint8_t *)dev->buf;
205   if (!mmapbuf) {
206     GST_ERROR ("failed to get mmaped memory address\n");
207     return -1;
208   }
209
210   ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &mem_offset);
211   CODEC_LOG (DEBUG, "[%s] mem_offset = 0x%x\n", __func__, mem_offset);
212   emul_avcodec_decode_video_to (in_buf, in_size, idx, in_offset, mmapbuf + mem_offset);
213
214   dev->mem_info.offset = mem_offset;
215   emul_codec_write_to_qemu (ctx->index, CODEC_DECODE_VIDEO, dev);
216
217   ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &mem_offset);
218   CODEC_LOG (DEBUG, "[%s] mem_offset = 0x%x\n", __func__, mem_offset);
219   len = emul_avcodec_decode_video_from (ctx, got_picture_ptr, mmapbuf + mem_offset);
220
221   ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &mem_offset);
222
223   CODEC_LOG (DEBUG, "leave: %s\n", __func__);
224   return len;
225 }
226
227 void
228 emul_av_picture_copy (CodecContext *ctx, uint8_t *pict,
229                       uint32_t pict_size, CodecDevice *dev)
230 {
231   int fd;
232   void *mmapbuf = NULL;
233 //  int copyback, usable;
234   uint32_t mem_offset = 0;
235
236   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
237
238   fd = dev->fd;
239   if (fd < 0) {
240     GST_ERROR ("failed to get %s fd\n", CODEC_DEV);
241     return;
242   }
243
244   mmapbuf = dev->buf;
245   if (!mmapbuf) {
246     GST_ERROR ("failed to get mmaped memory address\n");
247     return;
248   }
249
250 #if 0
251   ioctl (fd, CODEC_CMD_ADD_TASK_QUEUE, NULL);
252
253   while (1) {
254     ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &usable);
255     if (usable) {
256       CODEC_LOG (DEBUG, "[copy_frame] waiting before write.\n");
257       usleep (500);
258       continue;
259     }
260     break;
261   }
262
263   emul_codec_write_to_qemu (ctx->index, CODEC_PICTURE_COPY, dev);
264
265   while (1) {
266     ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &usable);
267     if (usable) {
268       CODEC_LOG (DEBUG, "[copy_frame] waiting after write.\n");
269       usleep (500);
270       continue;
271     }
272     memcpy (pict, mmapbuf, pict_size);
273     break;
274   }
275   ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &copyback);
276 #endif
277
278   dev->mem_info.offset = (uint32_t)pict - (uint32_t)device_mem;
279   CODEC_LOG (DEBUG, "[%s] mem_offset = 0x%x\n", __func__, dev->mem_info.offset);
280   emul_codec_write_to_qemu (ctx->index, CODEC_PICTURE_COPY, dev);
281 //  ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &mem_offset);
282   ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM2, &(dev->mem_info.offset));
283
284   CODEC_LOG (DEBUG, "caramis1 = 0x%x\n", __func__, mem_offset);
285 #if 0
286   memcpy (pict, mmapbuf, pict_size);
287
288   ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &mem_offset);
289 #endif
290
291   CODEC_LOG (DEBUG, "leave: %s\n", __func__);
292 }
293
294 int
295 emul_avcodec_decode_audio (CodecContext *ctx, int16_t *samples,
296                           int *frame_size_ptr, uint8_t *in_buf,
297                           int in_size, CodecDevice *dev)
298 {
299   int fd;
300   uint8_t *mmapbuf = NULL;
301   int len;
302 //  int copyback, usable;
303   uint32_t mem_offset = 0;
304
305   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
306
307   fd = dev->fd;
308   if (fd < 0) {
309     GST_ERROR("failed to get %s fd\n", CODEC_DEV);
310     return -1;
311   }
312
313   mmapbuf = (uint8_t *)dev->buf;
314   if (!mmapbuf) {
315     GST_ERROR("failed to get mmaped memory address\n");
316     return -1;
317   }
318
319 #if 0
320   ioctl (fd, CODEC_CMD_ADD_TASK_QUEUE, NULL);
321
322   while (1) {
323     ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &usable);
324     if (usable) {
325       CODEC_LOG (DEBUG, "[decode_audio] waiting before write.\n");
326       usleep (500);
327       continue;
328     }
329
330     emul_avcodec_decode_audio_to (in_buf, in_size, mmapbuf);
331     break;
332   }
333
334   emul_codec_write_to_qemu (ctx->index, CODEC_DECODE_AUDIO, dev);
335
336   while (1) {
337     ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &usable);
338     if (usable) {
339       CODEC_LOG (DEBUG, "[decode_audio] waiting after write.\n");
340       usleep (500);
341       continue;
342     }
343
344     len =
345       emul_avcodec_decode_audio_from (ctx, frame_size_ptr, samples, mmapbuf);
346     break;
347   }
348   ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &copyback);
349 #endif
350
351   ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &mem_offset);
352   emul_avcodec_decode_audio_to (in_buf, in_size, mmapbuf + mem_offset);
353
354   dev->mem_info.offset = mem_offset;
355   emul_codec_write_to_qemu (ctx->index, CODEC_DECODE_AUDIO, dev);
356
357   ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &mem_offset);
358   len =
359     emul_avcodec_decode_audio_from (ctx, frame_size_ptr, samples, mmapbuf + mem_offset);
360
361   ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &mem_offset);
362
363   CODEC_LOG (DEBUG, "leave: %s\n", __func__);
364
365   return len;
366 }
367
368 int
369 emul_avcodec_encode_video (CodecContext *ctx, uint8_t *out_buf,
370                         int out_size, uint8_t *in_buf,
371                         int in_size, int64_t in_timestamp, CodecDevice *dev)
372 {
373   int fd;
374   void *mmapbuf;
375   int len = 0;
376   int copyback, usable;
377
378   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
379
380   fd = dev->fd;
381   if (fd < 0) {
382     GST_ERROR ("failed to get %s fd.\n", CODEC_DEV);
383     return -1;
384   }
385
386   mmapbuf = dev->buf;
387   if (!mmapbuf) {
388     GST_ERROR ("failed to get mmaped memory address.\n");
389     return -1;
390   }
391
392 //  ioctl (fd, CODEC_CMD_ADD_TASK_QUEUE, NULL);
393 #if 0
394   while (1) {
395     ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &usable);
396     if (usable) {
397       CODEC_LOG (DEBUG, "[encode_video] waiting before write.\n");
398       usleep (500);
399       continue;
400     }
401
402     emul_avcodec_encode_video_to (in_buf, in_size, in_timestamp, mmapbuf);
403     break;
404   }
405
406   emul_codec_write_to_qemu (ctx->index, CODEC_ENCODE_VIDEO, dev);
407
408   while (1) {
409     ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &usable);
410     if (usable) {
411       CODEC_LOG (DEBUG, "[encode_video] waiting after write.\n");
412       usleep (500);
413       continue;
414     }
415
416     len = emul_avcodec_encode_video_from (out_buf, out_size, mmapbuf);
417     break;
418   }
419   ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &copyback);
420 #endif
421
422   CODEC_LOG (DEBUG, "leave: %s\n", __func__);
423   return len;
424 }
425
426 int
427 emul_avcodec_encode_audio (CodecContext *ctx, uint8_t *out_buf,
428                           int out_size, uint8_t *in_buf,
429                           int in_size, CodecDevice *dev)
430 {
431   int fd;
432   void *mmapbuf;
433   int len = 0;
434   int copyback, usable;
435
436   CODEC_LOG (DEBUG, "enter: %s\n", __func__);
437
438   fd = dev->fd;
439   if (fd < 0) {
440     GST_ERROR ("failed to get %s fd.\n", CODEC_DEV);
441     return -1;
442   }
443
444   mmapbuf = dev->buf;
445   if (!mmapbuf) {
446     GST_ERROR ("failed to get mmaped memory address.\n");
447     return -1;
448   }
449
450 //  ioctl (fd, CODEC_CMD_ADD_TASK_QUEUE, NULL);
451 #if 0
452   while (1) {
453     ioctl (fd, CODEC_CMD_COPY_TO_DEVICE_MEM, &usable);
454     if (usable) {
455       CODEC_LOG (DEBUG, "[encode_audio] waiting before write.\n");
456       usleep (500);
457       continue;
458     }
459
460     emul_avcodec_encode_audio_to (out_size, in_size, in_buf, mmapbuf);
461     break;
462   }
463
464   emul_codec_write_to_qemu (ctx->index, CODEC_ENCODE_AUDIO, dev);
465
466   while (1) {
467     ioctl (fd, CODEC_CMD_COPY_FROM_DEVICE_MEM, &usable);
468     if (usable) {
469       CODEC_LOG (DEBUG, "[encode_audio] waiting after write.\n");
470       usleep (500);
471       continue;
472     }
473     len = emul_avcodec_encode_audio_from (out_buf, out_size, mmapbuf);
474     break;
475   }
476   ioctl (fd, CODEC_CMD_REMOVE_TASK_QUEUE, &copyback);
477 #endif
478
479   CODEC_LOG (DEBUG, "leave: %s\n", __func__);
480   return len;
481 }