Loading media/libmediaplayerservice/StagefrightRecorder.cpp +200 −30 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ #include <utils/Errors.h> #include <sys/types.h> #include <unistd.h> #include <ctype.h> namespace android { Loading Loading @@ -149,9 +150,149 @@ status_t StagefrightRecorder::setOutputFile(int fd, int64_t offset, int64_t leng return OK; } status_t StagefrightRecorder::setParameters(const String8 ¶ms) { mParams = params; // Attempt to parse an int64 literal optionally surrounded by whitespace, // returns true on success, false otherwise. static bool safe_strtoi64(const char *s, int32_t *val) { char *end; *val = static_cast<int32_t>(strtoll(s, &end, 10)); if (end == s || errno == ERANGE) { return false; } // Skip trailing whitespace while (isspace(*end)) { ++end; } // For a successful return, the string must contain nothing but a valid // int64 literal optionally surrounded by whitespace. return *end == '\0'; } // Trim both leading and trailing whitespace from the given string. static void TrimString(String8 *s) { size_t num_bytes = s->bytes(); const char *data = s->string(); size_t leading_space = 0; while (leading_space < num_bytes && isspace(data[leading_space])) { ++leading_space; } size_t i = num_bytes; while (i > leading_space && isspace(data[i - 1])) { --i; } s->setTo(String8(&data[leading_space], i - leading_space)); } status_t StagefrightRecorder::setParamAudioSamplingRate(int32_t sampleRate) { LOGV("setParamAudioSamplingRate: %d", sampleRate); mSampleRate = sampleRate; return OK; } status_t StagefrightRecorder::setParamAudioNumberOfChannels(int32_t channels) { LOGV("setParamAudioNumberOfChannels: %d", channels); mAudioChannels = channels; return OK; } status_t StagefrightRecorder::setParamAudioEncodingBitRate(int32_t bitRate) { LOGV("setParamAudioEncodingBitRate: %d", bitRate); mAudioBitRate = bitRate; return OK; } status_t StagefrightRecorder::setParamVideoEncodingBitRate(int32_t bitRate) { LOGV("setParamVideoEncodingBitRate: %d", bitRate); mVideoBitRate = bitRate; return OK; } status_t StagefrightRecorder::setMaxDurationOrFileSize(int32_t limit, bool limit_is_duration) { LOGV("setMaxDurationOrFileSize: limit (%d) for %s", limit, limit_is_duration?"duration":"size"); return OK; } status_t StagefrightRecorder::setParameter( const String8 &key, const String8 &value) { LOGV("setParameter: key (%s) => value (%s)", key.string(), value.string()); if (key == "max-duration") { int32_t max_duration_ms; if (safe_strtoi64(value.string(), &max_duration_ms)) { return setMaxDurationOrFileSize( max_duration_ms, true /* limit_is_duration */); } } else if (key == "max-filesize") { int32_t max_filesize_bytes; if (safe_strtoi64(value.string(), &max_filesize_bytes)) { return setMaxDurationOrFileSize( max_filesize_bytes, false /* limit is filesize */); } } else if (key == "audio-param-sampling-rate") { int32_t sampling_rate; if (safe_strtoi64(value.string(), &sampling_rate)) { return setParamAudioSamplingRate(sampling_rate); } } else if (key == "audio-param-number-of-channels") { int32_t number_of_channels; if (safe_strtoi64(value.string(), &number_of_channels)) { return setParamAudioNumberOfChannels(number_of_channels); } } else if (key == "audio-param-encoding-bitrate") { int32_t audio_bitrate; if (safe_strtoi64(value.string(), &audio_bitrate)) { return setParamAudioEncodingBitRate(audio_bitrate); } } else if (key == "video-param-encoding-bitrate") { int32_t video_bitrate; if (safe_strtoi64(value.string(), &video_bitrate)) { return setParamVideoEncodingBitRate(video_bitrate); } } else { LOGE("setParameter: failed to find key %s", key.string()); return BAD_VALUE; } return OK; } status_t StagefrightRecorder::setParameters(const String8 ¶ms) { LOGV("setParameters: %s", params.string()); const char *cparams = params.string(); const char *key_start = cparams; for (;;) { const char *equal_pos = strchr(key_start, '='); if (equal_pos == NULL) { LOGE("Parameters %s miss a value", cparams); return BAD_VALUE; } String8 key(key_start, equal_pos - key_start); TrimString(&key); if (key.length() == 0) { LOGE("Parameters %s contains an empty key", cparams); return BAD_VALUE; } const char *value_start = equal_pos + 1; const char *semicolon_pos = strchr(value_start, ';'); String8 value; if (semicolon_pos == NULL) { value.setTo(value_start); } else { value.setTo(value_start, semicolon_pos - value_start); } if (setParameter(key, value) != OK) { return BAD_VALUE; } if (semicolon_pos == NULL) { break; // Reaches the end } key_start = semicolon_pos + 1; } return OK; } Loading Loading @@ -185,35 +326,46 @@ status_t StagefrightRecorder::start() { } } sp<MediaSource> StagefrightRecorder::createAMRAudioSource() { uint32_t sampleRate = mAudioEncoder == AUDIO_ENCODER_AMR_NB ? 8000 : 16000; sp<MediaSource> StagefrightRecorder::createAudioSource() { sp<AudioSource> audioSource = new AudioSource( mAudioSource, sampleRate, mSampleRate, AudioSystem::CHANNEL_IN_MONO); status_t err = audioSource->initCheck(); if (err != OK) { LOGE("audio source is not initialized"); return NULL; } sp<MetaData> encMeta = new MetaData; encMeta->setCString( kKeyMIMEType, mAudioEncoder == AUDIO_ENCODER_AMR_NB ? MEDIA_MIMETYPE_AUDIO_AMR_NB : MEDIA_MIMETYPE_AUDIO_AMR_WB); const char *mime; switch (mAudioEncoder) { case AUDIO_ENCODER_AMR_NB: case AUDIO_ENCODER_DEFAULT: mime = MEDIA_MIMETYPE_AUDIO_AMR_NB; break; case AUDIO_ENCODER_AMR_WB: mime = MEDIA_MIMETYPE_AUDIO_AMR_WB; break; case AUDIO_ENCODER_AAC: mime = MEDIA_MIMETYPE_AUDIO_AAC; break; default: LOGE("Unknown audio encoder: %d", mAudioEncoder); return NULL; } encMeta->setCString(kKeyMIMEType, mime); int32_t maxInputSize; CHECK(audioSource->getFormat()->findInt32( kKeyMaxInputSize, &maxInputSize)); encMeta->setInt32(kKeyMaxInputSize, maxInputSize); encMeta->setInt32(kKeyChannelCount, 1); encMeta->setInt32(kKeySampleRate, sampleRate); encMeta->setInt32(kKeyChannelCount, mAudioChannels); encMeta->setInt32(kKeySampleRate, mSampleRate); OMXClient client; CHECK_EQ(client.connect(), OK); Loading @@ -240,7 +392,7 @@ status_t StagefrightRecorder::startAMRRecording() { return UNKNOWN_ERROR; } sp<MediaSource> audioEncoder = createAMRAudioSource(); sp<MediaSource> audioEncoder = createAudioSource(); if (audioEncoder == NULL) { return UNKNOWN_ERROR; Loading @@ -257,6 +409,26 @@ status_t StagefrightRecorder::startAMRRecording() { status_t StagefrightRecorder::startMPEG4Recording() { mWriter = new MPEG4Writer(dup(mOutputFd)); // Add audio source first if it exists if (mAudioSource != AUDIO_SOURCE_LIST_END) { sp<MediaSource> audioEncoder; switch(mAudioEncoder) { case AUDIO_ENCODER_AMR_NB: case AUDIO_ENCODER_AMR_WB: case AUDIO_ENCODER_AAC: audioEncoder = createAudioSource(); break; default: LOGE("Unsupported audio encoder: %d", mAudioEncoder); return UNKNOWN_ERROR; } if (audioEncoder == NULL) { return UNKNOWN_ERROR; } mWriter->addSource(audioEncoder); } if (mVideoSource == VIDEO_SOURCE_DEFAULT || mVideoSource == VIDEO_SOURCE_CAMERA) { CHECK(mCamera != NULL); Loading Loading @@ -308,16 +480,6 @@ status_t StagefrightRecorder::startMPEG4Recording() { mWriter->addSource(encoder); } if (mAudioSource != AUDIO_SOURCE_LIST_END) { sp<MediaSource> audioEncoder = createAMRAudioSource(); if (audioEncoder == NULL) { return UNKNOWN_ERROR; } mWriter->addSource(audioEncoder); } mWriter->start(); return OK; } Loading Loading @@ -353,14 +515,22 @@ status_t StagefrightRecorder::close() { status_t StagefrightRecorder::reset() { stop(); // No audio or video source by default mAudioSource = AUDIO_SOURCE_LIST_END; mVideoSource = VIDEO_SOURCE_LIST_END; mOutputFormat = OUTPUT_FORMAT_LIST_END; mAudioEncoder = AUDIO_ENCODER_LIST_END; mVideoEncoder = VIDEO_ENCODER_LIST_END; mVideoWidth = -1; mVideoHeight = -1; mFrameRate = -1; // Default parameters mOutputFormat = OUTPUT_FORMAT_THREE_GPP; mAudioEncoder = AUDIO_ENCODER_AMR_NB; mVideoEncoder = VIDEO_ENCODER_H263; mVideoWidth = 176; mVideoHeight = 144; mFrameRate = 20; mVideoBitRate = 192000; mSampleRate = 8000; mAudioChannels = 1; mAudioBitRate = 12200; mOutputFd = -1; mFlags = 0; Loading media/libmediaplayerservice/StagefrightRecorder.h +14 −3 Original line number Diff line number Diff line Loading @@ -68,15 +68,26 @@ private: output_format mOutputFormat; audio_encoder mAudioEncoder; video_encoder mVideoEncoder; int mVideoWidth, mVideoHeight; int mFrameRate; int32_t mVideoWidth, mVideoHeight; int32_t mFrameRate; int32_t mVideoBitRate; int32_t mAudioBitRate; int32_t mAudioChannels; int32_t mSampleRate; String8 mParams; int mOutputFd; int32_t mFlags; status_t startMPEG4Recording(); status_t startAMRRecording(); sp<MediaSource> createAMRAudioSource(); sp<MediaSource> createAudioSource(); status_t setParameter(const String8 &key, const String8 &value); status_t setParamVideoEncodingBitRate(int32_t bitRate); status_t setParamAudioEncodingBitRate(int32_t bitRate); status_t setParamAudioNumberOfChannels(int32_t channles); status_t setParamAudioSamplingRate(int32_t sampleRate); status_t setMaxDurationOrFileSize(int32_t limit, bool limit_is_duration); StagefrightRecorder(const StagefrightRecorder &); StagefrightRecorder &operator=(const StagefrightRecorder &); Loading media/libstagefright/AudioSource.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -14,6 +14,10 @@ * limitations under the License. */ //#define LOG_NDEBUG 0 #define LOG_TAG "AudioSource" #include <utils/Log.h> #include <media/stagefright/AudioSource.h> #include <media/AudioRecord.h> Loading media/libstagefright/MPEG4Writer.cpp +85 −22 Original line number Diff line number Diff line Loading @@ -14,6 +14,10 @@ * limitations under the License. */ //#define LOG_NDEBUG 0 #define LOG_TAG "MPEG4Writer" #include <utils/Log.h> #include <arpa/inet.h> #include <ctype.h> Loading Loading @@ -58,6 +62,8 @@ private: }; List<SampleInfo> mSampleInfos; List<int32_t> mStssTableEntries; void *mCodecSpecificData; size_t mCodecSpecificDataSize; bool mGotAllCodecSpecificData; Loading Loading @@ -522,7 +528,8 @@ void MPEG4Writer::Track::threadEntry() { sp<MetaData> meta = mSource->getFormat(); const char *mime; meta->findCString(kKeyMIMEType, &mime); bool is_mpeg4 = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4); bool is_mpeg4 = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC); bool is_avc = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); int32_t count = 0; Loading Loading @@ -668,6 +675,9 @@ void MPEG4Writer::Track::threadEntry() { info.offset = offset; bool is_audio = !strncasecmp(mime, "audio/", 6); int64_t timestampUs; CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs)); Loading @@ -680,6 +690,12 @@ void MPEG4Writer::Track::threadEntry() { mSampleInfos.push_back(info); int32_t isSync = false; buffer->meta_data()->findInt32(kKeyIsSyncFrame, &isSync); if (isSync) { mStssTableEntries.push_back(mSampleInfos.size()); } // Our timestamp is in ms. buffer->release(); buffer = NULL; } Loading Loading @@ -735,8 +751,8 @@ void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) { success = success && mMeta->findInt32(kKeyHeight, &height); CHECK(success); mOwner->writeInt32(width); mOwner->writeInt32(height); mOwner->writeInt32(width << 16); // 32-bit fixed-point value mOwner->writeInt32(height << 16); // 32-bit fixed-point value } mOwner->endBox(); // tkhd Loading @@ -754,26 +770,15 @@ void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) { mOwner->beginBox("hdlr"); mOwner->writeInt32(0); // version=0, flags=0 mOwner->writeInt32(0); // predefined mOwner->writeFourcc(is_audio ? "soun" : "vide"); mOwner->writeInt32(0); // component type: should be mhlr mOwner->writeFourcc(is_audio ? "soun" : "vide"); // component subtype mOwner->writeInt32(0); // reserved mOwner->writeInt32(0); // reserved mOwner->writeInt32(0); // reserved mOwner->writeCString(""); // name mOwner->writeCString("SoundHandler"); // name mOwner->endBox(); mOwner->beginBox("minf"); mOwner->beginBox("dinf"); mOwner->beginBox("dref"); mOwner->writeInt32(0); // version=0, flags=0 mOwner->writeInt32(1); mOwner->beginBox("url "); mOwner->writeInt32(1); // version=0, flags=1 mOwner->endBox(); // url mOwner->endBox(); // dref mOwner->endBox(); // dinf if (is_audio) { mOwner->beginBox("smhd"); mOwner->writeInt32(0); // version=0, flags=0 Loading @@ -789,6 +794,17 @@ void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) { mOwner->writeInt16(0); mOwner->endBox(); } mOwner->beginBox("dinf"); mOwner->beginBox("dref"); mOwner->writeInt32(0); // version=0, flags=0 mOwner->writeInt32(1); mOwner->beginBox("url "); mOwner->writeInt32(1); // version=0, flags=1 mOwner->endBox(); // url mOwner->endBox(); // dref mOwner->endBox(); // dinf mOwner->endBox(); // minf mOwner->beginBox("stbl"); Loading @@ -802,6 +818,8 @@ void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) { fourcc = "samr"; } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) { fourcc = "sawb"; } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) { fourcc = "mp4a"; } else { LOGE("Unknown mime type '%s'.", mime); CHECK(!"should not be here, unknown mime type."); Loading @@ -810,10 +828,12 @@ void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) { mOwner->beginBox(fourcc); // audio format mOwner->writeInt32(0); // reserved mOwner->writeInt16(0); // reserved mOwner->writeInt16(0); // data ref index mOwner->writeInt16(0x1); // data ref index mOwner->writeInt32(0); // reserved mOwner->writeInt32(0); // reserved mOwner->writeInt16(2); // channel count int32_t nChannels; CHECK_EQ(true, mMeta->findInt32(kKeyChannelCount, &nChannels)); mOwner->writeInt16(nChannels); // channel count mOwner->writeInt16(16); // sample size mOwner->writeInt16(0); // predefined mOwner->writeInt16(0); // reserved Loading @@ -823,6 +843,38 @@ void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) { CHECK(success); mOwner->writeInt32(samplerate << 16); if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) { mOwner->beginBox("esds"); mOwner->writeInt32(0); // version=0, flags=0 mOwner->writeInt8(0x03); // ES_DescrTag mOwner->writeInt8(23 + mCodecSpecificDataSize); mOwner->writeInt16(0x0000);// ES_ID mOwner->writeInt8(0x00); mOwner->writeInt8(0x04); // DecoderConfigDescrTag mOwner->writeInt8(15 + mCodecSpecificDataSize); mOwner->writeInt8(0x40); // objectTypeIndication ISO/IEC 14492-2 mOwner->writeInt8(0x15); // streamType AudioStream mOwner->writeInt16(0x03); // XXX mOwner->writeInt8(0x00); // buffer size 24-bit mOwner->writeInt32(96000); // max bit rate mOwner->writeInt32(96000); // avg bit rate mOwner->writeInt8(0x05); // DecoderSpecificInfoTag mOwner->writeInt8(mCodecSpecificDataSize); mOwner->write(mCodecSpecificData, mCodecSpecificDataSize); static const uint8_t kData2[] = { 0x06, // SLConfigDescriptorTag 0x01, 0x02 }; mOwner->write(kData2, sizeof(kData2)); mOwner->endBox(); // esds } mOwner->endBox(); } else { if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { Loading Loading @@ -943,6 +995,17 @@ void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) { mOwner->endBox(); // stts if (!is_audio) { mOwner->beginBox("stss"); mOwner->writeInt32(0); // version=0, flags=0 mOwner->writeInt32(mStssTableEntries.size()); // number of sync frames for (List<int32_t>::iterator it = mStssTableEntries.begin(); it != mStssTableEntries.end(); ++it) { mOwner->writeInt32(*it); } mOwner->endBox(); // stss } mOwner->beginBox("stsz"); mOwner->writeInt32(0); // version=0, flags=0 mOwner->writeInt32(0); // default sample size Loading @@ -969,7 +1032,7 @@ void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) { mOwner->writeInt32(0); // version=0, flags=0 mOwner->writeInt32(mSampleInfos.size()); for (List<SampleInfo>::iterator it = mSampleInfos.begin(); it != mSampleInfos.end(); ++it, ++n) { it != mSampleInfos.end(); ++it) { mOwner->writeInt64((*it).offset); } mOwner->endBox(); // co64 Loading media/libstagefright/OMXCodec.cpp +77 −3 Original line number Diff line number Diff line Loading @@ -520,6 +520,7 @@ status_t OMXCodec::configureCodec(const sp<MetaData> &meta) { setAACFormat(numChannels, sampleRate); } if (!strncasecmp(mMIME, "video/", 6)) { int32_t width, height; bool success = meta->findInt32(kKeyWidth, &width); Loading Loading @@ -567,7 +568,8 @@ status_t OMXCodec::configureCodec(const sp<MetaData> &meta) { } if (!strcmp(mComponentName, "OMX.TI.AMR.encode") || !strcmp(mComponentName, "OMX.TI.WBAMR.encode")) { || !strcmp(mComponentName, "OMX.TI.WBAMR.encode") || !strcmp(mComponentName, "OMX.TI.AAC.encode")) { setMinBufferSize(kPortIndexOutput, 8192); // XXX } Loading Loading @@ -708,7 +710,7 @@ void OMXCodec::setVideoInputFormat( OMX_COLOR_FORMATTYPE colorFormat = OMX_COLOR_FormatYUV420SemiPlanar; if (!strcasecmp("OMX.TI.Video.encoder", mComponentName)) { colorFormat = OMX_COLOR_FormatYUV420Planar; colorFormat = OMX_COLOR_FormatYCbYCr; } Loading Loading @@ -2127,11 +2129,24 @@ void OMXCodec::setState(State newState) { void OMXCodec::setRawAudioFormat( OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) { // port definition OMX_PARAM_PORTDEFINITIONTYPE def; InitOMXParams(&def); def.nPortIndex = portIndex; status_t err = mOMX->getParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); CHECK_EQ(err, OK); def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)), OK); // pcm param OMX_AUDIO_PARAM_PCMMODETYPE pcmParams; InitOMXParams(&pcmParams); pcmParams.nPortIndex = portIndex; status_t err = mOMX->getParameter( err = mOMX->getParameter( mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); CHECK_EQ(err, OK); Loading Loading @@ -2171,6 +2186,8 @@ void OMXCodec::setAMRFormat(bool isWAMR) { CHECK_EQ(err, OK); def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; // XXX: Select bandmode based on bit rate def.eAMRBandMode = isWAMR ? OMX_AUDIO_AMRBandModeWB0 : OMX_AUDIO_AMRBandModeNB0; Loading @@ -2191,8 +2208,60 @@ void OMXCodec::setAMRFormat(bool isWAMR) { } void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate) { CHECK(numChannels == 1 || numChannels == 2); if (mIsEncoder) { //////////////// input port //////////////////// setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); //////////////// output port //////////////////// // format OMX_AUDIO_PARAM_PORTFORMATTYPE format; format.nPortIndex = kPortIndexOutput; format.nIndex = 0; status_t err = OMX_ErrorNone; while (OMX_ErrorNone == err) { CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format)), OK); if (format.eEncoding == OMX_AUDIO_CodingAAC) { break; } format.nIndex++; } CHECK_EQ(OK, err); CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format)), OK); // port definition OMX_PARAM_PORTDEFINITIONTYPE def; InitOMXParams(&def); def.nPortIndex = kPortIndexOutput; CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)), OK); def.format.audio.bFlagErrorConcealment = OMX_TRUE; def.format.audio.eEncoding = OMX_AUDIO_CodingAAC; CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)), OK); // profile OMX_AUDIO_PARAM_AACPROFILETYPE profile; InitOMXParams(&profile); profile.nPortIndex = kPortIndexOutput; CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)), OK); profile.nChannels = numChannels; profile.eChannelMode = (numChannels == 1? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo); profile.nSampleRate = sampleRate; profile.nBitRate = 96000; // XXX profile.nAudioBandWidth = 0; profile.nFrameLength = 0; profile.nAACtools = OMX_AUDIO_AACToolAll; profile.nAACERtools = OMX_AUDIO_AACERNone; profile.eAACProfile = OMX_AUDIO_AACObjectLC; profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF; CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)), OK); } else { OMX_AUDIO_PARAM_AACPROFILETYPE profile; InitOMXParams(&profile); Loading Loading @@ -2961,6 +3030,11 @@ void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) { } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) { mOutputFormat->setCString( kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); int32_t numChannels, sampleRate; inputFormat->findInt32(kKeyChannelCount, &numChannels); inputFormat->findInt32(kKeySampleRate, &sampleRate); mOutputFormat->setInt32(kKeyChannelCount, numChannels); mOutputFormat->setInt32(kKeySampleRate, sampleRate); } else { CHECK(!"Should not be here. Unknown audio encoding."); } Loading Loading
media/libmediaplayerservice/StagefrightRecorder.cpp +200 −30 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ #include <utils/Errors.h> #include <sys/types.h> #include <unistd.h> #include <ctype.h> namespace android { Loading Loading @@ -149,9 +150,149 @@ status_t StagefrightRecorder::setOutputFile(int fd, int64_t offset, int64_t leng return OK; } status_t StagefrightRecorder::setParameters(const String8 ¶ms) { mParams = params; // Attempt to parse an int64 literal optionally surrounded by whitespace, // returns true on success, false otherwise. static bool safe_strtoi64(const char *s, int32_t *val) { char *end; *val = static_cast<int32_t>(strtoll(s, &end, 10)); if (end == s || errno == ERANGE) { return false; } // Skip trailing whitespace while (isspace(*end)) { ++end; } // For a successful return, the string must contain nothing but a valid // int64 literal optionally surrounded by whitespace. return *end == '\0'; } // Trim both leading and trailing whitespace from the given string. static void TrimString(String8 *s) { size_t num_bytes = s->bytes(); const char *data = s->string(); size_t leading_space = 0; while (leading_space < num_bytes && isspace(data[leading_space])) { ++leading_space; } size_t i = num_bytes; while (i > leading_space && isspace(data[i - 1])) { --i; } s->setTo(String8(&data[leading_space], i - leading_space)); } status_t StagefrightRecorder::setParamAudioSamplingRate(int32_t sampleRate) { LOGV("setParamAudioSamplingRate: %d", sampleRate); mSampleRate = sampleRate; return OK; } status_t StagefrightRecorder::setParamAudioNumberOfChannels(int32_t channels) { LOGV("setParamAudioNumberOfChannels: %d", channels); mAudioChannels = channels; return OK; } status_t StagefrightRecorder::setParamAudioEncodingBitRate(int32_t bitRate) { LOGV("setParamAudioEncodingBitRate: %d", bitRate); mAudioBitRate = bitRate; return OK; } status_t StagefrightRecorder::setParamVideoEncodingBitRate(int32_t bitRate) { LOGV("setParamVideoEncodingBitRate: %d", bitRate); mVideoBitRate = bitRate; return OK; } status_t StagefrightRecorder::setMaxDurationOrFileSize(int32_t limit, bool limit_is_duration) { LOGV("setMaxDurationOrFileSize: limit (%d) for %s", limit, limit_is_duration?"duration":"size"); return OK; } status_t StagefrightRecorder::setParameter( const String8 &key, const String8 &value) { LOGV("setParameter: key (%s) => value (%s)", key.string(), value.string()); if (key == "max-duration") { int32_t max_duration_ms; if (safe_strtoi64(value.string(), &max_duration_ms)) { return setMaxDurationOrFileSize( max_duration_ms, true /* limit_is_duration */); } } else if (key == "max-filesize") { int32_t max_filesize_bytes; if (safe_strtoi64(value.string(), &max_filesize_bytes)) { return setMaxDurationOrFileSize( max_filesize_bytes, false /* limit is filesize */); } } else if (key == "audio-param-sampling-rate") { int32_t sampling_rate; if (safe_strtoi64(value.string(), &sampling_rate)) { return setParamAudioSamplingRate(sampling_rate); } } else if (key == "audio-param-number-of-channels") { int32_t number_of_channels; if (safe_strtoi64(value.string(), &number_of_channels)) { return setParamAudioNumberOfChannels(number_of_channels); } } else if (key == "audio-param-encoding-bitrate") { int32_t audio_bitrate; if (safe_strtoi64(value.string(), &audio_bitrate)) { return setParamAudioEncodingBitRate(audio_bitrate); } } else if (key == "video-param-encoding-bitrate") { int32_t video_bitrate; if (safe_strtoi64(value.string(), &video_bitrate)) { return setParamVideoEncodingBitRate(video_bitrate); } } else { LOGE("setParameter: failed to find key %s", key.string()); return BAD_VALUE; } return OK; } status_t StagefrightRecorder::setParameters(const String8 ¶ms) { LOGV("setParameters: %s", params.string()); const char *cparams = params.string(); const char *key_start = cparams; for (;;) { const char *equal_pos = strchr(key_start, '='); if (equal_pos == NULL) { LOGE("Parameters %s miss a value", cparams); return BAD_VALUE; } String8 key(key_start, equal_pos - key_start); TrimString(&key); if (key.length() == 0) { LOGE("Parameters %s contains an empty key", cparams); return BAD_VALUE; } const char *value_start = equal_pos + 1; const char *semicolon_pos = strchr(value_start, ';'); String8 value; if (semicolon_pos == NULL) { value.setTo(value_start); } else { value.setTo(value_start, semicolon_pos - value_start); } if (setParameter(key, value) != OK) { return BAD_VALUE; } if (semicolon_pos == NULL) { break; // Reaches the end } key_start = semicolon_pos + 1; } return OK; } Loading Loading @@ -185,35 +326,46 @@ status_t StagefrightRecorder::start() { } } sp<MediaSource> StagefrightRecorder::createAMRAudioSource() { uint32_t sampleRate = mAudioEncoder == AUDIO_ENCODER_AMR_NB ? 8000 : 16000; sp<MediaSource> StagefrightRecorder::createAudioSource() { sp<AudioSource> audioSource = new AudioSource( mAudioSource, sampleRate, mSampleRate, AudioSystem::CHANNEL_IN_MONO); status_t err = audioSource->initCheck(); if (err != OK) { LOGE("audio source is not initialized"); return NULL; } sp<MetaData> encMeta = new MetaData; encMeta->setCString( kKeyMIMEType, mAudioEncoder == AUDIO_ENCODER_AMR_NB ? MEDIA_MIMETYPE_AUDIO_AMR_NB : MEDIA_MIMETYPE_AUDIO_AMR_WB); const char *mime; switch (mAudioEncoder) { case AUDIO_ENCODER_AMR_NB: case AUDIO_ENCODER_DEFAULT: mime = MEDIA_MIMETYPE_AUDIO_AMR_NB; break; case AUDIO_ENCODER_AMR_WB: mime = MEDIA_MIMETYPE_AUDIO_AMR_WB; break; case AUDIO_ENCODER_AAC: mime = MEDIA_MIMETYPE_AUDIO_AAC; break; default: LOGE("Unknown audio encoder: %d", mAudioEncoder); return NULL; } encMeta->setCString(kKeyMIMEType, mime); int32_t maxInputSize; CHECK(audioSource->getFormat()->findInt32( kKeyMaxInputSize, &maxInputSize)); encMeta->setInt32(kKeyMaxInputSize, maxInputSize); encMeta->setInt32(kKeyChannelCount, 1); encMeta->setInt32(kKeySampleRate, sampleRate); encMeta->setInt32(kKeyChannelCount, mAudioChannels); encMeta->setInt32(kKeySampleRate, mSampleRate); OMXClient client; CHECK_EQ(client.connect(), OK); Loading @@ -240,7 +392,7 @@ status_t StagefrightRecorder::startAMRRecording() { return UNKNOWN_ERROR; } sp<MediaSource> audioEncoder = createAMRAudioSource(); sp<MediaSource> audioEncoder = createAudioSource(); if (audioEncoder == NULL) { return UNKNOWN_ERROR; Loading @@ -257,6 +409,26 @@ status_t StagefrightRecorder::startAMRRecording() { status_t StagefrightRecorder::startMPEG4Recording() { mWriter = new MPEG4Writer(dup(mOutputFd)); // Add audio source first if it exists if (mAudioSource != AUDIO_SOURCE_LIST_END) { sp<MediaSource> audioEncoder; switch(mAudioEncoder) { case AUDIO_ENCODER_AMR_NB: case AUDIO_ENCODER_AMR_WB: case AUDIO_ENCODER_AAC: audioEncoder = createAudioSource(); break; default: LOGE("Unsupported audio encoder: %d", mAudioEncoder); return UNKNOWN_ERROR; } if (audioEncoder == NULL) { return UNKNOWN_ERROR; } mWriter->addSource(audioEncoder); } if (mVideoSource == VIDEO_SOURCE_DEFAULT || mVideoSource == VIDEO_SOURCE_CAMERA) { CHECK(mCamera != NULL); Loading Loading @@ -308,16 +480,6 @@ status_t StagefrightRecorder::startMPEG4Recording() { mWriter->addSource(encoder); } if (mAudioSource != AUDIO_SOURCE_LIST_END) { sp<MediaSource> audioEncoder = createAMRAudioSource(); if (audioEncoder == NULL) { return UNKNOWN_ERROR; } mWriter->addSource(audioEncoder); } mWriter->start(); return OK; } Loading Loading @@ -353,14 +515,22 @@ status_t StagefrightRecorder::close() { status_t StagefrightRecorder::reset() { stop(); // No audio or video source by default mAudioSource = AUDIO_SOURCE_LIST_END; mVideoSource = VIDEO_SOURCE_LIST_END; mOutputFormat = OUTPUT_FORMAT_LIST_END; mAudioEncoder = AUDIO_ENCODER_LIST_END; mVideoEncoder = VIDEO_ENCODER_LIST_END; mVideoWidth = -1; mVideoHeight = -1; mFrameRate = -1; // Default parameters mOutputFormat = OUTPUT_FORMAT_THREE_GPP; mAudioEncoder = AUDIO_ENCODER_AMR_NB; mVideoEncoder = VIDEO_ENCODER_H263; mVideoWidth = 176; mVideoHeight = 144; mFrameRate = 20; mVideoBitRate = 192000; mSampleRate = 8000; mAudioChannels = 1; mAudioBitRate = 12200; mOutputFd = -1; mFlags = 0; Loading
media/libmediaplayerservice/StagefrightRecorder.h +14 −3 Original line number Diff line number Diff line Loading @@ -68,15 +68,26 @@ private: output_format mOutputFormat; audio_encoder mAudioEncoder; video_encoder mVideoEncoder; int mVideoWidth, mVideoHeight; int mFrameRate; int32_t mVideoWidth, mVideoHeight; int32_t mFrameRate; int32_t mVideoBitRate; int32_t mAudioBitRate; int32_t mAudioChannels; int32_t mSampleRate; String8 mParams; int mOutputFd; int32_t mFlags; status_t startMPEG4Recording(); status_t startAMRRecording(); sp<MediaSource> createAMRAudioSource(); sp<MediaSource> createAudioSource(); status_t setParameter(const String8 &key, const String8 &value); status_t setParamVideoEncodingBitRate(int32_t bitRate); status_t setParamAudioEncodingBitRate(int32_t bitRate); status_t setParamAudioNumberOfChannels(int32_t channles); status_t setParamAudioSamplingRate(int32_t sampleRate); status_t setMaxDurationOrFileSize(int32_t limit, bool limit_is_duration); StagefrightRecorder(const StagefrightRecorder &); StagefrightRecorder &operator=(const StagefrightRecorder &); Loading
media/libstagefright/AudioSource.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -14,6 +14,10 @@ * limitations under the License. */ //#define LOG_NDEBUG 0 #define LOG_TAG "AudioSource" #include <utils/Log.h> #include <media/stagefright/AudioSource.h> #include <media/AudioRecord.h> Loading
media/libstagefright/MPEG4Writer.cpp +85 −22 Original line number Diff line number Diff line Loading @@ -14,6 +14,10 @@ * limitations under the License. */ //#define LOG_NDEBUG 0 #define LOG_TAG "MPEG4Writer" #include <utils/Log.h> #include <arpa/inet.h> #include <ctype.h> Loading Loading @@ -58,6 +62,8 @@ private: }; List<SampleInfo> mSampleInfos; List<int32_t> mStssTableEntries; void *mCodecSpecificData; size_t mCodecSpecificDataSize; bool mGotAllCodecSpecificData; Loading Loading @@ -522,7 +528,8 @@ void MPEG4Writer::Track::threadEntry() { sp<MetaData> meta = mSource->getFormat(); const char *mime; meta->findCString(kKeyMIMEType, &mime); bool is_mpeg4 = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4); bool is_mpeg4 = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC); bool is_avc = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); int32_t count = 0; Loading Loading @@ -668,6 +675,9 @@ void MPEG4Writer::Track::threadEntry() { info.offset = offset; bool is_audio = !strncasecmp(mime, "audio/", 6); int64_t timestampUs; CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs)); Loading @@ -680,6 +690,12 @@ void MPEG4Writer::Track::threadEntry() { mSampleInfos.push_back(info); int32_t isSync = false; buffer->meta_data()->findInt32(kKeyIsSyncFrame, &isSync); if (isSync) { mStssTableEntries.push_back(mSampleInfos.size()); } // Our timestamp is in ms. buffer->release(); buffer = NULL; } Loading Loading @@ -735,8 +751,8 @@ void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) { success = success && mMeta->findInt32(kKeyHeight, &height); CHECK(success); mOwner->writeInt32(width); mOwner->writeInt32(height); mOwner->writeInt32(width << 16); // 32-bit fixed-point value mOwner->writeInt32(height << 16); // 32-bit fixed-point value } mOwner->endBox(); // tkhd Loading @@ -754,26 +770,15 @@ void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) { mOwner->beginBox("hdlr"); mOwner->writeInt32(0); // version=0, flags=0 mOwner->writeInt32(0); // predefined mOwner->writeFourcc(is_audio ? "soun" : "vide"); mOwner->writeInt32(0); // component type: should be mhlr mOwner->writeFourcc(is_audio ? "soun" : "vide"); // component subtype mOwner->writeInt32(0); // reserved mOwner->writeInt32(0); // reserved mOwner->writeInt32(0); // reserved mOwner->writeCString(""); // name mOwner->writeCString("SoundHandler"); // name mOwner->endBox(); mOwner->beginBox("minf"); mOwner->beginBox("dinf"); mOwner->beginBox("dref"); mOwner->writeInt32(0); // version=0, flags=0 mOwner->writeInt32(1); mOwner->beginBox("url "); mOwner->writeInt32(1); // version=0, flags=1 mOwner->endBox(); // url mOwner->endBox(); // dref mOwner->endBox(); // dinf if (is_audio) { mOwner->beginBox("smhd"); mOwner->writeInt32(0); // version=0, flags=0 Loading @@ -789,6 +794,17 @@ void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) { mOwner->writeInt16(0); mOwner->endBox(); } mOwner->beginBox("dinf"); mOwner->beginBox("dref"); mOwner->writeInt32(0); // version=0, flags=0 mOwner->writeInt32(1); mOwner->beginBox("url "); mOwner->writeInt32(1); // version=0, flags=1 mOwner->endBox(); // url mOwner->endBox(); // dref mOwner->endBox(); // dinf mOwner->endBox(); // minf mOwner->beginBox("stbl"); Loading @@ -802,6 +818,8 @@ void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) { fourcc = "samr"; } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) { fourcc = "sawb"; } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) { fourcc = "mp4a"; } else { LOGE("Unknown mime type '%s'.", mime); CHECK(!"should not be here, unknown mime type."); Loading @@ -810,10 +828,12 @@ void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) { mOwner->beginBox(fourcc); // audio format mOwner->writeInt32(0); // reserved mOwner->writeInt16(0); // reserved mOwner->writeInt16(0); // data ref index mOwner->writeInt16(0x1); // data ref index mOwner->writeInt32(0); // reserved mOwner->writeInt32(0); // reserved mOwner->writeInt16(2); // channel count int32_t nChannels; CHECK_EQ(true, mMeta->findInt32(kKeyChannelCount, &nChannels)); mOwner->writeInt16(nChannels); // channel count mOwner->writeInt16(16); // sample size mOwner->writeInt16(0); // predefined mOwner->writeInt16(0); // reserved Loading @@ -823,6 +843,38 @@ void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) { CHECK(success); mOwner->writeInt32(samplerate << 16); if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) { mOwner->beginBox("esds"); mOwner->writeInt32(0); // version=0, flags=0 mOwner->writeInt8(0x03); // ES_DescrTag mOwner->writeInt8(23 + mCodecSpecificDataSize); mOwner->writeInt16(0x0000);// ES_ID mOwner->writeInt8(0x00); mOwner->writeInt8(0x04); // DecoderConfigDescrTag mOwner->writeInt8(15 + mCodecSpecificDataSize); mOwner->writeInt8(0x40); // objectTypeIndication ISO/IEC 14492-2 mOwner->writeInt8(0x15); // streamType AudioStream mOwner->writeInt16(0x03); // XXX mOwner->writeInt8(0x00); // buffer size 24-bit mOwner->writeInt32(96000); // max bit rate mOwner->writeInt32(96000); // avg bit rate mOwner->writeInt8(0x05); // DecoderSpecificInfoTag mOwner->writeInt8(mCodecSpecificDataSize); mOwner->write(mCodecSpecificData, mCodecSpecificDataSize); static const uint8_t kData2[] = { 0x06, // SLConfigDescriptorTag 0x01, 0x02 }; mOwner->write(kData2, sizeof(kData2)); mOwner->endBox(); // esds } mOwner->endBox(); } else { if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { Loading Loading @@ -943,6 +995,17 @@ void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) { mOwner->endBox(); // stts if (!is_audio) { mOwner->beginBox("stss"); mOwner->writeInt32(0); // version=0, flags=0 mOwner->writeInt32(mStssTableEntries.size()); // number of sync frames for (List<int32_t>::iterator it = mStssTableEntries.begin(); it != mStssTableEntries.end(); ++it) { mOwner->writeInt32(*it); } mOwner->endBox(); // stss } mOwner->beginBox("stsz"); mOwner->writeInt32(0); // version=0, flags=0 mOwner->writeInt32(0); // default sample size Loading @@ -969,7 +1032,7 @@ void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) { mOwner->writeInt32(0); // version=0, flags=0 mOwner->writeInt32(mSampleInfos.size()); for (List<SampleInfo>::iterator it = mSampleInfos.begin(); it != mSampleInfos.end(); ++it, ++n) { it != mSampleInfos.end(); ++it) { mOwner->writeInt64((*it).offset); } mOwner->endBox(); // co64 Loading
media/libstagefright/OMXCodec.cpp +77 −3 Original line number Diff line number Diff line Loading @@ -520,6 +520,7 @@ status_t OMXCodec::configureCodec(const sp<MetaData> &meta) { setAACFormat(numChannels, sampleRate); } if (!strncasecmp(mMIME, "video/", 6)) { int32_t width, height; bool success = meta->findInt32(kKeyWidth, &width); Loading Loading @@ -567,7 +568,8 @@ status_t OMXCodec::configureCodec(const sp<MetaData> &meta) { } if (!strcmp(mComponentName, "OMX.TI.AMR.encode") || !strcmp(mComponentName, "OMX.TI.WBAMR.encode")) { || !strcmp(mComponentName, "OMX.TI.WBAMR.encode") || !strcmp(mComponentName, "OMX.TI.AAC.encode")) { setMinBufferSize(kPortIndexOutput, 8192); // XXX } Loading Loading @@ -708,7 +710,7 @@ void OMXCodec::setVideoInputFormat( OMX_COLOR_FORMATTYPE colorFormat = OMX_COLOR_FormatYUV420SemiPlanar; if (!strcasecmp("OMX.TI.Video.encoder", mComponentName)) { colorFormat = OMX_COLOR_FormatYUV420Planar; colorFormat = OMX_COLOR_FormatYCbYCr; } Loading Loading @@ -2127,11 +2129,24 @@ void OMXCodec::setState(State newState) { void OMXCodec::setRawAudioFormat( OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) { // port definition OMX_PARAM_PORTDEFINITIONTYPE def; InitOMXParams(&def); def.nPortIndex = portIndex; status_t err = mOMX->getParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); CHECK_EQ(err, OK); def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)), OK); // pcm param OMX_AUDIO_PARAM_PCMMODETYPE pcmParams; InitOMXParams(&pcmParams); pcmParams.nPortIndex = portIndex; status_t err = mOMX->getParameter( err = mOMX->getParameter( mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams)); CHECK_EQ(err, OK); Loading Loading @@ -2171,6 +2186,8 @@ void OMXCodec::setAMRFormat(bool isWAMR) { CHECK_EQ(err, OK); def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; // XXX: Select bandmode based on bit rate def.eAMRBandMode = isWAMR ? OMX_AUDIO_AMRBandModeWB0 : OMX_AUDIO_AMRBandModeNB0; Loading @@ -2191,8 +2208,60 @@ void OMXCodec::setAMRFormat(bool isWAMR) { } void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate) { CHECK(numChannels == 1 || numChannels == 2); if (mIsEncoder) { //////////////// input port //////////////////// setRawAudioFormat(kPortIndexInput, sampleRate, numChannels); //////////////// output port //////////////////// // format OMX_AUDIO_PARAM_PORTFORMATTYPE format; format.nPortIndex = kPortIndexOutput; format.nIndex = 0; status_t err = OMX_ErrorNone; while (OMX_ErrorNone == err) { CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format)), OK); if (format.eEncoding == OMX_AUDIO_CodingAAC) { break; } format.nIndex++; } CHECK_EQ(OK, err); CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format)), OK); // port definition OMX_PARAM_PORTDEFINITIONTYPE def; InitOMXParams(&def); def.nPortIndex = kPortIndexOutput; CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)), OK); def.format.audio.bFlagErrorConcealment = OMX_TRUE; def.format.audio.eEncoding = OMX_AUDIO_CodingAAC; CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)), OK); // profile OMX_AUDIO_PARAM_AACPROFILETYPE profile; InitOMXParams(&profile); profile.nPortIndex = kPortIndexOutput; CHECK_EQ(mOMX->getParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)), OK); profile.nChannels = numChannels; profile.eChannelMode = (numChannels == 1? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo); profile.nSampleRate = sampleRate; profile.nBitRate = 96000; // XXX profile.nAudioBandWidth = 0; profile.nFrameLength = 0; profile.nAACtools = OMX_AUDIO_AACToolAll; profile.nAACERtools = OMX_AUDIO_AACERNone; profile.eAACProfile = OMX_AUDIO_AACObjectLC; profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF; CHECK_EQ(mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile)), OK); } else { OMX_AUDIO_PARAM_AACPROFILETYPE profile; InitOMXParams(&profile); Loading Loading @@ -2961,6 +3030,11 @@ void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) { } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) { mOutputFormat->setCString( kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); int32_t numChannels, sampleRate; inputFormat->findInt32(kKeyChannelCount, &numChannels); inputFormat->findInt32(kKeySampleRate, &sampleRate); mOutputFormat->setInt32(kKeyChannelCount, numChannels); mOutputFormat->setInt32(kKeySampleRate, sampleRate); } else { CHECK(!"Should not be here. Unknown audio encoding."); } Loading