summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
Diffstat (limited to 'media')
-rw-r--r--media/libmedia/MediaProfiles.cpp18
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp15
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.cpp10
-rw-r--r--media/libmediaplayerservice/nuplayer/Android.mk1
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp74
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.h2
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp6
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerSource.h1
-rw-r--r--media/libstagefright/AudioSource.cpp2
-rw-r--r--media/mtp/Android.mk3
-rw-r--r--media/mtp/MtpUtils.cpp3
11 files changed, 124 insertions, 11 deletions
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index e9e453b..d2e181b 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -81,6 +81,12 @@ const MediaProfiles::NameToTagMap MediaProfiles::sCamcorderQualityNameMap[] = {
{"timelapse1080p", CAMCORDER_QUALITY_TIME_LAPSE_1080P},
{"timelapse2160p", CAMCORDER_QUALITY_TIME_LAPSE_2160P},
{"timelapseqvga", CAMCORDER_QUALITY_TIME_LAPSE_QVGA},
+
+ {"highspeedlow", CAMCORDER_QUALITY_HIGH_SPEED_LOW},
+ {"highspeedhigh", CAMCORDER_QUALITY_HIGH_SPEED_HIGH},
+ {"highspeed480p", CAMCORDER_QUALITY_HIGH_SPEED_480P},
+ {"highspeed720p", CAMCORDER_QUALITY_HIGH_SPEED_720P},
+ {"highspeed1080p", CAMCORDER_QUALITY_HIGH_SPEED_1080P},
};
#if LOG_NDEBUG
@@ -474,6 +480,11 @@ static bool isTimelapseProfile(camcorder_quality quality) {
quality <= CAMCORDER_QUALITY_TIME_LAPSE_LIST_END;
}
+static bool isHighSpeedProfile(camcorder_quality quality) {
+ return quality >= CAMCORDER_QUALITY_HIGH_SPEED_LIST_START &&
+ quality <= CAMCORDER_QUALITY_HIGH_SPEED_LIST_END;
+}
+
void MediaProfiles::initRequiredProfileRefs(const Vector<int>& cameraIds) {
ALOGV("Number of camera ids: %zu", cameraIds.size());
CHECK(cameraIds.size() > 0);
@@ -521,14 +532,17 @@ void MediaProfiles::checkAndAddRequiredProfilesIfNecessary() {
camcorder_quality refQuality;
VideoCodec *codec = NULL;
- // Check high and low from either camcorder profile or timelapse profile
- // but not both. Default, check camcorder profile
+ // Check high and low from either camcorder profile, timelapse profile
+ // or high speed profile, but not all of them. Default, check camcorder profile
size_t j = 0;
size_t o = 2;
if (isTimelapseProfile(quality)) {
// Check timelapse profile instead.
j = 2;
o = kNumRequiredProfiles;
+ } else if (isHighSpeedProfile(quality)) {
+ // Skip the check for high speed profile.
+ continue;
} else {
// Must be camcorder profile.
CHECK(isCamcorderProfile(quality));
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 7218467..735344c 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -34,6 +34,7 @@
#include <utils/misc.h>
+#include <binder/IBatteryStats.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/MemoryHeapBase.h>
@@ -275,6 +276,20 @@ MediaPlayerService::MediaPlayerService()
// speaker is on by default
mBatteryAudio.deviceOn[SPEAKER] = 1;
+ // reset battery stats
+ // if the mediaserver has crashed, battery stats could be left
+ // in bad state, reset the state upon service start.
+ const sp<IServiceManager> sm(defaultServiceManager());
+ if (sm != NULL) {
+ const String16 name("batterystats");
+ sp<IBatteryStats> batteryStats =
+ interface_cast<IBatteryStats>(sm->getService(name));
+ if (batteryStats != NULL) {
+ batteryStats->noteResetVideo();
+ batteryStats->noteResetAudio();
+ }
+ }
+
MediaPlayerFactory::registerBuiltinFactories();
}
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 217b248..8774117 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -1551,10 +1551,10 @@ status_t StagefrightRecorder::setupMPEG4orWEBMRecording() {
status_t err = OK;
sp<MediaWriter> writer;
- if (mOutputFormat == OUTPUT_FORMAT_MPEG_4) {
- writer = new MPEG4Writer(mOutputFd);
- } else {
+ if (mOutputFormat == OUTPUT_FORMAT_WEBM) {
writer = new WebmWriter(mOutputFd);
+ } else {
+ writer = new MPEG4Writer(mOutputFd);
}
if (mVideoSource < VIDEO_SOURCE_LIST_END) {
@@ -1575,7 +1575,7 @@ status_t StagefrightRecorder::setupMPEG4orWEBMRecording() {
mTotalBitRate += mVideoBitRate;
}
- if (mOutputFormat == OUTPUT_FORMAT_MPEG_4) {
+ if (mOutputFormat != OUTPUT_FORMAT_WEBM) {
// Audio source is added at the end if it exists.
// This help make sure that the "recoding" sound is suppressed for
// camcorder applications in the recorded files.
@@ -1625,7 +1625,7 @@ void StagefrightRecorder::setupMPEG4orWEBMMetaData(sp<MetaData> *meta) {
if (mMovieTimeScale > 0) {
(*meta)->setInt32(kKeyTimeScale, mMovieTimeScale);
}
- if (mOutputFormat == OUTPUT_FORMAT_MPEG_4) {
+ if (mOutputFormat != OUTPUT_FORMAT_WEBM) {
(*meta)->setInt32(kKey64BitFileOffset, mUse64BitFileOffset);
if (mTrackEveryTimeDurationUs > 0) {
(*meta)->setInt64(kKeyTrackTimeStatus, mTrackEveryTimeDurationUs);
diff --git a/media/libmediaplayerservice/nuplayer/Android.mk b/media/libmediaplayerservice/nuplayer/Android.mk
index 25002e3..0dd2b61 100644
--- a/media/libmediaplayerservice/nuplayer/Android.mk
+++ b/media/libmediaplayerservice/nuplayer/Android.mk
@@ -18,6 +18,7 @@ LOCAL_C_INCLUDES := \
$(TOP)/frameworks/av/media/libstagefright/include \
$(TOP)/frameworks/av/media/libstagefright/mpeg2ts \
$(TOP)/frameworks/av/media/libstagefright/rtsp \
+ $(TOP)/frameworks/av/media/libstagefright/timedtext \
$(TOP)/frameworks/native/include/media/openmax
LOCAL_MODULE:= libstagefright_nuplayer
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index fa6b1e5..d144af1 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -29,6 +29,7 @@
#include "RTSPSource.h"
#include "StreamingSource.h"
#include "GenericSource.h"
+#include "TextDescriptions.h"
#include "ATSParser.h"
@@ -151,6 +152,7 @@ NuPlayer::NuPlayer()
mScanSourcesPending(false),
mScanSourcesGeneration(0),
mPollDurationGeneration(0),
+ mTimedTextGeneration(0),
mTimeDiscontinuityPending(false),
mFlushingAudio(NONE),
mFlushingVideo(NONE),
@@ -428,6 +430,16 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
if (trackIndex < inbandTracks) {
err = mSource->selectTrack(trackIndex, select);
+
+ if (!select && err == OK) {
+ int32_t type;
+ sp<AMessage> info = mSource->getTrackInfo(trackIndex);
+ if (info != NULL
+ && info->findInt32("type", &type)
+ && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
+ ++mTimedTextGeneration;
+ }
+ }
} else {
trackIndex -= inbandTracks;
@@ -1492,6 +1504,7 @@ void NuPlayer::performSeek(int64_t seekTimeUs) {
seekTimeUs / 1E6);
mSource->seekTo(seekTimeUs);
+ ++mTimedTextGeneration;
if (mDriver != NULL) {
sp<NuPlayerDriver> driver = mDriver.promote();
@@ -1700,6 +1713,39 @@ void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
break;
}
+ case Source::kWhatTimedTextData:
+ {
+ int32_t generation;
+ if (msg->findInt32("generation", &generation)
+ && generation != mTimedTextGeneration) {
+ break;
+ }
+
+ sp<ABuffer> buffer;
+ CHECK(msg->findBuffer("buffer", &buffer));
+
+ sp<NuPlayerDriver> driver = mDriver.promote();
+ if (driver == NULL) {
+ break;
+ }
+
+ int posMs;
+ int64_t timeUs, posUs;
+ driver->getCurrentPosition(&posMs);
+ posUs = posMs * 1000;
+ CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
+
+ if (posUs < timeUs) {
+ if (!msg->findInt32("generation", &generation)) {
+ msg->setInt32("generation", mTimedTextGeneration);
+ }
+ msg->post(timeUs - posUs);
+ } else {
+ sendTimedTextData(buffer);
+ }
+ break;
+ }
+
case Source::kWhatQueueDecoderShutdown:
{
int32_t audio, video;
@@ -1768,6 +1814,34 @@ void NuPlayer::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in);
}
+
+void NuPlayer::sendTimedTextData(const sp<ABuffer> &buffer) {
+ const void *data;
+ size_t size = 0;
+ int64_t timeUs;
+ int32_t flag = TextDescriptions::LOCAL_DESCRIPTIONS;
+
+ AString mime;
+ CHECK(buffer->meta()->findString("mime", &mime));
+ CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
+
+ data = buffer->data();
+ size = buffer->size();
+
+ Parcel parcel;
+ if (size > 0) {
+ CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
+ flag |= TextDescriptions::IN_BAND_TEXT_3GPP;
+ TextDescriptions::getParcelOfDescriptions(
+ (const uint8_t *)data, size, flag, timeUs / 1000, &parcel);
+ }
+
+ if ((parcel.dataSize() > 0)) {
+ notifyListener(MEDIA_TIMED_TEXT, 0, 0, &parcel);
+ } else { // send an empty timed text
+ notifyListener(MEDIA_TIMED_TEXT, 0, 0);
+ }
+}
////////////////////////////////////////////////////////////////////////////////
void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index c04e277..8bcf10e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -136,6 +136,7 @@ private:
int32_t mScanSourcesGeneration;
int32_t mPollDurationGeneration;
+ int32_t mTimedTextGeneration;
enum FlushStatus {
NONE,
@@ -198,6 +199,7 @@ private:
bool audio, bool video, const sp<AMessage> &reply);
void sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex);
+ void sendTimedTextData(const sp<ABuffer> &buffer);
void writeTrackInfo(Parcel* reply, const sp<AMessage> format) const;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 1b9bafb..8fce2f4 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -155,8 +155,14 @@ void NuPlayer::Decoder::releaseAndResetMediaBuffers() {
}
}
mMediaBuffers.resize(mInputBuffers.size());
+ for (size_t i = 0; i < mMediaBuffers.size(); i++) {
+ mMediaBuffers.editItemAt(i) = NULL;
+ }
mInputBufferIsDequeued.clear();
mInputBufferIsDequeued.resize(mInputBuffers.size());
+ for (size_t i = 0; i < mInputBufferIsDequeued.size(); i++) {
+ mInputBufferIsDequeued.editItemAt(i) = false;
+ }
}
void NuPlayer::Decoder::requestCodecNotification() {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
index 259925f..0ec017e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
@@ -47,6 +47,7 @@ struct NuPlayer::Source : public AHandler {
kWhatBufferingStart,
kWhatBufferingEnd,
kWhatSubtitleData,
+ kWhatTimedTextData,
kWhatQueueDecoderShutdown,
};
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index d9aed01..a67fabe 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -159,6 +159,8 @@ status_t AudioSource::reset() {
waitOutstandingEncodingFrames_l();
releaseQueuedFrames_l();
+ mFrameAvailableCondition.signal();
+
return OK;
}
diff --git a/media/mtp/Android.mk b/media/mtp/Android.mk
index ac608a1..3af0956 100644
--- a/media/mtp/Android.mk
+++ b/media/mtp/Android.mk
@@ -39,9 +39,6 @@ LOCAL_MODULE:= libmtp
LOCAL_CFLAGS := -DMTP_DEVICE -DMTP_HOST
-# Needed for <bionic_time.h>
-LOCAL_C_INCLUDES := bionic/libc/private
-
LOCAL_SHARED_LIBRARIES := libutils libcutils liblog libusbhost libbinder
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/mtp/MtpUtils.cpp b/media/mtp/MtpUtils.cpp
index 6ec8876..0667bdd 100644
--- a/media/mtp/MtpUtils.cpp
+++ b/media/mtp/MtpUtils.cpp
@@ -19,7 +19,8 @@
#include <stdio.h>
#include <time.h>
-#include <cutils/tztime.h>
+#include <../private/bionic_time.h> /* TODO: switch this code to icu4c! */
+
#include "MtpUtils.h"
namespace android {