Merge "Whitespace"
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index e41b666..30be7fa 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -7,7 +7,7 @@
SineSource.cpp
LOCAL_SHARED_LIBRARIES := \
- libstagefright libmedia libutils libbinder libstagefright_foundation \
+ libstagefright libmedia libmedia_native libutils libbinder libstagefright_foundation \
libskia libgui
LOCAL_C_INCLUDES:= \
@@ -108,7 +108,7 @@
LOCAL_SHARED_LIBRARIES := \
libstagefright liblog libutils libbinder libgui \
- libstagefright_foundation libmedia
+ libstagefright_foundation libmedia libmedia_native
LOCAL_C_INCLUDES:= \
$(JNI_H_INCLUDE) \
@@ -132,7 +132,7 @@
LOCAL_SHARED_LIBRARIES := \
libstagefright liblog libutils libbinder libstagefright_foundation \
- libmedia libgui libcutils libui
+ libmedia libmedia_native libgui libcutils libui
LOCAL_C_INCLUDES:= \
$(JNI_H_INCLUDE) \
@@ -157,7 +157,7 @@
LOCAL_SHARED_LIBRARIES := \
libstagefright liblog libutils libbinder libstagefright_foundation \
- libmedia libgui libcutils libui
+ libmedia libmedia_native libgui libcutils libui
LOCAL_C_INCLUDES:= \
$(JNI_H_INCLUDE) \
diff --git a/cmds/stagefright/SimplePlayer.cpp b/cmds/stagefright/SimplePlayer.cpp
index fac3a8c..0cfeb3e 100644
--- a/cmds/stagefright/SimplePlayer.cpp
+++ b/cmds/stagefright/SimplePlayer.cpp
@@ -583,8 +583,7 @@
AUDIO_STREAM_MUSIC,
sampleRate,
AUDIO_FORMAT_PCM_16_BIT,
- (channelCount == 1)
- ? AUDIO_CHANNEL_OUT_MONO : AUDIO_CHANNEL_OUT_STEREO,
+ audio_channel_out_mask_from_count(channelCount),
0);
state->mNumFramesWritten = 0;
diff --git a/cmds/stagefright/audioloop.cpp b/cmds/stagefright/audioloop.cpp
index a6362a4..ed7d6cb 100644
--- a/cmds/stagefright/audioloop.cpp
+++ b/cmds/stagefright/audioloop.cpp
@@ -32,9 +32,7 @@
sp<MediaSource> source = new AudioSource(
AUDIO_SOURCE_DEFAULT,
kSampleRate,
- kNumChannels == 1
- ? AUDIO_CHANNEL_IN_MONO
- : AUDIO_CHANNEL_IN_STEREO);
+ audio_channel_in_mask_from_count(kNumChannels));
#endif
sp<MetaData> meta = new MetaData;
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index 8b4b8ed..00b8679 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -70,6 +70,8 @@
kKeyThumbnailTime = 'thbT', // int64_t (usecs)
kKeyTrackID = 'trID',
kKeyIsDRM = 'idrm', // int32_t (bool)
+ kKeyEncoderDelay = 'encd', // int32_t (frames)
+ kKeyEncoderPadding = 'encp', // int32_t (frames)
kKeyAlbum = 'albu', // cstring
kKeyArtist = 'arti', // cstring
diff --git a/media/libaah_rtp/Android.mk b/media/libaah_rtp/Android.mk
index 1e87cf0..6c927ba 100644
--- a/media/libaah_rtp/Android.mk
+++ b/media/libaah_rtp/Android.mk
@@ -29,6 +29,7 @@
libcommon_time_client \
libbinder \
libmedia \
+ libmedia_native \
libstagefright \
libstagefright_foundation \
libutils
@@ -37,4 +38,3 @@
-lpthread
include $(BUILD_SHARED_LIBRARY)
-
diff --git a/media/libaah_rtp/aah_decoder_pump.cpp b/media/libaah_rtp/aah_decoder_pump.cpp
index 28b8c7b..bebba54 100644
--- a/media/libaah_rtp/aah_decoder_pump.cpp
+++ b/media/libaah_rtp/aah_decoder_pump.cpp
@@ -105,9 +105,8 @@
AudioTrack::getMinFrameCount(&frameCount,
AUDIO_STREAM_DEFAULT,
static_cast<int>(format_sample_rate_));
- int ch_format = (format_channels_ == 1)
- ? AUDIO_CHANNEL_OUT_MONO
- : AUDIO_CHANNEL_OUT_STEREO;
+ audio_channel_mask_t ch_format =
+ audio_channel_out_mask_from_count(format_channels_);
res = renderer_->set(AUDIO_STREAM_DEFAULT,
format_sample_rate_,
diff --git a/media/libaah_rtp/aah_decoder_pump.h b/media/libaah_rtp/aah_decoder_pump.h
index f5a6529..4d57e49 100644
--- a/media/libaah_rtp/aah_decoder_pump.h
+++ b/media/libaah_rtp/aah_decoder_pump.h
@@ -75,7 +75,7 @@
void stopAndCleanupRenderer();
sp<MetaData> format_;
- int32_t format_channels_;
+ int32_t format_channels_; // channel count, not channel mask
int32_t format_sample_rate_;
sp<MediaSource> decoder_;
diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp
index dc27d38..1d76f62 100755
--- a/media/libeffects/preprocessing/PreProcessing.cpp
+++ b/media/libeffects/preprocessing/PreProcessing.cpp
@@ -956,10 +956,9 @@
memset(config, 0, sizeof(effect_config_t));
config->inputCfg.samplingRate = config->outputCfg.samplingRate = session->samplingRate;
config->inputCfg.format = config->outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
- config->inputCfg.channels = session->inChannelCount == 1 ?
- AUDIO_CHANNEL_IN_MONO : AUDIO_CHANNEL_IN_STEREO;
- config->outputCfg.channels = session->outChannelCount == 1 ?
- AUDIO_CHANNEL_IN_MONO : AUDIO_CHANNEL_IN_STEREO;
+ config->inputCfg.channels = audio_channel_in_mask_from_count(session->inChannelCount);
+ // "out" doesn't mean output device, so this is the correct API to convert channel count to mask
+ config->outputCfg.channels = audio_channel_in_mask_from_count(session->outChannelCount);
config->inputCfg.mask = config->outputCfg.mask =
(EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT);
}
@@ -999,7 +998,7 @@
config->inputCfg.samplingRate = config->outputCfg.samplingRate = session->samplingRate;
config->inputCfg.format = config->outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
config->inputCfg.channels = config->outputCfg.channels =
- session->revChannelCount == 1 ? AUDIO_CHANNEL_IN_MONO : AUDIO_CHANNEL_IN_STEREO;
+ audio_channel_in_mask_from_count(session->revChannelCount);
config->inputCfg.mask = config->outputCfg.mask =
(EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT);
}
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 8b009aa..21e8f29 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -48,7 +48,7 @@
LOCAL_SHARED_LIBRARIES := \
libui libcutils libutils libbinder libsonivox libicuuc libexpat \
libcamera_client libstagefright_foundation \
- libgui libdl libaudioutils
+ libgui libdl libaudioutils libmedia_native
LOCAL_WHOLE_STATIC_LIBRARY := libmedia_helper
diff --git a/media/libmedia/JetPlayer.cpp b/media/libmedia/JetPlayer.cpp
index 312a493..f1f62f7 100644
--- a/media/libmedia/JetPlayer.cpp
+++ b/media/libmedia/JetPlayer.cpp
@@ -92,7 +92,7 @@
mAudioTrack->set(AUDIO_STREAM_MUSIC, //TODO parametrize this
pLibConfig->sampleRate,
AUDIO_FORMAT_PCM_16_BIT,
- (pLibConfig->numChannels == 2) ? AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO,
+ audio_channel_out_mask_from_count(pLibConfig->numChannels),
mTrackBufferSize,
AUDIO_POLICY_OUTPUT_FLAG_NONE);
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index 41bcab0..ba5c776 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -23,6 +23,7 @@
libvorbisidec \
libsonivox \
libmedia \
+ libmedia_native \
libcamera_client \
libandroid_runtime \
libstagefright \
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 1cc120c..8f62ee4 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1514,7 +1514,7 @@
frameCount = (sampleRate*afFrameCount*bufferCount)/afSampleRate;
if (channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER) {
- channelMask = audio_channel_mask_from_count(channelCount);
+ channelMask = audio_channel_out_mask_from_count(channelCount);
if (0 == channelMask) {
ALOGE("open() error, can\'t derive mask for %d audio channels", channelCount);
return NO_INIT;
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 047b4cb..77714f3 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -79,6 +79,7 @@
libicuuc \
liblog \
libmedia \
+ libmedia_native \
libsonivox \
libssl \
libstagefright_omx \
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index 9db3c97..0f816e7 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -144,7 +144,7 @@
} else {
// playing to an AudioTrack, set up mask if necessary
audio_channel_mask_t audioMask = channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER ?
- audio_channel_mask_from_count(numChannels) : channelMask;
+ audio_channel_out_mask_from_count(numChannels) : channelMask;
if (0 == audioMask) {
return BAD_VALUE;
}
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index cbe709b..0f1d841 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -47,22 +47,22 @@
}
AudioSource::AudioSource(
- audio_source_t inputSource, uint32_t sampleRate, uint32_t channels)
+ audio_source_t inputSource, uint32_t sampleRate, uint32_t channelCount)
: mStarted(false),
mSampleRate(sampleRate),
mPrevSampleTimeUs(0),
mNumFramesReceived(0),
mNumClientOwnedBuffers(0) {
- ALOGV("sampleRate: %d, channels: %d", sampleRate, channels);
- CHECK(channels == 1 || channels == 2);
+ ALOGV("sampleRate: %d, channelCount: %d", sampleRate, channelCount);
+ CHECK(channelCount == 1 || channelCount == 2);
AudioRecord::record_flags flags = (AudioRecord::record_flags)
(AudioRecord::RECORD_AGC_ENABLE |
AudioRecord::RECORD_NS_ENABLE |
AudioRecord::RECORD_IIR_ENABLE);
mRecord = new AudioRecord(
inputSource, sampleRate, AUDIO_FORMAT_PCM_16_BIT,
- channels > 1? AUDIO_CHANNEL_IN_STEREO: AUDIO_CHANNEL_IN_MONO,
+ audio_channel_in_mask_from_count(channelCount),
4 * kMaxBufferSize / sizeof(int16_t), /* Enable ping-pong buffers */
flags,
AudioRecordCallbackFunction,
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 0d67800..fd3f892 100755
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -515,9 +515,13 @@
return err;
}
- // This CHECK is good, since we just passed the lock/unlock
- // check earlier by calling mCamera->setParameters().
- CHECK_EQ((status_t)OK, mCamera->setPreviewDisplay(mSurface));
+ // Set the preview display. Skip this if mSurface is null because
+ // applications may already set a surface to the camera.
+ if (mSurface != NULL) {
+ // This CHECK is good, since we just passed the lock/unlock
+ // check earlier by calling mCamera->setParameters().
+ CHECK_EQ((status_t)OK, mCamera->setPreviewDisplay(mSurface));
+ }
// By default, do not store metadata in video buffers
mIsMetaDataStoredInVideoBuffers = false;
diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index 69209b5..6abaf23 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -311,10 +311,18 @@
mMeta->setInt32(kKeyBitRate, bitrate * 1000);
mMeta->setInt32(kKeyChannelCount, num_channels);
- mSeeker = XINGSeeker::CreateFromSource(mDataSource, mFirstFramePos);
+ sp<XINGSeeker> seeker = XINGSeeker::CreateFromSource(mDataSource, mFirstFramePos);
- if (mSeeker == NULL) {
+ if (seeker == NULL) {
mSeeker = VBRISeeker::CreateFromSource(mDataSource, post_id3_pos);
+ } else {
+ mSeeker = seeker;
+ int encd = seeker->getEncoderDelay();
+ int encp = seeker->getEncoderPadding();
+ if (encd != 0 || encp != 0) {
+ mMeta->setInt32(kKeyEncoderDelay, encd);
+ mMeta->setInt32(kKeyEncoderPadding, encp);
+ }
}
if (mSeeker != NULL) {
@@ -340,6 +348,37 @@
}
mInitCheck = OK;
+
+ // get iTunes-style gapless info if present
+ ID3 id3(mDataSource);
+ if (id3.isValid()) {
+ ID3::Iterator *com = new ID3::Iterator(id3, "COM");
+ if (com->done()) {
+ delete com;
+ com = new ID3::Iterator(id3, "COMM");
+ }
+ while(!com->done()) {
+ String8 commentdesc;
+ String8 commentvalue;
+ com->getString(&commentdesc, &commentvalue);
+ const char * desc = commentdesc.string();
+ const char * value = commentvalue.string();
+
+ // first 3 characters are the language, which we don't care about
+ if(strlen(desc) > 3 && strcmp(desc + 3, "iTunSMPB") == 0) {
+
+ int32_t delay, padding;
+ if (sscanf(value, " %*x %x %x %*x", &delay, &padding) == 2) {
+ mMeta->setInt32(kKeyEncoderDelay, delay);
+ mMeta->setInt32(kKeyEncoderPadding, padding);
+ }
+ break;
+ }
+ com->next();
+ }
+ delete com;
+ com = NULL;
+ }
}
size_t MP3Extractor::countTracks() {
diff --git a/media/libstagefright/XINGSeeker.cpp b/media/libstagefright/XINGSeeker.cpp
index 8c99c76..9c91134 100644
--- a/media/libstagefright/XINGSeeker.cpp
+++ b/media/libstagefright/XINGSeeker.cpp
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+#define LOG_TAG "XINGSEEKER"
+#include <utils/Log.h>
+
#include "include/XINGSeeker.h"
#include "include/avc_utils.h"
@@ -24,7 +27,9 @@
XINGSeeker::XINGSeeker()
: mDurationUs(-1),
- mSizeBytes(0) {
+ mSizeBytes(0),
+ mEncoderDelay(0),
+ mEncoderPadding(0) {
}
bool XINGSeeker::getDuration(int64_t *durationUs) {
@@ -76,8 +81,6 @@
seeker->mFirstFramePos = first_frame_pos;
- ALOGI("xingseeker first frame pos: %lld", first_frame_pos);
-
seeker->mSizeBytes = 0;
seeker->mTOCValid = false;
seeker->mDurationUs = 0;
@@ -111,6 +114,8 @@
else offset += 9;
}
+ int xingbase = offset;
+
if (source->readAt(offset, &buffer, 4) < 4) { // XING header ID
return NULL;
}
@@ -161,10 +166,31 @@
// do something with the quality indicator
offset += 4;
}
+
+ if (source->readAt(xingbase + 0xaf - 0x24, &buffer, 1) < 1) { // encoding flags
+ return false;
+ }
+
+ ALOGV("nogap preceding: %s, nogap continued in next: %s",
+ (buffer[0] & 0x80) ? "true" : "false",
+ (buffer[0] & 0x40) ? "true" : "false");
#endif
+ if (source->readAt(xingbase + 0xb1 - 0x24, &buffer, 3) == 3) {
+ seeker->mEncoderDelay = (buffer[0] << 4) + (buffer[1] >> 4);
+ seeker->mEncoderPadding = ((buffer[1] & 0xf) << 8) + buffer[2];
+ }
+
return seeker;
}
+int32_t XINGSeeker::getEncoderDelay() {
+ return mEncoderDelay;
+}
+
+int32_t XINGSeeker::getEncoderPadding() {
+ return mEncoderPadding;
+}
+
} // namespace android
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index 2e92926..ca14054 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -463,40 +463,65 @@
tmp = NULL;
}
-void ID3::Iterator::getString(String8 *id) const {
+// the 2nd argument is used to get the data following the \0 in a comment field
+void ID3::Iterator::getString(String8 *id, String8 *comment) const {
+ getstring(id, false);
+ if (comment != NULL) {
+ getstring(comment, true);
+ }
+}
+
+// comment fields (COM/COMM) contain an initial short descriptor, followed by \0,
+// followed by more data. The data following the \0 can be retrieved by setting
+// "otherdata" to true.
+void ID3::Iterator::getstring(String8 *id, bool otherdata) const {
id->setTo("");
- if (mFrameData == NULL) {
+ const uint8_t *frameData = mFrameData;
+ if (frameData == NULL) {
return;
}
+ uint8_t encoding = *frameData;
+
if (mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1) {
if (mOffset == 126 || mOffset == 127) {
// Special treatment for the track number and genre.
char tmp[16];
- sprintf(tmp, "%d", (int)*mFrameData);
+ sprintf(tmp, "%d", (int)*frameData);
id->setTo(tmp);
return;
}
- convertISO8859ToString8(mFrameData, mFrameSize, id);
+ convertISO8859ToString8(frameData, mFrameSize, id);
return;
}
size_t n = mFrameSize - getHeaderLength() - 1;
+ if (otherdata) {
+ // skip past the encoding, language, and the 0 separator
+ frameData += 4;
+ int32_t i = n - 4;
+ while(--i >= 0 && *++frameData != 0) ;
+ int skipped = (frameData - mFrameData);
+ if (skipped >= n) {
+ return;
+ }
+ n -= skipped;
+ }
- if (*mFrameData == 0x00) {
+ if (encoding == 0x00) {
// ISO 8859-1
- convertISO8859ToString8(mFrameData + 1, n, id);
- } else if (*mFrameData == 0x03) {
+ convertISO8859ToString8(frameData + 1, n, id);
+ } else if (encoding == 0x03) {
// UTF-8
- id->setTo((const char *)(mFrameData + 1), n);
- } else if (*mFrameData == 0x02) {
+ id->setTo((const char *)(frameData + 1), n);
+ } else if (encoding == 0x02) {
// UTF-16 BE, no byte order mark.
// API wants number of characters, not number of bytes...
int len = n / 2;
- const char16_t *framedata = (const char16_t *) (mFrameData + 1);
+ const char16_t *framedata = (const char16_t *) (frameData + 1);
char16_t *framedatacopy = NULL;
#if BYTE_ORDER == LITTLE_ENDIAN
framedatacopy = new char16_t[len];
@@ -513,7 +538,7 @@
// UCS-2
// API wants number of characters, not number of bytes...
int len = n / 2;
- const char16_t *framedata = (const char16_t *) (mFrameData + 1);
+ const char16_t *framedata = (const char16_t *) (frameData + 1);
char16_t *framedatacopy = NULL;
if (*framedata == 0xfffe) {
// endianness marker doesn't match host endianness, convert
diff --git a/media/libstagefright/include/ID3.h b/media/libstagefright/include/ID3.h
index 98c82a4..8714008 100644
--- a/media/libstagefright/include/ID3.h
+++ b/media/libstagefright/include/ID3.h
@@ -50,7 +50,7 @@
bool done() const;
void getID(String8 *id) const;
- void getString(String8 *s) const;
+ void getString(String8 *s, String8 *ss = NULL) const;
const uint8_t *getData(size_t *length) const;
void next();
@@ -65,6 +65,7 @@
void findFrame();
size_t getHeaderLength() const;
+ void getstring(String8 *s, bool secondhalf) const;
Iterator(const Iterator &);
Iterator &operator=(const Iterator &);
diff --git a/media/libstagefright/include/XINGSeeker.h b/media/libstagefright/include/XINGSeeker.h
index 8510979..c408576 100644
--- a/media/libstagefright/include/XINGSeeker.h
+++ b/media/libstagefright/include/XINGSeeker.h
@@ -31,10 +31,15 @@
virtual bool getDuration(int64_t *durationUs);
virtual bool getOffsetForTime(int64_t *timeUs, off64_t *pos);
+ virtual int32_t getEncoderDelay();
+ virtual int32_t getEncoderPadding();
+
private:
int64_t mFirstFramePos;
int64_t mDurationUs;
int32_t mSizeBytes;
+ int32_t mEncoderDelay;
+ int32_t mEncoderPadding;
// TOC entries in XING header. Skip the first one since it's always 0.
unsigned char mTOC[99];
diff --git a/media/libstagefright/timedtext/TimedText3GPPSource.cpp b/media/libstagefright/timedtext/TimedText3GPPSource.cpp
index c423ef0..4854121 100644
--- a/media/libstagefright/timedtext/TimedText3GPPSource.cpp
+++ b/media/libstagefright/timedtext/TimedText3GPPSource.cpp
@@ -39,19 +39,21 @@
}
status_t TimedText3GPPSource::read(
- int64_t *timeUs, Parcel *parcel, const MediaSource::ReadOptions *options) {
+ int64_t *startTimeUs, int64_t *endTimeUs, Parcel *parcel,
+ const MediaSource::ReadOptions *options) {
MediaBuffer *textBuffer = NULL;
status_t err = mSource->read(&textBuffer, options);
if (err != OK) {
return err;
}
CHECK(textBuffer != NULL);
- textBuffer->meta_data()->findInt64(kKeyTime, timeUs);
- // TODO: this is legacy code. when 'timeUs' can be <= 0?
- if (*timeUs > 0) {
- extractAndAppendLocalDescriptions(*timeUs, textBuffer, parcel);
- }
+ textBuffer->meta_data()->findInt64(kKeyTime, startTimeUs);
+ CHECK_GE(*startTimeUs, 0);
+ extractAndAppendLocalDescriptions(*startTimeUs, textBuffer, parcel);
textBuffer->release();
+ // endTimeUs is a dummy parameter for 3gpp timed text format.
+ // Set a negative value to it to mark it is unavailable.
+ *endTimeUs = -1;
return OK;
}
diff --git a/media/libstagefright/timedtext/TimedText3GPPSource.h b/media/libstagefright/timedtext/TimedText3GPPSource.h
index 4ec3d8a..4170940 100644
--- a/media/libstagefright/timedtext/TimedText3GPPSource.h
+++ b/media/libstagefright/timedtext/TimedText3GPPSource.h
@@ -33,7 +33,8 @@
virtual status_t start() { return mSource->start(); }
virtual status_t stop() { return mSource->stop(); }
virtual status_t read(
- int64_t *timeUs,
+ int64_t *startTimeUs,
+ int64_t *endTimeUs,
Parcel *parcel,
const MediaSource::ReadOptions *options = NULL);
virtual status_t extractGlobalDescriptions(Parcel *parcel);
diff --git a/media/libstagefright/timedtext/TimedTextPlayer.cpp b/media/libstagefright/timedtext/TimedTextPlayer.cpp
index 8717914..917c62a 100644
--- a/media/libstagefright/timedtext/TimedTextPlayer.cpp
+++ b/media/libstagefright/timedtext/TimedTextPlayer.cpp
@@ -31,6 +31,7 @@
namespace android {
static const int64_t kAdjustmentProcessingTimeUs = 100000ll;
+static const int64_t kWaitTimeUsToRetryRead = 100000ll;
TimedTextPlayer::TimedTextPlayer(const wp<MediaPlayerBase> &listener)
: mListener(listener),
@@ -139,13 +140,25 @@
}
void TimedTextPlayer::doRead(MediaSource::ReadOptions* options) {
- int64_t timeUs = 0;
+ int64_t startTimeUs = 0;
+ int64_t endTimeUs = 0;
sp<ParcelEvent> parcelEvent = new ParcelEvent();
- status_t err = mSource->read(&timeUs, &(parcelEvent->parcel), options);
- if (err != OK) {
+ status_t err = mSource->read(&startTimeUs, &endTimeUs,
+ &(parcelEvent->parcel), options);
+ if (err == WOULD_BLOCK) {
+ postTextEventDelayUs(NULL, kWaitTimeUsToRetryRead);
+ return;
+ } else if (err != OK) {
notifyError(err);
- } else {
- postTextEvent(parcelEvent, timeUs);
+ return;
+ }
+
+ postTextEvent(parcelEvent, startTimeUs);
+ if (endTimeUs > 0) {
+ CHECK_GE(endTimeUs, startTimeUs);
+ // send an empty timed text to clear the subtitle when it reaches to the
+ // end time.
+ postTextEvent(NULL, endTimeUs);
}
}
@@ -162,6 +175,13 @@
} else {
delayUs = timeUs - positionUs - kAdjustmentProcessingTimeUs;
}
+ postTextEventDelayUs(parcel, delayUs);
+ }
+}
+
+void TimedTextPlayer::postTextEventDelayUs(const sp<ParcelEvent>& parcel, int64_t delayUs) {
+ sp<MediaPlayerBase> listener = mListener.promote();
+ if (listener != NULL) {
sp<AMessage> msg = new AMessage(kWhatSendSubtitle, id());
msg->setInt32("generation", mSendSubtitleGeneration);
if (parcel != NULL) {
diff --git a/media/libstagefright/timedtext/TimedTextPlayer.h b/media/libstagefright/timedtext/TimedTextPlayer.h
index b869f18..47aff03 100644
--- a/media/libstagefright/timedtext/TimedTextPlayer.h
+++ b/media/libstagefright/timedtext/TimedTextPlayer.h
@@ -67,6 +67,7 @@
void doRead(MediaSource::ReadOptions* options = NULL);
void onTextEvent();
void postTextEvent(const sp<ParcelEvent>& parcel = NULL, int64_t timeUs = -1);
+ void postTextEventDelayUs(const sp<ParcelEvent>& parcel = NULL, int64_t delayUs = -1);
void notifyError(int error = 0);
void notifyListener(const Parcel *parcel = NULL);
diff --git a/media/libstagefright/timedtext/TimedTextSRTSource.cpp b/media/libstagefright/timedtext/TimedTextSRTSource.cpp
index c44a99b..7b1f7f6 100644
--- a/media/libstagefright/timedtext/TimedTextSRTSource.cpp
+++ b/media/libstagefright/timedtext/TimedTextSRTSource.cpp
@@ -19,6 +19,7 @@
#include <utils/Log.h>
#include <binder/Parcel.h>
+#include <media/stagefright/foundation/ADebug.h> // for CHECK_xx
#include <media/stagefright/foundation/AString.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaDefs.h> // for MEDIA_MIMETYPE_xxx
@@ -63,19 +64,18 @@
}
status_t TimedTextSRTSource::read(
- int64_t *timeUs,
+ int64_t *startTimeUs,
+ int64_t *endTimeUs,
Parcel *parcel,
const MediaSource::ReadOptions *options) {
- int64_t endTimeUs;
AString text;
- status_t err = getText(options, &text, timeUs, &endTimeUs);
+ status_t err = getText(options, &text, startTimeUs, endTimeUs);
if (err != OK) {
return err;
}
- if (*timeUs > 0) {
- extractAndAppendLocalDescriptions(*timeUs, text, parcel);
- }
+ CHECK_GE(*startTimeUs, 0);
+ extractAndAppendLocalDescriptions(*startTimeUs, text, parcel);
return OK;
}
diff --git a/media/libstagefright/timedtext/TimedTextSRTSource.h b/media/libstagefright/timedtext/TimedTextSRTSource.h
index 62710a0..e1371b8 100644
--- a/media/libstagefright/timedtext/TimedTextSRTSource.h
+++ b/media/libstagefright/timedtext/TimedTextSRTSource.h
@@ -36,7 +36,8 @@
virtual status_t start();
virtual status_t stop();
virtual status_t read(
- int64_t *timeUs,
+ int64_t *startTimeUs,
+ int64_t *endTimeUs,
Parcel *parcel,
const MediaSource::ReadOptions *options = NULL);
virtual sp<MetaData> getFormat();
diff --git a/media/libstagefright/timedtext/TimedTextSource.h b/media/libstagefright/timedtext/TimedTextSource.h
index 9349342..756cc31 100644
--- a/media/libstagefright/timedtext/TimedTextSource.h
+++ b/media/libstagefright/timedtext/TimedTextSource.h
@@ -43,7 +43,8 @@
virtual status_t stop() = 0;
// Returns subtitle parcel and its start time.
virtual status_t read(
- int64_t *timeUs,
+ int64_t *startTimeUs,
+ int64_t *endTimeUs,
Parcel *parcel,
const MediaSource::ReadOptions *options = NULL) = 0;
virtual status_t extractGlobalDescriptions(Parcel *parcel) {
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 5164213..257f62c 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -15,6 +15,7 @@
$(call include-path-for, audio-effects) \
$(call include-path-for, audio-utils)
+# FIXME keep libmedia_native but remove libmedia after split
LOCAL_SHARED_LIBRARIES := \
libaudioutils \
libcommon_time_client \
@@ -22,6 +23,7 @@
libutils \
libbinder \
libmedia \
+ libmedia_native \
libhardware \
libhardware_legacy \
libeffects \
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 86bb7f9..1dd9a38 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -894,7 +894,8 @@
// indicate output device change to all input threads for pre processing
AudioParameter param = AudioParameter(keyValuePairs);
int value;
- if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) {
+ if ((param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) &&
+ (value != 0)) {
for (size_t i = 0; i < mRecordThreads.size(); i++) {
mRecordThreads.valueAt(i)->setParameters(keyValuePairs);
}
@@ -3793,16 +3794,9 @@
if (!client->reserveTimedTrack())
return NULL;
- sp<TimedTrack> track = new TimedTrack(
+ return new TimedTrack(
thread, client, streamType, sampleRate, format, channelMask, frameCount,
sharedBuffer, sessionId);
-
- if (track == NULL) {
- client->releaseTimedTrack();
- return NULL;
- }
-
- return track;
}
AudioFlinger::PlaybackThread::TimedTrack::TimedTrack(
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk
index e35435e..3cae1f5 100644
--- a/services/camera/libcameraservice/Android.mk
+++ b/services/camera/libcameraservice/Android.mk
@@ -15,6 +15,7 @@
libbinder \
libcutils \
libmedia \
+ libmedia_native \
libcamera_client \
libgui \
libhardware