Merge "Avoid copying for input recording frames in CameraSource" into kraken
diff --git a/camera/CameraParameters.cpp b/camera/CameraParameters.cpp
index 7b4c7f6..e4d5bb3 100644
--- a/camera/CameraParameters.cpp
+++ b/camera/CameraParameters.cpp
@@ -70,6 +70,7 @@
 const char CameraParameters::KEY_ZOOM_SUPPORTED[] = "zoom-supported";
 const char CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED[] = "smooth-zoom-supported";
 const char CameraParameters::KEY_FOCUS_DISTANCES[] = "focus-distances";
+const char CameraParameters::KEY_VIDEO_FRAME_FORMAT[] = "video-frame-format";
 
 const char CameraParameters::TRUE[] = "true";
 const char CameraParameters::FOCUS_DISTANCE_INFINITY[] = "Infinity";
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index faf6155..2b7a86e 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -65,13 +65,15 @@
     // Supported preview frame sizes in pixels.
     // Example value: "800x600,480x320". Read only.
     static const char KEY_SUPPORTED_PREVIEW_SIZES[];
-    // The image format for preview frames.
+    // The image format for preview frames. See CAMERA_MSG_PREVIEW_FRAME in
+    // frameworks/base/include/camera/Camera.h.
     // Example value: "yuv420sp" or PIXEL_FORMAT_XXX constants. Read/write.
     static const char KEY_PREVIEW_FORMAT[];
     // Supported image formats for preview frames.
     // Example value: "yuv420sp,yuv422i-yuyv". Read only.
     static const char KEY_SUPPORTED_PREVIEW_FORMATS[];
-    // Number of preview frames per second.
+    // Number of preview frames per second. This is the target frame rate. The
+    // actual frame rate depends on the driver.
     // Example value: "15". Read/write.
     static const char KEY_PREVIEW_FRAME_RATE[];
     // Supported number of preview frames per second.
@@ -83,7 +85,8 @@
     // Supported dimensions for captured pictures in pixels.
     // Example value: "2048x1536,1024x768". Read only.
     static const char KEY_SUPPORTED_PICTURE_SIZES[];
-    // The image format for captured pictures.
+    // The image format for captured pictures. See CAMERA_MSG_COMPRESSED_IMAGE
+    // in frameworks/base/include/camera/Camera.h.
     // Example value: "jpeg" or PIXEL_FORMAT_XXX constants. Read/write.
     static const char KEY_PICTURE_FORMAT[];
     // Supported image formats for captured pictures.
@@ -242,6 +245,11 @@
     // Example value: "0.95,1.9,Infinity" or "0.049,0.05,0.051". Read only.
     static const char KEY_FOCUS_DISTANCES[];
 
+    // The image format for video frames. See CAMERA_MSG_VIDEO_FRAME in
+    // frameworks/base/include/camera/Camera.h.
+    // Example value: "yuv420sp" or PIXEL_FORMAT_XXX constants. Read only.
+    static const char KEY_VIDEO_FRAME_FORMAT[];
+
     // Value for KEY_ZOOM_SUPPORTED or KEY_SMOOTH_ZOOM_SUPPORTED.
     static const char TRUE[];
 
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index a41b2f4..3639db4 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -1633,7 +1633,7 @@
     }
 }
 
-bool SniffMPEG4(
+static bool LegacySniffMPEG4(
         const sp<DataSource> &source, String8 *mimeType, float *confidence) {
     uint8_t header[8];
 
@@ -1657,5 +1657,83 @@
     return false;
 }
 
+static bool isCompatibleBrand(uint32_t fourcc) {
+    static const uint32_t kCompatibleBrands[] = {
+        FOURCC('i', 's', 'o', 'm'),
+        FOURCC('i', 's', 'o', '2'),
+        FOURCC('a', 'v', 'c', '1'),
+        FOURCC('3', 'g', 'p', '4'),
+        FOURCC('m', 'p', '4', '1'),
+        FOURCC('m', 'p', '4', '2'),
+    };
+
+    for (size_t i = 0;
+         i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]);
+         ++i) {
+        if (kCompatibleBrands[i] == fourcc) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+// Attempt to actually parse the 'ftyp' atom and determine if a suitable
+// compatible brand is present.
+static bool BetterSniffMPEG4(
+        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
+    uint8_t header[12];
+    if (source->readAt(0, header, 12) != 12
+            || memcmp("ftyp", &header[4], 4)) {
+        return false;
+    }
+
+    size_t atomSize = U32_AT(&header[0]);
+    if (atomSize < 16 || (atomSize % 4) != 0) {
+        return false;
+    }
+
+    bool success = false;
+    if (isCompatibleBrand(U32_AT(&header[8]))) {
+        success = true;
+    } else {
+        size_t numCompatibleBrands = (atomSize - 16) / 4;
+        for (size_t i = 0; i < numCompatibleBrands; ++i) {
+            uint8_t tmp[4];
+            if (source->readAt(16 + i * 4, tmp, 4) != 4) {
+                return false;
+            }
+
+            if (isCompatibleBrand(U32_AT(&tmp[0]))) {
+                success = true;
+                break;
+            }
+        }
+    }
+
+    if (!success) {
+        return false;
+    }
+
+    *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
+    *confidence = 0.3f;
+
+    return true;
+}
+
+bool SniffMPEG4(
+        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
+    if (BetterSniffMPEG4(source, mimeType, confidence)) {
+        return true;
+    }
+
+    if (LegacySniffMPEG4(source, mimeType, confidence)) {
+        LOGW("Identified supported mpeg4 through LegacySniffMPEG4.");
+        return true;
+    }
+
+    return false;
+}
+
 }  // namespace android