diff --git a/media/libmedia/Metadata.cpp b/media/libmedia/Metadata.cpp
new file mode 100644
index 0000000..35ec6b3
--- /dev/null
+++ b/media/libmedia/Metadata.cpp
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2009 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Metadata"
+#include <utils/Log.h>
+
+#include <sys/types.h>
+#include <media/Metadata.h>
+#include <binder/Parcel.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+// This file contains code to serialize Metadata triples (key, type,
+// value) into a parcel. The Parcel is destinated to be decoded by the
+// Metadata.java class.
+
+namespace {
+// All these constants below must be kept in sync with Metadata.java.
+enum MetadataId {
+    FIRST_SYSTEM_ID = 1,
+    LAST_SYSTEM_ID = 31,
+    FIRST_CUSTOM_ID = 8192
+};
+
+// Types
+enum Types {
+    STRING_VAL = 1,
+    INTEGER_VAL,
+    BOOLEAN_VAL,
+    LONG_VAL,
+    DOUBLE_VAL,
+    TIMED_TEXT_VAL,
+    DATE_VAL,
+    BYTE_ARRAY_VAL,
+};
+
+const size_t kRecordHeaderSize = 3 * sizeof(int32_t);
+const int32_t kMetaMarker = 0x4d455441;  // 'M' 'E' 'T' 'A'
+
+}  // anonymous namespace
+
+namespace android {
+namespace media {
+
+Metadata::Metadata(Parcel *p)
+    :mData(p),
+     mBegin(p->dataPosition()) { }
+
+Metadata::~Metadata() { }
+
+void Metadata::resetParcel()
+{
+    mData->setDataPosition(mBegin);
+}
+
+// Update the 4 bytes int at the beginning of the parcel which holds
+// the number of bytes written so far.
+void Metadata::updateLength()
+{
+    const size_t end = mData->dataPosition();
+
+    mData->setDataPosition(mBegin);
+    mData->writeInt32(end - mBegin);
+    mData->setDataPosition(end);
+}
+
+// Write the header. The java layer will look for the marker.
+bool Metadata::appendHeader()
+{
+    bool ok = true;
+
+    // Placeholder for the length of the metadata
+    ok = ok && mData->writeInt32(-1) == OK;
+    ok = ok && mData->writeInt32(kMetaMarker) == OK;
+    return ok;
+}
+
+bool Metadata::appendBool(int key, bool val)
+{
+    if (!checkKey(key)) {
+        return false;
+    }
+
+    const size_t begin = mData->dataPosition();
+    bool ok = true;
+
+    // 4 int32s: size, key, type, value.
+    ok = ok && mData->writeInt32(4 * sizeof(int32_t)) == OK;
+    ok = ok && mData->writeInt32(key) == OK;
+    ok = ok && mData->writeInt32(BOOLEAN_VAL) == OK;
+    ok = ok && mData->writeInt32(val ? 1 : 0) == OK;
+    if (!ok) {
+        mData->setDataPosition(begin);
+    }
+    return ok;
+}
+
+bool Metadata::appendInt32(int key, int32_t val)
+{
+    if (!checkKey(key)) {
+        return false;
+    }
+
+    const size_t begin = mData->dataPosition();
+    bool ok = true;
+
+    // 4 int32s: size, key, type, value.
+    ok = ok && mData->writeInt32(4 * sizeof(int32_t)) == OK;
+    ok = ok && mData->writeInt32(key) == OK;
+    ok = ok && mData->writeInt32(INTEGER_VAL) == OK;
+    ok = ok && mData->writeInt32(val) == OK;
+    if (!ok) {
+        mData->setDataPosition(begin);
+    }
+    return ok;
+}
+
+// Check the key (i.e metadata id) is valid if it is a system one.
+// Loop over all the exiting ones in the Parcel to check for duplicate
+// (not allowed).
+bool Metadata::checkKey(int key)
+{
+    if (key < FIRST_SYSTEM_ID ||
+        (LAST_SYSTEM_ID < key && key < FIRST_CUSTOM_ID)) {
+        LOGE("Bad key %d", key);
+        return false;
+    }
+    size_t curr = mData->dataPosition();
+    // Loop over the keys to check if it has been used already.
+    mData->setDataPosition(mBegin);
+
+    bool error = false;
+    size_t left = curr - mBegin;
+    while (left > 0) {
+        size_t pos = mData->dataPosition();
+        size_t size = mData->readInt32();
+        if (size < kRecordHeaderSize || size > left) {
+            error = true;
+            break;
+        }
+        if (mData->readInt32() == key) {
+            LOGE("Key exists already %d", key);
+            error = true;
+            break;
+        }
+        mData->setDataPosition(pos + size);
+        left -= size;
+    }
+    mData->setDataPosition(curr);
+    return !error;
+}
+
+}  // namespace android::media
+}  // namespace android
