1
2 /*--------------------------------------------------------------------------
3 Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 * Neither the name of The Linux Foundation nor
13 the names of its contributors may be used to endorse or promote
14 products derived from this software without specific prior written
15 permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 --------------------------------------------------------------------------*/
29
30
31 /*
32 An Open max test application ....
33 */
34
35 #include <stdio.h>
36 #include <string.h>
37 #include <stdlib.h>
38 #include <unistd.h>
39 #include <fcntl.h>
40 #include <sys/types.h>
41 #include <sys/mman.h>
42 #include <time.h>
43 #include <sys/ioctl.h>
44 #include "OMX_Core.h"
45 #include "OMX_Component.h"
46 #include "pthread.h"
47 #include <signal.h>
48
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <fcntl.h>
52 #include <stdint.h>
53 #include <sys/mman.h>
54 #include <sys/ioctl.h>
55 #include<unistd.h>
56 #include<string.h>
57 #include <pthread.h>
58 #include "QOMX_AudioExtensions.h"
59 #include "QOMX_AudioIndexExtensions.h"
60 #ifdef AUDIOV2
61 #include "control.h"
62 #endif
63
64
65 #include <linux/ioctl.h>
66
67 typedef unsigned char uint8;
68 typedef unsigned char byte;
69 typedef unsigned int uint32;
70 typedef unsigned int uint16;
71 QOMX_AUDIO_STREAM_INFO_DATA streaminfoparam;
72 /* maximum ADTS frame header length */
73 void Release_Encoder();
74
75 #ifdef AUDIOV2
76 unsigned short session_id;
77 int device_id;
78 int control = 0;
79 const char *device="handset_tx";
80 #define DIR_TX 2
81 #endif
82
83 uint32_t samplerate = 8000;
84 uint32_t channels = 1;
85 uint32_t min_bitrate = 0;
86 uint32_t max_bitrate = 0;
87 uint32_t cdmarate = 0;
88 uint32_t rectime = 0;
89 uint32_t recpath = 0;
90 uint32_t pcmplayback = 0;
91 uint32_t tunnel = 0;
92 uint32_t format = 1;
93 #define DEBUG_PRINT printf
94 unsigned to_idle_transition = 0;
95 unsigned long total_pcm_bytes;
96
97 /************************************************************************/
98 /* GLOBAL INIT */
99 /************************************************************************/
100
101 /************************************************************************/
102 /* #DEFINES */
103 /************************************************************************/
104 #define false 0
105 #define true 1
106
107 #define CONFIG_VERSION_SIZE(param) \
108 param.nVersion.nVersion = CURRENT_OMX_SPEC_VERSION;\
109 param.nSize = sizeof(param);
110
111 #define QCP_HEADER_SIZE sizeof(struct qcp_header)
112 #define MIN_BITRATE 4 /* Bit rate 1 - 13.6 , 2 - 6.2 , 3 - 2.7 , 4 - 1.0 kbps*/
113 #define MAX_BITRATE 4
114
115 #define FAILED(result) (result != OMX_ErrorNone)
116
117 #define SUCCEEDED(result) (result == OMX_ErrorNone)
118
119 /************************************************************************/
120 /* GLOBAL DECLARATIONS */
121 /************************************************************************/
122
123 pthread_mutex_t lock;
124 pthread_cond_t cond;
125 pthread_mutex_t elock;
126 pthread_cond_t econd;
127 pthread_cond_t fcond;
128 pthread_mutex_t etb_lock;
129 pthread_mutex_t etb_lock1;
130 pthread_cond_t etb_cond;
131 FILE * inputBufferFile;
132 FILE * outputBufferFile;
133 OMX_PARAM_PORTDEFINITIONTYPE inputportFmt;
134 OMX_PARAM_PORTDEFINITIONTYPE outputportFmt;
135 OMX_AUDIO_PARAM_QCELP13TYPE qcelp13param;
136 OMX_AUDIO_PARAM_PCMMODETYPE pcmparam;
137 OMX_PORT_PARAM_TYPE portParam;
138 OMX_PORT_PARAM_TYPE portFmt;
139 OMX_ERRORTYPE error;
140
141
142
143
144 #define ID_RIFF 0x46464952
145 #define ID_WAVE 0x45564157
146 #define ID_FMT 0x20746d66
147 #define ID_DATA 0x61746164
148
149 #define FORMAT_PCM 1
150
151 struct wav_header {
152 uint32_t riff_id;
153 uint32_t riff_sz;
154 uint32_t riff_fmt;
155 uint32_t fmt_id;
156 uint32_t fmt_sz;
157 uint16_t audio_format;
158 uint16_t num_channels;
159 uint32_t sample_rate;
160 uint32_t byte_rate; /* sample_rate * num_channels * bps / 8 */
161 uint16_t block_align; /* num_channels * bps / 8 */
162 uint16_t bits_per_sample;
163 uint32_t data_id;
164 uint32_t data_sz;
165 };
166 struct enc_meta_out{
167 unsigned int offset_to_frame;
168 unsigned int frame_size;
169 unsigned int encoded_pcm_samples;
170 unsigned int msw_ts;
171 unsigned int lsw_ts;
172 unsigned int nflags;
173 } __attribute__ ((packed));
174
175 struct qcp_header {
176 /* RIFF Section */
177 char riff[4];
178 unsigned int s_riff;
179 char qlcm[4];
180
181 /* Format chunk */
182 char fmt[4];
183 unsigned int s_fmt;
184 char mjr;
185 char mnr;
186 unsigned int data1; /* UNIQUE ID of the codec */
187 unsigned short data2;
188 unsigned short data3;
189 char data4[8];
190 unsigned short ver; /* Codec Info */
191 char name[80];
192 unsigned short abps; /* average bits per sec of the codec */
193 unsigned short bytes_per_pkt;
194 unsigned short samp_per_block;
195 unsigned short samp_per_sec;
196 unsigned short bits_per_samp;
197 unsigned char vr_num_of_rates; /* Rate Header fmt info */
198 unsigned char rvd1[3];
199 unsigned short vr_bytes_per_pkt[8];
200 unsigned int rvd2[5];
201
202 /* Vrat chunk */
203 unsigned char vrat[4];
204 unsigned int s_vrat;
205 unsigned int v_rate;
206 unsigned int size_in_pkts;
207
208 /* Data chunk */
209 unsigned char data[4];
210 unsigned int s_data;
211 } __attribute__ ((packed));
212
213 /* Common part */
214 static struct qcp_header append_header = {
215 {'R', 'I', 'F', 'F'}, 0, {'Q', 'L', 'C', 'M'},
216 {'f', 'm', 't', ' '}, 150, 1, 0, 0, 0, 0,{0}, 0, {0},0,0,160,8000,16,0,{0},{0},{0},
217 {'v','r','a','t'},0, 0, 0,{'d','a','t','a'},0
218 };
219
220 static int totaldatalen = 0;
221 static int framecnt = 0;
222 /************************************************************************/
223 /* GLOBAL INIT */
224 /************************************************************************/
225
226 unsigned int input_buf_cnt = 0;
227 unsigned int output_buf_cnt = 0;
228 int used_ip_buf_cnt = 0;
229 volatile int event_is_done = 0;
230 volatile int ebd_event_is_done = 0;
231 volatile int fbd_event_is_done = 0;
232 volatile int etb_event_is_done = 0;
233 int ebd_cnt;
234 int bInputEosReached = 0;
235 int bOutputEosReached = 0;
236 int bInputEosReached_tunnel = 0;
237 static int etb_done = 0;
238 int bFlushing = false;
239 int bPause = false;
240 const char *in_filename;
241 const char *out_filename;
242
243 int timeStampLfile = 0;
244 int timestampInterval = 100;
245
246 //* OMX Spec Version supported by the wrappers. Version = 1.1 */
247 const OMX_U32 CURRENT_OMX_SPEC_VERSION = 0x00000101;
248 OMX_COMPONENTTYPE* qcelp13_enc_handle = 0;
249
250 OMX_BUFFERHEADERTYPE **pInputBufHdrs = NULL;
251 OMX_BUFFERHEADERTYPE **pOutputBufHdrs = NULL;
252
253 /************************************************************************/
254 /* GLOBAL FUNC DECL */
255 /************************************************************************/
256 int Init_Encoder(char*);
257 int Play_Encoder();
258 OMX_STRING aud_comp;
259 /**************************************************************************/
260 /* STATIC DECLARATIONS */
261 /**************************************************************************/
262
263 static int open_audio_file ();
264 static int Read_Buffer(OMX_BUFFERHEADERTYPE *pBufHdr );
265 static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *qcelp13_enc_handle,
266 OMX_BUFFERHEADERTYPE ***pBufHdrs,
267 OMX_U32 nPortIndex,
268 unsigned int bufCntMin, unsigned int bufSize);
269
270
271 static OMX_ERRORTYPE EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
272 OMX_IN OMX_PTR pAppData,
273 OMX_IN OMX_EVENTTYPE eEvent,
274 OMX_IN OMX_U32 nData1, OMX_IN OMX_U32 nData2,
275 OMX_IN OMX_PTR pEventData);
276 static OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
277 OMX_IN OMX_PTR pAppData,
278 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
279
280 static OMX_ERRORTYPE FillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
281 OMX_IN OMX_PTR pAppData,
282 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
283 static OMX_ERRORTYPE parse_pcm_header();
wait_for_event(void)284 void wait_for_event(void)
285 {
286 pthread_mutex_lock(&lock);
287 DEBUG_PRINT("%s: event_is_done=%d", __FUNCTION__, event_is_done);
288 while (event_is_done == 0) {
289 pthread_cond_wait(&cond, &lock);
290 }
291 event_is_done = 0;
292 pthread_mutex_unlock(&lock);
293 }
294
event_complete(void)295 void event_complete(void )
296 {
297 pthread_mutex_lock(&lock);
298 if (event_is_done == 0) {
299 event_is_done = 1;
300 pthread_cond_broadcast(&cond);
301 }
302 pthread_mutex_unlock(&lock);
303 }
304
etb_wait_for_event(void)305 void etb_wait_for_event(void)
306 {
307 pthread_mutex_lock(&etb_lock1);
308 DEBUG_PRINT("%s: etb_event_is_done=%d", __FUNCTION__, etb_event_is_done);
309 while (etb_event_is_done == 0) {
310 pthread_cond_wait(&etb_cond, &etb_lock1);
311 }
312 etb_event_is_done = 0;
313 pthread_mutex_unlock(&etb_lock1);
314 }
315
etb_event_complete(void)316 void etb_event_complete(void )
317 {
318 pthread_mutex_lock(&etb_lock1);
319 if (etb_event_is_done == 0) {
320 etb_event_is_done = 1;
321 pthread_cond_broadcast(&etb_cond);
322 }
323 pthread_mutex_unlock(&etb_lock1);
324 }
325
create_qcp_header(int Datasize,int Frames)326 static void create_qcp_header(int Datasize, int Frames)
327 {
328 append_header.s_riff = (unsigned)(Datasize + (int)QCP_HEADER_SIZE - 8);
329 /* exclude riff id and size field */
330 append_header.data1 = 0x5E7F6D41;
331 append_header.data2 = 0xB115;
332 append_header.data3 = 0x11D0;
333 append_header.data4[0] = 0xBA;
334 append_header.data4[1] = 0x91;
335 append_header.data4[2] = 0x00;
336 append_header.data4[3] = 0x80;
337 append_header.data4[4] = 0x5F;
338 append_header.data4[5] = 0xB4;
339 append_header.data4[6] = 0xB9;
340 append_header.data4[7] = 0x7E;
341 append_header.ver = 0x0002;
342 memcpy(append_header.name, "Qcelp 13K", 9);
343 append_header.abps = 13000;
344 append_header.bytes_per_pkt = 35;
345 append_header.vr_num_of_rates = 5;
346 append_header.vr_bytes_per_pkt[0] = 0x0422;
347 append_header.vr_bytes_per_pkt[1] = 0x0310;
348 append_header.vr_bytes_per_pkt[2] = 0x0207;
349 append_header.vr_bytes_per_pkt[3] = 0x0103;
350 append_header.s_vrat = 0x00000008;
351 append_header.v_rate = 0x00000001;
352 append_header.size_in_pkts = (unsigned)Frames;
353 append_header.s_data = (unsigned)Datasize;
354 return;
355 }
356
EventHandler(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_PTR pAppData,OMX_IN OMX_EVENTTYPE eEvent,OMX_IN OMX_U32 nData1,OMX_IN OMX_U32 nData2,OMX_IN OMX_PTR pEventData)357 OMX_ERRORTYPE EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
358 OMX_IN OMX_PTR pAppData,
359 OMX_IN OMX_EVENTTYPE eEvent,
360 OMX_IN OMX_U32 nData1, OMX_IN OMX_U32 nData2,
361 OMX_IN OMX_PTR pEventData)
362 {
363 DEBUG_PRINT("Function %s \n", __FUNCTION__);
364
365 /* To remove warning for unused variable to keep prototype same */
366 (void)hComponent;
367 (void)pAppData;
368 (void)pEventData;
369
370 switch(eEvent) {
371 case OMX_EventCmdComplete:
372 DEBUG_PRINT("\n OMX_EventCmdComplete event=%d data1=%u data2=%u\n",(OMX_EVENTTYPE)eEvent,
373 nData1,nData2);
374 event_complete();
375 break;
376 case OMX_EventError:
377 DEBUG_PRINT("\n OMX_EventError \n");
378 break;
379 case OMX_EventBufferFlag:
380 DEBUG_PRINT("\n OMX_EventBufferFlag \n");
381 bOutputEosReached = true;
382 event_complete();
383 break;
384 case OMX_EventPortSettingsChanged:
385 DEBUG_PRINT("\n OMX_EventPortSettingsChanged \n");
386 break;
387 default:
388 DEBUG_PRINT("\n Unknown Event \n");
389 break;
390 }
391 return OMX_ErrorNone;
392 }
393
FillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_PTR pAppData,OMX_IN OMX_BUFFERHEADERTYPE * pBuffer)394 OMX_ERRORTYPE FillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
395 OMX_IN OMX_PTR pAppData,
396 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
397 {
398 size_t bytes_writen = 0;
399 size_t total_bytes_writen = 0;
400 size_t len = 0;
401 struct enc_meta_out *meta = NULL;
402 OMX_U8 *src = pBuffer->pBuffer;
403 unsigned int num_of_frames = 1;
404
405 /* To remove warning for unused variable to keep prototype same */
406 (void)pAppData;
407
408 if(((pBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
409 DEBUG_PRINT("FBD::EOS on output port\n ");
410 bOutputEosReached = true;
411 return OMX_ErrorNone;
412 }
413 if(bInputEosReached_tunnel || bOutputEosReached)
414 {
415 DEBUG_PRINT("EOS REACHED NO MORE PROCESSING OF BUFFERS\n");
416 return OMX_ErrorNone;
417 }
418 if(num_of_frames != src[0]){
419
420 printf("Data corrupt\n");
421 return OMX_ErrorNone;
422 }
423 /* Skip the first bytes */
424
425
426
427 src += sizeof(unsigned char);
428 meta = (struct enc_meta_out *)src;
429 while (num_of_frames > 0) {
430 meta = (struct enc_meta_out *)src;
431 /*printf("offset=%d framesize=%d encoded_pcm[%d] msw_ts[%d]lsw_ts[%d] nflags[%d]\n",
432 meta->offset_to_frame,
433 meta->frame_size,
434 meta->encoded_pcm_samples, meta->msw_ts, meta->lsw_ts, meta->nflags);*/
435 len = meta->frame_size;
436
437 bytes_writen = fwrite(pBuffer->pBuffer + sizeof(unsigned char) + meta->offset_to_frame,1,len,outputBufferFile);
438 if(bytes_writen < len)
439 {
440 DEBUG_PRINT("error: invalid QCELP13 encoded data \n");
441 return OMX_ErrorNone;
442 }
443 src += sizeof(struct enc_meta_out);
444 num_of_frames--;
445 total_bytes_writen += len;
446 }
447 DEBUG_PRINT(" FillBufferDone size writen to file %zu count %d\n",total_bytes_writen, framecnt);
448 totaldatalen = totaldatalen + (int)total_bytes_writen;
449 framecnt++;
450
451 DEBUG_PRINT(" FBD calling FTB\n");
452 OMX_FillThisBuffer(hComponent,pBuffer);
453
454 return OMX_ErrorNone;
455 }
456
EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_PTR pAppData,OMX_IN OMX_BUFFERHEADERTYPE * pBuffer)457 OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
458 OMX_IN OMX_PTR pAppData,
459 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
460 {
461 int readBytes =0;
462
463 /* To remove warning for unused variable to keep prototype same */
464 (void)pAppData;
465
466 ebd_cnt++;
467 used_ip_buf_cnt--;
468 pthread_mutex_lock(&etb_lock);
469 if(!etb_done)
470 {
471 DEBUG_PRINT("\n*********************************************\n");
472 DEBUG_PRINT("Wait till first set of buffers are given to component\n");
473 DEBUG_PRINT("\n*********************************************\n");
474 etb_done++;
475 pthread_mutex_unlock(&etb_lock);
476 etb_wait_for_event();
477 }
478 else
479 {
480 pthread_mutex_unlock(&etb_lock);
481 }
482
483
484 if(bInputEosReached)
485 {
486 DEBUG_PRINT("\n*********************************************\n");
487 DEBUG_PRINT(" EBD::EOS on input port\n ");
488 DEBUG_PRINT("*********************************************\n");
489 return OMX_ErrorNone;
490 }else if (bFlushing == true) {
491 DEBUG_PRINT("omx_qcelp13_adec_test: bFlushing is set to TRUE used_ip_buf_cnt=%d\n",used_ip_buf_cnt);
492 if (used_ip_buf_cnt == 0) {
493 bFlushing = false;
494 } else {
495 DEBUG_PRINT("omx_qcelp13_adec_test: more buffer to come back used_ip_buf_cnt=%d\n",used_ip_buf_cnt);
496 return OMX_ErrorNone;
497 }
498 }
499
500 if((readBytes = Read_Buffer(pBuffer)) > 0) {
501 pBuffer->nFilledLen = (OMX_U32)readBytes;
502 used_ip_buf_cnt++;
503 OMX_EmptyThisBuffer(hComponent,pBuffer);
504 }
505 else{
506 pBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
507 used_ip_buf_cnt++;
508 bInputEosReached = true;
509 pBuffer->nFilledLen = 0;
510 OMX_EmptyThisBuffer(hComponent,pBuffer);
511 DEBUG_PRINT("EBD..Either EOS or Some Error while reading file\n");
512 }
513 return OMX_ErrorNone;
514 }
515
signal_handler(int sig_id)516 void signal_handler(int sig_id) {
517
518 /* Flush */
519 if (sig_id == SIGUSR1) {
520 DEBUG_PRINT("%s Initiate flushing\n", __FUNCTION__);
521 bFlushing = true;
522 OMX_SendCommand(qcelp13_enc_handle, OMX_CommandFlush, OMX_ALL, NULL);
523 } else if (sig_id == SIGUSR2) {
524 if (bPause == true) {
525 DEBUG_PRINT("%s resume record\n", __FUNCTION__);
526 bPause = false;
527 OMX_SendCommand(qcelp13_enc_handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
528 } else {
529 DEBUG_PRINT("%s pause record\n", __FUNCTION__);
530 bPause = true;
531 OMX_SendCommand(qcelp13_enc_handle, OMX_CommandStateSet, OMX_StatePause, NULL);
532 }
533 }
534 }
535
main(int argc,char ** argv)536 int main(int argc, char **argv)
537 {
538 unsigned int bufCnt=0;
539 OMX_ERRORTYPE result;
540
541 struct sigaction sa;
542
543 memset(&sa, 0, sizeof(sa));
544 sa.sa_handler = &signal_handler;
545 sigaction(SIGABRT, &sa, NULL);
546 sigaction(SIGUSR1, &sa, NULL);
547 sigaction(SIGUSR2, &sa, NULL);
548
549 (void) signal(SIGINT, Release_Encoder);
550
551 pthread_cond_init(&cond, 0);
552 pthread_mutex_init(&lock, 0);
553 pthread_cond_init(&etb_cond, 0);
554 pthread_mutex_init(&etb_lock, 0);
555 pthread_mutex_init(&etb_lock1, 0);
556
557 if (argc >= 9) {
558 in_filename = argv[1];
559 out_filename = argv[2];
560 tunnel = (uint32_t)atoi(argv[3]);
561 min_bitrate = (uint32_t)atoi(argv[4]);
562 max_bitrate = (uint32_t)atoi(argv[5]);
563 cdmarate = (uint32_t)atoi(argv[6]);
564 recpath = (uint32_t)atoi(argv[7]); // No configuration support yet..
565 rectime = (uint32_t)atoi(argv[8]);
566
567 } else {
568 DEBUG_PRINT(" invalid format: \n");
569 DEBUG_PRINT("ex: ./mm-aenc-omxqcelp13-test INPUTFILE OUTPUTFILE Tunnel MINRATE MAXRATE CDMARATE RECORDPATH RECORDTIME\n");
570 DEBUG_PRINT("MINRATE, MAXRATE and CDMARATE 1 to 4\n");
571 DEBUG_PRINT("RECORDPATH 0(TX),1(RX),2(BOTH),3(MIC)\n");
572 DEBUG_PRINT("RECORDTIME in seconds for AST Automation\n");
573 return 0;
574 }
575 if(recpath != 3) {
576 DEBUG_PRINT("For RECORDPATH Only MIC supported\n");
577 return 0;
578 }
579
580 if(tunnel == 0)
581 aud_comp = "OMX.qcom.audio.encoder.qcelp13";
582 else
583 aud_comp = "OMX.qcom.audio.encoder.tunneled.qcelp13";
584 if(Init_Encoder(aud_comp)!= 0x00)
585 {
586 DEBUG_PRINT("Decoder Init failed\n");
587 return -1;
588 }
589
590 fcntl(0, F_SETFL, O_NONBLOCK);
591
592 if(Play_Encoder() != 0x00)
593 {
594 DEBUG_PRINT("Play_Decoder failed\n");
595 return -1;
596 }
597
598 // Wait till EOS is reached...
599 if(rectime && tunnel)
600 {
601 sleep(rectime);
602 rectime = 0;
603 bInputEosReached_tunnel = 1;
604 DEBUG_PRINT("\EOS ON INPUT PORT\n");
605 }
606 else
607 {
608 wait_for_event();
609 }
610
611 if((bInputEosReached_tunnel) || ((bOutputEosReached) && !tunnel))
612 {
613
614 DEBUG_PRINT("\nMoving the decoder to idle state \n");
615 OMX_SendCommand(qcelp13_enc_handle, OMX_CommandStateSet, OMX_StateIdle,0);
616 wait_for_event();
617
618 DEBUG_PRINT("\nMoving the encoder to loaded state \n");
619 OMX_SendCommand(qcelp13_enc_handle, OMX_CommandStateSet, OMX_StateLoaded,0);
620 sleep(1);
621 if (!tunnel)
622 {
623 DEBUG_PRINT("\nFillBufferDone: Deallocating i/p buffers \n");
624 for(bufCnt=0; bufCnt < input_buf_cnt; ++bufCnt) {
625 OMX_FreeBuffer(qcelp13_enc_handle, 0, pInputBufHdrs[bufCnt]);
626 }
627 }
628
629 DEBUG_PRINT ("\nFillBufferDone: Deallocating o/p buffers \n");
630 for(bufCnt=0; bufCnt < output_buf_cnt; ++bufCnt) {
631 OMX_FreeBuffer(qcelp13_enc_handle, 1, pOutputBufHdrs[bufCnt]);
632 }
633 wait_for_event();
634 create_qcp_header(totaldatalen, framecnt);
635 fseek(outputBufferFile, 0,SEEK_SET);
636 fwrite(&append_header,1,QCP_HEADER_SIZE,outputBufferFile);
637
638
639 result = OMX_FreeHandle(qcelp13_enc_handle);
640 if (result != OMX_ErrorNone) {
641 DEBUG_PRINT ("\nOMX_FreeHandle error. Error code: %d\n", result);
642 }
643
644 /* Deinit OpenMAX */
645 if(tunnel)
646 {
647 #ifdef AUDIOV2
648 if (msm_route_stream(DIR_TX,session_id,device_id, 0))
649 {
650 DEBUG_PRINT("\ncould not set stream routing\n");
651 return -1;
652 }
653 if (msm_en_device(device_id, 0))
654 {
655 DEBUG_PRINT("\ncould not enable device\n");
656 return -1;
657 }
658 msm_mixer_close();
659 #endif
660 }
661 OMX_Deinit();
662 ebd_cnt=0;
663 bOutputEosReached = false;
664 bInputEosReached_tunnel = false;
665 bInputEosReached = 0;
666 qcelp13_enc_handle = NULL;
667 pthread_cond_destroy(&cond);
668 pthread_mutex_destroy(&lock);
669 fclose(outputBufferFile);
670 DEBUG_PRINT("*****************************************\n");
671 DEBUG_PRINT("******...QCELP13 ENC TEST COMPLETED...***************\n");
672 DEBUG_PRINT("*****************************************\n");
673 }
674 return 0;
675 }
676
Release_Encoder()677 void Release_Encoder()
678 {
679 static int cnt=0;
680 OMX_ERRORTYPE result;
681
682 DEBUG_PRINT("END OF QCELP13 ENCODING: EXITING PLEASE WAIT\n");
683 bInputEosReached_tunnel = 1;
684 event_complete();
685 cnt++;
686 if(cnt > 1)
687 {
688 /* FORCE RESET */
689 qcelp13_enc_handle = NULL;
690 ebd_cnt=0;
691 bInputEosReached_tunnel = false;
692
693 result = OMX_FreeHandle(qcelp13_enc_handle);
694 if (result != OMX_ErrorNone) {
695 DEBUG_PRINT ("\nOMX_FreeHandle error. Error code: %d\n", result);
696 }
697
698 /* Deinit OpenMAX */
699
700 OMX_Deinit();
701
702 pthread_cond_destroy(&cond);
703 pthread_mutex_destroy(&lock);
704 DEBUG_PRINT("*****************************************\n");
705 DEBUG_PRINT("******...QCELP13 ENC TEST COMPLETED...***************\n");
706 DEBUG_PRINT("*****************************************\n");
707 exit(0);
708 }
709 }
710
Init_Encoder(OMX_STRING audio_component)711 int Init_Encoder(OMX_STRING audio_component)
712 {
713 DEBUG_PRINT("Inside %s \n", __FUNCTION__);
714 OMX_ERRORTYPE omxresult;
715 OMX_U32 total = 0;
716 typedef OMX_U8* OMX_U8_PTR;
717 char *role ="audio_encoder";
718
719 static OMX_CALLBACKTYPE call_back = {
720 &EventHandler,&EmptyBufferDone,&FillBufferDone
721 };
722
723 /* Init. the OpenMAX Core */
724 DEBUG_PRINT("\nInitializing OpenMAX Core....\n");
725 omxresult = OMX_Init();
726
727 if(OMX_ErrorNone != omxresult) {
728 DEBUG_PRINT("\n Failed to Init OpenMAX core");
729 return -1;
730 }
731 else {
732 DEBUG_PRINT("\nOpenMAX Core Init Done\n");
733 }
734
735 /* Query for audio decoders*/
736 DEBUG_PRINT("Qcelp13_test: Before entering OMX_GetComponentOfRole");
737 OMX_GetComponentsOfRole(role, &total, 0);
738 DEBUG_PRINT ("\nTotal components of role=%s :%u", role, total);
739
740
741 omxresult = OMX_GetHandle((OMX_HANDLETYPE*)(&qcelp13_enc_handle),
742 (OMX_STRING)audio_component, NULL, &call_back);
743 if (FAILED(omxresult)) {
744 DEBUG_PRINT("\nFailed to Load the component:%s\n", audio_component);
745 return -1;
746 }
747 else
748 {
749 DEBUG_PRINT("\nComponent %s is in LOADED state\n", audio_component);
750 }
751
752 /* Get the port information */
753 CONFIG_VERSION_SIZE(portParam);
754 omxresult = OMX_GetParameter(qcelp13_enc_handle, OMX_IndexParamAudioInit,
755 (OMX_PTR)&portParam);
756
757 if(FAILED(omxresult)) {
758 DEBUG_PRINT("\nFailed to get Port Param\n");
759 return -1;
760 }
761 else
762 {
763 DEBUG_PRINT("\nportParam.nPorts:%u\n", portParam.nPorts);
764 DEBUG_PRINT("\nportParam.nStartPortNumber:%u\n",
765 portParam.nStartPortNumber);
766 }
767
768 if(OMX_ErrorNone != omxresult)
769 {
770 DEBUG_PRINT("Set parameter failed");
771 }
772
773 return 0;
774 }
775
Play_Encoder()776 int Play_Encoder()
777 {
778 unsigned int i;
779 int Size=0;
780 DEBUG_PRINT("Inside %s \n", __FUNCTION__);
781 OMX_ERRORTYPE ret;
782 OMX_INDEXTYPE index;
783 #ifdef __LP64__
784 DEBUG_PRINT("sizeof[%ld]\n", sizeof(OMX_BUFFERHEADERTYPE));
785 #else
786 DEBUG_PRINT("sizeof[%d]\n", sizeof(OMX_BUFFERHEADERTYPE));
787 #endif
788
789 /* open the i/p and o/p files based on the video file format passed */
790 if(open_audio_file()) {
791 DEBUG_PRINT("\n Returning -1");
792 return -1;
793 }
794
795 /* Query the encoder input min buf requirements */
796 CONFIG_VERSION_SIZE(inputportFmt);
797
798 /* Port for which the Client needs to obtain info */
799 inputportFmt.nPortIndex = portParam.nStartPortNumber;
800
801 OMX_GetParameter(qcelp13_enc_handle,OMX_IndexParamPortDefinition,&inputportFmt);
802 DEBUG_PRINT ("\nEnc Input Buffer Count %u\n", inputportFmt.nBufferCountMin);
803 DEBUG_PRINT ("\nEnc: Input Buffer Size %u\n", inputportFmt.nBufferSize);
804
805 if(OMX_DirInput != inputportFmt.eDir) {
806 DEBUG_PRINT ("\nEnc: Expect Input Port\n");
807 return -1;
808 }
809
810 pcmparam.nPortIndex = 0;
811 pcmparam.nChannels = channels;
812 pcmparam.nSamplingRate = samplerate;
813 OMX_SetParameter(qcelp13_enc_handle,OMX_IndexParamAudioPcm,&pcmparam);
814
815
816 /* Query the encoder outport's min buf requirements */
817 CONFIG_VERSION_SIZE(outputportFmt);
818 /* Port for which the Client needs to obtain info */
819 outputportFmt.nPortIndex = portParam.nStartPortNumber + 1;
820
821 OMX_GetParameter(qcelp13_enc_handle,OMX_IndexParamPortDefinition,&outputportFmt);
822 DEBUG_PRINT ("\nEnc: Output Buffer Count %u\n", outputportFmt.nBufferCountMin);
823 DEBUG_PRINT ("\nEnc: Output Buffer Size %u\n", outputportFmt.nBufferSize);
824
825 if(OMX_DirOutput != outputportFmt.eDir) {
826 DEBUG_PRINT ("\nEnc: Expect Output Port\n");
827 return -1;
828 }
829
830
831 CONFIG_VERSION_SIZE(qcelp13param);
832
833 qcelp13param.nPortIndex = 1;
834 qcelp13param.nChannels = channels; //2 ; /* 1-> mono 2-> stereo*/
835 qcelp13param.nMinBitRate = min_bitrate;
836 qcelp13param.nMaxBitRate = max_bitrate;
837 OMX_SetParameter(qcelp13_enc_handle,OMX_IndexParamAudioQcelp13,&qcelp13param);
838 OMX_GetExtensionIndex(qcelp13_enc_handle,"OMX.Qualcomm.index.audio.sessionId",&index);
839 OMX_GetParameter(qcelp13_enc_handle,index,&streaminfoparam);
840 if(tunnel) {
841 #ifdef AUDIOV2
842 session_id = streaminfoparam.sessionId;
843 control = msm_mixer_open("/dev/snd/controlC0", 0);
844 if(control < 0)
845 printf("ERROR opening the device\n");
846 device_id = msm_get_device(device);
847 DEBUG_PRINT ("\ndevice_id = %d\n",device_id);
848 DEBUG_PRINT("\nsession_id = %d\n",session_id);
849 if (msm_en_device(device_id, 1))
850 {
851 perror("could not enable device\n");
852 return -1;
853 }
854 if (msm_route_stream(DIR_TX,session_id,device_id, 1))
855 {
856 perror("could not set stream routing\n");
857 return -1;
858 }
859 #endif
860 }
861
862 DEBUG_PRINT ("\nOMX_SendCommand Encoder -> IDLE\n");
863 OMX_SendCommand(qcelp13_enc_handle, OMX_CommandStateSet, OMX_StateIdle,0);
864 /* wait_for_event(); should not wait here event complete status will
865 not come until enough buffer are allocated */
866 if (tunnel == 0)
867 {
868 input_buf_cnt = inputportFmt.nBufferCountActual; // inputportFmt.nBufferCountMin + 5;
869 DEBUG_PRINT("Transition to Idle State succesful...\n");
870 /* Allocate buffer on decoder's i/p port */
871 error = Allocate_Buffer(qcelp13_enc_handle, &pInputBufHdrs, inputportFmt.nPortIndex,
872 input_buf_cnt, inputportFmt.nBufferSize);
873 if (error != OMX_ErrorNone || pInputBufHdrs == NULL) {
874 DEBUG_PRINT ("\nOMX_AllocateBuffer Input buffer error\n");
875 return -1;
876 }
877 else {
878 DEBUG_PRINT ("\nOMX_AllocateBuffer Input buffer success\n");
879 }
880 }
881 output_buf_cnt = outputportFmt.nBufferCountMin ;
882
883 /* Allocate buffer on encoder's O/Pp port */
884 error = Allocate_Buffer(qcelp13_enc_handle, &pOutputBufHdrs, outputportFmt.nPortIndex,
885 output_buf_cnt, outputportFmt.nBufferSize);
886 if (error != OMX_ErrorNone || pOutputBufHdrs == NULL ) {
887 DEBUG_PRINT ("\nOMX_AllocateBuffer Output buffer error\n");
888 return -1;
889 }
890 else {
891 DEBUG_PRINT ("\nOMX_AllocateBuffer Output buffer success\n");
892 }
893
894 wait_for_event();
895
896
897 if (tunnel == 1)
898 {
899 DEBUG_PRINT ("\nOMX_SendCommand to enable TUNNEL MODE during IDLE\n");
900 OMX_SendCommand(qcelp13_enc_handle, OMX_CommandPortDisable,0,0); // disable input port
901 wait_for_event();
902 }
903
904 DEBUG_PRINT ("\nOMX_SendCommand encoder -> Executing\n");
905 OMX_SendCommand(qcelp13_enc_handle, OMX_CommandStateSet, OMX_StateExecuting,0);
906 wait_for_event();
907
908 DEBUG_PRINT(" Start sending OMX_FILLthisbuffer\n");
909
910 for(i=0; i < output_buf_cnt; i++) {
911 DEBUG_PRINT ("\nOMX_FillThisBuffer on output buf no.%d\n",i);
912 pOutputBufHdrs[i]->nOutputPortIndex = 1;
913 pOutputBufHdrs[i]->nFlags = pOutputBufHdrs[i]->nFlags & (unsigned)~OMX_BUFFERFLAG_EOS;
914 ret = OMX_FillThisBuffer(qcelp13_enc_handle, pOutputBufHdrs[i]);
915 if (OMX_ErrorNone != ret) {
916 DEBUG_PRINT("OMX_FillThisBuffer failed with result %d\n", ret);
917 }
918 else {
919 DEBUG_PRINT("OMX_FillThisBuffer success!\n");
920 }
921 }
922
923 if(tunnel == 0)
924 {
925 DEBUG_PRINT(" Start sending OMX_emptythisbuffer\n");
926 for (i = 0;i < input_buf_cnt;i++) {
927 DEBUG_PRINT ("\nOMX_EmptyThisBuffer on Input buf no.%d\n",i);
928 pInputBufHdrs[i]->nInputPortIndex = 0;
929 Size = Read_Buffer(pInputBufHdrs[i]);
930 if(Size <=0 ){
931 DEBUG_PRINT("NO DATA READ\n");
932 bInputEosReached = true;
933 pInputBufHdrs[i]->nFlags= OMX_BUFFERFLAG_EOS;
934 }
935 pInputBufHdrs[i]->nFilledLen = (OMX_U32)Size;
936 pInputBufHdrs[i]->nInputPortIndex = 0;
937 used_ip_buf_cnt++;
938 ret = OMX_EmptyThisBuffer(qcelp13_enc_handle, pInputBufHdrs[i]);
939 if (OMX_ErrorNone != ret) {
940 DEBUG_PRINT("OMX_EmptyThisBuffer failed with result %d\n", ret);
941 }
942 else {
943 DEBUG_PRINT("OMX_EmptyThisBuffer success!\n");
944 }
945 if(Size <=0 ){
946 break;//eos reached
947 }
948 }
949 pthread_mutex_lock(&etb_lock);
950 if(etb_done)
951 {
952 DEBUG_PRINT("Component is waiting for EBD to be released.\n");
953 etb_event_complete();
954 }
955 else
956 {
957 DEBUG_PRINT("\n****************************\n");
958 DEBUG_PRINT("EBD not yet happened ...\n");
959 DEBUG_PRINT("\n****************************\n");
960 etb_done++;
961 }
962 pthread_mutex_unlock(&etb_lock);
963 }
964
965 return 0;
966 }
967
968
969
Allocate_Buffer(OMX_COMPONENTTYPE * avc_enc_handle,OMX_BUFFERHEADERTYPE *** pBufHdrs,OMX_U32 nPortIndex,unsigned int bufCntMin,unsigned int bufSize)970 static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *avc_enc_handle,
971 OMX_BUFFERHEADERTYPE ***pBufHdrs,
972 OMX_U32 nPortIndex,
973 unsigned int bufCntMin, unsigned int bufSize)
974 {
975 DEBUG_PRINT("Inside %s \n", __FUNCTION__);
976 OMX_ERRORTYPE error=OMX_ErrorNone;
977 unsigned int bufCnt=0;
978
979 /* To remove warning for unused variable to keep prototype same */
980 (void)avc_enc_handle;
981
982 *pBufHdrs= (OMX_BUFFERHEADERTYPE **)
983 malloc(sizeof(OMX_BUFFERHEADERTYPE*)*bufCntMin);
984
985 for(bufCnt=0; bufCnt < bufCntMin; ++bufCnt) {
986 DEBUG_PRINT("\n OMX_AllocateBuffer No %d \n", bufCnt);
987 error = OMX_AllocateBuffer(qcelp13_enc_handle, &((*pBufHdrs)[bufCnt]),
988 nPortIndex, NULL, bufSize);
989 }
990
991 return error;
992 }
993
994
995
996
Read_Buffer(OMX_BUFFERHEADERTYPE * pBufHdr)997 static int Read_Buffer (OMX_BUFFERHEADERTYPE *pBufHdr )
998 {
999
1000 size_t bytes_read=0;
1001
1002
1003 pBufHdr->nFilledLen = 0;
1004 pBufHdr->nFlags |= OMX_BUFFERFLAG_EOS;
1005
1006 bytes_read = fread(pBufHdr->pBuffer, 1, pBufHdr->nAllocLen , inputBufferFile);
1007
1008 pBufHdr->nFilledLen = (OMX_U32)bytes_read;
1009 // Time stamp logic
1010 ((OMX_BUFFERHEADERTYPE *)pBufHdr)->nTimeStamp = \
1011
1012 (OMX_TICKS) ((total_pcm_bytes * 1000)/(samplerate * channels *2));
1013
1014 DEBUG_PRINT ("\n--time stamp -- %ld\n", (unsigned long)((OMX_BUFFERHEADERTYPE *)pBufHdr)->nTimeStamp);
1015 if(bytes_read == 0)
1016 {
1017 pBufHdr->nFlags |= OMX_BUFFERFLAG_EOS;
1018 DEBUG_PRINT ("\nBytes read zero\n");
1019 }
1020 else
1021 {
1022 pBufHdr->nFlags = pBufHdr->nFlags & (unsigned)~OMX_BUFFERFLAG_EOS;
1023
1024 total_pcm_bytes = (unsigned)(total_pcm_bytes + bytes_read);
1025 }
1026
1027 return (int)bytes_read;;
1028 }
1029
1030
1031
1032 //In Encoder this Should Open a PCM or WAV file for input.
1033
open_audio_file()1034 static int open_audio_file ()
1035 {
1036 int error_code = 0;
1037
1038 if (!tunnel)
1039 {
1040 DEBUG_PRINT("Inside %s filename=%s\n", __FUNCTION__, in_filename);
1041 inputBufferFile = fopen (in_filename, "rb");
1042 if (inputBufferFile == NULL) {
1043 DEBUG_PRINT("\ni/p file %s could NOT be opened\n",
1044 in_filename);
1045 error_code = -1;
1046 }
1047 if(parse_pcm_header() != 0x00)
1048 {
1049 DEBUG_PRINT("PCM parser failed \n");
1050 return -1;
1051 }
1052 }
1053
1054 DEBUG_PRINT("Inside %s filename=%s\n", __FUNCTION__, out_filename);
1055 outputBufferFile = fopen (out_filename, "wb");
1056 if (outputBufferFile == NULL) {
1057 DEBUG_PRINT("\ni/p file %s could NOT be opened\n",
1058 out_filename);
1059 error_code = -1;
1060 return error_code;
1061 }
1062 fseek(outputBufferFile, QCP_HEADER_SIZE, SEEK_SET);
1063 return error_code;
1064 }
1065
parse_pcm_header()1066 static OMX_ERRORTYPE parse_pcm_header()
1067 {
1068 struct wav_header hdr;
1069
1070 DEBUG_PRINT("\n***************************************************************\n");
1071 if(fread(&hdr, 1, sizeof(hdr),inputBufferFile)!=sizeof(hdr))
1072 {
1073 DEBUG_PRINT("Wav file cannot read header\n");
1074 return -1;
1075 }
1076
1077 if ((hdr.riff_id != ID_RIFF) ||
1078 (hdr.riff_fmt != ID_WAVE)||
1079 (hdr.fmt_id != ID_FMT))
1080 {
1081 DEBUG_PRINT("Wav file is not a riff/wave file\n");
1082 return -1;
1083 }
1084
1085 if (hdr.audio_format != FORMAT_PCM)
1086 {
1087 DEBUG_PRINT("Wav file is not adpcm format %d and fmt size is %d\n",
1088 hdr.audio_format, hdr.fmt_sz);
1089 return -1;
1090 }
1091
1092 DEBUG_PRINT("Samplerate is %d\n", hdr.sample_rate);
1093 DEBUG_PRINT("Channel Count is %d\n", hdr.num_channels);
1094 DEBUG_PRINT("\n***************************************************************\n");
1095
1096 samplerate = hdr.sample_rate;
1097 channels = hdr.num_channels;
1098 total_pcm_bytes = 0;
1099
1100 return OMX_ErrorNone;
1101 }
1102