Home | History | Annotate | Download | only in stagefright
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <binder/ProcessState.h>
     18 #include <media/mediarecorder.h>
     19 #include <media/stagefright/foundation/ADebug.h>
     20 #include <media/stagefright/AMRWriter.h>
     21 #include <media/stagefright/AudioPlayer.h>
     22 #include <media/stagefright/AudioSource.h>
     23 #include <media/stagefright/MediaDefs.h>
     24 #include <media/stagefright/MetaData.h>
     25 #include <media/stagefright/OMXClient.h>
     26 #include <media/stagefright/OMXCodec.h>
     27 #include "SineSource.h"
     28 
     29 using namespace android;
     30 
     31 static void usage(const char* name)
     32 {
     33     fprintf(stderr, "Usage: %s [-d duration] [-m] [-w] [<output-file>]\n", name);
     34     fprintf(stderr, "Encodes either a sine wave or microphone input to AMR format\n");
     35     fprintf(stderr, "    -d    duration in seconds, default 5 seconds\n");
     36     fprintf(stderr, "    -m    use microphone for input, default sine source\n");
     37     fprintf(stderr, "    -w    use AMR wideband (default narrowband)\n");
     38     fprintf(stderr, "    <output-file> output file for AMR encoding,"
     39             " if unspecified, decode to speaker.\n");
     40 }
     41 
     42 int main(int argc, char* argv[])
     43 {
     44     static const int channels = 1; // not permitted to be stereo now
     45     unsigned duration = 5;
     46     bool useMic = false;
     47     bool outputWBAMR = false;
     48     bool playToSpeaker = true;
     49     const char* fileOut = NULL;
     50     int ch;
     51     while ((ch = getopt(argc, argv, "d:mw")) != -1) {
     52         switch (ch) {
     53         case 'd':
     54             duration = atoi(optarg);
     55             break;
     56         case 'm':
     57             useMic = true;
     58             break;
     59         case 'w':
     60             outputWBAMR = true;
     61             break;
     62         default:
     63             usage(argv[0]);
     64             return -1;
     65         }
     66     }
     67     argc -= optind;
     68     argv += optind;
     69     if (argc == 1) {
     70         fileOut = argv[0];
     71     }
     72     const int32_t kSampleRate = outputWBAMR ? 16000 : 8000;
     73     const int32_t kBitRate = outputWBAMR ? 16000 : 8000;
     74 
     75     android::ProcessState::self()->startThreadPool();
     76     OMXClient client;
     77     CHECK_EQ(client.connect(), (status_t)OK);
     78     sp<MediaSource> source;
     79 
     80     if (useMic) {
     81         // talk into the appropriate microphone for the duration
     82         source = new AudioSource(
     83                 AUDIO_SOURCE_MIC,
     84                 kSampleRate,
     85                 channels);
     86     } else {
     87         // use a sine source at 500 hz.
     88         source = new SineSource(kSampleRate, channels);
     89     }
     90 
     91     sp<MetaData> meta = new MetaData;
     92     meta->setCString(
     93             kKeyMIMEType,
     94             outputWBAMR ? MEDIA_MIMETYPE_AUDIO_AMR_WB
     95                     : MEDIA_MIMETYPE_AUDIO_AMR_NB);
     96 
     97     meta->setInt32(kKeyChannelCount, channels);
     98     meta->setInt32(kKeySampleRate, kSampleRate);
     99     meta->setInt32(kKeyBitRate, kBitRate);
    100     int32_t maxInputSize;
    101     if (source->getFormat()->findInt32(kKeyMaxInputSize, &maxInputSize)) {
    102         meta->setInt32(kKeyMaxInputSize, maxInputSize);
    103     }
    104 
    105     sp<MediaSource> encoder = OMXCodec::Create(
    106             client.interface(),
    107             meta, true /* createEncoder */,
    108             source);
    109 
    110     if (fileOut != NULL) {
    111         // target file specified, write encoded AMR output
    112         sp<AMRWriter> writer = new AMRWriter(fileOut);
    113         writer->addSource(encoder);
    114         writer->start();
    115         sleep(duration);
    116         writer->stop();
    117     } else {
    118         // otherwise decode to speaker
    119         sp<MediaSource> decoder = OMXCodec::Create(
    120                 client.interface(),
    121                 meta, false /* createEncoder */,
    122                 encoder);
    123 
    124         if (playToSpeaker) {
    125             AudioPlayer *player = new AudioPlayer(NULL);
    126             player->setSource(decoder);
    127             player->start();
    128             sleep(duration);
    129             source->stop(); // must stop source otherwise delete player will hang
    130             delete player; // there is no player->stop()...
    131         } else {
    132             CHECK_EQ(decoder->start(), (status_t)OK);
    133             MediaBuffer* buffer;
    134             while (decoder->read(&buffer) == OK) {
    135                 // do something with buffer (save it eventually?)
    136                 // need to stop after some count though...
    137                 putchar('.');
    138                 fflush(stdout);
    139                 buffer->release();
    140                 buffer = NULL;
    141             }
    142             CHECK_EQ(decoder->stop(), (status_t)OK);
    143         }
    144     }
    145 
    146     return 0;
    147 }
    148