record.cpp revision 92d57f926eb39d72e8fd8f3b3c9e40d25f77ad47
15d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull/* 25d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull * Copyright (C) 2009 The Android Open Source Project 35d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull * 45d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull * Licensed under the Apache License, Version 2.0 (the "License"); 55d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull * you may not use this file except in compliance with the License. 65d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull * You may obtain a copy of the License at 75d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull * 85d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull * http://www.apache.org/licenses/LICENSE-2.0 95d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull * 105d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull * Unless required by applicable law or agreed to in writing, software 115d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull * distributed under the License is distributed on an "AS IS" BASIS, 125d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull * See the License for the specific language governing permissions and 145d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull * limitations under the License. 155d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull */ 165d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 175d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull#include "SineSource.h" 185d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 195d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull#include <binder/ProcessState.h> 205d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull#include <media/stagefright/foundation/ADebug.h> 215d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull#include <media/stagefright/foundation/ALooper.h> 225d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull#include <media/stagefright/foundation/AMessage.h> 235d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull#include <media/stagefright/AudioPlayer.h> 245d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull#include <media/stagefright/CameraSource.h> 255d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull#include <media/stagefright/FileSource.h> 265d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull#include <media/stagefright/MediaBufferGroup.h> 275d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull#include <media/stagefright/MediaDefs.h> 285d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull#include <media/stagefright/MediaCodecSource.h> 295d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull#include <media/stagefright/MetaData.h> 305d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull#include <media/stagefright/MediaExtractor.h> 315d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull#include <media/stagefright/MPEG4Writer.h> 325d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull#include <media/stagefright/SimpleDecodingSource.h> 335d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull#include <media/MediaPlayerInterface.h> 345d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 355d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scullusing namespace android; 365d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 375d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scullstatic const int32_t kAudioBitRate = 12200; 385d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull#if 0 395d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scullstatic const int32_t kFramerate = 24; // fps 405d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scullstatic const int32_t kIFramesIntervalSec = 1; 415d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scullstatic const int32_t kVideoBitRate = 512 * 1024; 425d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scullstatic const int64_t kDurationUs = 10000000LL; // 10 seconds 435d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 445d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scullclass DummySource : public MediaSource { 455d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 465d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scullpublic: 475d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull DummySource(int width, int height, int colorFormat) 485d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull : mWidth(width), 495d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull mHeight(height), 505d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull mColorFormat(colorFormat), 515d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull mSize((width * height * 3) / 2) { 525d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull mGroup.add_buffer(new MediaBuffer(mSize)); 535d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 545d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull // Check the color format to make sure 555d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull // that the buffer size mSize it set correctly above. 565d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull CHECK(colorFormat == OMX_COLOR_FormatYUV420SemiPlanar || 575d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull colorFormat == OMX_COLOR_FormatYUV420Planar); 585d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull } 595d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 605d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull virtual sp<MetaData> getFormat() { 615d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull sp<MetaData> meta = new MetaData; 625d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull meta->setInt32(kKeyWidth, mWidth); 635d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull meta->setInt32(kKeyHeight, mHeight); 645d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull meta->setInt32(kKeyColorFormat, mColorFormat); 655d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 665d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 675d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull return meta; 685d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull } 695d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 705d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull virtual status_t start(MetaData *params) { 715d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull mNumFramesOutput = 0; 725d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull return OK; 735d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull } 745d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 755d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull virtual status_t stop() { 765d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull return OK; 775d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull } 785d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 795d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull virtual status_t read( 805d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull MediaBuffer **buffer, const MediaSource::ReadOptions *options) { 815d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull if (mNumFramesOutput == kFramerate * 10) { 825d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull // Stop returning data after 10 secs. 835d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull return ERROR_END_OF_STREAM; 845d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull } 855d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 865d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull // printf("DummySource::read\n"); 875d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull status_t err = mGroup.acquire_buffer(buffer); 885d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull if (err != OK) { 895d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull return err; 905d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull } 915d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 925d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull char x = (char)((double)rand() / RAND_MAX * 255); 935d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull memset((*buffer)->data(), x, mSize); 945d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull (*buffer)->set_range(0, mSize); 955d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull (*buffer)->meta_data()->clear(); 965d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull (*buffer)->meta_data()->setInt64( 975d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull kKeyTime, (mNumFramesOutput * 1000000) / kFramerate); 985d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull ++mNumFramesOutput; 995d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 1005d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull // printf("DummySource::read - returning buffer\n"); 1015d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull // ALOGI("DummySource::read - returning buffer"); 1025d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull return OK; 1035d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull } 1045d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 1055d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scullprotected: 1065d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull virtual ~DummySource() {} 1075d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 1085d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scullprivate: 1095d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull MediaBufferGroup mGroup; 1105d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull int mWidth, mHeight; 1115d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull int mColorFormat; 1125d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull size_t mSize; 1135d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull int64_t mNumFramesOutput;; 1145d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 1155d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull DummySource(const DummySource &); 1165d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull DummySource &operator=(const DummySource &); 1175d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull}; 1185d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 1195d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scullsp<MediaSource> createSource(const char *filename) { 1205d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull sp<MediaSource> source; 1215d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 1225d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull sp<MediaExtractor> extractor = 1235d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull MediaExtractor::Create(new FileSource(filename)); 1245d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull if (extractor == NULL) { 1255d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull return NULL; 1265d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull } 1275d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 1285d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull size_t num_tracks = extractor->countTracks(); 1295d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 1305d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull sp<MetaData> meta; 1315d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull for (size_t i = 0; i < num_tracks; ++i) { 1325d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull meta = extractor->getTrackMetaData(i); 1335d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull CHECK(meta.get() != NULL); 1345d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 1355d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull const char *mime; 1365d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull if (!meta->findCString(kKeyMIMEType, &mime)) { 1375d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull continue; 1385d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull } 1395d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 1405d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull if (strncasecmp(mime, "video/", 6)) { 1415d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull continue; 1425d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull } 1435d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 1445d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull source = extractor->getTrack(i); 1455d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull break; 1465d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull } 1475d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 1485d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull return source; 1495d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull} 1505d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 1515d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scullenum { 1525d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull kYUV420SP = 0, 1535d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull kYUV420P = 1, 1545d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull}; 1555d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull 1565d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull// returns -1 if mapping of the given color is unsuccessful 1575d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull// returns an omx color enum value otherwise 1585d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scullstatic int translateColorToOmxEnumValue(int color) { 1595d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull switch (color) { 1605d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull case kYUV420SP: 1615d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull return OMX_COLOR_FormatYUV420SemiPlanar; 1625d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull case kYUV420P: 1635d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull return OMX_COLOR_FormatYUV420Planar; 1645d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull default: 1655d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull fprintf(stderr, "Unsupported color: %d\n", color); 1665d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull return -1; 1675d7027db6e0b82c0ffcb101c3a17997f6aefafc5Andrew Scull } 168} 169 170int main(int argc, char **argv) { 171 android::ProcessState::self()->startThreadPool(); 172 173#if 1 174 if (argc != 3) { 175 fprintf(stderr, "usage: %s <filename> <input_color_format>\n", argv[0]); 176 fprintf(stderr, " <input_color_format>: 0 (YUV420SP) or 1 (YUV420P)\n"); 177 return 1; 178 } 179 180 int colorFormat = translateColorToOmxEnumValue(atoi(argv[2])); 181 if (colorFormat == -1) { 182 fprintf(stderr, "input color format must be 0 (YUV420SP) or 1 (YUV420P)\n"); 183 return 1; 184 } 185 status_t err = OK; 186 187#if 0 188 sp<MediaSource> source = createSource(argv[1]); 189 190 if (source == NULL) { 191 fprintf(stderr, "Unable to find a suitable video track.\n"); 192 return 1; 193 } 194 195 sp<MetaData> meta = source->getFormat(); 196 197 sp<MediaSource> decoder = SimpleDecodingSource::Create(source); 198 199 int width, height; 200 bool success = meta->findInt32(kKeyWidth, &width); 201 success = success && meta->findInt32(kKeyHeight, &height); 202 CHECK(success); 203#else 204 int width = 720; 205 int height = 480; 206 sp<MediaSource> decoder = new DummySource(width, height, colorFormat); 207#endif 208 209 sp<AMessage> enc_meta = new AMessage; 210 // enc_meta->setString("mime", MEDIA_MIMETYPE_VIDEO_H263); 211 // enc_meta->setString("mime", MEDIA_MIMETYPE_VIDEO_MPEG4); 212 enc_meta->setString("mime", MEDIA_MIMETYPE_VIDEO_AVC); 213 enc_meta->setInt32("width", width); 214 enc_meta->setInt32("height", height); 215 enc_meta->setInt32("sample-rate", kFramerate); 216 enc_meta->setInt32("bitrate", kVideoBitRate); 217 // enc_meta->setInt32("stride", width); 218 // enc_meta->setInt32("slice-height", height); 219 enc_meta->setInt32("i-frame-interval", kIFramesIntervalSec); 220 enc_meta->setInt32("color-format", colorFormat); 221 222 sp<MediaSource> encoder = 223 MediaCodecSource::Create(looper, format, decoder); 224 225#if 1 226 sp<MPEG4Writer> writer = new MPEG4Writer("/sdcard/output.mp4"); 227 writer->addSource(encoder); 228 writer->setMaxFileDuration(kDurationUs); 229 CHECK_EQ((status_t)OK, writer->start()); 230 while (!writer->reachedEOS()) { 231 fprintf(stderr, "."); 232 usleep(100000); 233 } 234 err = writer->stop(); 235#else 236 CHECK_EQ((status_t)OK, encoder->start()); 237 238 MediaBuffer *buffer; 239 while (encoder->read(&buffer) == OK) { 240 printf("."); 241 fflush(stdout); 242 int32_t isSync; 243 if (!buffer->meta_data()->findInt32(kKeyIsSyncFrame, &isSync)) { 244 isSync = false; 245 } 246 247 printf("got an output frame of size %d%s\n", buffer->range_length(), 248 isSync ? " (SYNC)" : ""); 249 250 buffer->release(); 251 buffer = NULL; 252 } 253 254 err = encoder->stop(); 255#endif 256 257 printf("$\n"); 258#endif 259 260#if 0 261 CameraSource *source = CameraSource::Create( 262 String16(argv[0], strlen(argv[0]))); 263 source->start(); 264 265 printf("source = %p\n", source); 266 267 for (int i = 0; i < 100; ++i) { 268 MediaBuffer *buffer; 269 status_t err = source->read(&buffer); 270 CHECK_EQ(err, (status_t)OK); 271 272 printf("got a frame, data=%p, size=%d\n", 273 buffer->data(), buffer->range_length()); 274 275 buffer->release(); 276 buffer = NULL; 277 } 278 279 err = source->stop(); 280 281 delete source; 282 source = NULL; 283#endif 284 285 if (err != OK && err != ERROR_END_OF_STREAM) { 286 fprintf(stderr, "record failed: %d\n", err); 287 return 1; 288 } 289 return 0; 290} 291#else 292 293int main(int /* argc */, char ** /* argv */) { 294 android::ProcessState::self()->startThreadPool(); 295 296 const int32_t kSampleRate = 22050; 297 const int32_t kNumChannels = 2; 298 sp<MediaSource> audioSource = new SineSource(kSampleRate, kNumChannels); 299 300#if 0 301 sp<MediaPlayerBase::AudioSink> audioSink; 302 AudioPlayer *player = new AudioPlayer(audioSink); 303 player->setSource(audioSource); 304 player->start(); 305 306 sleep(10); 307 308 player->stop(); 309#endif 310 311 sp<AMessage> encMeta = new AMessage; 312 encMeta->setString("mime", 313 0 ? MEDIA_MIMETYPE_AUDIO_AMR_WB : MEDIA_MIMETYPE_AUDIO_AAC); 314 encMeta->setInt32("sample-rate", kSampleRate); 315 encMeta->setInt32("channel-count", kNumChannels); 316 encMeta->setInt32("max-input-size", 8192); 317 encMeta->setInt32("bitrate", kAudioBitRate); 318 319 sp<ALooper> looper = new ALooper; 320 looper->setName("record"); 321 looper->start(); 322 323 sp<IMediaSource> encoder = 324 MediaCodecSource::Create(looper, encMeta, audioSource); 325 326 encoder->start(); 327 328 int32_t n = 0; 329 status_t err; 330 MediaBuffer *buffer; 331 while ((err = encoder->read(&buffer)) == OK) { 332 printf("."); 333 fflush(stdout); 334 335 buffer->release(); 336 buffer = NULL; 337 338 if (++n == 100) { 339 break; 340 } 341 } 342 printf("$\n"); 343 344 encoder->stop(); 345 346 return 0; 347} 348#endif 349