Merge "android.hardware.media.bufferpool@2.0 impl"
diff --git a/camera/ndk/impl/ACameraMetadata.cpp b/camera/ndk/impl/ACameraMetadata.cpp
index fc00a2d..d73f744 100644
--- a/camera/ndk/impl/ACameraMetadata.cpp
+++ b/camera/ndk/impl/ACameraMetadata.cpp
@@ -32,6 +32,10 @@
     if (mType == ACM_CHARACTERISTICS) {
         filterUnsupportedFeatures();
         filterStreamConfigurations();
+        filterDurations(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS);
+        filterDurations(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS);
+        filterDurations(ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS);
+        filterDurations(ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS);
     }
     // TODO: filter request/result keys
 }
@@ -82,6 +86,72 @@
 
 
 void
+ACameraMetadata::filterDurations(uint32_t tag) {
+    const int STREAM_CONFIGURATION_SIZE = 4;
+    const int STREAM_FORMAT_OFFSET = 0;
+    const int STREAM_WIDTH_OFFSET = 1;
+    const int STREAM_HEIGHT_OFFSET = 2;
+    const int STREAM_DURATION_OFFSET = 3;
+    camera_metadata_entry entry = mData.find(tag);
+    if (entry.count == 0 || entry.count % 4 || entry.type != TYPE_INT64) {
+        ALOGE("%s: malformed duration key %d! count %zu, type %d",
+                __FUNCTION__, tag, entry.count, entry.type);
+        return;
+    }
+    Vector<int64_t> filteredDurations;
+    filteredDurations.setCapacity(entry.count * 2);
+
+    for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
+        int64_t format = entry.data.i64[i + STREAM_FORMAT_OFFSET];
+        int64_t width = entry.data.i64[i + STREAM_WIDTH_OFFSET];
+        int64_t height = entry.data.i64[i + STREAM_HEIGHT_OFFSET];
+        int64_t duration = entry.data.i32[i + STREAM_DURATION_OFFSET];
+
+        // Leave the unfiltered format in so apps depending on previous wrong
+        // filter behavior continue to work
+        filteredDurations.push_back(format);
+        filteredDurations.push_back(width);
+        filteredDurations.push_back(height);
+        filteredDurations.push_back(duration);
+
+        // Translate HAL formats to NDK format
+        switch (tag) {
+            case ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS:
+            case ANDROID_SCALER_AVAILABLE_STALL_DURATIONS:
+                if (format == HAL_PIXEL_FORMAT_BLOB) {
+                    format = AIMAGE_FORMAT_JPEG;
+                    filteredDurations.push_back(format);
+                    filteredDurations.push_back(width);
+                    filteredDurations.push_back(height);
+                    filteredDurations.push_back(duration);
+                }
+                break;
+            case ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS:
+            case ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS:
+                if (format == HAL_PIXEL_FORMAT_BLOB) {
+                    format = AIMAGE_FORMAT_DEPTH_POINT_CLOUD;
+                    filteredDurations.push_back(format);
+                    filteredDurations.push_back(width);
+                    filteredDurations.push_back(height);
+                    filteredDurations.push_back(duration);
+                } else if (format == HAL_PIXEL_FORMAT_Y16) {
+                    format = AIMAGE_FORMAT_DEPTH16;
+                    filteredDurations.push_back(format);
+                    filteredDurations.push_back(width);
+                    filteredDurations.push_back(height);
+                    filteredDurations.push_back(duration);
+                }
+                break;
+            default:
+                // Should not reach here
+                ALOGE("%s: Unkown tag 0x%x", __FUNCTION__, tag);
+        }
+    }
+
+    mData.update(tag, filteredDurations);
+}
+
+void
 ACameraMetadata::filterStreamConfigurations() {
     const int STREAM_CONFIGURATION_SIZE = 4;
     const int STREAM_FORMAT_OFFSET = 0;
diff --git a/camera/ndk/impl/ACameraMetadata.h b/camera/ndk/impl/ACameraMetadata.h
index 0fd7efa..e76b80c 100644
--- a/camera/ndk/impl/ACameraMetadata.h
+++ b/camera/ndk/impl/ACameraMetadata.h
@@ -58,13 +58,16 @@
     camera_status_t getTags(/*out*/int32_t* numTags,
                             /*out*/const uint32_t** tags) const;
 
+    const CameraMetadata& getInternalData() const;
+
+  private:
+
     bool isNdkSupportedCapability(const int32_t capability);
     static inline bool isVendorTag(const uint32_t tag);
     static bool isCaptureRequestTag(const uint32_t tag);
     void filterUnsupportedFeatures(); // Hide features not yet supported by NDK
     void filterStreamConfigurations(); // Hide input streams, translate hal format to NDK formats
-
-    const CameraMetadata& getInternalData() const;
+    void filterDurations(uint32_t tag); // translate hal format to NDK formats
 
     template<typename INTERNAL_T, typename NDK_T>
     camera_status_t updateImpl(uint32_t tag, uint32_t count, const NDK_T* data) {
@@ -96,7 +99,6 @@
         }
     }
 
-  private:
     // guard access of public APIs: get/update/getTags
     mutable Mutex    mLock;
     CameraMetadata   mData;
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index c02d2fb..f52d451 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -393,7 +393,9 @@
     }
     mPssh.clear();
 
-    delete mCachedSource;
+    if (mCachedSource != mDataSource) {
+        delete mCachedSource;
+    }
     delete mDataSource;
 }
 
diff --git a/media/libstagefright/foundation/MediaDefs.cpp b/media/libstagefright/foundation/MediaDefs.cpp
index a32cf08..28bb10a 100644
--- a/media/libstagefright/foundation/MediaDefs.cpp
+++ b/media/libstagefright/foundation/MediaDefs.cpp
@@ -55,7 +55,7 @@
 
 const char *MEDIA_MIMETYPE_CONTAINER_MPEG4 = "video/mp4";
 const char *MEDIA_MIMETYPE_CONTAINER_WAV = "audio/x-wav";
-const char *MEDIA_MIMETYPE_CONTAINER_OGG = "application/ogg";
+const char *MEDIA_MIMETYPE_CONTAINER_OGG = "audio/ogg";
 const char *MEDIA_MIMETYPE_CONTAINER_MATROSKA = "video/x-matroska";
 const char *MEDIA_MIMETYPE_CONTAINER_MPEG2TS = "video/mp2ts";
 const char *MEDIA_MIMETYPE_CONTAINER_AVI = "video/avi";