summaryrefslogtreecommitdiffstats
path: root/media/libstagefright
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright')
-rw-r--r--media/libstagefright/AACExtractor.cpp4
-rw-r--r--media/libstagefright/AACWriter.cpp2
-rw-r--r--media/libstagefright/ACodec.cpp91
-rw-r--r--media/libstagefright/AMRExtractor.cpp6
-rw-r--r--media/libstagefright/AMRWriter.cpp2
-rw-r--r--media/libstagefright/Android.mk12
-rw-r--r--media/libstagefright/AudioPlayer.cpp2
-rw-r--r--media/libstagefright/AudioSource.cpp6
-rw-r--r--media/libstagefright/AwesomePlayer.cpp46
-rw-r--r--media/libstagefright/CameraSource.cpp11
-rw-r--r--media/libstagefright/CameraSourceTimeLapse.cpp5
-rw-r--r--media/libstagefright/DataSource.cpp19
-rw-r--r--media/libstagefright/DataURISource.cpp109
-rw-r--r--media/libstagefright/FLACExtractor.cpp70
-rw-r--r--media/libstagefright/HTTPBase.cpp48
-rw-r--r--media/libstagefright/MP3Extractor.cpp3
-rw-r--r--media/libstagefright/MPEG2TSWriter.cpp5
-rw-r--r--media/libstagefright/MPEG4Extractor.cpp170
-rw-r--r--media/libstagefright/MPEG4Writer.cpp34
-rw-r--r--media/libstagefright/MediaAdapter.cpp4
-rw-r--r--media/libstagefright/MediaCodec.cpp2
-rw-r--r--media/libstagefright/MediaCodecSource.cpp881
-rw-r--r--media/libstagefright/NuCachedSource2.cpp13
-rw-r--r--media/libstagefright/NuMediaExtractor.cpp6
-rw-r--r--media/libstagefright/OggExtractor.cpp10
-rw-r--r--media/libstagefright/SkipCutBuffer.cpp3
-rw-r--r--media/libstagefright/StagefrightMediaScanner.cpp5
-rw-r--r--media/libstagefright/StagefrightMetadataRetriever.cpp7
-rw-r--r--media/libstagefright/SurfaceMediaSource.cpp17
-rw-r--r--media/libstagefright/TimedEventQueue.cpp4
-rw-r--r--media/libstagefright/VBRISeeker.cpp4
-rw-r--r--media/libstagefright/WAVExtractor.cpp4
-rw-r--r--media/libstagefright/avc_utils.cpp9
-rw-r--r--media/libstagefright/chromium_http/Android.mk37
-rw-r--r--media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp355
-rw-r--r--media/libstagefright/chromium_http/DataUriSource.cpp68
-rw-r--r--media/libstagefright/chromium_http/chromium_http_stub.cpp38
-rw-r--r--media/libstagefright/chromium_http/support.cpp559
-rw-r--r--media/libstagefright/chromium_http/support.h178
-rw-r--r--media/libstagefright/chromium_http_stub.cpp102
-rw-r--r--media/libstagefright/codecs/aacdec/Android.mk2
-rw-r--r--media/libstagefright/codecs/aacdec/SoftAAC2.cpp230
-rw-r--r--media/libstagefright/codecs/aacdec/SoftAAC2.h2
-rw-r--r--media/libstagefright/codecs/aacenc/Android.mk6
-rw-r--r--media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp2
-rw-r--r--media/libstagefright/codecs/aacenc/basic_op/oper_32b.c4
-rw-r--r--media/libstagefright/codecs/aacenc/src/aacenc.c8
-rw-r--r--media/libstagefright/codecs/aacenc/src/adj_thr.c2
-rw-r--r--media/libstagefright/codecs/aacenc/src/bitenc.c3
-rw-r--r--media/libstagefright/codecs/aacenc/src/dyn_bits.c3
-rw-r--r--media/libstagefright/codecs/aacenc/src/psy_main.c6
-rw-r--r--media/libstagefright/codecs/aacenc/src/qc_main.c8
-rw-r--r--media/libstagefright/codecs/aacenc/src/tns.c4
-rw-r--r--media/libstagefright/codecs/amrnb/common/Android.mk2
-rw-r--r--media/libstagefright/codecs/amrnb/dec/Android.mk4
-rw-r--r--media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp4
-rw-r--r--media/libstagefright/codecs/amrnb/enc/Android.mk4
-rw-r--r--media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp2
-rw-r--r--media/libstagefright/codecs/amrwb/Android.mk2
-rw-r--r--media/libstagefright/codecs/amrwbenc/Android.mk4
-rw-r--r--media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp2
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/autocorr.c4
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/convolve.c4
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/pitch_f4.c3
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/syn_filt.c4
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c4
-rw-r--r--media/libstagefright/codecs/avc/common/Android.mk2
-rw-r--r--media/libstagefright/codecs/avc/enc/Android.mk4
-rw-r--r--media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp17
-rw-r--r--media/libstagefright/codecs/common/Android.mk2
-rw-r--r--media/libstagefright/codecs/common/cmnMemory.c18
-rw-r--r--media/libstagefright/codecs/flac/enc/Android.mk2
-rw-r--r--media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp21
-rw-r--r--media/libstagefright/codecs/g711/dec/Android.mk2
-rw-r--r--media/libstagefright/codecs/g711/dec/SoftG711.cpp2
-rw-r--r--media/libstagefright/codecs/gsm/dec/Android.mk2
-rw-r--r--media/libstagefright/codecs/gsm/dec/SoftGSM.cpp2
-rw-r--r--media/libstagefright/codecs/m4v_h263/dec/Android.mk4
-rw-r--r--media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp2
-rw-r--r--media/libstagefright/codecs/m4v_h263/enc/Android.mk4
-rw-r--r--media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp4
-rw-r--r--media/libstagefright/codecs/mp3dec/Android.mk4
-rw-r--r--media/libstagefright/codecs/mp3dec/SoftMP3.cpp119
-rw-r--r--media/libstagefright/codecs/mp3dec/SoftMP3.h2
-rw-r--r--media/libstagefright/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.cpp2
-rw-r--r--media/libstagefright/codecs/on2/dec/Android.mk2
-rw-r--r--media/libstagefright/codecs/on2/dec/SoftVPX.cpp2
-rw-r--r--media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp2
-rw-r--r--media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c3
-rwxr-xr-xmedia/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c2
-rwxr-xr-xmedia/libstagefright/codecs/on2/h264dec/source/h264bsd_reconstruct.c5
-rwxr-xr-xmedia/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_header.c3
-rwxr-xr-xmedia/libstagefright/codecs/on2/h264dec/source/h264bsd_util.c2
-rw-r--r--media/libstagefright/codecs/raw/Android.mk2
-rw-r--r--media/libstagefright/codecs/raw/SoftRaw.cpp2
-rw-r--r--media/libstagefright/codecs/vorbis/dec/Android.mk2
-rw-r--r--media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp79
-rw-r--r--media/libstagefright/codecs/vorbis/dec/SoftVorbis.h2
-rw-r--r--media/libstagefright/foundation/ANetworkSession.cpp2
-rw-r--r--media/libstagefright/foundation/Android.mk2
-rw-r--r--media/libstagefright/foundation/base64.cpp6
-rw-r--r--media/libstagefright/http/Android.mk28
-rw-r--r--media/libstagefright/http/HTTPHelper.cpp70
-rw-r--r--media/libstagefright/http/HTTPHelper.h (renamed from media/libstagefright/include/chromium_http_stub.h)23
-rw-r--r--media/libstagefright/http/MediaHTTP.cpp201
-rw-r--r--media/libstagefright/httplive/Android.mk2
-rw-r--r--media/libstagefright/httplive/LiveSession.cpp19
-rw-r--r--media/libstagefright/httplive/LiveSession.h7
-rw-r--r--media/libstagefright/httplive/M3UParser.cpp6
-rw-r--r--media/libstagefright/httplive/PlaylistFetcher.cpp137
-rw-r--r--media/libstagefright/httplive/PlaylistFetcher.h7
-rw-r--r--media/libstagefright/id3/Android.mk4
-rw-r--r--media/libstagefright/id3/ID3.cpp79
-rw-r--r--media/libstagefright/include/AwesomePlayer.h3
-rw-r--r--media/libstagefright/include/ChromiumHTTPDataSource.h125
-rw-r--r--media/libstagefright/include/FragmentedMP4Parser.h274
-rw-r--r--media/libstagefright/include/HTTPBase.h11
-rw-r--r--media/libstagefright/include/SDPLoader.h8
-rw-r--r--media/libstagefright/include/StagefrightMetadataRetriever.h1
-rw-r--r--media/libstagefright/include/TimedEventQueue.h2
-rw-r--r--media/libstagefright/matroska/Android.mk2
-rw-r--r--media/libstagefright/matroska/MatroskaExtractor.cpp84
-rw-r--r--media/libstagefright/mp4/FragmentedMP4Parser.cpp1993
-rw-r--r--media/libstagefright/mp4/TrackFragment.cpp364
-rw-r--r--media/libstagefright/mp4/TrackFragment.h122
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.cpp4
-rw-r--r--media/libstagefright/mpeg2ts/Android.mk2
-rw-r--r--media/libstagefright/mpeg2ts/AnotherPacketSource.cpp50
-rw-r--r--media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp5
-rw-r--r--media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp2
-rw-r--r--media/libstagefright/omx/GraphicBufferSource.cpp128
-rw-r--r--media/libstagefright/omx/GraphicBufferSource.h30
-rw-r--r--media/libstagefright/omx/OMX.cpp4
-rw-r--r--media/libstagefright/omx/OMXNodeInstance.cpp52
-rw-r--r--media/libstagefright/omx/SoftOMXComponent.cpp40
-rw-r--r--media/libstagefright/omx/SoftOMXPlugin.cpp2
-rw-r--r--media/libstagefright/omx/tests/Android.mk2
-rw-r--r--media/libstagefright/omx/tests/OMXHarness.cpp4
-rw-r--r--media/libstagefright/rtsp/AMPEG2TSAssembler.cpp4
-rw-r--r--media/libstagefright/rtsp/APacketSource.cpp2
-rw-r--r--media/libstagefright/rtsp/ARTPWriter.cpp2
-rw-r--r--media/libstagefright/rtsp/ARTSPConnection.cpp2
-rw-r--r--media/libstagefright/rtsp/ARawAudioAssembler.cpp4
-rw-r--r--media/libstagefright/rtsp/Android.mk4
-rw-r--r--media/libstagefright/rtsp/MyHandler.h18
-rw-r--r--media/libstagefright/rtsp/SDPLoader.cpp25
-rw-r--r--media/libstagefright/tests/SurfaceMediaSource_test.cpp12
-rw-r--r--media/libstagefright/timedtext/Android.mk3
-rw-r--r--media/libstagefright/timedtext/TimedTextDriver.cpp7
-rw-r--r--media/libstagefright/timedtext/TimedTextSource.h2
-rw-r--r--media/libstagefright/timedtext/test/Android.mk8
-rw-r--r--media/libstagefright/wifi-display/rtp/RTPSender.cpp5
-rw-r--r--media/libstagefright/wifi-display/source/PlaybackSession.cpp4
-rw-r--r--media/libstagefright/wifi-display/source/RepeaterSource.cpp3
-rw-r--r--media/libstagefright/wifi-display/source/TSPacketizer.cpp2
-rw-r--r--media/libstagefright/wifi-display/source/WifiDisplaySource.cpp8
-rw-r--r--media/libstagefright/yuv/Android.mk2
-rw-r--r--media/libstagefright/yuv/YUVImage.cpp12
158 files changed, 2709 insertions, 4924 deletions
diff --git a/media/libstagefright/AACExtractor.cpp b/media/libstagefright/AACExtractor.cpp
index 4d1072f..196f6ee 100644
--- a/media/libstagefright/AACExtractor.cpp
+++ b/media/libstagefright/AACExtractor.cpp
@@ -219,7 +219,7 @@ sp<MediaSource> AACExtractor::getTrack(size_t index) {
return new AACSource(mDataSource, mMeta, mOffsetVector, mFrameDurationUs);
}
-sp<MetaData> AACExtractor::getTrackMetaData(size_t index, uint32_t flags) {
+sp<MetaData> AACExtractor::getTrackMetaData(size_t index, uint32_t /* flags */) {
if (mInitCheck != OK || index != 0) {
return NULL;
}
@@ -252,7 +252,7 @@ AACSource::~AACSource() {
}
}
-status_t AACSource::start(MetaData *params) {
+status_t AACSource::start(MetaData * /* params */) {
CHECK(!mStarted);
if (mOffsetVector.empty()) {
diff --git a/media/libstagefright/AACWriter.cpp b/media/libstagefright/AACWriter.cpp
index c9bcaba..deee8e7 100644
--- a/media/libstagefright/AACWriter.cpp
+++ b/media/libstagefright/AACWriter.cpp
@@ -111,7 +111,7 @@ status_t AACWriter::addSource(const sp<MediaSource> &source) {
return OK;
}
-status_t AACWriter::start(MetaData *params) {
+status_t AACWriter::start(MetaData * /* params */) {
if (mInitCheck != OK) {
return mInitCheck;
}
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index c68dfc1..ac78d6c 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -365,6 +365,7 @@ ACodec::ACodec()
mIsEncoder(false),
mUseMetadataOnEncoderOutput(false),
mShutdownInProgress(false),
+ mIsConfiguredForAdaptivePlayback(false),
mEncoderDelay(0),
mEncoderPadding(0),
mChannelMaskPresent(false),
@@ -372,7 +373,9 @@ ACodec::ACodec()
mDequeueCounter(0),
mStoreMetaDataInOutputBuffers(false),
mMetaDataBuffersToSubmit(0),
- mRepeatFrameDelayUs(-1ll) {
+ mRepeatFrameDelayUs(-1ll),
+ mMaxPtsGapUs(-1l),
+ mCreateInputBuffersSuspended(false) {
mUninitializedState = new UninitializedState(this);
mLoadedState = new LoadedState(this);
mLoadedToIdleState = new LoadedToIdleState(this);
@@ -1114,6 +1117,16 @@ status_t ACodec::configureCodec(
&mRepeatFrameDelayUs)) {
mRepeatFrameDelayUs = -1ll;
}
+
+ if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
+ mMaxPtsGapUs = -1l;
+ }
+
+ if (!msg->findInt32(
+ "create-input-buffers-suspended",
+ (int32_t*)&mCreateInputBuffersSuspended)) {
+ mCreateInputBuffersSuspended = false;
+ }
}
// Always try to enable dynamic output buffers on native surface
@@ -1121,6 +1134,7 @@ status_t ACodec::configureCodec(
int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
obj != NULL;
mStoreMetaDataInOutputBuffers = false;
+ mIsConfiguredForAdaptivePlayback = false;
if (!encoder && video && haveNativeWindow) {
err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
if (err != OK) {
@@ -1157,7 +1171,7 @@ status_t ACodec::configureCodec(
if (canDoAdaptivePlayback &&
msg->findInt32("max-width", &maxWidth) &&
msg->findInt32("max-height", &maxHeight)) {
- ALOGV("[%s] prepareForAdaptivePlayback(%ldx%ld)",
+ ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
mComponentName.c_str(), maxWidth, maxHeight);
err = mOMX->prepareForAdaptivePlayback(
@@ -1165,12 +1179,14 @@ status_t ACodec::configureCodec(
ALOGW_IF(err != OK,
"[%s] prepareForAdaptivePlayback failed w/ err %d",
mComponentName.c_str(), err);
+ mIsConfiguredForAdaptivePlayback = (err == OK);
}
// allow failure
err = OK;
} else {
ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
mStoreMetaDataInOutputBuffers = true;
+ mIsConfiguredForAdaptivePlayback = true;
}
int32_t push;
@@ -2951,7 +2967,8 @@ ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
mCodec(codec) {
}
-ACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
+ACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
+ OMX_U32 /* portIndex */) {
return KEEP_BUFFERS;
}
@@ -3318,11 +3335,11 @@ void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
mCodec->mInputEOSResult = err;
}
break;
-
- default:
- CHECK_EQ((int)mode, (int)FREE_BUFFERS);
- break;
}
+
+ default:
+ CHECK_EQ((int)mode, (int)FREE_BUFFERS);
+ break;
}
}
@@ -3360,8 +3377,8 @@ bool ACodec::BaseState::onOMXFillBufferDone(
size_t rangeOffset, size_t rangeLength,
OMX_U32 flags,
int64_t timeUs,
- void *platformPrivate,
- void *dataPtr) {
+ void * /* platformPrivate */,
+ void * /* dataPtr */) {
ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
@@ -3413,7 +3430,7 @@ bool ACodec::BaseState::onOMXFillBufferDone(
sp<AMessage> reply =
new AMessage(kWhatOutputBufferDrained, mCodec->id());
- if (!mCodec->mSentFormat) {
+ if (!mCodec->mSentFormat && rangeLength > 0) {
mCodec->sendFormatChange(reply);
}
@@ -3773,6 +3790,7 @@ void ACodec::LoadedState::stateEntered() {
mCodec->mDequeueCounter = 0;
mCodec->mMetaDataBuffersToSubmit = 0;
mCodec->mRepeatFrameDelayUs = -1ll;
+ mCodec->mIsConfiguredForAdaptivePlayback = false;
if (mCodec->mShutdownInProgress) {
bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
@@ -3893,7 +3911,7 @@ bool ACodec::LoadedState::onConfigureComponent(
}
void ACodec::LoadedState::onCreateInputSurface(
- const sp<AMessage> &msg) {
+ const sp<AMessage> & /* msg */) {
ALOGV("onCreateInputSurface");
sp<AMessage> notify = mCodec->mNotify->dup();
@@ -3921,6 +3939,37 @@ void ACodec::LoadedState::onCreateInputSurface(
}
}
+ if (err == OK && mCodec->mMaxPtsGapUs > 0l) {
+ err = mCodec->mOMX->setInternalOption(
+ mCodec->mNode,
+ kPortIndexInput,
+ IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
+ &mCodec->mMaxPtsGapUs,
+ sizeof(mCodec->mMaxPtsGapUs));
+
+ if (err != OK) {
+ ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
+ mCodec->mComponentName.c_str(),
+ err);
+ }
+ }
+
+ if (err == OK && mCodec->mCreateInputBuffersSuspended) {
+ bool suspend = true;
+ err = mCodec->mOMX->setInternalOption(
+ mCodec->mNode,
+ kPortIndexInput,
+ IOMX::INTERNAL_OPTION_SUSPEND,
+ &suspend,
+ sizeof(suspend));
+
+ if (err != OK) {
+ ALOGE("[%s] Unable to configure option to suspend (err %d)",
+ mCodec->mComponentName.c_str(),
+ err);
+ }
+ }
+
if (err == OK) {
notify->setObject("input-surface",
new BufferProducerWrapper(bufferProducer));
@@ -3978,6 +4027,7 @@ status_t ACodec::LoadedToIdleState::allocateBuffers() {
bool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
switch (msg->what()) {
+ case kWhatSetParameters:
case kWhatShutdown:
{
mCodec->deferMessage(msg);
@@ -4044,6 +4094,7 @@ void ACodec::IdleToExecutingState::stateEntered() {
bool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
switch (msg->what()) {
+ case kWhatSetParameters:
case kWhatShutdown:
{
mCodec->deferMessage(msg);
@@ -4104,7 +4155,7 @@ ACodec::ExecutingState::ExecutingState(ACodec *codec)
}
ACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
- OMX_U32 portIndex) {
+ OMX_U32 /* portIndex */) {
return RESUBMIT_BUFFERS;
}
@@ -4313,6 +4364,22 @@ status_t ACodec::setParameters(const sp<AMessage> &params) {
}
}
+ int64_t skipFramesBeforeUs;
+ if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
+ status_t err =
+ mOMX->setInternalOption(
+ mNode,
+ kPortIndexInput,
+ IOMX::INTERNAL_OPTION_START_TIME,
+ &skipFramesBeforeUs,
+ sizeof(skipFramesBeforeUs));
+
+ if (err != OK) {
+ ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
+ return err;
+ }
+ }
+
int32_t dropInputFrames;
if (params->findInt32("drop-input-frames", &dropInputFrames)) {
bool suspend = dropInputFrames != 0;
diff --git a/media/libstagefright/AMRExtractor.cpp b/media/libstagefright/AMRExtractor.cpp
index 03dcbf9..3f592ed 100644
--- a/media/libstagefright/AMRExtractor.cpp
+++ b/media/libstagefright/AMRExtractor.cpp
@@ -189,7 +189,7 @@ sp<MediaSource> AMRExtractor::getTrack(size_t index) {
mOffsetTable, mOffsetTableLength);
}
-sp<MetaData> AMRExtractor::getTrackMetaData(size_t index, uint32_t flags) {
+sp<MetaData> AMRExtractor::getTrackMetaData(size_t index, uint32_t /* flags */) {
if (mInitCheck != OK || index != 0) {
return NULL;
}
@@ -221,7 +221,7 @@ AMRSource::~AMRSource() {
}
}
-status_t AMRSource::start(MetaData *params) {
+status_t AMRSource::start(MetaData * /* params */) {
CHECK(!mStarted);
mOffset = mIsWide ? 9 : 6;
@@ -258,7 +258,7 @@ status_t AMRSource::read(
int64_t seekFrame = seekTimeUs / 20000ll; // 20ms per frame.
mCurrentTimeUs = seekFrame * 20000ll;
- int index = seekFrame / 50;
+ size_t index = seekFrame < 0 ? 0 : seekFrame / 50;
if (index >= mOffsetTableLength) {
index = mOffsetTableLength - 1;
}
diff --git a/media/libstagefright/AMRWriter.cpp b/media/libstagefright/AMRWriter.cpp
index 3fe247a..653ca36 100644
--- a/media/libstagefright/AMRWriter.cpp
+++ b/media/libstagefright/AMRWriter.cpp
@@ -105,7 +105,7 @@ status_t AMRWriter::addSource(const sp<MediaSource> &source) {
return OK;
}
-status_t AMRWriter::start(MetaData *params) {
+status_t AMRWriter::start(MetaData * /* params */) {
if (mInitCheck != OK) {
return mInitCheck;
}
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 6a2a696..0636dcc 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -15,6 +15,7 @@ LOCAL_SRC_FILES:= \
CameraSource.cpp \
CameraSourceTimeLapse.cpp \
DataSource.cpp \
+ DataURISource.cpp \
DRMExtractor.cpp \
ESDS.cpp \
FileSource.cpp \
@@ -30,8 +31,10 @@ LOCAL_SRC_FILES:= \
MediaBufferGroup.cpp \
MediaCodec.cpp \
MediaCodecList.cpp \
+ MediaCodecSource.cpp \
MediaDefs.cpp \
MediaExtractor.cpp \
+ http/MediaHTTP.cpp \
MediaMuxer.cpp \
MediaSource.cpp \
MetaData.cpp \
@@ -55,8 +58,6 @@ LOCAL_SRC_FILES:= \
WVMExtractor.cpp \
XINGSeeker.cpp \
avc_utils.cpp \
- mp4/FragmentedMP4Parser.cpp \
- mp4/TrackFragment.cpp \
LOCAL_C_INCLUDES:= \
$(TOP)/frameworks/av/include/media/stagefright/timedtext \
@@ -103,13 +104,6 @@ LOCAL_STATIC_LIBRARIES := \
libFLAC \
libmedia_helper
-LOCAL_SRC_FILES += \
- chromium_http_stub.cpp
-LOCAL_CPPFLAGS += -DCHROMIUM_AVAILABLE=1
-
-LOCAL_SHARED_LIBRARIES += libstlport
-include external/stlport/libstlport.mk
-
LOCAL_SHARED_LIBRARIES += \
libstagefright_enc_common \
libstagefright_avc_common \
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index 05ee34e..8623100 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -410,7 +410,7 @@ status_t AudioPlayer::setPlaybackRatePermille(int32_t ratePermille) {
// static
size_t AudioPlayer::AudioSinkCallback(
- MediaPlayerBase::AudioSink *audioSink,
+ MediaPlayerBase::AudioSink * /* audioSink */,
void *buffer, size_t size, void *cookie,
MediaPlayerBase::AudioSink::cb_event_t event) {
AudioPlayer *me = (AudioPlayer *)cookie;
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index f0d1a14..df7da0a 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -68,7 +68,7 @@ AudioSource::AudioSource(
int frameCount = kMaxBufferSize / sizeof(int16_t) / channelCount;
// make sure that the AudioRecord total buffer size is large enough
- int bufCount = 2;
+ size_t bufCount = 2;
while ((bufCount * frameCount) < minFrameCount) {
bufCount++;
}
@@ -208,7 +208,7 @@ void AudioSource::rampVolume(
}
status_t AudioSource::read(
- MediaBuffer **out, const ReadOptions *options) {
+ MediaBuffer **out, const ReadOptions * /* options */) {
Mutex::Autolock autoLock(mLock);
*out = NULL;
@@ -278,7 +278,7 @@ status_t AudioSource::dataCallback(const AudioRecord::Buffer& audioBuffer) {
// Drop retrieved and previously lost audio data.
if (mNumFramesReceived == 0 && timeUs < mStartTimeUs) {
- mRecord->getInputFramesLost();
+ (void) mRecord->getInputFramesLost();
ALOGV("Drop audio data at %lld/%lld us", timeUs, mStartTimeUs);
return OK;
}
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 29c007a..e83ec62 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -35,6 +35,8 @@
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
+#include <media/IMediaHTTPConnection.h>
+#include <media/IMediaHTTPService.h>
#include <media/IMediaPlayerService.h>
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/foundation/ADebug.h>
@@ -45,6 +47,7 @@
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaExtractor.h>
+#include <media/stagefright/MediaHTTP.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/OMXCodec.h>
@@ -83,7 +86,7 @@ struct AwesomeEvent : public TimedEventQueue::Event {
protected:
virtual ~AwesomeEvent() {}
- virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
+ virtual void fire(TimedEventQueue * /* queue */, int64_t /* now_us */) {
(mPlayer->*mMethod)();
}
@@ -277,15 +280,20 @@ void AwesomePlayer::setUID(uid_t uid) {
}
status_t AwesomePlayer::setDataSource(
- const char *uri, const KeyedVector<String8, String8> *headers) {
+ const sp<IMediaHTTPService> &httpService,
+ const char *uri,
+ const KeyedVector<String8, String8> *headers) {
Mutex::Autolock autoLock(mLock);
- return setDataSource_l(uri, headers);
+ return setDataSource_l(httpService, uri, headers);
}
status_t AwesomePlayer::setDataSource_l(
- const char *uri, const KeyedVector<String8, String8> *headers) {
+ const sp<IMediaHTTPService> &httpService,
+ const char *uri,
+ const KeyedVector<String8, String8> *headers) {
reset_l();
+ mHTTPService = httpService;
mUri = uri;
if (headers) {
@@ -582,6 +590,7 @@ void AwesomePlayer::reset_l() {
mSeekNotificationSent = true;
mSeekTimeUs = 0;
+ mHTTPService.clear();
mUri.setTo("");
mUriHeaders.clear();
@@ -1483,7 +1492,7 @@ void AwesomePlayer::addTextSource_l(size_t trackIndex, const sp<MediaSource>& so
CHECK(source != NULL);
if (mTextDriver == NULL) {
- mTextDriver = new TimedTextDriver(mListener);
+ mTextDriver = new TimedTextDriver(mListener, mHTTPService);
}
mTextDriver->addInBandTextSource(trackIndex, source);
@@ -2193,15 +2202,14 @@ status_t AwesomePlayer::finishSetDataSource_l() {
if (!strncasecmp("http://", mUri.string(), 7)
|| !strncasecmp("https://", mUri.string(), 8)
|| isWidevineStreaming) {
- mConnectingDataSource = HTTPBase::Create(
- (mFlags & INCOGNITO)
- ? HTTPBase::kFlagIncognito
- : 0);
-
- if (mUIDValid) {
- mConnectingDataSource->setUID(mUID);
+ if (mHTTPService == NULL) {
+ ALOGE("Attempt to play media from http URI without HTTP service.");
+ return UNKNOWN_ERROR;
}
+ sp<IMediaHTTPConnection> conn = mHTTPService->makeHTTPConnection();
+ mConnectingDataSource = new MediaHTTP(conn);
+
String8 cacheConfig;
bool disconnectAtHighwatermark;
NuCachedSource2::RemoveCacheSpecificHeaders(
@@ -2317,7 +2325,8 @@ status_t AwesomePlayer::finishSetDataSource_l() {
}
}
} else {
- dataSource = DataSource::CreateFromURI(mUri.string(), &mUriHeaders);
+ dataSource = DataSource::CreateFromURI(
+ mHTTPService, mUri.string(), &mUriHeaders);
}
if (dataSource == NULL) {
@@ -2759,7 +2768,7 @@ status_t AwesomePlayer::invoke(const Parcel &request, Parcel *reply) {
{
Mutex::Autolock autoLock(mLock);
if (mTextDriver == NULL) {
- mTextDriver = new TimedTextDriver(mListener);
+ mTextDriver = new TimedTextDriver(mListener, mHTTPService);
}
// String values written in Parcel are UTF-16 values.
String8 uri(request.readString16());
@@ -2771,7 +2780,7 @@ status_t AwesomePlayer::invoke(const Parcel &request, Parcel *reply) {
{
Mutex::Autolock autoLock(mLock);
if (mTextDriver == NULL) {
- mTextDriver = new TimedTextDriver(mListener);
+ mTextDriver = new TimedTextDriver(mListener, mHTTPService);
}
int fd = request.readFileDescriptor();
off64_t offset = request.readInt64();
@@ -2804,7 +2813,8 @@ bool AwesomePlayer::isStreamingHTTP() const {
return mCachedSource != NULL || mWVMExtractor != NULL;
}
-status_t AwesomePlayer::dump(int fd, const Vector<String16> &args) const {
+status_t AwesomePlayer::dump(
+ int fd, const Vector<String16> & /* args */) const {
Mutex::Autolock autoLock(mStatsLock);
FILE *out = fdopen(dup(fd), "w");
@@ -2900,6 +2910,8 @@ void AwesomePlayer::onAudioTearDownEvent() {
// get current position so we can start recreated stream from here
getPosition(&mAudioTearDownPosition);
+ sp<IMediaHTTPService> savedHTTPService = mHTTPService;
+
// Reset and recreate
reset_l();
@@ -2909,7 +2921,7 @@ void AwesomePlayer::onAudioTearDownEvent() {
mFileSource = fileSource;
err = setDataSource_l(fileSource);
} else {
- err = setDataSource_l(uri, &uriHeaders);
+ err = setDataSource_l(savedHTTPService, uri, &uriHeaders);
}
mFlags |= PREPARING;
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 3017fe7..f3ff792 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -31,6 +31,12 @@
#include <utils/String8.h>
#include <cutils/properties.h>
+#if LOG_NDEBUG
+#define UNUSED_UNLESS_VERBOSE(x) (void)(x)
+#else
+#define UNUSED_UNLESS_VERBOSE(x)
+#endif
+
namespace android {
static const int64_t CAMERA_SOURCE_TIMEOUT_NS = 3000000000LL;
@@ -63,11 +69,14 @@ CameraSourceListener::~CameraSourceListener() {
}
void CameraSourceListener::notify(int32_t msgType, int32_t ext1, int32_t ext2) {
+ UNUSED_UNLESS_VERBOSE(msgType);
+ UNUSED_UNLESS_VERBOSE(ext1);
+ UNUSED_UNLESS_VERBOSE(ext2);
ALOGV("notify(%d, %d, %d)", msgType, ext1, ext2);
}
void CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr,
- camera_frame_metadata_t *metadata) {
+ camera_frame_metadata_t * /* metadata */) {
ALOGV("postData(%d, ptr:%p, size:%d)",
msgType, dataPtr->pointer(), dataPtr->size());
diff --git a/media/libstagefright/CameraSourceTimeLapse.cpp b/media/libstagefright/CameraSourceTimeLapse.cpp
index 5772316..60cdf66 100644
--- a/media/libstagefright/CameraSourceTimeLapse.cpp
+++ b/media/libstagefright/CameraSourceTimeLapse.cpp
@@ -85,7 +85,8 @@ CameraSourceTimeLapse::CameraSourceTimeLapse(
mVideoWidth = videoSize.width;
mVideoHeight = videoSize.height;
- if (!trySettingVideoSize(videoSize.width, videoSize.height)) {
+ if (OK == mInitCheck && !trySettingVideoSize(videoSize.width, videoSize.height)) {
+ releaseCamera();
mInitCheck = NO_INIT;
}
@@ -231,7 +232,7 @@ sp<IMemory> CameraSourceTimeLapse::createIMemoryCopy(
return newMemory;
}
-bool CameraSourceTimeLapse::skipCurrentFrame(int64_t timestampUs) {
+bool CameraSourceTimeLapse::skipCurrentFrame(int64_t /* timestampUs */) {
ALOGV("skipCurrentFrame");
if (mSkipCurrentFrame) {
mSkipCurrentFrame = false;
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index 97987e2..6e0f37a 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -16,10 +16,6 @@
#include "include/AMRExtractor.h"
-#if CHROMIUM_AVAILABLE
-#include "include/chromium_http_stub.h"
-#endif
-
#include "include/AACExtractor.h"
#include "include/DRMExtractor.h"
#include "include/FLACExtractor.h"
@@ -35,10 +31,14 @@
#include "matroska/MatroskaExtractor.h"
+#include <media/IMediaHTTPConnection.h>
+#include <media/IMediaHTTPService.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/DataSource.h>
+#include <media/stagefright/DataURISource.h>
#include <media/stagefright/FileSource.h>
#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaHTTP.h>
#include <utils/String8.h>
#include <cutils/properties.h>
@@ -180,7 +180,9 @@ void DataSource::RegisterDefaultSniffers() {
// static
sp<DataSource> DataSource::CreateFromURI(
- const char *uri, const KeyedVector<String8, String8> *headers) {
+ const sp<IMediaHTTPService> &httpService,
+ const char *uri,
+ const KeyedVector<String8, String8> *headers) {
bool isWidevine = !strncasecmp("widevine://", uri, 11);
sp<DataSource> source;
@@ -189,7 +191,7 @@ sp<DataSource> DataSource::CreateFromURI(
} else if (!strncasecmp("http://", uri, 7)
|| !strncasecmp("https://", uri, 8)
|| isWidevine) {
- sp<HTTPBase> httpSource = HTTPBase::Create();
+ sp<HTTPBase> httpSource = new MediaHTTP(httpService->makeHTTPConnection());
String8 tmp;
if (isWidevine) {
@@ -220,11 +222,8 @@ sp<DataSource> DataSource::CreateFromURI(
// in the widevine:// case.
source = httpSource;
}
-
-# if CHROMIUM_AVAILABLE
} else if (!strncasecmp("data:", uri, 5)) {
- source = createDataUriSource(uri);
-#endif
+ source = DataURISource::Create(uri);
} else {
// Assume it's a filename.
source = new FileSource(uri);
diff --git a/media/libstagefright/DataURISource.cpp b/media/libstagefright/DataURISource.cpp
new file mode 100644
index 0000000..377bc85
--- /dev/null
+++ b/media/libstagefright/DataURISource.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <media/stagefright/DataURISource.h>
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/AString.h>
+#include <media/stagefright/foundation/base64.h>
+
+namespace android {
+
+// static
+sp<DataURISource> DataURISource::Create(const char *uri) {
+ if (strncasecmp("data:", uri, 5)) {
+ return NULL;
+ }
+
+ char *commaPos = strrchr(uri, ',');
+
+ if (commaPos == NULL) {
+ return NULL;
+ }
+
+ sp<ABuffer> buffer;
+
+ AString tmp(&uri[5], commaPos - &uri[5]);
+
+ if (tmp.endsWith(";base64")) {
+ AString encoded(commaPos + 1);
+
+ // Strip CR and LF...
+ for (size_t i = encoded.size(); i-- > 0;) {
+ if (encoded.c_str()[i] == '\r' || encoded.c_str()[i] == '\n') {
+ encoded.erase(i, 1);
+ }
+ }
+
+ buffer = decodeBase64(encoded);
+
+ if (buffer == NULL) {
+ ALOGE("Malformed base64 encoded content found.");
+ return NULL;
+ }
+ } else {
+#if 0
+ size_t dataLen = strlen(uri) - tmp.size() - 6;
+ buffer = new ABuffer(dataLen);
+ memcpy(buffer->data(), commaPos + 1, dataLen);
+
+ // unescape
+#else
+ // MediaPlayer doesn't care for this right now as we don't
+ // play any text-based media.
+ return NULL;
+#endif
+ }
+
+ // We don't really care about charset or mime type.
+
+ return new DataURISource(buffer);
+}
+
+DataURISource::DataURISource(const sp<ABuffer> &buffer)
+ : mBuffer(buffer) {
+}
+
+DataURISource::~DataURISource() {
+}
+
+status_t DataURISource::initCheck() const {
+ return OK;
+}
+
+ssize_t DataURISource::readAt(off64_t offset, void *data, size_t size) {
+ if (offset >= mBuffer->size()) {
+ return 0;
+ }
+
+ size_t copy = mBuffer->size() - offset;
+ if (copy > size) {
+ copy = size;
+ }
+
+ memcpy(data, mBuffer->data() + offset, copy);
+
+ return copy;
+}
+
+status_t DataURISource::getSize(off64_t *size) {
+ *size = mBuffer->size();
+
+ return OK;
+}
+
+} // namespace android
+
diff --git a/media/libstagefright/FLACExtractor.cpp b/media/libstagefright/FLACExtractor.cpp
index 098fcf9..fa7251c 100644
--- a/media/libstagefright/FLACExtractor.cpp
+++ b/media/libstagefright/FLACExtractor.cpp
@@ -208,55 +208,55 @@ private:
// with the same parameter list, but discard redundant information.
FLAC__StreamDecoderReadStatus FLACParser::read_callback(
- const FLAC__StreamDecoder *decoder, FLAC__byte buffer[],
+ const FLAC__StreamDecoder * /* decoder */, FLAC__byte buffer[],
size_t *bytes, void *client_data)
{
return ((FLACParser *) client_data)->readCallback(buffer, bytes);
}
FLAC__StreamDecoderSeekStatus FLACParser::seek_callback(
- const FLAC__StreamDecoder *decoder,
+ const FLAC__StreamDecoder * /* decoder */,
FLAC__uint64 absolute_byte_offset, void *client_data)
{
return ((FLACParser *) client_data)->seekCallback(absolute_byte_offset);
}
FLAC__StreamDecoderTellStatus FLACParser::tell_callback(
- const FLAC__StreamDecoder *decoder,
+ const FLAC__StreamDecoder * /* decoder */,
FLAC__uint64 *absolute_byte_offset, void *client_data)
{
return ((FLACParser *) client_data)->tellCallback(absolute_byte_offset);
}
FLAC__StreamDecoderLengthStatus FLACParser::length_callback(
- const FLAC__StreamDecoder *decoder,
+ const FLAC__StreamDecoder * /* decoder */,
FLAC__uint64 *stream_length, void *client_data)
{
return ((FLACParser *) client_data)->lengthCallback(stream_length);
}
FLAC__bool FLACParser::eof_callback(
- const FLAC__StreamDecoder *decoder, void *client_data)
+ const FLAC__StreamDecoder * /* decoder */, void *client_data)
{
return ((FLACParser *) client_data)->eofCallback();
}
FLAC__StreamDecoderWriteStatus FLACParser::write_callback(
- const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame,
+ const FLAC__StreamDecoder * /* decoder */, const FLAC__Frame *frame,
const FLAC__int32 * const buffer[], void *client_data)
{
return ((FLACParser *) client_data)->writeCallback(frame, buffer);
}
void FLACParser::metadata_callback(
- const FLAC__StreamDecoder *decoder,
+ const FLAC__StreamDecoder * /* decoder */,
const FLAC__StreamMetadata *metadata, void *client_data)
{
((FLACParser *) client_data)->metadataCallback(metadata);
}
void FLACParser::error_callback(
- const FLAC__StreamDecoder *decoder,
+ const FLAC__StreamDecoder * /* decoder */,
FLAC__StreamDecoderErrorStatus status, void *client_data)
{
((FLACParser *) client_data)->errorCallback(status);
@@ -380,15 +380,21 @@ void FLACParser::errorCallback(FLAC__StreamDecoderErrorStatus status)
// Copy samples from FLAC native 32-bit non-interleaved to 16-bit interleaved.
// These are candidates for optimization if needed.
-static void copyMono8(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
-{
+static void copyMono8(
+ short *dst,
+ const int *const *src,
+ unsigned nSamples,
+ unsigned /* nChannels */) {
for (unsigned i = 0; i < nSamples; ++i) {
*dst++ = src[0][i] << 8;
}
}
-static void copyStereo8(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
-{
+static void copyStereo8(
+ short *dst,
+ const int *const *src,
+ unsigned nSamples,
+ unsigned /* nChannels */) {
for (unsigned i = 0; i < nSamples; ++i) {
*dst++ = src[0][i] << 8;
*dst++ = src[1][i] << 8;
@@ -404,15 +410,21 @@ static void copyMultiCh8(short *dst, const int *const *src, unsigned nSamples, u
}
}
-static void copyMono16(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
-{
+static void copyMono16(
+ short *dst,
+ const int *const *src,
+ unsigned nSamples,
+ unsigned /* nChannels */) {
for (unsigned i = 0; i < nSamples; ++i) {
*dst++ = src[0][i];
}
}
-static void copyStereo16(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
-{
+static void copyStereo16(
+ short *dst,
+ const int *const *src,
+ unsigned nSamples,
+ unsigned /* nChannels */) {
for (unsigned i = 0; i < nSamples; ++i) {
*dst++ = src[0][i];
*dst++ = src[1][i];
@@ -430,15 +442,21 @@ static void copyMultiCh16(short *dst, const int *const *src, unsigned nSamples,
// 24-bit versions should do dithering or noise-shaping, here or in AudioFlinger
-static void copyMono24(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
-{
+static void copyMono24(
+ short *dst,
+ const int *const *src,
+ unsigned nSamples,
+ unsigned /* nChannels */) {
for (unsigned i = 0; i < nSamples; ++i) {
*dst++ = src[0][i] >> 8;
}
}
-static void copyStereo24(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
-{
+static void copyStereo24(
+ short *dst,
+ const int *const *src,
+ unsigned nSamples,
+ unsigned /* nChannels */) {
for (unsigned i = 0; i < nSamples; ++i) {
*dst++ = src[0][i] >> 8;
*dst++ = src[1][i] >> 8;
@@ -454,8 +472,11 @@ static void copyMultiCh24(short *dst, const int *const *src, unsigned nSamples,
}
}
-static void copyTrespass(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
-{
+static void copyTrespass(
+ short * /* dst */,
+ const int *const * /* src */,
+ unsigned /* nSamples */,
+ unsigned /* nChannels */) {
TRESPASS();
}
@@ -700,7 +721,7 @@ FLACSource::~FLACSource()
}
}
-status_t FLACSource::start(MetaData *params)
+status_t FLACSource::start(MetaData * /* params */)
{
ALOGV("FLACSource::start");
@@ -792,8 +813,7 @@ sp<MediaSource> FLACExtractor::getTrack(size_t index)
}
sp<MetaData> FLACExtractor::getTrackMetaData(
- size_t index, uint32_t flags)
-{
+ size_t index, uint32_t /* flags */) {
if (mInitCheck != OK || index > 0) {
return NULL;
}
diff --git a/media/libstagefright/HTTPBase.cpp b/media/libstagefright/HTTPBase.cpp
index 5fa4b6f..ca68c3d 100644
--- a/media/libstagefright/HTTPBase.cpp
+++ b/media/libstagefright/HTTPBase.cpp
@@ -20,10 +20,6 @@
#include "include/HTTPBase.h"
-#if CHROMIUM_AVAILABLE
-#include "include/chromium_http_stub.h"
-#endif
-
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ALooper.h>
@@ -40,34 +36,7 @@ HTTPBase::HTTPBase()
mTotalTransferBytes(0),
mPrevBandwidthMeasureTimeUs(0),
mPrevEstimatedBandWidthKbps(0),
- mBandWidthCollectFreqMs(5000),
- mUIDValid(false),
- mUID(0) {
-}
-
-// static
-sp<HTTPBase> HTTPBase::Create(uint32_t flags) {
-#if CHROMIUM_AVAILABLE
- HTTPBase *dataSource = createChromiumHTTPDataSource(flags);
- if (dataSource) {
- return dataSource;
- }
-#endif
- {
- TRESPASS();
-
- return NULL;
- }
-}
-
-// static
-status_t HTTPBase::UpdateProxyConfig(
- const char *host, int32_t port, const char *exclusionList) {
-#if CHROMIUM_AVAILABLE
- return UpdateChromiumHTTPDataSourceProxyConfig(host, port, exclusionList);
-#else
- return INVALID_OPERATION;
-#endif
+ mBandWidthCollectFreqMs(5000) {
}
void HTTPBase::addBandwidthMeasurement(
@@ -135,21 +104,6 @@ status_t HTTPBase::setBandwidthStatCollectFreq(int32_t freqMs) {
return OK;
}
-void HTTPBase::setUID(uid_t uid) {
- mUIDValid = true;
- mUID = uid;
-}
-
-bool HTTPBase::getUID(uid_t *uid) const {
- if (!mUIDValid) {
- return false;
- }
-
- *uid = mUID;
-
- return true;
-}
-
// static
void HTTPBase::RegisterSocketUserTag(int sockfd, uid_t uid, uint32_t kTag) {
int res = qtaguid_tagSocket(sockfd, kTag, uid);
diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index 380dab4..4a63152 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -398,7 +398,8 @@ sp<MediaSource> MP3Extractor::getTrack(size_t index) {
mSeeker);
}
-sp<MetaData> MP3Extractor::getTrackMetaData(size_t index, uint32_t flags) {
+sp<MetaData> MP3Extractor::getTrackMetaData(
+ size_t index, uint32_t /* flags */) {
if (mInitCheck != OK || index != 0) {
return NULL;
}
diff --git a/media/libstagefright/MPEG2TSWriter.cpp b/media/libstagefright/MPEG2TSWriter.cpp
index c9ed5bb..78c12e1 100644
--- a/media/libstagefright/MPEG2TSWriter.cpp
+++ b/media/libstagefright/MPEG2TSWriter.cpp
@@ -555,7 +555,7 @@ status_t MPEG2TSWriter::addSource(const sp<MediaSource> &source) {
return OK;
}
-status_t MPEG2TSWriter::start(MetaData *param) {
+status_t MPEG2TSWriter::start(MetaData * /* param */) {
CHECK(!mStarted);
mStarted = true;
@@ -596,7 +596,8 @@ bool MPEG2TSWriter::reachedEOS() {
return !mStarted || (mNumSourcesDone == mSources.size() ? true : false);
}
-status_t MPEG2TSWriter::dump(int fd, const Vector<String16> &args) {
+status_t MPEG2TSWriter::dump(
+ int /* fd */, const Vector<String16> & /* args */) {
return OK;
}
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 6a33ce6..4756b3e 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -571,7 +571,8 @@ static int32_t readSize(off64_t offset,
return size;
}
-status_t MPEG4Extractor::parseDrmSINF(off64_t *offset, off64_t data_offset) {
+status_t MPEG4Extractor::parseDrmSINF(
+ off64_t * /* offset */, off64_t data_offset) {
uint8_t updateIdTag;
if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) {
return ERROR_IO;
@@ -2441,6 +2442,58 @@ status_t MPEG4Extractor::verifyTrack(Track *track) {
return OK;
}
+typedef enum {
+ //AOT_NONE = -1,
+ //AOT_NULL_OBJECT = 0,
+ //AOT_AAC_MAIN = 1, /**< Main profile */
+ AOT_AAC_LC = 2, /**< Low Complexity object */
+ //AOT_AAC_SSR = 3,
+ //AOT_AAC_LTP = 4,
+ AOT_SBR = 5,
+ //AOT_AAC_SCAL = 6,
+ //AOT_TWIN_VQ = 7,
+ //AOT_CELP = 8,
+ //AOT_HVXC = 9,
+ //AOT_RSVD_10 = 10, /**< (reserved) */
+ //AOT_RSVD_11 = 11, /**< (reserved) */
+ //AOT_TTSI = 12, /**< TTSI Object */
+ //AOT_MAIN_SYNTH = 13, /**< Main Synthetic object */
+ //AOT_WAV_TAB_SYNTH = 14, /**< Wavetable Synthesis object */
+ //AOT_GEN_MIDI = 15, /**< General MIDI object */
+ //AOT_ALG_SYNTH_AUD_FX = 16, /**< Algorithmic Synthesis and Audio FX object */
+ AOT_ER_AAC_LC = 17, /**< Error Resilient(ER) AAC Low Complexity */
+ //AOT_RSVD_18 = 18, /**< (reserved) */
+ //AOT_ER_AAC_LTP = 19, /**< Error Resilient(ER) AAC LTP object */
+ AOT_ER_AAC_SCAL = 20, /**< Error Resilient(ER) AAC Scalable object */
+ //AOT_ER_TWIN_VQ = 21, /**< Error Resilient(ER) TwinVQ object */
+ AOT_ER_BSAC = 22, /**< Error Resilient(ER) BSAC object */
+ AOT_ER_AAC_LD = 23, /**< Error Resilient(ER) AAC LowDelay object */
+ //AOT_ER_CELP = 24, /**< Error Resilient(ER) CELP object */
+ //AOT_ER_HVXC = 25, /**< Error Resilient(ER) HVXC object */
+ //AOT_ER_HILN = 26, /**< Error Resilient(ER) HILN object */
+ //AOT_ER_PARA = 27, /**< Error Resilient(ER) Parametric object */
+ //AOT_RSVD_28 = 28, /**< might become SSC */
+ AOT_PS = 29, /**< PS, Parametric Stereo (includes SBR) */
+ //AOT_MPEGS = 30, /**< MPEG Surround */
+
+ AOT_ESCAPE = 31, /**< Signal AOT uses more than 5 bits */
+
+ //AOT_MP3ONMP4_L1 = 32, /**< MPEG-Layer1 in mp4 */
+ //AOT_MP3ONMP4_L2 = 33, /**< MPEG-Layer2 in mp4 */
+ //AOT_MP3ONMP4_L3 = 34, /**< MPEG-Layer3 in mp4 */
+ //AOT_RSVD_35 = 35, /**< might become DST */
+ //AOT_RSVD_36 = 36, /**< might become ALS */
+ //AOT_AAC_SLS = 37, /**< AAC + SLS */
+ //AOT_SLS = 38, /**< SLS */
+ //AOT_ER_AAC_ELD = 39, /**< AAC Enhanced Low Delay */
+
+ //AOT_USAC = 42, /**< USAC */
+ //AOT_SAOC = 43, /**< SAOC */
+ //AOT_LD_MPEGS = 44, /**< Low Delay MPEG Surround */
+
+ //AOT_RSVD50 = 50, /**< Interim AOT for Rsvd50 */
+} AUDIO_OBJECT_TYPE;
+
status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
const void *esds_data, size_t esds_size) {
ESDS esds(esds_data, esds_size);
@@ -2523,7 +2576,7 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
sampleRate = kSamplingRate[freqIndex];
}
- if (objectType == 5 || objectType == 29) { // SBR specific config per 14496-3 table 1.13
+ if (objectType == AOT_SBR || objectType == AOT_PS) {//SBR specific config per 14496-3 table 1.13
uint32_t extFreqIndex = br.getBits(4);
int32_t extSampleRate;
if (extFreqIndex == 15) {
@@ -2541,6 +2594,111 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
// mLastTrack->meta->setInt32(kKeyExtSampleRate, extSampleRate);
}
+ switch (numChannels) {
+ // values defined in 14496-3_2009 amendment-4 Table 1.19 - Channel Configuration
+ case 0:
+ case 1:// FC
+ case 2:// FL FR
+ case 3:// FC, FL FR
+ case 4:// FC, FL FR, RC
+ case 5:// FC, FL FR, SL SR
+ case 6:// FC, FL FR, SL SR, LFE
+ //numChannels already contains the right value
+ break;
+ case 11:// FC, FL FR, SL SR, RC, LFE
+ numChannels = 7;
+ break;
+ case 7: // FC, FCL FCR, FL FR, SL SR, LFE
+ case 12:// FC, FL FR, SL SR, RL RR, LFE
+ case 14:// FC, FL FR, SL SR, LFE, FHL FHR
+ numChannels = 8;
+ break;
+ default:
+ return ERROR_UNSUPPORTED;
+ }
+
+ {
+ if (objectType == AOT_SBR || objectType == AOT_PS) {
+ const int32_t extensionSamplingFrequency = br.getBits(4);
+ objectType = br.getBits(5);
+
+ if (objectType == AOT_ESCAPE) {
+ objectType = 32 + br.getBits(6);
+ }
+ }
+ if (objectType == AOT_AAC_LC || objectType == AOT_ER_AAC_LC ||
+ objectType == AOT_ER_AAC_LD || objectType == AOT_ER_AAC_SCAL ||
+ objectType == AOT_ER_BSAC) {
+ const int32_t frameLengthFlag = br.getBits(1);
+
+ const int32_t dependsOnCoreCoder = br.getBits(1);
+
+ if (dependsOnCoreCoder ) {
+ const int32_t coreCoderDelay = br.getBits(14);
+ }
+
+ const int32_t extensionFlag = br.getBits(1);
+
+ if (numChannels == 0 ) {
+ int32_t channelsEffectiveNum = 0;
+ int32_t channelsNum = 0;
+ const int32_t ElementInstanceTag = br.getBits(4);
+ const int32_t Profile = br.getBits(2);
+ const int32_t SamplingFrequencyIndex = br.getBits(4);
+ const int32_t NumFrontChannelElements = br.getBits(4);
+ const int32_t NumSideChannelElements = br.getBits(4);
+ const int32_t NumBackChannelElements = br.getBits(4);
+ const int32_t NumLfeChannelElements = br.getBits(2);
+ const int32_t NumAssocDataElements = br.getBits(3);
+ const int32_t NumValidCcElements = br.getBits(4);
+
+ const int32_t MonoMixdownPresent = br.getBits(1);
+ if (MonoMixdownPresent != 0) {
+ const int32_t MonoMixdownElementNumber = br.getBits(4);
+ }
+
+ const int32_t StereoMixdownPresent = br.getBits(1);
+ if (StereoMixdownPresent != 0) {
+ const int32_t StereoMixdownElementNumber = br.getBits(4);
+ }
+
+ const int32_t MatrixMixdownIndexPresent = br.getBits(1);
+ if (MatrixMixdownIndexPresent != 0) {
+ const int32_t MatrixMixdownIndex = br.getBits(2);
+ const int32_t PseudoSurroundEnable = br.getBits(1);
+ }
+
+ int i;
+ for (i=0; i < NumFrontChannelElements; i++) {
+ const int32_t FrontElementIsCpe = br.getBits(1);
+ const int32_t FrontElementTagSelect = br.getBits(4);
+ channelsNum += FrontElementIsCpe ? 2 : 1;
+ }
+
+ for (i=0; i < NumSideChannelElements; i++) {
+ const int32_t SideElementIsCpe = br.getBits(1);
+ const int32_t SideElementTagSelect = br.getBits(4);
+ channelsNum += SideElementIsCpe ? 2 : 1;
+ }
+
+ for (i=0; i < NumBackChannelElements; i++) {
+ const int32_t BackElementIsCpe = br.getBits(1);
+ const int32_t BackElementTagSelect = br.getBits(4);
+ channelsNum += BackElementIsCpe ? 2 : 1;
+ }
+ channelsEffectiveNum = channelsNum;
+
+ for (i=0; i < NumLfeChannelElements; i++) {
+ const int32_t LfeElementTagSelect = br.getBits(4);
+ channelsNum += 1;
+ }
+ ALOGV("mpeg4 audio channelsNum = %d", channelsNum);
+ ALOGV("mpeg4 audio channelsEffectiveNum = %d", channelsEffectiveNum);
+ numChannels = channelsNum;
+ }
+ }
+ }
+
if (numChannels == 0) {
return ERROR_UNSUPPORTED;
}
@@ -2802,7 +2960,8 @@ status_t MPEG4Source::parseChunk(off64_t *offset) {
return OK;
}
-status_t MPEG4Source::parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size) {
+status_t MPEG4Source::parseSampleAuxiliaryInformationSizes(
+ off64_t offset, off64_t /* size */) {
ALOGV("parseSampleAuxiliaryInformationSizes");
// 14496-12 8.7.12
uint8_t version;
@@ -2864,7 +3023,8 @@ status_t MPEG4Source::parseSampleAuxiliaryInformationSizes(off64_t offset, off64
return OK;
}
-status_t MPEG4Source::parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size) {
+status_t MPEG4Source::parseSampleAuxiliaryInformationOffsets(
+ off64_t offset, off64_t /* size */) {
ALOGV("parseSampleAuxiliaryInformationOffsets");
// 14496-12 8.7.13
uint8_t version;
@@ -3575,7 +3735,7 @@ status_t MPEG4Source::fragmentedRead(
}
off64_t offset = 0;
- size_t size;
+ size_t size = 0;
uint32_t cts = 0;
bool isSyncSample = false;
bool newBuffer = false;
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index e7d3cc2..fb316f9 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -44,7 +44,9 @@
namespace android {
static const int64_t kMinStreamableFileSizeInBytes = 5 * 1024 * 1024;
-static const int64_t kMax32BitFileSize = 0x007fffffffLL;
+static const int64_t kMax32BitFileSize = 0x00ffffffffLL; // 2^32-1 : max FAT32
+ // filesystem file size
+ // used by most SD cards
static const uint8_t kNalUnitTypeSeqParamSet = 0x07;
static const uint8_t kNalUnitTypePicParamSet = 0x08;
static const int64_t kInitialDelayTimeUs = 700000LL;
@@ -407,7 +409,7 @@ status_t MPEG4Writer::dump(
}
status_t MPEG4Writer::Track::dump(
- int fd, const Vector<String16>& args) const {
+ int fd, const Vector<String16>& /* args */) const {
const size_t SIZE = 256;
char buffer[SIZE];
String8 result;
@@ -861,11 +863,11 @@ status_t MPEG4Writer::reset() {
// Fix up the size of the 'mdat' chunk.
if (mUse32BitOffset) {
lseek64(mFd, mMdatOffset, SEEK_SET);
- int32_t size = htonl(static_cast<int32_t>(mOffset - mMdatOffset));
+ uint32_t size = htonl(static_cast<uint32_t>(mOffset - mMdatOffset));
::write(mFd, &size, 4);
} else {
lseek64(mFd, mMdatOffset + 8, SEEK_SET);
- int64_t size = mOffset - mMdatOffset;
+ uint64_t size = mOffset - mMdatOffset;
size = hton64(size);
::write(mFd, &size, 8);
}
@@ -973,13 +975,16 @@ void MPEG4Writer::writeFtypBox(MetaData *param) {
if (param && param->findInt32(kKeyFileType, &fileType) &&
fileType != OUTPUT_FORMAT_MPEG_4) {
writeFourcc("3gp4");
+ writeInt32(0);
+ writeFourcc("isom");
+ writeFourcc("3gp4");
} else {
+ writeFourcc("mp42");
+ writeInt32(0);
writeFourcc("isom");
+ writeFourcc("mp42");
}
- writeInt32(0);
- writeFourcc("isom");
- writeFourcc("3gp4");
endBox();
}
@@ -1761,7 +1766,7 @@ status_t MPEG4Writer::Track::pause() {
}
status_t MPEG4Writer::Track::stop() {
- ALOGD("Stopping %s track", mIsAudio? "Audio": "Video");
+ ALOGD("%s track stopping", mIsAudio? "Audio": "Video");
if (!mStarted) {
ALOGE("Stop() called but track is not started");
return ERROR_END_OF_STREAM;
@@ -1772,19 +1777,14 @@ status_t MPEG4Writer::Track::stop() {
}
mDone = true;
+ ALOGD("%s track source stopping", mIsAudio? "Audio": "Video");
+ mSource->stop();
+ ALOGD("%s track source stopped", mIsAudio? "Audio": "Video");
+
void *dummy;
pthread_join(mThread, &dummy);
-
status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy));
- ALOGD("Stopping %s track source", mIsAudio? "Audio": "Video");
- {
- status_t status = mSource->stop();
- if (err == OK && status != OK && status != ERROR_END_OF_STREAM) {
- err = status;
- }
- }
-
ALOGD("%s track stopped", mIsAudio? "Audio": "Video");
return err;
}
diff --git a/media/libstagefright/MediaAdapter.cpp b/media/libstagefright/MediaAdapter.cpp
index 2484212..d680e0c 100644
--- a/media/libstagefright/MediaAdapter.cpp
+++ b/media/libstagefright/MediaAdapter.cpp
@@ -36,7 +36,7 @@ MediaAdapter::~MediaAdapter() {
CHECK(mCurrentMediaBuffer == NULL);
}
-status_t MediaAdapter::start(MetaData *params) {
+status_t MediaAdapter::start(MetaData * /* params */) {
Mutex::Autolock autoLock(mAdapterLock);
if (!mStarted) {
mStarted = true;
@@ -75,7 +75,7 @@ void MediaAdapter::signalBufferReturned(MediaBuffer *buffer) {
}
status_t MediaAdapter::read(
- MediaBuffer **buffer, const ReadOptions *options) {
+ MediaBuffer **buffer, const ReadOptions * /* options */) {
Mutex::Autolock autoLock(mAdapterLock);
if (!mStarted) {
ALOGV("Read before even started!");
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index c4c47b3..fe21296 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -115,7 +115,7 @@ status_t MediaCodec::init(const char *name, bool nameIsType, bool encoder) {
if (codecIdx >= 0) {
Vector<AString> types;
if (mcl->getSupportedTypes(codecIdx, &types) == OK) {
- for (int i = 0; i < types.size(); i++) {
+ for (size_t i = 0; i < types.size(); i++) {
if (types[i].startsWith("video/")) {
needDedicatedLooper = true;
break;
diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp
new file mode 100644
index 0000000..924173c
--- /dev/null
+++ b/media/libstagefright/MediaCodecSource.cpp
@@ -0,0 +1,881 @@
+/*
+ * Copyright 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MediaCodecSource"
+#define DEBUG_DRIFT_TIME 0
+#include <gui/IGraphicBufferProducer.h>
+#include <gui/Surface.h>
+#include <media/ICrypto.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaCodec.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MediaCodecSource.h>
+#include <media/stagefright/Utils.h>
+
+namespace android {
+
+static void ReleaseMediaBufferReference(const sp<ABuffer> &accessUnit) {
+ void *mbuf;
+ if (accessUnit->meta()->findPointer("mediaBuffer", &mbuf)
+ && mbuf != NULL) {
+ ALOGV("releasing mbuf %p", mbuf);
+
+ accessUnit->meta()->setPointer("mediaBuffer", NULL);
+
+ static_cast<MediaBuffer *>(mbuf)->release();
+ mbuf = NULL;
+ }
+}
+
+struct MediaCodecSource::Puller : public AHandler {
+ Puller(const sp<MediaSource> &source);
+
+ status_t start(const sp<MetaData> &meta, const sp<AMessage> &notify);
+ void stopAsync();
+
+ void pause();
+ void resume();
+
+protected:
+ virtual void onMessageReceived(const sp<AMessage> &msg);
+ virtual ~Puller();
+
+private:
+ enum {
+ kWhatStart = 'msta',
+ kWhatStop,
+ kWhatPull,
+ kWhatPause,
+ kWhatResume,
+ };
+
+ sp<MediaSource> mSource;
+ sp<AMessage> mNotify;
+ sp<ALooper> mLooper;
+ int32_t mPullGeneration;
+ bool mIsAudio;
+ bool mPaused;
+ bool mReachedEOS;
+
+ status_t postSynchronouslyAndReturnError(const sp<AMessage> &msg);
+ void schedulePull();
+ void handleEOS();
+
+ DISALLOW_EVIL_CONSTRUCTORS(Puller);
+};
+
+MediaCodecSource::Puller::Puller(const sp<MediaSource> &source)
+ : mSource(source),
+ mLooper(new ALooper()),
+ mPullGeneration(0),
+ mIsAudio(false),
+ mPaused(false),
+ mReachedEOS(false) {
+ sp<MetaData> meta = source->getFormat();
+ const char *mime;
+ CHECK(meta->findCString(kKeyMIMEType, &mime));
+
+ mIsAudio = !strncasecmp(mime, "audio/", 6);
+
+ mLooper->setName("pull_looper");
+}
+
+MediaCodecSource::Puller::~Puller() {
+ mLooper->unregisterHandler(id());
+ mLooper->stop();
+}
+
+status_t MediaCodecSource::Puller::postSynchronouslyAndReturnError(
+ const sp<AMessage> &msg) {
+ sp<AMessage> response;
+ status_t err = msg->postAndAwaitResponse(&response);
+
+ if (err != OK) {
+ return err;
+ }
+
+ if (!response->findInt32("err", &err)) {
+ err = OK;
+ }
+
+ return err;
+}
+
+status_t MediaCodecSource::Puller::start(const sp<MetaData> &meta,
+ const sp<AMessage> &notify) {
+ ALOGV("puller (%s) start", mIsAudio ? "audio" : "video");
+ mLooper->start(
+ false /* runOnCallingThread */,
+ false /* canCallJava */,
+ PRIORITY_AUDIO);
+ mLooper->registerHandler(this);
+ mNotify = notify;
+
+ sp<AMessage> msg = new AMessage(kWhatStart, id());
+ msg->setObject("meta", meta);
+ return postSynchronouslyAndReturnError(msg);
+}
+
+void MediaCodecSource::Puller::stopAsync() {
+ ALOGV("puller (%s) stopAsync", mIsAudio ? "audio" : "video");
+ (new AMessage(kWhatStop, id()))->post();
+}
+
+void MediaCodecSource::Puller::pause() {
+ (new AMessage(kWhatPause, id()))->post();
+}
+
+void MediaCodecSource::Puller::resume() {
+ (new AMessage(kWhatResume, id()))->post();
+}
+
+void MediaCodecSource::Puller::schedulePull() {
+ sp<AMessage> msg = new AMessage(kWhatPull, id());
+ msg->setInt32("generation", mPullGeneration);
+ msg->post();
+}
+
+void MediaCodecSource::Puller::handleEOS() {
+ if (!mReachedEOS) {
+ ALOGV("puller (%s) posting EOS", mIsAudio ? "audio" : "video");
+ mReachedEOS = true;
+ sp<AMessage> notify = mNotify->dup();
+ notify->setPointer("accessUnit", NULL);
+ notify->post();
+ }
+}
+
+void MediaCodecSource::Puller::onMessageReceived(const sp<AMessage> &msg) {
+ switch (msg->what()) {
+ case kWhatStart:
+ {
+ sp<RefBase> obj;
+ CHECK(msg->findObject("meta", &obj));
+
+ mReachedEOS = false;
+
+ status_t err = mSource->start(static_cast<MetaData *>(obj.get()));
+
+ if (err == OK) {
+ schedulePull();
+ }
+
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", err);
+
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+ response->postReply(replyID);
+ break;
+ }
+
+ case kWhatStop:
+ {
+ ALOGV("source (%s) stopping", mIsAudio ? "audio" : "video");
+ mSource->stop();
+ ALOGV("source (%s) stopped", mIsAudio ? "audio" : "video");
+ ++mPullGeneration;
+
+ handleEOS();
+ break;
+ }
+
+ case kWhatPull:
+ {
+ int32_t generation;
+ CHECK(msg->findInt32("generation", &generation));
+
+ if (generation != mPullGeneration) {
+ break;
+ }
+
+ MediaBuffer *mbuf;
+ status_t err = mSource->read(&mbuf);
+
+ if (mPaused) {
+ if (err == OK) {
+ mbuf->release();
+ mbuf = NULL;
+ }
+
+ msg->post();
+ break;
+ }
+
+ if (err != OK) {
+ if (err == ERROR_END_OF_STREAM) {
+ ALOGV("stream ended, mbuf %p", mbuf);
+ } else {
+ ALOGE("error %d reading stream.", err);
+ }
+ handleEOS();
+ } else {
+ sp<AMessage> notify = mNotify->dup();
+
+ notify->setPointer("accessUnit", mbuf);
+ notify->post();
+
+ msg->post();
+ }
+ break;
+ }
+
+ case kWhatPause:
+ {
+ mPaused = true;
+ break;
+ }
+
+ case kWhatResume:
+ {
+ mPaused = false;
+ break;
+ }
+
+ default:
+ TRESPASS();
+ }
+}
+
+// static
+sp<MediaCodecSource> MediaCodecSource::Create(
+ const sp<ALooper> &looper,
+ const sp<AMessage> &format,
+ const sp<MediaSource> &source,
+ uint32_t flags) {
+ sp<MediaCodecSource> mediaSource =
+ new MediaCodecSource(looper, format, source, flags);
+
+ if (mediaSource->init() == OK) {
+ return mediaSource;
+ }
+ return NULL;
+}
+
+status_t MediaCodecSource::start(MetaData* params) {
+ sp<AMessage> msg = new AMessage(kWhatStart, mReflector->id());
+ msg->setObject("meta", params);
+ return postSynchronouslyAndReturnError(msg);
+}
+
+status_t MediaCodecSource::stop() {
+ sp<AMessage> msg = new AMessage(kWhatStop, mReflector->id());
+ return postSynchronouslyAndReturnError(msg);
+}
+
+status_t MediaCodecSource::pause() {
+ (new AMessage(kWhatPause, mReflector->id()))->post();
+ return OK;
+}
+
+sp<IGraphicBufferProducer> MediaCodecSource::getGraphicBufferProducer() {
+ CHECK(mFlags & FLAG_USE_SURFACE_INPUT);
+ return mGraphicBufferProducer;
+}
+
+status_t MediaCodecSource::read(
+ MediaBuffer** buffer, const ReadOptions* /* options */) {
+ Mutex::Autolock autolock(mOutputBufferLock);
+
+ *buffer = NULL;
+ while (mOutputBufferQueue.size() == 0 && !mEncodedReachedEOS) {
+ mOutputBufferCond.wait(mOutputBufferLock);
+ }
+ if (!mEncodedReachedEOS) {
+ *buffer = *mOutputBufferQueue.begin();
+ mOutputBufferQueue.erase(mOutputBufferQueue.begin());
+ return OK;
+ }
+ return mErrorCode;
+}
+
+void MediaCodecSource::signalBufferReturned(MediaBuffer *buffer) {
+ buffer->setObserver(0);
+ buffer->release();
+}
+
+MediaCodecSource::MediaCodecSource(
+ const sp<ALooper> &looper,
+ const sp<AMessage> &outputFormat,
+ const sp<MediaSource> &source,
+ uint32_t flags)
+ : mLooper(looper),
+ mOutputFormat(outputFormat),
+ mMeta(new MetaData),
+ mFlags(flags),
+ mIsVideo(false),
+ mStarted(false),
+ mStopping(false),
+ mDoMoreWorkPending(false),
+ mPullerReachedEOS(false),
+ mFirstSampleTimeUs(-1ll),
+ mEncodedReachedEOS(false),
+ mErrorCode(OK) {
+ CHECK(mLooper != NULL);
+
+ AString mime;
+ CHECK(mOutputFormat->findString("mime", &mime));
+
+ if (!strncasecmp("video/", mime.c_str(), 6)) {
+ mIsVideo = true;
+ }
+
+ if (!(mFlags & FLAG_USE_SURFACE_INPUT)) {
+ mPuller = new Puller(source);
+ }
+}
+
+MediaCodecSource::~MediaCodecSource() {
+ releaseEncoder();
+
+ mCodecLooper->stop();
+ mLooper->unregisterHandler(mReflector->id());
+}
+
+status_t MediaCodecSource::init() {
+ status_t err = initEncoder();
+
+ if (err != OK) {
+ releaseEncoder();
+ }
+
+ return err;
+}
+
+status_t MediaCodecSource::initEncoder() {
+ mReflector = new AHandlerReflector<MediaCodecSource>(this);
+ mLooper->registerHandler(mReflector);
+
+ mCodecLooper = new ALooper;
+ mCodecLooper->setName("codec_looper");
+ mCodecLooper->start();
+
+ if (mFlags & FLAG_USE_METADATA_INPUT) {
+ mOutputFormat->setInt32("store-metadata-in-buffers", 1);
+ }
+
+ if (mFlags & FLAG_USE_SURFACE_INPUT) {
+ mOutputFormat->setInt32("create-input-buffers-suspended", 1);
+ }
+
+ AString outputMIME;
+ CHECK(mOutputFormat->findString("mime", &outputMIME));
+
+ mEncoder = MediaCodec::CreateByType(
+ mCodecLooper, outputMIME.c_str(), true /* encoder */);
+
+ if (mEncoder == NULL) {
+ return NO_INIT;
+ }
+
+ ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str());
+
+ status_t err = mEncoder->configure(
+ mOutputFormat,
+ NULL /* nativeWindow */,
+ NULL /* crypto */,
+ MediaCodec::CONFIGURE_FLAG_ENCODE);
+
+ if (err != OK) {
+ return err;
+ }
+
+ mEncoder->getOutputFormat(&mOutputFormat);
+ convertMessageToMetaData(mOutputFormat, mMeta);
+
+ if (mFlags & FLAG_USE_SURFACE_INPUT) {
+ CHECK(mIsVideo);
+
+ err = mEncoder->createInputSurface(&mGraphicBufferProducer);
+
+ if (err != OK) {
+ return err;
+ }
+ }
+
+ err = mEncoder->start();
+
+ if (err != OK) {
+ return err;
+ }
+
+ err = mEncoder->getInputBuffers(&mEncoderInputBuffers);
+
+ if (err != OK) {
+ return err;
+ }
+
+ err = mEncoder->getOutputBuffers(&mEncoderOutputBuffers);
+
+ if (err != OK) {
+ return err;
+ }
+
+ mEncodedReachedEOS = false;
+ mErrorCode = OK;
+
+ return OK;
+}
+
+void MediaCodecSource::releaseEncoder() {
+ if (mEncoder == NULL) {
+ return;
+ }
+
+ mEncoder->release();
+ mEncoder.clear();
+
+ while (!mInputBufferQueue.empty()) {
+ MediaBuffer *mbuf = *mInputBufferQueue.begin();
+ mInputBufferQueue.erase(mInputBufferQueue.begin());
+ if (mbuf != NULL) {
+ mbuf->release();
+ }
+ }
+
+ for (size_t i = 0; i < mEncoderInputBuffers.size(); ++i) {
+ sp<ABuffer> accessUnit = mEncoderInputBuffers.itemAt(i);
+ ReleaseMediaBufferReference(accessUnit);
+ }
+
+ mEncoderInputBuffers.clear();
+ mEncoderOutputBuffers.clear();
+}
+
+bool MediaCodecSource::reachedEOS() {
+ return mEncodedReachedEOS && ((mPuller == NULL) || mPullerReachedEOS);
+}
+
+status_t MediaCodecSource::postSynchronouslyAndReturnError(
+ const sp<AMessage> &msg) {
+ sp<AMessage> response;
+ status_t err = msg->postAndAwaitResponse(&response);
+
+ if (err != OK) {
+ return err;
+ }
+
+ if (!response->findInt32("err", &err)) {
+ err = OK;
+ }
+
+ return err;
+}
+
+void MediaCodecSource::signalEOS(status_t err) {
+ if (!mEncodedReachedEOS) {
+ ALOGI("encoder (%s) reached EOS", mIsVideo ? "video" : "audio");
+ {
+ Mutex::Autolock autoLock(mOutputBufferLock);
+ // release all unread media buffers
+ for (List<MediaBuffer*>::iterator it = mOutputBufferQueue.begin();
+ it != mOutputBufferQueue.end(); it++) {
+ (*it)->release();
+ }
+ mOutputBufferQueue.clear();
+ mEncodedReachedEOS = true;
+ mErrorCode = err;
+ mOutputBufferCond.signal();
+ }
+
+ releaseEncoder();
+ }
+ if (mStopping && reachedEOS()) {
+ ALOGI("MediaCodecSource (%s) fully stopped",
+ mIsVideo ? "video" : "audio");
+ // posting reply to everyone that's waiting
+ List<uint32_t>::iterator it;
+ for (it = mStopReplyIDQueue.begin();
+ it != mStopReplyIDQueue.end(); it++) {
+ (new AMessage)->postReply(*it);
+ }
+ mStopReplyIDQueue.clear();
+ mStopping = false;
+ }
+}
+
+void MediaCodecSource::suspend() {
+ CHECK(mFlags & FLAG_USE_SURFACE_INPUT);
+ if (mEncoder != NULL) {
+ sp<AMessage> params = new AMessage;
+ params->setInt32("drop-input-frames", true);
+ mEncoder->setParameters(params);
+ }
+}
+
+void MediaCodecSource::resume(int64_t skipFramesBeforeUs) {
+ CHECK(mFlags & FLAG_USE_SURFACE_INPUT);
+ if (mEncoder != NULL) {
+ sp<AMessage> params = new AMessage;
+ params->setInt32("drop-input-frames", false);
+ if (skipFramesBeforeUs > 0) {
+ params->setInt64("skip-frames-before", skipFramesBeforeUs);
+ }
+ mEncoder->setParameters(params);
+ }
+}
+
+void MediaCodecSource::scheduleDoMoreWork() {
+ if (mDoMoreWorkPending) {
+ return;
+ }
+
+ mDoMoreWorkPending = true;
+
+ if (mEncoderActivityNotify == NULL) {
+ mEncoderActivityNotify = new AMessage(
+ kWhatEncoderActivity, mReflector->id());
+ }
+ mEncoder->requestActivityNotification(mEncoderActivityNotify);
+}
+
+status_t MediaCodecSource::feedEncoderInputBuffers() {
+ while (!mInputBufferQueue.empty()
+ && !mAvailEncoderInputIndices.empty()) {
+ MediaBuffer* mbuf = *mInputBufferQueue.begin();
+ mInputBufferQueue.erase(mInputBufferQueue.begin());
+
+ size_t bufferIndex = *mAvailEncoderInputIndices.begin();
+ mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin());
+
+ int64_t timeUs = 0ll;
+ uint32_t flags = 0;
+ size_t size = 0;
+
+ if (mbuf != NULL) {
+ CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs));
+
+ // push decoding time for video, or drift time for audio
+ if (mIsVideo) {
+ mDecodingTimeQueue.push_back(timeUs);
+ } else {
+#if DEBUG_DRIFT_TIME
+ if (mFirstSampleTimeUs < 0ll) {
+ mFirstSampleTimeUs = timeUs;
+ }
+
+ int64_t driftTimeUs = 0;
+ if (mbuf->meta_data()->findInt64(kKeyDriftTime, &driftTimeUs)
+ && driftTimeUs) {
+ driftTimeUs = timeUs - mFirstSampleTimeUs - driftTimeUs;
+ }
+ mDriftTimeQueue.push_back(driftTimeUs);
+#endif // DEBUG_DRIFT_TIME
+ }
+
+ size = mbuf->size();
+
+ memcpy(mEncoderInputBuffers.itemAt(bufferIndex)->data(),
+ mbuf->data(), size);
+
+ if (mIsVideo) {
+ // video encoder will release MediaBuffer when done
+ // with underlying data.
+ mEncoderInputBuffers.itemAt(bufferIndex)->meta()
+ ->setPointer("mediaBuffer", mbuf);
+ } else {
+ mbuf->release();
+ }
+ } else {
+ flags = MediaCodec::BUFFER_FLAG_EOS;
+ }
+
+ status_t err = mEncoder->queueInputBuffer(
+ bufferIndex, 0, size, timeUs, flags);
+
+ if (err != OK) {
+ return err;
+ }
+ }
+
+ return OK;
+}
+
+status_t MediaCodecSource::doMoreWork() {
+ status_t err;
+
+ if (!(mFlags & FLAG_USE_SURFACE_INPUT)) {
+ for (;;) {
+ size_t bufferIndex;
+ err = mEncoder->dequeueInputBuffer(&bufferIndex);
+
+ if (err != OK) {
+ break;
+ }
+
+ mAvailEncoderInputIndices.push_back(bufferIndex);
+ }
+
+ feedEncoderInputBuffers();
+ }
+
+ for (;;) {
+ size_t bufferIndex;
+ size_t offset;
+ size_t size;
+ int64_t timeUs;
+ uint32_t flags;
+ native_handle_t* handle = NULL;
+ err = mEncoder->dequeueOutputBuffer(
+ &bufferIndex, &offset, &size, &timeUs, &flags);
+
+ if (err != OK) {
+ if (err == INFO_FORMAT_CHANGED) {
+ continue;
+ } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) {
+ mEncoder->getOutputBuffers(&mEncoderOutputBuffers);
+ continue;
+ }
+
+ if (err == -EAGAIN) {
+ err = OK;
+ }
+ break;
+ }
+ if (!(flags & MediaCodec::BUFFER_FLAG_EOS)) {
+ sp<ABuffer> outbuf = mEncoderOutputBuffers.itemAt(bufferIndex);
+
+ MediaBuffer *mbuf = new MediaBuffer(outbuf->size());
+ memcpy(mbuf->data(), outbuf->data(), outbuf->size());
+
+ if (!(flags & MediaCodec::BUFFER_FLAG_CODECCONFIG)) {
+ if (mIsVideo) {
+ int64_t decodingTimeUs;
+ if (mFlags & FLAG_USE_SURFACE_INPUT) {
+ // GraphicBufferSource is supposed to discard samples
+ // queued before start, and offset timeUs by start time
+ CHECK_GE(timeUs, 0ll);
+ // TODO:
+ // Decoding time for surface source is unavailable,
+ // use presentation time for now. May need to move
+ // this logic into MediaCodec.
+ decodingTimeUs = timeUs;
+ } else {
+ CHECK(!mDecodingTimeQueue.empty());
+ decodingTimeUs = *(mDecodingTimeQueue.begin());
+ mDecodingTimeQueue.erase(mDecodingTimeQueue.begin());
+ }
+ mbuf->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs);
+
+ ALOGV("[video] time %lld us (%.2f secs), dts/pts diff %lld",
+ timeUs, timeUs / 1E6, decodingTimeUs - timeUs);
+ } else {
+ int64_t driftTimeUs = 0;
+#if DEBUG_DRIFT_TIME
+ CHECK(!mDriftTimeQueue.empty());
+ driftTimeUs = *(mDriftTimeQueue.begin());
+ mDriftTimeQueue.erase(mDriftTimeQueue.begin());
+ mbuf->meta_data()->setInt64(kKeyDriftTime, driftTimeUs);
+#endif // DEBUG_DRIFT_TIME
+ ALOGV("[audio] time %lld us (%.2f secs), drift %lld",
+ timeUs, timeUs / 1E6, driftTimeUs);
+ }
+ mbuf->meta_data()->setInt64(kKeyTime, timeUs);
+ } else {
+ mbuf->meta_data()->setInt32(kKeyIsCodecConfig, true);
+ }
+ if (flags & MediaCodec::BUFFER_FLAG_SYNCFRAME) {
+ mbuf->meta_data()->setInt32(kKeyIsSyncFrame, true);
+ }
+ mbuf->setObserver(this);
+ mbuf->add_ref();
+
+ {
+ Mutex::Autolock autoLock(mOutputBufferLock);
+ mOutputBufferQueue.push_back(mbuf);
+ mOutputBufferCond.signal();
+ }
+ }
+
+ mEncoder->releaseOutputBuffer(bufferIndex);
+
+ if (flags & MediaCodec::BUFFER_FLAG_EOS) {
+ err = ERROR_END_OF_STREAM;
+ break;
+ }
+ }
+
+ return err;
+}
+
+status_t MediaCodecSource::onStart(MetaData *params) {
+ if (mStopping) {
+ ALOGE("Failed to start while we're stopping");
+ return INVALID_OPERATION;
+ }
+
+ if (mStarted) {
+ ALOGI("MediaCodecSource (%s) resuming", mIsVideo ? "video" : "audio");
+ if (mFlags & FLAG_USE_SURFACE_INPUT) {
+ resume();
+ } else {
+ CHECK(mPuller != NULL);
+ mPuller->resume();
+ }
+ return OK;
+ }
+
+ ALOGI("MediaCodecSource (%s) starting", mIsVideo ? "video" : "audio");
+
+ status_t err = OK;
+
+ if (mFlags & FLAG_USE_SURFACE_INPUT) {
+ int64_t startTimeUs;
+ if (!params || !params->findInt64(kKeyTime, &startTimeUs)) {
+ startTimeUs = -1ll;
+ }
+ resume(startTimeUs);
+ scheduleDoMoreWork();
+ } else {
+ CHECK(mPuller != NULL);
+ sp<AMessage> notify = new AMessage(
+ kWhatPullerNotify, mReflector->id());
+ err = mPuller->start(params, notify);
+ if (err != OK) {
+ mPullerReachedEOS = true;
+ return err;
+ }
+ }
+
+ ALOGI("MediaCodecSource (%s) started", mIsVideo ? "video" : "audio");
+
+ mStarted = true;
+ return OK;
+}
+
+void MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) {
+ switch (msg->what()) {
+ case kWhatPullerNotify:
+ {
+ MediaBuffer *mbuf;
+ CHECK(msg->findPointer("accessUnit", (void**)&mbuf));
+
+ if (mbuf == NULL) {
+ ALOGI("puller (%s) reached EOS",
+ mIsVideo ? "video" : "audio");
+ mPullerReachedEOS = true;
+ }
+
+ if (mEncoder == NULL) {
+ ALOGV("got msg '%s' after encoder shutdown.",
+ msg->debugString().c_str());
+
+ if (mbuf != NULL) {
+ mbuf->release();
+ } else {
+ signalEOS();
+ }
+ break;
+ }
+
+ mInputBufferQueue.push_back(mbuf);
+
+ feedEncoderInputBuffers();
+ scheduleDoMoreWork();
+
+ break;
+ }
+ case kWhatEncoderActivity:
+ {
+ mDoMoreWorkPending = false;
+
+ if (mEncoder == NULL) {
+ break;
+ }
+
+ status_t err = doMoreWork();
+
+ if (err == OK) {
+ scheduleDoMoreWork();
+ } else {
+ // reached EOS, or error
+ signalEOS(err);
+ }
+
+ break;
+ }
+ case kWhatStart:
+ {
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ sp<RefBase> obj;
+ CHECK(msg->findObject("meta", &obj));
+ MetaData *params = static_cast<MetaData *>(obj.get());
+
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", onStart(params));
+ response->postReply(replyID);
+ break;
+ }
+ case kWhatStop:
+ {
+ ALOGI("MediaCodecSource (%s) stopping", mIsVideo ? "video" : "audio");
+
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ if (reachedEOS()) {
+ // if we already reached EOS, reply and return now
+ ALOGI("MediaCodecSource (%s) already stopped",
+ mIsVideo ? "video" : "audio");
+ (new AMessage)->postReply(replyID);
+ break;
+ }
+
+ mStopReplyIDQueue.push_back(replyID);
+ if (mStopping) {
+ // nothing to do if we're already stopping, reply will be posted
+ // to all when we're stopped.
+ break;
+ }
+
+ mStopping = true;
+
+ // if using surface, signal source EOS and wait for EOS to come back.
+ // otherwise, release encoder and post EOS if haven't done already
+ if (mFlags & FLAG_USE_SURFACE_INPUT) {
+ mEncoder->signalEndOfInputStream();
+ } else {
+ CHECK(mPuller != NULL);
+ mPuller->stopAsync();
+ signalEOS();
+ }
+ break;
+ }
+ case kWhatPause:
+ {
+ if (mFlags && FLAG_USE_SURFACE_INPUT) {
+ suspend();
+ } else {
+ CHECK(mPuller != NULL);
+ mPuller->pause();
+ }
+ break;
+ }
+ default:
+ TRESPASS();
+ }
+}
+
+} // namespace android
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index 05e599b..72ea32d 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -213,7 +213,14 @@ NuCachedSource2::NuCachedSource2(
mLooper->setName("NuCachedSource2");
mLooper->registerHandler(mReflector);
- mLooper->start();
+
+ // Since it may not be obvious why our looper thread needs to be
+ // able to call into java since it doesn't appear to do so at all...
+ // IMediaHTTPConnection may be (and most likely is) implemented in JAVA
+ // and a local JAVA IBinder will call directly into JNI methods.
+ // So whenever we call DataSource::readAt it may end up in a call to
+ // IMediaHTTPConnection::readAt and therefore call back into JAVA.
+ mLooper->start(false /* runOnCallingThread */, true /* canCallJava */);
Mutex::Autolock autoLock(mLock);
(new AMessage(kWhatFetchMore, mReflector->id()))->post();
@@ -326,7 +333,7 @@ void NuCachedSource2::fetchInternal() {
mNumRetriesLeft = 0;
}
- ALOGE("source returned error %ld, %d retries left", n, mNumRetriesLeft);
+ ALOGE("source returned error %d, %d retries left", n, mNumRetriesLeft);
mCache->releasePage(page);
} else if (n == 0) {
ALOGI("ERROR_END_OF_STREAM");
@@ -641,7 +648,7 @@ void NuCachedSource2::updateCacheParamsFromString(const char *s) {
ssize_t lowwaterMarkKb, highwaterMarkKb;
int keepAliveSecs;
- if (sscanf(s, "%ld/%ld/%d",
+ if (sscanf(s, "%d/%d/%d",
&lowwaterMarkKb, &highwaterMarkKb, &keepAliveSecs) != 3) {
ALOGE("Failed to parse cache parameters from '%s'.", s);
return;
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 7bc7da2..64f56e9 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -58,7 +58,9 @@ NuMediaExtractor::~NuMediaExtractor() {
}
status_t NuMediaExtractor::setDataSource(
- const char *path, const KeyedVector<String8, String8> *headers) {
+ const sp<IMediaHTTPService> &httpService,
+ const char *path,
+ const KeyedVector<String8, String8> *headers) {
Mutex::Autolock autoLock(mLock);
if (mImpl != NULL) {
@@ -66,7 +68,7 @@ status_t NuMediaExtractor::setDataSource(
}
sp<DataSource> dataSource =
- DataSource::CreateFromURI(path, headers);
+ DataSource::CreateFromURI(httpService, path, headers);
if (dataSource == NULL) {
return -ENOENT;
diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp
index 5e79e78..f3eeb03 100644
--- a/media/libstagefright/OggExtractor.cpp
+++ b/media/libstagefright/OggExtractor.cpp
@@ -151,7 +151,7 @@ sp<MetaData> OggSource::getFormat() {
return mExtractor->mImpl->getFormat();
}
-status_t OggSource::start(MetaData *params) {
+status_t OggSource::start(MetaData * /* params */) {
if (mStarted) {
return INVALID_OPERATION;
}
@@ -381,7 +381,7 @@ ssize_t MyVorbisExtractor::readPage(off64_t offset, Page *page) {
ssize_t n;
if ((n = mSource->readAt(offset, header, sizeof(header)))
< (ssize_t)sizeof(header)) {
- ALOGV("failed to read %d bytes at offset 0x%016llx, got %ld bytes",
+ ALOGV("failed to read %zu bytes at offset 0x%016llx, got %d bytes",
sizeof(header), offset, n);
if (n < 0) {
@@ -505,7 +505,7 @@ status_t MyVorbisExtractor::readNextPacket(MediaBuffer **out) {
packetSize);
if (n < (ssize_t)packetSize) {
- ALOGV("failed to read %d bytes at 0x%016llx, got %ld bytes",
+ ALOGV("failed to read %zu bytes at 0x%016llx, got %d bytes",
packetSize, dataOffset, n);
return ERROR_IO;
}
@@ -546,7 +546,7 @@ status_t MyVorbisExtractor::readNextPacket(MediaBuffer **out) {
buffer = NULL;
}
- ALOGV("readPage returned %ld", n);
+ ALOGV("readPage returned %d", n);
return n < 0 ? n : (status_t)ERROR_END_OF_STREAM;
}
@@ -998,7 +998,7 @@ sp<MediaSource> OggExtractor::getTrack(size_t index) {
}
sp<MetaData> OggExtractor::getTrackMetaData(
- size_t index, uint32_t flags) {
+ size_t index, uint32_t /* flags */) {
if (index >= 1) {
return NULL;
}
diff --git a/media/libstagefright/SkipCutBuffer.cpp b/media/libstagefright/SkipCutBuffer.cpp
index 773854f..e2e6d79 100644
--- a/media/libstagefright/SkipCutBuffer.cpp
+++ b/media/libstagefright/SkipCutBuffer.cpp
@@ -25,7 +25,7 @@
namespace android {
SkipCutBuffer::SkipCutBuffer(int32_t skip, int32_t cut) {
- mFrontPadding = skip;
+ mFrontPadding = mSkip = skip;
mBackPadding = cut;
mWriteHead = 0;
mReadHead = 0;
@@ -94,6 +94,7 @@ void SkipCutBuffer::submit(const sp<ABuffer>& buffer) {
void SkipCutBuffer::clear() {
mWriteHead = mReadHead = 0;
+ mFrontPadding = mSkip;
}
void SkipCutBuffer::write(const char *src, size_t num) {
diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp
index af8186c..fe20835 100644
--- a/media/libstagefright/StagefrightMediaScanner.cpp
+++ b/media/libstagefright/StagefrightMediaScanner.cpp
@@ -24,6 +24,7 @@
#include <media/stagefright/StagefrightMediaScanner.h>
+#include <media/IMediaHTTPService.h>
#include <media/mediametadataretriever.h>
#include <private/media/VideoFrame.h>
@@ -117,7 +118,7 @@ MediaScanResult StagefrightMediaScanner::processFile(
}
MediaScanResult StagefrightMediaScanner::processFileInternal(
- const char *path, const char *mimeType,
+ const char *path, const char * /* mimeType */,
MediaScannerClient &client) {
const char *extension = strrchr(path, '.');
@@ -147,7 +148,7 @@ MediaScanResult StagefrightMediaScanner::processFileInternal(
status_t status;
if (fd < 0) {
// couldn't open it locally, maybe the media server can?
- status = mRetriever->setDataSource(path);
+ status = mRetriever->setDataSource(NULL /* httpService */, path);
} else {
status = mRetriever->setDataSource(fd, 0, 0x7ffffffffffffffL);
close(fd);
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index fcd9a85..9475d05 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -21,6 +21,7 @@
#include "include/StagefrightMetadataRetriever.h"
+#include <media/IMediaHTTPService.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/ColorConverter.h>
#include <media/stagefright/DataSource.h>
@@ -51,7 +52,9 @@ StagefrightMetadataRetriever::~StagefrightMetadataRetriever() {
}
status_t StagefrightMetadataRetriever::setDataSource(
- const char *uri, const KeyedVector<String8, String8> *headers) {
+ const sp<IMediaHTTPService> &httpService,
+ const char *uri,
+ const KeyedVector<String8, String8> *headers) {
ALOGV("setDataSource(%s)", uri);
mParsedMetaData = false;
@@ -59,7 +62,7 @@ status_t StagefrightMetadataRetriever::setDataSource(
delete mAlbumArt;
mAlbumArt = NULL;
- mSource = DataSource::CreateFromURI(uri, headers);
+ mSource = DataSource::CreateFromURI(httpService, uri, headers);
if (mSource == NULL) {
ALOGE("Unable to create data source for '%s'.", uri);
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index 6b934d4..10c00f4 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -99,8 +99,11 @@ void SurfaceMediaSource::dump(String8& result) const
dump(result, "", buffer, 1024);
}
-void SurfaceMediaSource::dump(String8& result, const char* prefix,
- char* buffer, size_t SIZE) const
+void SurfaceMediaSource::dump(
+ String8& result,
+ const char* /* prefix */,
+ char* buffer,
+ size_t /* SIZE */) const
{
Mutex::Autolock lock(mMutex);
@@ -202,6 +205,9 @@ status_t SurfaceMediaSource::stop()
return OK;
}
+ mStarted = false;
+ mFrameAvailableCondition.signal();
+
while (mNumPendingBuffers > 0) {
ALOGI("Still waiting for %d buffers to be returned.",
mNumPendingBuffers);
@@ -215,8 +221,6 @@ status_t SurfaceMediaSource::stop()
mMediaBuffersAvailableCondition.wait(mMutex);
}
- mStarted = false;
- mFrameAvailableCondition.signal();
mMediaBuffersAvailableCondition.signal();
return mBufferQueue->consumerDisconnect();
@@ -269,9 +273,8 @@ static void passMetadataBuffer(MediaBuffer **buffer,
bufferHandle, (*buffer)->range_length(), (*buffer)->range_offset());
}
-status_t SurfaceMediaSource::read( MediaBuffer **buffer,
- const ReadOptions *options)
-{
+status_t SurfaceMediaSource::read(
+ MediaBuffer **buffer, const ReadOptions * /* options */) {
ALOGV("read");
Mutex::Autolock lock(mMutex);
diff --git a/media/libstagefright/TimedEventQueue.cpp b/media/libstagefright/TimedEventQueue.cpp
index 0afac69..3d2eb1f 100644
--- a/media/libstagefright/TimedEventQueue.cpp
+++ b/media/libstagefright/TimedEventQueue.cpp
@@ -376,8 +376,8 @@ void TimedEventQueue::clearPowerManager()
mPowerManager.clear();
}
-void TimedEventQueue::PMDeathRecipient::binderDied(const wp<IBinder>& who)
-{
+void TimedEventQueue::PMDeathRecipient::binderDied(
+ const wp<IBinder>& /* who */) {
mQueue->clearPowerManager();
}
diff --git a/media/libstagefright/VBRISeeker.cpp b/media/libstagefright/VBRISeeker.cpp
index a245f2c..af858b9 100644
--- a/media/libstagefright/VBRISeeker.cpp
+++ b/media/libstagefright/VBRISeeker.cpp
@@ -119,7 +119,7 @@ sp<VBRISeeker> VBRISeeker::CreateFromSource(
seeker->mSegments.push(numBytes);
- ALOGV("entry #%d: %d offset 0x%08lx", i, numBytes, offset);
+ ALOGV("entry #%d: %u offset 0x%016llx", i, numBytes, offset);
offset += numBytes;
}
@@ -160,7 +160,7 @@ bool VBRISeeker::getOffsetForTime(int64_t *timeUs, off64_t *pos) {
*pos += mSegments.itemAt(segmentIndex++);
}
- ALOGV("getOffsetForTime %lld us => 0x%08lx", *timeUs, *pos);
+ ALOGV("getOffsetForTime %lld us => 0x%016llx", *timeUs, *pos);
*timeUs = nowUs;
diff --git a/media/libstagefright/WAVExtractor.cpp b/media/libstagefright/WAVExtractor.cpp
index 22af6fb..fe9058b 100644
--- a/media/libstagefright/WAVExtractor.cpp
+++ b/media/libstagefright/WAVExtractor.cpp
@@ -127,7 +127,7 @@ sp<MediaSource> WAVExtractor::getTrack(size_t index) {
}
sp<MetaData> WAVExtractor::getTrackMetaData(
- size_t index, uint32_t flags) {
+ size_t index, uint32_t /* flags */) {
if (mInitCheck != OK || index > 0) {
return NULL;
}
@@ -358,7 +358,7 @@ WAVSource::~WAVSource() {
}
}
-status_t WAVSource::start(MetaData *params) {
+status_t WAVSource::start(MetaData * /* params */) {
ALOGV("WAVSource::start");
CHECK(!mStarted);
diff --git a/media/libstagefright/avc_utils.cpp b/media/libstagefright/avc_utils.cpp
index b822868..c6ac0da 100644
--- a/media/libstagefright/avc_utils.cpp
+++ b/media/libstagefright/avc_utils.cpp
@@ -251,9 +251,7 @@ status_t getNextNALUnit(
return OK;
}
-static sp<ABuffer> FindNAL(
- const uint8_t *data, size_t size, unsigned nalType,
- size_t *stopOffset) {
+static sp<ABuffer> FindNAL(const uint8_t *data, size_t size, unsigned nalType) {
const uint8_t *nalStart;
size_t nalSize;
while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
@@ -293,7 +291,7 @@ sp<MetaData> MakeAVCCodecSpecificData(const sp<ABuffer> &accessUnit) {
const uint8_t *data = accessUnit->data();
size_t size = accessUnit->size();
- sp<ABuffer> seqParamSet = FindNAL(data, size, 7, NULL);
+ sp<ABuffer> seqParamSet = FindNAL(data, size, 7);
if (seqParamSet == NULL) {
return NULL;
}
@@ -303,8 +301,7 @@ sp<MetaData> MakeAVCCodecSpecificData(const sp<ABuffer> &accessUnit) {
FindAVCDimensions(
seqParamSet, &width, &height, &sarWidth, &sarHeight);
- size_t stopOffset;
- sp<ABuffer> picParamSet = FindNAL(data, size, 8, &stopOffset);
+ sp<ABuffer> picParamSet = FindNAL(data, size, 8);
CHECK(picParamSet != NULL);
size_t csdSize =
diff --git a/media/libstagefright/chromium_http/Android.mk b/media/libstagefright/chromium_http/Android.mk
deleted file mode 100644
index f26f386..0000000
--- a/media/libstagefright/chromium_http/Android.mk
+++ /dev/null
@@ -1,37 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-ifneq ($(TARGET_BUILD_PDK), true)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- DataUriSource.cpp \
- ChromiumHTTPDataSource.cpp \
- support.cpp \
- chromium_http_stub.cpp
-
-LOCAL_C_INCLUDES:= \
- $(TOP)/frameworks/av/media/libstagefright \
- $(TOP)/frameworks/native/include/media/openmax \
- external/chromium \
- external/chromium/android
-
-LOCAL_CFLAGS += -Wno-multichar
-
-LOCAL_SHARED_LIBRARIES += \
- libstlport \
- libchromium_net \
- libutils \
- libcutils \
- liblog \
- libstagefright_foundation \
- libstagefright \
- libdrmframework
-
-include external/stlport/libstlport.mk
-
-LOCAL_MODULE:= libstagefright_chromium_http
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
-endif
diff --git a/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp b/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
deleted file mode 100644
index 7e5c280..0000000
--- a/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "ChromiumHTTPDataSource"
-#include <media/stagefright/foundation/ADebug.h>
-
-#include "include/ChromiumHTTPDataSource.h"
-
-#include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/MediaErrors.h>
-
-#include "support.h"
-
-#include <cutils/properties.h> // for property_get
-
-namespace android {
-
-ChromiumHTTPDataSource::ChromiumHTTPDataSource(uint32_t flags)
- : mFlags(flags),
- mState(DISCONNECTED),
- mDelegate(new SfDelegate),
- mCurrentOffset(0),
- mIOResult(OK),
- mContentSize(-1),
- mDecryptHandle(NULL),
- mDrmManagerClient(NULL) {
- mDelegate->setOwner(this);
-}
-
-ChromiumHTTPDataSource::~ChromiumHTTPDataSource() {
- disconnect();
-
- delete mDelegate;
- mDelegate = NULL;
-
- clearDRMState_l();
-
- if (mDrmManagerClient != NULL) {
- delete mDrmManagerClient;
- mDrmManagerClient = NULL;
- }
-}
-
-status_t ChromiumHTTPDataSource::connect(
- const char *uri,
- const KeyedVector<String8, String8> *headers,
- off64_t offset) {
- Mutex::Autolock autoLock(mLock);
-
- uid_t uid;
- if (getUID(&uid)) {
- mDelegate->setUID(uid);
- }
-
-#if defined(LOG_NDEBUG) && !LOG_NDEBUG
- LOG_PRI(ANDROID_LOG_VERBOSE, LOG_TAG, "connect on behalf of uid %d", uid);
-#endif
-
- return connect_l(uri, headers, offset);
-}
-
-status_t ChromiumHTTPDataSource::connect_l(
- const char *uri,
- const KeyedVector<String8, String8> *headers,
- off64_t offset) {
- if (mState != DISCONNECTED) {
- disconnect_l();
- }
-
-#if defined(LOG_NDEBUG) && !LOG_NDEBUG
- LOG_PRI(ANDROID_LOG_VERBOSE, LOG_TAG,
- "connect to <URL suppressed> @%lld", offset);
-#endif
-
- mURI = uri;
- mContentType = String8("application/octet-stream");
-
- if (headers != NULL) {
- mHeaders = *headers;
- } else {
- mHeaders.clear();
- }
-
- mState = CONNECTING;
- mContentSize = -1;
- mCurrentOffset = offset;
-
- mDelegate->initiateConnection(mURI.c_str(), &mHeaders, offset);
-
- while (mState == CONNECTING || mState == DISCONNECTING) {
- mCondition.wait(mLock);
- }
-
- return mState == CONNECTED ? OK : mIOResult;
-}
-
-void ChromiumHTTPDataSource::onRedirect(const char *url) {
- Mutex::Autolock autoLock(mLock);
- mURI = url;
-}
-
-void ChromiumHTTPDataSource::onConnectionEstablished(
- int64_t contentSize, const char *contentType) {
- Mutex::Autolock autoLock(mLock);
-
- if (mState != CONNECTING) {
- // We may have initiated disconnection.
- CHECK_EQ(mState, DISCONNECTING);
- return;
- }
-
- mState = CONNECTED;
- mContentSize = (contentSize < 0) ? -1 : contentSize + mCurrentOffset;
- mContentType = String8(contentType);
- mCondition.broadcast();
-}
-
-void ChromiumHTTPDataSource::onConnectionFailed(status_t err) {
- Mutex::Autolock autoLock(mLock);
- mState = DISCONNECTED;
- mCondition.broadcast();
-
- // mURI.clear();
-
- mIOResult = err;
-}
-
-void ChromiumHTTPDataSource::disconnect() {
- Mutex::Autolock autoLock(mLock);
- disconnect_l();
-}
-
-void ChromiumHTTPDataSource::disconnect_l() {
- if (mState == DISCONNECTED) {
- return;
- }
-
- mState = DISCONNECTING;
- mIOResult = -EINTR;
-
- mDelegate->initiateDisconnect();
-
- while (mState == DISCONNECTING) {
- mCondition.wait(mLock);
- }
-
- CHECK_EQ((int)mState, (int)DISCONNECTED);
-}
-
-status_t ChromiumHTTPDataSource::initCheck() const {
- Mutex::Autolock autoLock(mLock);
-
- return mState == CONNECTED ? OK : NO_INIT;
-}
-
-ssize_t ChromiumHTTPDataSource::readAt(off64_t offset, void *data, size_t size) {
- Mutex::Autolock autoLock(mLock);
-
- if (mState != CONNECTED) {
- return INVALID_OPERATION;
- }
-
-#if 0
- char value[PROPERTY_VALUE_MAX];
- if (property_get("media.stagefright.disable-net", value, 0)
- && (!strcasecmp(value, "true") || !strcmp(value, "1"))) {
- LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "Simulating that the network is down.");
- disconnect_l();
- return ERROR_IO;
- }
-#endif
-
- if (offset != mCurrentOffset) {
- AString tmp = mURI;
- KeyedVector<String8, String8> tmpHeaders = mHeaders;
-
- disconnect_l();
-
- status_t err = connect_l(tmp.c_str(), &tmpHeaders, offset);
-
- if (err != OK) {
- return err;
- }
- }
-
- mState = READING;
-
- int64_t startTimeUs = ALooper::GetNowUs();
-
- mDelegate->initiateRead(data, size);
-
- while (mState == READING) {
- mCondition.wait(mLock);
- }
-
- if (mIOResult < OK) {
- return mIOResult;
- }
-
- if (mState == CONNECTED) {
- int64_t delayUs = ALooper::GetNowUs() - startTimeUs;
-
- // The read operation was successful, mIOResult contains
- // the number of bytes read.
- addBandwidthMeasurement(mIOResult, delayUs);
-
- mCurrentOffset += mIOResult;
- return mIOResult;
- }
-
- return ERROR_IO;
-}
-
-void ChromiumHTTPDataSource::onReadCompleted(ssize_t size) {
- Mutex::Autolock autoLock(mLock);
-
- mIOResult = size;
-
- if (mState == READING) {
- mState = CONNECTED;
- mCondition.broadcast();
- }
-}
-
-status_t ChromiumHTTPDataSource::getSize(off64_t *size) {
- Mutex::Autolock autoLock(mLock);
-
- if (mContentSize < 0) {
- return ERROR_UNSUPPORTED;
- }
-
- *size = mContentSize;
-
- return OK;
-}
-
-uint32_t ChromiumHTTPDataSource::flags() {
- return kWantsPrefetching | kIsHTTPBasedSource;
-}
-
-// static
-void ChromiumHTTPDataSource::InitiateRead(
- ChromiumHTTPDataSource *me, void *data, size_t size) {
- me->initiateRead(data, size);
-}
-
-void ChromiumHTTPDataSource::initiateRead(void *data, size_t size) {
- mDelegate->initiateRead(data, size);
-}
-
-void ChromiumHTTPDataSource::onDisconnectComplete() {
- Mutex::Autolock autoLock(mLock);
- CHECK_EQ((int)mState, (int)DISCONNECTING);
-
- mState = DISCONNECTED;
- // mURI.clear();
- mIOResult = -ENOTCONN;
-
- mCondition.broadcast();
-}
-
-sp<DecryptHandle> ChromiumHTTPDataSource::DrmInitialization(const char* mime) {
- Mutex::Autolock autoLock(mLock);
-
- if (mDrmManagerClient == NULL) {
- mDrmManagerClient = new DrmManagerClient();
- }
-
- if (mDrmManagerClient == NULL) {
- return NULL;
- }
-
- if (mDecryptHandle == NULL) {
- /* Note if redirect occurs, mUri is the redirect uri instead of the
- * original one
- */
- mDecryptHandle = mDrmManagerClient->openDecryptSession(
- String8(mURI.c_str()), mime);
- }
-
- if (mDecryptHandle == NULL) {
- delete mDrmManagerClient;
- mDrmManagerClient = NULL;
- }
-
- return mDecryptHandle;
-}
-
-void ChromiumHTTPDataSource::getDrmInfo(
- sp<DecryptHandle> &handle, DrmManagerClient **client) {
- Mutex::Autolock autoLock(mLock);
-
- handle = mDecryptHandle;
- *client = mDrmManagerClient;
-}
-
-String8 ChromiumHTTPDataSource::getUri() {
- Mutex::Autolock autoLock(mLock);
-
- return String8(mURI.c_str());
-}
-
-String8 ChromiumHTTPDataSource::getMIMEType() const {
- Mutex::Autolock autoLock(mLock);
-
- return mContentType;
-}
-
-void ChromiumHTTPDataSource::clearDRMState_l() {
- if (mDecryptHandle != NULL) {
- // To release mDecryptHandle
- CHECK(mDrmManagerClient);
- mDrmManagerClient->closeDecryptSession(mDecryptHandle);
- mDecryptHandle = NULL;
- }
-}
-
-status_t ChromiumHTTPDataSource::reconnectAtOffset(off64_t offset) {
- Mutex::Autolock autoLock(mLock);
-
- if (mURI.empty()) {
- return INVALID_OPERATION;
- }
-
- LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "Reconnecting...");
- status_t err = connect_l(mURI.c_str(), &mHeaders, offset);
- if (err != OK) {
- LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "Reconnect failed w/ err 0x%08x", err);
- }
-
- return err;
-}
-
-// static
-status_t ChromiumHTTPDataSource::UpdateProxyConfig(
- const char *host, int32_t port, const char *exclusionList) {
- return SfDelegate::UpdateProxyConfig(host, port, exclusionList);
-}
-
-} // namespace android
-
diff --git a/media/libstagefright/chromium_http/DataUriSource.cpp b/media/libstagefright/chromium_http/DataUriSource.cpp
deleted file mode 100644
index ecf3fa1..0000000
--- a/media/libstagefright/chromium_http/DataUriSource.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <include/DataUriSource.h>
-
-#include <net/base/data_url.h>
-#include <googleurl/src/gurl.h>
-
-
-namespace android {
-
-DataUriSource::DataUriSource(const char *uri) :
- mDataUri(uri),
- mInited(NO_INIT) {
-
- // Copy1: const char *uri -> String8 mDataUri.
- std::string mimeTypeStr, unusedCharsetStr, dataStr;
- // Copy2: String8 mDataUri -> std::string
- const bool ret = net::DataURL::Parse(
- GURL(std::string(mDataUri.string())),
- &mimeTypeStr, &unusedCharsetStr, &dataStr);
- // Copy3: std::string dataStr -> AString mData
- mData.setTo(dataStr.data(), dataStr.length());
- mInited = ret ? OK : UNKNOWN_ERROR;
-
- // The chromium data url implementation defaults to using "text/plain"
- // if no mime type is specified. We prefer to leave this unspecified
- // instead, since the mime type is sniffed in most cases.
- if (mimeTypeStr != "text/plain") {
- mMimeType = mimeTypeStr.c_str();
- }
-}
-
-ssize_t DataUriSource::readAt(off64_t offset, void *out, size_t size) {
- if (mInited != OK) {
- return mInited;
- }
-
- const off64_t length = mData.size();
- if (offset >= length) {
- return UNKNOWN_ERROR;
- }
-
- const char *dataBuf = mData.c_str();
- const size_t bytesToCopy =
- offset + size >= length ? (length - offset) : size;
-
- if (bytesToCopy > 0) {
- memcpy(out, dataBuf + offset, bytesToCopy);
- }
-
- return bytesToCopy;
-}
-
-} // namespace android
diff --git a/media/libstagefright/chromium_http/chromium_http_stub.cpp b/media/libstagefright/chromium_http/chromium_http_stub.cpp
deleted file mode 100644
index 289f6de..0000000
--- a/media/libstagefright/chromium_http/chromium_http_stub.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <dlfcn.h>
-
-#include <include/chromium_http_stub.h>
-#include <include/ChromiumHTTPDataSource.h>
-#include <include/DataUriSource.h>
-
-namespace android {
-
-HTTPBase *createChromiumHTTPDataSource(uint32_t flags) {
- return new ChromiumHTTPDataSource(flags);
-}
-
-status_t UpdateChromiumHTTPDataSourceProxyConfig(
- const char *host, int32_t port, const char *exclusionList) {
- return ChromiumHTTPDataSource::UpdateProxyConfig(host, port, exclusionList);
-}
-
-DataSource *createDataUriSource(const char *uri) {
- return new DataUriSource(uri);
-}
-
-}
diff --git a/media/libstagefright/chromium_http/support.cpp b/media/libstagefright/chromium_http/support.cpp
deleted file mode 100644
index 3b33212..0000000
--- a/media/libstagefright/chromium_http/support.cpp
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "ChromiumHTTPDataSourceSupport"
-#include <utils/Log.h>
-
-#include <media/stagefright/foundation/AString.h>
-
-#include "support.h"
-
-#include "android/net/android_network_library_impl.h"
-#include "base/logging.h"
-#include "base/threading/thread.h"
-#include "net/base/cert_verifier.h"
-#include "net/base/cookie_monster.h"
-#include "net/base/host_resolver.h"
-#include "net/base/ssl_config_service.h"
-#include "net/http/http_auth_handler_factory.h"
-#include "net/http/http_cache.h"
-#include "net/proxy/proxy_config_service_android.h"
-
-#include "include/ChromiumHTTPDataSource.h"
-
-#include <cutils/log.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/Utils.h>
-#include <string>
-
-namespace android {
-
-static Mutex gNetworkThreadLock;
-static base::Thread *gNetworkThread = NULL;
-static scoped_refptr<SfRequestContext> gReqContext;
-static scoped_ptr<net::NetworkChangeNotifier> gNetworkChangeNotifier;
-
-bool logMessageHandler(
- int severity,
- const char* file,
- int line,
- size_t message_start,
- const std::string& str) {
- int androidSeverity = ANDROID_LOG_VERBOSE;
- switch(severity) {
- case logging::LOG_FATAL:
- androidSeverity = ANDROID_LOG_FATAL;
- break;
- case logging::LOG_ERROR_REPORT:
- case logging::LOG_ERROR:
- androidSeverity = ANDROID_LOG_ERROR;
- break;
- case logging::LOG_WARNING:
- androidSeverity = ANDROID_LOG_WARN;
- break;
- default:
- androidSeverity = ANDROID_LOG_VERBOSE;
- break;
- }
- android_printLog(androidSeverity, "chromium-libstagefright",
- "%s:%d: %s", file, line, str.c_str());
- return false;
-}
-
-struct AutoPrioritySaver {
- AutoPrioritySaver()
- : mTID(androidGetTid()),
- mPrevPriority(androidGetThreadPriority(mTID)) {
- androidSetThreadPriority(mTID, ANDROID_PRIORITY_NORMAL);
- }
-
- ~AutoPrioritySaver() {
- androidSetThreadPriority(mTID, mPrevPriority);
- }
-
-private:
- pid_t mTID;
- int mPrevPriority;
-
- DISALLOW_EVIL_CONSTRUCTORS(AutoPrioritySaver);
-};
-
-static void InitializeNetworkThreadIfNecessary() {
- Mutex::Autolock autoLock(gNetworkThreadLock);
-
- if (gNetworkThread == NULL) {
- // Make sure any threads spawned by the chromium framework are
- // running at normal priority instead of inheriting this thread's.
- AutoPrioritySaver saver;
-
- gNetworkThread = new base::Thread("network");
- base::Thread::Options options;
- options.message_loop_type = MessageLoop::TYPE_IO;
- CHECK(gNetworkThread->StartWithOptions(options));
-
- gReqContext = new SfRequestContext;
-
- gNetworkChangeNotifier.reset(net::NetworkChangeNotifier::Create());
-
- net::AndroidNetworkLibrary::RegisterSharedInstance(
- new SfNetworkLibrary);
- logging::SetLogMessageHandler(logMessageHandler);
- }
-}
-
-static void MY_LOGI(const char *s) {
- LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "%s", s);
-}
-
-static void MY_LOGV(const char *s) {
-#if !defined(LOG_NDEBUG) || LOG_NDEBUG == 0
- LOG_PRI(ANDROID_LOG_VERBOSE, LOG_TAG, "%s", s);
-#endif
-}
-
-SfNetLog::SfNetLog()
- : mNextID(1) {
-}
-
-void SfNetLog::AddEntry(
- EventType type,
- const base::TimeTicks &time,
- const Source &source,
- EventPhase phase,
- EventParameters *params) {
-#if 0
- MY_LOGI(StringPrintf(
- "AddEntry time=%s type=%s source=%s phase=%s\n",
- TickCountToString(time).c_str(),
- EventTypeToString(type),
- SourceTypeToString(source.type),
- EventPhaseToString(phase)).c_str());
-#endif
-}
-
-uint32 SfNetLog::NextID() {
- return mNextID++;
-}
-
-net::NetLog::LogLevel SfNetLog::GetLogLevel() const {
- return LOG_BASIC;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-SfRequestContext::SfRequestContext() {
- mUserAgent = MakeUserAgent().c_str();
-
- set_net_log(new SfNetLog());
-
- set_host_resolver(
- net::CreateSystemHostResolver(
- net::HostResolver::kDefaultParallelism,
- NULL /* resolver_proc */,
- net_log()));
-
- set_ssl_config_service(
- net::SSLConfigService::CreateSystemSSLConfigService());
-
- mProxyConfigService = new net::ProxyConfigServiceAndroid;
-
- set_proxy_service(net::ProxyService::CreateWithoutProxyResolver(
- mProxyConfigService, net_log()));
-
- set_http_transaction_factory(new net::HttpCache(
- host_resolver(),
- new net::CertVerifier(),
- dnsrr_resolver(),
- dns_cert_checker(),
- proxy_service(),
- ssl_config_service(),
- net::HttpAuthHandlerFactory::CreateDefault(host_resolver()),
- network_delegate(),
- net_log(),
- NULL)); // backend_factory
-
- set_cookie_store(new net::CookieMonster(NULL, NULL));
-}
-
-const std::string &SfRequestContext::GetUserAgent(const GURL &url) const {
- return mUserAgent;
-}
-
-status_t SfRequestContext::updateProxyConfig(
- const char *host, int32_t port, const char *exclusionList) {
- Mutex::Autolock autoLock(mProxyConfigLock);
-
- if (host == NULL || *host == '\0') {
- MY_LOGV("updateProxyConfig NULL");
-
- std::string proxy;
- std::string exList;
- mProxyConfigService->UpdateProxySettings(proxy, exList);
- } else {
-#if !defined(LOG_NDEBUG) || LOG_NDEBUG == 0
- LOG_PRI(ANDROID_LOG_VERBOSE, LOG_TAG,
- "updateProxyConfig %s:%d, exclude '%s'",
- host, port, exclusionList);
-#endif
-
- std::string proxy = StringPrintf("%s:%d", host, port).c_str();
- std::string exList = exclusionList;
- mProxyConfigService->UpdateProxySettings(proxy, exList);
- }
-
- return OK;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-SfNetworkLibrary::SfNetworkLibrary() {}
-
-SfNetworkLibrary::VerifyResult SfNetworkLibrary::VerifyX509CertChain(
- const std::vector<std::string>& cert_chain,
- const std::string& hostname,
- const std::string& auth_type) {
- return VERIFY_OK;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-SfDelegate::SfDelegate()
- : mOwner(NULL),
- mURLRequest(NULL),
- mReadBuffer(new net::IOBufferWithSize(8192)),
- mNumBytesRead(0),
- mNumBytesTotal(0),
- mDataDestination(NULL),
- mAtEOS(false) {
- InitializeNetworkThreadIfNecessary();
-}
-
-SfDelegate::~SfDelegate() {
- CHECK(mURLRequest == NULL);
-}
-
-// static
-status_t SfDelegate::UpdateProxyConfig(
- const char *host, int32_t port, const char *exclusionList) {
- InitializeNetworkThreadIfNecessary();
-
- return gReqContext->updateProxyConfig(host, port, exclusionList);
-}
-
-void SfDelegate::setOwner(ChromiumHTTPDataSource *owner) {
- mOwner = owner;
-}
-
-void SfDelegate::setUID(uid_t uid) {
- gReqContext->setUID(uid);
-}
-
-bool SfDelegate::getUID(uid_t *uid) const {
- return gReqContext->getUID(uid);
-}
-
-void SfDelegate::OnReceivedRedirect(
- net::URLRequest *request, const GURL &new_url, bool *defer_redirect) {
- MY_LOGV("OnReceivedRedirect");
- mOwner->onRedirect(new_url.spec().c_str());
-}
-
-void SfDelegate::OnAuthRequired(
- net::URLRequest *request, net::AuthChallengeInfo *auth_info) {
- MY_LOGV("OnAuthRequired");
-
- inherited::OnAuthRequired(request, auth_info);
-}
-
-void SfDelegate::OnCertificateRequested(
- net::URLRequest *request, net::SSLCertRequestInfo *cert_request_info) {
- MY_LOGV("OnCertificateRequested");
-
- inherited::OnCertificateRequested(request, cert_request_info);
-}
-
-void SfDelegate::OnSSLCertificateError(
- net::URLRequest *request, int cert_error, net::X509Certificate *cert) {
- fprintf(stderr, "OnSSLCertificateError cert_error=%d\n", cert_error);
-
- inherited::OnSSLCertificateError(request, cert_error, cert);
-}
-
-void SfDelegate::OnGetCookies(net::URLRequest *request, bool blocked_by_policy) {
- MY_LOGV("OnGetCookies");
-}
-
-void SfDelegate::OnSetCookie(
- net::URLRequest *request,
- const std::string &cookie_line,
- const net::CookieOptions &options,
- bool blocked_by_policy) {
- MY_LOGV("OnSetCookie");
-}
-
-void SfDelegate::OnResponseStarted(net::URLRequest *request) {
- if (request->status().status() != net::URLRequestStatus::SUCCESS) {
- MY_LOGI(StringPrintf(
- "Request failed with status %d and os_error %d",
- request->status().status(),
- request->status().os_error()).c_str());
-
- delete mURLRequest;
- mURLRequest = NULL;
-
- mOwner->onConnectionFailed(ERROR_IO);
- return;
- } else if (mRangeRequested && request->GetResponseCode() != 206) {
- MY_LOGI(StringPrintf(
- "We requested a content range, but server didn't "
- "support that. (responded with %d)",
- request->GetResponseCode()).c_str());
-
- delete mURLRequest;
- mURLRequest = NULL;
-
- mOwner->onConnectionFailed(-EPIPE);
- return;
- } else if ((request->GetResponseCode() / 100) != 2) {
- MY_LOGI(StringPrintf(
- "Server responded with http status %d",
- request->GetResponseCode()).c_str());
-
- delete mURLRequest;
- mURLRequest = NULL;
-
- mOwner->onConnectionFailed(ERROR_IO);
- return;
- }
-
- MY_LOGV("OnResponseStarted");
-
- std::string headers;
- request->GetAllResponseHeaders(&headers);
-
- MY_LOGV(StringPrintf("response headers: %s", headers.c_str()).c_str());
-
- std::string contentType;
- request->GetResponseHeaderByName("Content-Type", &contentType);
-
- mOwner->onConnectionEstablished(
- request->GetExpectedContentSize(), contentType.c_str());
-}
-
-void SfDelegate::OnReadCompleted(net::URLRequest *request, int bytes_read) {
- if (bytes_read == -1) {
- MY_LOGI(StringPrintf(
- "OnReadCompleted, read failed, status %d",
- request->status().status()).c_str());
-
- mOwner->onReadCompleted(ERROR_IO);
- return;
- }
-
- MY_LOGV(StringPrintf("OnReadCompleted, read %d bytes", bytes_read).c_str());
-
- if (bytes_read < 0) {
- MY_LOGI(StringPrintf(
- "Read failed w/ status %d\n",
- request->status().status()).c_str());
-
- mOwner->onReadCompleted(ERROR_IO);
- return;
- } else if (bytes_read == 0) {
- mAtEOS = true;
- mOwner->onReadCompleted(mNumBytesRead);
- return;
- }
-
- CHECK_GT(bytes_read, 0);
- CHECK_LE(mNumBytesRead + bytes_read, mNumBytesTotal);
-
- memcpy((uint8_t *)mDataDestination + mNumBytesRead,
- mReadBuffer->data(),
- bytes_read);
-
- mNumBytesRead += bytes_read;
-
- readMore(request);
-}
-
-void SfDelegate::readMore(net::URLRequest *request) {
- while (mNumBytesRead < mNumBytesTotal) {
- size_t copy = mNumBytesTotal - mNumBytesRead;
- if (copy > mReadBuffer->size()) {
- copy = mReadBuffer->size();
- }
-
- int n;
- if (request->Read(mReadBuffer, copy, &n)) {
- MY_LOGV(StringPrintf("Read %d bytes directly.", n).c_str());
-
- CHECK_LE((size_t)n, copy);
-
- memcpy((uint8_t *)mDataDestination + mNumBytesRead,
- mReadBuffer->data(),
- n);
-
- mNumBytesRead += n;
-
- if (n == 0) {
- mAtEOS = true;
- break;
- }
- } else {
- MY_LOGV("readMore pending read");
-
- if (request->status().status() != net::URLRequestStatus::IO_PENDING) {
- MY_LOGI(StringPrintf(
- "Direct read failed w/ status %d\n",
- request->status().status()).c_str());
-
- mOwner->onReadCompleted(ERROR_IO);
- return;
- }
-
- return;
- }
- }
-
- mOwner->onReadCompleted(mNumBytesRead);
-}
-
-void SfDelegate::initiateConnection(
- const char *uri,
- const KeyedVector<String8, String8> *headers,
- off64_t offset) {
- GURL url(uri);
-
- MessageLoop *loop = gNetworkThread->message_loop();
- loop->PostTask(
- FROM_HERE,
- NewRunnableFunction(
- &SfDelegate::OnInitiateConnectionWrapper,
- this,
- url,
- headers,
- offset));
-
-}
-
-// static
-void SfDelegate::OnInitiateConnectionWrapper(
- SfDelegate *me, GURL url,
- const KeyedVector<String8, String8> *headers,
- off64_t offset) {
- me->onInitiateConnection(url, headers, offset);
-}
-
-void SfDelegate::onInitiateConnection(
- const GURL &url,
- const KeyedVector<String8, String8> *extra,
- off64_t offset) {
- CHECK(mURLRequest == NULL);
-
- mURLRequest = new net::URLRequest(url, this);
- mAtEOS = false;
-
- mRangeRequested = false;
-
- if (offset != 0 || extra != NULL) {
- net::HttpRequestHeaders headers =
- mURLRequest->extra_request_headers();
-
- if (offset != 0) {
- headers.AddHeaderFromString(
- StringPrintf("Range: bytes=%lld-", offset).c_str());
-
- mRangeRequested = true;
- }
-
- if (extra != NULL) {
- for (size_t i = 0; i < extra->size(); ++i) {
- AString s;
- s.append(extra->keyAt(i).string());
- s.append(": ");
- s.append(extra->valueAt(i).string());
-
- headers.AddHeaderFromString(s.c_str());
- }
- }
-
- mURLRequest->SetExtraRequestHeaders(headers);
- }
-
- mURLRequest->set_context(gReqContext);
-
- mURLRequest->Start();
-}
-
-void SfDelegate::initiateDisconnect() {
- MessageLoop *loop = gNetworkThread->message_loop();
- loop->PostTask(
- FROM_HERE,
- NewRunnableFunction(
- &SfDelegate::OnInitiateDisconnectWrapper, this));
-}
-
-// static
-void SfDelegate::OnInitiateDisconnectWrapper(SfDelegate *me) {
- me->onInitiateDisconnect();
-}
-
-void SfDelegate::onInitiateDisconnect() {
- if (mURLRequest == NULL) {
- return;
- }
-
- mURLRequest->Cancel();
-
- delete mURLRequest;
- mURLRequest = NULL;
-
- mOwner->onDisconnectComplete();
-}
-
-void SfDelegate::initiateRead(void *data, size_t size) {
- MessageLoop *loop = gNetworkThread->message_loop();
- loop->PostTask(
- FROM_HERE,
- NewRunnableFunction(
- &SfDelegate::OnInitiateReadWrapper, this, data, size));
-}
-
-// static
-void SfDelegate::OnInitiateReadWrapper(
- SfDelegate *me, void *data, size_t size) {
- me->onInitiateRead(data, size);
-}
-
-void SfDelegate::onInitiateRead(void *data, size_t size) {
- CHECK(mURLRequest != NULL);
-
- mNumBytesRead = 0;
- mNumBytesTotal = size;
- mDataDestination = data;
-
- if (mAtEOS) {
- mOwner->onReadCompleted(0);
- return;
- }
-
- readMore(mURLRequest);
-}
-
-} // namespace android
-
diff --git a/media/libstagefright/chromium_http/support.h b/media/libstagefright/chromium_http/support.h
deleted file mode 100644
index 975a1d3..0000000
--- a/media/libstagefright/chromium_http/support.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SUPPORT_H_
-
-#define SUPPORT_H_
-
-#include <assert.h>
-
-#include "net/base/net_log.h"
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_context.h"
-#include "net/base/android_network_library.h"
-#include "net/base/io_buffer.h"
-
-#include <utils/KeyedVector.h>
-#include <utils/Mutex.h>
-#include <utils/String8.h>
-
-namespace net {
- struct ProxyConfigServiceAndroid;
-};
-
-namespace android {
-
-struct SfNetLog : public net::NetLog {
- SfNetLog();
-
- virtual void AddEntry(
- EventType type,
- const base::TimeTicks &time,
- const Source &source,
- EventPhase phase,
- EventParameters *params);
-
- virtual uint32 NextID();
- virtual LogLevel GetLogLevel() const;
-
-private:
- uint32 mNextID;
-
- DISALLOW_EVIL_CONSTRUCTORS(SfNetLog);
-};
-
-struct SfRequestContext : public net::URLRequestContext {
- SfRequestContext();
-
- virtual const std::string &GetUserAgent(const GURL &url) const;
-
- status_t updateProxyConfig(
- const char *host, int32_t port, const char *exclusionList);
-
-private:
- Mutex mProxyConfigLock;
-
- std::string mUserAgent;
- net::ProxyConfigServiceAndroid *mProxyConfigService;
-
- DISALLOW_EVIL_CONSTRUCTORS(SfRequestContext);
-};
-
-// This is required for https support, we don't really verify certificates,
-// we accept anything...
-struct SfNetworkLibrary : public net::AndroidNetworkLibrary {
- SfNetworkLibrary();
-
- virtual VerifyResult VerifyX509CertChain(
- const std::vector<std::string>& cert_chain,
- const std::string& hostname,
- const std::string& auth_type);
-
-private:
- DISALLOW_EVIL_CONSTRUCTORS(SfNetworkLibrary);
-};
-
-struct ChromiumHTTPDataSource;
-
-struct SfDelegate : public net::URLRequest::Delegate {
- SfDelegate();
- virtual ~SfDelegate();
-
- void initiateConnection(
- const char *uri,
- const KeyedVector<String8, String8> *headers,
- off64_t offset);
-
- void initiateDisconnect();
- void initiateRead(void *data, size_t size);
-
- void setOwner(ChromiumHTTPDataSource *mOwner);
-
- // Gets the UID of the calling process
- bool getUID(uid_t *uid) const;
-
- void setUID(uid_t uid);
-
- virtual void OnReceivedRedirect(
- net::URLRequest *request, const GURL &new_url, bool *defer_redirect);
-
- virtual void OnAuthRequired(
- net::URLRequest *request, net::AuthChallengeInfo *auth_info);
-
- virtual void OnCertificateRequested(
- net::URLRequest *request, net::SSLCertRequestInfo *cert_request_info);
-
- virtual void OnSSLCertificateError(
- net::URLRequest *request, int cert_error, net::X509Certificate *cert);
-
- virtual void OnGetCookies(net::URLRequest *request, bool blocked_by_policy);
-
- virtual void OnSetCookie(
- net::URLRequest *request,
- const std::string &cookie_line,
- const net::CookieOptions &options,
- bool blocked_by_policy);
-
- virtual void OnResponseStarted(net::URLRequest *request);
-
- virtual void OnReadCompleted(net::URLRequest *request, int bytes_read);
-
- static status_t UpdateProxyConfig(
- const char *host, int32_t port, const char *exclusionList);
-
-private:
- typedef Delegate inherited;
-
- ChromiumHTTPDataSource *mOwner;
-
- net::URLRequest *mURLRequest;
- scoped_refptr<net::IOBufferWithSize> mReadBuffer;
-
- size_t mNumBytesRead;
- size_t mNumBytesTotal;
- void *mDataDestination;
-
- bool mRangeRequested;
- bool mAtEOS;
-
- void readMore(net::URLRequest *request);
-
- static void OnInitiateConnectionWrapper(
- SfDelegate *me,
- GURL url,
- const KeyedVector<String8, String8> *headers,
- off64_t offset);
-
- static void OnInitiateDisconnectWrapper(SfDelegate *me);
-
- static void OnInitiateReadWrapper(
- SfDelegate *me, void *data, size_t size);
-
- void onInitiateConnection(
- const GURL &url,
- const KeyedVector<String8, String8> *headers,
- off64_t offset);
-
- void onInitiateDisconnect();
- void onInitiateRead(void *data, size_t size);
-
- DISALLOW_EVIL_CONSTRUCTORS(SfDelegate);
-};
-
-} // namespace android
-
-#endif // SUPPORT_H_
diff --git a/media/libstagefright/chromium_http_stub.cpp b/media/libstagefright/chromium_http_stub.cpp
deleted file mode 100644
index ed8a878..0000000
--- a/media/libstagefright/chromium_http_stub.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <dlfcn.h>
-
-#include <media/stagefright/DataSource.h>
-
-#include "include/chromium_http_stub.h"
-#include "include/HTTPBase.h"
-
-namespace android {
-
-static bool gFirst = true;
-static void *gHandle;
-static Mutex gLibMutex;
-
-HTTPBase *(*gLib_createChromiumHTTPDataSource)(uint32_t flags);
-DataSource *(*gLib_createDataUriSource)(const char *uri);
-
-status_t (*gLib_UpdateChromiumHTTPDataSourceProxyConfig)(
- const char *host, int32_t port, const char *exclusionList);
-
-static bool load_libstagefright_chromium_http() {
- Mutex::Autolock autoLock(gLibMutex);
- void *sym;
-
- if (!gFirst) {
- return (gHandle != NULL);
- }
-
- gFirst = false;
-
- gHandle = dlopen("libstagefright_chromium_http.so", RTLD_NOW);
- if (gHandle == NULL) {
- return false;
- }
-
- sym = dlsym(gHandle, "createChromiumHTTPDataSource");
- if (sym == NULL) {
- gHandle = NULL;
- return false;
- }
- gLib_createChromiumHTTPDataSource = (HTTPBase *(*)(uint32_t))sym;
-
- sym = dlsym(gHandle, "createDataUriSource");
- if (sym == NULL) {
- gHandle = NULL;
- return false;
- }
- gLib_createDataUriSource = (DataSource *(*)(const char *))sym;
-
- sym = dlsym(gHandle, "UpdateChromiumHTTPDataSourceProxyConfig");
- if (sym == NULL) {
- gHandle = NULL;
- return false;
- }
- gLib_UpdateChromiumHTTPDataSourceProxyConfig =
- (status_t (*)(const char *, int32_t, const char *))sym;
-
- return true;
-}
-
-HTTPBase *createChromiumHTTPDataSource(uint32_t flags) {
- if (!load_libstagefright_chromium_http()) {
- return NULL;
- }
-
- return gLib_createChromiumHTTPDataSource(flags);
-}
-
-status_t UpdateChromiumHTTPDataSourceProxyConfig(
- const char *host, int32_t port, const char *exclusionList) {
- if (!load_libstagefright_chromium_http()) {
- return INVALID_OPERATION;
- }
-
- return gLib_UpdateChromiumHTTPDataSourceProxyConfig(
- host, port, exclusionList);
-}
-
-DataSource *createDataUriSource(const char *uri) {
- if (!load_libstagefright_chromium_http()) {
- return NULL;
- }
-
- return gLib_createDataUriSource(uri);
-}
-
-}
diff --git a/media/libstagefright/codecs/aacdec/Android.mk b/media/libstagefright/codecs/aacdec/Android.mk
index ffa64f9..49ff238 100644
--- a/media/libstagefright/codecs/aacdec/Android.mk
+++ b/media/libstagefright/codecs/aacdec/Android.mk
@@ -17,6 +17,8 @@ LOCAL_C_INCLUDES := \
LOCAL_CFLAGS :=
+LOCAL_CFLAGS += -Werror
+
LOCAL_STATIC_LIBRARIES := libFraunhoferAAC
LOCAL_SHARED_LIBRARIES := \
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index 1b20cbb..4ac8999 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -30,7 +30,7 @@
#define DRC_DEFAULT_MOBILE_REF_LEVEL 64 /* 64*-0.25dB = -16 dB below full scale for mobile conf */
#define DRC_DEFAULT_MOBILE_DRC_CUT 127 /* maximum compression of dynamic range for mobile conf */
#define DRC_DEFAULT_MOBILE_DRC_BOOST 127 /* maximum compression of dynamic range for mobile conf */
-#define MAX_CHANNEL_COUNT 6 /* maximum number of audio channels that can be decoded */
+#define MAX_CHANNEL_COUNT 8 /* maximum number of audio channels that can be decoded */
// names of properties that can be used to override the default DRC settings
#define PROP_DRC_OVERRIDE_REF_LEVEL "aac_drc_reference_level"
#define PROP_DRC_OVERRIDE_CUT "aac_drc_cut"
@@ -58,6 +58,8 @@ SoftAAC2::SoftAAC2(
mIsADTS(false),
mInputBufferCount(0),
mSignalledError(false),
+ mSawInputEos(false),
+ mSignalledOutputEos(false),
mAnchorTimeUs(0),
mNumSamplesOutput(0),
mOutputPortSettingsChange(NONE) {
@@ -294,8 +296,11 @@ void SoftAAC2::maybeConfigureDownmix() const {
if (!(property_get("media.aac_51_output_enabled", value, NULL) &&
(!strcmp(value, "1") || !strcasecmp(value, "true")))) {
ALOGI("Downmixing multichannel AAC to stereo");
- aacDecoder_SetParam(mAACDecoder, AAC_PCM_OUTPUT_CHANNELS, 2);
+ aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, 2);
mStreamInfo->numChannels = 2;
+ // By default, the decoder creates a 5.1 channel downmix signal
+ // for seven and eight channel input streams. To enable 6.1 and 7.1 channel output
+ // use aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, -1)
}
}
}
@@ -350,115 +355,83 @@ void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
return;
}
- while (!inQueue.empty() && !outQueue.empty()) {
- BufferInfo *inInfo = *inQueue.begin();
- OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+ while ((!inQueue.empty() || (mSawInputEos && !mSignalledOutputEos)) && !outQueue.empty()) {
+ BufferInfo *inInfo = NULL;
+ OMX_BUFFERHEADERTYPE *inHeader = NULL;
+ if (!inQueue.empty()) {
+ inInfo = *inQueue.begin();
+ inHeader = inInfo->mHeader;
+ }
BufferInfo *outInfo = *outQueue.begin();
OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+ outHeader->nFlags = 0;
- if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
- inQueue.erase(inQueue.begin());
- inInfo->mOwnedByUs = false;
- notifyEmptyBufferDone(inHeader);
-
- if (mDecoderHasData) {
- // flush out the decoder's delayed data by calling DecodeFrame
- // one more time, with the AACDEC_FLUSH flag set
- INT_PCM *outBuffer =
- reinterpret_cast<INT_PCM *>(
- outHeader->pBuffer + outHeader->nOffset);
-
- AAC_DECODER_ERROR decoderErr =
- aacDecoder_DecodeFrame(mAACDecoder,
- outBuffer,
- outHeader->nAllocLen,
- AACDEC_FLUSH);
- mDecoderHasData = false;
-
- if (decoderErr != AAC_DEC_OK) {
- mSignalledError = true;
-
- notify(OMX_EventError, OMX_ErrorUndefined, decoderErr,
- NULL);
-
- return;
- }
-
- outHeader->nFilledLen =
- mStreamInfo->frameSize
- * sizeof(int16_t)
- * mStreamInfo->numChannels;
- } else {
- // we never submitted any data to the decoder, so there's nothing to flush out
- outHeader->nFilledLen = 0;
+ if (inHeader) {
+ if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+ mSawInputEos = true;
}
- outHeader->nFlags = OMX_BUFFERFLAG_EOS;
-
- outQueue.erase(outQueue.begin());
- outInfo->mOwnedByUs = false;
- notifyFillBufferDone(outHeader);
- return;
- }
-
- if (inHeader->nOffset == 0) {
- mAnchorTimeUs = inHeader->nTimeStamp;
- mNumSamplesOutput = 0;
- }
+ if (inHeader->nOffset == 0 && inHeader->nFilledLen) {
+ mAnchorTimeUs = inHeader->nTimeStamp;
+ mNumSamplesOutput = 0;
+ }
- size_t adtsHeaderSize = 0;
- if (mIsADTS) {
- // skip 30 bits, aac_frame_length follows.
- // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
+ if (mIsADTS && inHeader->nFilledLen) {
+ size_t adtsHeaderSize = 0;
+ // skip 30 bits, aac_frame_length follows.
+ // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
- const uint8_t *adtsHeader = inHeader->pBuffer + inHeader->nOffset;
+ const uint8_t *adtsHeader = inHeader->pBuffer + inHeader->nOffset;
- bool signalError = false;
- if (inHeader->nFilledLen < 7) {
- ALOGE("Audio data too short to contain even the ADTS header. "
- "Got %ld bytes.", inHeader->nFilledLen);
- hexdump(adtsHeader, inHeader->nFilledLen);
- signalError = true;
- } else {
- bool protectionAbsent = (adtsHeader[1] & 1);
-
- unsigned aac_frame_length =
- ((adtsHeader[3] & 3) << 11)
- | (adtsHeader[4] << 3)
- | (adtsHeader[5] >> 5);
-
- if (inHeader->nFilledLen < aac_frame_length) {
- ALOGE("Not enough audio data for the complete frame. "
- "Got %ld bytes, frame size according to the ADTS "
- "header is %u bytes.",
- inHeader->nFilledLen, aac_frame_length);
+ bool signalError = false;
+ if (inHeader->nFilledLen < 7) {
+ ALOGE("Audio data too short to contain even the ADTS header. "
+ "Got %ld bytes.", inHeader->nFilledLen);
hexdump(adtsHeader, inHeader->nFilledLen);
signalError = true;
} else {
- adtsHeaderSize = (protectionAbsent ? 7 : 9);
-
- inBuffer[0] = (UCHAR *)adtsHeader + adtsHeaderSize;
- inBufferLength[0] = aac_frame_length - adtsHeaderSize;
-
- inHeader->nOffset += adtsHeaderSize;
- inHeader->nFilledLen -= adtsHeaderSize;
+ bool protectionAbsent = (adtsHeader[1] & 1);
+
+ unsigned aac_frame_length =
+ ((adtsHeader[3] & 3) << 11)
+ | (adtsHeader[4] << 3)
+ | (adtsHeader[5] >> 5);
+
+ if (inHeader->nFilledLen < aac_frame_length) {
+ ALOGE("Not enough audio data for the complete frame. "
+ "Got %ld bytes, frame size according to the ADTS "
+ "header is %u bytes.",
+ inHeader->nFilledLen, aac_frame_length);
+ hexdump(adtsHeader, inHeader->nFilledLen);
+ signalError = true;
+ } else {
+ adtsHeaderSize = (protectionAbsent ? 7 : 9);
+
+ inBuffer[0] = (UCHAR *)adtsHeader + adtsHeaderSize;
+ inBufferLength[0] = aac_frame_length - adtsHeaderSize;
+
+ inHeader->nOffset += adtsHeaderSize;
+ inHeader->nFilledLen -= adtsHeaderSize;
+ }
}
- }
- if (signalError) {
- mSignalledError = true;
+ if (signalError) {
+ mSignalledError = true;
- notify(OMX_EventError,
- OMX_ErrorStreamCorrupt,
- ERROR_MALFORMED,
- NULL);
+ notify(OMX_EventError,
+ OMX_ErrorStreamCorrupt,
+ ERROR_MALFORMED,
+ NULL);
- return;
+ return;
+ }
+ } else {
+ inBuffer[0] = inHeader->pBuffer + inHeader->nOffset;
+ inBufferLength[0] = inHeader->nFilledLen;
}
} else {
- inBuffer[0] = inHeader->pBuffer + inHeader->nOffset;
- inBufferLength[0] = inHeader->nFilledLen;
+ inBufferLength[0] = 0;
}
// Fill and decode
@@ -471,50 +444,66 @@ void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
int prevNumChannels = mStreamInfo->numChannels;
AAC_DECODER_ERROR decoderErr = AAC_DEC_NOT_ENOUGH_BITS;
- while (bytesValid[0] > 0 && decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
+ while ((bytesValid[0] > 0 || mSawInputEos) && decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
+ mDecoderHasData |= (bytesValid[0] > 0);
aacDecoder_Fill(mAACDecoder,
inBuffer,
inBufferLength,
bytesValid);
- mDecoderHasData = true;
decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
outBuffer,
outHeader->nAllocLen,
0 /* flags */);
-
if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
- ALOGW("Not enough bits, bytesValid %d", bytesValid[0]);
+ if (mSawInputEos && bytesValid[0] <= 0) {
+ if (mDecoderHasData) {
+ // flush out the decoder's delayed data by calling DecodeFrame
+ // one more time, with the AACDEC_FLUSH flag set
+ decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
+ outBuffer,
+ outHeader->nAllocLen,
+ AACDEC_FLUSH);
+ mDecoderHasData = false;
+ }
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+ mSignalledOutputEos = true;
+ break;
+ } else {
+ ALOGW("Not enough bits, bytesValid %d", bytesValid[0]);
+ }
}
}
size_t numOutBytes =
mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;
- if (decoderErr == AAC_DEC_OK) {
- UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
- inHeader->nFilledLen -= inBufferUsedLength;
- inHeader->nOffset += inBufferUsedLength;
- } else {
- ALOGW("AAC decoder returned error %d, substituting silence",
- decoderErr);
+ if (inHeader) {
+ if (decoderErr == AAC_DEC_OK) {
+ UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
+ inHeader->nFilledLen -= inBufferUsedLength;
+ inHeader->nOffset += inBufferUsedLength;
+ } else {
+ ALOGW("AAC decoder returned error %d, substituting silence",
+ decoderErr);
- memset(outHeader->pBuffer + outHeader->nOffset, 0, numOutBytes);
+ memset(outHeader->pBuffer + outHeader->nOffset, 0, numOutBytes);
- // Discard input buffer.
- inHeader->nFilledLen = 0;
+ // Discard input buffer.
+ inHeader->nFilledLen = 0;
- aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
+ aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
- // fall through
- }
+ // fall through
+ }
- if (inHeader->nFilledLen == 0) {
- inInfo->mOwnedByUs = false;
- inQueue.erase(inQueue.begin());
- inInfo = NULL;
- notifyEmptyBufferDone(inHeader);
- inHeader = NULL;
+ if (inHeader->nFilledLen == 0) {
+ inInfo->mOwnedByUs = false;
+ inQueue.erase(inQueue.begin());
+ inInfo = NULL;
+ notifyEmptyBufferDone(inHeader);
+ inHeader = NULL;
+ }
}
/*
@@ -555,7 +544,6 @@ void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
// we've previously decoded valid data, in the latter case
// (decode failed) we'll output a silent frame.
outHeader->nFilledLen = numOutBytes;
- outHeader->nFlags = 0;
outHeader->nTimeStamp =
mAnchorTimeUs
@@ -582,6 +570,12 @@ void SoftAAC2::onPortFlushCompleted(OMX_U32 portIndex) {
// depend on fragments from the last one decoded.
// drain all existing data
drainDecoder();
+ // force decoder loop to drop the first decoded buffer by resetting these state variables,
+ // but only if initialization has already happened.
+ if (mInputBufferCount != 0) {
+ mInputBufferCount = 1;
+ mStreamInfo->sampleRate = 0;
+ }
}
}
@@ -606,6 +600,8 @@ void SoftAAC2::onReset() {
mStreamInfo->sampleRate = 0;
mSignalledError = false;
+ mSawInputEos = false;
+ mSignalledOutputEos = false;
mOutputPortSettingsChange = NONE;
}
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.h b/media/libstagefright/codecs/aacdec/SoftAAC2.h
index 2d960ab..a7ea1e2 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.h
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.h
@@ -55,6 +55,8 @@ private:
bool mDecoderHasData;
size_t mInputBufferCount;
bool mSignalledError;
+ bool mSawInputEos;
+ bool mSignalledOutputEos;
int64_t mAnchorTimeUs;
int64_t mNumSamplesOutput;
diff --git a/media/libstagefright/codecs/aacenc/Android.mk b/media/libstagefright/codecs/aacenc/Android.mk
index 057c69b..58ec3ba 100644
--- a/media/libstagefright/codecs/aacenc/Android.mk
+++ b/media/libstagefright/codecs/aacenc/Android.mk
@@ -82,6 +82,8 @@ LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/asm/ARMV5E
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/asm/ARMV7
endif
+LOCAL_CFLAGS += -Werror
+
include $(BUILD_STATIC_LIBRARY)
################################################################################
@@ -106,6 +108,8 @@ ifeq ($(AAC_LIBRARY), fraunhofer)
LOCAL_CFLAGS :=
+ LOCAL_CFLAGS += -Werror
+
LOCAL_STATIC_LIBRARIES := libFraunhoferAAC
LOCAL_SHARED_LIBRARIES := \
@@ -128,6 +132,8 @@ else # visualon
LOCAL_CFLAGS := -DOSCL_IMPORT_REF=
+ LOCAL_CFLAGS += -Werror
+
LOCAL_STATIC_LIBRARIES := \
libstagefright_aacenc
diff --git a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
index ff2b503..9a91579 100644
--- a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
+++ b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
@@ -338,7 +338,7 @@ status_t SoftAACEncoder2::setAudioParams() {
return OK;
}
-void SoftAACEncoder2::onQueueFilled(OMX_U32 portIndex) {
+void SoftAACEncoder2::onQueueFilled(OMX_U32 /* portIndex */) {
if (mSignalledError) {
return;
}
diff --git a/media/libstagefright/codecs/aacenc/basic_op/oper_32b.c b/media/libstagefright/codecs/aacenc/basic_op/oper_32b.c
index cc01927..1d029fc 100644
--- a/media/libstagefright/codecs/aacenc/basic_op/oper_32b.c
+++ b/media/libstagefright/codecs/aacenc/basic_op/oper_32b.c
@@ -24,6 +24,8 @@
#include "basic_op.h"
#include "oper_32b.h"
+#define UNUSED(x) (void)(x)
+
/*****************************************************************************
* *
* Function L_Extract() *
@@ -243,6 +245,8 @@ Word16 iLog4(Word32 value)
Word32 rsqrt(Word32 value, /*!< Operand to square root (0.0 ... 1) */
Word32 accuracy) /*!< Number of valid bits that will be calculated */
{
+ UNUSED(accuracy);
+
Word32 root = 0;
Word32 scale;
diff --git a/media/libstagefright/codecs/aacenc/src/aacenc.c b/media/libstagefright/codecs/aacenc/src/aacenc.c
index d1c8621..40db92c 100644
--- a/media/libstagefright/codecs/aacenc/src/aacenc.c
+++ b/media/libstagefright/codecs/aacenc/src/aacenc.c
@@ -27,6 +27,8 @@
#include "cmnMemory.h"
#include "memalign.h"
+#define UNUSED(x) (void)(x)
+
/**
* Init the audio codec module and return codec handle
* \param phCodec [OUT] Return the video codec handle
@@ -46,6 +48,8 @@ VO_U32 VO_API voAACEncInit(VO_HANDLE * phCodec,VO_AUDIO_CODINGTYPE vType, VO_COD
VO_MEM_OPERATOR *pMemOP;
int interMem;
+ UNUSED(vType);
+
interMem = 0;
error = 0;
@@ -471,6 +475,10 @@ VO_U32 VO_API voAACEncSetParam(VO_HANDLE hCodec, VO_S32 uParamID, VO_PTR pData)
*/
VO_U32 VO_API voAACEncGetParam(VO_HANDLE hCodec, VO_S32 uParamID, VO_PTR pData)
{
+ UNUSED(hCodec);
+ UNUSED(uParamID);
+ UNUSED(pData);
+
return VO_ERR_NONE;
}
diff --git a/media/libstagefright/codecs/aacenc/src/adj_thr.c b/media/libstagefright/codecs/aacenc/src/adj_thr.c
index ccfe883..471631c 100644
--- a/media/libstagefright/codecs/aacenc/src/adj_thr.c
+++ b/media/libstagefright/codecs/aacenc/src/adj_thr.c
@@ -72,7 +72,7 @@ static void calcThreshExp(Word32 thrExp[MAX_CHANNELS][MAX_GROUPED_SFB],
const Word16 nChannels)
{
Word16 ch, sfb, sfbGrp;
- Word32 *pthrExp, *psfbThre;
+ Word32 *pthrExp = NULL, *psfbThre;
for (ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
for(sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt; sfbGrp+= psyOutChan->sfbPerGroup)
diff --git a/media/libstagefright/codecs/aacenc/src/bitenc.c b/media/libstagefright/codecs/aacenc/src/bitenc.c
index fcc12dd..d1fd647 100644
--- a/media/libstagefright/codecs/aacenc/src/bitenc.c
+++ b/media/libstagefright/codecs/aacenc/src/bitenc.c
@@ -26,6 +26,7 @@
#include "qc_data.h"
#include "interface.h"
+#define UNUSED(x) (void)(x)
static const Word16 globalGainOffset = 100;
static const Word16 icsReservedBit = 0;
@@ -585,6 +586,8 @@ Word16 WriteBitstream (HANDLE_BIT_BUF hBitStream,
Word16 elementUsedBits;
Word16 frameBits=0;
+ UNUSED(ancBytes);
+
/* struct bitbuffer bsWriteCopy; */
bitMarkUp = GetBitsAvail(hBitStream);
if(qcOut->qcElement.adtsUsed) /* write adts header*/
diff --git a/media/libstagefright/codecs/aacenc/src/dyn_bits.c b/media/libstagefright/codecs/aacenc/src/dyn_bits.c
index 7769188..4d763d0 100644
--- a/media/libstagefright/codecs/aacenc/src/dyn_bits.c
+++ b/media/libstagefright/codecs/aacenc/src/dyn_bits.c
@@ -25,7 +25,6 @@
#include "bit_cnt.h"
#include "psy_const.h"
-
/*****************************************************************************
*
* function name: buildBitLookUp
@@ -226,7 +225,7 @@ gmStage2(SECTION_INFO *sectionInfo,
}
while (TRUE) {
- Word16 maxMergeGain, maxNdx, maxNdxNext, maxNdxLast;
+ Word16 maxMergeGain, maxNdx = 0, maxNdxNext, maxNdxLast;
maxMergeGain = findMaxMerge(mergeGainLookUp, sectionInfo, maxSfb, &maxNdx);
diff --git a/media/libstagefright/codecs/aacenc/src/psy_main.c b/media/libstagefright/codecs/aacenc/src/psy_main.c
index 4e9218c..6f0679c 100644
--- a/media/libstagefright/codecs/aacenc/src/psy_main.c
+++ b/media/libstagefright/codecs/aacenc/src/psy_main.c
@@ -38,6 +38,8 @@
#include "tns_func.h"
#include "memalign.h"
+#define UNUSED(x) (void)(x)
+
/* long start short stop */
static Word16 blockType2windowShape[] = {KBD_WINDOW,SINE_WINDOW,SINE_WINDOW,KBD_WINDOW};
@@ -170,7 +172,9 @@ Word16 PsyOutNew(PSY_OUT *hPsyOut, VO_MEM_OPERATOR *pMemOP)
*****************************************************************************/
Word16 PsyOutDelete(PSY_OUT *hPsyOut, VO_MEM_OPERATOR *pMemOP)
{
- hPsyOut=NULL;
+ UNUSED(hPsyOut);
+ UNUSED(pMemOP);
+
return 0;
}
diff --git a/media/libstagefright/codecs/aacenc/src/qc_main.c b/media/libstagefright/codecs/aacenc/src/qc_main.c
index 48ff300..e5d78aa 100644
--- a/media/libstagefright/codecs/aacenc/src/qc_main.c
+++ b/media/libstagefright/codecs/aacenc/src/qc_main.c
@@ -33,6 +33,7 @@
#include "channel_map.h"
#include "memalign.h"
+#define UNUSED(x) (void)(x)
typedef enum{
FRAME_LEN_BYTES_MODULO = 1,
@@ -204,11 +205,8 @@ Word16 QCNew(QC_STATE *hQC, VO_MEM_OPERATOR *pMemOP)
**********************************************************************************/
void QCDelete(QC_STATE *hQC, VO_MEM_OPERATOR *pMemOP)
{
-
- /*
- nothing to do
- */
- hQC=NULL;
+ UNUSED(hQC);
+ UNUSED(pMemOP);
}
/*********************************************************************************
diff --git a/media/libstagefright/codecs/aacenc/src/tns.c b/media/libstagefright/codecs/aacenc/src/tns.c
index 455a864..5172612 100644
--- a/media/libstagefright/codecs/aacenc/src/tns.c
+++ b/media/libstagefright/codecs/aacenc/src/tns.c
@@ -30,6 +30,8 @@
#include "psy_configuration.h"
#include "tns_func.h"
+#define UNUSED(x) (void)(x)
+
#define TNS_MODIFY_BEGIN 2600 /* Hz */
#define RATIO_PATCH_LOWER_BORDER 380 /* Hz */
#define TNS_GAIN_THRESH 141 /* 1.41*100 */
@@ -643,6 +645,8 @@ static Word16 CalcTnsFilter(const Word16 *signal,
Word32 i;
Word32 tnsOrderPlus1 = tnsOrder + 1;
+ UNUSED(window);
+
assert(tnsOrder <= TNS_MAX_ORDER); /* remove asserts later? (btg) */
for(i=0;i<tnsOrder;i++) {
diff --git a/media/libstagefright/codecs/amrnb/common/Android.mk b/media/libstagefright/codecs/amrnb/common/Android.mk
index 30ce29c..a2b3c8f 100644
--- a/media/libstagefright/codecs/amrnb/common/Android.mk
+++ b/media/libstagefright/codecs/amrnb/common/Android.mk
@@ -69,6 +69,8 @@ LOCAL_C_INCLUDES := \
LOCAL_CFLAGS := \
-DOSCL_UNUSED_ARG= -DOSCL_IMPORT_REF= -DOSCL_EXPORT_REF=
+LOCAL_CFLAGS += -Werror
+
LOCAL_MODULE := libstagefright_amrnb_common
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/codecs/amrnb/dec/Android.mk b/media/libstagefright/codecs/amrnb/dec/Android.mk
index 8d6c6f8..b067456 100644
--- a/media/libstagefright/codecs/amrnb/dec/Android.mk
+++ b/media/libstagefright/codecs/amrnb/dec/Android.mk
@@ -47,6 +47,8 @@ LOCAL_C_INCLUDES := \
LOCAL_CFLAGS := \
-DOSCL_UNUSED_ARG= -DOSCL_IMPORT_REF=
+LOCAL_CFLAGS += -Werror
+
LOCAL_MODULE := libstagefright_amrnbdec
include $(BUILD_STATIC_LIBRARY)
@@ -68,6 +70,8 @@ LOCAL_C_INCLUDES := \
LOCAL_CFLAGS := -DOSCL_IMPORT_REF=
+LOCAL_CFLAGS += -Werror
+
LOCAL_STATIC_LIBRARIES := \
libstagefright_amrnbdec libstagefright_amrwbdec
diff --git a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
index 3320688..d1b0f76 100644
--- a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
@@ -274,7 +274,7 @@ static size_t getFrameSize(unsigned FT) {
return frameSize;
}
-void SoftAMR::onQueueFilled(OMX_U32 portIndex) {
+void SoftAMR::onQueueFilled(OMX_U32 /* portIndex */) {
List<BufferInfo *> &inQueue = getPortQueue(0);
List<BufferInfo *> &outQueue = getPortQueue(1);
@@ -428,7 +428,7 @@ void SoftAMR::onQueueFilled(OMX_U32 portIndex) {
}
}
-void SoftAMR::onPortFlushCompleted(OMX_U32 portIndex) {
+void SoftAMR::onPortFlushCompleted(OMX_U32 /* portIndex */) {
}
void SoftAMR::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
diff --git a/media/libstagefright/codecs/amrnb/enc/Android.mk b/media/libstagefright/codecs/amrnb/enc/Android.mk
index f4e467a..afc0b89 100644
--- a/media/libstagefright/codecs/amrnb/enc/Android.mk
+++ b/media/libstagefright/codecs/amrnb/enc/Android.mk
@@ -69,6 +69,8 @@ LOCAL_C_INCLUDES := \
LOCAL_CFLAGS := \
-DOSCL_UNUSED_ARG=
+LOCAL_CFLAGS += -Werror
+
LOCAL_MODULE := libstagefright_amrnbenc
include $(BUILD_STATIC_LIBRARY)
@@ -88,6 +90,8 @@ LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/../common/include \
$(LOCAL_PATH)/../common
+LOCAL_CFLAGS += -Werror
+
LOCAL_STATIC_LIBRARIES := \
libstagefright_amrnbenc
diff --git a/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp b/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp
index 50b739c..9489457 100644
--- a/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp
@@ -270,7 +270,7 @@ OMX_ERRORTYPE SoftAMRNBEncoder::internalSetParameter(
}
}
-void SoftAMRNBEncoder::onQueueFilled(OMX_U32 portIndex) {
+void SoftAMRNBEncoder::onQueueFilled(OMX_U32 /* portIndex */) {
if (mSignalledError) {
return;
}
diff --git a/media/libstagefright/codecs/amrwb/Android.mk b/media/libstagefright/codecs/amrwb/Android.mk
index 677107f..efdf988 100644
--- a/media/libstagefright/codecs/amrwb/Android.mk
+++ b/media/libstagefright/codecs/amrwb/Android.mk
@@ -50,6 +50,8 @@ LOCAL_C_INCLUDES := \
LOCAL_CFLAGS := \
-DOSCL_UNUSED_ARG= -DOSCL_IMPORT_REF=
+LOCAL_CFLAGS += -Werror
+
LOCAL_MODULE := libstagefright_amrwbdec
include $(BUILD_STATIC_LIBRARY)
diff --git a/media/libstagefright/codecs/amrwbenc/Android.mk b/media/libstagefright/codecs/amrwbenc/Android.mk
index c5b8e0c..64fe8d1 100644
--- a/media/libstagefright/codecs/amrwbenc/Android.mk
+++ b/media/libstagefright/codecs/amrwbenc/Android.mk
@@ -112,6 +112,8 @@ LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/asm/ARMV5E
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/asm/ARMV7
endif
+LOCAL_CFLAGS += -Werror
+
include $(BUILD_STATIC_LIBRARY)
################################################################################
@@ -126,6 +128,8 @@ LOCAL_C_INCLUDES := \
frameworks/av/media/libstagefright/codecs/common/include \
frameworks/native/include/media/openmax
+LOCAL_CFLAGS += -Werror
+
LOCAL_STATIC_LIBRARIES := \
libstagefright_amrwbenc
diff --git a/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp b/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp
index 9ccb49c..91a512d 100644
--- a/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp
+++ b/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp
@@ -317,7 +317,7 @@ OMX_ERRORTYPE SoftAMRWBEncoder::internalSetParameter(
}
}
-void SoftAMRWBEncoder::onQueueFilled(OMX_U32 portIndex) {
+void SoftAMRWBEncoder::onQueueFilled(OMX_U32 /* portIndex */) {
if (mSignalledError) {
return;
}
diff --git a/media/libstagefright/codecs/amrwbenc/src/autocorr.c b/media/libstagefright/codecs/amrwbenc/src/autocorr.c
index 8c477ca..0b2ea89 100644
--- a/media/libstagefright/codecs/amrwbenc/src/autocorr.c
+++ b/media/libstagefright/codecs/amrwbenc/src/autocorr.c
@@ -28,6 +28,8 @@
#include "acelp.h"
#include "ham_wind.tab"
+#define UNUSED(x) (void)(x)
+
void Autocorr(
Word16 x[], /* (i) : Input signal */
Word16 m, /* (i) : LPC order */
@@ -40,6 +42,8 @@ void Autocorr(
Word32 L_sum, L_sum1, L_tmp, F_LEN;
Word16 *p1,*p2,*p3;
const Word16 *p4;
+ UNUSED(m);
+
/* Windowing of signal */
p1 = x;
p4 = vo_window;
diff --git a/media/libstagefright/codecs/amrwbenc/src/convolve.c b/media/libstagefright/codecs/amrwbenc/src/convolve.c
index acba532..4c1f7d4 100644
--- a/media/libstagefright/codecs/amrwbenc/src/convolve.c
+++ b/media/libstagefright/codecs/amrwbenc/src/convolve.c
@@ -25,6 +25,8 @@
#include "typedef.h"
#include "basic_op.h"
+#define UNUSED(x) (void)(x)
+
void Convolve (
Word16 x[], /* (i) : input vector */
Word16 h[], /* (i) : impulse response */
@@ -35,6 +37,8 @@ void Convolve (
Word32 i, n;
Word16 *tmpH,*tmpX;
Word32 s;
+ UNUSED(L);
+
for (n = 0; n < 64;)
{
tmpH = h+n;
diff --git a/media/libstagefright/codecs/amrwbenc/src/pitch_f4.c b/media/libstagefright/codecs/amrwbenc/src/pitch_f4.c
index 0d66c31..b66b55e 100644
--- a/media/libstagefright/codecs/amrwbenc/src/pitch_f4.c
+++ b/media/libstagefright/codecs/amrwbenc/src/pitch_f4.c
@@ -31,6 +31,8 @@
#define UP_SAMP 4
#define L_INTERPOL1 4
+#define UNUSED(x) (void)(x)
+
/* Local functions */
#ifdef ASM_OPT
@@ -171,6 +173,7 @@ static void Norm_Corr(
Word32 corr, exp_corr, norm, exp, scale;
Word16 exp_norm, excf[L_SUBFR], tmp;
Word32 L_tmp, L_tmp1, L_tmp2;
+ UNUSED(L_subfr);
/* compute the filtered excitation for the first delay t_min */
k = -t_min;
diff --git a/media/libstagefright/codecs/amrwbenc/src/syn_filt.c b/media/libstagefright/codecs/amrwbenc/src/syn_filt.c
index 1bda05a..961aadc 100644
--- a/media/libstagefright/codecs/amrwbenc/src/syn_filt.c
+++ b/media/libstagefright/codecs/amrwbenc/src/syn_filt.c
@@ -26,6 +26,8 @@
#include "math_op.h"
#include "cnst.h"
+#define UNUSED(x) (void)(x)
+
void Syn_filt(
Word16 a[], /* (i) Q12 : a[m+1] prediction coefficients */
Word16 x[], /* (i) : input signal */
@@ -95,6 +97,8 @@ void Syn_filt_32(
Word32 i,a0;
Word32 L_tmp, L_tmp1;
Word16 *p1, *p2, *p3;
+ UNUSED(m);
+
a0 = a[0] >> (4 + Qnew); /* input / 16 and >>Qnew */
/* Do the filtering. */
for (i = 0; i < lg; i++)
diff --git a/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c b/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
index ea9da52..df7b9b3 100644
--- a/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
+++ b/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
@@ -39,6 +39,8 @@
#include "mem_align.h"
#include "cmnMemory.h"
+#define UNUSED(x) (void)(x)
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -1602,6 +1604,8 @@ VO_U32 VO_API voAMRWB_Init(VO_HANDLE * phCodec, /* o: the audi
VO_MEM_OPERATOR voMemoprator;
#endif
VO_MEM_OPERATOR *pMemOP;
+ UNUSED(vType);
+
int interMem = 0;
if(pUserData == NULL || pUserData->memflag != VO_IMF_USERMEMOPERATOR || pUserData->memData == NULL )
diff --git a/media/libstagefright/codecs/avc/common/Android.mk b/media/libstagefright/codecs/avc/common/Android.mk
index 22dee15..844ef0a 100644
--- a/media/libstagefright/codecs/avc/common/Android.mk
+++ b/media/libstagefright/codecs/avc/common/Android.mk
@@ -16,4 +16,6 @@ LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/src \
$(LOCAL_PATH)/include
+LOCAL_CFLAGS += -Werror
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/codecs/avc/enc/Android.mk b/media/libstagefright/codecs/avc/enc/Android.mk
index 7d17c2a..537ba42 100644
--- a/media/libstagefright/codecs/avc/enc/Android.mk
+++ b/media/libstagefright/codecs/avc/enc/Android.mk
@@ -30,6 +30,8 @@ LOCAL_C_INCLUDES := \
LOCAL_CFLAGS := \
-DOSCL_IMPORT_REF= -DOSCL_UNUSED_ARG= -DOSCL_EXPORT_REF=
+LOCAL_CFLAGS += -Werror
+
include $(BUILD_STATIC_LIBRARY)
################################################################################
@@ -69,4 +71,6 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_MODULE := libstagefright_soft_h264enc
LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS += -Werror
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp b/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp
index 1d398fb..a15b040 100644
--- a/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp
+++ b/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp
@@ -34,6 +34,12 @@
#include "SoftAVCEncoder.h"
+#if LOG_NDEBUG
+#define UNUSED_UNLESS_VERBOSE(x) (void)(x)
+#else
+#define UNUSED_UNLESS_VERBOSE(x)
+#endif
+
namespace android {
template<class T>
@@ -136,14 +142,14 @@ inline static void ConvertYUV420SemiPlanarToYUV420Planar(
}
static void* MallocWrapper(
- void *userData, int32_t size, int32_t attrs) {
+ void * /* userData */, int32_t size, int32_t /* attrs */) {
void *ptr = malloc(size);
if (ptr)
memset(ptr, 0, size);
return ptr;
}
-static void FreeWrapper(void *userData, void* ptr) {
+static void FreeWrapper(void * /* userData */, void* ptr) {
free(ptr);
}
@@ -217,7 +223,7 @@ OMX_ERRORTYPE SoftAVCEncoder::initEncParams() {
mHandle->CBAVC_Free = FreeWrapper;
CHECK(mEncParams != NULL);
- memset(mEncParams, 0, sizeof(mEncParams));
+ memset(mEncParams, 0, sizeof(*mEncParams));
mEncParams->rate_control = AVC_ON;
mEncParams->initQP = 0;
mEncParams->init_CBP_removal_delay = 1600;
@@ -722,7 +728,7 @@ OMX_ERRORTYPE SoftAVCEncoder::internalSetParameter(
}
}
-void SoftAVCEncoder::onQueueFilled(OMX_U32 portIndex) {
+void SoftAVCEncoder::onQueueFilled(OMX_U32 /* portIndex */) {
if (mSignalledError || mSawInputEOS) {
return;
}
@@ -795,7 +801,7 @@ void SoftAVCEncoder::onQueueFilled(OMX_U32 portIndex) {
}
}
- buffer_handle_t srcBuffer; // for MetaDataMode only
+ buffer_handle_t srcBuffer = NULL; // for MetaDataMode only
// Get next input video frame
if (mReadyForNextFrame) {
@@ -964,6 +970,7 @@ int32_t SoftAVCEncoder::bindOutputBuffer(int32_t index, uint8_t **yuv) {
}
void SoftAVCEncoder::signalBufferReturned(MediaBuffer *buffer) {
+ UNUSED_UNLESS_VERBOSE(buffer);
ALOGV("signalBufferReturned: %p", buffer);
}
diff --git a/media/libstagefright/codecs/common/Android.mk b/media/libstagefright/codecs/common/Android.mk
index a33cb92..b0010ff 100644
--- a/media/libstagefright/codecs/common/Android.mk
+++ b/media/libstagefright/codecs/common/Android.mk
@@ -14,6 +14,8 @@ LOCAL_STATIC_LIBRARIES :=
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/include
+LOCAL_CFLAGS += -Werror
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/codecs/common/cmnMemory.c b/media/libstagefright/codecs/common/cmnMemory.c
index aa52bd9..5bb6cc4 100644
--- a/media/libstagefright/codecs/common/cmnMemory.c
+++ b/media/libstagefright/codecs/common/cmnMemory.c
@@ -26,8 +26,12 @@
//VO_MEM_OPERATOR g_memOP;
+#define UNUSED(x) (void)(x)
+
VO_U32 cmnMemAlloc (VO_S32 uID, VO_MEM_INFO * pMemInfo)
{
+ UNUSED(uID);
+
if (!pMemInfo)
return VO_ERR_INVALID_ARG;
@@ -37,34 +41,48 @@ VO_U32 cmnMemAlloc (VO_S32 uID, VO_MEM_INFO * pMemInfo)
VO_U32 cmnMemFree (VO_S32 uID, VO_PTR pMem)
{
+ UNUSED(uID);
+
free (pMem);
return 0;
}
VO_U32 cmnMemSet (VO_S32 uID, VO_PTR pBuff, VO_U8 uValue, VO_U32 uSize)
{
+ UNUSED(uID);
+
memset (pBuff, uValue, uSize);
return 0;
}
VO_U32 cmnMemCopy (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize)
{
+ UNUSED(uID);
+
memcpy (pDest, pSource, uSize);
return 0;
}
VO_U32 cmnMemCheck (VO_S32 uID, VO_PTR pBuffer, VO_U32 uSize)
{
+ UNUSED(uID);
+ UNUSED(pBuffer);
+ UNUSED(uSize);
+
return 0;
}
VO_S32 cmnMemCompare (VO_S32 uID, VO_PTR pBuffer1, VO_PTR pBuffer2, VO_U32 uSize)
{
+ UNUSED(uID);
+
return memcmp(pBuffer1, pBuffer2, uSize);
}
VO_U32 cmnMemMove (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize)
{
+ UNUSED(uID);
+
memmove (pDest, pSource, uSize);
return 0;
}
diff --git a/media/libstagefright/codecs/flac/enc/Android.mk b/media/libstagefright/codecs/flac/enc/Android.mk
index f01d605..59a11de 100644
--- a/media/libstagefright/codecs/flac/enc/Android.mk
+++ b/media/libstagefright/codecs/flac/enc/Android.mk
@@ -9,6 +9,8 @@ LOCAL_C_INCLUDES := \
frameworks/native/include/media/openmax \
external/flac/include
+LOCAL_CFLAGS += -Werror
+
LOCAL_SHARED_LIBRARIES := \
libstagefright libstagefright_omx libstagefright_foundation libutils liblog
diff --git a/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp b/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp
index e64fe72..40661e7 100644
--- a/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp
+++ b/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp
@@ -27,6 +27,12 @@
#define FLAC_COMPRESSION_LEVEL_DEFAULT 5
#define FLAC_COMPRESSION_LEVEL_MAX 8
+#if LOG_NDEBUG
+#define UNUSED_UNLESS_VERBOSE(x) (void)(x)
+#else
+#define UNUSED_UNLESS_VERBOSE(x)
+#endif
+
namespace android {
template<class T>
@@ -257,7 +263,7 @@ OMX_ERRORTYPE SoftFlacEncoder::internalSetParameter(
}
void SoftFlacEncoder::onQueueFilled(OMX_U32 portIndex) {
-
+ UNUSED_UNLESS_VERBOSE(portIndex);
ALOGV("SoftFlacEncoder::onQueueFilled(portIndex=%ld)", portIndex);
if (mSignalledError) {
@@ -343,10 +349,11 @@ void SoftFlacEncoder::onQueueFilled(OMX_U32 portIndex) {
}
}
-
FLAC__StreamEncoderWriteStatus SoftFlacEncoder::onEncodedFlacAvailable(
const FLAC__byte buffer[],
- size_t bytes, unsigned samples, unsigned current_frame) {
+ size_t bytes, unsigned samples,
+ unsigned current_frame) {
+ UNUSED_UNLESS_VERBOSE(current_frame);
ALOGV("SoftFlacEncoder::onEncodedFlacAvailable(bytes=%d, samples=%d, curr_frame=%d)",
bytes, samples, current_frame);
@@ -444,8 +451,12 @@ return_result:
// static
FLAC__StreamEncoderWriteStatus SoftFlacEncoder::flacEncoderWriteCallback(
- const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[],
- size_t bytes, unsigned samples, unsigned current_frame, void *client_data) {
+ const FLAC__StreamEncoder * /* encoder */,
+ const FLAC__byte buffer[],
+ size_t bytes,
+ unsigned samples,
+ unsigned current_frame,
+ void *client_data) {
return ((SoftFlacEncoder*) client_data)->onEncodedFlacAvailable(
buffer, bytes, samples, current_frame);
}
diff --git a/media/libstagefright/codecs/g711/dec/Android.mk b/media/libstagefright/codecs/g711/dec/Android.mk
index 4c80da6..a0112e1 100644
--- a/media/libstagefright/codecs/g711/dec/Android.mk
+++ b/media/libstagefright/codecs/g711/dec/Android.mk
@@ -14,4 +14,6 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_MODULE := libstagefright_soft_g711dec
LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS += -Werror
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/codecs/g711/dec/SoftG711.cpp b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
index bcdd3c7..160ada0 100644
--- a/media/libstagefright/codecs/g711/dec/SoftG711.cpp
+++ b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
@@ -182,7 +182,7 @@ OMX_ERRORTYPE SoftG711::internalSetParameter(
}
}
-void SoftG711::onQueueFilled(OMX_U32 portIndex) {
+void SoftG711::onQueueFilled(OMX_U32 /* portIndex */) {
if (mSignalledError) {
return;
}
diff --git a/media/libstagefright/codecs/gsm/dec/Android.mk b/media/libstagefright/codecs/gsm/dec/Android.mk
index 71613d2..30868d5 100644
--- a/media/libstagefright/codecs/gsm/dec/Android.mk
+++ b/media/libstagefright/codecs/gsm/dec/Android.mk
@@ -9,6 +9,8 @@ LOCAL_C_INCLUDES := \
frameworks/native/include/media/openmax \
external/libgsm/inc
+LOCAL_CFLAGS += -Werror
+
LOCAL_SHARED_LIBRARIES := \
libstagefright libstagefright_omx libstagefright_foundation libutils liblog
diff --git a/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp b/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
index 00e0c85..18f7d29 100644
--- a/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
+++ b/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
@@ -172,7 +172,7 @@ OMX_ERRORTYPE SoftGSM::internalSetParameter(
}
}
-void SoftGSM::onQueueFilled(OMX_U32 portIndex) {
+void SoftGSM::onQueueFilled(OMX_U32 /* portIndex */) {
if (mSignalledError) {
return;
}
diff --git a/media/libstagefright/codecs/m4v_h263/dec/Android.mk b/media/libstagefright/codecs/m4v_h263/dec/Android.mk
index a3d5779..1d232c6 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/Android.mk
+++ b/media/libstagefright/codecs/m4v_h263/dec/Android.mk
@@ -46,6 +46,8 @@ LOCAL_C_INCLUDES := \
LOCAL_CFLAGS := -DOSCL_EXPORT_REF= -DOSCL_IMPORT_REF=
+LOCAL_CFLAGS += -Werror
+
include $(BUILD_STATIC_LIBRARY)
################################################################################
@@ -72,4 +74,6 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_MODULE := libstagefright_soft_mpeg4dec
LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS += -Werror
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
index fb2a430..0d1ab71 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
@@ -91,7 +91,7 @@ status_t SoftMPEG4::initDecoder() {
return OK;
}
-void SoftMPEG4::onQueueFilled(OMX_U32 portIndex) {
+void SoftMPEG4::onQueueFilled(OMX_U32 /* portIndex */) {
if (mSignalledError || mOutputPortSettingsChange != NONE) {
return;
}
diff --git a/media/libstagefright/codecs/m4v_h263/enc/Android.mk b/media/libstagefright/codecs/m4v_h263/enc/Android.mk
index 83a2dd2..c9006d9 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/Android.mk
+++ b/media/libstagefright/codecs/m4v_h263/enc/Android.mk
@@ -33,6 +33,8 @@ LOCAL_C_INCLUDES := \
$(TOP)/frameworks/av/media/libstagefright/include \
$(TOP)/frameworks/native/include/media/openmax
+LOCAL_CFLAGS += -Werror
+
include $(BUILD_STATIC_LIBRARY)
################################################################################
@@ -72,4 +74,6 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_MODULE := libstagefright_soft_mpeg4enc
LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS += -Werror
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
index e02af90..2c73e57 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
@@ -620,7 +620,7 @@ OMX_ERRORTYPE SoftMPEG4Encoder::internalSetParameter(
}
}
-void SoftMPEG4Encoder::onQueueFilled(OMX_U32 portIndex) {
+void SoftMPEG4Encoder::onQueueFilled(OMX_U32 /* portIndex */) {
if (mSignalledError || mSawInputEOS) {
return;
}
@@ -677,7 +677,7 @@ void SoftMPEG4Encoder::onQueueFilled(OMX_U32 portIndex) {
mSawInputEOS = true;
}
- buffer_handle_t srcBuffer; // for MetaDataMode only
+ buffer_handle_t srcBuffer = NULL; // for MetaDataMode only
if (inHeader->nFilledLen > 0) {
uint8_t *inputData = NULL;
if (mStoreMetaDataInBuffers) {
diff --git a/media/libstagefright/codecs/mp3dec/Android.mk b/media/libstagefright/codecs/mp3dec/Android.mk
index 135c715..8284490 100644
--- a/media/libstagefright/codecs/mp3dec/Android.mk
+++ b/media/libstagefright/codecs/mp3dec/Android.mk
@@ -50,6 +50,8 @@ LOCAL_C_INCLUDES := \
LOCAL_CFLAGS := \
-DOSCL_UNUSED_ARG=
+LOCAL_CFLAGS += -Werror
+
LOCAL_MODULE := libstagefright_mp3dec
LOCAL_ARM_MODE := arm
@@ -69,6 +71,8 @@ LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/src \
$(LOCAL_PATH)/include
+LOCAL_CFLAGS += -Werror
+
LOCAL_SHARED_LIBRARIES := \
libstagefright libstagefright_omx libstagefright_foundation libutils liblog
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
index 7c382fb..a09ab7c 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
@@ -49,6 +49,8 @@ SoftMP3::SoftMP3(
mNumChannels(2),
mSamplingRate(44100),
mSignalledError(false),
+ mSawInputEos(false),
+ mSignalledOutputEos(false),
mOutputPortSettingsChange(NONE) {
initPorts();
initDecoder();
@@ -186,7 +188,7 @@ OMX_ERRORTYPE SoftMP3::internalSetParameter(
}
}
-void SoftMP3::onQueueFilled(OMX_U32 portIndex) {
+void SoftMP3::onQueueFilled(OMX_U32 /* portIndex */) {
if (mSignalledError || mOutputPortSettingsChange != NONE) {
return;
}
@@ -194,48 +196,36 @@ void SoftMP3::onQueueFilled(OMX_U32 portIndex) {
List<BufferInfo *> &inQueue = getPortQueue(0);
List<BufferInfo *> &outQueue = getPortQueue(1);
- while (!inQueue.empty() && !outQueue.empty()) {
- BufferInfo *inInfo = *inQueue.begin();
- OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+ while ((!inQueue.empty() || (mSawInputEos && !mSignalledOutputEos)) && !outQueue.empty()) {
+ BufferInfo *inInfo = NULL;
+ OMX_BUFFERHEADERTYPE *inHeader = NULL;
+ if (!inQueue.empty()) {
+ inInfo = *inQueue.begin();
+ inHeader = inInfo->mHeader;
+ }
BufferInfo *outInfo = *outQueue.begin();
OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+ outHeader->nFlags = 0;
- if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
- inQueue.erase(inQueue.begin());
- inInfo->mOwnedByUs = false;
- notifyEmptyBufferDone(inHeader);
-
- if (!mIsFirst) {
- // pad the end of the stream with 529 samples, since that many samples
- // were trimmed off the beginning when decoding started
- outHeader->nFilledLen =
- kPVMP3DecoderDelay * mNumChannels * sizeof(int16_t);
+ if (inHeader) {
+ if (inHeader->nOffset == 0 && inHeader->nFilledLen) {
+ mAnchorTimeUs = inHeader->nTimeStamp;
+ mNumFramesOutput = 0;
+ }
- memset(outHeader->pBuffer, 0, outHeader->nFilledLen);
- } else {
- // Since we never discarded frames from the start, we won't have
- // to add any padding at the end either.
- outHeader->nFilledLen = 0;
+ if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+ mSawInputEos = true;
}
- outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+ mConfig->pInputBuffer =
+ inHeader->pBuffer + inHeader->nOffset;
- outQueue.erase(outQueue.begin());
- outInfo->mOwnedByUs = false;
- notifyFillBufferDone(outHeader);
- return;
- }
-
- if (inHeader->nOffset == 0) {
- mAnchorTimeUs = inHeader->nTimeStamp;
- mNumFramesOutput = 0;
+ mConfig->inputBufferCurrentLength = inHeader->nFilledLen;
+ } else {
+ mConfig->pInputBuffer = NULL;
+ mConfig->inputBufferCurrentLength = 0;
}
-
- mConfig->pInputBuffer =
- inHeader->pBuffer + inHeader->nOffset;
-
- mConfig->inputBufferCurrentLength = inHeader->nFilledLen;
mConfig->inputBufferMaxLength = 0;
mConfig->inputBufferUsedLength = 0;
@@ -262,13 +252,28 @@ void SoftMP3::onQueueFilled(OMX_U32 portIndex) {
mConfig->outputFrameSize = kOutputBufferSize / sizeof(int16_t);
}
- // This is recoverable, just ignore the current frame and
- // play silence instead.
- memset(outHeader->pBuffer,
- 0,
- mConfig->outputFrameSize * sizeof(int16_t));
-
- mConfig->inputBufferUsedLength = inHeader->nFilledLen;
+ if (decoderErr == NO_ENOUGH_MAIN_DATA_ERROR && mSawInputEos) {
+ if (!mIsFirst) {
+ // pad the end of the stream with 529 samples, since that many samples
+ // were trimmed off the beginning when decoding started
+ outHeader->nOffset = 0;
+ outHeader->nFilledLen = kPVMP3DecoderDelay * mNumChannels * sizeof(int16_t);
+
+ memset(outHeader->pBuffer, 0, outHeader->nFilledLen);
+ }
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+ mSignalledOutputEos = true;
+ } else {
+ // This is recoverable, just ignore the current frame and
+ // play silence instead.
+ memset(outHeader->pBuffer,
+ 0,
+ mConfig->outputFrameSize * sizeof(int16_t));
+
+ if (inHeader) {
+ mConfig->inputBufferUsedLength = inHeader->nFilledLen;
+ }
+ }
} else if (mConfig->samplingRate != mSamplingRate
|| mConfig->num_channels != mNumChannels) {
mSamplingRate = mConfig->samplingRate;
@@ -289,7 +294,7 @@ void SoftMP3::onQueueFilled(OMX_U32 portIndex) {
outHeader->nFilledLen =
mConfig->outputFrameSize * sizeof(int16_t) - outHeader->nOffset;
- } else {
+ } else if (!mSignalledOutputEos) {
outHeader->nOffset = 0;
outHeader->nFilledLen = mConfig->outputFrameSize * sizeof(int16_t);
}
@@ -298,23 +303,24 @@ void SoftMP3::onQueueFilled(OMX_U32 portIndex) {
mAnchorTimeUs
+ (mNumFramesOutput * 1000000ll) / mConfig->samplingRate;
- outHeader->nFlags = 0;
-
- CHECK_GE(inHeader->nFilledLen, mConfig->inputBufferUsedLength);
+ if (inHeader) {
+ CHECK_GE(inHeader->nFilledLen, mConfig->inputBufferUsedLength);
- inHeader->nOffset += mConfig->inputBufferUsedLength;
- inHeader->nFilledLen -= mConfig->inputBufferUsedLength;
+ inHeader->nOffset += mConfig->inputBufferUsedLength;
+ inHeader->nFilledLen -= mConfig->inputBufferUsedLength;
- mNumFramesOutput += mConfig->outputFrameSize / mNumChannels;
- if (inHeader->nFilledLen == 0) {
- inInfo->mOwnedByUs = false;
- inQueue.erase(inQueue.begin());
- inInfo = NULL;
- notifyEmptyBufferDone(inHeader);
- inHeader = NULL;
+ if (inHeader->nFilledLen == 0) {
+ inInfo->mOwnedByUs = false;
+ inQueue.erase(inQueue.begin());
+ inInfo = NULL;
+ notifyEmptyBufferDone(inHeader);
+ inHeader = NULL;
+ }
}
+ mNumFramesOutput += mConfig->outputFrameSize / mNumChannels;
+
outInfo->mOwnedByUs = false;
outQueue.erase(outQueue.begin());
outInfo = NULL;
@@ -329,6 +335,9 @@ void SoftMP3::onPortFlushCompleted(OMX_U32 portIndex) {
// depend on fragments from the last one decoded.
pvmp3_InitDecoder(mConfig, mDecoderBuf);
mIsFirst = true;
+ mSignalledError = false;
+ mSawInputEos = false;
+ mSignalledOutputEos = false;
}
}
@@ -362,6 +371,8 @@ void SoftMP3::onReset() {
pvmp3_InitDecoder(mConfig, mDecoderBuf);
mIsFirst = true;
mSignalledError = false;
+ mSawInputEos = false;
+ mSignalledOutputEos = false;
mOutputPortSettingsChange = NONE;
}
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.h b/media/libstagefright/codecs/mp3dec/SoftMP3.h
index 4af91ea..f9e7b53 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.h
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.h
@@ -61,6 +61,8 @@ private:
bool mIsFirst;
bool mSignalledError;
+ bool mSawInputEos;
+ bool mSignalledOutputEos;
enum {
NONE,
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.cpp b/media/libstagefright/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.cpp
index ee42dc5..499672b 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.cpp
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.cpp
@@ -139,7 +139,7 @@ void pvmp3_mpeg2_get_scale_data(mp3SideInfo *si,
int16 blocknumber = 0;
granuleInfo *gr_info = &(si->ch[ch].gran[gr]);
- uint32 scalefac_comp, int_scalefac_comp, new_slen[4];
+ uint32 scalefac_comp, int_scalefac_comp, new_slen[4] = { 0,0,0,0 };
scalefac_comp = gr_info->scalefac_compress;
diff --git a/media/libstagefright/codecs/on2/dec/Android.mk b/media/libstagefright/codecs/on2/dec/Android.mk
index 7f2c46d..93ff64c 100644
--- a/media/libstagefright/codecs/on2/dec/Android.mk
+++ b/media/libstagefright/codecs/on2/dec/Android.mk
@@ -20,4 +20,6 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_MODULE := libstagefright_soft_vpxdec
LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS += -Werror
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
index 476e986..423a057 100644
--- a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
+++ b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
@@ -85,7 +85,7 @@ status_t SoftVPX::initDecoder() {
return OK;
}
-void SoftVPX::onQueueFilled(OMX_U32 portIndex) {
+void SoftVPX::onQueueFilled(OMX_U32 /* portIndex */) {
if (mOutputPortSettingsChange != NONE) {
return;
}
diff --git a/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp b/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp
index 7ddb13c..a7bde97 100644
--- a/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp
+++ b/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp
@@ -98,7 +98,7 @@ status_t SoftAVC::initDecoder() {
return UNKNOWN_ERROR;
}
-void SoftAVC::onQueueFilled(OMX_U32 portIndex) {
+void SoftAVC::onQueueFilled(OMX_U32 /* portIndex */) {
if (mSignalledError || mOutputPortSettingsChange != NONE) {
return;
}
diff --git a/media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c b/media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c
index 2bb4c4d..524a3f0 100644
--- a/media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c
+++ b/media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c
@@ -42,6 +42,8 @@
#include "h264bsd_decoder.h"
#include "h264bsd_util.h"
+#define UNUSED(x) (void)(x)
+
/*------------------------------------------------------------------------------
Version Information
------------------------------------------------------------------------------*/
@@ -73,6 +75,7 @@ H264DEC_EVALUATION Compile evaluation version, restricts number of frames
#endif
void H264SwDecTrace(char *string) {
+ UNUSED(string);
}
void* H264SwDecMalloc(u32 size) {
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c
index 493fb9e..7a262ed 100755
--- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c
@@ -267,7 +267,7 @@ u32 ConcealMb(mbStorage_t *pMb, image_t *currImage, u32 row, u32 col,
i32 firstPhase[16];
i32 *pTmp;
/* neighbours above, below, left and right */
- i32 a[4], b[4], l[4], r[4];
+ i32 a[4] = { 0,0,0,0 }, b[4], l[4] = { 0,0,0,0 }, r[4];
u32 A, B, L, R;
#ifdef H264DEC_OMXDL
u8 fillBuff[32*21 + 15 + 32];
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_reconstruct.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_reconstruct.c
index c948776..b409a06 100755
--- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_reconstruct.c
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_reconstruct.c
@@ -42,6 +42,8 @@
#include "armVC.h"
#endif /* H264DEC_OMXDL */
+#define UNUSED(x) (void)(x)
+
/*------------------------------------------------------------------------------
2. External compiler flags
--------------------------------------------------------------------------------
@@ -2136,7 +2138,8 @@ static void FillRow1(
i32 center,
i32 right)
{
-
+ UNUSED(left);
+ UNUSED(right);
ASSERT(ref);
ASSERT(fill);
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_header.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_header.c
index a7c6f64..23401c6 100755
--- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_header.c
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_header.c
@@ -47,6 +47,8 @@
#include "h264bsd_nal_unit.h"
#include "h264bsd_dpb.h"
+#define UNUSED(x) (void)(x)
+
/*------------------------------------------------------------------------------
2. External compiler flags
--------------------------------------------------------------------------------
@@ -1407,6 +1409,7 @@ u32 h264bsdCheckPriorPicsFlag(u32 * noOutputOfPriorPicsFlag,
u32 tmp, value, i;
i32 ivalue;
strmData_t tmpStrmData[1];
+ UNUSED(nalUnitType);
/* Code */
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.c
index cc838fd..fb97a28 100755
--- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.c
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.c
@@ -186,7 +186,7 @@ u32 h264bsdMoreRbspData(strmData_t *pStrmData)
return(HANTRO_FALSE);
if ( (bits > 8) ||
- ((h264bsdShowBits32(pStrmData)>>(32-bits)) != (1 << (bits-1))) )
+ ((h264bsdShowBits32(pStrmData)>>(32-bits)) != (1ul << (bits-1))) )
return(HANTRO_TRUE);
else
return(HANTRO_FALSE);
diff --git a/media/libstagefright/codecs/raw/Android.mk b/media/libstagefright/codecs/raw/Android.mk
index fe90a03..87080e7 100644
--- a/media/libstagefright/codecs/raw/Android.mk
+++ b/media/libstagefright/codecs/raw/Android.mk
@@ -8,6 +8,8 @@ LOCAL_C_INCLUDES := \
frameworks/av/media/libstagefright/include \
frameworks/native/include/media/openmax
+LOCAL_CFLAGS += -Werror
+
LOCAL_SHARED_LIBRARIES := \
libstagefright_omx libstagefright_foundation libutils liblog
diff --git a/media/libstagefright/codecs/raw/SoftRaw.cpp b/media/libstagefright/codecs/raw/SoftRaw.cpp
index 19d6f13..9d514a6 100644
--- a/media/libstagefright/codecs/raw/SoftRaw.cpp
+++ b/media/libstagefright/codecs/raw/SoftRaw.cpp
@@ -163,7 +163,7 @@ OMX_ERRORTYPE SoftRaw::internalSetParameter(
}
}
-void SoftRaw::onQueueFilled(OMX_U32 portIndex) {
+void SoftRaw::onQueueFilled(OMX_U32 /* portIndex */) {
if (mSignalledError) {
return;
}
diff --git a/media/libstagefright/codecs/vorbis/dec/Android.mk b/media/libstagefright/codecs/vorbis/dec/Android.mk
index 2232353..217a6d2 100644
--- a/media/libstagefright/codecs/vorbis/dec/Android.mk
+++ b/media/libstagefright/codecs/vorbis/dec/Android.mk
@@ -16,4 +16,6 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_MODULE := libstagefright_soft_vorbisdec
LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS += -Werror
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
index 51bb958..515e4d3 100644
--- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
+++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
@@ -54,6 +54,8 @@ SoftVorbis::SoftVorbis(
mAnchorTimeUs(0),
mNumFramesOutput(0),
mNumFramesLeftOnPage(-1),
+ mSawInputEos(false),
+ mSignalledOutputEos(false),
mOutputPortSettingsChange(NONE) {
initPorts();
CHECK_EQ(initDecoder(), (status_t)OK);
@@ -290,48 +292,47 @@ void SoftVorbis::onQueueFilled(OMX_U32 portIndex) {
return;
}
- while (!inQueue.empty() && !outQueue.empty()) {
- BufferInfo *inInfo = *inQueue.begin();
- OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+ while ((!inQueue.empty() || (mSawInputEos && !mSignalledOutputEos)) && !outQueue.empty()) {
+ BufferInfo *inInfo = NULL;
+ OMX_BUFFERHEADERTYPE *inHeader = NULL;
+ if (!inQueue.empty()) {
+ inInfo = *inQueue.begin();
+ inHeader = inInfo->mHeader;
+ }
BufferInfo *outInfo = *outQueue.begin();
OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
- if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
- inQueue.erase(inQueue.begin());
- inInfo->mOwnedByUs = false;
- notifyEmptyBufferDone(inHeader);
+ int32_t numPageSamples = 0;
- outHeader->nFilledLen = 0;
- outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+ if (inHeader) {
+ if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+ mSawInputEos = true;
+ }
- outQueue.erase(outQueue.begin());
- outInfo->mOwnedByUs = false;
- notifyFillBufferDone(outHeader);
- return;
- }
+ if (inHeader->nFilledLen || !mSawInputEos) {
+ CHECK_GE(inHeader->nFilledLen, sizeof(numPageSamples));
+ memcpy(&numPageSamples,
+ inHeader->pBuffer
+ + inHeader->nOffset + inHeader->nFilledLen - 4,
+ sizeof(numPageSamples));
- int32_t numPageSamples;
- CHECK_GE(inHeader->nFilledLen, sizeof(numPageSamples));
- memcpy(&numPageSamples,
- inHeader->pBuffer
- + inHeader->nOffset + inHeader->nFilledLen - 4,
- sizeof(numPageSamples));
+ if (inHeader->nOffset == 0) {
+ mAnchorTimeUs = inHeader->nTimeStamp;
+ mNumFramesOutput = 0;
+ }
- if (numPageSamples >= 0) {
- mNumFramesLeftOnPage = numPageSamples;
+ inHeader->nFilledLen -= sizeof(numPageSamples);;
+ }
}
- if (inHeader->nOffset == 0) {
- mAnchorTimeUs = inHeader->nTimeStamp;
- mNumFramesOutput = 0;
+ if (numPageSamples >= 0) {
+ mNumFramesLeftOnPage = numPageSamples;
}
- inHeader->nFilledLen -= sizeof(numPageSamples);;
-
ogg_buffer buf;
- buf.data = inHeader->pBuffer + inHeader->nOffset;
- buf.size = inHeader->nFilledLen;
+ buf.data = inHeader ? inHeader->pBuffer + inHeader->nOffset : NULL;
+ buf.size = inHeader ? inHeader->nFilledLen : 0;
buf.refcount = 1;
buf.ptr.owner = NULL;
@@ -351,6 +352,7 @@ void SoftVorbis::onQueueFilled(OMX_U32 portIndex) {
int numFrames = 0;
+ outHeader->nFlags = 0;
int err = vorbis_dsp_synthesis(mState, &pack, 1);
if (err != 0) {
ALOGW("vorbis_dsp_synthesis returned %d", err);
@@ -370,13 +372,16 @@ void SoftVorbis::onQueueFilled(OMX_U32 portIndex) {
ALOGV("discarding %d frames at end of page",
numFrames - mNumFramesLeftOnPage);
numFrames = mNumFramesLeftOnPage;
+ if (mSawInputEos) {
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+ mSignalledOutputEos = true;
+ }
}
mNumFramesLeftOnPage -= numFrames;
}
outHeader->nFilledLen = numFrames * sizeof(int16_t) * mVi->channels;
outHeader->nOffset = 0;
- outHeader->nFlags = 0;
outHeader->nTimeStamp =
mAnchorTimeUs
@@ -384,11 +389,13 @@ void SoftVorbis::onQueueFilled(OMX_U32 portIndex) {
mNumFramesOutput += numFrames;
- inInfo->mOwnedByUs = false;
- inQueue.erase(inQueue.begin());
- inInfo = NULL;
- notifyEmptyBufferDone(inHeader);
- inHeader = NULL;
+ if (inHeader) {
+ inInfo->mOwnedByUs = false;
+ inQueue.erase(inQueue.begin());
+ inInfo = NULL;
+ notifyEmptyBufferDone(inHeader);
+ inHeader = NULL;
+ }
outInfo->mOwnedByUs = false;
outQueue.erase(outQueue.begin());
@@ -425,6 +432,8 @@ void SoftVorbis::onReset() {
mVi = NULL;
}
+ mSawInputEos = false;
+ mSignalledOutputEos = false;
mOutputPortSettingsChange = NONE;
}
diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h
index cb628a0..1d00816 100644
--- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h
+++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h
@@ -59,6 +59,8 @@ private:
int64_t mAnchorTimeUs;
int64_t mNumFramesOutput;
int32_t mNumFramesLeftOnPage;
+ bool mSawInputEos;
+ bool mSignalledOutputEos;
enum {
NONE,
diff --git a/media/libstagefright/foundation/ANetworkSession.cpp b/media/libstagefright/foundation/ANetworkSession.cpp
index e629588..08c4a87 100644
--- a/media/libstagefright/foundation/ANetworkSession.cpp
+++ b/media/libstagefright/foundation/ANetworkSession.cpp
@@ -521,7 +521,7 @@ status_t ANetworkSession::Session::readMore() {
return err;
}
-void ANetworkSession::Session::dumpFragmentStats(const Fragment &frag) {
+void ANetworkSession::Session::dumpFragmentStats(const Fragment & /* frag */) {
#if 0
int64_t nowUs = ALooper::GetNowUs();
int64_t delayMs = (nowUs - frag.mTimeUs) / 1000ll;
diff --git a/media/libstagefright/foundation/Android.mk b/media/libstagefright/foundation/Android.mk
index ad2dab5..90a6a23 100644
--- a/media/libstagefright/foundation/Android.mk
+++ b/media/libstagefright/foundation/Android.mk
@@ -24,7 +24,7 @@ LOCAL_SHARED_LIBRARIES := \
libutils \
liblog
-LOCAL_CFLAGS += -Wno-multichar
+LOCAL_CFLAGS += -Wno-multichar -Werror
LOCAL_MODULE:= libstagefright_foundation
diff --git a/media/libstagefright/foundation/base64.cpp b/media/libstagefright/foundation/base64.cpp
index d5fb4e0..dcf5bef 100644
--- a/media/libstagefright/foundation/base64.cpp
+++ b/media/libstagefright/foundation/base64.cpp
@@ -33,6 +33,10 @@ sp<ABuffer> decodeBase64(const AString &s) {
if (n >= 2 && s.c_str()[n - 2] == '=') {
padding = 2;
+
+ if (n >= 3 && s.c_str()[n - 3] == '=') {
+ padding = 3;
+ }
}
}
@@ -71,7 +75,7 @@ sp<ABuffer> decodeBase64(const AString &s) {
if (((i + 1) % 4) == 0) {
out[j++] = (accum >> 16);
- if (j < outLen) { out[j++] = (accum >> 8) & 0xff; }
+ if (j < outLen) { out[j++] = (accum >> 8) & 0xff; }
if (j < outLen) { out[j++] = accum & 0xff; }
accum = 0;
diff --git a/media/libstagefright/http/Android.mk b/media/libstagefright/http/Android.mk
new file mode 100644
index 0000000..7f3307d
--- /dev/null
+++ b/media/libstagefright/http/Android.mk
@@ -0,0 +1,28 @@
+LOCAL_PATH:= $(call my-dir)
+
+ifneq ($(TARGET_BUILD_PDK), true)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ HTTPHelper.cpp \
+
+LOCAL_C_INCLUDES:= \
+ $(TOP)/frameworks/av/media/libstagefright \
+ $(TOP)/frameworks/native/include/media/openmax \
+ $(TOP)/frameworks/base/core/jni \
+
+LOCAL_SHARED_LIBRARIES := \
+ libstagefright liblog libutils libbinder libstagefright_foundation \
+ libandroid_runtime \
+ libmedia
+
+LOCAL_MODULE:= libstagefright_http_support
+
+LOCAL_CFLAGS += -Wno-multichar
+
+LOCAL_CFLAGS += -Werror
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif
diff --git a/media/libstagefright/http/HTTPHelper.cpp b/media/libstagefright/http/HTTPHelper.cpp
new file mode 100644
index 0000000..77845e2
--- /dev/null
+++ b/media/libstagefright/http/HTTPHelper.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "HTTPHelper"
+#include <utils/Log.h>
+
+#include "HTTPHelper.h"
+
+#include "android_runtime/AndroidRuntime.h"
+#include "android_util_Binder.h"
+#include <media/IMediaHTTPService.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <nativehelper/ScopedLocalRef.h>
+#include "jni.h"
+
+namespace android {
+
+sp<IMediaHTTPService> CreateHTTPServiceInCurrentJavaContext() {
+ if (AndroidRuntime::getJavaVM() == NULL) {
+ ALOGE("CreateHTTPServiceInCurrentJavaContext called outside "
+ "JAVA environment.");
+ return NULL;
+ }
+
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+
+ ScopedLocalRef<jclass> clazz(
+ env, env->FindClass("android/media/MediaHTTPService"));
+ CHECK(clazz.get() != NULL);
+
+ jmethodID constructID = env->GetMethodID(clazz.get(), "<init>", "()V");
+ CHECK(constructID != NULL);
+
+ ScopedLocalRef<jobject> httpServiceObj(
+ env, env->NewObject(clazz.get(), constructID));
+
+ sp<IMediaHTTPService> httpService;
+ if (httpServiceObj.get() != NULL) {
+ jmethodID asBinderID =
+ env->GetMethodID(clazz.get(), "asBinder", "()Landroid/os/IBinder;");
+ CHECK(asBinderID != NULL);
+
+ ScopedLocalRef<jobject> httpServiceBinderObj(
+ env, env->CallObjectMethod(httpServiceObj.get(), asBinderID));
+ CHECK(httpServiceBinderObj.get() != NULL);
+
+ sp<IBinder> binder =
+ ibinderForJavaObject(env, httpServiceBinderObj.get());
+
+ httpService = interface_cast<IMediaHTTPService>(binder);
+ }
+
+ return httpService;
+}
+
+} // namespace android
diff --git a/media/libstagefright/include/chromium_http_stub.h b/media/libstagefright/http/HTTPHelper.h
index e0651a4..8aef115 100644
--- a/media/libstagefright/include/chromium_http_stub.h
+++ b/media/libstagefright/http/HTTPHelper.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 The Android Open Source Project
+ * Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,21 +14,18 @@
* limitations under the License.
*/
-#ifndef CHROMIUM_HTTP_STUB_H_
-#define CHROMIUM_HTTP_STUB_H_
+#ifndef HTTP_HELPER_H_
-#include <include/HTTPBase.h>
-#include <media/stagefright/DataSource.h>
+#define HTTP_HELPER_H_
+
+#include <utils/RefBase.h>
namespace android {
-extern "C" {
-HTTPBase *createChromiumHTTPDataSource(uint32_t flags);
-status_t UpdateChromiumHTTPDataSourceProxyConfig(
- const char *host, int32_t port, const char *exclusionList);
+struct IMediaHTTPService;
+
+sp<IMediaHTTPService> CreateHTTPServiceInCurrentJavaContext();
-DataSource *createDataUriSource(const char *uri);
-}
-}
+} // namespace android
-#endif
+#endif // HTTP_HELPER_H_
diff --git a/media/libstagefright/http/MediaHTTP.cpp b/media/libstagefright/http/MediaHTTP.cpp
new file mode 100644
index 0000000..157d967
--- /dev/null
+++ b/media/libstagefright/http/MediaHTTP.cpp
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MediaHTTP"
+#include <utils/Log.h>
+
+#include <media/stagefright/MediaHTTP.h>
+
+#include <binder/IServiceManager.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/Utils.h>
+
+#include <media/IMediaHTTPConnection.h>
+
+namespace android {
+
+MediaHTTP::MediaHTTP(const sp<IMediaHTTPConnection> &conn)
+ : mInitCheck(NO_INIT),
+ mHTTPConnection(conn),
+ mCachedSizeValid(false),
+ mCachedSize(0ll),
+ mDrmManagerClient(NULL) {
+ mInitCheck = OK;
+}
+
+MediaHTTP::~MediaHTTP() {
+ clearDRMState_l();
+}
+
+status_t MediaHTTP::connect(
+ const char *uri,
+ const KeyedVector<String8, String8> *headers,
+ off64_t /* offset */) {
+ if (mInitCheck != OK) {
+ return mInitCheck;
+ }
+
+ KeyedVector<String8, String8> extHeaders;
+ if (headers != NULL) {
+ extHeaders = *headers;
+ }
+ extHeaders.add(String8("User-Agent"), String8(MakeUserAgent().c_str()));
+
+ bool success = mHTTPConnection->connect(uri, &extHeaders);
+
+ mLastHeaders = extHeaders;
+ mLastURI = uri;
+
+ mCachedSizeValid = false;
+
+ return success ? OK : UNKNOWN_ERROR;
+}
+
+void MediaHTTP::disconnect() {
+ if (mInitCheck != OK) {
+ return;
+ }
+
+ mHTTPConnection->disconnect();
+}
+
+status_t MediaHTTP::initCheck() const {
+ return mInitCheck;
+}
+
+ssize_t MediaHTTP::readAt(off64_t offset, void *data, size_t size) {
+ if (mInitCheck != OK) {
+ return mInitCheck;
+ }
+
+ int64_t startTimeUs = ALooper::GetNowUs();
+
+ size_t numBytesRead = 0;
+ while (numBytesRead < size) {
+ size_t copy = size - numBytesRead;
+
+ if (copy > 64 * 1024) {
+ // limit the buffer sizes transferred across binder boundaries
+ // to avoid spurious transaction failures.
+ copy = 64 * 1024;
+ }
+
+ ssize_t n = mHTTPConnection->readAt(
+ offset + numBytesRead, (uint8_t *)data + numBytesRead, copy);
+
+ if (n < 0) {
+ return n;
+ } else if (n == 0) {
+ break;
+ }
+
+ numBytesRead += n;
+ }
+
+ int64_t delayUs = ALooper::GetNowUs() - startTimeUs;
+
+ addBandwidthMeasurement(numBytesRead, delayUs);
+
+ return numBytesRead;
+}
+
+status_t MediaHTTP::getSize(off64_t *size) {
+ if (mInitCheck != OK) {
+ return mInitCheck;
+ }
+
+ // Caching the returned size so that it stays valid even after a
+ // disconnect. NuCachedSource2 relies on this.
+
+ if (!mCachedSizeValid) {
+ mCachedSize = mHTTPConnection->getSize();
+ mCachedSizeValid = true;
+ }
+
+ *size = mCachedSize;
+
+ return *size < 0 ? *size : OK;
+}
+
+uint32_t MediaHTTP::flags() {
+ return kWantsPrefetching | kIsHTTPBasedSource;
+}
+
+status_t MediaHTTP::reconnectAtOffset(off64_t offset) {
+ return connect(mLastURI.c_str(), &mLastHeaders, offset);
+}
+
+// DRM...
+
+sp<DecryptHandle> MediaHTTP::DrmInitialization(const char* mime) {
+ if (mDrmManagerClient == NULL) {
+ mDrmManagerClient = new DrmManagerClient();
+ }
+
+ if (mDrmManagerClient == NULL) {
+ return NULL;
+ }
+
+ if (mDecryptHandle == NULL) {
+ mDecryptHandle = mDrmManagerClient->openDecryptSession(
+ String8(mLastURI.c_str()), mime);
+ }
+
+ if (mDecryptHandle == NULL) {
+ delete mDrmManagerClient;
+ mDrmManagerClient = NULL;
+ }
+
+ return mDecryptHandle;
+}
+
+void MediaHTTP::getDrmInfo(
+ sp<DecryptHandle> &handle, DrmManagerClient **client) {
+ handle = mDecryptHandle;
+ *client = mDrmManagerClient;
+}
+
+String8 MediaHTTP::getUri() {
+ return String8(mLastURI.c_str());
+}
+
+String8 MediaHTTP::getMIMEType() const {
+ if (mInitCheck != OK) {
+ return String8("application/octet-stream");
+ }
+
+ String8 mimeType;
+ status_t err = mHTTPConnection->getMIMEType(&mimeType);
+
+ if (err != OK) {
+ return String8("application/octet-stream");
+ }
+
+ return mimeType;
+}
+
+void MediaHTTP::clearDRMState_l() {
+ if (mDecryptHandle != NULL) {
+ // To release mDecryptHandle
+ CHECK(mDrmManagerClient);
+ mDrmManagerClient->closeDecryptSession(mDecryptHandle);
+ mDecryptHandle = NULL;
+ }
+}
+
+} // namespace android
diff --git a/media/libstagefright/httplive/Android.mk b/media/libstagefright/httplive/Android.mk
index f3529f9..e8d558c 100644
--- a/media/libstagefright/httplive/Android.mk
+++ b/media/libstagefright/httplive/Android.mk
@@ -13,6 +13,8 @@ LOCAL_C_INCLUDES:= \
$(TOP)/frameworks/native/include/media/openmax \
$(TOP)/external/openssl/include
+LOCAL_CFLAGS += -Werror
+
LOCAL_SHARED_LIBRARIES := \
libbinder \
libcrypto \
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 233db44..149a817 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -27,6 +27,8 @@
#include "mpeg2ts/AnotherPacketSource.h"
#include <cutils/properties.h>
+#include <media/IMediaHTTPConnection.h>
+#include <media/IMediaHTTPService.h>
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
@@ -34,6 +36,7 @@
#include <media/stagefright/DataSource.h>
#include <media/stagefright/FileSource.h>
#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaHTTP.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/Utils.h>
@@ -44,17 +47,13 @@
namespace android {
LiveSession::LiveSession(
- const sp<AMessage> &notify, uint32_t flags, bool uidValid, uid_t uid)
+ const sp<AMessage> &notify, uint32_t flags,
+ const sp<IMediaHTTPService> &httpService)
: mNotify(notify),
mFlags(flags),
- mUIDValid(uidValid),
- mUID(uid),
+ mHTTPService(httpService),
mInPreparationPhase(true),
- mHTTPDataSource(
- HTTPBase::Create(
- (mFlags & kFlagIncognito)
- ? HTTPBase::kFlagIncognito
- : 0)),
+ mHTTPDataSource(new MediaHTTP(mHTTPService->makeHTTPConnection())),
mPrevBandwidthIndex(-1),
mStreamMask(0),
mCheckBandwidthGeneration(0),
@@ -62,10 +61,6 @@ LiveSession::LiveSession(
mRealTimeBaseUs(0ll),
mReconfigurationInProgress(false),
mDisconnectReplyID(0) {
- if (mUIDValid) {
- mHTTPDataSource->setUID(mUID);
- }
-
mPacketSources.add(
STREAMTYPE_AUDIO, new AnotherPacketSource(NULL /* meta */));
diff --git a/media/libstagefright/httplive/LiveSession.h b/media/libstagefright/httplive/LiveSession.h
index 99b480a8..ee10e70 100644
--- a/media/libstagefright/httplive/LiveSession.h
+++ b/media/libstagefright/httplive/LiveSession.h
@@ -28,6 +28,7 @@ struct ABuffer;
struct AnotherPacketSource;
struct DataSource;
struct HTTPBase;
+struct IMediaHTTPService;
struct LiveDataSource;
struct M3UParser;
struct PlaylistFetcher;
@@ -40,7 +41,8 @@ struct LiveSession : public AHandler {
};
LiveSession(
const sp<AMessage> &notify,
- uint32_t flags = 0, bool uidValid = false, uid_t uid = 0);
+ uint32_t flags,
+ const sp<IMediaHTTPService> &httpService);
enum StreamType {
STREAMTYPE_AUDIO = 1,
@@ -107,8 +109,7 @@ private:
sp<AMessage> mNotify;
uint32_t mFlags;
- bool mUIDValid;
- uid_t mUID;
+ sp<IMediaHTTPService> mHTTPService;
bool mInPreparationPhase;
diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp
index 5ef7c0f..39d80fc 100644
--- a/media/libstagefright/httplive/M3UParser.cpp
+++ b/media/libstagefright/httplive/M3UParser.cpp
@@ -125,7 +125,7 @@ void M3UParser::MediaGroup::pickRandomMediaItems() {
mSelectedIndex = strtoul(value, &end, 10);
CHECK(end > value && *end == '\0');
- if (mSelectedIndex >= mMediaItems.size()) {
+ if (mSelectedIndex >= (ssize_t)mMediaItems.size()) {
mSelectedIndex = mMediaItems.size() - 1;
}
} else {
@@ -165,14 +165,14 @@ status_t M3UParser::MediaGroup::selectTrack(size_t index, bool select) {
ALOGE("track %d does not exist", index);
return INVALID_OPERATION;
}
- if (mSelectedIndex == index) {
+ if (mSelectedIndex == (ssize_t)index) {
ALOGE("track %d already selected", index);
return BAD_VALUE;
}
ALOGV("selected track %d", index);
mSelectedIndex = index;
} else {
- if (mSelectedIndex != index) {
+ if (mSelectedIndex != (ssize_t)index) {
ALOGE("track %d is not selected", index);
return BAD_VALUE;
}
diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp
index 973b779..4d29366 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.cpp
+++ b/media/libstagefright/httplive/PlaylistFetcher.cpp
@@ -47,6 +47,7 @@ namespace android {
// static
const int64_t PlaylistFetcher::kMinBufferedDurationUs = 10000000ll;
+const int64_t PlaylistFetcher::kMaxMonitorDelayUs = 3000000ll;
PlaylistFetcher::PlaylistFetcher(
const sp<AMessage> &notify,
@@ -61,6 +62,7 @@ PlaylistFetcher::PlaylistFetcher(
mSeqNumber(-1),
mNumRetries(0),
mStartup(true),
+ mPrepared(false),
mNextPTSTimeUs(-1ll),
mMonitorQueueGeneration(0),
mRefreshState(INITIAL_MINIMUM_RELOAD_DELAY),
@@ -103,10 +105,16 @@ int64_t PlaylistFetcher::getSegmentStartTimeUs(int32_t seqNumber) const {
return segmentStartUs;
}
-bool PlaylistFetcher::timeToRefreshPlaylist(int64_t nowUs) const {
- if (mPlaylist == NULL) {
+int64_t PlaylistFetcher::delayUsToRefreshPlaylist() const {
+ int64_t nowUs = ALooper::GetNowUs();
+
+ if (mPlaylist == NULL || mLastPlaylistFetchTimeUs < 0ll) {
CHECK_EQ((int)mRefreshState, (int)INITIAL_MINIMUM_RELOAD_DELAY);
- return true;
+ return 0ll;
+ }
+
+ if (mPlaylist->isComplete()) {
+ return (~0llu >> 1);
}
int32_t targetDurationSecs;
@@ -157,7 +165,8 @@ bool PlaylistFetcher::timeToRefreshPlaylist(int64_t nowUs) const {
break;
}
- return mLastPlaylistFetchTimeUs + minPlaylistAgeUs <= nowUs;
+ int64_t delayUs = mLastPlaylistFetchTimeUs + minPlaylistAgeUs - nowUs;
+ return delayUs > 0ll ? delayUs : 0ll;
}
status_t PlaylistFetcher::decryptBuffer(
@@ -274,7 +283,15 @@ status_t PlaylistFetcher::decryptBuffer(
return OK;
}
-void PlaylistFetcher::postMonitorQueue(int64_t delayUs) {
+void PlaylistFetcher::postMonitorQueue(int64_t delayUs, int64_t minDelayUs) {
+ int64_t maxDelayUs = delayUsToRefreshPlaylist();
+ if (maxDelayUs < minDelayUs) {
+ maxDelayUs = minDelayUs;
+ }
+ if (delayUs > maxDelayUs) {
+ ALOGV("Need to refresh playlist in %lld", maxDelayUs);
+ delayUs = maxDelayUs;
+ }
sp<AMessage> msg = new AMessage(kWhatMonitorQueue, id());
msg->setInt32("generation", mMonitorQueueGeneration);
msg->post(delayUs);
@@ -415,6 +432,7 @@ status_t PlaylistFetcher::onStart(const sp<AMessage> &msg) {
if (mStartTimeUs >= 0ll) {
mSeqNumber = -1;
mStartup = true;
+ mPrepared = false;
}
postMonitorQueue();
@@ -456,40 +474,62 @@ void PlaylistFetcher::queueDiscontinuity(
void PlaylistFetcher::onMonitorQueue() {
bool downloadMore = false;
+ refreshPlaylist();
+
+ int32_t targetDurationSecs;
+ int64_t targetDurationUs = kMinBufferedDurationUs;
+ if (mPlaylist != NULL) {
+ CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs));
+ targetDurationUs = targetDurationSecs * 1000000ll;
+ }
- status_t finalResult;
+ // buffer at least 3 times the target duration, or up to 10 seconds
+ int64_t durationToBufferUs = targetDurationUs * 3;
+ if (durationToBufferUs > kMinBufferedDurationUs) {
+ durationToBufferUs = kMinBufferedDurationUs;
+ }
+
+ int64_t bufferedDurationUs = 0ll;
+ status_t finalResult = NOT_ENOUGH_DATA;
if (mStreamTypeMask == LiveSession::STREAMTYPE_SUBTITLES) {
sp<AnotherPacketSource> packetSource =
mPacketSources.valueFor(LiveSession::STREAMTYPE_SUBTITLES);
- int64_t bufferedDurationUs =
+ bufferedDurationUs =
packetSource->getBufferedDurationUs(&finalResult);
-
- downloadMore = (bufferedDurationUs < kMinBufferedDurationUs);
finalResult = OK;
} else {
bool first = true;
- int64_t minBufferedDurationUs = 0ll;
for (size_t i = 0; i < mPacketSources.size(); ++i) {
if ((mStreamTypeMask & mPacketSources.keyAt(i)) == 0) {
continue;
}
- int64_t bufferedDurationUs =
+ int64_t bufferedStreamDurationUs =
mPacketSources.valueAt(i)->getBufferedDurationUs(&finalResult);
-
- if (first || bufferedDurationUs < minBufferedDurationUs) {
- minBufferedDurationUs = bufferedDurationUs;
+ if (first || bufferedStreamDurationUs < bufferedDurationUs) {
+ bufferedDurationUs = bufferedStreamDurationUs;
first = false;
}
}
+ }
+ downloadMore = (bufferedDurationUs < durationToBufferUs);
- downloadMore =
- !first && (minBufferedDurationUs < kMinBufferedDurationUs);
+ // signal start if buffered up at least the target size
+ if (!mPrepared && bufferedDurationUs > targetDurationUs && downloadMore) {
+ mPrepared = true;
+
+ ALOGV("prepared, buffered=%lld > %lld",
+ bufferedDurationUs, targetDurationUs);
+ sp<AMessage> msg = mNotify->dup();
+ msg->setInt32("what", kWhatTemporarilyDoneFetching);
+ msg->post();
}
if (finalResult == OK && downloadMore) {
+ ALOGV("monitoring, buffered=%lld < %lld",
+ bufferedDurationUs, durationToBufferUs);
onDownloadNext();
} else {
// Nothing to do yet, try again in a second.
@@ -498,15 +538,17 @@ void PlaylistFetcher::onMonitorQueue() {
msg->setInt32("what", kWhatTemporarilyDoneFetching);
msg->post();
- postMonitorQueue(1000000ll);
+ int64_t delayUs = mPrepared ? kMaxMonitorDelayUs : targetDurationUs / 2;
+ ALOGV("pausing for %lld, buffered=%lld > %lld",
+ delayUs, bufferedDurationUs, durationToBufferUs);
+ // :TRICKY: need to enforce minimum delay because the delay to
+ // refresh the playlist will become 0
+ postMonitorQueue(delayUs, mPrepared ? targetDurationUs * 2 : 0);
}
}
-void PlaylistFetcher::onDownloadNext() {
- int64_t nowUs = ALooper::GetNowUs();
-
- if (mLastPlaylistFetchTimeUs < 0ll
- || (!mPlaylist->isComplete() && timeToRefreshPlaylist(nowUs))) {
+status_t PlaylistFetcher::refreshPlaylist() {
+ if (delayUsToRefreshPlaylist() <= 0) {
bool unchanged;
sp<M3UParser> playlist = mSession->fetchPlaylist(
mURI.c_str(), mPlaylistHash, &unchanged);
@@ -522,7 +564,7 @@ void PlaylistFetcher::onDownloadNext() {
} else {
ALOGE("failed to load playlist at url '%s'", mURI.c_str());
notifyError(ERROR_IO);
- return;
+ return ERROR_IO;
}
} else {
mRefreshState = INITIAL_MINIMUM_RELOAD_DELAY;
@@ -535,6 +577,13 @@ void PlaylistFetcher::onDownloadNext() {
mLastPlaylistFetchTimeUs = ALooper::GetNowUs();
}
+ return OK;
+}
+
+void PlaylistFetcher::onDownloadNext() {
+ if (refreshPlaylist() != OK) {
+ return;
+ }
int32_t firstSeqNumberInPlaylist;
if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32(
@@ -553,12 +602,18 @@ void PlaylistFetcher::onDownloadNext() {
if (mPlaylist->isComplete() || mPlaylist->isEvent()) {
mSeqNumber = getSeqNumberForTime(mStartTimeUs);
+ ALOGV("Initial sequence number for time %lld is %d from (%d .. %d)",
+ mStartTimeUs, mSeqNumber, firstSeqNumberInPlaylist,
+ lastSeqNumberInPlaylist);
} else {
// If this is a live session, start 3 segments from the end.
mSeqNumber = lastSeqNumberInPlaylist - 3;
if (mSeqNumber < firstSeqNumberInPlaylist) {
mSeqNumber = firstSeqNumberInPlaylist;
}
+ ALOGV("Initial sequence number for live event %d from (%d .. %d)",
+ mSeqNumber, firstSeqNumberInPlaylist,
+ lastSeqNumberInPlaylist);
}
mStartTimeUs = -1ll;
@@ -570,16 +625,35 @@ void PlaylistFetcher::onDownloadNext() {
++mNumRetries;
if (mSeqNumber > lastSeqNumberInPlaylist) {
- mLastPlaylistFetchTimeUs = -1;
- postMonitorQueue(3000000ll);
+ // refresh in increasing fraction (1/2, 1/3, ...) of the
+ // playlist's target duration or 3 seconds, whichever is less
+ int32_t targetDurationSecs;
+ CHECK(mPlaylist->meta()->findInt32(
+ "target-duration", &targetDurationSecs));
+ int64_t delayUs = mPlaylist->size() * targetDurationSecs *
+ 1000000ll / (1 + mNumRetries);
+ if (delayUs > kMaxMonitorDelayUs) {
+ delayUs = kMaxMonitorDelayUs;
+ }
+ ALOGV("sequence number high: %d from (%d .. %d), "
+ "monitor in %lld (retry=%d)",
+ mSeqNumber, firstSeqNumberInPlaylist,
+ lastSeqNumberInPlaylist, delayUs, mNumRetries);
+ postMonitorQueue(delayUs);
return;
}
// we've missed the boat, let's start from the lowest sequence
// number available and signal a discontinuity.
- ALOGI("We've missed the boat, restarting playback.");
- mSeqNumber = lastSeqNumberInPlaylist;
+ ALOGI("We've missed the boat, restarting playback."
+ " mStartup=%d, was looking for %d in %d-%d",
+ mStartup, mSeqNumber, firstSeqNumberInPlaylist,
+ lastSeqNumberInPlaylist);
+ mSeqNumber = lastSeqNumberInPlaylist - 3;
+ if (mSeqNumber < firstSeqNumberInPlaylist) {
+ mSeqNumber = firstSeqNumberInPlaylist;
+ }
explicitDiscontinuity = true;
// fall through
@@ -788,12 +862,13 @@ status_t PlaylistFetcher::extractAndQueueAccessUnits(
&& source->dequeueAccessUnit(&accessUnit) == OK) {
// Note that we do NOT dequeue any discontinuities.
+ // for simplicity, store a reference to the format in each unit
+ sp<MetaData> format = source->getFormat();
+ if (format != NULL) {
+ accessUnit->meta()->setObject("format", format);
+ }
packetSource->queueAccessUnit(accessUnit);
}
-
- if (packetSource->getFormat() == NULL) {
- packetSource->setFormat(source->getFormat());
- }
}
return OK;
diff --git a/media/libstagefright/httplive/PlaylistFetcher.h b/media/libstagefright/httplive/PlaylistFetcher.h
index 1648e02..78dea20 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.h
+++ b/media/libstagefright/httplive/PlaylistFetcher.h
@@ -79,6 +79,7 @@ private:
};
static const int64_t kMinBufferedDurationUs;
+ static const int64_t kMaxMonitorDelayUs;
sp<AMessage> mNotify;
sp<LiveSession> mSession;
@@ -97,6 +98,7 @@ private:
int32_t mSeqNumber;
int32_t mNumRetries;
bool mStartup;
+ bool mPrepared;
int64_t mNextPTSTimeUs;
int32_t mMonitorQueueGeneration;
@@ -120,10 +122,11 @@ private:
status_t decryptBuffer(
size_t playlistIndex, const sp<ABuffer> &buffer);
- void postMonitorQueue(int64_t delayUs = 0);
+ void postMonitorQueue(int64_t delayUs = 0, int64_t minDelayUs = 0);
void cancelMonitorQueue();
- bool timeToRefreshPlaylist(int64_t nowUs) const;
+ int64_t delayUsToRefreshPlaylist() const;
+ status_t refreshPlaylist();
// Returns the media time in us of the segment specified by seqNumber.
// This is computed by summing the durations of all segments before it.
diff --git a/media/libstagefright/id3/Android.mk b/media/libstagefright/id3/Android.mk
index bf6f7bb..2194c38 100644
--- a/media/libstagefright/id3/Android.mk
+++ b/media/libstagefright/id3/Android.mk
@@ -4,6 +4,8 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
ID3.cpp
+LOCAL_CFLAGS += -Werror
+
LOCAL_MODULE := libstagefright_id3
include $(BUILD_STATIC_LIBRARY)
@@ -15,6 +17,8 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
testid3.cpp
+LOCAL_CFLAGS += -Werror
+
LOCAL_SHARED_LIBRARIES := \
libstagefright libutils liblog libbinder libstagefright_foundation
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index 1ec4a40..f0f203c 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -468,49 +468,6 @@ void ID3::Iterator::getID(String8 *id) const {
}
}
-static void convertISO8859ToString8(
- const uint8_t *data, size_t size,
- String8 *s) {
- size_t utf8len = 0;
- for (size_t i = 0; i < size; ++i) {
- if (data[i] == '\0') {
- size = i;
- break;
- } else if (data[i] < 0x80) {
- ++utf8len;
- } else {
- utf8len += 2;
- }
- }
-
- if (utf8len == size) {
- // Only ASCII characters present.
-
- s->setTo((const char *)data, size);
- return;
- }
-
- char *tmp = new char[utf8len];
- char *ptr = tmp;
- for (size_t i = 0; i < size; ++i) {
- if (data[i] == '\0') {
- break;
- } else if (data[i] < 0x80) {
- *ptr++ = data[i];
- } else if (data[i] < 0xc0) {
- *ptr++ = 0xc2;
- *ptr++ = data[i];
- } else {
- *ptr++ = 0xc3;
- *ptr++ = data[i] - 64;
- }
- }
-
- s->setTo(tmp, utf8len);
-
- delete[] tmp;
- tmp = NULL;
-}
// 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 {
@@ -543,7 +500,9 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const {
return;
}
- convertISO8859ToString8(frameData, mFrameSize, id);
+ // this is supposed to be ISO-8859-1, but pass it up as-is to the caller, who will figure
+ // out the real encoding
+ id->setTo((const char*)frameData, mFrameSize);
return;
}
@@ -561,13 +520,13 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const {
}
if (encoding == 0x00) {
- // ISO 8859-1
- convertISO8859ToString8(frameData + 1, n, id);
+ // supposedly ISO 8859-1
+ id->setTo((const char*)frameData + 1, n);
} else if (encoding == 0x03) {
- // UTF-8
+ // supposedly UTF-8
id->setTo((const char *)(frameData + 1), n);
} else if (encoding == 0x02) {
- // UTF-16 BE, no byte order mark.
+ // supposedly 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 *) (frameData + 1);
@@ -583,7 +542,7 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const {
if (framedatacopy != NULL) {
delete[] framedatacopy;
}
- } else {
+ } else if (encoding == 0x01) {
// UCS-2
// API wants number of characters, not number of bytes...
int len = n / 2;
@@ -602,7 +561,27 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const {
framedata++;
len--;
}
- id->setTo(framedata, len);
+
+ // check if the resulting data consists entirely of 8-bit values
+ bool eightBit = true;
+ for (int i = 0; i < len; i++) {
+ if (framedata[i] > 0xff) {
+ eightBit = false;
+ break;
+ }
+ }
+ if (eightBit) {
+ // collapse to 8 bit, then let the media scanner client figure out the real encoding
+ char *frame8 = new char[len];
+ for (int i = 0; i < len; i++) {
+ frame8[i] = framedata[i];
+ }
+ id->setTo(frame8, len);
+ delete [] frame8;
+ } else {
+ id->setTo(framedata, len);
+ }
+
if (framedatacopy != NULL) {
delete[] framedatacopy;
}
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 271df8e..a81bbba 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -63,6 +63,7 @@ struct AwesomePlayer {
void setUID(uid_t uid);
status_t setDataSource(
+ const sp<IMediaHTTPService> &httpService,
const char *uri,
const KeyedVector<String8, String8> *headers = NULL);
@@ -159,6 +160,7 @@ private:
SystemTimeSource mSystemTimeSource;
TimeSource *mTimeSource;
+ sp<IMediaHTTPService> mHTTPService;
String8 mUri;
KeyedVector<String8, String8> mUriHeaders;
@@ -247,6 +249,7 @@ private:
sp<MediaExtractor> mExtractor;
status_t setDataSource_l(
+ const sp<IMediaHTTPService> &httpService,
const char *uri,
const KeyedVector<String8, String8> *headers = NULL);
diff --git a/media/libstagefright/include/ChromiumHTTPDataSource.h b/media/libstagefright/include/ChromiumHTTPDataSource.h
deleted file mode 100644
index da188dd..0000000
--- a/media/libstagefright/include/ChromiumHTTPDataSource.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef CHROME_HTTP_DATA_SOURCE_H_
-
-#define CHROME_HTTP_DATA_SOURCE_H_
-
-#include <media/stagefright/foundation/AString.h>
-#include <utils/threads.h>
-
-#include "HTTPBase.h"
-
-namespace android {
-
-struct SfDelegate;
-
-struct ChromiumHTTPDataSource : public HTTPBase {
- ChromiumHTTPDataSource(uint32_t flags = 0);
-
- virtual status_t connect(
- const char *uri,
- const KeyedVector<String8, String8> *headers = NULL,
- off64_t offset = 0);
-
- virtual void disconnect();
-
- virtual status_t initCheck() const;
-
- virtual ssize_t readAt(off64_t offset, void *data, size_t size);
- virtual status_t getSize(off64_t *size);
- virtual uint32_t flags();
-
- virtual sp<DecryptHandle> DrmInitialization(const char *mime);
-
- virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client);
-
- virtual String8 getUri();
-
- virtual String8 getMIMEType() const;
-
- virtual status_t reconnectAtOffset(off64_t offset);
-
- static status_t UpdateProxyConfig(
- const char *host, int32_t port, const char *exclusionList);
-
-protected:
- virtual ~ChromiumHTTPDataSource();
-
-private:
- friend struct SfDelegate;
-
- enum State {
- DISCONNECTED,
- CONNECTING,
- CONNECTED,
- READING,
- DISCONNECTING
- };
-
- const uint32_t mFlags;
-
- mutable Mutex mLock;
- Condition mCondition;
-
- State mState;
-
- SfDelegate *mDelegate;
-
- AString mURI;
- KeyedVector<String8, String8> mHeaders;
-
- off64_t mCurrentOffset;
-
- // Any connection error or the result of a read operation
- // (for the lattter this is the number of bytes read, if successful).
- ssize_t mIOResult;
-
- int64_t mContentSize;
-
- String8 mContentType;
-
- sp<DecryptHandle> mDecryptHandle;
- DrmManagerClient *mDrmManagerClient;
-
- void disconnect_l();
-
- status_t connect_l(
- const char *uri,
- const KeyedVector<String8, String8> *headers,
- off64_t offset);
-
- static void InitiateRead(
- ChromiumHTTPDataSource *me, void *data, size_t size);
-
- void initiateRead(void *data, size_t size);
-
- void onConnectionEstablished(
- int64_t contentSize, const char *contentType);
-
- void onConnectionFailed(status_t err);
- void onReadCompleted(ssize_t size);
- void onDisconnectComplete();
- void onRedirect(const char *url);
-
- void clearDRMState_l();
-
- DISALLOW_EVIL_CONSTRUCTORS(ChromiumHTTPDataSource);
-};
-
-} // namespace android
-
-#endif // CHROME_HTTP_DATA_SOURCE_H_
diff --git a/media/libstagefright/include/FragmentedMP4Parser.h b/media/libstagefright/include/FragmentedMP4Parser.h
deleted file mode 100644
index dbe02b8..0000000
--- a/media/libstagefright/include/FragmentedMP4Parser.h
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef PARSER_H_
-
-#define PARSER_H_
-
-#include <media/stagefright/foundation/AHandler.h>
-#include <media/stagefright/DataSource.h>
-#include <utils/Vector.h>
-
-namespace android {
-
-struct ABuffer;
-
-struct FragmentedMP4Parser : public AHandler {
- struct Source : public RefBase {
- Source() {}
-
- virtual ssize_t readAt(off64_t offset, void *data, size_t size) = 0;
- virtual bool isSeekable() = 0;
-
- protected:
- virtual ~Source() {}
-
- private:
- DISALLOW_EVIL_CONSTRUCTORS(Source);
- };
-
- FragmentedMP4Parser();
-
- void start(const char *filename);
- void start(const sp<Source> &source);
- void start(sp<DataSource> &source);
-
- sp<AMessage> getFormat(bool audio, bool synchronous = false);
- status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit, bool synchronous = false);
- status_t seekTo(bool audio, int64_t timeUs);
- bool isSeekable() const;
-
- virtual void onMessageReceived(const sp<AMessage> &msg);
-
-protected:
- virtual ~FragmentedMP4Parser();
-
-private:
- enum {
- kWhatStart,
- kWhatProceed,
- kWhatReadMore,
- kWhatGetFormat,
- kWhatDequeueAccessUnit,
- kWhatSeekTo,
- };
-
- struct TrackFragment;
- struct DynamicTrackFragment;
- struct StaticTrackFragment;
-
- struct DispatchEntry {
- uint32_t mType;
- uint32_t mParentType;
- status_t (FragmentedMP4Parser::*mHandler)(uint32_t, size_t, uint64_t);
- };
-
- struct Container {
- uint64_t mOffset;
- uint64_t mBytesRemaining;
- uint32_t mType;
- bool mExtendsToEOF;
- };
-
- struct SampleDescription {
- uint32_t mType;
- uint16_t mDataRefIndex;
-
- sp<AMessage> mFormat;
- };
-
- struct SampleInfo {
- off64_t mOffset;
- size_t mSize;
- uint32_t mPresentationTime;
- size_t mSampleDescIndex;
- uint32_t mFlags;
- };
-
- struct MediaDataInfo {
- sp<ABuffer> mBuffer;
- off64_t mOffset;
- };
-
- struct SidxEntry {
- size_t mSize;
- uint32_t mDurationUs;
- };
-
- struct TrackInfo {
- enum Flags {
- kTrackEnabled = 0x01,
- kTrackInMovie = 0x02,
- kTrackInPreview = 0x04,
- };
-
- uint32_t mTrackID;
- uint32_t mFlags;
- uint32_t mDuration; // This is the duration in terms of movie timescale!
- uint64_t mSidxDuration; // usec, from sidx box, which can use a different timescale
-
- uint32_t mMediaTimeScale;
-
- uint32_t mMediaHandlerType;
- Vector<SampleDescription> mSampleDescs;
-
- // from track extends:
- uint32_t mDefaultSampleDescriptionIndex;
- uint32_t mDefaultSampleDuration;
- uint32_t mDefaultSampleSize;
- uint32_t mDefaultSampleFlags;
-
- uint32_t mDecodingTime;
-
- Vector<SidxEntry> mSidx;
- sp<StaticTrackFragment> mStaticFragment;
- List<sp<TrackFragment> > mFragments;
- };
-
- struct TrackFragmentHeaderInfo {
- enum Flags {
- kBaseDataOffsetPresent = 0x01,
- kSampleDescriptionIndexPresent = 0x02,
- kDefaultSampleDurationPresent = 0x08,
- kDefaultSampleSizePresent = 0x10,
- kDefaultSampleFlagsPresent = 0x20,
- kDurationIsEmpty = 0x10000,
- };
-
- uint32_t mTrackID;
- uint32_t mFlags;
- uint64_t mBaseDataOffset;
- uint32_t mSampleDescriptionIndex;
- uint32_t mDefaultSampleDuration;
- uint32_t mDefaultSampleSize;
- uint32_t mDefaultSampleFlags;
-
- uint64_t mDataOffset;
- };
-
- static const DispatchEntry kDispatchTable[];
-
- sp<Source> mSource;
- off_t mBufferPos;
- bool mSuspended;
- bool mDoneWithMoov;
- off_t mFirstMoofOffset; // used as the starting point for offsets calculated from the sidx box
- sp<ABuffer> mBuffer;
- Vector<Container> mStack;
- KeyedVector<uint32_t, TrackInfo> mTracks; // TrackInfo by trackID
- Vector<MediaDataInfo> mMediaData;
-
- uint32_t mCurrentTrackID;
-
- status_t mFinalResult;
-
- TrackFragmentHeaderInfo mTrackFragmentHeaderInfo;
-
- status_t onProceed();
- status_t onDequeueAccessUnit(size_t trackIndex, sp<ABuffer> *accessUnit);
- status_t onSeekTo(bool wantAudio, int64_t position);
-
- void enter(off64_t offset, uint32_t type, uint64_t size);
-
- uint16_t readU16(size_t offset);
- uint32_t readU32(size_t offset);
- uint64_t readU64(size_t offset);
- void skip(off_t distance);
- status_t need(size_t size);
- bool fitsContainer(uint64_t size) const;
-
- status_t parseTrackHeader(
- uint32_t type, size_t offset, uint64_t size);
-
- status_t parseMediaHeader(
- uint32_t type, size_t offset, uint64_t size);
-
- status_t parseMediaHandler(
- uint32_t type, size_t offset, uint64_t size);
-
- status_t parseTrackExtends(
- uint32_t type, size_t offset, uint64_t size);
-
- status_t parseTrackFragmentHeader(
- uint32_t type, size_t offset, uint64_t size);
-
- status_t parseTrackFragmentRun(
- uint32_t type, size_t offset, uint64_t size);
-
- status_t parseVisualSampleEntry(
- uint32_t type, size_t offset, uint64_t size);
-
- status_t parseAudioSampleEntry(
- uint32_t type, size_t offset, uint64_t size);
-
- status_t parseSampleSizes(
- uint32_t type, size_t offset, uint64_t size);
-
- status_t parseCompactSampleSizes(
- uint32_t type, size_t offset, uint64_t size);
-
- status_t parseSampleToChunk(
- uint32_t type, size_t offset, uint64_t size);
-
- status_t parseChunkOffsets(
- uint32_t type, size_t offset, uint64_t size);
-
- status_t parseChunkOffsets64(
- uint32_t type, size_t offset, uint64_t size);
-
- status_t parseAVCCodecSpecificData(
- uint32_t type, size_t offset, uint64_t size);
-
- status_t parseESDSCodecSpecificData(
- uint32_t type, size_t offset, uint64_t size);
-
- status_t parseMediaData(
- uint32_t type, size_t offset, uint64_t size);
-
- status_t parseSegmentIndex(
- uint32_t type, size_t offset, uint64_t size);
-
- TrackInfo *editTrack(uint32_t trackID, bool createIfNecessary = false);
-
- ssize_t findTrack(bool wantAudio) const;
-
- status_t makeAccessUnit(
- TrackInfo *info,
- const SampleInfo &sample,
- const MediaDataInfo &mdatInfo,
- sp<ABuffer> *accessUnit);
-
- status_t getSample(
- TrackInfo *info,
- sp<TrackFragment> *fragment,
- SampleInfo *sampleInfo);
-
- static int CompareSampleLocation(
- const SampleInfo &sample, const MediaDataInfo &mdatInfo);
-
- void resumeIfNecessary();
-
- void copyBuffer(
- sp<ABuffer> *dst,
- size_t offset, uint64_t size) const;
-
- DISALLOW_EVIL_CONSTRUCTORS(FragmentedMP4Parser);
-};
-
-} // namespace android
-
-#endif // PARSER_H_
-
diff --git a/media/libstagefright/include/HTTPBase.h b/media/libstagefright/include/HTTPBase.h
index d4b7f9f..1c3cd5e 100644
--- a/media/libstagefright/include/HTTPBase.h
+++ b/media/libstagefright/include/HTTPBase.h
@@ -48,14 +48,6 @@ struct HTTPBase : public DataSource {
virtual status_t setBandwidthStatCollectFreq(int32_t freqMs);
- static status_t UpdateProxyConfig(
- const char *host, int32_t port, const char *exclusionList);
-
- void setUID(uid_t uid);
- bool getUID(uid_t *uid) const;
-
- static sp<HTTPBase> Create(uint32_t flags = 0);
-
static void RegisterSocketUserTag(int sockfd, uid_t uid, uint32_t kTag);
static void UnRegisterSocketUserTag(int sockfd);
@@ -87,9 +79,6 @@ private:
int32_t mPrevEstimatedBandWidthKbps;
int32_t mBandWidthCollectFreqMs;
- bool mUIDValid;
- uid_t mUID;
-
DISALLOW_EVIL_CONSTRUCTORS(HTTPBase);
};
diff --git a/media/libstagefright/include/SDPLoader.h b/media/libstagefright/include/SDPLoader.h
index ca59dc0..2c4f543 100644
--- a/media/libstagefright/include/SDPLoader.h
+++ b/media/libstagefright/include/SDPLoader.h
@@ -25,6 +25,7 @@
namespace android {
struct HTTPBase;
+struct IMediaHTTPService;
struct SDPLoader : public AHandler {
enum Flags {
@@ -34,7 +35,10 @@ struct SDPLoader : public AHandler {
enum {
kWhatSDPLoaded = 'sdpl'
};
- SDPLoader(const sp<AMessage> &notify, uint32_t flags = 0, bool uidValid = false, uid_t uid = 0);
+ SDPLoader(
+ const sp<AMessage> &notify,
+ uint32_t flags,
+ const sp<IMediaHTTPService> &httpService);
void load(const char* url, const KeyedVector<String8, String8> *headers);
@@ -55,8 +59,6 @@ private:
sp<AMessage> mNotify;
const char* mUrl;
uint32_t mFlags;
- bool mUIDValid;
- uid_t mUID;
sp<ALooper> mNetLooper;
bool mCancelled;
diff --git a/media/libstagefright/include/StagefrightMetadataRetriever.h b/media/libstagefright/include/StagefrightMetadataRetriever.h
index b02ed0e..6632c27 100644
--- a/media/libstagefright/include/StagefrightMetadataRetriever.h
+++ b/media/libstagefright/include/StagefrightMetadataRetriever.h
@@ -33,6 +33,7 @@ struct StagefrightMetadataRetriever : public MediaMetadataRetrieverInterface {
virtual ~StagefrightMetadataRetriever();
virtual status_t setDataSource(
+ const sp<IMediaHTTPService> &httpService,
const char *url,
const KeyedVector<String8, String8> *headers);
diff --git a/media/libstagefright/include/TimedEventQueue.h b/media/libstagefright/include/TimedEventQueue.h
index 3e84256..2963150 100644
--- a/media/libstagefright/include/TimedEventQueue.h
+++ b/media/libstagefright/include/TimedEventQueue.h
@@ -122,7 +122,7 @@ private:
};
struct StopEvent : public TimedEventQueue::Event {
- virtual void fire(TimedEventQueue *queue, int64_t now_us) {
+ virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
queue->mStopped = true;
}
};
diff --git a/media/libstagefright/matroska/Android.mk b/media/libstagefright/matroska/Android.mk
index 2d8c1e1..446ff8c 100644
--- a/media/libstagefright/matroska/Android.mk
+++ b/media/libstagefright/matroska/Android.mk
@@ -8,7 +8,7 @@ LOCAL_C_INCLUDES:= \
$(TOP)/external/libvpx/libwebm \
$(TOP)/frameworks/native/include/media/openmax \
-LOCAL_CFLAGS += -Wno-multichar
+LOCAL_CFLAGS += -Wno-multichar -Werror
LOCAL_MODULE:= libstagefright_matroska
diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp
index d260d0f..6f69d0b 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.cpp
+++ b/media/libstagefright/matroska/MatroskaExtractor.cpp
@@ -193,7 +193,7 @@ MatroskaSource::~MatroskaSource() {
clearPendingFrames();
}
-status_t MatroskaSource::start(MetaData *params) {
+status_t MatroskaSource::start(MetaData * /* params */) {
mBlockIter.reset();
return OK;
@@ -410,7 +410,7 @@ void BlockIterator::seek(
// Accept the first key frame
*actualFrameTimeUs = (block()->GetTime(mCluster) + 500LL) / 1000LL;
ALOGV("Requested seek point: %lld actual: %lld",
- seekTimeUs, actualFrameTimeUs);
+ seekTimeUs, *actualFrameTimeUs);
break;
}
}
@@ -716,41 +716,61 @@ bool MatroskaExtractor::isLiveStreaming() const {
return mIsLiveStreaming;
}
+static int bytesForSize(size_t size) {
+ // use at most 28 bits (4 times 7)
+ CHECK(size <= 0xfffffff);
+
+ if (size > 0x1fffff) {
+ return 4;
+ } else if (size > 0x3fff) {
+ return 3;
+ } else if (size > 0x7f) {
+ return 2;
+ }
+ return 1;
+}
+
+static void storeSize(uint8_t *data, size_t &idx, size_t size) {
+ int numBytes = bytesForSize(size);
+ idx += numBytes;
+
+ data += idx;
+ size_t next = 0;
+ while (numBytes--) {
+ *--data = (size & 0x7f) | next;
+ size >>= 7;
+ next = 0x80;
+ }
+}
+
static void addESDSFromCodecPrivate(
const sp<MetaData> &meta,
bool isAudio, const void *priv, size_t privSize) {
- static const uint8_t kStaticESDS[] = {
- 0x03, 22,
- 0x00, 0x00, // ES_ID
- 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag
-
- 0x04, 17,
- 0x40, // ObjectTypeIndication
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
-
- 0x05,
- // CodecSpecificInfo (with size prefix) follows
- };
- // Make sure all sizes can be coded in a single byte.
- CHECK(privSize + 22 - 2 < 128);
- size_t esdsSize = sizeof(kStaticESDS) + privSize + 1;
+ int privSizeBytesRequired = bytesForSize(privSize);
+ int esdsSize2 = 14 + privSizeBytesRequired + privSize;
+ int esdsSize2BytesRequired = bytesForSize(esdsSize2);
+ int esdsSize1 = 4 + esdsSize2BytesRequired + esdsSize2;
+ int esdsSize1BytesRequired = bytesForSize(esdsSize1);
+ size_t esdsSize = 1 + esdsSize1BytesRequired + esdsSize1;
uint8_t *esds = new uint8_t[esdsSize];
- memcpy(esds, kStaticESDS, sizeof(kStaticESDS));
- uint8_t *ptr = esds + sizeof(kStaticESDS);
- *ptr++ = privSize;
- memcpy(ptr, priv, privSize);
-
- // Increment by codecPrivateSize less 2 bytes that are accounted for
- // already in lengths of 22/17
- esds[1] += privSize - 2;
- esds[6] += privSize - 2;
-
- // Set ObjectTypeIndication.
- esds[7] = isAudio ? 0x40 // Audio ISO/IEC 14496-3
- : 0x20; // Visual ISO/IEC 14496-2
+
+ size_t idx = 0;
+ esds[idx++] = 0x03;
+ storeSize(esds, idx, esdsSize1);
+ esds[idx++] = 0x00; // ES_ID
+ esds[idx++] = 0x00; // ES_ID
+ esds[idx++] = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag
+ esds[idx++] = 0x04;
+ storeSize(esds, idx, esdsSize2);
+ esds[idx++] = isAudio ? 0x40 // Audio ISO/IEC 14496-3
+ : 0x20; // Visual ISO/IEC 14496-2
+ for (int i = 0; i < 12; i++) {
+ esds[idx++] = 0x00;
+ }
+ esds[idx++] = 0x05;
+ storeSize(esds, idx, privSize);
+ memcpy(esds + idx, priv, privSize);
meta->setData(kKeyESDS, 0, esds, esdsSize);
diff --git a/media/libstagefright/mp4/FragmentedMP4Parser.cpp b/media/libstagefright/mp4/FragmentedMP4Parser.cpp
deleted file mode 100644
index 0102656..0000000
--- a/media/libstagefright/mp4/FragmentedMP4Parser.cpp
+++ /dev/null
@@ -1,1993 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "FragmentedMP4Parser"
-#include <utils/Log.h>
-
-#include "include/avc_utils.h"
-#include "include/ESDS.h"
-#include "include/FragmentedMP4Parser.h"
-#include "TrackFragment.h"
-
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/Utils.h>
-
-
-namespace android {
-
-static const char *Fourcc2String(uint32_t fourcc) {
- static char buffer[5];
- buffer[4] = '\0';
- buffer[0] = fourcc >> 24;
- buffer[1] = (fourcc >> 16) & 0xff;
- buffer[2] = (fourcc >> 8) & 0xff;
- buffer[3] = fourcc & 0xff;
-
- return buffer;
-}
-
-static const char *IndentString(size_t n) {
- static const char kSpace[] = " ";
- return kSpace + sizeof(kSpace) - 2 * n - 1;
-}
-
-// static
-const FragmentedMP4Parser::DispatchEntry FragmentedMP4Parser::kDispatchTable[] = {
- { FOURCC('m', 'o', 'o', 'v'), 0, NULL },
- { FOURCC('t', 'r', 'a', 'k'), FOURCC('m', 'o', 'o', 'v'), NULL },
- { FOURCC('u', 'd', 't', 'a'), FOURCC('t', 'r', 'a', 'k'), NULL },
- { FOURCC('u', 'd', 't', 'a'), FOURCC('m', 'o', 'o', 'v'), NULL },
- { FOURCC('m', 'e', 't', 'a'), FOURCC('u', 'd', 't', 'a'), NULL },
- { FOURCC('i', 'l', 's', 't'), FOURCC('m', 'e', 't', 'a'), NULL },
-
- { FOURCC('t', 'k', 'h', 'd'), FOURCC('t', 'r', 'a', 'k'),
- &FragmentedMP4Parser::parseTrackHeader
- },
-
- { FOURCC('m', 'v', 'e', 'x'), FOURCC('m', 'o', 'o', 'v'), NULL },
-
- { FOURCC('t', 'r', 'e', 'x'), FOURCC('m', 'v', 'e', 'x'),
- &FragmentedMP4Parser::parseTrackExtends
- },
-
- { FOURCC('e', 'd', 't', 's'), FOURCC('t', 'r', 'a', 'k'), NULL },
- { FOURCC('m', 'd', 'i', 'a'), FOURCC('t', 'r', 'a', 'k'), NULL },
-
- { FOURCC('m', 'd', 'h', 'd'), FOURCC('m', 'd', 'i', 'a'),
- &FragmentedMP4Parser::parseMediaHeader
- },
-
- { FOURCC('h', 'd', 'l', 'r'), FOURCC('m', 'd', 'i', 'a'),
- &FragmentedMP4Parser::parseMediaHandler
- },
-
- { FOURCC('m', 'i', 'n', 'f'), FOURCC('m', 'd', 'i', 'a'), NULL },
- { FOURCC('d', 'i', 'n', 'f'), FOURCC('m', 'i', 'n', 'f'), NULL },
- { FOURCC('s', 't', 'b', 'l'), FOURCC('m', 'i', 'n', 'f'), NULL },
- { FOURCC('s', 't', 's', 'd'), FOURCC('s', 't', 'b', 'l'), NULL },
-
- { FOURCC('s', 't', 's', 'z'), FOURCC('s', 't', 'b', 'l'),
- &FragmentedMP4Parser::parseSampleSizes },
-
- { FOURCC('s', 't', 'z', '2'), FOURCC('s', 't', 'b', 'l'),
- &FragmentedMP4Parser::parseCompactSampleSizes },
-
- { FOURCC('s', 't', 's', 'c'), FOURCC('s', 't', 'b', 'l'),
- &FragmentedMP4Parser::parseSampleToChunk },
-
- { FOURCC('s', 't', 'c', 'o'), FOURCC('s', 't', 'b', 'l'),
- &FragmentedMP4Parser::parseChunkOffsets },
-
- { FOURCC('c', 'o', '6', '4'), FOURCC('s', 't', 'b', 'l'),
- &FragmentedMP4Parser::parseChunkOffsets64 },
-
- { FOURCC('a', 'v', 'c', 'C'), FOURCC('a', 'v', 'c', '1'),
- &FragmentedMP4Parser::parseAVCCodecSpecificData },
-
- { FOURCC('e', 's', 'd', 's'), FOURCC('m', 'p', '4', 'a'),
- &FragmentedMP4Parser::parseESDSCodecSpecificData },
-
- { FOURCC('e', 's', 'd', 's'), FOURCC('m', 'p', '4', 'v'),
- &FragmentedMP4Parser::parseESDSCodecSpecificData },
-
- { FOURCC('m', 'd', 'a', 't'), 0, &FragmentedMP4Parser::parseMediaData },
-
- { FOURCC('m', 'o', 'o', 'f'), 0, NULL },
- { FOURCC('t', 'r', 'a', 'f'), FOURCC('m', 'o', 'o', 'f'), NULL },
-
- { FOURCC('t', 'f', 'h', 'd'), FOURCC('t', 'r', 'a', 'f'),
- &FragmentedMP4Parser::parseTrackFragmentHeader
- },
- { FOURCC('t', 'r', 'u', 'n'), FOURCC('t', 'r', 'a', 'f'),
- &FragmentedMP4Parser::parseTrackFragmentRun
- },
-
- { FOURCC('m', 'f', 'r', 'a'), 0, NULL },
-
- { FOURCC('s', 'i', 'd', 'x'), 0, &FragmentedMP4Parser::parseSegmentIndex },
-};
-
-struct FileSource : public FragmentedMP4Parser::Source {
- FileSource(const char *filename)
- : mFile(fopen(filename, "rb")) {
- CHECK(mFile != NULL);
- }
-
- virtual ~FileSource() {
- fclose(mFile);
- }
-
- virtual ssize_t readAt(off64_t offset, void *data, size_t size) {
- fseek(mFile, offset, SEEK_SET);
- return fread(data, 1, size, mFile);
- }
-
- virtual bool isSeekable() {
- return true;
- }
-
- private:
- FILE *mFile;
-
- DISALLOW_EVIL_CONSTRUCTORS(FileSource);
-};
-
-struct ReadTracker : public RefBase {
- ReadTracker(off64_t size) {
- allocSize = 1 + size / 8192; // 1 bit per kilobyte
- bitmap = (char*) calloc(1, allocSize);
- }
- virtual ~ReadTracker() {
- dumpToLog();
- free(bitmap);
- }
- void mark(off64_t offset, size_t size) {
- int firstbit = offset / 1024;
- int lastbit = (offset + size - 1) / 1024;
- for (int i = firstbit; i <= lastbit; i++) {
- bitmap[i/8] |= (0x80 >> (i & 7));
- }
- }
-
- private:
- void dumpToLog() {
- // 96 chars per line, each char represents one kilobyte, 1 kb per bit
- int numlines = allocSize / 12;
- char buf[97];
- char *cur = bitmap;
- for (int i = 0; i < numlines; i++ && cur) {
- for (int j = 0; j < 12; j++) {
- for (int k = 0; k < 8; k++) {
- buf[(j * 8) + k] = (*cur & (0x80 >> k)) ? 'X' : '.';
- }
- cur++;
- }
- buf[96] = '\0';
- ALOGI("%5dk: %s", i * 96, buf);
- }
- }
-
- size_t allocSize;
- char *bitmap;
-};
-
-struct DataSourceSource : public FragmentedMP4Parser::Source {
- DataSourceSource(sp<DataSource> &source)
- : mDataSource(source) {
- CHECK(mDataSource != NULL);
-#if 0
- off64_t size;
- if (source->getSize(&size) == OK) {
- mReadTracker = new ReadTracker(size);
- } else {
- ALOGE("couldn't get data source size");
- }
-#endif
- }
-
- virtual ssize_t readAt(off64_t offset, void *data, size_t size) {
- if (mReadTracker != NULL) {
- mReadTracker->mark(offset, size);
- }
- return mDataSource->readAt(offset, data, size);
- }
-
- virtual bool isSeekable() {
- return true;
- }
-
- private:
- sp<DataSource> mDataSource;
- sp<ReadTracker> mReadTracker;
-
- DISALLOW_EVIL_CONSTRUCTORS(DataSourceSource);
-};
-
-FragmentedMP4Parser::FragmentedMP4Parser()
- : mBufferPos(0),
- mSuspended(false),
- mDoneWithMoov(false),
- mFirstMoofOffset(0),
- mFinalResult(OK) {
-}
-
-FragmentedMP4Parser::~FragmentedMP4Parser() {
-}
-
-void FragmentedMP4Parser::start(const char *filename) {
- sp<AMessage> msg = new AMessage(kWhatStart, id());
- msg->setObject("source", new FileSource(filename));
- msg->post();
- ALOGV("Parser::start(%s)", filename);
-}
-
-void FragmentedMP4Parser::start(const sp<Source> &source) {
- sp<AMessage> msg = new AMessage(kWhatStart, id());
- msg->setObject("source", source);
- msg->post();
- ALOGV("Parser::start(Source)");
-}
-
-void FragmentedMP4Parser::start(sp<DataSource> &source) {
- sp<AMessage> msg = new AMessage(kWhatStart, id());
- msg->setObject("source", new DataSourceSource(source));
- msg->post();
- ALOGV("Parser::start(DataSource)");
-}
-
-sp<AMessage> FragmentedMP4Parser::getFormat(bool audio, bool synchronous) {
-
- while (true) {
- bool moovDone = mDoneWithMoov;
- sp<AMessage> msg = new AMessage(kWhatGetFormat, id());
- msg->setInt32("audio", audio);
-
- sp<AMessage> response;
- status_t err = msg->postAndAwaitResponse(&response);
-
- if (err != OK) {
- ALOGV("getFormat post failed: %d", err);
- return NULL;
- }
-
- if (response->findInt32("err", &err) && err != OK) {
- if (synchronous && err == -EWOULDBLOCK && !moovDone) {
- resumeIfNecessary();
- ALOGV("@getFormat parser not ready yet, retrying");
- usleep(10000);
- continue;
- }
- ALOGV("getFormat failed: %d", err);
- return NULL;
- }
-
- sp<AMessage> format;
- CHECK(response->findMessage("format", &format));
-
- ALOGV("returning format %s", format->debugString().c_str());
- return format;
- }
-}
-
-status_t FragmentedMP4Parser::seekTo(bool wantAudio, int64_t timeUs) {
- sp<AMessage> msg = new AMessage(kWhatSeekTo, id());
- msg->setInt32("audio", wantAudio);
- msg->setInt64("position", timeUs);
-
- sp<AMessage> response;
- status_t err = msg->postAndAwaitResponse(&response);
- return err;
-}
-
-bool FragmentedMP4Parser::isSeekable() const {
- while (mFirstMoofOffset == 0 && mFinalResult == OK) {
- usleep(10000);
- }
- bool seekable = mSource->isSeekable();
- for (size_t i = 0; seekable && i < mTracks.size(); i++) {
- const TrackInfo *info = &mTracks.valueAt(i);
- seekable &= !info->mSidx.empty();
- }
- return seekable;
-}
-
-status_t FragmentedMP4Parser::onSeekTo(bool wantAudio, int64_t position) {
- status_t err = -EINVAL;
- ssize_t trackIndex = findTrack(wantAudio);
- if (trackIndex < 0) {
- err = trackIndex;
- } else {
- TrackInfo *info = &mTracks.editValueAt(trackIndex);
-
- int numSidxEntries = info->mSidx.size();
- int64_t totalTime = 0;
- off_t totalOffset = mFirstMoofOffset;
- for (int i = 0; i < numSidxEntries; i++) {
- const SidxEntry *se = &info->mSidx[i];
- if (totalTime + se->mDurationUs > position) {
- mBuffer->setRange(0,0);
- mBufferPos = totalOffset;
- if (mFinalResult == ERROR_END_OF_STREAM) {
- mFinalResult = OK;
- mSuspended = true; // force resume
- resumeIfNecessary();
- }
- info->mFragments.clear();
- info->mDecodingTime = totalTime * info->mMediaTimeScale / 1000000ll;
- return OK;
- }
- totalTime += se->mDurationUs;
- totalOffset += se->mSize;
- }
- }
- ALOGV("seekTo out of range");
- return err;
-}
-
-status_t FragmentedMP4Parser::dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit,
- bool synchronous) {
-
- while (true) {
- sp<AMessage> msg = new AMessage(kWhatDequeueAccessUnit, id());
- msg->setInt32("audio", audio);
-
- sp<AMessage> response;
- status_t err = msg->postAndAwaitResponse(&response);
-
- if (err != OK) {
- ALOGV("dequeue fail 1: %d", err);
- return err;
- }
-
- if (response->findInt32("err", &err) && err != OK) {
- if (synchronous && err == -EWOULDBLOCK) {
- resumeIfNecessary();
- ALOGV("Parser not ready yet, retrying");
- usleep(10000);
- continue;
- }
- ALOGV("dequeue fail 2: %d, %d", err, synchronous);
- return err;
- }
-
- CHECK(response->findBuffer("accessUnit", accessUnit));
-
- return OK;
- }
-}
-
-ssize_t FragmentedMP4Parser::findTrack(bool wantAudio) const {
- for (size_t i = 0; i < mTracks.size(); ++i) {
- const TrackInfo *info = &mTracks.valueAt(i);
-
- bool isAudio =
- info->mMediaHandlerType == FOURCC('s', 'o', 'u', 'n');
-
- bool isVideo =
- info->mMediaHandlerType == FOURCC('v', 'i', 'd', 'e');
-
- if ((wantAudio && isAudio) || (!wantAudio && !isAudio)) {
- if (info->mSampleDescs.empty()) {
- break;
- }
-
- return i;
- }
- }
-
- return -EWOULDBLOCK;
-}
-
-void FragmentedMP4Parser::onMessageReceived(const sp<AMessage> &msg) {
- switch (msg->what()) {
- case kWhatStart:
- {
- sp<RefBase> obj;
- CHECK(msg->findObject("source", &obj));
-
- mSource = static_cast<Source *>(obj.get());
-
- mBuffer = new ABuffer(512 * 1024);
- mBuffer->setRange(0, 0);
-
- enter(0ll, 0, 0);
-
- (new AMessage(kWhatProceed, id()))->post();
- break;
- }
-
- case kWhatProceed:
- {
- CHECK(!mSuspended);
-
- status_t err = onProceed();
-
- if (err == OK) {
- if (!mSuspended) {
- msg->post();
- }
- } else if (err != -EAGAIN) {
- ALOGE("onProceed returned error %d", err);
- }
-
- break;
- }
-
- case kWhatReadMore:
- {
- size_t needed;
- CHECK(msg->findSize("needed", &needed));
-
- memmove(mBuffer->base(), mBuffer->data(), mBuffer->size());
- mBufferPos += mBuffer->offset();
- mBuffer->setRange(0, mBuffer->size());
-
- size_t maxBytesToRead = mBuffer->capacity() - mBuffer->size();
-
- if (maxBytesToRead < needed) {
- ALOGV("resizing buffer.");
-
- sp<ABuffer> newBuffer =
- new ABuffer((mBuffer->size() + needed + 1023) & ~1023);
- memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
- newBuffer->setRange(0, mBuffer->size());
-
- mBuffer = newBuffer;
- maxBytesToRead = mBuffer->capacity() - mBuffer->size();
- }
-
- CHECK_GE(maxBytesToRead, needed);
-
- ssize_t n = mSource->readAt(
- mBufferPos + mBuffer->size(),
- mBuffer->data() + mBuffer->size(), needed);
-
- if (n < (ssize_t)needed) {
- ALOGV("Reached EOF when reading %d @ %d + %d", needed, mBufferPos, mBuffer->size());
- if (n < 0) {
- mFinalResult = n;
- } else if (n == 0) {
- mFinalResult = ERROR_END_OF_STREAM;
- } else {
- mFinalResult = ERROR_IO;
- }
- } else {
- mBuffer->setRange(0, mBuffer->size() + n);
- (new AMessage(kWhatProceed, id()))->post();
- }
-
- break;
- }
-
- case kWhatGetFormat:
- {
- int32_t wantAudio;
- CHECK(msg->findInt32("audio", &wantAudio));
-
- status_t err = -EWOULDBLOCK;
- sp<AMessage> response = new AMessage;
-
- ssize_t trackIndex = findTrack(wantAudio);
-
- if (trackIndex < 0) {
- err = trackIndex;
- } else {
- TrackInfo *info = &mTracks.editValueAt(trackIndex);
-
- sp<AMessage> format = info->mSampleDescs.itemAt(0).mFormat;
- if (info->mSidxDuration) {
- format->setInt64("durationUs", info->mSidxDuration);
- } else {
- // this is probably going to be zero. Oh well...
- format->setInt64("durationUs",
- 1000000ll * info->mDuration / info->mMediaTimeScale);
- }
- response->setMessage(
- "format", format);
-
- err = OK;
- }
-
- response->setInt32("err", err);
-
- uint32_t replyID;
- CHECK(msg->senderAwaitsResponse(&replyID));
-
- response->postReply(replyID);
- break;
- }
-
- case kWhatDequeueAccessUnit:
- {
- int32_t wantAudio;
- CHECK(msg->findInt32("audio", &wantAudio));
-
- status_t err = -EWOULDBLOCK;
- sp<AMessage> response = new AMessage;
-
- ssize_t trackIndex = findTrack(wantAudio);
-
- if (trackIndex < 0) {
- err = trackIndex;
- } else {
- sp<ABuffer> accessUnit;
- err = onDequeueAccessUnit(trackIndex, &accessUnit);
-
- if (err == OK) {
- response->setBuffer("accessUnit", accessUnit);
- }
- }
-
- response->setInt32("err", err);
-
- uint32_t replyID;
- CHECK(msg->senderAwaitsResponse(&replyID));
-
- response->postReply(replyID);
- break;
- }
-
- case kWhatSeekTo:
- {
- ALOGV("kWhatSeekTo");
- int32_t wantAudio;
- CHECK(msg->findInt32("audio", &wantAudio));
- int64_t position;
- CHECK(msg->findInt64("position", &position));
-
- status_t err = -EWOULDBLOCK;
- sp<AMessage> response = new AMessage;
-
- ssize_t trackIndex = findTrack(wantAudio);
-
- if (trackIndex < 0) {
- err = trackIndex;
- } else {
- err = onSeekTo(wantAudio, position);
- }
- response->setInt32("err", err);
- uint32_t replyID;
- CHECK(msg->senderAwaitsResponse(&replyID));
- response->postReply(replyID);
- break;
- }
- default:
- TRESPASS();
- }
-}
-
-status_t FragmentedMP4Parser::onProceed() {
- status_t err;
-
- if ((err = need(8)) != OK) {
- return err;
- }
-
- uint64_t size = readU32(0);
- uint32_t type = readU32(4);
-
- size_t offset = 8;
-
- if (size == 1) {
- if ((err = need(16)) != OK) {
- return err;
- }
-
- size = readU64(offset);
- offset += 8;
- }
-
- uint8_t userType[16];
-
- if (type == FOURCC('u', 'u', 'i', 'd')) {
- if ((err = need(offset + 16)) != OK) {
- return err;
- }
-
- memcpy(userType, mBuffer->data() + offset, 16);
- offset += 16;
- }
-
- CHECK(!mStack.isEmpty());
- uint32_t ptype = mStack.itemAt(mStack.size() - 1).mType;
-
- static const size_t kNumDispatchers =
- sizeof(kDispatchTable) / sizeof(kDispatchTable[0]);
-
- size_t i;
- for (i = 0; i < kNumDispatchers; ++i) {
- if (kDispatchTable[i].mType == type
- && kDispatchTable[i].mParentType == ptype) {
- break;
- }
- }
-
- // SampleEntry boxes are container boxes that start with a variable
- // amount of data depending on the media handler type.
- // We don't look inside 'hint' type SampleEntry boxes.
-
- bool isSampleEntryBox =
- (ptype == FOURCC('s', 't', 's', 'd'))
- && editTrack(mCurrentTrackID)->mMediaHandlerType
- != FOURCC('h', 'i', 'n', 't');
-
- if ((i < kNumDispatchers && kDispatchTable[i].mHandler == 0)
- || isSampleEntryBox || ptype == FOURCC('i', 'l', 's', 't')) {
- // This is a container box.
- if (type == FOURCC('m', 'o', 'o', 'f')) {
- if (mFirstMoofOffset == 0) {
- ALOGV("first moof @ %08x", mBufferPos + offset);
- mFirstMoofOffset = mBufferPos + offset - 8; // point at the size
- }
- }
- if (type == FOURCC('m', 'e', 't', 'a')) {
- if ((err = need(offset + 4)) < OK) {
- return err;
- }
-
- if (readU32(offset) != 0) {
- return -EINVAL;
- }
-
- offset += 4;
- } else if (type == FOURCC('s', 't', 's', 'd')) {
- if ((err = need(offset + 8)) < OK) {
- return err;
- }
-
- if (readU32(offset) != 0) {
- return -EINVAL;
- }
-
- if (readU32(offset + 4) == 0) {
- // We need at least some entries.
- return -EINVAL;
- }
-
- offset += 8;
- } else if (isSampleEntryBox) {
- size_t headerSize;
-
- switch (editTrack(mCurrentTrackID)->mMediaHandlerType) {
- case FOURCC('v', 'i', 'd', 'e'):
- {
- // 8 bytes SampleEntry + 70 bytes VisualSampleEntry
- headerSize = 78;
- break;
- }
-
- case FOURCC('s', 'o', 'u', 'n'):
- {
- // 8 bytes SampleEntry + 20 bytes AudioSampleEntry
- headerSize = 28;
- break;
- }
-
- case FOURCC('m', 'e', 't', 'a'):
- {
- headerSize = 8; // 8 bytes SampleEntry
- break;
- }
-
- default:
- TRESPASS();
- }
-
- if (offset + headerSize > size) {
- return -EINVAL;
- }
-
- if ((err = need(offset + headerSize)) != OK) {
- return err;
- }
-
- switch (editTrack(mCurrentTrackID)->mMediaHandlerType) {
- case FOURCC('v', 'i', 'd', 'e'):
- {
- err = parseVisualSampleEntry(
- type, offset, offset + headerSize);
- break;
- }
-
- case FOURCC('s', 'o', 'u', 'n'):
- {
- err = parseAudioSampleEntry(
- type, offset, offset + headerSize);
- break;
- }
-
- case FOURCC('m', 'e', 't', 'a'):
- {
- err = OK;
- break;
- }
-
- default:
- TRESPASS();
- }
-
- if (err != OK) {
- return err;
- }
-
- offset += headerSize;
- }
-
- skip(offset);
-
- ALOGV("%sentering box of type '%s'",
- IndentString(mStack.size()), Fourcc2String(type));
-
- enter(mBufferPos - offset, type, size - offset);
- } else {
- if (!fitsContainer(size)) {
- return -EINVAL;
- }
-
- if (i < kNumDispatchers && kDispatchTable[i].mHandler != 0) {
- // We have a handler for this box type.
-
- if ((err = need(size)) != OK) {
- return err;
- }
-
- ALOGV("%sparsing box of type '%s'",
- IndentString(mStack.size()), Fourcc2String(type));
-
- if ((err = (this->*kDispatchTable[i].mHandler)(
- type, offset, size)) != OK) {
- return err;
- }
- } else {
- // Unknown box type
-
- ALOGV("%sskipping box of type '%s', size %llu",
- IndentString(mStack.size()),
- Fourcc2String(type), size);
-
- }
-
- skip(size);
- }
-
- return OK;
-}
-
-// static
-int FragmentedMP4Parser::CompareSampleLocation(
- const SampleInfo &sample, const MediaDataInfo &mdatInfo) {
- if (sample.mOffset + sample.mSize < mdatInfo.mOffset) {
- return -1;
- }
-
- if (sample.mOffset >= mdatInfo.mOffset + mdatInfo.mBuffer->size()) {
- return 1;
- }
-
- // Otherwise make sure the sample is completely contained within this
- // media data block.
-
- CHECK_GE(sample.mOffset, mdatInfo.mOffset);
-
- CHECK_LE(sample.mOffset + sample.mSize,
- mdatInfo.mOffset + mdatInfo.mBuffer->size());
-
- return 0;
-}
-
-void FragmentedMP4Parser::resumeIfNecessary() {
- if (!mSuspended) {
- return;
- }
-
- ALOGV("resuming.");
-
- mSuspended = false;
- (new AMessage(kWhatProceed, id()))->post();
-}
-
-status_t FragmentedMP4Parser::getSample(
- TrackInfo *info, sp<TrackFragment> *fragment, SampleInfo *sampleInfo) {
- for (;;) {
- if (info->mFragments.empty()) {
- if (mFinalResult != OK) {
- return mFinalResult;
- }
-
- resumeIfNecessary();
- return -EWOULDBLOCK;
- }
-
- *fragment = *info->mFragments.begin();
-
- status_t err = (*fragment)->getSample(sampleInfo);
-
- if (err == OK) {
- return OK;
- } else if (err != ERROR_END_OF_STREAM) {
- return err;
- }
-
- // Really, end of this fragment...
-
- info->mFragments.erase(info->mFragments.begin());
- }
-}
-
-status_t FragmentedMP4Parser::onDequeueAccessUnit(
- size_t trackIndex, sp<ABuffer> *accessUnit) {
- TrackInfo *info = &mTracks.editValueAt(trackIndex);
-
- sp<TrackFragment> fragment;
- SampleInfo sampleInfo;
- status_t err = getSample(info, &fragment, &sampleInfo);
-
- if (err == -EWOULDBLOCK) {
- resumeIfNecessary();
- return err;
- } else if (err != OK) {
- return err;
- }
-
- err = -EWOULDBLOCK;
-
- bool checkDroppable = false;
-
- for (size_t i = 0; i < mMediaData.size(); ++i) {
- const MediaDataInfo &mdatInfo = mMediaData.itemAt(i);
-
- int cmp = CompareSampleLocation(sampleInfo, mdatInfo);
-
- if (cmp < 0 && !mSource->isSeekable()) {
- return -EPIPE;
- } else if (cmp == 0) {
- if (i > 0) {
- checkDroppable = true;
- }
-
- err = makeAccessUnit(info, sampleInfo, mdatInfo, accessUnit);
- break;
- }
- }
-
- if (err != OK) {
- return err;
- }
-
- fragment->advance();
-
- if (!mMediaData.empty() && checkDroppable) {
- size_t numDroppable = 0;
- bool done = false;
-
- // XXX FIXME: if one of the tracks is not advanced (e.g. if you play an audio+video
- // file with sf2), then mMediaData will not be pruned and keeps growing
- for (size_t i = 0; !done && i < mMediaData.size(); ++i) {
- const MediaDataInfo &mdatInfo = mMediaData.itemAt(i);
-
- for (size_t j = 0; j < mTracks.size(); ++j) {
- TrackInfo *info = &mTracks.editValueAt(j);
-
- sp<TrackFragment> fragment;
- SampleInfo sampleInfo;
- err = getSample(info, &fragment, &sampleInfo);
-
- if (err != OK) {
- done = true;
- break;
- }
-
- int cmp = CompareSampleLocation(sampleInfo, mdatInfo);
-
- if (cmp <= 0) {
- done = true;
- break;
- }
- }
-
- if (!done) {
- ++numDroppable;
- }
- }
-
- if (numDroppable > 0) {
- mMediaData.removeItemsAt(0, numDroppable);
-
- if (mMediaData.size() < 5) {
- resumeIfNecessary();
- }
- }
- }
-
- return err;
-}
-
-static size_t parseNALSize(size_t nalLengthSize, const uint8_t *data) {
- switch (nalLengthSize) {
- case 1:
- return *data;
- case 2:
- return U16_AT(data);
- case 3:
- return ((size_t)data[0] << 16) | U16_AT(&data[1]);
- case 4:
- return U32_AT(data);
- }
-
- // This cannot happen, mNALLengthSize springs to life by adding 1 to
- // a 2-bit integer.
- TRESPASS();
-
- return 0;
-}
-
-status_t FragmentedMP4Parser::makeAccessUnit(
- TrackInfo *info,
- const SampleInfo &sample,
- const MediaDataInfo &mdatInfo,
- sp<ABuffer> *accessUnit) {
- if (sample.mSampleDescIndex < 1
- || sample.mSampleDescIndex > info->mSampleDescs.size()) {
- return ERROR_MALFORMED;
- }
-
- int64_t presentationTimeUs =
- 1000000ll * sample.mPresentationTime / info->mMediaTimeScale;
-
- const SampleDescription &sampleDesc =
- info->mSampleDescs.itemAt(sample.mSampleDescIndex - 1);
-
- size_t nalLengthSize;
- if (!sampleDesc.mFormat->findSize("nal-length-size", &nalLengthSize)) {
- *accessUnit = new ABuffer(sample.mSize);
-
- memcpy((*accessUnit)->data(),
- mdatInfo.mBuffer->data() + (sample.mOffset - mdatInfo.mOffset),
- sample.mSize);
-
- (*accessUnit)->meta()->setInt64("timeUs", presentationTimeUs);
- if (IsIDR(*accessUnit)) {
- (*accessUnit)->meta()->setInt32("is-sync-frame", 1);
- }
-
- return OK;
- }
-
- const uint8_t *srcPtr =
- mdatInfo.mBuffer->data() + (sample.mOffset - mdatInfo.mOffset);
-
- for (int i = 0; i < 2 ; ++i) {
- size_t srcOffset = 0;
- size_t dstOffset = 0;
-
- while (srcOffset < sample.mSize) {
- if (srcOffset + nalLengthSize > sample.mSize) {
- return ERROR_MALFORMED;
- }
-
- size_t nalSize = parseNALSize(nalLengthSize, &srcPtr[srcOffset]);
- srcOffset += nalLengthSize;
-
- if (srcOffset + nalSize > sample.mSize) {
- return ERROR_MALFORMED;
- }
-
- if (i == 1) {
- memcpy((*accessUnit)->data() + dstOffset,
- "\x00\x00\x00\x01",
- 4);
-
- memcpy((*accessUnit)->data() + dstOffset + 4,
- srcPtr + srcOffset,
- nalSize);
- }
-
- srcOffset += nalSize;
- dstOffset += nalSize + 4;
- }
-
- if (i == 0) {
- (*accessUnit) = new ABuffer(dstOffset);
- (*accessUnit)->meta()->setInt64(
- "timeUs", presentationTimeUs);
- }
- }
- if (IsIDR(*accessUnit)) {
- (*accessUnit)->meta()->setInt32("is-sync-frame", 1);
- }
-
- return OK;
-}
-
-status_t FragmentedMP4Parser::need(size_t size) {
- if (!fitsContainer(size)) {
- return -EINVAL;
- }
-
- if (size <= mBuffer->size()) {
- return OK;
- }
-
- sp<AMessage> msg = new AMessage(kWhatReadMore, id());
- msg->setSize("needed", size - mBuffer->size());
- msg->post();
-
- // ALOGV("need(%d) returning -EAGAIN, only have %d", size, mBuffer->size());
-
- return -EAGAIN;
-}
-
-void FragmentedMP4Parser::enter(off64_t offset, uint32_t type, uint64_t size) {
- Container container;
- container.mOffset = offset;
- container.mType = type;
- container.mExtendsToEOF = (size == 0);
- container.mBytesRemaining = size;
-
- mStack.push(container);
-}
-
-bool FragmentedMP4Parser::fitsContainer(uint64_t size) const {
- CHECK(!mStack.isEmpty());
- const Container &container = mStack.itemAt(mStack.size() - 1);
-
- return container.mExtendsToEOF || size <= container.mBytesRemaining;
-}
-
-uint16_t FragmentedMP4Parser::readU16(size_t offset) {
- CHECK_LE(offset + 2, mBuffer->size());
-
- const uint8_t *ptr = mBuffer->data() + offset;
- return (ptr[0] << 8) | ptr[1];
-}
-
-uint32_t FragmentedMP4Parser::readU32(size_t offset) {
- CHECK_LE(offset + 4, mBuffer->size());
-
- const uint8_t *ptr = mBuffer->data() + offset;
- return (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3];
-}
-
-uint64_t FragmentedMP4Parser::readU64(size_t offset) {
- return (((uint64_t)readU32(offset)) << 32) | readU32(offset + 4);
-}
-
-void FragmentedMP4Parser::skip(off_t distance) {
- CHECK(!mStack.isEmpty());
- for (size_t i = mStack.size(); i-- > 0;) {
- Container *container = &mStack.editItemAt(i);
- if (!container->mExtendsToEOF) {
- CHECK_LE(distance, (off_t)container->mBytesRemaining);
-
- container->mBytesRemaining -= distance;
-
- if (container->mBytesRemaining == 0) {
- ALOGV("%sleaving box of type '%s'",
- IndentString(mStack.size() - 1),
- Fourcc2String(container->mType));
-
-#if 0
- if (container->mType == FOURCC('s', 't', 's', 'd')) {
- TrackInfo *trackInfo = editTrack(mCurrentTrackID);
- for (size_t i = 0;
- i < trackInfo->mSampleDescs.size(); ++i) {
- ALOGI("format #%d: %s",
- i,
- trackInfo->mSampleDescs.itemAt(i)
- .mFormat->debugString().c_str());
- }
- }
-#endif
-
- if (container->mType == FOURCC('s', 't', 'b', 'l')) {
- TrackInfo *trackInfo = editTrack(mCurrentTrackID);
-
- trackInfo->mStaticFragment->signalCompletion();
-
- CHECK(trackInfo->mFragments.empty());
- trackInfo->mFragments.push_back(trackInfo->mStaticFragment);
- trackInfo->mStaticFragment.clear();
- } else if (container->mType == FOURCC('t', 'r', 'a', 'f')) {
- TrackInfo *trackInfo =
- editTrack(mTrackFragmentHeaderInfo.mTrackID);
-
- const sp<TrackFragment> &fragment =
- *--trackInfo->mFragments.end();
-
- static_cast<DynamicTrackFragment *>(
- fragment.get())->signalCompletion();
- } else if (container->mType == FOURCC('m', 'o', 'o', 'v')) {
- mDoneWithMoov = true;
- }
-
- container = NULL;
- mStack.removeItemsAt(i);
- }
- }
- }
-
- if (distance < (off_t)mBuffer->size()) {
- mBuffer->setRange(mBuffer->offset() + distance, mBuffer->size() - distance);
- mBufferPos += distance;
- return;
- }
-
- mBuffer->setRange(0, 0);
- mBufferPos += distance;
-}
-
-status_t FragmentedMP4Parser::parseTrackHeader(
- uint32_t type, size_t offset, uint64_t size) {
- if (offset + 4 > size) {
- return -EINVAL;
- }
-
- uint32_t flags = readU32(offset);
-
- uint32_t version = flags >> 24;
- flags &= 0xffffff;
-
- uint32_t trackID;
- uint64_t duration;
-
- if (version == 1) {
- if (offset + 36 > size) {
- return -EINVAL;
- }
-
- trackID = readU32(offset + 20);
- duration = readU64(offset + 28);
-
- offset += 36;
- } else if (version == 0) {
- if (offset + 24 > size) {
- return -EINVAL;
- }
-
- trackID = readU32(offset + 12);
- duration = readU32(offset + 20);
-
- offset += 24;
- } else {
- return -EINVAL;
- }
-
- TrackInfo *info = editTrack(trackID, true /* createIfNecessary */);
- info->mFlags = flags;
- info->mDuration = duration;
- if (info->mDuration == 0xffffffff) {
- // ffmpeg sets this to -1, which is incorrect.
- info->mDuration = 0;
- }
-
- info->mStaticFragment = new StaticTrackFragment;
-
- mCurrentTrackID = trackID;
-
- return OK;
-}
-
-status_t FragmentedMP4Parser::parseMediaHeader(
- uint32_t type, size_t offset, uint64_t size) {
- if (offset + 4 > size) {
- return -EINVAL;
- }
-
- uint32_t versionAndFlags = readU32(offset);
-
- if (versionAndFlags & 0xffffff) {
- return ERROR_MALFORMED;
- }
-
- uint32_t version = versionAndFlags >> 24;
-
- TrackInfo *info = editTrack(mCurrentTrackID);
-
- if (version == 1) {
- if (offset + 4 + 32 > size) {
- return -EINVAL;
- }
- info->mMediaTimeScale = U32_AT(mBuffer->data() + offset + 20);
- } else if (version == 0) {
- if (offset + 4 + 20 > size) {
- return -EINVAL;
- }
- info->mMediaTimeScale = U32_AT(mBuffer->data() + offset + 12);
- } else {
- return ERROR_MALFORMED;
- }
-
- return OK;
-}
-
-status_t FragmentedMP4Parser::parseMediaHandler(
- uint32_t type, size_t offset, uint64_t size) {
- if (offset + 12 > size) {
- return -EINVAL;
- }
-
- if (readU32(offset) != 0) {
- return -EINVAL;
- }
-
- uint32_t handlerType = readU32(offset + 8);
-
- switch (handlerType) {
- case FOURCC('v', 'i', 'd', 'e'):
- case FOURCC('s', 'o', 'u', 'n'):
- case FOURCC('h', 'i', 'n', 't'):
- case FOURCC('m', 'e', 't', 'a'):
- break;
-
- default:
- return -EINVAL;
- }
-
- editTrack(mCurrentTrackID)->mMediaHandlerType = handlerType;
-
- return OK;
-}
-
-status_t FragmentedMP4Parser::parseVisualSampleEntry(
- uint32_t type, size_t offset, uint64_t size) {
- if (offset + 78 > size) {
- return -EINVAL;
- }
-
- TrackInfo *trackInfo = editTrack(mCurrentTrackID);
-
- trackInfo->mSampleDescs.push();
- SampleDescription *sampleDesc =
- &trackInfo->mSampleDescs.editItemAt(
- trackInfo->mSampleDescs.size() - 1);
-
- sampleDesc->mType = type;
- sampleDesc->mDataRefIndex = readU16(offset + 6);
-
- sp<AMessage> format = new AMessage;
-
- switch (type) {
- case FOURCC('a', 'v', 'c', '1'):
- format->setString("mime", MEDIA_MIMETYPE_VIDEO_AVC);
- break;
- case FOURCC('m', 'p', '4', 'v'):
- format->setString("mime", MEDIA_MIMETYPE_VIDEO_MPEG4);
- break;
- case FOURCC('s', '2', '6', '3'):
- case FOURCC('h', '2', '6', '3'):
- case FOURCC('H', '2', '6', '3'):
- format->setString("mime", MEDIA_MIMETYPE_VIDEO_H263);
- break;
- default:
- format->setString("mime", "application/octet-stream");
- break;
- }
-
- format->setInt32("width", readU16(offset + 8 + 16));
- format->setInt32("height", readU16(offset + 8 + 18));
-
- sampleDesc->mFormat = format;
-
- return OK;
-}
-
-status_t FragmentedMP4Parser::parseAudioSampleEntry(
- uint32_t type, size_t offset, uint64_t size) {
- if (offset + 28 > size) {
- return -EINVAL;
- }
-
- TrackInfo *trackInfo = editTrack(mCurrentTrackID);
-
- trackInfo->mSampleDescs.push();
- SampleDescription *sampleDesc =
- &trackInfo->mSampleDescs.editItemAt(
- trackInfo->mSampleDescs.size() - 1);
-
- sampleDesc->mType = type;
- sampleDesc->mDataRefIndex = readU16(offset + 6);
-
- sp<AMessage> format = new AMessage;
-
- format->setInt32("channel-count", readU16(offset + 8 + 8));
- format->setInt32("sample-size", readU16(offset + 8 + 10));
- format->setInt32("sample-rate", readU32(offset + 8 + 16) / 65536.0f);
-
- switch (type) {
- case FOURCC('m', 'p', '4', 'a'):
- format->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
- break;
-
- case FOURCC('s', 'a', 'm', 'r'):
- format->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
- format->setInt32("channel-count", 1);
- format->setInt32("sample-rate", 8000);
- break;
-
- case FOURCC('s', 'a', 'w', 'b'):
- format->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
- format->setInt32("channel-count", 1);
- format->setInt32("sample-rate", 16000);
- break;
- default:
- format->setString("mime", "application/octet-stream");
- break;
- }
-
- sampleDesc->mFormat = format;
-
- return OK;
-}
-
-static void addCodecSpecificData(
- const sp<AMessage> &format, int32_t index,
- const void *data, size_t size,
- bool insertStartCode = false) {
- sp<ABuffer> csd = new ABuffer(insertStartCode ? size + 4 : size);
-
- memcpy(csd->data() + (insertStartCode ? 4 : 0), data, size);
-
- if (insertStartCode) {
- memcpy(csd->data(), "\x00\x00\x00\x01", 4);
- }
-
- csd->meta()->setInt32("csd", true);
- csd->meta()->setInt64("timeUs", 0ll);
-
- format->setBuffer(StringPrintf("csd-%d", index).c_str(), csd);
-}
-
-status_t FragmentedMP4Parser::parseSampleSizes(
- uint32_t type, size_t offset, uint64_t size) {
- return editTrack(mCurrentTrackID)->mStaticFragment->parseSampleSizes(
- this, type, offset, size);
-}
-
-status_t FragmentedMP4Parser::parseCompactSampleSizes(
- uint32_t type, size_t offset, uint64_t size) {
- return editTrack(mCurrentTrackID)->mStaticFragment->parseCompactSampleSizes(
- this, type, offset, size);
-}
-
-status_t FragmentedMP4Parser::parseSampleToChunk(
- uint32_t type, size_t offset, uint64_t size) {
- return editTrack(mCurrentTrackID)->mStaticFragment->parseSampleToChunk(
- this, type, offset, size);
-}
-
-status_t FragmentedMP4Parser::parseChunkOffsets(
- uint32_t type, size_t offset, uint64_t size) {
- return editTrack(mCurrentTrackID)->mStaticFragment->parseChunkOffsets(
- this, type, offset, size);
-}
-
-status_t FragmentedMP4Parser::parseChunkOffsets64(
- uint32_t type, size_t offset, uint64_t size) {
- return editTrack(mCurrentTrackID)->mStaticFragment->parseChunkOffsets64(
- this, type, offset, size);
-}
-
-status_t FragmentedMP4Parser::parseAVCCodecSpecificData(
- uint32_t type, size_t offset, uint64_t size) {
- TrackInfo *trackInfo = editTrack(mCurrentTrackID);
-
- SampleDescription *sampleDesc =
- &trackInfo->mSampleDescs.editItemAt(
- trackInfo->mSampleDescs.size() - 1);
-
- if (sampleDesc->mType != FOURCC('a', 'v', 'c', '1')) {
- return -EINVAL;
- }
-
- const uint8_t *ptr = mBuffer->data() + offset;
-
- size -= offset;
- offset = 0;
-
- if (size < 7 || ptr[0] != 0x01) {
- return ERROR_MALFORMED;
- }
-
- sampleDesc->mFormat->setSize("nal-length-size", 1 + (ptr[4] & 3));
-
- size_t numSPS = ptr[5] & 31;
-
- ptr += 6;
- size -= 6;
-
- for (size_t i = 0; i < numSPS; ++i) {
- if (size < 2) {
- return ERROR_MALFORMED;
- }
-
- size_t length = U16_AT(ptr);
-
- ptr += 2;
- size -= 2;
-
- if (size < length) {
- return ERROR_MALFORMED;
- }
-
- addCodecSpecificData(
- sampleDesc->mFormat, i, ptr, length,
- true /* insertStartCode */);
-
- ptr += length;
- size -= length;
- }
-
- if (size < 1) {
- return ERROR_MALFORMED;
- }
-
- size_t numPPS = *ptr;
- ++ptr;
- --size;
-
- for (size_t i = 0; i < numPPS; ++i) {
- if (size < 2) {
- return ERROR_MALFORMED;
- }
-
- size_t length = U16_AT(ptr);
-
- ptr += 2;
- size -= 2;
-
- if (size < length) {
- return ERROR_MALFORMED;
- }
-
- addCodecSpecificData(
- sampleDesc->mFormat, numSPS + i, ptr, length,
- true /* insertStartCode */);
-
- ptr += length;
- size -= length;
- }
-
- return OK;
-}
-
-status_t FragmentedMP4Parser::parseESDSCodecSpecificData(
- uint32_t type, size_t offset, uint64_t size) {
- TrackInfo *trackInfo = editTrack(mCurrentTrackID);
-
- SampleDescription *sampleDesc =
- &trackInfo->mSampleDescs.editItemAt(
- trackInfo->mSampleDescs.size() - 1);
-
- if (sampleDesc->mType != FOURCC('m', 'p', '4', 'a')
- && sampleDesc->mType != FOURCC('m', 'p', '4', 'v')) {
- return -EINVAL;
- }
-
- const uint8_t *ptr = mBuffer->data() + offset;
-
- size -= offset;
- offset = 0;
-
- if (size < 4) {
- return -EINVAL;
- }
-
- if (U32_AT(ptr) != 0) {
- return -EINVAL;
- }
-
- ptr += 4;
- size -=4;
-
- ESDS esds(ptr, size);
-
- uint8_t objectTypeIndication;
- if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) {
- return ERROR_MALFORMED;
- }
-
- const uint8_t *csd;
- size_t csd_size;
- if (esds.getCodecSpecificInfo(
- (const void **)&csd, &csd_size) != OK) {
- return ERROR_MALFORMED;
- }
-
- addCodecSpecificData(sampleDesc->mFormat, 0, csd, csd_size);
-
- if (sampleDesc->mType != FOURCC('m', 'p', '4', 'a')) {
- return OK;
- }
-
- if (csd_size == 0) {
- // There's no further information, i.e. no codec specific data
- // Let's assume that the information provided in the mpeg4 headers
- // is accurate and hope for the best.
-
- return OK;
- }
-
- if (csd_size < 2) {
- return ERROR_MALFORMED;
- }
-
- uint32_t objectType = csd[0] >> 3;
-
- if (objectType == 31) {
- return ERROR_UNSUPPORTED;
- }
-
- uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7);
- int32_t sampleRate = 0;
- int32_t numChannels = 0;
- if (freqIndex == 15) {
- if (csd_size < 5) {
- return ERROR_MALFORMED;
- }
-
- sampleRate = (csd[1] & 0x7f) << 17
- | csd[2] << 9
- | csd[3] << 1
- | (csd[4] >> 7);
-
- numChannels = (csd[4] >> 3) & 15;
- } else {
- static uint32_t kSamplingRate[] = {
- 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
- 16000, 12000, 11025, 8000, 7350
- };
-
- if (freqIndex == 13 || freqIndex == 14) {
- return ERROR_MALFORMED;
- }
-
- sampleRate = kSamplingRate[freqIndex];
- numChannels = (csd[1] >> 3) & 15;
- }
-
- if (numChannels == 0) {
- return ERROR_UNSUPPORTED;
- }
-
- sampleDesc->mFormat->setInt32("sample-rate", sampleRate);
- sampleDesc->mFormat->setInt32("channel-count", numChannels);
-
- return OK;
-}
-
-status_t FragmentedMP4Parser::parseMediaData(
- uint32_t type, size_t offset, uint64_t size) {
- ALOGV("skipping 'mdat' chunk at offsets 0x%08lx-0x%08llx.",
- mBufferPos + offset, mBufferPos + size);
-
- sp<ABuffer> buffer = new ABuffer(size - offset);
- memcpy(buffer->data(), mBuffer->data() + offset, size - offset);
-
- mMediaData.push();
- MediaDataInfo *info = &mMediaData.editItemAt(mMediaData.size() - 1);
- info->mBuffer = buffer;
- info->mOffset = mBufferPos + offset;
-
- if (mMediaData.size() > 10) {
- ALOGV("suspending for now.");
- mSuspended = true;
- }
-
- return OK;
-}
-
-status_t FragmentedMP4Parser::parseSegmentIndex(
- uint32_t type, size_t offset, uint64_t size) {
- ALOGV("sidx box type %d, offset %d, size %d", type, int(offset), int(size));
-// AString sidxstr;
-// hexdump(mBuffer->data() + offset, size, 0 /* indent */, &sidxstr);
-// ALOGV("raw sidx:");
-// ALOGV("%s", sidxstr.c_str());
- if (offset + 12 > size) {
- return -EINVAL;
- }
-
- uint32_t flags = readU32(offset);
-
- uint32_t version = flags >> 24;
- flags &= 0xffffff;
-
- ALOGV("sidx version %d", version);
-
- uint32_t referenceId = readU32(offset + 4);
- uint32_t timeScale = readU32(offset + 8);
- ALOGV("sidx refid/timescale: %d/%d", referenceId, timeScale);
-
- uint64_t earliestPresentationTime;
- uint64_t firstOffset;
-
- offset += 12;
-
- if (version == 0) {
- if (offset + 8 > size) {
- return -EINVAL;
- }
- earliestPresentationTime = readU32(offset);
- firstOffset = readU32(offset + 4);
- offset += 8;
- } else {
- if (offset + 16 > size) {
- return -EINVAL;
- }
- earliestPresentationTime = readU64(offset);
- firstOffset = readU64(offset + 8);
- offset += 16;
- }
- ALOGV("sidx pres/off: %Ld/%Ld", earliestPresentationTime, firstOffset);
-
- if (offset + 4 > size) {
- return -EINVAL;
- }
- if (readU16(offset) != 0) { // reserved
- return -EINVAL;
- }
- int32_t referenceCount = readU16(offset + 2);
- offset += 4;
- ALOGV("refcount: %d", referenceCount);
-
- if (offset + referenceCount * 12 > size) {
- return -EINVAL;
- }
-
- TrackInfo *info = editTrack(mCurrentTrackID);
- uint64_t total_duration = 0;
- for (int i = 0; i < referenceCount; i++) {
- uint32_t d1 = readU32(offset);
- uint32_t d2 = readU32(offset + 4);
- uint32_t d3 = readU32(offset + 8);
-
- if (d1 & 0x80000000) {
- ALOGW("sub-sidx boxes not supported yet");
- }
- bool sap = d3 & 0x80000000;
- bool saptype = d3 >> 28;
- if (!sap || saptype > 2) {
- ALOGW("not a stream access point, or unsupported type");
- }
- total_duration += d2;
- offset += 12;
- ALOGV(" item %d, %08x %08x %08x", i, d1, d2, d3);
- SidxEntry se;
- se.mSize = d1 & 0x7fffffff;
- se.mDurationUs = 1000000LL * d2 / timeScale;
- info->mSidx.add(se);
- }
-
- info->mSidxDuration = total_duration * 1000000 / timeScale;
- ALOGV("duration: %lld", info->mSidxDuration);
- return OK;
-}
-
-status_t FragmentedMP4Parser::parseTrackExtends(
- uint32_t type, size_t offset, uint64_t size) {
- if (offset + 24 > size) {
- return -EINVAL;
- }
-
- if (readU32(offset) != 0) {
- return -EINVAL;
- }
-
- uint32_t trackID = readU32(offset + 4);
-
- TrackInfo *info = editTrack(trackID, true /* createIfNecessary */);
- info->mDefaultSampleDescriptionIndex = readU32(offset + 8);
- info->mDefaultSampleDuration = readU32(offset + 12);
- info->mDefaultSampleSize = readU32(offset + 16);
- info->mDefaultSampleFlags = readU32(offset + 20);
-
- return OK;
-}
-
-FragmentedMP4Parser::TrackInfo *FragmentedMP4Parser::editTrack(
- uint32_t trackID, bool createIfNecessary) {
- ssize_t i = mTracks.indexOfKey(trackID);
-
- if (i >= 0) {
- return &mTracks.editValueAt(i);
- }
-
- if (!createIfNecessary) {
- return NULL;
- }
-
- TrackInfo info;
- info.mTrackID = trackID;
- info.mFlags = 0;
- info.mDuration = 0xffffffff;
- info.mSidxDuration = 0;
- info.mMediaTimeScale = 0;
- info.mMediaHandlerType = 0;
- info.mDefaultSampleDescriptionIndex = 0;
- info.mDefaultSampleDuration = 0;
- info.mDefaultSampleSize = 0;
- info.mDefaultSampleFlags = 0;
-
- info.mDecodingTime = 0;
-
- mTracks.add(trackID, info);
- return &mTracks.editValueAt(mTracks.indexOfKey(trackID));
-}
-
-status_t FragmentedMP4Parser::parseTrackFragmentHeader(
- uint32_t type, size_t offset, uint64_t size) {
- if (offset + 8 > size) {
- return -EINVAL;
- }
-
- uint32_t flags = readU32(offset);
-
- if (flags & 0xff000000) {
- return -EINVAL;
- }
-
- mTrackFragmentHeaderInfo.mFlags = flags;
-
- mTrackFragmentHeaderInfo.mTrackID = readU32(offset + 4);
- offset += 8;
-
- if (flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent) {
- if (offset + 8 > size) {
- return -EINVAL;
- }
-
- mTrackFragmentHeaderInfo.mBaseDataOffset = readU64(offset);
- offset += 8;
- }
-
- if (flags & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) {
- if (offset + 4 > size) {
- return -EINVAL;
- }
-
- mTrackFragmentHeaderInfo.mSampleDescriptionIndex = readU32(offset);
- offset += 4;
- }
-
- if (flags & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) {
- if (offset + 4 > size) {
- return -EINVAL;
- }
-
- mTrackFragmentHeaderInfo.mDefaultSampleDuration = readU32(offset);
- offset += 4;
- }
-
- if (flags & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) {
- if (offset + 4 > size) {
- return -EINVAL;
- }
-
- mTrackFragmentHeaderInfo.mDefaultSampleSize = readU32(offset);
- offset += 4;
- }
-
- if (flags & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) {
- if (offset + 4 > size) {
- return -EINVAL;
- }
-
- mTrackFragmentHeaderInfo.mDefaultSampleFlags = readU32(offset);
- offset += 4;
- }
-
- if (!(flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent)) {
- // This should point to the position of the first byte of the
- // enclosing 'moof' container for the first track and
- // the end of the data of the preceding fragment for subsequent
- // tracks.
-
- CHECK_GE(mStack.size(), 2u);
-
- mTrackFragmentHeaderInfo.mBaseDataOffset =
- mStack.itemAt(mStack.size() - 2).mOffset;
-
- // XXX TODO: This does not do the right thing for the 2nd and
- // subsequent tracks yet.
- }
-
- mTrackFragmentHeaderInfo.mDataOffset =
- mTrackFragmentHeaderInfo.mBaseDataOffset;
-
- TrackInfo *trackInfo = editTrack(mTrackFragmentHeaderInfo.mTrackID);
-
- if (trackInfo->mFragments.empty()
- || (*trackInfo->mFragments.begin())->complete()) {
- trackInfo->mFragments.push_back(new DynamicTrackFragment);
- }
-
- return OK;
-}
-
-status_t FragmentedMP4Parser::parseTrackFragmentRun(
- uint32_t type, size_t offset, uint64_t size) {
- if (offset + 8 > size) {
- return -EINVAL;
- }
-
- enum {
- kDataOffsetPresent = 0x01,
- kFirstSampleFlagsPresent = 0x04,
- kSampleDurationPresent = 0x100,
- kSampleSizePresent = 0x200,
- kSampleFlagsPresent = 0x400,
- kSampleCompositionTimeOffsetPresent = 0x800,
- };
-
- uint32_t flags = readU32(offset);
-
- if (flags & 0xff000000) {
- return -EINVAL;
- }
-
- if ((flags & kFirstSampleFlagsPresent) && (flags & kSampleFlagsPresent)) {
- // These two shall not be used together.
- return -EINVAL;
- }
-
- uint32_t sampleCount = readU32(offset + 4);
- offset += 8;
-
- uint64_t dataOffset = mTrackFragmentHeaderInfo.mDataOffset;
-
- uint32_t firstSampleFlags = 0;
-
- if (flags & kDataOffsetPresent) {
- if (offset + 4 > size) {
- return -EINVAL;
- }
-
- int32_t dataOffsetDelta = (int32_t)readU32(offset);
-
- dataOffset = mTrackFragmentHeaderInfo.mBaseDataOffset + dataOffsetDelta;
-
- offset += 4;
- }
-
- if (flags & kFirstSampleFlagsPresent) {
- if (offset + 4 > size) {
- return -EINVAL;
- }
-
- firstSampleFlags = readU32(offset);
- offset += 4;
- }
-
- TrackInfo *info = editTrack(mTrackFragmentHeaderInfo.mTrackID);
-
- if (info == NULL) {
- return -EINVAL;
- }
-
- uint32_t sampleDuration = 0, sampleSize = 0, sampleFlags = 0,
- sampleCtsOffset = 0;
-
- size_t bytesPerSample = 0;
- if (flags & kSampleDurationPresent) {
- bytesPerSample += 4;
- } else if (mTrackFragmentHeaderInfo.mFlags
- & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) {
- sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration;
- } else {
- sampleDuration = info->mDefaultSampleDuration;
- }
-
- if (flags & kSampleSizePresent) {
- bytesPerSample += 4;
- } else if (mTrackFragmentHeaderInfo.mFlags
- & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) {
- sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize;
- } else {
- sampleSize = info->mDefaultSampleSize;
- }
-
- if (flags & kSampleFlagsPresent) {
- bytesPerSample += 4;
- } else if (mTrackFragmentHeaderInfo.mFlags
- & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) {
- sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags;
- } else {
- sampleFlags = info->mDefaultSampleFlags;
- }
-
- if (flags & kSampleCompositionTimeOffsetPresent) {
- bytesPerSample += 4;
- } else {
- sampleCtsOffset = 0;
- }
-
- if (offset + sampleCount * bytesPerSample > size) {
- return -EINVAL;
- }
-
- uint32_t sampleDescIndex =
- (mTrackFragmentHeaderInfo.mFlags
- & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent)
- ? mTrackFragmentHeaderInfo.mSampleDescriptionIndex
- : info->mDefaultSampleDescriptionIndex;
-
- for (uint32_t i = 0; i < sampleCount; ++i) {
- if (flags & kSampleDurationPresent) {
- sampleDuration = readU32(offset);
- offset += 4;
- }
-
- if (flags & kSampleSizePresent) {
- sampleSize = readU32(offset);
- offset += 4;
- }
-
- if (flags & kSampleFlagsPresent) {
- sampleFlags = readU32(offset);
- offset += 4;
- }
-
- if (flags & kSampleCompositionTimeOffsetPresent) {
- sampleCtsOffset = readU32(offset);
- offset += 4;
- }
-
- ALOGV("adding sample at offset 0x%08llx, size %u, duration %u, "
- "sampleDescIndex=%u, flags 0x%08x",
- dataOffset, sampleSize, sampleDuration,
- sampleDescIndex,
- (flags & kFirstSampleFlagsPresent) && i == 0
- ? firstSampleFlags : sampleFlags);
-
- const sp<TrackFragment> &fragment = *--info->mFragments.end();
-
- uint32_t decodingTime = info->mDecodingTime;
- info->mDecodingTime += sampleDuration;
- uint32_t presentationTime = decodingTime + sampleCtsOffset;
-
- static_cast<DynamicTrackFragment *>(
- fragment.get())->addSample(
- dataOffset,
- sampleSize,
- presentationTime,
- sampleDescIndex,
- ((flags & kFirstSampleFlagsPresent) && i == 0)
- ? firstSampleFlags : sampleFlags);
-
- dataOffset += sampleSize;
- }
-
- mTrackFragmentHeaderInfo.mDataOffset = dataOffset;
-
- return OK;
-}
-
-void FragmentedMP4Parser::copyBuffer(
- sp<ABuffer> *dst, size_t offset, uint64_t size) const {
- sp<ABuffer> buf = new ABuffer(size);
- memcpy(buf->data(), mBuffer->data() + offset, size);
-
- *dst = buf;
-}
-
-} // namespace android
diff --git a/media/libstagefright/mp4/TrackFragment.cpp b/media/libstagefright/mp4/TrackFragment.cpp
deleted file mode 100644
index 3699038..0000000
--- a/media/libstagefright/mp4/TrackFragment.cpp
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "TrackFragment"
-#include <utils/Log.h>
-
-#include "TrackFragment.h"
-
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/Utils.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/hexdump.h>
-
-namespace android {
-
-FragmentedMP4Parser::DynamicTrackFragment::DynamicTrackFragment()
- : mComplete(false),
- mSampleIndex(0) {
-}
-
-FragmentedMP4Parser::DynamicTrackFragment::~DynamicTrackFragment() {
-}
-
-status_t FragmentedMP4Parser::DynamicTrackFragment::getSample(SampleInfo *info) {
- if (mSampleIndex >= mSamples.size()) {
- return mComplete ? ERROR_END_OF_STREAM : -EWOULDBLOCK;
- }
-
- *info = mSamples.itemAt(mSampleIndex);
-
- return OK;
-}
-
-void FragmentedMP4Parser::DynamicTrackFragment::advance() {
- ++mSampleIndex;
-}
-
-void FragmentedMP4Parser::DynamicTrackFragment::addSample(
- off64_t dataOffset, size_t sampleSize,
- uint32_t presentationTime,
- size_t sampleDescIndex,
- uint32_t flags) {
- mSamples.push();
- SampleInfo *sampleInfo = &mSamples.editItemAt(mSamples.size() - 1);
-
- sampleInfo->mOffset = dataOffset;
- sampleInfo->mSize = sampleSize;
- sampleInfo->mPresentationTime = presentationTime;
- sampleInfo->mSampleDescIndex = sampleDescIndex;
- sampleInfo->mFlags = flags;
-}
-
-status_t FragmentedMP4Parser::DynamicTrackFragment::signalCompletion() {
- mComplete = true;
-
- return OK;
-}
-
-bool FragmentedMP4Parser::DynamicTrackFragment::complete() const {
- return mComplete;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-FragmentedMP4Parser::StaticTrackFragment::StaticTrackFragment()
- : mSampleIndex(0),
- mSampleCount(0),
- mChunkIndex(0),
- mSampleToChunkIndex(-1),
- mSampleToChunkRemaining(0),
- mPrevChunkIndex(0xffffffff),
- mNextSampleOffset(0) {
-}
-
-FragmentedMP4Parser::StaticTrackFragment::~StaticTrackFragment() {
-}
-
-status_t FragmentedMP4Parser::StaticTrackFragment::getSample(SampleInfo *info) {
- if (mSampleIndex >= mSampleCount) {
- return ERROR_END_OF_STREAM;
- }
-
- *info = mSampleInfo;
-
- ALOGV("returning sample %d at [0x%08llx, 0x%08llx)",
- mSampleIndex,
- info->mOffset, info->mOffset + info->mSize);
-
- return OK;
-}
-
-void FragmentedMP4Parser::StaticTrackFragment::updateSampleInfo() {
- if (mSampleIndex >= mSampleCount) {
- return;
- }
-
- if (mSampleSizes != NULL) {
- uint32_t defaultSampleSize = U32_AT(mSampleSizes->data() + 4);
- if (defaultSampleSize > 0) {
- mSampleInfo.mSize = defaultSampleSize;
- } else {
- mSampleInfo.mSize= U32_AT(mSampleSizes->data() + 12 + 4 * mSampleIndex);
- }
- } else {
- CHECK(mCompactSampleSizes != NULL);
-
- uint32_t fieldSize = U32_AT(mCompactSampleSizes->data() + 4);
-
- switch (fieldSize) {
- case 4:
- {
- unsigned byte = mCompactSampleSizes->data()[12 + mSampleIndex / 2];
- mSampleInfo.mSize = (mSampleIndex & 1) ? byte & 0x0f : byte >> 4;
- break;
- }
-
- case 8:
- {
- mSampleInfo.mSize = mCompactSampleSizes->data()[12 + mSampleIndex];
- break;
- }
-
- default:
- {
- CHECK_EQ(fieldSize, 16);
- mSampleInfo.mSize =
- U16_AT(mCompactSampleSizes->data() + 12 + mSampleIndex * 2);
- break;
- }
- }
- }
-
- CHECK_GT(mSampleToChunkRemaining, 0);
-
- // The sample desc index is 1-based... XXX
- mSampleInfo.mSampleDescIndex =
- U32_AT(mSampleToChunk->data() + 8 + 12 * mSampleToChunkIndex + 8);
-
- if (mChunkIndex != mPrevChunkIndex) {
- mPrevChunkIndex = mChunkIndex;
-
- if (mChunkOffsets != NULL) {
- uint32_t entryCount = U32_AT(mChunkOffsets->data() + 4);
-
- if (mChunkIndex >= entryCount) {
- mSampleIndex = mSampleCount;
- return;
- }
-
- mNextSampleOffset =
- U32_AT(mChunkOffsets->data() + 8 + 4 * mChunkIndex);
- } else {
- CHECK(mChunkOffsets64 != NULL);
-
- uint32_t entryCount = U32_AT(mChunkOffsets64->data() + 4);
-
- if (mChunkIndex >= entryCount) {
- mSampleIndex = mSampleCount;
- return;
- }
-
- mNextSampleOffset =
- U64_AT(mChunkOffsets64->data() + 8 + 8 * mChunkIndex);
- }
- }
-
- mSampleInfo.mOffset = mNextSampleOffset;
-
- mSampleInfo.mPresentationTime = 0;
- mSampleInfo.mFlags = 0;
-}
-
-void FragmentedMP4Parser::StaticTrackFragment::advance() {
- mNextSampleOffset += mSampleInfo.mSize;
-
- ++mSampleIndex;
- if (--mSampleToChunkRemaining == 0) {
- ++mChunkIndex;
-
- uint32_t entryCount = U32_AT(mSampleToChunk->data() + 4);
-
- // If this is the last entry in the sample to chunk table, we will
- // stay on this entry.
- if ((uint32_t)(mSampleToChunkIndex + 1) < entryCount) {
- uint32_t nextChunkIndex =
- U32_AT(mSampleToChunk->data() + 8 + 12 * (mSampleToChunkIndex + 1));
-
- CHECK_GE(nextChunkIndex, 1u);
- --nextChunkIndex;
-
- if (mChunkIndex >= nextChunkIndex) {
- CHECK_EQ(mChunkIndex, nextChunkIndex);
- ++mSampleToChunkIndex;
- }
- }
-
- mSampleToChunkRemaining =
- U32_AT(mSampleToChunk->data() + 8 + 12 * mSampleToChunkIndex + 4);
- }
-
- updateSampleInfo();
-}
-
-static void setU32At(uint8_t *ptr, uint32_t x) {
- ptr[0] = x >> 24;
- ptr[1] = (x >> 16) & 0xff;
- ptr[2] = (x >> 8) & 0xff;
- ptr[3] = x & 0xff;
-}
-
-status_t FragmentedMP4Parser::StaticTrackFragment::signalCompletion() {
- mSampleToChunkIndex = 0;
-
- mSampleToChunkRemaining =
- (mSampleToChunk == NULL)
- ? 0
- : U32_AT(mSampleToChunk->data() + 8 + 12 * mSampleToChunkIndex + 4);
-
- updateSampleInfo();
-
- return OK;
-}
-
-bool FragmentedMP4Parser::StaticTrackFragment::complete() const {
- return true;
-}
-
-status_t FragmentedMP4Parser::StaticTrackFragment::parseSampleSizes(
- FragmentedMP4Parser *parser, uint32_t type, size_t offset, uint64_t size) {
- if (offset + 12 > size) {
- return ERROR_MALFORMED;
- }
-
- if (parser->readU32(offset) != 0) {
- return ERROR_MALFORMED;
- }
-
- uint32_t sampleSize = parser->readU32(offset + 4);
- uint32_t sampleCount = parser->readU32(offset + 8);
-
- if (sampleSize == 0 && offset + 12 + sampleCount * 4 != size) {
- return ERROR_MALFORMED;
- }
-
- parser->copyBuffer(&mSampleSizes, offset, size);
-
- mSampleCount = sampleCount;
-
- return OK;
-}
-
-status_t FragmentedMP4Parser::StaticTrackFragment::parseCompactSampleSizes(
- FragmentedMP4Parser *parser, uint32_t type, size_t offset, uint64_t size) {
- if (offset + 12 > size) {
- return ERROR_MALFORMED;
- }
-
- if (parser->readU32(offset) != 0) {
- return ERROR_MALFORMED;
- }
-
- uint32_t fieldSize = parser->readU32(offset + 4);
-
- if (fieldSize != 4 && fieldSize != 8 && fieldSize != 16) {
- return ERROR_MALFORMED;
- }
-
- uint32_t sampleCount = parser->readU32(offset + 8);
-
- if (offset + 12 + (sampleCount * fieldSize + 4) / 8 != size) {
- return ERROR_MALFORMED;
- }
-
- parser->copyBuffer(&mCompactSampleSizes, offset, size);
-
- mSampleCount = sampleCount;
-
- return OK;
-}
-
-status_t FragmentedMP4Parser::StaticTrackFragment::parseSampleToChunk(
- FragmentedMP4Parser *parser, uint32_t type, size_t offset, uint64_t size) {
- if (offset + 8 > size) {
- return ERROR_MALFORMED;
- }
-
- if (parser->readU32(offset) != 0) {
- return ERROR_MALFORMED;
- }
-
- uint32_t entryCount = parser->readU32(offset + 4);
-
- if (entryCount == 0) {
- return OK;
- }
-
- if (offset + 8 + entryCount * 12 != size) {
- return ERROR_MALFORMED;
- }
-
- parser->copyBuffer(&mSampleToChunk, offset, size);
-
- return OK;
-}
-
-status_t FragmentedMP4Parser::StaticTrackFragment::parseChunkOffsets(
- FragmentedMP4Parser *parser, uint32_t type, size_t offset, uint64_t size) {
- if (offset + 8 > size) {
- return ERROR_MALFORMED;
- }
-
- if (parser->readU32(offset) != 0) {
- return ERROR_MALFORMED;
- }
-
- uint32_t entryCount = parser->readU32(offset + 4);
-
- if (offset + 8 + entryCount * 4 != size) {
- return ERROR_MALFORMED;
- }
-
- parser->copyBuffer(&mChunkOffsets, offset, size);
-
- return OK;
-}
-
-status_t FragmentedMP4Parser::StaticTrackFragment::parseChunkOffsets64(
- FragmentedMP4Parser *parser, uint32_t type, size_t offset, uint64_t size) {
- if (offset + 8 > size) {
- return ERROR_MALFORMED;
- }
-
- if (parser->readU32(offset) != 0) {
- return ERROR_MALFORMED;
- }
-
- uint32_t entryCount = parser->readU32(offset + 4);
-
- if (offset + 8 + entryCount * 8 != size) {
- return ERROR_MALFORMED;
- }
-
- parser->copyBuffer(&mChunkOffsets64, offset, size);
-
- return OK;
-}
-
-} // namespace android
-
diff --git a/media/libstagefright/mp4/TrackFragment.h b/media/libstagefright/mp4/TrackFragment.h
deleted file mode 100644
index e1ad46e..0000000
--- a/media/libstagefright/mp4/TrackFragment.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef TRACK_FRAGMENT_H_
-
-#define TRACK_FRAGMENT_H_
-
-#include "include/FragmentedMP4Parser.h"
-
-namespace android {
-
-struct FragmentedMP4Parser::TrackFragment : public RefBase {
- TrackFragment() {}
-
- virtual status_t getSample(SampleInfo *info) = 0;
- virtual void advance() = 0;
-
- virtual status_t signalCompletion() = 0;
- virtual bool complete() const = 0;
-
-protected:
- virtual ~TrackFragment() {}
-
-private:
- DISALLOW_EVIL_CONSTRUCTORS(TrackFragment);
-};
-
-struct FragmentedMP4Parser::DynamicTrackFragment : public FragmentedMP4Parser::TrackFragment {
- DynamicTrackFragment();
-
- virtual status_t getSample(SampleInfo *info);
- virtual void advance();
-
- void addSample(
- off64_t dataOffset, size_t sampleSize,
- uint32_t presentationTime,
- size_t sampleDescIndex,
- uint32_t flags);
-
- // No more samples will be added to this fragment.
- virtual status_t signalCompletion();
-
- virtual bool complete() const;
-
-protected:
- virtual ~DynamicTrackFragment();
-
-private:
- bool mComplete;
- size_t mSampleIndex;
- Vector<SampleInfo> mSamples;
-
- DISALLOW_EVIL_CONSTRUCTORS(DynamicTrackFragment);
-};
-
-struct FragmentedMP4Parser::StaticTrackFragment : public FragmentedMP4Parser::TrackFragment {
- StaticTrackFragment();
-
- virtual status_t getSample(SampleInfo *info);
- virtual void advance();
-
- virtual status_t signalCompletion();
- virtual bool complete() const;
-
- status_t parseSampleSizes(
- FragmentedMP4Parser *parser, uint32_t type, size_t offset, uint64_t size);
-
- status_t parseCompactSampleSizes(
- FragmentedMP4Parser *parser, uint32_t type, size_t offset, uint64_t size);
-
- status_t parseSampleToChunk(
- FragmentedMP4Parser *parser, uint32_t type, size_t offset, uint64_t size);
-
- status_t parseChunkOffsets(
- FragmentedMP4Parser *parser, uint32_t type, size_t offset, uint64_t size);
-
- status_t parseChunkOffsets64(
- FragmentedMP4Parser *parser, uint32_t type, size_t offset, uint64_t size);
-
-protected:
- virtual ~StaticTrackFragment();
-
-private:
- size_t mSampleIndex;
- size_t mSampleCount;
- uint32_t mChunkIndex;
-
- SampleInfo mSampleInfo;
-
- sp<ABuffer> mSampleSizes;
- sp<ABuffer> mCompactSampleSizes;
-
- sp<ABuffer> mSampleToChunk;
- ssize_t mSampleToChunkIndex;
- size_t mSampleToChunkRemaining;
-
- sp<ABuffer> mChunkOffsets;
- sp<ABuffer> mChunkOffsets64;
- uint32_t mPrevChunkIndex;
- uint64_t mNextSampleOffset;
-
- void updateSampleInfo();
-
- DISALLOW_EVIL_CONSTRUCTORS(StaticTrackFragment);
-};
-
-} // namespace android
-
-#endif // TRACK_FRAGMENT_H_
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index cb57a2f..d039f7d 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -862,7 +862,7 @@ status_t ATSParser::Stream::flush() {
}
void ATSParser::Stream::onPayloadData(
- unsigned PTS_DTS_flags, uint64_t PTS, uint64_t DTS,
+ unsigned PTS_DTS_flags, uint64_t PTS, uint64_t /* DTS */,
const uint8_t *data, size_t size) {
#if 0
ALOGI("payload streamType 0x%02x, PTS = 0x%016llx, dPTS = %lld",
@@ -1267,7 +1267,7 @@ bool ATSParser::PTSTimeDeltaEstablished() {
}
void ATSParser::updatePCR(
- unsigned PID, uint64_t PCR, size_t byteOffsetFromStart) {
+ unsigned /* PID */, uint64_t PCR, size_t byteOffsetFromStart) {
ALOGV("PCR 0x%016llx @ %d", PCR, byteOffsetFromStart);
if (mNumPCRs == 2) {
diff --git a/media/libstagefright/mpeg2ts/Android.mk b/media/libstagefright/mpeg2ts/Android.mk
index c1a7a9d..c17a0b7 100644
--- a/media/libstagefright/mpeg2ts/Android.mk
+++ b/media/libstagefright/mpeg2ts/Android.mk
@@ -13,6 +13,8 @@ LOCAL_C_INCLUDES:= \
$(TOP)/frameworks/av/media/libstagefright \
$(TOP)/frameworks/native/include/media/openmax
+LOCAL_CFLAGS += -Werror
+
LOCAL_MODULE:= libstagefright_mpeg2ts
ifeq ($(TARGET_ARCH),arm)
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
index 3153c8b..9fb13c1 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
@@ -61,7 +61,7 @@ void AnotherPacketSource::setFormat(const sp<MetaData> &meta) {
AnotherPacketSource::~AnotherPacketSource() {
}
-status_t AnotherPacketSource::start(MetaData *params) {
+status_t AnotherPacketSource::start(MetaData * /* params */) {
return OK;
}
@@ -70,7 +70,27 @@ status_t AnotherPacketSource::stop() {
}
sp<MetaData> AnotherPacketSource::getFormat() {
- return mFormat;
+ Mutex::Autolock autoLock(mLock);
+ if (mFormat != NULL) {
+ return mFormat;
+ }
+
+ List<sp<ABuffer> >::iterator it = mBuffers.begin();
+ while (it != mBuffers.end()) {
+ sp<ABuffer> buffer = *it;
+ int32_t discontinuity;
+ if (buffer->meta()->findInt32("discontinuity", &discontinuity)) {
+ break;
+ }
+
+ sp<RefBase> object;
+ if (buffer->meta()->findObject("format", &object)) {
+ return static_cast<MetaData*>(object.get());
+ }
+
+ ++it;
+ }
+ return NULL;
}
status_t AnotherPacketSource::dequeueAccessUnit(sp<ABuffer> *buffer) {
@@ -94,6 +114,11 @@ status_t AnotherPacketSource::dequeueAccessUnit(sp<ABuffer> *buffer) {
return INFO_DISCONTINUITY;
}
+ sp<RefBase> object;
+ if ((*buffer)->meta()->findObject("format", &object)) {
+ mFormat = static_cast<MetaData*>(object.get());
+ }
+
return OK;
}
@@ -120,17 +145,22 @@ status_t AnotherPacketSource::read(
}
return INFO_DISCONTINUITY;
- } else {
- int64_t timeUs;
- CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
+ }
- MediaBuffer *mediaBuffer = new MediaBuffer(buffer);
+ sp<RefBase> object;
+ if (buffer->meta()->findObject("format", &object)) {
+ mFormat = static_cast<MetaData*>(object.get());
+ }
- mediaBuffer->meta_data()->setInt64(kKeyTime, timeUs);
+ int64_t timeUs;
+ CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
- *out = mediaBuffer;
- return OK;
- }
+ MediaBuffer *mediaBuffer = new MediaBuffer(buffer);
+
+ mediaBuffer->meta_data()->setInt64(kKeyTime, timeUs);
+
+ *out = mediaBuffer;
+ return OK;
}
return mEOSResult;
diff --git a/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
index dd714c9..bc2a16d 100644
--- a/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
@@ -130,7 +130,8 @@ sp<MediaSource> MPEG2PSExtractor::getTrack(size_t index) {
return new WrappedTrack(this, mTracks.valueAt(index));
}
-sp<MetaData> MPEG2PSExtractor::getTrackMetaData(size_t index, uint32_t flags) {
+sp<MetaData> MPEG2PSExtractor::getTrackMetaData(
+ size_t index, uint32_t /* flags */) {
if (index >= mTracks.size()) {
return NULL;
}
@@ -625,7 +626,7 @@ status_t MPEG2PSExtractor::Track::read(
status_t MPEG2PSExtractor::Track::appendPESData(
unsigned PTS_DTS_flags,
- uint64_t PTS, uint64_t DTS,
+ uint64_t PTS, uint64_t /* DTS */,
const uint8_t *data, size_t size) {
if (mQueue == NULL) {
return OK;
diff --git a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
index d449c34..35ca118 100644
--- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
@@ -141,7 +141,7 @@ sp<MediaSource> MPEG2TSExtractor::getTrack(size_t index) {
}
sp<MetaData> MPEG2TSExtractor::getTrackMetaData(
- size_t index, uint32_t flags) {
+ size_t index, uint32_t /* flags */) {
return index < mSourceImpls.size()
? mSourceImpls.editItemAt(index)->getFormat() : NULL;
}
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index b8970ad..7672204 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -41,8 +41,13 @@ GraphicBufferSource::GraphicBufferSource(OMXNodeInstance* nodeInstance,
mNumFramesAvailable(0),
mEndOfStream(false),
mEndOfStreamSent(false),
+ mMaxTimestampGapUs(-1ll),
+ mPrevOriginalTimeUs(-1ll),
+ mPrevModifiedTimeUs(-1ll),
+ mSkipFramesBeforeNs(-1ll),
mRepeatAfterUs(-1ll),
mRepeatLastFrameGeneration(0),
+ mRepeatLastFrameTimestamp(-1ll),
mLatestSubmittedBufferId(-1),
mLatestSubmittedBufferFrameNum(0),
mLatestSubmittedBufferUseCount(0),
@@ -299,6 +304,32 @@ void GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header) {
return;
}
+void GraphicBufferSource::codecBufferFilled(OMX_BUFFERHEADERTYPE* header) {
+ Mutex::Autolock autoLock(mMutex);
+
+ if (mMaxTimestampGapUs > 0ll
+ && !(header->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
+ ssize_t index = mOriginalTimeUs.indexOfKey(header->nTimeStamp);
+ if (index >= 0) {
+ ALOGV("OUT timestamp: %lld -> %lld",
+ header->nTimeStamp, mOriginalTimeUs[index]);
+ header->nTimeStamp = mOriginalTimeUs[index];
+ mOriginalTimeUs.removeItemsAt(index);
+ } else {
+ // giving up the effort as encoder doesn't appear to preserve pts
+ ALOGW("giving up limiting timestamp gap (pts = %lld)",
+ header->nTimeStamp);
+ mMaxTimestampGapUs = -1ll;
+ }
+ if (mOriginalTimeUs.size() > BufferQueue::NUM_BUFFER_SLOTS) {
+ // something terribly wrong must have happened, giving up...
+ ALOGE("mOriginalTimeUs has too many entries (%d)",
+ mOriginalTimeUs.size());
+ mMaxTimestampGapUs = -1ll;
+ }
+ }
+}
+
void GraphicBufferSource::suspend(bool suspend) {
Mutex::Autolock autoLock(mMutex);
@@ -384,7 +415,18 @@ bool GraphicBufferSource::fillCodecBuffer_l() {
mBufferSlot[item.mBuf] = item.mGraphicBuffer;
}
- err = submitBuffer_l(item, cbi);
+ err = UNKNOWN_ERROR;
+
+ // only submit sample if start time is unspecified, or sample
+ // is queued after the specified start time
+ if (mSkipFramesBeforeNs < 0ll || item.mTimestamp >= mSkipFramesBeforeNs) {
+ // if start time is set, offset time stamp by start time
+ if (mSkipFramesBeforeNs > 0) {
+ item.mTimestamp -= mSkipFramesBeforeNs;
+ }
+ err = submitBuffer_l(item, cbi);
+ }
+
if (err != OK) {
ALOGV("submitBuffer_l failed, releasing bq buf %d", item.mBuf);
mBufferQueue->releaseBuffer(item.mBuf, item.mFrameNumber,
@@ -431,6 +473,7 @@ bool GraphicBufferSource::repeatLatestSubmittedBuffer_l() {
BufferQueue::BufferItem item;
item.mBuf = mLatestSubmittedBufferId;
item.mFrameNumber = mLatestSubmittedBufferFrameNum;
+ item.mTimestamp = mRepeatLastFrameTimestamp;
status_t err = submitBuffer_l(item, cbi);
@@ -440,6 +483,20 @@ bool GraphicBufferSource::repeatLatestSubmittedBuffer_l() {
++mLatestSubmittedBufferUseCount;
+ /* repeat last frame up to kRepeatLastFrameCount times.
+ * in case of static scene, a single repeat might not get rid of encoder
+ * ghosting completely, refresh a couple more times to get better quality
+ */
+ if (--mRepeatLastFrameCount > 0) {
+ mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000;
+
+ if (mReflector != NULL) {
+ sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector->id());
+ msg->setInt32("generation", ++mRepeatLastFrameGeneration);
+ msg->post(mRepeatAfterUs);
+ }
+ }
+
return true;
}
@@ -460,8 +517,11 @@ void GraphicBufferSource::setLatestSubmittedBuffer_l(
mLatestSubmittedBufferId = item.mBuf;
mLatestSubmittedBufferFrameNum = item.mFrameNumber;
+ mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000;
+
mLatestSubmittedBufferUseCount = 1;
mRepeatBufferDeferred = false;
+ mRepeatLastFrameCount = kRepeatLastFrameCount;
if (mReflector != NULL) {
sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector->id());
@@ -497,6 +557,39 @@ status_t GraphicBufferSource::signalEndOfInputStream() {
return OK;
}
+int64_t GraphicBufferSource::getTimestamp(const BufferQueue::BufferItem &item) {
+ int64_t timeUs = item.mTimestamp / 1000;
+
+ if (mMaxTimestampGapUs > 0ll) {
+ /* Cap timestamp gap between adjacent frames to specified max
+ *
+ * In the scenario of cast mirroring, encoding could be suspended for
+ * prolonged periods. Limiting the pts gap to workaround the problem
+ * where encoder's rate control logic produces huge frames after a
+ * long period of suspension.
+ */
+
+ int64_t originalTimeUs = timeUs;
+ if (mPrevOriginalTimeUs >= 0ll) {
+ if (originalTimeUs < mPrevOriginalTimeUs) {
+ // Drop the frame if it's going backward in time. Bad timestamp
+ // could disrupt encoder's rate control completely.
+ ALOGV("Dropping frame that's going backward in time");
+ return -1;
+ }
+ int64_t timestampGapUs = originalTimeUs - mPrevOriginalTimeUs;
+ timeUs = (timestampGapUs < mMaxTimestampGapUs ?
+ timestampGapUs : mMaxTimestampGapUs) + mPrevModifiedTimeUs;
+ }
+ mPrevOriginalTimeUs = originalTimeUs;
+ mPrevModifiedTimeUs = timeUs;
+ mOriginalTimeUs.add(timeUs, originalTimeUs);
+ ALOGV("IN timestamp: %lld -> %lld", originalTimeUs, timeUs);
+ }
+
+ return timeUs;
+}
+
status_t GraphicBufferSource::submitBuffer_l(
const BufferQueue::BufferItem &item, int cbi) {
ALOGV("submitBuffer_l cbi=%d", cbi);
@@ -513,9 +606,15 @@ status_t GraphicBufferSource::submitBuffer_l(
memcpy(data, &type, 4);
memcpy(data + 4, &handle, sizeof(buffer_handle_t));
+ int64_t timeUs = getTimestamp(item);
+ if (timeUs < 0ll) {
+ ALOGE("Dropping frame with bad timestamp");
+ return UNKNOWN_ERROR;
+ }
+
status_t err = mNodeInstance->emptyDirectBuffer(header, 0,
4 + sizeof(buffer_handle_t), OMX_BUFFERFLAG_ENDOFFRAME,
- item.mTimestamp / 1000);
+ timeUs);
if (err != OK) {
ALOGW("WARNING: emptyDirectBuffer failed: 0x%x", err);
codecBuffer.mGraphicBuffer = NULL;
@@ -609,6 +708,12 @@ void GraphicBufferSource::onFrameAvailable() {
BufferQueue::BufferItem item;
status_t err = mBufferQueue->acquireBuffer(&item, 0);
if (err == OK) {
+ // If this is the first time we're seeing this buffer, add it to our
+ // slot table.
+ if (item.mGraphicBuffer != NULL) {
+ ALOGV("fillCodecBuffer_l: setting mBufferSlot %d", item.mBuf);
+ mBufferSlot[item.mBuf] = item.mGraphicBuffer;
+ }
mBufferQueue->releaseBuffer(item.mBuf, item.mFrameNumber,
EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence);
}
@@ -658,6 +763,25 @@ status_t GraphicBufferSource::setRepeatPreviousFrameDelayUs(
return OK;
}
+status_t GraphicBufferSource::setMaxTimestampGapUs(int64_t maxGapUs) {
+ Mutex::Autolock autoLock(mMutex);
+
+ if (mExecuting || maxGapUs <= 0ll) {
+ return INVALID_OPERATION;
+ }
+
+ mMaxTimestampGapUs = maxGapUs;
+
+ return OK;
+}
+
+void GraphicBufferSource::setSkipFramesBeforeUs(int64_t skipFramesBeforeUs) {
+ Mutex::Autolock autoLock(mMutex);
+
+ mSkipFramesBeforeNs =
+ (skipFramesBeforeUs > 0) ? (skipFramesBeforeUs * 1000) : -1ll;
+}
+
void GraphicBufferSource::onMessageReceived(const sp<AMessage> &msg) {
switch (msg->what()) {
case kWhatRepeatLastFrame:
diff --git a/media/libstagefright/omx/GraphicBufferSource.h b/media/libstagefright/omx/GraphicBufferSource.h
index 9e5eee6..153f2a0 100644
--- a/media/libstagefright/omx/GraphicBufferSource.h
+++ b/media/libstagefright/omx/GraphicBufferSource.h
@@ -87,6 +87,10 @@ public:
// fill it with a new frame of data; otherwise, just mark it as available.
void codecBufferEmptied(OMX_BUFFERHEADERTYPE* header);
+ // Called when omx_message::FILL_BUFFER_DONE is received. (Currently the
+ // buffer source will fix timestamp in the header if needed.)
+ void codecBufferFilled(OMX_BUFFERHEADERTYPE* header);
+
// This is called after the last input frame has been submitted. We
// need to submit an empty buffer with the EOS flag set. If we don't
// have a codec buffer ready, we just set the mEndOfStream flag.
@@ -105,6 +109,19 @@ public:
// state and once this behaviour is specified it cannot be reset.
status_t setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs);
+ // When set, the timestamp fed to the encoder will be modified such that
+ // the gap between two adjacent frames is capped at maxGapUs. Timestamp
+ // will be restored to the original when the encoded frame is returned to
+ // the client.
+ // This is to solve a problem in certain real-time streaming case, where
+ // encoder's rate control logic produces huge frames after a long period
+ // of suspension on input.
+ status_t setMaxTimestampGapUs(int64_t maxGapUs);
+
+ // Sets the start time us (in system time), samples before which should
+ // be dropped and not submitted to encoder
+ void setSkipFramesBeforeUs(int64_t startTimeUs);
+
protected:
// BufferQueue::ConsumerListener interface, called when a new frame of
// data is available. If we're executing and a codec buffer is
@@ -165,6 +182,7 @@ private:
void setLatestSubmittedBuffer_l(const BufferQueue::BufferItem &item);
bool repeatLatestSubmittedBuffer_l();
+ int64_t getTimestamp(const BufferQueue::BufferItem &item);
// Lock, covers all member variables.
mutable Mutex mMutex;
@@ -206,13 +224,23 @@ private:
enum {
kWhatRepeatLastFrame,
};
+ enum {
+ kRepeatLastFrameCount = 10,
+ };
- int64_t mRepeatAfterUs;
+ KeyedVector<int64_t, int64_t> mOriginalTimeUs;
+ int64_t mMaxTimestampGapUs;
+ int64_t mPrevOriginalTimeUs;
+ int64_t mPrevModifiedTimeUs;
+ int64_t mSkipFramesBeforeNs;
sp<ALooper> mLooper;
sp<AHandlerReflector<GraphicBufferSource> > mReflector;
+ int64_t mRepeatAfterUs;
int32_t mRepeatLastFrameGeneration;
+ int64_t mRepeatLastFrameTimestamp;
+ int32_t mRepeatLastFrameCount;
int mLatestSubmittedBufferId;
uint64_t mLatestSubmittedBufferFrameNum;
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 274f2eb..a608479 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -185,7 +185,7 @@ void OMX::binderDied(const wp<IBinder> &the_late_who) {
instance->onObserverDied(mMaster);
}
-bool OMX::livesLocally(node_id node, pid_t pid) {
+bool OMX::livesLocally(node_id /* node */, pid_t pid) {
return pid == getpid();
}
@@ -424,7 +424,7 @@ OMX_ERRORTYPE OMX::OnEvent(
OMX_IN OMX_EVENTTYPE eEvent,
OMX_IN OMX_U32 nData1,
OMX_IN OMX_U32 nData2,
- OMX_IN OMX_PTR pEventData) {
+ OMX_IN OMX_PTR /* pEventData */) {
ALOGV("OnEvent(%d, %ld, %ld)", eEvent, nData1, nData2);
// Forward to OMXNodeInstance.
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 5f104fc..aa96389 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -266,7 +266,7 @@ status_t OMXNodeInstance::sendCommand(
}
status_t OMXNodeInstance::getParameter(
- OMX_INDEXTYPE index, void *params, size_t size) {
+ OMX_INDEXTYPE index, void *params, size_t /* size */) {
Mutex::Autolock autoLock(mLock);
OMX_ERRORTYPE err = OMX_GetParameter(mHandle, index, params);
@@ -275,7 +275,7 @@ status_t OMXNodeInstance::getParameter(
}
status_t OMXNodeInstance::setParameter(
- OMX_INDEXTYPE index, const void *params, size_t size) {
+ OMX_INDEXTYPE index, const void *params, size_t /* size */) {
Mutex::Autolock autoLock(mLock);
OMX_ERRORTYPE err = OMX_SetParameter(
@@ -285,7 +285,7 @@ status_t OMXNodeInstance::setParameter(
}
status_t OMXNodeInstance::getConfig(
- OMX_INDEXTYPE index, void *params, size_t size) {
+ OMX_INDEXTYPE index, void *params, size_t /* size */) {
Mutex::Autolock autoLock(mLock);
OMX_ERRORTYPE err = OMX_GetConfig(mHandle, index, params);
@@ -293,7 +293,7 @@ status_t OMXNodeInstance::getConfig(
}
status_t OMXNodeInstance::setConfig(
- OMX_INDEXTYPE index, const void *params, size_t size) {
+ OMX_INDEXTYPE index, const void *params, size_t /* size */) {
Mutex::Autolock autoLock(mLock);
OMX_ERRORTYPE err = OMX_SetConfig(
@@ -610,7 +610,7 @@ status_t OMXNodeInstance::useGraphicBuffer(
}
status_t OMXNodeInstance::updateGraphicBufferInMeta(
- OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
+ OMX_U32 /* portIndex */, const sp<GraphicBuffer>& graphicBuffer,
OMX::buffer_id buffer) {
Mutex::Autolock autoLock(mLock);
@@ -849,6 +849,8 @@ status_t OMXNodeInstance::setInternalOption(
switch (type) {
case IOMX::INTERNAL_OPTION_SUSPEND:
case IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY:
+ case IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP:
+ case IOMX::INTERNAL_OPTION_START_TIME:
{
const sp<GraphicBufferSource> &bufferSource =
getGraphicBufferSource();
@@ -864,7 +866,8 @@ status_t OMXNodeInstance::setInternalOption(
bool suspend = *(bool *)data;
bufferSource->suspend(suspend);
- } else {
+ } else if (type ==
+ IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY){
if (size != sizeof(int64_t)) {
return INVALID_OPERATION;
}
@@ -872,6 +875,23 @@ status_t OMXNodeInstance::setInternalOption(
int64_t delayUs = *(int64_t *)data;
return bufferSource->setRepeatPreviousFrameDelayUs(delayUs);
+ } else if (type ==
+ IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP){
+ if (size != sizeof(int64_t)) {
+ return INVALID_OPERATION;
+ }
+
+ int64_t maxGapUs = *(int64_t *)data;
+
+ return bufferSource->setMaxTimestampGapUs(maxGapUs);
+ } else { // IOMX::INTERNAL_OPTION_START_TIME
+ if (size != sizeof(int64_t)) {
+ return INVALID_OPERATION;
+ }
+
+ int64_t skipFramesBeforeUs = *(int64_t *)data;
+
+ bufferSource->setSkipFramesBeforeUs(skipFramesBeforeUs);
}
return OK;
@@ -883,6 +903,8 @@ status_t OMXNodeInstance::setInternalOption(
}
void OMXNodeInstance::onMessage(const omx_message &msg) {
+ const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource());
+
if (msg.type == omx_message::FILL_BUFFER_DONE) {
OMX_BUFFERHEADERTYPE *buffer =
static_cast<OMX_BUFFERHEADERTYPE *>(
@@ -892,10 +914,18 @@ void OMXNodeInstance::onMessage(const omx_message &msg) {
static_cast<BufferMeta *>(buffer->pAppPrivate);
buffer_meta->CopyFromOMX(buffer);
- } else if (msg.type == omx_message::EMPTY_BUFFER_DONE) {
- const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource());
if (bufferSource != NULL) {
+ // fix up the buffer info (especially timestamp) if needed
+ bufferSource->codecBufferFilled(buffer);
+
+ omx_message newMsg = msg;
+ newMsg.u.extended_buffer_data.timestamp = buffer->nTimeStamp;
+ mObserver->onMessage(newMsg);
+ return;
+ }
+ } else if (msg.type == omx_message::EMPTY_BUFFER_DONE) {
+ if (bufferSource != NULL) {
// This is one of the buffers used exclusively by
// GraphicBufferSource.
// Don't dispatch a message back to ACodec, since it doesn't
@@ -941,7 +971,7 @@ void OMXNodeInstance::onEvent(
// static
OMX_ERRORTYPE OMXNodeInstance::OnEvent(
- OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_HANDLETYPE /* hComponent */,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_EVENTTYPE eEvent,
OMX_IN OMX_U32 nData1,
@@ -957,7 +987,7 @@ OMX_ERRORTYPE OMXNodeInstance::OnEvent(
// static
OMX_ERRORTYPE OMXNodeInstance::OnEmptyBufferDone(
- OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_HANDLETYPE /* hComponent */,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
@@ -969,7 +999,7 @@ OMX_ERRORTYPE OMXNodeInstance::OnEmptyBufferDone(
// static
OMX_ERRORTYPE OMXNodeInstance::OnFillBufferDone(
- OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_HANDLETYPE /* hComponent */,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
diff --git a/media/libstagefright/omx/SoftOMXComponent.cpp b/media/libstagefright/omx/SoftOMXComponent.cpp
index b1c34dc..646cd32 100644
--- a/media/libstagefright/omx/SoftOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftOMXComponent.cpp
@@ -257,69 +257,69 @@ OMX_ERRORTYPE SoftOMXComponent::GetStateWrapper(
////////////////////////////////////////////////////////////////////////////////
OMX_ERRORTYPE SoftOMXComponent::sendCommand(
- OMX_COMMANDTYPE cmd, OMX_U32 param, OMX_PTR data) {
+ OMX_COMMANDTYPE /* cmd */, OMX_U32 /* param */, OMX_PTR /* data */) {
return OMX_ErrorUndefined;
}
OMX_ERRORTYPE SoftOMXComponent::getParameter(
- OMX_INDEXTYPE index, OMX_PTR params) {
+ OMX_INDEXTYPE /* index */, OMX_PTR /* params */) {
return OMX_ErrorUndefined;
}
OMX_ERRORTYPE SoftOMXComponent::setParameter(
- OMX_INDEXTYPE index, const OMX_PTR params) {
+ OMX_INDEXTYPE /* index */, const OMX_PTR /* params */) {
return OMX_ErrorUndefined;
}
OMX_ERRORTYPE SoftOMXComponent::getConfig(
- OMX_INDEXTYPE index, OMX_PTR params) {
+ OMX_INDEXTYPE /* index */, OMX_PTR /* params */) {
return OMX_ErrorUndefined;
}
OMX_ERRORTYPE SoftOMXComponent::setConfig(
- OMX_INDEXTYPE index, const OMX_PTR params) {
+ OMX_INDEXTYPE /* index */, const OMX_PTR /* params */) {
return OMX_ErrorUndefined;
}
OMX_ERRORTYPE SoftOMXComponent::getExtensionIndex(
- const char *name, OMX_INDEXTYPE *index) {
+ const char * /* name */, OMX_INDEXTYPE * /* index */) {
return OMX_ErrorUndefined;
}
OMX_ERRORTYPE SoftOMXComponent::useBuffer(
- OMX_BUFFERHEADERTYPE **buffer,
- OMX_U32 portIndex,
- OMX_PTR appPrivate,
- OMX_U32 size,
- OMX_U8 *ptr) {
+ OMX_BUFFERHEADERTYPE ** /* buffer */,
+ OMX_U32 /* portIndex */,
+ OMX_PTR /* appPrivate */,
+ OMX_U32 /* size */,
+ OMX_U8 * /* ptr */) {
return OMX_ErrorUndefined;
}
OMX_ERRORTYPE SoftOMXComponent::allocateBuffer(
- OMX_BUFFERHEADERTYPE **buffer,
- OMX_U32 portIndex,
- OMX_PTR appPrivate,
- OMX_U32 size) {
+ OMX_BUFFERHEADERTYPE ** /* buffer */,
+ OMX_U32 /* portIndex */,
+ OMX_PTR /* appPrivate */,
+ OMX_U32 /* size */) {
return OMX_ErrorUndefined;
}
OMX_ERRORTYPE SoftOMXComponent::freeBuffer(
- OMX_U32 portIndex,
- OMX_BUFFERHEADERTYPE *buffer) {
+ OMX_U32 /* portIndex */,
+ OMX_BUFFERHEADERTYPE * /* buffer */) {
return OMX_ErrorUndefined;
}
OMX_ERRORTYPE SoftOMXComponent::emptyThisBuffer(
- OMX_BUFFERHEADERTYPE *buffer) {
+ OMX_BUFFERHEADERTYPE * /* buffer */) {
return OMX_ErrorUndefined;
}
OMX_ERRORTYPE SoftOMXComponent::fillThisBuffer(
- OMX_BUFFERHEADERTYPE *buffer) {
+ OMX_BUFFERHEADERTYPE * /* buffer */) {
return OMX_ErrorUndefined;
}
-OMX_ERRORTYPE SoftOMXComponent::getState(OMX_STATETYPE *state) {
+OMX_ERRORTYPE SoftOMXComponent::getState(OMX_STATETYPE * /* state */) {
return OMX_ErrorUndefined;
}
diff --git a/media/libstagefright/omx/SoftOMXPlugin.cpp b/media/libstagefright/omx/SoftOMXPlugin.cpp
index d6cde73..d49e50b 100644
--- a/media/libstagefright/omx/SoftOMXPlugin.cpp
+++ b/media/libstagefright/omx/SoftOMXPlugin.cpp
@@ -154,7 +154,7 @@ OMX_ERRORTYPE SoftOMXPlugin::destroyComponentInstance(
OMX_ERRORTYPE SoftOMXPlugin::enumerateComponents(
OMX_STRING name,
- size_t size,
+ size_t /* size */,
OMX_U32 index) {
if (index >= kNumComponents) {
return OMX_ErrorNoMore;
diff --git a/media/libstagefright/omx/tests/Android.mk b/media/libstagefright/omx/tests/Android.mk
index 1061c39..8b79af4 100644
--- a/media/libstagefright/omx/tests/Android.mk
+++ b/media/libstagefright/omx/tests/Android.mk
@@ -11,6 +11,8 @@ LOCAL_C_INCLUDES := \
$(TOP)/frameworks/av/media/libstagefright \
$(TOP)/frameworks/native/include/media/openmax
+LOCAL_CFLAGS += -Werror
+
LOCAL_MODULE := omx_tests
LOCAL_MODULE_TAGS := tests
diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp
index 44e4f9d..03725df 100644
--- a/media/libstagefright/omx/tests/OMXHarness.cpp
+++ b/media/libstagefright/omx/tests/OMXHarness.cpp
@@ -26,6 +26,7 @@
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <binder/MemoryDealer.h>
+#include <media/IMediaHTTPService.h>
#include <media/IMediaPlayerService.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ALooper.h>
@@ -242,7 +243,8 @@ private:
};
static sp<MediaExtractor> CreateExtractorFromURI(const char *uri) {
- sp<DataSource> source = DataSource::CreateFromURI(uri);
+ sp<DataSource> source =
+ DataSource::CreateFromURI(NULL /* httpService */, uri);
if (source == NULL) {
return NULL;
diff --git a/media/libstagefright/rtsp/AMPEG2TSAssembler.cpp b/media/libstagefright/rtsp/AMPEG2TSAssembler.cpp
index 4c9bf5b..dca5c89 100644
--- a/media/libstagefright/rtsp/AMPEG2TSAssembler.cpp
+++ b/media/libstagefright/rtsp/AMPEG2TSAssembler.cpp
@@ -34,7 +34,9 @@
namespace android {
AMPEG2TSAssembler::AMPEG2TSAssembler(
- const sp<AMessage> &notify, const char *desc, const AString &params)
+ const sp<AMessage> &notify,
+ const char * /* desc */,
+ const AString & /* params */)
: mNotifyMsg(notify),
mNextExpectedSeqNoValid(false),
mNextExpectedSeqNo(0) {
diff --git a/media/libstagefright/rtsp/APacketSource.cpp b/media/libstagefright/rtsp/APacketSource.cpp
index 462c384..09f52bc 100644
--- a/media/libstagefright/rtsp/APacketSource.cpp
+++ b/media/libstagefright/rtsp/APacketSource.cpp
@@ -23,7 +23,7 @@
#include "ARawAudioAssembler.h"
#include "ASessionDescription.h"
-#include "avc_utils.h"
+#include "include/avc_utils.h"
#include <ctype.h>
diff --git a/media/libstagefright/rtsp/ARTPWriter.cpp b/media/libstagefright/rtsp/ARTPWriter.cpp
index 0d07043..c46d16f 100644
--- a/media/libstagefright/rtsp/ARTPWriter.cpp
+++ b/media/libstagefright/rtsp/ARTPWriter.cpp
@@ -114,7 +114,7 @@ bool ARTPWriter::reachedEOS() {
return (mFlags & kFlagEOS) != 0;
}
-status_t ARTPWriter::start(MetaData *params) {
+status_t ARTPWriter::start(MetaData * /* params */) {
Mutex::Autolock autoLock(mLock);
if (mFlags & kFlagStarted) {
return INVALID_OPERATION;
diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp
index efde7a9..4054da6 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTSPConnection.cpp
@@ -33,7 +33,7 @@
#include <openssl/md5.h>
#include <sys/socket.h>
-#include "HTTPBase.h"
+#include "include/HTTPBase.h"
namespace android {
diff --git a/media/libstagefright/rtsp/ARawAudioAssembler.cpp b/media/libstagefright/rtsp/ARawAudioAssembler.cpp
index 0da5dd2..167f7a4 100644
--- a/media/libstagefright/rtsp/ARawAudioAssembler.cpp
+++ b/media/libstagefright/rtsp/ARawAudioAssembler.cpp
@@ -34,7 +34,9 @@
namespace android {
ARawAudioAssembler::ARawAudioAssembler(
- const sp<AMessage> &notify, const char *desc, const AString &params)
+ const sp<AMessage> &notify,
+ const char * /* desc */,
+ const AString & /* params */)
: mNotifyMsg(notify),
mNextExpectedSeqNoValid(false),
mNextExpectedSeqNo(0) {
diff --git a/media/libstagefright/rtsp/Android.mk b/media/libstagefright/rtsp/Android.mk
index e77c69c..39eedc0 100644
--- a/media/libstagefright/rtsp/Android.mk
+++ b/media/libstagefright/rtsp/Android.mk
@@ -20,7 +20,7 @@ LOCAL_SRC_FILES:= \
SDPLoader.cpp \
LOCAL_C_INCLUDES:= \
- $(TOP)/frameworks/av/media/libstagefright/include \
+ $(TOP)/frameworks/av/media/libstagefright \
$(TOP)/frameworks/native/include/media/openmax \
$(TOP)/external/openssl/include
@@ -30,6 +30,8 @@ ifeq ($(TARGET_ARCH),arm)
LOCAL_CFLAGS += -Wno-psabi
endif
+LOCAL_CFLAGS += -Werror
+
include $(BUILD_STATIC_LIBRARY)
################################################################################
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index cd77aa0..45470a3 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -19,7 +19,11 @@
#define MY_HANDLER_H_
//#define LOG_NDEBUG 0
+
+#ifndef LOG_TAG
#define LOG_TAG "MyHandler"
+#endif
+
#include <utils/Log.h>
#include "APacketSource.h"
@@ -42,6 +46,12 @@
#include "HTTPBase.h"
+#if LOG_NDEBUG
+#define UNUSED_UNLESS_VERBOSE(x) (void)(x)
+#else
+#define UNUSED_UNLESS_VERBOSE(x)
+#endif
+
// If no access units are received within 5 secs, assume that the rtp
// stream has ended and signal end of stream.
static int64_t kAccessUnitTimeoutUs = 10000000ll;
@@ -178,7 +188,7 @@ struct MyHandler : public AHandler {
mConn->connect(mOriginalSessionURL.c_str(), reply);
}
- AString getControlURL(sp<ASessionDescription> desc) {
+ AString getControlURL() {
AString sessionLevelControlURL;
if (mSessionDesc->findAttribute(
0,
@@ -545,7 +555,7 @@ struct MyHandler : public AHandler {
mBaseURL = tmp;
}
- mControlURL = getControlURL(mSessionDesc);
+ mControlURL = getControlURL();
if (mSessionDesc->countTracks() < 2) {
// There's no actual tracks in this session.
@@ -591,7 +601,7 @@ struct MyHandler : public AHandler {
mSeekable = !isLiveStream(mSessionDesc);
- mControlURL = getControlURL(mSessionDesc);
+ mControlURL = getControlURL();
if (mSessionDesc->countTracks() < 2) {
// There's no actual tracks in this session.
@@ -1805,6 +1815,8 @@ private:
bool addMediaTimestamp(
int32_t trackIndex, const TrackInfo *track,
const sp<ABuffer> &accessUnit) {
+ UNUSED_UNLESS_VERBOSE(trackIndex);
+
uint32_t rtpTime;
CHECK(accessUnit->meta()->findInt32(
"rtp-time", (int32_t *)&rtpTime));
diff --git a/media/libstagefright/rtsp/SDPLoader.cpp b/media/libstagefright/rtsp/SDPLoader.cpp
index ed3fa7e..ce1e89d 100644
--- a/media/libstagefright/rtsp/SDPLoader.cpp
+++ b/media/libstagefright/rtsp/SDPLoader.cpp
@@ -18,11 +18,13 @@
#define LOG_TAG "SDPLoader"
#include <utils/Log.h>
-#include "SDPLoader.h"
+#include "include/SDPLoader.h"
#include "ASessionDescription.h"
-#include "HTTPBase.h"
+#include <media/IMediaHTTPConnection.h>
+#include <media/IMediaHTTPService.h>
+#include <media/stagefright/MediaHTTP.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
@@ -30,22 +32,15 @@
namespace android {
-SDPLoader::SDPLoader(const sp<AMessage> &notify, uint32_t flags, bool uidValid, uid_t uid)
+SDPLoader::SDPLoader(
+ const sp<AMessage> &notify,
+ uint32_t flags,
+ const sp<IMediaHTTPService> &httpService)
: mNotify(notify),
mFlags(flags),
- mUIDValid(uidValid),
- mUID(uid),
mNetLooper(new ALooper),
mCancelled(false),
- mHTTPDataSource(
- HTTPBase::Create(
- (mFlags & kFlagIncognito)
- ? HTTPBase::kFlagIncognito
- : 0)) {
- if (mUIDValid) {
- mHTTPDataSource->setUID(mUID);
- }
-
+ mHTTPDataSource(new MediaHTTP(httpService->makeHTTPConnection())) {
mNetLooper->setName("sdp net");
mNetLooper->start(false /* runOnCallingThread */,
false /* canCallJava */,
@@ -130,7 +125,7 @@ void SDPLoader::onLoad(const sp<AMessage> &msg) {
ssize_t readSize = mHTTPDataSource->readAt(0, buffer->data(), sdpSize);
if (readSize < 0) {
- ALOGE("Failed to read SDP, error code = %ld", readSize);
+ ALOGE("Failed to read SDP, error code = %d", readSize);
err = UNKNOWN_ERROR;
} else {
desc = new ASessionDescription;
diff --git a/media/libstagefright/tests/SurfaceMediaSource_test.cpp b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
index 49ffcd6..aeecdbc 100644
--- a/media/libstagefright/tests/SurfaceMediaSource_test.cpp
+++ b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
@@ -527,7 +527,8 @@ void SurfaceMediaSourceTest::oneBufferPass(int width, int height ) {
}
// Dequeuing and queuing the buffer without really filling it in.
-void SurfaceMediaSourceTest::oneBufferPassNoFill(int width, int height ) {
+void SurfaceMediaSourceTest::oneBufferPassNoFill(
+ int /* width */, int /* height */) {
ANativeWindowBuffer* anb;
ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
ASSERT_TRUE(anb != NULL);
@@ -746,9 +747,8 @@ TEST_F(SurfaceMediaSourceTest, DISABLED_EncodingFromCpuYV12BufferNpotWriteMediaS
CHECK(fd >= 0);
sp<MediaRecorder> mr = SurfaceMediaSourceGLTest::setUpMediaRecorder(fd,
- VIDEO_SOURCE_GRALLOC_BUFFER,
- OUTPUT_FORMAT_MPEG_4, VIDEO_ENCODER_H264, mYuvTexWidth,
- mYuvTexHeight, 30);
+ VIDEO_SOURCE_SURFACE, OUTPUT_FORMAT_MPEG_4, VIDEO_ENCODER_H264,
+ mYuvTexWidth, mYuvTexHeight, 30);
// get the reference to the surfacemediasource living in
// mediaserver that is created by stagefrightrecorder
sp<IGraphicBufferProducer> iST = mr->querySurfaceMediaSourceFromMediaServer();
@@ -880,7 +880,7 @@ TEST_F(SurfaceMediaSourceGLTest, EncodingFromGLRgbaSameImageEachBufNpotWrite) {
}
CHECK(fd >= 0);
- sp<MediaRecorder> mr = setUpMediaRecorder(fd, VIDEO_SOURCE_GRALLOC_BUFFER,
+ sp<MediaRecorder> mr = setUpMediaRecorder(fd, VIDEO_SOURCE_SURFACE,
OUTPUT_FORMAT_MPEG_4, VIDEO_ENCODER_H264, mYuvTexWidth, mYuvTexHeight, 30);
// get the reference to the surfacemediasource living in
@@ -923,7 +923,7 @@ TEST_F(SurfaceMediaSourceGLTest, EncodingFromGLRgbaDiffImageEachBufNpotWrite) {
}
CHECK(fd >= 0);
- sp<MediaRecorder> mr = setUpMediaRecorder(fd, VIDEO_SOURCE_GRALLOC_BUFFER,
+ sp<MediaRecorder> mr = setUpMediaRecorder(fd, VIDEO_SOURCE_SURFACE,
OUTPUT_FORMAT_MPEG_4, VIDEO_ENCODER_H264, mYuvTexWidth, mYuvTexHeight, 30);
// get the reference to the surfacemediasource living in
diff --git a/media/libstagefright/timedtext/Android.mk b/media/libstagefright/timedtext/Android.mk
index f099bbd..6a8b9fc 100644
--- a/media/libstagefright/timedtext/Android.mk
+++ b/media/libstagefright/timedtext/Android.mk
@@ -9,7 +9,8 @@ LOCAL_SRC_FILES:= \
TimedTextSRTSource.cpp \
TimedTextPlayer.cpp
-LOCAL_CFLAGS += -Wno-multichar
+LOCAL_CFLAGS += -Wno-multichar -Werror
+
LOCAL_C_INCLUDES:= \
$(TOP)/frameworks/av/include/media/stagefright/timedtext \
$(TOP)/frameworks/av/media/libstagefright
diff --git a/media/libstagefright/timedtext/TimedTextDriver.cpp b/media/libstagefright/timedtext/TimedTextDriver.cpp
index 12fd7f4..71aa21e 100644
--- a/media/libstagefright/timedtext/TimedTextDriver.cpp
+++ b/media/libstagefright/timedtext/TimedTextDriver.cpp
@@ -20,6 +20,7 @@
#include <binder/IPCThreadState.h>
+#include <media/IMediaHTTPService.h>
#include <media/mediaplayer.h>
#include <media/MediaPlayerInterface.h>
#include <media/stagefright/DataSource.h>
@@ -40,9 +41,11 @@
namespace android {
TimedTextDriver::TimedTextDriver(
- const wp<MediaPlayerBase> &listener)
+ const wp<MediaPlayerBase> &listener,
+ const sp<IMediaHTTPService> &httpService)
: mLooper(new ALooper),
mListener(listener),
+ mHTTPService(httpService),
mState(UNINITIALIZED),
mCurrentTrackIndex(UINT_MAX) {
mLooper->setName("TimedTextDriver");
@@ -207,7 +210,7 @@ status_t TimedTextDriver::addOutOfBandTextSource(
}
sp<DataSource> dataSource =
- DataSource::CreateFromURI(uri);
+ DataSource::CreateFromURI(mHTTPService, uri);
return createOutOfBandTextSource(trackIndex, mimeType, dataSource);
}
diff --git a/media/libstagefright/timedtext/TimedTextSource.h b/media/libstagefright/timedtext/TimedTextSource.h
index 756cc31..8c1c1cd 100644
--- a/media/libstagefright/timedtext/TimedTextSource.h
+++ b/media/libstagefright/timedtext/TimedTextSource.h
@@ -47,7 +47,7 @@ class TimedTextSource : public RefBase {
int64_t *endTimeUs,
Parcel *parcel,
const MediaSource::ReadOptions *options = NULL) = 0;
- virtual status_t extractGlobalDescriptions(Parcel *parcel) {
+ virtual status_t extractGlobalDescriptions(Parcel * /* parcel */) {
return INVALID_OPERATION;
}
virtual sp<MetaData> getFormat();
diff --git a/media/libstagefright/timedtext/test/Android.mk b/media/libstagefright/timedtext/test/Android.mk
index a5e7ba2..9a9fde2 100644
--- a/media/libstagefright/timedtext/test/Android.mk
+++ b/media/libstagefright/timedtext/test/Android.mk
@@ -2,7 +2,6 @@ LOCAL_PATH:= $(call my-dir)
# ================================================================
# Unit tests for libstagefright_timedtext
-# See also /development/testrunner/test_defs.xml
# ================================================================
# ================================================================
@@ -18,10 +17,13 @@ LOCAL_SRC_FILES := TimedTextSRTSource_test.cpp
LOCAL_C_INCLUDES := \
$(TOP)/external/expat/lib \
- $(TOP)/frameworks/base/media/libstagefright/timedtext
+ $(TOP)/frameworks/av/media/libstagefright/timedtext
LOCAL_SHARED_LIBRARIES := \
+ libbinder \
libexpat \
- libstagefright
+ libstagefright \
+ libstagefright_foundation \
+ libutils
include $(BUILD_NATIVE_TEST)
diff --git a/media/libstagefright/wifi-display/rtp/RTPSender.cpp b/media/libstagefright/wifi-display/rtp/RTPSender.cpp
index 1887b8b..e88a3bd 100644
--- a/media/libstagefright/wifi-display/rtp/RTPSender.cpp
+++ b/media/libstagefright/wifi-display/rtp/RTPSender.cpp
@@ -685,9 +685,8 @@ status_t RTPSender::onRTCPData(const sp<ABuffer> &buffer) {
return OK;
}
-status_t RTPSender::parseReceiverReport(const uint8_t *data, size_t size) {
- // hexdump(data, size);
-
+status_t RTPSender::parseReceiverReport(
+ const uint8_t *data, size_t /* size */) {
float fractionLost = data[12] / 256.0f;
ALOGI("lost %.2f %% of packets during report interval.",
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
index 286ea13..1a5acba 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
@@ -29,6 +29,7 @@
#include <binder/IServiceManager.h>
#include <cutils/properties.h>
#include <media/IHDCP.h>
+#include <media/IMediaHTTPService.h>
#include <media/stagefright/foundation/ABitReader.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
@@ -749,7 +750,8 @@ status_t WifiDisplaySource::PlaybackSession::setupMediaPacketizer(
mExtractor = new NuMediaExtractor;
- status_t err = mExtractor->setDataSource(mMediaPath.c_str());
+ status_t err = mExtractor->setDataSource(
+ NULL /* httpService */, mMediaPath.c_str());
if (err != OK) {
return err;
diff --git a/media/libstagefright/wifi-display/source/RepeaterSource.cpp b/media/libstagefright/wifi-display/source/RepeaterSource.cpp
index cc8dee3..59d7e6e 100644
--- a/media/libstagefright/wifi-display/source/RepeaterSource.cpp
+++ b/media/libstagefright/wifi-display/source/RepeaterSource.cpp
@@ -79,6 +79,8 @@ status_t RepeaterSource::stop() {
ALOGV("stopping");
+ status_t err = mSource->stop();
+
if (mLooper != NULL) {
mLooper->stop();
mLooper.clear();
@@ -92,7 +94,6 @@ status_t RepeaterSource::stop() {
mBuffer = NULL;
}
- status_t err = mSource->stop();
ALOGV("stopped");
diff --git a/media/libstagefright/wifi-display/source/TSPacketizer.cpp b/media/libstagefright/wifi-display/source/TSPacketizer.cpp
index edcc087..50d317a 100644
--- a/media/libstagefright/wifi-display/source/TSPacketizer.cpp
+++ b/media/libstagefright/wifi-display/source/TSPacketizer.cpp
@@ -216,7 +216,7 @@ sp<ABuffer> TSPacketizer::Track::prependADTSHeader(
uint8_t *ptr = dup->data();
*ptr++ = 0xff;
- *ptr++ = 0xf1; // b11110001, ID=0, layer=0, protection_absent=1
+ *ptr++ = 0xf9; // b11111001, ID=1(MPEG-2), layer=0, protection_absent=1
*ptr++ =
profile << 6
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
index 05e4018..da405e2 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
@@ -746,7 +746,7 @@ status_t WifiDisplaySource::sendM16(int32_t sessionID) {
}
status_t WifiDisplaySource::onReceiveM1Response(
- int32_t sessionID, const sp<ParsedMessage> &msg) {
+ int32_t /* sessionID */, const sp<ParsedMessage> &msg) {
int32_t statusCode;
if (!msg->getStatusCode(&statusCode)) {
return ERROR_MALFORMED;
@@ -991,7 +991,7 @@ status_t WifiDisplaySource::onReceiveM4Response(
}
status_t WifiDisplaySource::onReceiveM5Response(
- int32_t sessionID, const sp<ParsedMessage> &msg) {
+ int32_t /* sessionID */, const sp<ParsedMessage> &msg) {
int32_t statusCode;
if (!msg->getStatusCode(&statusCode)) {
return ERROR_MALFORMED;
@@ -1005,7 +1005,7 @@ status_t WifiDisplaySource::onReceiveM5Response(
}
status_t WifiDisplaySource::onReceiveM16Response(
- int32_t sessionID, const sp<ParsedMessage> &msg) {
+ int32_t sessionID, const sp<ParsedMessage> & /* msg */) {
// If only the response was required to include a "Session:" header...
CHECK_EQ(sessionID, mClientSessionID);
@@ -1680,7 +1680,7 @@ WifiDisplaySource::HDCPObserver::HDCPObserver(
}
void WifiDisplaySource::HDCPObserver::notify(
- int msg, int ext1, int ext2, const Parcel *obj) {
+ int msg, int ext1, int ext2, const Parcel * /* obj */) {
sp<AMessage> notify = mNotify->dup();
notify->setInt32("msg", msg);
notify->setInt32("ext1", ext1);
diff --git a/media/libstagefright/yuv/Android.mk b/media/libstagefright/yuv/Android.mk
index b3f7b1b..bb86dfc 100644
--- a/media/libstagefright/yuv/Android.mk
+++ b/media/libstagefright/yuv/Android.mk
@@ -12,5 +12,7 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_MODULE:= libstagefright_yuv
+LOCAL_CFLAGS += -Werror
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/yuv/YUVImage.cpp b/media/libstagefright/yuv/YUVImage.cpp
index 7b9000b..bb3e2fd 100644
--- a/media/libstagefright/yuv/YUVImage.cpp
+++ b/media/libstagefright/yuv/YUVImage.cpp
@@ -226,8 +226,8 @@ void YUVImage::fastCopyRectangle420Planar(
&ySrcOffsetIncrement, &uSrcOffsetIncrement, &vSrcOffsetIncrement);
int32_t yDestOffsetIncrement;
- int32_t uDestOffsetIncrement;
- int32_t vDestOffsetIncrement;
+ int32_t uDestOffsetIncrement = 0;
+ int32_t vDestOffsetIncrement = 0;
destImage.getOffsetIncrementsPerDataRow(
&yDestOffsetIncrement, &uDestOffsetIncrement, &vDestOffsetIncrement);
@@ -309,7 +309,7 @@ void YUVImage::fastCopyRectangle420SemiPlanar(
int32_t yDestOffsetIncrement;
int32_t uDestOffsetIncrement;
- int32_t vDestOffsetIncrement;
+ int32_t vDestOffsetIncrement = 0;
destImage.getOffsetIncrementsPerDataRow(
&yDestOffsetIncrement, &uDestOffsetIncrement, &vDestOffsetIncrement);
@@ -393,9 +393,9 @@ bool YUVImage::writeToPPM(const char *filename) const {
fprintf(fp, "255\n");
for (int32_t y = 0; y < mHeight; ++y) {
for (int32_t x = 0; x < mWidth; ++x) {
- uint8_t yValue;
- uint8_t uValue;
- uint8_t vValue;
+ uint8_t yValue = 0u;
+ uint8_t uValue = 0u;
+ uint8_t vValue = 0u;
getPixelValue(x, y, &yValue, &uValue, & vValue);
uint8_t rValue;