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 <sys/types.h>
     18 #include <sys/stat.h>
     19 #include <fcntl.h>
     20 
     21 #include <utils/String16.h>
     22 
     23 #include <binder/ProcessState.h>
     24 #include <media/mediarecorder.h>
     25 #include <media/stagefright/foundation/ADebug.h>
     26 #include <media/stagefright/foundation/AMessage.h>
     27 #include <media/stagefright/AMRWriter.h>
     28 #include <media/stagefright/AudioPlayer.h>
     29 #include <media/stagefright/AudioSource.h>
     30 #include <media/stagefright/MediaCodecSource.h>
     31 #include <media/stagefright/MediaDefs.h>
     32 #include <media/stagefright/MetaData.h>
     33 #include <media/stagefright/SimpleDecodingSource.h>
     34 #include "SineSource.h"
     35 
     36 using namespace android;
     37 
     38 static void usage(const char* name)
     39 {
     40     fprintf(stderr, "Usage: %s [-d du.ration] [-m] [-w] [<output-file>]\n", name);
     41     fprintf(stderr, "Encodes either a sine wave or microphone input to AMR format\n");
     42     fprintf(stderr, "    -d    duration in seconds, default 5 seconds\n");
     43     fprintf(stderr, "    -m    use microphone for input, default sine source\n");
     44     fprintf(stderr, "    -w    use AMR wideband (default narrowband)\n");
     45     fprintf(stderr, "    <output-file> output file for AMR encoding,"
     46             " if unspecified, decode to speaker.\n");
     47 }
     48 
     49 int main(int argc, char* argv[])
     50 {
     51     static const int channels = 1; // not permitted to be stereo now
     52     unsigned duration = 5;
     53     bool useMic = false;
     54     bool outputWBAMR = false;
     55     bool playToSpeaker = true;
     56     const char* fileOut = NULL;
     57     int ch;
     58     while ((ch = getopt(argc, argv, "d:mw")) != -1) {
     59         switch (ch) {
     60         case 'd':
     61             duration = atoi(optarg);
     62             break;
     63         case 'm':
     64             useMic = true;
     65             break;
     66         case 'w':
     67             outputWBAMR = true;
     68             break;
     69         default:
     70             usage(argv[0]);
     71             return -1;
     72         }
     73     }
     74     argc -= optind;
     75     argv += optind;
     76     if (argc == 1) {
     77         fileOut = argv[0];
     78     }
     79     const int32_t kSampleRate = outputWBAMR ? 16000 : 8000;
     80     const int32_t kBitRate = outputWBAMR ? 16000 : 8000;
     81 
     82     android::ProcessState::self()->startThreadPool();
     83     sp<MediaSource> source;
     84 
     85     if (useMic) {
     86         // talk into the appropriate microphone for the duration
     87         source = new AudioSource(
     88                 AUDIO_SOURCE_MIC,
     89                 String16(),
     90                 kSampleRate,
     91                 channels);
     92     } else {
     93         // use a sine source at 500 hz.
     94         source = new SineSource(kSampleRate, channels);
     95     }
     96 
     97     sp<AMessage> meta = new AMessage;
     98     meta->setString(
     99             "mime",
    100             outputWBAMR ? MEDIA_MIMETYPE_AUDIO_AMR_WB
    101                     : MEDIA_MIMETYPE_AUDIO_AMR_NB);
    102 
    103     meta->setInt32("channel-count", channels);
    104     meta->setInt32("sample-rate", kSampleRate);
    105     meta->setInt32("bitrate", kBitRate);
    106     int32_t maxInputSize;
    107     if (source->getFormat()->findInt32(kKeyMaxInputSize, &maxInputSize)) {
    108         meta->setInt32("max-input-size", maxInputSize);
    109     }
    110 
    111     sp<ALooper> looper = new ALooper;
    112     looper->setName("audioloop");
    113     looper->start();
    114 
    115     sp<IMediaSource> encoder = MediaCodecSource::Create(looper, meta, source);
    116 
    117     if (fileOut != NULL) {
    118         // target file specified, write encoded AMR output
    119         int fd = open(fileOut, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
    120         if (fd < 0) {
    121             return 1;
    122         }
    123         sp<AMRWriter> writer = new AMRWriter(fd);
    124         close(fd);
    125         writer->addSource(encoder);
    126         writer->start();
    127         sleep(duration);
    128         writer->stop();
    129     } else {
    130         // otherwise decode to speaker
    131         sp<IMediaSource> decoder = SimpleDecodingSource::Create(encoder);
    132 
    133         if (playToSpeaker) {
    134             AudioPlayer *player = new AudioPlayer(NULL);
    135             player->setSource(decoder);
    136             player->start();
    137             sleep(duration);
    138 
    139             decoder.clear(); // must clear |decoder| otherwise delete player will hang.
    140             delete player; // there is no player->stop()...
    141         } else {
    142             CHECK_EQ(decoder->start(), (status_t)OK);
    143             MediaBuffer* buffer;
    144             while (decoder->read(&buffer) == OK) {
    145                 // do something with buffer (save it eventually?)
    146                 // need to stop after some count though...
    147                 putchar('.');
    148                 fflush(stdout);
    149                 buffer->release();
    150                 buffer = NULL;
    151             }
    152             CHECK_EQ(decoder->stop(), (status_t)OK);
    153         }
    154     }
    155 
    156     return 0;
    157 }
    158