implemented decoding audio part, but needs to improve.
[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 "gstemuldev.h"
34
35 gboolean
36 emul_avcodec_init (CodecContext *ctx, CodecElement *codec, CodecDevice *dev)
37 {
38   int fd;
39   void *mmapbuf;
40   int size = 0;
41   gboolean ret = TRUE;
42   CodecIOParams params;
43
44   printf ("enter: %s\n", __func__);
45
46   fd = dev->fd;
47   if (fd < 0) {
48     GST_ERROR ("failed to get %s fd.\n", CODEC_DEV);
49     return FALSE;
50   }
51
52   mmapbuf = dev->buf;
53   if (!mmapbuf) {
54     GST_ERROR ("failed to get mmaped memory address.\n");
55     return FALSE;
56   }
57
58 //  printf("codec_init media_type: %d, codec_type: %d, name: %s\n",
59 //    media_type, codec_type, name);
60
61   /* copy basic info to initialize codec on the host side.
62    * e.g. width, height, FPS ant etc. */
63   memcpy ((uint8_t *)mmapbuf, &codec->media_type, sizeof(codec->media_type));
64   size = sizeof(codec->media_type);
65   memcpy ((uint8_t *)mmapbuf + size, &codec->codec_type, sizeof(codec->codec_type));
66   size += sizeof(codec->codec_type);
67   memcpy ((uint8_t *)mmapbuf + size, codec->name, sizeof(codec->name));
68   size += sizeof(codec->name);
69
70   switch (codec->media_type) {
71   case AVMEDIA_TYPE_VIDEO:
72     memcpy ((uint8_t *)mmapbuf + size, &ctx->video, sizeof(ctx->video));
73     size += sizeof(ctx->video);
74     break;
75   case AVMEDIA_TYPE_AUDIO:
76     memcpy ((uint8_t *)mmapbuf + size, &ctx->audio, sizeof(ctx->audio));
77     size += sizeof(ctx->audio);
78     break;
79   default:
80     GST_ERROR ("media type is unknown.\n");
81     ret = FALSE;
82     break;
83   }
84
85   memcpy ((uint8_t *)mmapbuf + size, &ctx->codecdata_size, sizeof(ctx->codecdata_size));
86   size += sizeof(ctx->codecdata_size);
87   if (ctx->codecdata_size) {
88     memcpy ((uint8_t *)mmapbuf + size, ctx->codecdata, ctx->codecdata_size);
89   }
90
91   CODEC_PARAM_INIT (params);
92   params.api_index = CODEC_INIT;
93   params.ctx_index = 0;
94   CODEC_WRITE_TO_QEMU (fd, &params, 1);
95
96   if (codec->media_type == AVMEDIA_TYPE_AUDIO) {
97     memcpy (&ctx->audio.sample_fmt,
98                   (uint8_t *)mmapbuf, sizeof(ctx->audio.sample_fmt));
99   }
100   ctx->codec = codec;
101
102   printf ("leave: %s\n", __func__);
103
104   return ret;
105 }
106
107 void
108 emul_avcodec_deinit (CodecContext *ctx, CodecDevice *dev)
109 {
110   int fd;
111   void *mmapbuf;
112   CodecIOParams params;
113
114   printf ("enter: %s\n", __func__);
115
116   fd = dev->fd;
117   if (fd < 0) {
118     GST_ERROR ("failed to get %s fd.\n", CODEC_DEV);
119     return;
120   }
121
122   mmapbuf = dev->buf;
123   if (!mmapbuf) {
124     GST_ERROR ("failed to get mmaped memory address.\n");
125     return;
126   }
127
128   CODEC_PARAM_INIT (params);
129   params.api_index = CODEC_DEINIT;
130   params.ctx_index = 0;
131   CODEC_WRITE_TO_QEMU (fd, &params, 1);
132
133 #if 0
134   /* close device fd and release mapped memory region */
135   gst_emul_codec_device_close (dev);
136 #endif
137
138   printf ("leave: %s\n", __func__);
139 }
140
141 int
142 emul_avcodec_decode_video (CodecContext *ctx, guint8 *in_buf, guint in_size,
143         GstBuffer **out_buf, int *got_picture_ptr, CodecDevice *dev)
144 {
145   int fd;
146   void *mmapbuf;
147   int len = 0, size = 0;
148   guint out_size;
149   CodecIOParams params;
150
151   *out_buf = NULL;
152
153   printf ("enter: %s\n", __func__);
154
155   fd = dev->fd;
156   if (fd < 0) {
157     GST_ERROR ("failed to get %s fd\n", CODEC_DEV);
158     return -1;
159   }
160
161   mmapbuf = dev->buf;
162   if (!mmapbuf) {
163     GST_ERROR ("failed to get mmaped memory address\n");
164     return -1;
165   }
166
167   memcpy ((uint8_t *)mmapbuf, &in_size, sizeof(guint));
168   size = sizeof(guint);
169 //  memcpy ((uint8_t *)mmapbuf + size, &dec_info->timestamp, sizeof(GstClockTime));
170 //  size += sizeof(GstClockTime);
171   memcpy ((uint8_t *)mmapbuf + size, in_buf, in_size);
172
173   /* provide raw image for decoding to qemu */
174   CODEC_PARAM_INIT (params);
175   params.api_index = CODEC_DECODE_VIDEO;
176   params.ctx_index = 0;
177   CODEC_WRITE_TO_QEMU (fd, &params, 1);
178
179   memcpy (&len, (uint8_t *)mmapbuf, sizeof(len));
180   size = sizeof(len);
181
182
183   printf ("leave: %s\n", __func__);
184
185   return len;
186 }
187
188 int
189 emul_avcodec_decode_audio (CodecContext *ctx, int16_t *samples,
190                 gint *frame_size_ptr, guint8 *in_buf, guint in_size, CodecDevice *dev)
191 {
192   int fd;
193   void *mmapbuf = NULL;
194   int size = 0;
195   gint out_size = 0, len;
196   CodecIOParams params;
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 = dev->buf;
205   if (!mmapbuf) {
206     GST_ERROR("failed to get mmaped memory address\n");
207     return -1;
208   }
209
210   memcpy ((uint8_t *)mmapbuf, &in_size, sizeof(guint));
211   size = sizeof(guint);
212   if (in_size > 0) {
213     memcpy ((uint8_t *)mmapbuf + size, in_buf, in_size);
214   }
215
216   CODEC_PARAM_INIT (params);
217   params.api_index = CODEC_DECODE_AUDIO;
218   params.ctx_index = 0;
219   params.device_mem_offset = 0;
220   CODEC_WRITE_TO_QEMU (fd, &params, 1);
221
222   memcpy (&ctx->audio.channel_layout,
223                   (uint8_t *)mmapbuf, sizeof(ctx->audio.channel_layout));
224   size = sizeof(ctx->audio.channel_layout);
225   memcpy (&len, (uint8_t *)mmapbuf + size, sizeof(len));
226   size += sizeof(len);
227   memcpy (frame_size_ptr, (uint8_t *)mmapbuf + size, sizeof(*frame_size_ptr));
228   size += sizeof(*frame_size_ptr);
229   if (len > 0) {
230     memcpy (samples, (uint8_t *)mmapbuf + size, FF_MAX_AUDIO_FRAME_SIZE);
231   }
232
233   return len;
234 }
235
236 int
237 emul_avcodec_encode_video (CodecContext *ctx, guint8 *in_buf, guint in_size,
238         GstBuffer **out_buf, CodecDevice *dev)
239 {
240   int fd;
241   void *mmapbuf;
242   int len = 0, outbuf_size, size = 0;
243   CodecIOParams params;
244
245   printf ("enter: %s\n", __func__);
246
247   fd = dev->fd;
248   if (fd < 0) {
249     GST_ERROR ("failed to get %s fd.\n", CODEC_DEV);
250     return FALSE;
251   }
252
253   mmapbuf = dev->buf;
254   if (!mmapbuf) {
255     GST_ERROR ("failed to get mmaped memory address.\n");
256     return FALSE;
257   }
258
259   memcpy ((uint8_t *)mmapbuf + size, &in_size, sizeof(guint));
260   size += sizeof(guint);
261 #if 0
262   memcpy ((uint8_t *)mmapbuf + size, &in_timestamp, sizeof(GstClockTime));
263   size += sizeof(GstClockTime);
264 #endif
265   memcpy ((uint8_t *)mmapbuf + size, in_buf, in_size);
266
267   CODEC_PARAM_INIT (params);
268   params.api_index = CODEC_DECODE_AUDIO;
269   params.ctx_index = 0;
270   CODEC_WRITE_TO_QEMU (fd, &params, 1);
271
272 #if 0
273   size = 0;
274   memcpy (&out_size, (uint8_t *)mmapbuf + size, sizeof(uint));
275   size += sizeof(guint);
276
277   ret = gst_pad_alloc_buffer_and_set_caps (emulenc->srcpad,
278           GST_BUFFER_OFFSET_NONE, out_size,
279           GST_PAD_CAPS (emulenc->srcpad), out_buf);
280
281   gst_buffer_set_caps (*out_buf, GST_PAD_CAPS (emulenc->srcpad));
282
283   if (GST_BUFFER_DATA(*out_buf)) {
284       memcpy (GST_BUFFER_DATA(*out_buf), (uint8_t *)mmapbuf + size, out_size);
285   } else {
286       pritnf ("failed to allocate output buffer\n");
287   }
288 #endif
289
290   printf ("leave: %s\n", __func__);
291
292   return len;
293 }
294
295 int
296 emul_avcodec_encode_audio (CodecContext *ctx, CodecDevice *dev)
297 {
298   int fd;
299   void *mmapbuf;
300   int len = 0, size = 0;
301   CodecIOParams params;
302
303   printf ("enter: %s\n", __func__);
304
305   fd = dev->fd;
306   if (fd < 0) {
307     GST_ERROR ("failed to get %s fd.\n", CODEC_DEV);
308     return FALSE;
309   }
310
311   mmapbuf = dev->buf;
312   if (!mmapbuf) {
313     GST_ERROR ("failed to get mmaped memory address.\n");
314     return FALSE;
315   }
316
317 #if 0
318   memcpy ((uint8_t *)mmapbuf + size, &in_size, sizeof(guint));
319   size += sizeof(guint);
320   memcpy ((uint8_t *)mmapbuf + size, &in_timestamp, sizeof(GstClockTime));
321   size += sizeof(GstClockTime);
322   memcpy ((uint8_t *)mmapbuf + size, in_buf, in_size);
323 #endif
324
325   CODEC_PARAM_INIT (params);
326   params.api_index = CODEC_DECODE_AUDIO;
327   params.ctx_index = 0;
328   CODEC_WRITE_TO_QEMU (fd, &params, 1);
329
330 #if 0
331   size = 0;
332   memcpy (&out_size, (uint8_t *)mmapbuf + size, sizeof(uint));
333   size += sizeof(guint);
334
335   *out_buf = gst_buffer_new();
336   GST_BUFFER_DATA (out_buf) = GST_BUFFER_MALLOCDATA (out_buf) = av_malloc (out_size);
337   GST_BUFFER_SIZE (out_buf) = out_size;
338   //  GST_BUFFER_FREE_FUNC (out_buf) = g_free;
339   if (GST_PAD_CAPS(emulenc->srcpad)) {
340       gst_buffer_set_caps (*out_buf, GST_PAD_CAPS (emulenc->srcpad));
341   }
342
343   if (GST_BUFFER_DATA(*out_buf)) {
344       memcpy (GST_BUFFER_DATA(*out_buf), (uint8_t *)mmapbuf + size, out_size);
345   } else {
346       pritnf ("failed to allocate output buffer\n");
347   }
348 #endif
349
350   printf ("leave: %s\n", __func__);
351
352   return len;
353 }