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