diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
new file mode 100644
index 0000000..a320bd5
--- /dev/null
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
@@ -0,0 +1,250 @@
+/*
+**
+** Copyright (C) 2008 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 "MetadataRetrieverClient"
+#include <utils/Log.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <unistd.h>
+
+#include <string.h>
+#include <cutils/atomic.h>
+#include <utils/MemoryDealer.h>
+#include <android_runtime/ActivityManager.h>
+#include <utils/IPCThreadState.h>
+#include <utils/IServiceManager.h>
+#include <media/MediaMetadataRetrieverInterface.h>
+#include <media/MediaPlayerInterface.h>
+#include <media/PVMetadataRetriever.h>
+#include <private/media/VideoFrame.h>
+
+#include "MetadataRetrieverClient.h"
+
+
+namespace android {
+
+MetadataRetrieverClient::MetadataRetrieverClient(pid_t pid)
+{
+    LOGV("MetadataRetrieverClient constructor pid(%d)", pid);
+    mPid = pid;
+    mThumbnailDealer = NULL;
+    mAlbumArtDealer = NULL;
+    mThumbnail = NULL;
+    mAlbumArt = NULL;
+
+    mRetriever = new PVMetadataRetriever();
+    if (mRetriever == NULL) {
+        LOGE("failed to initialize the retriever");
+    }
+}
+
+MetadataRetrieverClient::~MetadataRetrieverClient()
+{
+    LOGV("MetadataRetrieverClient destructor");
+    disconnect();
+}
+
+status_t MetadataRetrieverClient::dump(int fd, const Vector<String16>& args) const
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    result.append(" MetadataRetrieverClient\n");
+    snprintf(buffer, 255, "  pid(%d)\n", mPid);
+    result.append(buffer);
+    write(fd, result.string(), result.size());
+    write(fd, "\n", 1);
+    return NO_ERROR;
+}
+
+void MetadataRetrieverClient::disconnect()
+{
+    LOGV("disconnect from pid %d", mPid);
+    Mutex::Autolock lock(mLock);
+    mRetriever.clear();
+    mThumbnailDealer.clear();
+    mAlbumArtDealer.clear();
+    mThumbnail.clear();
+    mAlbumArt.clear();
+    IPCThreadState::self()->flushCommands();
+}
+
+status_t MetadataRetrieverClient::setDataSource(const char *url)
+{
+    LOGV("setDataSource(%s)", url);
+    Mutex::Autolock lock(mLock);
+    if (url == NULL) {
+        return UNKNOWN_ERROR;
+    }
+    if (mRetriever == NULL) {
+        LOGE("retriever is not initialized");
+        return NO_INIT;
+    }
+    return mRetriever->setDataSource(url);
+}
+
+status_t MetadataRetrieverClient::setDataSource(int fd, int64_t offset, int64_t length)
+{
+    LOGV("setDataSource fd=%d, offset=%lld, length=%lld", fd, offset, length);
+    Mutex::Autolock lock(mLock);
+    if (mRetriever == NULL) {
+        LOGE("retriever is not initialized");
+        ::close(fd);
+        return NO_INIT;
+    }
+
+    struct stat sb;
+    int ret = fstat(fd, &sb);
+    if (ret != 0) {
+        LOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno));
+        return UNKNOWN_ERROR;
+    }
+    LOGV("st_dev  = %llu", sb.st_dev);
+    LOGV("st_mode = %u", sb.st_mode);
+    LOGV("st_uid  = %lu", sb.st_uid);
+    LOGV("st_gid  = %lu", sb.st_gid);
+    LOGV("st_size = %llu", sb.st_size);
+
+    if (offset >= sb.st_size) {
+        LOGE("offset (%lld) bigger than file size (%llu)", offset, sb.st_size);
+        ::close(fd);
+        return UNKNOWN_ERROR;
+    }
+    if (offset + length > sb.st_size) {
+        length = sb.st_size - offset;
+        LOGE("calculated length = %lld", length);
+    }
+    status_t status = mRetriever->setDataSource(fd, offset, length);
+    ::close(fd);
+    return status;
+}
+
+status_t MetadataRetrieverClient::setMode(int mode)
+{
+    LOGV("setMode");
+    Mutex::Autolock lock(mLock);
+    if (mRetriever == NULL) {
+        LOGE("retriever is not initialized");
+        return NO_INIT;
+    }
+    return mRetriever->setMode(mode);
+}
+
+status_t MetadataRetrieverClient::getMode(int* mode) const
+{
+    LOGV("getMode");
+    Mutex::Autolock lock(mLock);
+    if (mRetriever == NULL) {
+        LOGE("retriever is not initialized");
+        return NO_INIT;
+    }
+    return mRetriever->getMode(mode);
+}
+
+sp<IMemory> MetadataRetrieverClient::captureFrame()
+{
+    LOGV("captureFrame");
+    Mutex::Autolock lock(mLock);
+    mThumbnail.clear();
+    mThumbnailDealer.clear();
+    if (mRetriever == NULL) {
+        LOGE("retriever is not initialized");
+        return NULL;
+    }
+    VideoFrame *frame = mRetriever->captureFrame();
+    if (frame == NULL) {
+        LOGE("failed to capture a video frame");
+        return NULL;
+    }
+    size_t size = sizeof(VideoFrame) + frame->mSize;
+    mThumbnailDealer = new MemoryDealer(size);
+    if (mThumbnailDealer == NULL) {
+        LOGE("failed to create MemoryDealer");
+        delete frame;
+        return NULL;
+    }
+    mThumbnail = mThumbnailDealer->allocate(size);
+    if (mThumbnail == NULL) {
+        LOGE("not enough memory for VideoFrame size=%u", size);
+        mThumbnailDealer.clear();
+        delete frame;
+        return NULL;
+    }
+    VideoFrame *frameCopy = static_cast<VideoFrame *>(mThumbnail->pointer());
+    frameCopy->mWidth = frame->mWidth;
+    frameCopy->mHeight = frame->mHeight;
+    frameCopy->mDisplayWidth = frame->mDisplayWidth;
+    frameCopy->mDisplayHeight = frame->mDisplayHeight;
+    frameCopy->mSize = frame->mSize;
+    frameCopy->mData = (uint8_t *)frameCopy + sizeof(VideoFrame);
+    memcpy(frameCopy->mData, frame->mData, frame->mSize);
+    delete frame;  // Fix memory leakage
+    return mThumbnail;
+}
+
+sp<IMemory> MetadataRetrieverClient::extractAlbumArt()
+{
+    LOGV("extractAlbumArt");
+    Mutex::Autolock lock(mLock);
+    mAlbumArt.clear();
+    mAlbumArtDealer.clear();
+    if (mRetriever == NULL) {
+        LOGE("retriever is not initialized");
+        return NULL;
+    }
+    MediaAlbumArt *albumArt = mRetriever->extractAlbumArt();
+    if (albumArt == NULL) {
+        LOGE("failed to extract an album art");
+        return NULL;
+    }
+    size_t size = sizeof(MediaAlbumArt) + albumArt->mSize;
+    mAlbumArtDealer = new MemoryDealer(size);
+    if (mAlbumArtDealer == NULL) {
+        LOGE("failed to create MemoryDealer object");
+        delete albumArt;
+        return NULL;
+    }
+    mAlbumArt = mAlbumArtDealer->allocate(size);
+    if (mAlbumArt == NULL) {
+        LOGE("not enough memory for MediaAlbumArt size=%u", size);
+        mAlbumArtDealer.clear();
+        delete albumArt;
+        return NULL;
+    }
+    MediaAlbumArt *albumArtCopy = static_cast<MediaAlbumArt *>(mAlbumArt->pointer());
+    albumArtCopy->mSize = albumArt->mSize;
+    albumArtCopy->mData = (uint8_t *)albumArtCopy + sizeof(MediaAlbumArt);
+    memcpy(albumArtCopy->mData, albumArt->mData, albumArt->mSize);
+    delete albumArt;  // Fix memory leakage
+    return mAlbumArt;
+}
+
+const char* MetadataRetrieverClient::extractMetadata(int keyCode)
+{
+    LOGV("extractMetadata");
+    Mutex::Autolock lock(mLock);
+    if (mRetriever == NULL) {
+        LOGE("retriever is not initialized");
+        return NULL;
+    }
+    return mRetriever->extractMetadata(keyCode);
+}
+
+}; // namespace android
