summaryrefslogtreecommitdiffstats
path: root/include/media
diff options
context:
space:
mode:
Diffstat (limited to 'include/media')
-rw-r--r--include/media/AudioTrack.h58
-rw-r--r--include/media/stagefright/MediaClock.h77
-rw-r--r--include/media/stagefright/MediaCodec.h13
-rw-r--r--include/media/stagefright/MediaCodecSource.h3
-rw-r--r--include/media/stagefright/foundation/ALooper.h21
-rw-r--r--include/media/stagefright/foundation/ALooperRoster.h9
-rw-r--r--include/media/stagefright/foundation/AMessage.h42
7 files changed, 186 insertions, 37 deletions
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 2e1ed6c..3de0774 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -63,7 +63,7 @@ public:
// See AudioTimestamp for the information included with event.
};
- /* Client should declare Buffer on the stack and pass address to obtainBuffer()
+ /* Client should declare a Buffer and pass the address to obtainBuffer()
* and releaseBuffer(). See also callback_t for EVENT_MORE_DATA.
*/
@@ -72,14 +72,20 @@ public:
public:
// FIXME use m prefix
size_t frameCount; // number of sample frames corresponding to size;
- // on input it is the number of frames desired,
- // on output is the number of frames actually filled
- // (currently ignored, but will make the primary field in future)
+ // on input to obtainBuffer() it is the number of frames desired,
+ // on output from obtainBuffer() it is the number of available
+ // [empty slots for] frames to be filled
+ // on input to releaseBuffer() it is currently ignored
size_t size; // input/output in bytes == frameCount * frameSize
- // on input it is unused
- // on output is the number of bytes actually filled
- // FIXME this is redundant with respect to frameCount.
+ // on input to obtainBuffer() it is ignored
+ // on output from obtainBuffer() it is the number of available
+ // [empty slots for] bytes to be filled,
+ // which is frameCount * frameSize
+ // on input to releaseBuffer() it is the number of bytes to
+ // release
+ // FIXME This is redundant with respect to frameCount. Consider
+ // removing size and making frameCount the primary field.
union {
void* raw;
@@ -484,10 +490,18 @@ public:
*/
status_t attachAuxEffect(int effectId);
- /* Obtains a buffer of up to "audioBuffer->frameCount" empty slots for frames.
+ /* Public API for TRANSFER_OBTAIN mode.
+ * Obtains a buffer of up to "audioBuffer->frameCount" empty slots for frames.
* After filling these slots with data, the caller should release them with releaseBuffer().
* If the track buffer is not full, obtainBuffer() returns as many contiguous
* [empty slots for] frames as are available immediately.
+ *
+ * If nonContig is non-NULL, it is an output parameter that will be set to the number of
+ * additional non-contiguous frames that are predicted to be available immediately,
+ * if the client were to release the first frames and then call obtainBuffer() again.
+ * This value is only a prediction, and needs to be confirmed.
+ * It will be set to zero for an error return.
+ *
* If the track buffer is full and track is stopped, obtainBuffer() returns WOULD_BLOCK
* regardless of the value of waitCount.
* If the track buffer is full and track is not stopped, obtainBuffer() blocks with a
@@ -496,7 +510,6 @@ public:
* is exhausted, at which point obtainBuffer() will either block
* or return WOULD_BLOCK depending on the value of the "waitCount"
* parameter.
- * Each sample is 16-bit signed PCM.
*
* obtainBuffer() and releaseBuffer() are deprecated for direct use by applications,
* which should use write() or callback EVENT_MORE_DATA instead.
@@ -508,24 +521,29 @@ public:
*
* Buffer fields
* On entry:
- * frameCount number of frames requested
+ * frameCount number of [empty slots for] frames requested
+ * size ignored
+ * raw ignored
* After error return:
* frameCount 0
* size 0
* raw undefined
* After successful return:
- * frameCount actual number of frames available, <= number requested
+ * frameCount actual number of [empty slots for] frames available, <= number requested
* size actual number of bytes available
* raw pointer to the buffer
*/
-
/* FIXME Deprecated public API for TRANSFER_OBTAIN mode */
- status_t obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
+ status_t obtainBuffer(Buffer* audioBuffer, int32_t waitCount,
+ size_t *nonContig = NULL)
__attribute__((__deprecated__));
private:
/* If nonContig is non-NULL, it is an output parameter that will be set to the number of
- * additional non-contiguous frames that are available immediately.
+ * additional non-contiguous frames that are predicted to be available immediately,
+ * if the client were to release the first frames and then call obtainBuffer() again.
+ * This value is only a prediction, and needs to be confirmed.
+ * It will be set to zero for an error return.
* FIXME We could pass an array of Buffers instead of only one Buffer to obtainBuffer(),
* in case the requested amount of frames is in two or more non-contiguous regions.
* FIXME requested and elapsed are both relative times. Consider changing to absolute time.
@@ -534,9 +552,17 @@ private:
struct timespec *elapsed = NULL, size_t *nonContig = NULL);
public:
- /* Release a filled buffer of "audioBuffer->frameCount" frames for AudioFlinger to process. */
+ /* Public API for TRANSFER_OBTAIN mode.
+ * Release a filled buffer of frames for AudioFlinger to process.
+ *
+ * Buffer fields:
+ * frameCount currently ignored but recommend to set to actual number of frames filled
+ * size actual number of bytes filled, must be multiple of frameSize
+ * raw ignored
+ *
+ */
// FIXME make private when obtainBuffer() for TRANSFER_OBTAIN is removed
- void releaseBuffer(Buffer* audioBuffer);
+ void releaseBuffer(const Buffer* audioBuffer);
/* As a convenience we provide a write() interface to the audio buffer.
* Input parameter 'size' is in byte units.
diff --git a/include/media/stagefright/MediaClock.h b/include/media/stagefright/MediaClock.h
new file mode 100644
index 0000000..660764f
--- /dev/null
+++ b/include/media/stagefright/MediaClock.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2015 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 MEDIA_CLOCK_H_
+
+#define MEDIA_CLOCK_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/Mutex.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+struct AMessage;
+
+struct MediaClock : public RefBase {
+ MediaClock();
+
+ void setStartingTimeMedia(int64_t startingTimeMediaUs);
+
+ void clearAnchor();
+ // It's required to use timestamp of just rendered frame as
+ // anchor time in paused state.
+ void updateAnchor(
+ int64_t anchorTimeMediaUs,
+ int64_t anchorTimeRealUs,
+ int64_t maxTimeMediaUs = INT64_MAX);
+
+ void updateMaxTimeMedia(int64_t maxTimeMediaUs);
+
+ void setPlaybackRate(float rate);
+
+ // query media time corresponding to real time |realUs|, and save the
+ // result in |outMediaUs|.
+ status_t getMediaTime(int64_t realUs,
+ int64_t *outMediaUs,
+ bool allowPastMaxTime = false);
+ // query real time corresponding to media time |targetMediaUs|.
+ // The result is saved in |outRealUs|.
+ status_t getRealTimeFor(int64_t targetMediaUs, int64_t *outRealUs);
+
+protected:
+ virtual ~MediaClock();
+
+private:
+ status_t getMediaTime_l(int64_t realUs,
+ int64_t *outMediaUs,
+ bool allowPastMaxTime);
+
+ Mutex mLock;
+
+ int64_t mAnchorTimeMediaUs;
+ int64_t mAnchorTimeRealUs;
+ int64_t mMaxTimeMediaUs;
+ int64_t mStartingTimeMediaUs;
+
+ float mPlaybackRate;
+
+ DISALLOW_EVIL_CONSTRUCTORS(MediaClock);
+};
+
+} // namespace android
+
+#endif // MEDIA_CLOCK_H_
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index d448097..8241e19 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -27,6 +27,7 @@ namespace android {
struct ABuffer;
struct AMessage;
+struct AReplyToken;
struct AString;
struct CodecBase;
struct ICrypto;
@@ -222,7 +223,7 @@ private:
sp<ALooper> mCodecLooper;
sp<CodecBase> mCodec;
AString mComponentName;
- uint32_t mReplyID;
+ sp<AReplyToken> mReplyID;
uint32_t mFlags;
status_t mStickyError;
sp<Surface> mNativeWindow;
@@ -249,10 +250,10 @@ private:
Vector<BufferInfo> mPortBuffers[2];
int32_t mDequeueInputTimeoutGeneration;
- uint32_t mDequeueInputReplyID;
+ sp<AReplyToken> mDequeueInputReplyID;
int32_t mDequeueOutputTimeoutGeneration;
- uint32_t mDequeueOutputReplyID;
+ sp<AReplyToken> mDequeueOutputReplyID;
sp<ICrypto> mCrypto;
@@ -267,7 +268,7 @@ private:
static status_t PostAndAwaitResponse(
const sp<AMessage> &msg, sp<AMessage> *response);
- static void PostReplyWithError(int32_t replyID, int32_t err);
+ static void PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err);
status_t init(const AString &name, bool nameIsType, bool encoder);
@@ -283,8 +284,8 @@ private:
size_t portIndex, size_t index,
sp<ABuffer> *buffer, sp<AMessage> *format);
- bool handleDequeueInputBuffer(uint32_t replyID, bool newRequest = false);
- bool handleDequeueOutputBuffer(uint32_t replyID, bool newRequest = false);
+ bool handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest = false);
+ bool handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest = false);
void cancelPendingDequeueOperations();
void extractCSD(const sp<AMessage> &format);
diff --git a/include/media/stagefright/MediaCodecSource.h b/include/media/stagefright/MediaCodecSource.h
index 0970b2b..7b8f59d 100644
--- a/include/media/stagefright/MediaCodecSource.h
+++ b/include/media/stagefright/MediaCodecSource.h
@@ -25,6 +25,7 @@ namespace android {
class ALooper;
class AMessage;
+struct AReplyToken;
class IGraphicBufferProducer;
class MediaCodec;
class MetaData;
@@ -99,7 +100,7 @@ private:
sp<Puller> mPuller;
sp<MediaCodec> mEncoder;
uint32_t mFlags;
- List<uint32_t> mStopReplyIDQueue;
+ List<sp<AReplyToken>> mStopReplyIDQueue;
bool mIsVideo;
bool mStarted;
bool mStopping;
diff --git a/include/media/stagefright/foundation/ALooper.h b/include/media/stagefright/foundation/ALooper.h
index 150cdba..09c469b 100644
--- a/include/media/stagefright/foundation/ALooper.h
+++ b/include/media/stagefright/foundation/ALooper.h
@@ -30,6 +30,7 @@ namespace android {
struct AHandler;
struct AMessage;
+struct AReplyToken;
struct ALooper : public RefBase {
typedef int32_t event_id;
@@ -79,7 +80,27 @@ private:
sp<LooperThread> mThread;
bool mRunningLocally;
+ // use a separate lock for reply handling, as it is always on another thread
+ // use a central lock, however, to avoid creating a mutex for each reply
+ Mutex mRepliesLock;
+ Condition mRepliesCondition;
+
+ // START --- methods used only by AMessage
+
+ // posts a message on this looper with the given timeout
void post(const sp<AMessage> &msg, int64_t delayUs);
+
+ // creates a reply token to be used with this looper
+ sp<AReplyToken> createReplyToken();
+ // waits for a response for the reply token. If status is OK, the response
+ // is stored into the supplied variable. Otherwise, it is unchanged.
+ status_t awaitResponse(const sp<AReplyToken> &replyToken, sp<AMessage> *response);
+ // posts a reply for a reply token. If the reply could be successfully posted,
+ // it returns OK. Otherwise, it returns an error value.
+ status_t postReply(const sp<AReplyToken> &replyToken, const sp<AMessage> &msg);
+
+ // END --- methods used only by AMessage
+
bool loop();
DISALLOW_EVIL_CONSTRUCTORS(ALooper);
diff --git a/include/media/stagefright/foundation/ALooperRoster.h b/include/media/stagefright/foundation/ALooperRoster.h
index 96bce6b..9912455 100644
--- a/include/media/stagefright/foundation/ALooperRoster.h
+++ b/include/media/stagefright/foundation/ALooperRoster.h
@@ -33,11 +33,6 @@ struct ALooperRoster {
void unregisterHandler(ALooper::handler_id handlerID);
void unregisterStaleHandlers();
- status_t postAndAwaitResponse(
- const sp<AMessage> &msg, sp<AMessage> *response);
-
- void postReply(uint32_t replyID, const sp<AMessage> &reply);
-
void dump(int fd, const Vector<String16>& args);
private:
@@ -49,10 +44,6 @@ private:
Mutex mLock;
KeyedVector<ALooper::handler_id, HandlerInfo> mHandlers;
ALooper::handler_id mNextHandlerID;
- uint32_t mNextReplyID;
- Condition mRepliesCondition;
-
- KeyedVector<uint32_t, sp<AMessage> > mReplies;
DISALLOW_EVIL_CONSTRUCTORS(ALooperRoster);
};
diff --git a/include/media/stagefright/foundation/AMessage.h b/include/media/stagefright/foundation/AMessage.h
index ab3279d..4c6bd21 100644
--- a/include/media/stagefright/foundation/AMessage.h
+++ b/include/media/stagefright/foundation/AMessage.h
@@ -30,6 +30,34 @@ struct AHandler;
struct AString;
struct Parcel;
+struct AReplyToken : public RefBase {
+ AReplyToken(const sp<ALooper> &looper)
+ : mLooper(looper),
+ mReplied(false) {
+ }
+
+private:
+ friend struct AMessage;
+ friend struct ALooper;
+ wp<ALooper> mLooper;
+ sp<AMessage> mReply;
+ bool mReplied;
+
+ sp<ALooper> getLooper() const {
+ return mLooper.promote();
+ }
+ // if reply is not set, returns false; otherwise, it retrieves the reply and returns true
+ bool retrieveReply(sp<AMessage> *reply) {
+ if (mReplied) {
+ *reply = mReply;
+ mReply.clear();
+ }
+ return mReplied;
+ }
+ // sets the reply for this token. returns OK or error
+ status_t setReply(const sp<AMessage> &reply);
+};
+
struct AMessage : public RefBase {
AMessage();
AMessage(uint32_t what, const sp<const AHandler> &handler);
@@ -84,11 +112,15 @@ struct AMessage : public RefBase {
status_t postAndAwaitResponse(sp<AMessage> *response);
// If this returns true, the sender of this message is synchronously
- // awaiting a response, the "replyID" can be used to send the response
- // via "postReply" below.
- bool senderAwaitsResponse(uint32_t *replyID) const;
-
- void postReply(uint32_t replyID);
+ // awaiting a response and the reply token is consumed from the message
+ // and stored into replyID. The reply token must be used to send the response
+ // using "postReply" below.
+ bool senderAwaitsResponse(sp<AReplyToken> *replyID);
+
+ // Posts the message as a response to a reply token. A reply token can
+ // only be used once. Returns OK if the response could be posted; otherwise,
+ // an error.
+ status_t postReply(const sp<AReplyToken> &replyID);
// Performs a deep-copy of "this", contained messages are in turn "dup'ed".
// Warning: RefBase items, i.e. "objects" are _not_ copied but only have