Add haptic metadata for Ogg file.
Add a key "haptic" in Ogg file metadata, which indicating the haptic
channel count of the Ogg file. When it is present as a valid number,
OggExtractor will set haptic channel mask accordingly to support haptic
playback via audio. This is part of haptic playback support.
Bug: 111454766
Test: Manually test
Change-Id: I9f9ba22358b7c538382f23f24143057970f6d7ad
diff --git a/media/extractors/ogg/Android.bp b/media/extractors/ogg/Android.bp
index c6deb18..2600947 100644
--- a/media/extractors/ogg/Android.bp
+++ b/media/extractors/ogg/Android.bp
@@ -7,6 +7,10 @@
"external/tremolo",
],
+ header_libs: [
+ "libaudio_system_headers",
+ ],
+
shared_libs: [
"liblog",
"libmediaextractor",
diff --git a/media/extractors/ogg/OggExtractor.cpp b/media/extractors/ogg/OggExtractor.cpp
index a52ccb1..cc2c792 100644
--- a/media/extractors/ogg/OggExtractor.cpp
+++ b/media/extractors/ogg/OggExtractor.cpp
@@ -34,6 +34,7 @@
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaDataBase.h>
#include <media/stagefright/MetaDataUtils.h>
+#include <system/audio.h>
#include <utils/String8.h>
extern "C" {
@@ -133,6 +134,8 @@
Vector<TOCEntry> mTableOfContents;
+ int32_t mHapticChannelCount;
+
ssize_t readPage(off64_t offset, Page *page);
status_t findNextPage(off64_t startOffset, off64_t *pageOffset);
@@ -163,6 +166,8 @@
void buildTableOfContents();
+ void setChannelMask(int channelCount);
+
MyOggExtractor(const MyOggExtractor &);
MyOggExtractor &operator=(const MyOggExtractor &);
};
@@ -310,7 +315,8 @@
mMimeType(mimeType),
mNumHeaders(numHeaders),
mSeekPreRollUs(seekPreRollUs),
- mFirstDataOffset(-1) {
+ mFirstDataOffset(-1),
+ mHapticChannelCount(0) {
mCurrentPage.mNumSegments = 0;
vorbis_info_init(&mVi);
@@ -1083,6 +1089,7 @@
}
parseFileMetaData();
+ setChannelMask(mChannelCount);
return AMEDIA_OK;
}
@@ -1157,6 +1164,7 @@
}
parseFileMetaData();
+ setChannelMask(mVi.channels);
break;
}
@@ -1192,6 +1200,29 @@
parseVorbisComment(mFileMeta, comment, commentLength);
//ALOGI("comment #%d: '%s'", i + 1, mVc.user_comments[i]);
}
+
+ AMediaFormat_getInt32(mFileMeta, "haptic", &mHapticChannelCount);
+}
+
+void MyOggExtractor::setChannelMask(int channelCount) {
+ // Set channel mask according to channel count. When haptic channel count is found in
+ // file meta, set haptic channel mask to try haptic playback.
+ if (mHapticChannelCount > 0) {
+ const audio_channel_mask_t hapticChannelMask =
+ haptic_channel_mask_from_count(mHapticChannelCount);
+ const int32_t audioChannelCount = channelCount - mHapticChannelCount;
+ if (hapticChannelMask == AUDIO_CHANNEL_INVALID
+ || audioChannelCount <= 0 || audioChannelCount > FCC_8) {
+ ALOGE("Invalid haptic channel count found in metadata: %d", mHapticChannelCount);
+ } else {
+ const audio_channel_mask_t channelMask = audio_channel_out_mask_from_count(
+ audioChannelCount) | hapticChannelMask;
+ AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_CHANNEL_MASK, channelMask);
+ }
+ } else {
+ AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_CHANNEL_MASK,
+ audio_channel_out_mask_from_count(channelCount));
+ }
}
diff --git a/media/libstagefright/MetaDataUtils.cpp b/media/libstagefright/MetaDataUtils.cpp
index a3259fd..dbc287e 100644
--- a/media/libstagefright/MetaDataUtils.cpp
+++ b/media/libstagefright/MetaDataUtils.cpp
@@ -308,6 +308,8 @@
void parseVorbisComment(
AMediaFormat *fileMeta, const char *comment, size_t commentLength) {
+ // Haptic tag is only kept here as it will only be used in extractor to generate channel mask.
+ const char* const haptic = "haptic";
struct {
const char *const mTag;
const char *mKey;
@@ -328,6 +330,7 @@
{ "LYRICIST", AMEDIAFORMAT_KEY_LYRICIST },
{ "METADATA_BLOCK_PICTURE", AMEDIAFORMAT_KEY_ALBUMART },
{ "ANDROID_LOOP", AMEDIAFORMAT_KEY_LOOP },
+ { "ANDROID_HAPTIC", haptic },
};
for (size_t j = 0; j < sizeof(kMap) / sizeof(kMap[0]); ++j) {
@@ -343,6 +346,15 @@
if (!strcasecmp(&comment[tagLen + 1], "true")) {
AMediaFormat_setInt32(fileMeta, AMEDIAFORMAT_KEY_LOOP, 1);
}
+ } else if (kMap[j].mKey == haptic) {
+ char *end;
+ errno = 0;
+ const int hapticChannelCount = strtol(&comment[tagLen + 1], &end, 10);
+ if (errno == 0) {
+ AMediaFormat_setInt32(fileMeta, haptic, hapticChannelCount);
+ } else {
+ ALOGE("Error(%d) when parsing haptic channel count", errno);
+ }
} else {
AMediaFormat_setString(fileMeta, kMap[j].mKey, &comment[tagLen + 1]);
}