Expand mediaextractor dumpsys
Bug: 22775369
Change-Id: I3366a52ba7a00d1685a2211465f2f18f143d0efc
diff --git a/include/media/IDataSource.h b/include/media/IDataSource.h
index 09009f0..838e29f 100644
--- a/include/media/IDataSource.h
+++ b/include/media/IDataSource.h
@@ -20,6 +20,7 @@
#include <binder/IInterface.h>
#include <media/stagefright/foundation/ABase.h>
#include <utils/Errors.h>
+#include <utils/String8.h>
namespace android {
@@ -44,6 +45,8 @@
// Get the flags of the source.
// Refer to DataSource:Flags for the definition of the flags.
virtual uint32_t getFlags() = 0;
+ // get a description of the source, e.g. the url or filename it is based on
+ virtual String8 toString() = 0;
private:
DISALLOW_EVIL_CONSTRUCTORS(IDataSource);
diff --git a/include/media/IMediaExtractor.h b/include/media/IMediaExtractor.h
index 9f7a719..d9fcd89 100644
--- a/include/media/IMediaExtractor.h
+++ b/include/media/IMediaExtractor.h
@@ -19,6 +19,7 @@
#define IMEDIA_EXTRACTOR_BASE_H_
#include <media/IMediaSource.h>
+#include <media/IDataSource.h>
namespace android {
@@ -69,6 +70,17 @@
uint32_t flags = 0);
};
+void registerMediaExtractor(
+ const sp<IMediaExtractor> &extractor,
+ const sp<IDataSource> &source,
+ const char *mime);
+
+void registerMediaSource(
+ const sp<IMediaExtractor> &extractor,
+ const sp<IMediaSource> &source);
+
+status_t dumpExtractors(int fd, const Vector<String16>& args);
+
} // namespace android
diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h
index c5e09c0..c5df1f6 100644
--- a/include/media/stagefright/DataSource.h
+++ b/include/media/stagefright/DataSource.h
@@ -78,6 +78,10 @@
return 0;
}
+ virtual String8 toString() {
+ return String8("<unspecified>");
+ }
+
virtual status_t reconnectAtOffset(off64_t offset) {
return ERROR_UNSUPPORTED;
}
diff --git a/include/media/stagefright/FileSource.h b/include/media/stagefright/FileSource.h
index 266168b..b6349e0 100644
--- a/include/media/stagefright/FileSource.h
+++ b/include/media/stagefright/FileSource.h
@@ -43,6 +43,10 @@
virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client);
+ virtual String8 toString() {
+ return mName;
+ }
+
protected:
virtual ~FileSource();
@@ -51,6 +55,7 @@
int64_t mOffset;
int64_t mLength;
Mutex mLock;
+ String8 mName;
/*for DRM*/
sp<DecryptHandle> mDecryptHandle;
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index a9ae49b..4f7426d 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -258,6 +258,7 @@
bool hasData(uint32_t key) const;
+ String8 toString() const;
void dumpToLog() const;
status_t writeToParcel(Parcel &parcel);
@@ -278,7 +279,8 @@
void clear();
void setData(uint32_t type, const void *data, size_t size);
void getData(uint32_t *type, const void **data, size_t *size) const;
- String8 asString() const;
+ // may include hexdump of binary data if verbose=true
+ String8 asString(bool verbose) const;
private:
uint32_t mType;
diff --git a/media/libmedia/IDataSource.cpp b/media/libmedia/IDataSource.cpp
index ac864a4..7aeba5a 100644
--- a/media/libmedia/IDataSource.cpp
+++ b/media/libmedia/IDataSource.cpp
@@ -33,6 +33,7 @@
GET_SIZE,
CLOSE,
GET_FLAGS,
+ TO_STRING,
};
struct BpDataSource : public BpInterface<IDataSource> {
@@ -76,6 +77,13 @@
remote()->transact(GET_FLAGS, data, &reply);
return reply.readUint32();
}
+
+ virtual String8 toString() {
+ Parcel data, reply;
+ data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
+ remote()->transact(TO_STRING, data, &reply);
+ return reply.readString8();
+ }
};
IMPLEMENT_META_INTERFACE(DataSource, "android.media.IDataSource");
@@ -113,6 +121,12 @@
reply->writeUint32(getFlags());
return NO_ERROR;
} break;
+ case TO_STRING: {
+ CHECK_INTERFACE(IDataSource, data, reply);
+ reply->writeString8(toString());
+ return NO_ERROR;
+ } break;
+
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libmedia/IMediaExtractor.cpp b/media/libmedia/IMediaExtractor.cpp
index 76d5648..b13b69f 100644
--- a/media/libmedia/IMediaExtractor.cpp
+++ b/media/libmedia/IMediaExtractor.cpp
@@ -21,6 +21,7 @@
#include <stdint.h>
#include <sys/types.h>
+#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
#include <media/IMediaExtractor.h>
#include <media/stagefright/MetaData.h>
@@ -145,7 +146,9 @@
CHECK_INTERFACE(IMediaExtractor, data, reply);
uint32_t idx;
if (data.readUint32(&idx) == NO_ERROR) {
- return reply->writeStrongBinder(IInterface::asBinder(getTrack((size_t(idx)))));
+ const sp<IMediaSource> track = getTrack(size_t(idx));
+ registerMediaSource(this, track);
+ return reply->writeStrongBinder(IInterface::asBinder(track));
}
return UNKNOWN_ERROR;
}
@@ -177,6 +180,90 @@
}
}
+typedef struct {
+ String8 mime;
+ String8 name;
+ String8 sourceDescription;
+ pid_t owner;
+ wp<IMediaExtractor> extractor;
+ Vector<wp<IMediaSource>> tracks;
+ Vector<String8> trackDescriptions;
+ String8 toString() const;
+} ExtractorInstance;
+
+String8 ExtractorInstance::toString() const {
+ String8 str = name;
+ str.append(" for mime ");
+ str.append(mime);
+ str.append(", source ");
+ str.append(sourceDescription);
+ str.append(String8::format(", pid %d: ", owner));
+ if (extractor.promote() == NULL) {
+ str.append("deleted\n");
+ } else {
+ str.append("active\n");
+ }
+ for (size_t i = 0; i < tracks.size(); i++) {
+ const String8 desc = trackDescriptions.itemAt(i);
+ str.appendFormat(" track {%s} ", desc.string());
+ const sp<IMediaSource> source = tracks.itemAt(i).promote();
+ if (source == NULL) {
+ str.append(": deleted\n");
+ } else {
+ str.appendFormat(": active\n");
+ }
+ }
+ return str;
+}
+
+static Vector<ExtractorInstance> extractors;
+
+void registerMediaSource(
+ const sp<IMediaExtractor> &ex,
+ const sp<IMediaSource> &source) {
+ for (size_t i = 0; i < extractors.size(); i++) {
+ ExtractorInstance &instance = extractors.editItemAt(i);
+ sp<IMediaExtractor> extractor = instance.extractor.promote();
+ if (extractor != NULL && extractor == ex) {
+ if (instance.tracks.size() > 5) {
+ instance.tracks.resize(5);
+ }
+ instance.tracks.push_front(source);
+ instance.trackDescriptions.add(source->getFormat()->toString());
+ break;
+ }
+ }
+}
+
+void registerMediaExtractor(
+ const sp<IMediaExtractor> &extractor,
+ const sp<IDataSource> &source,
+ const char *mime) {
+ ExtractorInstance ex;
+ ex.mime = mime == NULL ? "NULL" : mime;
+ ex.name = extractor->name();
+ ex.sourceDescription = source->toString();
+ ex.owner = IPCThreadState::self()->getCallingPid();
+ ex.extractor = extractor;
+
+ if (extractors.size() > 10) {
+ extractors.resize(10);
+ }
+ extractors.push_front(ex);
+}
+
+status_t dumpExtractors(int fd, const Vector<String16>&) {
+ String8 out;
+ out.append("Recent extractors, most recent first:\n");
+ for (size_t i = 0; i < extractors.size(); i++) {
+ const ExtractorInstance &instance = extractors.itemAt(i);
+ out.append(" ");
+ out.append(instance.toString());
+ }
+ write(fd, out.string(), out.size());
+ return OK;
+}
+
} // namespace android
diff --git a/media/libstagefright/CallbackDataSource.cpp b/media/libstagefright/CallbackDataSource.cpp
index bcbd78d..f14d34d 100644
--- a/media/libstagefright/CallbackDataSource.cpp
+++ b/media/libstagefright/CallbackDataSource.cpp
@@ -34,6 +34,8 @@
mIsClosed(false) {
// Set up the buffer to read into.
mMemory = mIDataSource->getIMemory();
+ mName = String8::format("CallbackDataSource(%s)", mIDataSource->toString().string());
+
}
CallbackDataSource::~CallbackDataSource() {
@@ -109,6 +111,7 @@
TinyCacheSource::TinyCacheSource(const sp<DataSource>& source)
: mSource(source), mCachedOffset(0), mCachedSize(0) {
+ mName = String8::format("TinyCacheSource(%s)", mSource->toString().string());
}
status_t TinyCacheSource::initCheck() const {
diff --git a/media/libstagefright/FileSource.cpp b/media/libstagefright/FileSource.cpp
index 52688b1..5b92f91 100644
--- a/media/libstagefright/FileSource.cpp
+++ b/media/libstagefright/FileSource.cpp
@@ -33,12 +33,16 @@
: mFd(-1),
mOffset(0),
mLength(-1),
+ mName("<null>"),
mDecryptHandle(NULL),
mDrmManagerClient(NULL),
mDrmBufOffset(0),
mDrmBufSize(0),
mDrmBuf(NULL){
+ if (filename) {
+ mName = String8::format("FileSource(%s)", filename);
+ }
ALOGV("%s", filename);
mFd = open(filename, O_LARGEFILE | O_RDONLY);
@@ -53,6 +57,7 @@
: mFd(fd),
mOffset(offset),
mLength(length),
+ mName("<null>"),
mDecryptHandle(NULL),
mDrmManagerClient(NULL),
mDrmBufOffset(0),
@@ -85,6 +90,13 @@
(long long) offset, (long long) length,
(long long) mOffset, (long long) mLength);
}
+
+ mName = String8::format(
+ "FileSource(fd(%s), %lld, %lld)",
+ nameForFd(fd).c_str(),
+ (long long) mOffset,
+ (long long) mLength);
+
}
FileSource::~FileSource() {
diff --git a/media/libstagefright/HTTPBase.cpp b/media/libstagefright/HTTPBase.cpp
index 068a77f..0f24329 100644
--- a/media/libstagefright/HTTPBase.cpp
+++ b/media/libstagefright/HTTPBase.cpp
@@ -38,6 +38,7 @@
mPrevBandwidthMeasureTimeUs(0),
mPrevEstimatedBandWidthKbps(0),
mBandWidthCollectFreqMs(5000) {
+ mName = String8("HTTPBase(<disconnected>)");
}
void HTTPBase::addBandwidthMeasurement(
diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp
index fe66a58..1c6c882 100644
--- a/media/libstagefright/MediaExtractor.cpp
+++ b/media/libstagefright/MediaExtractor.cpp
@@ -87,10 +87,12 @@
virtual status_t getSize(off64_t* size);
virtual void close();
virtual uint32_t getFlags();
+ virtual String8 toString();
private:
sp<IMemory> mMemory;
sp<DataSource> mSource;
+ String8 mName;
RemoteDataSource(const sp<DataSource> &source);
DISALLOW_EVIL_CONSTRUCTORS(RemoteDataSource);
};
@@ -106,6 +108,7 @@
if (mMemory == NULL) {
ALOGE("Failed to allocate memory!");
}
+ mName = String8::format("RemoteDataSource(%s)", mSource->toString().string());
}
RemoteDataSource::~RemoteDataSource() {
close();
@@ -127,6 +130,10 @@
return mSource->flags();
}
+String8 RemoteDataSource::toString() {
+ return mName;
+}
+
// static
sp<IMediaExtractor> MediaExtractor::Create(
const sp<DataSource> &source, const char *mime) {
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index d6255d6..453db03 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -224,6 +224,8 @@
// 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 */);
+
+ mName = String8::format("NuCachedSource2(%s)", mSource->toString().string());
}
NuCachedSource2::~NuCachedSource2() {
diff --git a/media/libstagefright/foundation/MetaData.cpp b/media/libstagefright/foundation/MetaData.cpp
index b847eed..b4abc60 100644
--- a/media/libstagefright/foundation/MetaData.cpp
+++ b/media/libstagefright/foundation/MetaData.cpp
@@ -316,7 +316,7 @@
mSize = 0;
}
-String8 MetaData::typed_data::asString() const {
+String8 MetaData::typed_data::asString(bool verbose) const {
String8 out;
const void *data = storage();
switch(mType) {
@@ -348,7 +348,7 @@
default:
out = String8::format("(unknown type %d, size %zu)", mType, mSize);
- if (mSize <= 48) { // if it's less than three lines of hex data, dump it
+ if (verbose && mSize <= 48) { // if it's less than three lines of hex data, dump it
AString foo;
hexdump(data, mSize, 0, &foo);
out.append("\n");
@@ -367,13 +367,27 @@
s[4] = '\0';
}
+String8 MetaData::toString() const {
+ String8 s;
+ for (int i = mItems.size(); --i >= 0;) {
+ int32_t key = mItems.keyAt(i);
+ char cc[5];
+ MakeFourCCString(key, cc);
+ const typed_data &item = mItems.valueAt(i);
+ s.appendFormat("%s: %s", cc, item.asString(false).string());
+ if (i != 0) {
+ s.append(", ");
+ }
+ }
+ return s;
+}
void MetaData::dumpToLog() const {
for (int i = mItems.size(); --i >= 0;) {
int32_t key = mItems.keyAt(i);
char cc[5];
MakeFourCCString(key, cc);
const typed_data &item = mItems.valueAt(i);
- ALOGI("%s: %s", cc, item.asString().string());
+ ALOGI("%s: %s", cc, item.asString(true /* verbose */).string());
}
}
diff --git a/media/libstagefright/http/MediaHTTP.cpp b/media/libstagefright/http/MediaHTTP.cpp
index 801ff26..76ec625 100644
--- a/media/libstagefright/http/MediaHTTP.cpp
+++ b/media/libstagefright/http/MediaHTTP.cpp
@@ -65,10 +65,16 @@
mCachedSizeValid = false;
+ if (success) {
+ AString sanitized = uriDebugString(uri);
+ mName = String8::format("MediaHTTP(%s)", sanitized.c_str());
+ }
+
return success ? OK : UNKNOWN_ERROR;
}
void MediaHTTP::disconnect() {
+ mName = String8("MediaHTTP(<disconnected>)");
if (mInitCheck != OK) {
return;
}
diff --git a/media/libstagefright/include/CallbackDataSource.h b/media/libstagefright/include/CallbackDataSource.h
index 9b33810..43e9b8d 100644
--- a/media/libstagefright/include/CallbackDataSource.h
+++ b/media/libstagefright/include/CallbackDataSource.h
@@ -38,11 +38,15 @@
virtual status_t getSize(off64_t *size);
virtual uint32_t flags();
virtual void close();
+ virtual String8 toString() {
+ return mName;
+ }
private:
sp<IDataSource> mIDataSource;
sp<IMemory> mMemory;
bool mIsClosed;
+ String8 mName;
DISALLOW_EVIL_CONSTRUCTORS(CallbackDataSource);
};
@@ -61,6 +65,9 @@
virtual status_t getSize(off64_t* size);
virtual uint32_t flags();
virtual void close() { mSource->close(); }
+ virtual String8 toString() {
+ return mName;
+ }
private:
// 2kb comes from experimenting with the time-to-first-frame from a MediaPlayer
@@ -74,6 +81,7 @@
uint8_t mCache[kCacheSize];
off64_t mCachedOffset;
size_t mCachedSize;
+ String8 mName;
DISALLOW_EVIL_CONSTRUCTORS(TinyCacheSource);
};
diff --git a/media/libstagefright/include/HTTPBase.h b/media/libstagefright/include/HTTPBase.h
index 0c66e27..d325e30 100644
--- a/media/libstagefright/include/HTTPBase.h
+++ b/media/libstagefright/include/HTTPBase.h
@@ -56,8 +56,13 @@
static void RegisterSocketUserMark(int sockfd, uid_t uid);
static void UnRegisterSocketUserMark(int sockfd);
+ virtual String8 toString() {
+ return mName;
+ }
+
protected:
virtual void addBandwidthMeasurement(size_t numBytes, int64_t delayUs);
+ String8 mName;
private:
struct BandwidthEntry {
diff --git a/media/libstagefright/include/NuCachedSource2.h b/media/libstagefright/include/NuCachedSource2.h
index a29bdf9..2639280 100644
--- a/media/libstagefright/include/NuCachedSource2.h
+++ b/media/libstagefright/include/NuCachedSource2.h
@@ -48,6 +48,10 @@
virtual String8 getMIMEType() const;
+ virtual String8 toString() {
+ return mName;
+ }
+
////////////////////////////////////////////////////////////////////////////
size_t cachedSize();
@@ -99,6 +103,7 @@
sp<DataSource> mSource;
sp<AHandlerReflector<NuCachedSource2> > mReflector;
sp<ALooper> mLooper;
+ String8 mName;
Mutex mSerializer;
mutable Mutex mLock;
diff --git a/services/mediaextractor/MediaExtractorService.cpp b/services/mediaextractor/MediaExtractorService.cpp
index a2b35f6..0c93af1 100644
--- a/services/mediaextractor/MediaExtractorService.cpp
+++ b/services/mediaextractor/MediaExtractorService.cpp
@@ -26,69 +26,29 @@
namespace android {
-typedef struct {
- String8 mime;
- String8 name;
- pid_t owner;
- wp<MediaExtractor> extractor;
- String8 toString() {
- String8 str = name;
- str.append(" for mime ");
- str.append(mime);
- str.append(String8::format(", pid %d: ", owner));
- if (extractor.promote() == NULL) {
- str.append("deleted");
- } else {
- str.append("active");
- }
- return str;
- }
-} ExtractorInstance;
-
-static Vector<ExtractorInstance> extractors;
-
sp<IMediaExtractor> MediaExtractorService::makeExtractor(
const sp<IDataSource> &remoteSource, const char *mime) {
ALOGV("@@@ MediaExtractorService::makeExtractor for %s", mime);
sp<DataSource> localSource = DataSource::CreateFromIDataSource(remoteSource);
- sp<MediaExtractor> ret = MediaExtractor::CreateFromService(localSource, mime);
+ sp<IMediaExtractor> ret = MediaExtractor::CreateFromService(localSource, mime);
ALOGV("extractor service created %p (%s)",
ret.get(),
ret == NULL ? "" : ret->name());
if (ret != NULL) {
- ExtractorInstance ex;
- ex.mime = mime == NULL ? "NULL" : mime;
- ex.name = ret->name();
- ex.owner = IPCThreadState::self()->getCallingPid();
- ex.extractor = ret;
-
- if (extractors.size() > 10) {
- extractors.resize(10);
- }
- extractors.push_front(ex);
+ registerMediaExtractor(ret, remoteSource, mime);
}
return ret;
}
status_t MediaExtractorService::dump(int fd, const Vector<String16>& args) {
- String8 out;
- out.append("Recent extractors, most recent first:\n");
- for (size_t i = 0; i < extractors.size(); i++) {
- ExtractorInstance ex = extractors.itemAt(i);
- out.append(" ");
- out.append(ex.toString());
- out.append("\n");
- }
- write(fd, out.string(), out.size());
- return OK;
+ return dumpExtractors(fd, args);
}
-
status_t MediaExtractorService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
uint32_t flags)
{