diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 6dce472..c29d004 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -2,9 +2,7 @@
 // libmediadrm
 //
 
-// TODO: change it back to cc_library_shared when MediaPlayer2 switches to
-// using NdkMediaDrm, instead of MediaDrm.java.
-cc_library {
+cc_library_shared {
     name: "libmediadrm",
 
     srcs: [
diff --git a/media/libmediaplayer2/Android.bp b/media/libmediaplayer2/Android.bp
deleted file mode 100644
index dca6bb6..0000000
--- a/media/libmediaplayer2/Android.bp
+++ /dev/null
@@ -1,129 +0,0 @@
-cc_library_headers {
-    name: "libmediaplayer2_headers",
-    vendor_available: true,
-    export_include_dirs: ["include"],
-}
-
-cc_library_static {
-    name: "libmediaplayer2",
-
-    srcs: [
-        "MediaPlayer2AudioOutput.cpp",
-        "mediaplayer2.cpp",
-    ],
-
-    shared_libs: [
-        "libandroid_runtime",
-        "libaudioclient",
-        "libbinder",
-        "libbinder_ndk",
-        "libcutils",
-        "libgui",
-        "liblog",
-        "libmedia_omx",
-        "libui",
-        "libutils",
-
-        "libcrypto",
-        "libmediametrics",
-        "libmediandk",
-        "libmediandk_utils",
-        "libmediautils",
-        "libmemunreachable",
-        "libnativewindow",
-        "libpowermanager",
-        "libstagefright_httplive",
-    ],
-
-    export_shared_lib_headers: [
-        "libaudioclient",
-        "libbinder",
-        "libgui",
-        "libmedia_omx",
-    ],
-
-    header_libs: [
-        "media_plugin_headers",
-    ],
-
-    include_dirs: [
-        "frameworks/base/core/jni",
-    ],
-
-    static_libs: [
-        "libmedia_helper",
-        "libmediaplayer2-protos",
-        "libmedia_player2_util",
-        "libprotobuf-cpp-lite",
-        "libstagefright_foundation_without_imemory",
-        "libstagefright_nuplayer2",
-        "libstagefright_player2",
-        "libstagefright_rtsp",
-        "libstagefright_timedtext2",
-        "libmedia2_jni_core",
-    ],
-
-    export_include_dirs: [
-        "include",
-    ],
-
-    cflags: [
-        "-Werror",
-        "-Wno-error=deprecated-declarations",
-        "-Wall",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-        cfi: true,
-    },
-}
-
-cc_library {
-    name: "libmedia2_jni_core",
-
-    srcs: [
-        "JavaVMHelper.cpp",
-        "JAudioTrack.cpp",
-        "JMedia2HTTPService.cpp",
-        "JMedia2HTTPConnection.cpp",
-    ],
-
-    header_libs: [
-        "libbinder_headers",
-        "libnativehelper_header_only",
-    ],
-
-    shared_libs: [
-        "liblog",
-        "libutils",
-        "libdl",
-    ],
-
-    include_dirs: [
-        "frameworks/av/media/libmedia/include",
-        "frameworks/base/core/jni",
-    ],
-
-    export_include_dirs: [
-        "include",
-    ],
-
-    cflags: [
-        "-Werror",
-        "-Wno-error=deprecated-declarations",
-        "-Wall",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-        cfi: true,
-    },
-
-}
diff --git a/media/libmediaplayer2/JAudioTrack.cpp b/media/libmediaplayer2/JAudioTrack.cpp
deleted file mode 100644
index fab6c64..0000000
--- a/media/libmediaplayer2/JAudioTrack.cpp
+++ /dev/null
@@ -1,768 +0,0 @@
-/*
- * Copyright 2018 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_TAG "JAudioTrack"
-
-#include "media/JAudioAttributes.h"
-#include "media/JAudioFormat.h"
-#include "mediaplayer2/JAudioTrack.h"
-
-#include <android_media_AudioErrors.h>
-#include <mediaplayer2/JavaVMHelper.h>
-
-namespace android {
-
-// TODO: Store Java class/methodID as a member variable in the class.
-// TODO: Add NULL && Exception checks after every JNI call.
-JAudioTrack::JAudioTrack(                             // < Usages of the arguments are below >
-        uint32_t sampleRate,                          // AudioFormat && bufferSizeInBytes
-        audio_format_t format,                        // AudioFormat && bufferSizeInBytes
-        audio_channel_mask_t channelMask,             // AudioFormat && bufferSizeInBytes
-        callback_t cbf,                               // Offload
-        void* user,                                   // Offload
-        size_t frameCount,                            // bufferSizeInBytes
-        int32_t sessionId,                            // AudioTrack
-        const jobject attributes,                     // AudioAttributes
-        float maxRequiredSpeed) {                     // bufferSizeInBytes
-
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-
-    jclass jAudioTrackCls = env->FindClass("android/media/AudioTrack");
-    mAudioTrackCls = reinterpret_cast<jclass>(env->NewGlobalRef(jAudioTrackCls));
-    env->DeleteLocalRef(jAudioTrackCls);
-
-    maxRequiredSpeed = std::min(std::max(maxRequiredSpeed, 1.0f), AUDIO_TIMESTRETCH_SPEED_MAX);
-
-    int bufferSizeInBytes = 0;
-    if (sampleRate == 0 || frameCount > 0) {
-        // Manually calculate buffer size.
-        bufferSizeInBytes = audio_channel_count_from_out_mask(channelMask)
-                * audio_bytes_per_sample(format) * (frameCount > 0 ? frameCount : 1);
-    } else if (sampleRate > 0) {
-        // Call Java AudioTrack::getMinBufferSize().
-        jmethodID jGetMinBufferSize =
-                env->GetStaticMethodID(mAudioTrackCls, "getMinBufferSize", "(III)I");
-        bufferSizeInBytes = env->CallStaticIntMethod(mAudioTrackCls, jGetMinBufferSize,
-                sampleRate, outChannelMaskFromNative(channelMask), audioFormatFromNative(format));
-    }
-    bufferSizeInBytes = (int) (bufferSizeInBytes * maxRequiredSpeed);
-
-    // Create a Java AudioTrack object through its Builder.
-    jclass jBuilderCls = env->FindClass("android/media/AudioTrack$Builder");
-    jmethodID jBuilderCtor = env->GetMethodID(jBuilderCls, "<init>", "()V");
-    jobject jBuilderObj = env->NewObject(jBuilderCls, jBuilderCtor);
-
-    {
-        sp<JObjectHolder> audioAttributesObj;
-        if (attributes != NULL) {
-            audioAttributesObj = new JObjectHolder(attributes);
-        } else {
-            audioAttributesObj = new JObjectHolder(
-                    JAudioAttributes::createAudioAttributesObj(env, NULL));
-        }
-        jmethodID jSetAudioAttributes = env->GetMethodID(jBuilderCls, "setAudioAttributes",
-                "(Landroid/media/AudioAttributes;)Landroid/media/AudioTrack$Builder;");
-        jBuilderObj = env->CallObjectMethod(jBuilderObj,
-                jSetAudioAttributes, audioAttributesObj->getJObject());
-    }
-
-    jmethodID jSetAudioFormat = env->GetMethodID(jBuilderCls, "setAudioFormat",
-            "(Landroid/media/AudioFormat;)Landroid/media/AudioTrack$Builder;");
-    jBuilderObj = env->CallObjectMethod(jBuilderObj, jSetAudioFormat,
-            JAudioFormat::createAudioFormatObj(env, sampleRate, format, channelMask));
-
-    jmethodID jSetBufferSizeInBytes = env->GetMethodID(jBuilderCls, "setBufferSizeInBytes",
-            "(I)Landroid/media/AudioTrack$Builder;");
-    jBuilderObj = env->CallObjectMethod(jBuilderObj, jSetBufferSizeInBytes, bufferSizeInBytes);
-
-    // We only use streaming mode of Java AudioTrack.
-    jfieldID jModeStream = env->GetStaticFieldID(mAudioTrackCls, "MODE_STREAM", "I");
-    jint transferMode = env->GetStaticIntField(mAudioTrackCls, jModeStream);
-    jmethodID jSetTransferMode = env->GetMethodID(jBuilderCls, "setTransferMode",
-            "(I)Landroid/media/AudioTrack$Builder;");
-    jBuilderObj = env->CallObjectMethod(jBuilderObj, jSetTransferMode,
-            transferMode /* Java AudioTrack::MODE_STREAM */);
-
-    if (sessionId != 0) {
-        jmethodID jSetSessionId = env->GetMethodID(jBuilderCls, "setSessionId",
-                "(I)Landroid/media/AudioTrack$Builder;");
-        jBuilderObj = env->CallObjectMethod(jBuilderObj, jSetSessionId, sessionId);
-    }
-
-    mFlags = AUDIO_OUTPUT_FLAG_NONE;
-    if (cbf != NULL) {
-        jmethodID jSetOffloadedPlayback = env->GetMethodID(jBuilderCls, "setOffloadedPlayback",
-                "(Z)Landroid/media/AudioTrack$Builder;");
-        jBuilderObj = env->CallObjectMethod(jBuilderObj, jSetOffloadedPlayback, true);
-        mFlags = AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
-    }
-
-    jmethodID jBuild = env->GetMethodID(jBuilderCls, "build", "()Landroid/media/AudioTrack;");
-    jobject jAudioTrackObj = env->CallObjectMethod(jBuilderObj, jBuild);
-    mAudioTrackObj = reinterpret_cast<jobject>(env->NewGlobalRef(jAudioTrackObj));
-    env->DeleteLocalRef(jBuilderObj);
-
-    if (cbf != NULL) {
-        // Set offload mode callback
-        jobject jStreamEventCallbackObj = createStreamEventCallback(cbf, user);
-        jobject jExecutorObj = createCallbackExecutor();
-        jmethodID jSetStreamEventCallback = env->GetMethodID(
-                jAudioTrackCls,
-                "setStreamEventCallback",
-                "(Ljava/util/concurrent/Executor;Landroid/media/AudioTrack$StreamEventCallback;)V");
-        env->CallVoidMethod(
-                mAudioTrackObj, jSetStreamEventCallback, jExecutorObj, jStreamEventCallbackObj);
-    }
-}
-
-JAudioTrack::~JAudioTrack() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    env->DeleteGlobalRef(mAudioTrackCls);
-    env->DeleteGlobalRef(mAudioTrackObj);
-}
-
-size_t JAudioTrack::frameCount() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jGetBufferSizeInFrames = env->GetMethodID(
-            mAudioTrackCls, "getBufferSizeInFrames", "()I");
-    return env->CallIntMethod(mAudioTrackObj, jGetBufferSizeInFrames);
-}
-
-size_t JAudioTrack::channelCount() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jGetChannelCount = env->GetMethodID(mAudioTrackCls, "getChannelCount", "()I");
-    return env->CallIntMethod(mAudioTrackObj, jGetChannelCount);
-}
-
-uint32_t JAudioTrack::latency() {
-    // TODO: Currently hard-coded as returning zero.
-    return 0;
-}
-
-status_t JAudioTrack::getPosition(uint32_t *position) {
-    if (position == NULL) {
-        return BAD_VALUE;
-    }
-
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jGetPlaybackHeadPosition = env->GetMethodID(
-            mAudioTrackCls, "getPlaybackHeadPosition", "()I");
-    *position = env->CallIntMethod(mAudioTrackObj, jGetPlaybackHeadPosition);
-
-    return NO_ERROR;
-}
-
-status_t JAudioTrack::getTimestamp(AudioTimestamp& timestamp) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-
-    jclass jAudioTimeStampCls = env->FindClass("android/media/AudioTimestamp");
-    jobject jAudioTimeStampObj = env->AllocObject(jAudioTimeStampCls);
-
-    jfieldID jFramePosition = env->GetFieldID(jAudioTimeStampCls, "framePosition", "J");
-    jfieldID jNanoTime = env->GetFieldID(jAudioTimeStampCls, "nanoTime", "J");
-
-    jmethodID jGetTimestamp = env->GetMethodID(mAudioTrackCls,
-            "getTimestamp", "(Landroid/media/AudioTimestamp;)Z");
-    bool success = env->CallBooleanMethod(mAudioTrackObj, jGetTimestamp, jAudioTimeStampObj);
-
-    if (!success) {
-        return NO_INIT;
-    }
-
-    long long framePosition = env->GetLongField(jAudioTimeStampObj, jFramePosition);
-    long long nanoTime = env->GetLongField(jAudioTimeStampObj, jNanoTime);
-
-    struct timespec ts;
-    const long long secondToNano = 1000000000LL; // 1E9
-    ts.tv_sec = nanoTime / secondToNano;
-    ts.tv_nsec = nanoTime % secondToNano;
-    timestamp.mTime = ts;
-    timestamp.mPosition = (uint32_t) framePosition;
-
-    return NO_ERROR;
-}
-
-status_t JAudioTrack::getTimestamp(ExtendedTimestamp *timestamp __unused) {
-    // TODO: Implement this after appropriate Java AudioTrack method is available.
-    return NO_ERROR;
-}
-
-status_t JAudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate) {
-    // TODO: existing native AudioTrack returns INVALID_OPERATION on offload/direct/fast tracks.
-    // Should we do the same thing?
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-
-    jclass jPlaybackParamsCls = env->FindClass("android/media/PlaybackParams");
-    jmethodID jPlaybackParamsCtor = env->GetMethodID(jPlaybackParamsCls, "<init>", "()V");
-    jobject jPlaybackParamsObj = env->NewObject(jPlaybackParamsCls, jPlaybackParamsCtor);
-
-    jmethodID jSetAudioFallbackMode = env->GetMethodID(
-            jPlaybackParamsCls, "setAudioFallbackMode", "(I)Landroid/media/PlaybackParams;");
-    jPlaybackParamsObj = env->CallObjectMethod(
-            jPlaybackParamsObj, jSetAudioFallbackMode, playbackRate.mFallbackMode);
-
-    jmethodID jSetAudioStretchMode = env->GetMethodID(
-                jPlaybackParamsCls, "setAudioStretchMode", "(I)Landroid/media/PlaybackParams;");
-    jPlaybackParamsObj = env->CallObjectMethod(
-            jPlaybackParamsObj, jSetAudioStretchMode, playbackRate.mStretchMode);
-
-    jmethodID jSetPitch = env->GetMethodID(
-            jPlaybackParamsCls, "setPitch", "(F)Landroid/media/PlaybackParams;");
-    jPlaybackParamsObj = env->CallObjectMethod(jPlaybackParamsObj, jSetPitch, playbackRate.mPitch);
-
-    jmethodID jSetSpeed = env->GetMethodID(
-            jPlaybackParamsCls, "setSpeed", "(F)Landroid/media/PlaybackParams;");
-    jPlaybackParamsObj = env->CallObjectMethod(jPlaybackParamsObj, jSetSpeed, playbackRate.mSpeed);
-
-
-    // Set this Java PlaybackParams object into Java AudioTrack.
-    jmethodID jSetPlaybackParams = env->GetMethodID(
-            mAudioTrackCls, "setPlaybackParams", "(Landroid/media/PlaybackParams;)V");
-    env->CallVoidMethod(mAudioTrackObj, jSetPlaybackParams, jPlaybackParamsObj);
-    // TODO: Should we catch the Java IllegalArgumentException?
-
-    return NO_ERROR;
-}
-
-const AudioPlaybackRate JAudioTrack::getPlaybackRate() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-
-    jmethodID jGetPlaybackParams = env->GetMethodID(
-            mAudioTrackCls, "getPlaybackParams", "()Landroid/media/PlaybackParams;");
-    jobject jPlaybackParamsObj = env->CallObjectMethod(mAudioTrackObj, jGetPlaybackParams);
-
-    AudioPlaybackRate playbackRate;
-    jclass jPlaybackParamsCls = env->FindClass("android/media/PlaybackParams");
-
-    jmethodID jGetAudioFallbackMode = env->GetMethodID(
-            jPlaybackParamsCls, "getAudioFallbackMode", "()I");
-    // TODO: Should we enable passing AUDIO_TIMESTRETCH_FALLBACK_CUT_REPEAT?
-    //       The enum is internal only, so it is not defined in PlaybackParmas.java.
-    // TODO: Is this right way to convert an int to an enum?
-    playbackRate.mFallbackMode = static_cast<AudioTimestretchFallbackMode>(
-            env->CallIntMethod(jPlaybackParamsObj, jGetAudioFallbackMode));
-
-    jmethodID jGetAudioStretchMode = env->GetMethodID(
-            jPlaybackParamsCls, "getAudioStretchMode", "()I");
-    playbackRate.mStretchMode = static_cast<AudioTimestretchStretchMode>(
-            env->CallIntMethod(jPlaybackParamsObj, jGetAudioStretchMode));
-
-    jmethodID jGetPitch = env->GetMethodID(jPlaybackParamsCls, "getPitch", "()F");
-    playbackRate.mPitch = env->CallFloatMethod(jPlaybackParamsObj, jGetPitch);
-
-    jmethodID jGetSpeed = env->GetMethodID(jPlaybackParamsCls, "getSpeed", "()F");
-    playbackRate.mSpeed = env->CallFloatMethod(jPlaybackParamsObj, jGetSpeed);
-
-    return playbackRate;
-}
-
-media::VolumeShaper::Status JAudioTrack::applyVolumeShaper(
-        const sp<media::VolumeShaper::Configuration>& configuration,
-        const sp<media::VolumeShaper::Operation>& operation) {
-
-    jobject jConfigurationObj = createVolumeShaperConfigurationObj(configuration);
-    jobject jOperationObj = createVolumeShaperOperationObj(operation);
-
-    if (jConfigurationObj == NULL || jOperationObj == NULL) {
-        return media::VolumeShaper::Status(BAD_VALUE);
-    }
-
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-
-    jmethodID jCreateVolumeShaper = env->GetMethodID(mAudioTrackCls, "createVolumeShaper",
-            "(Landroid/media/VolumeShaper$Configuration;)Landroid/media/VolumeShaper;");
-    jobject jVolumeShaperObj = env->CallObjectMethod(
-            mAudioTrackObj, jCreateVolumeShaper, jConfigurationObj);
-
-    jclass jVolumeShaperCls = env->FindClass("android/media/VolumeShaper");
-    jmethodID jApply = env->GetMethodID(jVolumeShaperCls, "apply",
-            "(Landroid/media/VolumeShaper$Operation;)V");
-    env->CallVoidMethod(jVolumeShaperObj, jApply, jOperationObj);
-
-    return media::VolumeShaper::Status(NO_ERROR);
-}
-
-status_t JAudioTrack::setAuxEffectSendLevel(float level) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jSetAuxEffectSendLevel = env->GetMethodID(
-            mAudioTrackCls, "setAuxEffectSendLevel", "(F)I");
-    int result = env->CallIntMethod(mAudioTrackObj, jSetAuxEffectSendLevel, level);
-    return javaToNativeStatus(result);
-}
-
-status_t JAudioTrack::attachAuxEffect(int effectId) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jAttachAuxEffect = env->GetMethodID(mAudioTrackCls, "attachAuxEffect", "(I)I");
-    int result = env->CallIntMethod(mAudioTrackObj, jAttachAuxEffect, effectId);
-    return javaToNativeStatus(result);
-}
-
-status_t JAudioTrack::setVolume(float left, float right) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    // TODO: Java setStereoVolume is deprecated. Do we really need this method?
-    jmethodID jSetStereoVolume = env->GetMethodID(mAudioTrackCls, "setStereoVolume", "(FF)I");
-    int result = env->CallIntMethod(mAudioTrackObj, jSetStereoVolume, left, right);
-    return javaToNativeStatus(result);
-}
-
-status_t JAudioTrack::setVolume(float volume) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jSetVolume = env->GetMethodID(mAudioTrackCls, "setVolume", "(F)I");
-    int result = env->CallIntMethod(mAudioTrackObj, jSetVolume, volume);
-    return javaToNativeStatus(result);
-}
-
-status_t JAudioTrack::start() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jPlay = env->GetMethodID(mAudioTrackCls, "play", "()V");
-    // TODO: Should we catch the Java IllegalStateException from play()?
-    env->CallVoidMethod(mAudioTrackObj, jPlay);
-    return NO_ERROR;
-}
-
-ssize_t JAudioTrack::write(const void* buffer, size_t size, bool blocking) {
-    if (buffer == NULL) {
-        return BAD_VALUE;
-    }
-
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jbyteArray jAudioData = env->NewByteArray(size);
-    env->SetByteArrayRegion(jAudioData, 0, size, (jbyte *) buffer);
-
-    jclass jByteBufferCls = env->FindClass("java/nio/ByteBuffer");
-    jmethodID jWrap = env->GetStaticMethodID(jByteBufferCls, "wrap", "([B)Ljava/nio/ByteBuffer;");
-    jobject jByteBufferObj = env->CallStaticObjectMethod(jByteBufferCls, jWrap, jAudioData);
-
-    int writeMode = 0;
-    if (blocking) {
-        jfieldID jWriteBlocking = env->GetStaticFieldID(mAudioTrackCls, "WRITE_BLOCKING", "I");
-        writeMode = env->GetStaticIntField(mAudioTrackCls, jWriteBlocking);
-    } else {
-        jfieldID jWriteNonBlocking = env->GetStaticFieldID(
-                mAudioTrackCls, "WRITE_NON_BLOCKING", "I");
-        writeMode = env->GetStaticIntField(mAudioTrackCls, jWriteNonBlocking);
-    }
-
-    jmethodID jWrite = env->GetMethodID(mAudioTrackCls, "write", "(Ljava/nio/ByteBuffer;II)I");
-    int result = env->CallIntMethod(mAudioTrackObj, jWrite, jByteBufferObj, size, writeMode);
-
-    if (result >= 0) {
-        return result;
-    } else {
-        return javaToNativeStatus(result);
-    }
-}
-
-void JAudioTrack::stop() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jStop = env->GetMethodID(mAudioTrackCls, "stop", "()V");
-    env->CallVoidMethod(mAudioTrackObj, jStop);
-    // TODO: Should we catch IllegalStateException?
-}
-
-// TODO: Is the right implementation?
-bool JAudioTrack::stopped() const {
-    return !isPlaying();
-}
-
-void JAudioTrack::flush() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jFlush = env->GetMethodID(mAudioTrackCls, "flush", "()V");
-    env->CallVoidMethod(mAudioTrackObj, jFlush);
-}
-
-void JAudioTrack::pause() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jPause = env->GetMethodID(mAudioTrackCls, "pause", "()V");
-    env->CallVoidMethod(mAudioTrackObj, jPause);
-    // TODO: Should we catch IllegalStateException?
-}
-
-bool JAudioTrack::isPlaying() const {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jGetPlayState = env->GetMethodID(mAudioTrackCls, "getPlayState", "()I");
-    int currentPlayState = env->CallIntMethod(mAudioTrackObj, jGetPlayState);
-
-    // TODO: In Java AudioTrack, there is no STOPPING state.
-    // This means while stopping, isPlaying() will return different value in two class.
-    //  - in existing native AudioTrack: true
-    //  - in JAudioTrack: false
-    // If not okay, also modify the implementation of stopped().
-    jfieldID jPlayStatePlaying = env->GetStaticFieldID(mAudioTrackCls, "PLAYSTATE_PLAYING", "I");
-    int statePlaying = env->GetStaticIntField(mAudioTrackCls, jPlayStatePlaying);
-    return currentPlayState == statePlaying;
-}
-
-uint32_t JAudioTrack::getSampleRate() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jGetSampleRate = env->GetMethodID(mAudioTrackCls, "getSampleRate", "()I");
-    return env->CallIntMethod(mAudioTrackObj, jGetSampleRate);
-}
-
-status_t JAudioTrack::getBufferDurationInUs(int64_t *duration) {
-    if (duration == nullptr) {
-        return BAD_VALUE;
-    }
-
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jGetBufferSizeInFrames = env->GetMethodID(
-            mAudioTrackCls, "getBufferSizeInFrames", "()I");
-    int bufferSizeInFrames = env->CallIntMethod(mAudioTrackObj, jGetBufferSizeInFrames);
-
-    const double secondToMicro = 1000000LL; // 1E6
-    int sampleRate = JAudioTrack::getSampleRate();
-    float speed = JAudioTrack::getPlaybackRate().mSpeed;
-
-    *duration = (int64_t) (bufferSizeInFrames * secondToMicro / (sampleRate * speed));
-    return NO_ERROR;
-}
-
-audio_format_t JAudioTrack::format() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jGetAudioFormat = env->GetMethodID(mAudioTrackCls, "getAudioFormat", "()I");
-    int javaFormat = env->CallIntMethod(mAudioTrackObj, jGetAudioFormat);
-    return audioFormatToNative(javaFormat);
-}
-
-size_t JAudioTrack::frameSize() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jGetFormat = env->GetMethodID(mAudioTrackCls,
-            "getFormat", "()Landroid/media/AudioFormat;");
-    jobject jAudioFormatObj = env->CallObjectMethod(mAudioTrackObj, jGetFormat);
-
-    jclass jAudioFormatCls = env->FindClass("android/media/AudioFormat");
-    jmethodID jGetFrameSizeInBytes = env->GetMethodID(
-            jAudioFormatCls, "getFrameSizeInBytes", "()I");
-    jint javaFrameSizeInBytes = env->CallIntMethod(jAudioFormatObj, jGetFrameSizeInBytes);
-
-    return (size_t)javaFrameSizeInBytes;
-}
-
-status_t JAudioTrack::dump(int fd, const Vector<String16>& args __unused) const
-{
-    String8 result;
-
-    result.append(" JAudioTrack::dump\n");
-
-    // TODO: Remove logs that includes unavailable information from below.
-//    result.appendFormat("  status(%d), state(%d), session Id(%d), flags(%#x)\n",
-//                        mStatus, mState, mSessionId, mFlags);
-//    result.appendFormat("  format(%#x), channel mask(%#x), channel count(%u)\n",
-//                  format(), mChannelMask, channelCount());
-//    result.appendFormat("  sample rate(%u), original sample rate(%u), speed(%f)\n",
-//            getSampleRate(), mOriginalSampleRate, mPlaybackRate.mSpeed);
-//    result.appendFormat("  frame count(%zu), req. frame count(%zu)\n",
-//                  frameCount(), mReqFrameCount);
-//    result.appendFormat("  notif. frame count(%u), req. notif. frame count(%u),"
-//            " req. notif. per buff(%u)\n",
-//             mNotificationFramesAct, mNotificationFramesReq, mNotificationsPerBufferReq);
-//    result.appendFormat("  latency (%d), selected device Id(%d), routed device Id(%d)\n",
-//                        latency(), mSelectedDeviceId, getRoutedDeviceId());
-//    result.appendFormat("  output(%d) AF latency (%u) AF frame count(%zu) AF SampleRate(%u)\n",
-//                        mOutput, mAfLatency, mAfFrameCount, mAfSampleRate);
-    ::write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-jobject JAudioTrack::getRoutedDevice() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jGetRoutedDevice = env->GetMethodID(mAudioTrackCls, "getRoutedDevice",
-            "()Landroid/media/AudioDeviceInfo;");
-    return env->CallObjectMethod(mAudioTrackObj, jGetRoutedDevice);
-}
-
-int32_t JAudioTrack::getAudioSessionId() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jGetAudioSessionId = env->GetMethodID(mAudioTrackCls, "getAudioSessionId", "()I");
-    jint sessionId = env->CallIntMethod(mAudioTrackObj, jGetAudioSessionId);
-    return sessionId;
-}
-
-status_t JAudioTrack::setPreferredDevice(jobject device) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jSetPreferredDeviceId = env->GetMethodID(mAudioTrackCls, "setPreferredDevice",
-            "(Landroid/media/AudioDeviceInfo;)Z");
-    jboolean result = env->CallBooleanMethod(mAudioTrackObj, jSetPreferredDeviceId, device);
-    return result == true ? NO_ERROR : BAD_VALUE;
-}
-
-audio_stream_type_t JAudioTrack::getAudioStreamType() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jGetAudioAttributes = env->GetMethodID(mAudioTrackCls, "getAudioAttributes",
-            "()Landroid/media/AudioAttributes;");
-    jobject jAudioAttributes = env->CallObjectMethod(mAudioTrackObj, jGetAudioAttributes);
-    jclass jAudioAttributesCls = env->FindClass("android/media/AudioAttributes");
-    jmethodID jGetVolumeControlStream = env->GetMethodID(jAudioAttributesCls,
-            "getVolumeControlStream", "()I");
-    int javaAudioStreamType = env->CallIntMethod(jAudioAttributes, jGetVolumeControlStream);
-    return (audio_stream_type_t)javaAudioStreamType;
-}
-
-status_t JAudioTrack::pendingDuration(int32_t *msec) {
-    if (msec == nullptr) {
-        return BAD_VALUE;
-    }
-
-    bool isPurePcmData = audio_is_linear_pcm(format()) && (getFlags() & AUDIO_FLAG_HW_AV_SYNC) == 0;
-    if (!isPurePcmData) {
-        return INVALID_OPERATION;
-    }
-
-    // TODO: Need to know the difference btw. client and server time.
-    // If getTimestamp(ExtendedTimestamp) is ready, and un-comment below and modify appropriately.
-    // (copied from AudioTrack.cpp)
-
-//    ExtendedTimestamp ets;
-//    ExtendedTimestamp::LOCATION location = ExtendedTimestamp::LOCATION_SERVER;
-//    if (getTimestamp_l(&ets) == OK && ets.mTimeNs[location] > 0) {
-//        int64_t diff = ets.mPosition[ExtendedTimestamp::LOCATION_CLIENT]
-//                - ets.mPosition[location];
-//        if (diff < 0) {
-//            *msec = 0;
-//        } else {
-//            // ms is the playback time by frames
-//            int64_t ms = (int64_t)((double)diff * 1000 /
-//                    ((double)mSampleRate * mPlaybackRate.mSpeed));
-//            // clockdiff is the timestamp age (negative)
-//            int64_t clockdiff = (mState != STATE_ACTIVE) ? 0 :
-//                    ets.mTimeNs[location]
-//                    + ets.mTimebaseOffset[ExtendedTimestamp::TIMEBASE_MONOTONIC]
-//                    - systemTime(SYSTEM_TIME_MONOTONIC);
-//
-//            //ALOGV("ms: %lld  clockdiff: %lld", (long long)ms, (long long)clockdiff);
-//            static const int NANOS_PER_MILLIS = 1000000;
-//            *msec = (int32_t)(ms + clockdiff / NANOS_PER_MILLIS);
-//        }
-//        return NO_ERROR;
-//    }
-
-    return NO_ERROR;
-}
-
-status_t JAudioTrack::addAudioDeviceCallback(jobject listener, jobject handler) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jAddOnRoutingChangedListener = env->GetMethodID(mAudioTrackCls,
-            "addOnRoutingChangedListener",
-            "(Landroid/media/AudioRouting$OnRoutingChangedListener;Landroid/os/Handler;)V");
-    env->CallVoidMethod(mAudioTrackObj, jAddOnRoutingChangedListener, listener, handler);
-    return NO_ERROR;
-}
-
-status_t JAudioTrack::removeAudioDeviceCallback(jobject listener) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jRemoveOnRoutingChangedListener = env->GetMethodID(mAudioTrackCls,
-            "removeOnRoutingChangedListener",
-            "(Landroid/media/AudioRouting$OnRoutingChangedListener;)V");
-    env->CallVoidMethod(mAudioTrackObj, jRemoveOnRoutingChangedListener, listener);
-    return NO_ERROR;
-}
-
-void JAudioTrack::registerRoutingDelegates(
-        Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& routingDelegates) {
-    for (auto it = routingDelegates.begin(); it != routingDelegates.end(); it++) {
-        addAudioDeviceCallback(it->second->getJObject(), getHandler(it->second->getJObject()));
-    }
-}
-
-/////////////////////////////////////////////////////////////
-///                Static methods begin                   ///
-/////////////////////////////////////////////////////////////
-jobject JAudioTrack::getListener(const jobject routingDelegateObj) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jclass jRoutingDelegateCls = env->FindClass("android/media/RoutingDelegate");
-    jmethodID jGetListener = env->GetMethodID(jRoutingDelegateCls,
-            "getListener", "()Landroid/media/AudioRouting$OnRoutingChangedListener;");
-    return env->CallObjectMethod(routingDelegateObj, jGetListener);
-}
-
-jobject JAudioTrack::getHandler(const jobject routingDelegateObj) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jclass jRoutingDelegateCls = env->FindClass("android/media/RoutingDelegate");
-    jmethodID jGetHandler = env->GetMethodID(jRoutingDelegateCls,
-        "getHandler", "()Landroid/os/Handler;");
-    return env->CallObjectMethod(routingDelegateObj, jGetHandler);
-}
-
-jobject JAudioTrack::findByKey(
-        Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& mp, const jobject key) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    for (auto it = mp.begin(); it != mp.end(); it++) {
-        if (env->IsSameObject(it->first->getJObject(), key)) {
-            return it->second->getJObject();
-        }
-    }
-    return nullptr;
-}
-
-void JAudioTrack::eraseByKey(
-        Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& mp, const jobject key) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    for (auto it = mp.begin(); it != mp.end(); it++) {
-        if (env->IsSameObject(it->first->getJObject(), key)) {
-            mp.erase(it);
-            return;
-        }
-    }
-}
-
-/////////////////////////////////////////////////////////////
-///                Private method begins                  ///
-/////////////////////////////////////////////////////////////
-
-jobject JAudioTrack::createVolumeShaperConfigurationObj(
-        const sp<media::VolumeShaper::Configuration>& config) {
-
-    // TODO: Java VolumeShaper's setId() / setOptionFlags() are hidden.
-    if (config == NULL || config->getType() == media::VolumeShaper::Configuration::TYPE_ID) {
-        return NULL;
-    }
-
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-
-    // Referenced "android_media_VolumeShaper.h".
-    jfloatArray xarray = nullptr;
-    jfloatArray yarray = nullptr;
-    if (config->getType() == media::VolumeShaper::Configuration::TYPE_SCALE) {
-        // convert curve arrays
-        xarray = env->NewFloatArray(config->size());
-        yarray = env->NewFloatArray(config->size());
-        float * const x = env->GetFloatArrayElements(xarray, nullptr /* isCopy */);
-        float * const y = env->GetFloatArrayElements(yarray, nullptr /* isCopy */);
-        float *xptr = x, *yptr = y;
-        for (const auto &pt : *config.get()) {
-            *xptr++ = pt.first;
-            *yptr++ = pt.second;
-        }
-        env->ReleaseFloatArrayElements(xarray, x, 0 /* mode */);
-        env->ReleaseFloatArrayElements(yarray, y, 0 /* mode */);
-    }
-
-    jclass jBuilderCls = env->FindClass("android/media/VolumeShaper$Configuration$Builder");
-    jmethodID jBuilderCtor = env->GetMethodID(jBuilderCls, "<init>", "()V");
-    jobject jBuilderObj = env->NewObject(jBuilderCls, jBuilderCtor);
-
-    jmethodID jSetDuration = env->GetMethodID(jBuilderCls, "setDuration",
-            "(L)Landroid/media/VolumeShaper$Configuration$Builder;");
-    jBuilderObj = env->CallObjectMethod(jBuilderCls, jSetDuration, (jlong) config->getDurationMs());
-
-    jmethodID jSetInterpolatorType = env->GetMethodID(jBuilderCls, "setInterpolatorType",
-            "(I)Landroid/media/VolumeShaper$Configuration$Builder;");
-    jBuilderObj = env->CallObjectMethod(jBuilderCls, jSetInterpolatorType,
-            config->getInterpolatorType());
-
-    jmethodID jSetCurve = env->GetMethodID(jBuilderCls, "setCurve",
-            "([F[F)Landroid/media/VolumeShaper$Configuration$Builder;");
-    jBuilderObj = env->CallObjectMethod(jBuilderCls, jSetCurve, xarray, yarray);
-
-    jmethodID jBuild = env->GetMethodID(jBuilderCls, "build",
-            "()Landroid/media/VolumeShaper$Configuration;");
-    return env->CallObjectMethod(jBuilderObj, jBuild);
-}
-
-jobject JAudioTrack::createVolumeShaperOperationObj(
-        const sp<media::VolumeShaper::Operation>& operation) {
-
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-
-    jclass jBuilderCls = env->FindClass("android/media/VolumeShaper$Operation$Builder");
-    jmethodID jBuilderCtor = env->GetMethodID(jBuilderCls, "<init>", "()V");
-    jobject jBuilderObj = env->NewObject(jBuilderCls, jBuilderCtor);
-
-    // Set XOffset
-    jmethodID jSetXOffset = env->GetMethodID(jBuilderCls, "setXOffset",
-            "(F)Landroid/media/VolumeShaper$Operation$Builder;");
-    jBuilderObj = env->CallObjectMethod(jBuilderCls, jSetXOffset, operation->getXOffset());
-
-    int32_t flags = operation->getFlags();
-
-    if (operation->getReplaceId() >= 0) {
-        jmethodID jReplace = env->GetMethodID(jBuilderCls, "replace",
-                "(IB)Landroid/media/VolumeShaper$Operation$Builder;");
-        bool join = (flags | media::VolumeShaper::Operation::FLAG_JOIN) != 0;
-        jBuilderObj = env->CallObjectMethod(jBuilderCls, jReplace, operation->getReplaceId(), join);
-    }
-
-    if (flags | media::VolumeShaper::Operation::FLAG_REVERSE) {
-        jmethodID jReverse = env->GetMethodID(jBuilderCls, "reverse",
-                "()Landroid/media/VolumeShaper$Operation$Builder;");
-        jBuilderObj = env->CallObjectMethod(jBuilderCls, jReverse);
-    }
-
-    // TODO: VolumeShaper Javadoc says "Do not call terminate() directly". Can we call this?
-    if (flags | media::VolumeShaper::Operation::FLAG_TERMINATE) {
-        jmethodID jTerminate = env->GetMethodID(jBuilderCls, "terminate",
-                "()Landroid/media/VolumeShaper$Operation$Builder;");
-        jBuilderObj = env->CallObjectMethod(jBuilderCls, jTerminate);
-    }
-
-    if (flags | media::VolumeShaper::Operation::FLAG_DELAY) {
-        jmethodID jDefer = env->GetMethodID(jBuilderCls, "defer",
-                "()Landroid/media/VolumeShaper$Operation$Builder;");
-        jBuilderObj = env->CallObjectMethod(jBuilderCls, jDefer);
-    }
-
-    if (flags | media::VolumeShaper::Operation::FLAG_CREATE_IF_NECESSARY) {
-        jmethodID jCreateIfNeeded = env->GetMethodID(jBuilderCls, "createIfNeeded",
-                "()Landroid/media/VolumeShaper$Operation$Builder;");
-        jBuilderObj = env->CallObjectMethod(jBuilderCls, jCreateIfNeeded);
-    }
-
-    // TODO: Handle error case (can it be NULL?)
-    jmethodID jBuild = env->GetMethodID(jBuilderCls, "build",
-            "()Landroid/media/VolumeShaper$Operation;");
-    return env->CallObjectMethod(jBuilderObj, jBuild);
-}
-
-jobject JAudioTrack::createStreamEventCallback(callback_t cbf, void* user) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jclass jCallbackCls = env->FindClass("android/media/MediaPlayer2$StreamEventCallback");
-    jmethodID jCallbackCtor = env->GetMethodID(jCallbackCls, "<init>", "(JJJ)V");
-    jobject jCallbackObj = env->NewObject(jCallbackCls, jCallbackCtor, this, cbf, user);
-    return jCallbackObj;
-}
-
-jobject JAudioTrack::createCallbackExecutor() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jclass jExecutorsCls = env->FindClass("java/util/concurrent/Executors");
-    jmethodID jNewSingleThreadExecutor = env->GetStaticMethodID(jExecutorsCls,
-            "newSingleThreadExecutor", "()Ljava/util/concurrent/ExecutorService;");
-    jobject jSingleThreadExecutorObj =
-            env->CallStaticObjectMethod(jExecutorsCls, jNewSingleThreadExecutor);
-    return jSingleThreadExecutorObj;
-}
-
-status_t JAudioTrack::javaToNativeStatus(int javaStatus) {
-    switch (javaStatus) {
-    case AUDIO_JAVA_SUCCESS:
-        return NO_ERROR;
-    case AUDIO_JAVA_BAD_VALUE:
-        return BAD_VALUE;
-    case AUDIO_JAVA_INVALID_OPERATION:
-        return INVALID_OPERATION;
-    case AUDIO_JAVA_PERMISSION_DENIED:
-        return PERMISSION_DENIED;
-    case AUDIO_JAVA_NO_INIT:
-        return NO_INIT;
-    case AUDIO_JAVA_WOULD_BLOCK:
-        return WOULD_BLOCK;
-    case AUDIO_JAVA_DEAD_OBJECT:
-        return DEAD_OBJECT;
-    default:
-        return UNKNOWN_ERROR;
-    }
-}
-
-} // namespace android
diff --git a/media/libmediaplayer2/JMedia2HTTPConnection.cpp b/media/libmediaplayer2/JMedia2HTTPConnection.cpp
deleted file mode 100644
index e1baa10..0000000
--- a/media/libmediaplayer2/JMedia2HTTPConnection.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright 2017, 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 "JMedia2HTTPConnection"
-#include <utils/Log.h>
-
-#include <mediaplayer2/JavaVMHelper.h>
-#include <mediaplayer2/JMedia2HTTPConnection.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <nativehelper/scoped_local_ref.h>
-
-#include "log/log.h"
-#include "jni.h"
-
-namespace android {
-
-static const size_t kBufferSize = 32768;
-
-JMedia2HTTPConnection::JMedia2HTTPConnection(JNIEnv *env, jobject thiz) {
-    mMedia2HTTPConnectionObj = env->NewGlobalRef(thiz);
-    CHECK(mMedia2HTTPConnectionObj != NULL);
-
-    ScopedLocalRef<jclass> media2HTTPConnectionClass(
-            env, env->GetObjectClass(mMedia2HTTPConnectionObj));
-    CHECK(media2HTTPConnectionClass.get() != NULL);
-
-    mConnectMethod = env->GetMethodID(
-            media2HTTPConnectionClass.get(),
-            "connect",
-            "(Ljava/lang/String;Ljava/lang/String;)Z");
-    CHECK(mConnectMethod != NULL);
-
-    mDisconnectMethod = env->GetMethodID(
-            media2HTTPConnectionClass.get(),
-            "disconnect",
-            "()V");
-    CHECK(mDisconnectMethod != NULL);
-
-    mReadAtMethod = env->GetMethodID(
-            media2HTTPConnectionClass.get(),
-            "readAt",
-            "(J[BI)I");
-    CHECK(mReadAtMethod != NULL);
-
-    mGetSizeMethod = env->GetMethodID(
-            media2HTTPConnectionClass.get(),
-            "getSize",
-            "()J");
-    CHECK(mGetSizeMethod != NULL);
-
-    mGetMIMETypeMethod = env->GetMethodID(
-            media2HTTPConnectionClass.get(),
-            "getMIMEType",
-            "()Ljava/lang/String;");
-    CHECK(mGetMIMETypeMethod != NULL);
-
-    mGetUriMethod = env->GetMethodID(
-            media2HTTPConnectionClass.get(),
-            "getUri",
-            "()Ljava/lang/String;");
-    CHECK(mGetUriMethod != NULL);
-
-    ScopedLocalRef<jbyteArray> tmp(
-        env, env->NewByteArray(kBufferSize));
-    mByteArrayObj = (jbyteArray)env->NewGlobalRef(tmp.get());
-    CHECK(mByteArrayObj != NULL);
-}
-
-JMedia2HTTPConnection::~JMedia2HTTPConnection() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    env->DeleteGlobalRef(mMedia2HTTPConnectionObj);
-    env->DeleteGlobalRef(mByteArrayObj);
-}
-
-bool JMedia2HTTPConnection::connect(
-        const char *uri, const KeyedVector<String8, String8> *headers) {
-    String8 tmp("");
-    if (headers != NULL) {
-        for (size_t i = 0; i < headers->size(); ++i) {
-            tmp.append(headers->keyAt(i));
-            tmp.append(String8(": "));
-            tmp.append(headers->valueAt(i));
-            tmp.append(String8("\r\n"));
-        }
-    }
-
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    jstring juri = env->NewStringUTF(uri);
-    jstring jheaders = env->NewStringUTF(tmp.string());
-
-    jboolean ret =
-        env->CallBooleanMethod(mMedia2HTTPConnectionObj, mConnectMethod, juri, jheaders);
-
-    env->DeleteLocalRef(juri);
-    env->DeleteLocalRef(jheaders);
-
-    return (bool)ret;
-}
-
-void JMedia2HTTPConnection::disconnect() {
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    env->CallVoidMethod(mMedia2HTTPConnectionObj, mDisconnectMethod);
-}
-
-ssize_t JMedia2HTTPConnection::readAt(off64_t offset, void *data, size_t size) {
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-
-    if (size > kBufferSize) {
-        size = kBufferSize;
-    }
-
-    jint n = env->CallIntMethod(
-            mMedia2HTTPConnectionObj, mReadAtMethod, (jlong)offset, mByteArrayObj, (jint)size);
-
-    if (n > 0) {
-        env->GetByteArrayRegion(
-                mByteArrayObj,
-                0,
-                n,
-                (jbyte *)data);
-    }
-
-    return n;
-}
-
-off64_t JMedia2HTTPConnection::getSize() {
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    return (off64_t)(env->CallLongMethod(mMedia2HTTPConnectionObj, mGetSizeMethod));
-}
-
-status_t JMedia2HTTPConnection::getMIMEType(String8 *mimeType) {
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    jstring jmime = (jstring)env->CallObjectMethod(mMedia2HTTPConnectionObj, mGetMIMETypeMethod);
-    jboolean flag = env->ExceptionCheck();
-    if (flag) {
-        env->ExceptionClear();
-        return UNKNOWN_ERROR;
-    }
-
-    const char *str = env->GetStringUTFChars(jmime, 0);
-    if (str != NULL) {
-        *mimeType = String8(str);
-    } else {
-        *mimeType = "application/octet-stream";
-    }
-    env->ReleaseStringUTFChars(jmime, str);
-    return OK;
-}
-
-status_t JMedia2HTTPConnection::getUri(String8 *uri) {
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    jstring juri = (jstring)env->CallObjectMethod(mMedia2HTTPConnectionObj, mGetUriMethod);
-    jboolean flag = env->ExceptionCheck();
-    if (flag) {
-        env->ExceptionClear();
-        return UNKNOWN_ERROR;
-    }
-
-    const char *str = env->GetStringUTFChars(juri, 0);
-    *uri = String8(str);
-    env->ReleaseStringUTFChars(juri, str);
-    return OK;
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/JMedia2HTTPService.cpp b/media/libmediaplayer2/JMedia2HTTPService.cpp
deleted file mode 100644
index 20e3573..0000000
--- a/media/libmediaplayer2/JMedia2HTTPService.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2017, 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 "JMedia2HTTPService"
-#include <utils/Log.h>
-
-#include <jni.h>
-
-#include <mediaplayer2/JavaVMHelper.h>
-#include <mediaplayer2/JMedia2HTTPService.h>
-#include <mediaplayer2/JMedia2HTTPConnection.h>
-#include <media/stagefright/foundation/ADebug.h>
-
-#include <nativehelper/scoped_local_ref.h>
-
-namespace android {
-
-JMedia2HTTPService::JMedia2HTTPService(JNIEnv *env, jobject thiz) {
-    mMedia2HTTPServiceObj = env->NewGlobalRef(thiz);
-    CHECK(mMedia2HTTPServiceObj != NULL);
-
-    ScopedLocalRef<jclass> media2HTTPServiceClass(env, env->GetObjectClass(mMedia2HTTPServiceObj));
-    CHECK(media2HTTPServiceClass.get() != NULL);
-
-    mMakeHTTPConnectionMethod = env->GetMethodID(
-            media2HTTPServiceClass.get(),
-            "makeHTTPConnection",
-            "()Landroid/media/Media2HTTPConnection;");
-    CHECK(mMakeHTTPConnectionMethod != NULL);
-}
-
-JMedia2HTTPService::~JMedia2HTTPService() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    env->DeleteGlobalRef(mMedia2HTTPServiceObj);
-}
-
-sp<MediaHTTPConnection> JMedia2HTTPService::makeHTTPConnection() {
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    jobject media2HTTPConnectionObj =
-        env->CallObjectMethod(mMedia2HTTPServiceObj, mMakeHTTPConnectionMethod);
-
-    return new JMedia2HTTPConnection(env, media2HTTPConnectionObj);
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/JavaVMHelper.cpp b/media/libmediaplayer2/JavaVMHelper.cpp
deleted file mode 100644
index 8d03ed0..0000000
--- a/media/libmediaplayer2/JavaVMHelper.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright 2018 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_TAG "JavaVMHelper"
-
-#include "mediaplayer2/JavaVMHelper.h"
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <utils/threads.h>
-
-#include <stdlib.h>
-
-namespace android {
-
-// static
-std::atomic<JavaVM *> JavaVMHelper::sJavaVM(NULL);
-
-/*
- * Makes the current thread visible to the VM.
- *
- * The JNIEnv pointer returned is only valid for the current thread, and
- * thus must be tucked into thread-local storage.
- */
-static int javaAttachThread(const char* threadName, JNIEnv** pEnv) {
-    JavaVMAttachArgs args;
-    JavaVM* vm;
-    jint result;
-
-    vm = JavaVMHelper::getJavaVM();
-    if (vm == NULL) {
-        return JNI_ERR;
-    }
-
-    args.version = JNI_VERSION_1_4;
-    args.name = (char*) threadName;
-    args.group = NULL;
-
-    result = vm->AttachCurrentThread(pEnv, (void*) &args);
-    if (result != JNI_OK) {
-        ALOGI("NOTE: attach of thread '%s' failed\n", threadName);
-    }
-
-    return result;
-}
-
-/*
- * Detach the current thread from the set visible to the VM.
- */
-static int javaDetachThread(void) {
-    JavaVM* vm;
-    jint result;
-
-    vm = JavaVMHelper::getJavaVM();
-    if (vm == NULL) {
-        return JNI_ERR;
-    }
-
-    result = vm->DetachCurrentThread();
-    if (result != JNI_OK) {
-        ALOGE("ERROR: thread detach failed\n");
-    }
-    return result;
-}
-
-/*
- * When starting a native thread that will be visible from the VM, we
- * bounce through this to get the right attach/detach action.
- * Note that this function calls free(args)
- */
-static int javaThreadShell(void* args) {
-    void* start = ((void**)args)[0];
-    void* userData = ((void **)args)[1];
-    char* name = (char*) ((void **)args)[2];        // we own this storage
-    free(args);
-    JNIEnv* env;
-    int result;
-
-    /* hook us into the VM */
-    if (javaAttachThread(name, &env) != JNI_OK) {
-        return -1;
-    }
-
-    /* start the thread running */
-    result = (*(android_thread_func_t)start)(userData);
-
-    /* unhook us */
-    javaDetachThread();
-    free(name);
-
-    return result;
-}
-
-/*
- * This is invoked from androidCreateThreadEtc() via the callback
- * set with androidSetCreateThreadFunc().
- *
- * We need to create the new thread in such a way that it gets hooked
- * into the VM before it really starts executing.
- */
-static int javaCreateThreadEtc(
-        android_thread_func_t entryFunction,
-        void* userData,
-        const char* threadName,
-        int32_t threadPriority,
-        size_t threadStackSize,
-        android_thread_id_t* threadId) {
-    void** args = (void**) malloc(3 * sizeof(void*));   // javaThreadShell must free
-    int result;
-
-    LOG_ALWAYS_FATAL_IF(threadName == nullptr, "threadName not provided to javaCreateThreadEtc");
-
-    args[0] = (void*) entryFunction;
-    args[1] = userData;
-    args[2] = (void*) strdup(threadName);   // javaThreadShell must free
-
-    result = androidCreateRawThreadEtc(javaThreadShell, args,
-        threadName, threadPriority, threadStackSize, threadId);
-    return result;
-}
-
-// static
-JNIEnv *JavaVMHelper::getJNIEnv() {
-    JNIEnv *env;
-    JavaVM *vm = sJavaVM.load();
-    CHECK(vm != NULL);
-
-    if (vm->GetEnv((void **)&env, JNI_VERSION_1_4) != JNI_OK) {
-        return NULL;
-    }
-
-    return env;
-}
-
-//static
-JavaVM *JavaVMHelper::getJavaVM() {
-    return sJavaVM.load();
-}
-
-// static
-void JavaVMHelper::setJavaVM(JavaVM *vm) {
-    sJavaVM.store(vm);
-
-    // Ensure that Thread(/*canCallJava*/ true) in libutils is attached to the VM.
-    // This is supposed to be done by runtime, but when libutils is used with linker
-    // namespace, CreateThreadFunc should be initialized separately within the namespace.
-    androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp b/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
deleted file mode 100644
index b4fa0c1..0000000
--- a/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
+++ /dev/null
@@ -1,656 +0,0 @@
-/*
-**
-** Copyright 2018, 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 "MediaPlayer2AudioOutput"
-#include <mediaplayer2/MediaPlayer2AudioOutput.h>
-
-#include <cutils/properties.h> // for property_get
-#include <utils/Log.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-
-namespace {
-
-const float kMaxRequiredSpeed = 8.0f; // for PCM tracks allow up to 8x speedup.
-
-} // anonymous namespace
-
-namespace android {
-
-// TODO: Find real cause of Audio/Video delay in PV framework and remove this workaround
-/* static */ int MediaPlayer2AudioOutput::mMinBufferCount = 4;
-/* static */ bool MediaPlayer2AudioOutput::mIsOnEmulator = false;
-
-status_t MediaPlayer2AudioOutput::dump(int fd, const Vector<String16>& args) const {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    result.append(" MediaPlayer2AudioOutput\n");
-    snprintf(buffer, 255, "  volume(%f)\n", mVolume);
-    result.append(buffer);
-    snprintf(buffer, 255, "  msec per frame(%f), latency (%d)\n",
-            mMsecsPerFrame, (mJAudioTrack != nullptr) ? mJAudioTrack->latency() : -1);
-    result.append(buffer);
-    snprintf(buffer, 255, "  aux effect id(%d), send level (%f)\n",
-            mAuxEffectId, mSendLevel);
-    result.append(buffer);
-
-    ::write(fd, result.string(), result.size());
-    if (mJAudioTrack != nullptr) {
-        mJAudioTrack->dump(fd, args);
-    }
-    return NO_ERROR;
-}
-
-MediaPlayer2AudioOutput::MediaPlayer2AudioOutput(int32_t sessionId, uid_t uid, int pid,
-        const jobject attributes)
-    : mCallback(nullptr),
-      mCallbackCookie(nullptr),
-      mCallbackData(nullptr),
-      mVolume(1.0),
-      mPlaybackRate(AUDIO_PLAYBACK_RATE_DEFAULT),
-      mSampleRateHz(0),
-      mMsecsPerFrame(0),
-      mFrameSize(0),
-      mSessionId(sessionId),
-      mUid(uid),
-      mPid(pid),
-      mSendLevel(0.0),
-      mAuxEffectId(0),
-      mFlags(AUDIO_OUTPUT_FLAG_NONE) {
-    ALOGV("MediaPlayer2AudioOutput(%d)", sessionId);
-
-    if (attributes != nullptr) {
-        mAttributes = new JObjectHolder(attributes);
-    }
-
-    setMinBufferCount();
-    mRoutingDelegates.clear();
-}
-
-MediaPlayer2AudioOutput::~MediaPlayer2AudioOutput() {
-    close();
-    delete mCallbackData;
-}
-
-//static
-void MediaPlayer2AudioOutput::setMinBufferCount() {
-    char value[PROPERTY_VALUE_MAX];
-    if (property_get("ro.kernel.qemu", value, 0)) {
-        mIsOnEmulator = true;
-        mMinBufferCount = 12;  // to prevent systematic buffer underrun for emulator
-    }
-}
-
-// static
-bool MediaPlayer2AudioOutput::isOnEmulator() {
-    setMinBufferCount();  // benign race wrt other threads
-    return mIsOnEmulator;
-}
-
-// static
-int MediaPlayer2AudioOutput::getMinBufferCount() {
-    setMinBufferCount();  // benign race wrt other threads
-    return mMinBufferCount;
-}
-
-ssize_t MediaPlayer2AudioOutput::bufferSize() const {
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == nullptr) {
-        return NO_INIT;
-    }
-    return mJAudioTrack->frameCount() * mFrameSize;
-}
-
-ssize_t MediaPlayer2AudioOutput::frameCount() const {
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == nullptr) {
-        return NO_INIT;
-    }
-    return mJAudioTrack->frameCount();
-}
-
-ssize_t MediaPlayer2AudioOutput::channelCount() const {
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == nullptr) {
-        return NO_INIT;
-    }
-    return mJAudioTrack->channelCount();
-}
-
-ssize_t MediaPlayer2AudioOutput::frameSize() const {
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == nullptr) {
-        return NO_INIT;
-    }
-    return mFrameSize;
-}
-
-uint32_t MediaPlayer2AudioOutput::latency () const {
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == nullptr) {
-        return 0;
-    }
-    return mJAudioTrack->latency();
-}
-
-float MediaPlayer2AudioOutput::msecsPerFrame() const {
-    Mutex::Autolock lock(mLock);
-    return mMsecsPerFrame;
-}
-
-status_t MediaPlayer2AudioOutput::getPosition(uint32_t *position) const {
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == nullptr) {
-        return NO_INIT;
-    }
-    return mJAudioTrack->getPosition(position);
-}
-
-status_t MediaPlayer2AudioOutput::getTimestamp(AudioTimestamp &ts) const {
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == nullptr) {
-        return NO_INIT;
-    }
-    return mJAudioTrack->getTimestamp(ts);
-}
-
-// TODO: Remove unnecessary calls to getPlayedOutDurationUs()
-// as it acquires locks and may query the audio driver.
-//
-// Some calls could conceivably retrieve extrapolated data instead of
-// accessing getTimestamp() or getPosition() every time a data buffer with
-// a media time is received.
-//
-// Calculate duration of played samples if played at normal rate (i.e., 1.0).
-int64_t MediaPlayer2AudioOutput::getPlayedOutDurationUs(int64_t nowUs) const {
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == nullptr || mSampleRateHz == 0) {
-        return 0;
-    }
-
-    uint32_t numFramesPlayed;
-    int64_t numFramesPlayedAtUs;
-    AudioTimestamp ts;
-
-    status_t res = mJAudioTrack->getTimestamp(ts);
-
-    if (res == OK) {                 // case 1: mixing audio tracks and offloaded tracks.
-        numFramesPlayed = ts.mPosition;
-        numFramesPlayedAtUs = ts.mTime.tv_sec * 1000000LL + ts.mTime.tv_nsec / 1000;
-        //ALOGD("getTimestamp: OK %d %lld", numFramesPlayed, (long long)numFramesPlayedAtUs);
-    } else {                         // case 2: transitory state on start of a new track
-                                     // case 3: transitory at new track or audio fast tracks.
-        numFramesPlayed = 0;
-        numFramesPlayedAtUs = nowUs;
-        //ALOGD("getTimestamp: WOULD_BLOCK %d %lld",
-        //        numFramesPlayed, (long long)numFramesPlayedAtUs);
-    }
-
-    // CHECK_EQ(numFramesPlayed & (1 << 31), 0);  // can't be negative until 12.4 hrs, test
-    // TODO: remove the (int32_t) casting below as it may overflow at 12.4 hours.
-    int64_t durationUs = (int64_t)((int32_t)numFramesPlayed * 1000000LL / mSampleRateHz)
-            + nowUs - numFramesPlayedAtUs;
-    if (durationUs < 0) {
-        // Occurs when numFramesPlayed position is very small and the following:
-        // (1) In case 1, the time nowUs is computed before getTimestamp() is called and
-        //     numFramesPlayedAtUs is greater than nowUs by time more than numFramesPlayed.
-        // (2) In case 3, using getPosition and adding mAudioSink->latency() to
-        //     numFramesPlayedAtUs, by a time amount greater than numFramesPlayed.
-        //
-        // Both of these are transitory conditions.
-        ALOGV("getPlayedOutDurationUs: negative duration %lld set to zero", (long long)durationUs);
-        durationUs = 0;
-    }
-    ALOGV("getPlayedOutDurationUs(%lld) nowUs(%lld) frames(%u) framesAt(%lld)",
-            (long long)durationUs, (long long)nowUs,
-            numFramesPlayed, (long long)numFramesPlayedAtUs);
-    return durationUs;
-}
-
-status_t MediaPlayer2AudioOutput::getFramesWritten(uint32_t *frameswritten) const {
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == nullptr) {
-        return NO_INIT;
-    }
-    ExtendedTimestamp ets;
-    status_t status = mJAudioTrack->getTimestamp(&ets);
-    if (status == OK || status == WOULD_BLOCK) {
-        *frameswritten = (uint32_t)ets.mPosition[ExtendedTimestamp::LOCATION_CLIENT];
-    }
-    return status;
-}
-
-void MediaPlayer2AudioOutput::setAudioAttributes(const jobject attributes) {
-    Mutex::Autolock lock(mLock);
-    mAttributes = (attributes == nullptr) ? nullptr : new JObjectHolder(attributes);
-}
-
-audio_stream_type_t MediaPlayer2AudioOutput::getAudioStreamType() const {
-    ALOGV("getAudioStreamType");
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == nullptr) {
-        return AUDIO_STREAM_DEFAULT;
-    }
-    return mJAudioTrack->getAudioStreamType();
-}
-
-void MediaPlayer2AudioOutput::close_l() {
-    mJAudioTrack.clear();
-}
-
-status_t MediaPlayer2AudioOutput::open(
-        uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
-        audio_format_t format,
-        AudioCallback cb, void *cookie,
-        audio_output_flags_t flags,
-        const audio_offload_info_t *offloadInfo,
-        uint32_t suggestedFrameCount) {
-    ALOGV("open(%u, %d, 0x%x, 0x%x, %d 0x%x)", sampleRate, channelCount, channelMask,
-                format, mSessionId, flags);
-
-    // offloading is only supported in callback mode for now.
-    // offloadInfo must be present if offload flag is set
-    if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) &&
-            ((cb == nullptr) || (offloadInfo == nullptr))) {
-        return BAD_VALUE;
-    }
-
-    // compute frame count for the AudioTrack internal buffer
-    const size_t frameCount =
-           ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) ? 0 : suggestedFrameCount;
-
-    if (channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER) {
-        channelMask = audio_channel_out_mask_from_count(channelCount);
-        if (0 == channelMask) {
-            ALOGE("open() error, can\'t derive mask for %d audio channels", channelCount);
-            return NO_INIT;
-        }
-    }
-
-    Mutex::Autolock lock(mLock);
-    mCallback = cb;
-    mCallbackCookie = cookie;
-
-    sp<JAudioTrack> jT;
-    CallbackData *newcbd = nullptr;
-
-    ALOGV("creating new JAudioTrack");
-
-    if (mCallback != nullptr) {
-        newcbd = new CallbackData(this);
-        jT = new JAudioTrack(
-                 sampleRate,
-                 format,
-                 channelMask,
-                 CallbackWrapper,
-                 newcbd,
-                 frameCount,
-                 mSessionId,
-                 mAttributes != nullptr ? mAttributes->getJObject() : nullptr,
-                 1.0f);  // default value for maxRequiredSpeed
-    } else {
-        // TODO: Due to buffer memory concerns, we use a max target playback speed
-        // based on mPlaybackRate at the time of open (instead of kMaxRequiredSpeed),
-        // also clamping the target speed to 1.0 <= targetSpeed <= kMaxRequiredSpeed.
-        const float targetSpeed =
-                std::min(std::max(mPlaybackRate.mSpeed, 1.0f), kMaxRequiredSpeed);
-        ALOGW_IF(targetSpeed != mPlaybackRate.mSpeed,
-                "track target speed:%f clamped from playback speed:%f",
-                targetSpeed, mPlaybackRate.mSpeed);
-        jT = new JAudioTrack(
-                 sampleRate,
-                 format,
-                 channelMask,
-                 nullptr,
-                 nullptr,
-                 frameCount,
-                 mSessionId,
-                 mAttributes != nullptr ? mAttributes->getJObject() : nullptr,
-                 targetSpeed);
-    }
-
-    if (jT == 0) {
-        ALOGE("Unable to create audio track");
-        delete newcbd;
-        // t goes out of scope, so reference count drops to zero
-        return NO_INIT;
-    }
-
-    CHECK((jT != nullptr) && ((mCallback == nullptr) || (newcbd != nullptr)));
-
-    mCallbackData = newcbd;
-    ALOGV("setVolume");
-    jT->setVolume(mVolume);
-
-    mSampleRateHz = sampleRate;
-    mFlags = flags;
-    mMsecsPerFrame = 1E3f / (mPlaybackRate.mSpeed * sampleRate);
-    mFrameSize = jT->frameSize();
-    mJAudioTrack = jT;
-
-    return updateTrack_l();
-}
-
-status_t MediaPlayer2AudioOutput::updateTrack_l() {
-    if (mJAudioTrack == nullptr) {
-        return NO_ERROR;
-    }
-
-    status_t res = NO_ERROR;
-    // Note some output devices may give us a direct track even though we don't specify it.
-    // Example: Line application b/17459982.
-    if ((mJAudioTrack->getFlags()
-            & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD | AUDIO_OUTPUT_FLAG_DIRECT)) == 0) {
-        res = mJAudioTrack->setPlaybackRate(mPlaybackRate);
-        if (res == NO_ERROR) {
-            mJAudioTrack->setAuxEffectSendLevel(mSendLevel);
-            res = mJAudioTrack->attachAuxEffect(mAuxEffectId);
-        }
-    }
-    if (mPreferredDevice != nullptr) {
-        mJAudioTrack->setPreferredDevice(mPreferredDevice->getJObject());
-    }
-
-    mJAudioTrack->registerRoutingDelegates(mRoutingDelegates);
-
-    ALOGV("updateTrack_l() DONE status %d", res);
-    return res;
-}
-
-status_t MediaPlayer2AudioOutput::start() {
-    ALOGV("start");
-    Mutex::Autolock lock(mLock);
-    if (mCallbackData != nullptr) {
-        mCallbackData->endTrackSwitch();
-    }
-    if (mJAudioTrack != nullptr) {
-        mJAudioTrack->setVolume(mVolume);
-        mJAudioTrack->setAuxEffectSendLevel(mSendLevel);
-        status_t status = mJAudioTrack->start();
-        return status;
-    }
-    return NO_INIT;
-}
-
-ssize_t MediaPlayer2AudioOutput::write(const void* buffer, size_t size, bool blocking) {
-    Mutex::Autolock lock(mLock);
-    LOG_ALWAYS_FATAL_IF(mCallback != nullptr, "Don't call write if supplying a callback.");
-
-    //ALOGV("write(%p, %u)", buffer, size);
-    if (mJAudioTrack != nullptr) {
-        return mJAudioTrack->write(buffer, size, blocking);
-    }
-    return NO_INIT;
-}
-
-void MediaPlayer2AudioOutput::stop() {
-    ALOGV("stop");
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack != nullptr) {
-        mJAudioTrack->stop();
-    }
-}
-
-void MediaPlayer2AudioOutput::flush() {
-    ALOGV("flush");
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack != nullptr) {
-        mJAudioTrack->flush();
-    }
-}
-
-void MediaPlayer2AudioOutput::pause() {
-    ALOGV("pause");
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack != nullptr) {
-        mJAudioTrack->pause();
-    }
-}
-
-void MediaPlayer2AudioOutput::close() {
-    ALOGV("close");
-    sp<JAudioTrack> track;
-    {
-        Mutex::Autolock lock(mLock);
-        track = mJAudioTrack;
-        close_l(); // clears mJAudioTrack
-    }
-    // destruction of the track occurs outside of mutex.
-}
-
-void MediaPlayer2AudioOutput::setVolume(float volume) {
-    ALOGV("setVolume(%f)", volume);
-    Mutex::Autolock lock(mLock);
-    mVolume = volume;
-    if (mJAudioTrack != nullptr) {
-        mJAudioTrack->setVolume(volume);
-    }
-}
-
-status_t MediaPlayer2AudioOutput::setPlaybackRate(const AudioPlaybackRate &rate) {
-    ALOGV("setPlaybackRate(%f %f %d %d)",
-                rate.mSpeed, rate.mPitch, rate.mFallbackMode, rate.mStretchMode);
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == 0) {
-        // remember rate so that we can set it when the track is opened
-        mPlaybackRate = rate;
-        return OK;
-    }
-    status_t res = mJAudioTrack->setPlaybackRate(rate);
-    if (res != NO_ERROR) {
-        return res;
-    }
-    // rate.mSpeed is always greater than 0 if setPlaybackRate succeeded
-    CHECK_GT(rate.mSpeed, 0.f);
-    mPlaybackRate = rate;
-    if (mSampleRateHz != 0) {
-        mMsecsPerFrame = 1E3f / (rate.mSpeed * mSampleRateHz);
-    }
-    return res;
-}
-
-status_t MediaPlayer2AudioOutput::getPlaybackRate(AudioPlaybackRate *rate) {
-    ALOGV("getPlaybackRate");
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == 0) {
-        return NO_INIT;
-    }
-    *rate = mJAudioTrack->getPlaybackRate();
-    return NO_ERROR;
-}
-
-status_t MediaPlayer2AudioOutput::setAuxEffectSendLevel(float level) {
-    ALOGV("setAuxEffectSendLevel(%f)", level);
-    Mutex::Autolock lock(mLock);
-    mSendLevel = level;
-    if (mJAudioTrack != nullptr) {
-        return mJAudioTrack->setAuxEffectSendLevel(level);
-    }
-    return NO_ERROR;
-}
-
-status_t MediaPlayer2AudioOutput::attachAuxEffect(int effectId) {
-    ALOGV("attachAuxEffect(%d)", effectId);
-    Mutex::Autolock lock(mLock);
-    mAuxEffectId = effectId;
-    if (mJAudioTrack != nullptr) {
-        return mJAudioTrack->attachAuxEffect(effectId);
-    }
-    return NO_ERROR;
-}
-
-status_t MediaPlayer2AudioOutput::setPreferredDevice(jobject device) {
-    ALOGV("setPreferredDevice");
-    Mutex::Autolock lock(mLock);
-    status_t ret = NO_ERROR;
-    if (mJAudioTrack != nullptr) {
-        ret = mJAudioTrack->setPreferredDevice(device);
-    }
-    if (ret == NO_ERROR) {
-        mPreferredDevice = new JObjectHolder(device);
-    }
-    return ret;
-}
-
-jobject MediaPlayer2AudioOutput::getRoutedDevice() {
-    ALOGV("getRoutedDevice");
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack != nullptr) {
-        return mJAudioTrack->getRoutedDevice();
-    }
-    return nullptr;
-}
-
-status_t MediaPlayer2AudioOutput::addAudioDeviceCallback(jobject jRoutingDelegate) {
-    ALOGV("addAudioDeviceCallback");
-    Mutex::Autolock lock(mLock);
-    jobject listener = JAudioTrack::getListener(jRoutingDelegate);
-    if (JAudioTrack::findByKey(mRoutingDelegates, listener) == nullptr) {
-        sp<JObjectHolder> listenerHolder = new JObjectHolder(listener);
-        jobject handler = JAudioTrack::getHandler(jRoutingDelegate);
-        sp<JObjectHolder> routingDelegateHolder = new JObjectHolder(jRoutingDelegate);
-
-        mRoutingDelegates.push_back(std::pair<sp<JObjectHolder>, sp<JObjectHolder>>(
-                listenerHolder, routingDelegateHolder));
-
-        if (mJAudioTrack != nullptr) {
-            return mJAudioTrack->addAudioDeviceCallback(
-                    routingDelegateHolder->getJObject(), handler);
-        }
-    }
-    return NO_ERROR;
-}
-
-status_t MediaPlayer2AudioOutput::removeAudioDeviceCallback(jobject listener) {
-    ALOGV("removeAudioDeviceCallback");
-    Mutex::Autolock lock(mLock);
-    jobject routingDelegate = nullptr;
-    if ((routingDelegate = JAudioTrack::findByKey(mRoutingDelegates, listener)) != nullptr) {
-        if (mJAudioTrack != nullptr) {
-            mJAudioTrack->removeAudioDeviceCallback(routingDelegate);
-        }
-        JAudioTrack::eraseByKey(mRoutingDelegates, listener);
-    }
-    return NO_ERROR;
-}
-
-// static
-void MediaPlayer2AudioOutput::CallbackWrapper(
-        int event, void *cookie, void *info) {
-    //ALOGV("callbackwrapper");
-    CallbackData *data = (CallbackData*)cookie;
-    // lock to ensure we aren't caught in the middle of a track switch.
-    data->lock();
-    MediaPlayer2AudioOutput *me = data->getOutput();
-    JAudioTrack::Buffer *buffer = (JAudioTrack::Buffer *)info;
-    if (me == nullptr) {
-        // no output set, likely because the track was scheduled to be reused
-        // by another player, but the format turned out to be incompatible.
-        data->unlock();
-        if (buffer != nullptr) {
-            buffer->mSize = 0;
-        }
-        return;
-    }
-
-    switch(event) {
-    case JAudioTrack::EVENT_MORE_DATA: {
-        size_t actualSize = (*me->mCallback)(
-                me, buffer->mData, buffer->mSize, me->mCallbackCookie,
-                CB_EVENT_FILL_BUFFER);
-
-        // Log when no data is returned from the callback.
-        // (1) We may have no data (especially with network streaming sources).
-        // (2) We may have reached the EOS and the audio track is not stopped yet.
-        // Note that AwesomePlayer/AudioPlayer will only return zero size when it reaches the EOS.
-        // NuPlayer2Renderer will return zero when it doesn't have data (it doesn't block to fill).
-        //
-        // This is a benign busy-wait, with the next data request generated 10 ms or more later;
-        // nevertheless for power reasons, we don't want to see too many of these.
-
-        ALOGV_IF(actualSize == 0 && buffer->mSize > 0, "callbackwrapper: empty buffer returned");
-
-        buffer->mSize = actualSize;
-        } break;
-
-    case JAudioTrack::EVENT_STREAM_END:
-        // currently only occurs for offloaded callbacks
-        ALOGV("callbackwrapper: deliver EVENT_STREAM_END");
-        (*me->mCallback)(me, nullptr /* buffer */, 0 /* size */,
-                me->mCallbackCookie, CB_EVENT_STREAM_END);
-        break;
-
-    case JAudioTrack::EVENT_NEW_IAUDIOTRACK :
-        ALOGV("callbackwrapper: deliver EVENT_TEAR_DOWN");
-        (*me->mCallback)(me,  nullptr /* buffer */, 0 /* size */,
-                me->mCallbackCookie, CB_EVENT_TEAR_DOWN);
-        break;
-
-    case JAudioTrack::EVENT_UNDERRUN:
-        // This occurs when there is no data available, typically
-        // when there is a failure to supply data to the AudioTrack.  It can also
-        // occur in non-offloaded mode when the audio device comes out of standby.
-        //
-        // If an AudioTrack underruns it outputs silence. Since this happens suddenly
-        // it may sound like an audible pop or glitch.
-        //
-        // The underrun event is sent once per track underrun; the condition is reset
-        // when more data is sent to the AudioTrack.
-        ALOGD("callbackwrapper: EVENT_UNDERRUN (discarded)");
-        break;
-
-    default:
-        ALOGE("received unknown event type: %d inside CallbackWrapper !", event);
-    }
-
-    data->unlock();
-}
-
-int32_t MediaPlayer2AudioOutput::getSessionId() const {
-    Mutex::Autolock lock(mLock);
-    return mSessionId;
-}
-
-void MediaPlayer2AudioOutput::setSessionId(const int32_t sessionId) {
-    Mutex::Autolock lock(mLock);
-    mSessionId = sessionId;
-}
-
-uint32_t MediaPlayer2AudioOutput::getSampleRate() const {
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == 0) {
-        return 0;
-    }
-    return mJAudioTrack->getSampleRate();
-}
-
-int64_t MediaPlayer2AudioOutput::getBufferDurationInUs() const {
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == 0) {
-        return 0;
-    }
-    int64_t duration;
-    if (mJAudioTrack->getBufferDurationInUs(&duration) != OK) {
-        return 0;
-    }
-    return duration;
-}
-
-} // namespace android
diff --git a/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h b/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h
deleted file mode 100644
index 2ed4632..0000000
--- a/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * Copyright 2018 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.
- */
-
-#ifndef ANDROID_JAUDIOTRACK_H
-#define ANDROID_JAUDIOTRACK_H
-
-#include <utility>
-#include <jni.h>
-#include <media/AudioResamplerPublic.h>
-#include <media/AudioSystem.h>
-#include <media/VolumeShaper.h>
-#include <system/audio.h>
-#include <utils/Errors.h>
-#include <utils/Vector.h>
-#include <mediaplayer2/JObjectHolder.h>
-#include <media/AudioTimestamp.h>   // It has dependency on audio.h/Errors.h, but doesn't
-                                    // include them in it. Therefore it is included here at last.
-
-namespace android {
-
-class JAudioTrack : public RefBase {
-public:
-
-    /* Events used by AudioTrack callback function (callback_t).
-     * Keep in sync with frameworks/base/media/java/android/media/AudioTrack.java NATIVE_EVENT_*.
-     */
-    enum event_type {
-        EVENT_MORE_DATA = 0,        // Request to write more data to buffer.
-        EVENT_UNDERRUN = 1,         // Buffer underrun occurred. This will not occur for
-                                    // static tracks.
-        EVENT_NEW_IAUDIOTRACK = 6,  // IAudioTrack was re-created, either due to re-routing and
-                                    // voluntary invalidation by mediaserver, or mediaserver crash.
-        EVENT_STREAM_END = 7,       // Sent after all the buffers queued in AF and HW are played
-                                    // back (after stop is called) for an offloaded track.
-    };
-
-    class Buffer
-    {
-    public:
-        size_t      mSize;        // input/output in bytes.
-        void*       mData;        // pointer to the audio data.
-    };
-
-    /* As a convenience, if a callback is supplied, a handler thread
-     * is automatically created with the appropriate priority. This thread
-     * invokes the callback when a new buffer becomes available or various conditions occur.
-     *
-     * Parameters:
-     *
-     * event:   type of event notified (see enum AudioTrack::event_type).
-     * user:    Pointer to context for use by the callback receiver.
-     * info:    Pointer to optional parameter according to event type:
-     *          - EVENT_MORE_DATA: pointer to JAudioTrack::Buffer struct. The callback must not
-     *            write more bytes than indicated by 'size' field and update 'size' if fewer bytes
-     *            are written.
-     *          - EVENT_NEW_IAUDIOTRACK: unused.
-     *          - EVENT_STREAM_END: unused.
-     */
-
-    typedef void (*callback_t)(int event, void* user, void *info);
-
-    /* Creates an JAudioTrack object for non-offload mode.
-     * Once created, the track needs to be started before it can be used.
-     * Unspecified values are set to appropriate default values.
-     *
-     * Parameters:
-     *
-     * streamType:         Select the type of audio stream this track is attached to
-     *                     (e.g. AUDIO_STREAM_MUSIC).
-     * sampleRate:         Data source sampling rate in Hz.  Zero means to use the sink sample rate.
-     *                     A non-zero value must be specified if AUDIO_OUTPUT_FLAG_DIRECT is set.
-     *                     0 will not work with current policy implementation for direct output
-     *                     selection where an exact match is needed for sampling rate.
-     *                     (TODO: Check direct output after flags can be used in Java AudioTrack.)
-     * format:             Audio format. For mixed tracks, any PCM format supported by server is OK.
-     *                     For direct and offloaded tracks, the possible format(s) depends on the
-     *                     output sink.
-     *                     (TODO: How can we check whether a format is supported?)
-     * channelMask:        Channel mask, such that audio_is_output_channel(channelMask) is true.
-     * cbf:                Callback function. If not null, this function is called periodically
-     *                     to provide new data and inform of marker, position updates, etc.
-     * user:               Context for use by the callback receiver.
-     * frameCount:         Minimum size of track PCM buffer in frames. This defines the
-     *                     application's contribution to the latency of the track.
-     *                     The actual size selected by the JAudioTrack could be larger if the
-     *                     requested size is not compatible with current audio HAL configuration.
-     *                     Zero means to use a default value.
-     * sessionId:          Specific session ID, or zero to use default.
-     * pAttributes:        If not NULL, supersedes streamType for use case selection.
-     * maxRequiredSpeed:   For PCM tracks, this creates an appropriate buffer size that will allow
-     *                     maxRequiredSpeed playback. Values less than 1.0f and greater than
-     *                     AUDIO_TIMESTRETCH_SPEED_MAX will be clamped.  For non-PCM tracks
-     *                     and direct or offloaded tracks, this parameter is ignored.
-     *                     (TODO: Handle this after offload / direct track is supported.)
-     *
-     * TODO: Revive removed arguments after offload mode is supported.
-     */
-    JAudioTrack(uint32_t sampleRate,
-                audio_format_t format,
-                audio_channel_mask_t channelMask,
-                callback_t cbf,
-                void* user,
-                size_t frameCount = 0,
-                int32_t sessionId  = AUDIO_SESSION_ALLOCATE,
-                const jobject pAttributes = NULL,
-                float maxRequiredSpeed = 1.0f);
-
-    /*
-       // Q. May be used in AudioTrack.setPreferredDevice(AudioDeviceInfo)?
-       audio_port_handle_t selectedDeviceId,
-
-       // TODO: No place to use these values.
-       int32_t notificationFrames,
-       const audio_offload_info_t *offloadInfo,
-    */
-
-    virtual ~JAudioTrack();
-
-    size_t frameCount();
-    size_t channelCount();
-
-    /* Returns this track's estimated latency in milliseconds.
-     * This includes the latency due to AudioTrack buffer size, AudioMixer (if any)
-     * and audio hardware driver.
-     */
-    uint32_t latency();
-
-    /* Return the total number of frames played since playback start.
-     * The counter will wrap (overflow) periodically, e.g. every ~27 hours at 44.1 kHz.
-     * It is reset to zero by flush(), reload(), and stop().
-     *
-     * Parameters:
-     *
-     * position: Address where to return play head position.
-     *
-     * Returned status (from utils/Errors.h) can be:
-     *  - NO_ERROR: successful operation
-     *  - BAD_VALUE: position is NULL
-     */
-    status_t getPosition(uint32_t *position);
-
-    // TODO: Does this comment apply same to Java AudioTrack::getTimestamp?
-    // Changed the return type from status_t to bool, since Java AudioTrack::getTimestamp returns
-    // boolean. Will Java getTimestampWithStatus() be public?
-    /* Poll for a timestamp on demand.
-     * Use if EVENT_NEW_TIMESTAMP is not delivered often enough for your needs,
-     * or if you need to get the most recent timestamp outside of the event callback handler.
-     * Caution: calling this method too often may be inefficient;
-     * if you need a high resolution mapping between frame position and presentation time,
-     * consider implementing that at application level, based on the low resolution timestamps.
-     * Returns NO_ERROR if timestamp is valid.
-     *         NO_INIT if finds error, and timestamp parameter will be undefined on return.
-     */
-    status_t getTimestamp(AudioTimestamp& timestamp);
-
-    // TODO: This doc is just copied from AudioTrack.h. Revise it after implemenation.
-    /* Return the extended timestamp, with additional timebase info and improved drain behavior.
-     *
-     * This is similar to the AudioTrack.java API:
-     * getTimestamp(@NonNull AudioTimestamp timestamp, @AudioTimestamp.Timebase int timebase)
-     *
-     * Some differences between this method and the getTimestamp(AudioTimestamp& timestamp) method
-     *
-     *   1. stop() by itself does not reset the frame position.
-     *      A following start() resets the frame position to 0.
-     *   2. flush() by itself does not reset the frame position.
-     *      The frame position advances by the number of frames flushed,
-     *      when the first frame after flush reaches the audio sink.
-     *   3. BOOTTIME clock offsets are provided to help synchronize with
-     *      non-audio streams, e.g. sensor data.
-     *   4. Position is returned with 64 bits of resolution.
-     *
-     * Parameters:
-     *  timestamp: A pointer to the caller allocated ExtendedTimestamp.
-     *
-     * Returns NO_ERROR    on success; timestamp is filled with valid data.
-     *         BAD_VALUE   if timestamp is NULL.
-     *         WOULD_BLOCK if called immediately after start() when the number
-     *                     of frames consumed is less than the
-     *                     overall hardware latency to physical output. In WOULD_BLOCK cases,
-     *                     one might poll again, or use getPosition(), or use 0 position and
-     *                     current time for the timestamp.
-     *                     If WOULD_BLOCK is returned, the timestamp is still
-     *                     modified with the LOCATION_CLIENT portion filled.
-     *         DEAD_OBJECT if AudioFlinger dies or the output device changes and
-     *                     the track cannot be automatically restored.
-     *                     The application needs to recreate the AudioTrack
-     *                     because the audio device changed or AudioFlinger died.
-     *                     This typically occurs for direct or offloaded tracks
-     *                     or if mDoNotReconnect is true.
-     *         INVALID_OPERATION  if called on a offloaded or direct track.
-     *                     Use getTimestamp(AudioTimestamp& timestamp) instead.
-     */
-    status_t getTimestamp(ExtendedTimestamp *timestamp);
-
-    /* Set source playback rate for timestretch
-     * 1.0 is normal speed: < 1.0 is slower, > 1.0 is faster
-     * 1.0 is normal pitch: < 1.0 is lower pitch, > 1.0 is higher pitch
-     *
-     * AUDIO_TIMESTRETCH_SPEED_MIN <= speed <= AUDIO_TIMESTRETCH_SPEED_MAX
-     * AUDIO_TIMESTRETCH_PITCH_MIN <= pitch <= AUDIO_TIMESTRETCH_PITCH_MAX
-     *
-     * Speed increases the playback rate of media, but does not alter pitch.
-     * Pitch increases the "tonal frequency" of media, but does not affect the playback rate.
-     */
-    status_t setPlaybackRate(const AudioPlaybackRate &playbackRate);
-
-    /* Return current playback rate */
-    const AudioPlaybackRate getPlaybackRate();
-
-    /* Sets the volume shaper object */
-    media::VolumeShaper::Status applyVolumeShaper(
-            const sp<media::VolumeShaper::Configuration>& configuration,
-            const sp<media::VolumeShaper::Operation>& operation);
-
-    /* Set the send level for this track. An auxiliary effect should be attached
-     * to the track with attachEffect(). Level must be >= 0.0 and <= 1.0.
-     */
-    status_t setAuxEffectSendLevel(float level);
-
-    /* Attach track auxiliary output to specified effect. Use effectId = 0
-     * to detach track from effect.
-     *
-     * Parameters:
-     *
-     * effectId: effectId obtained from AudioEffect::id().
-     *
-     * Returned status (from utils/Errors.h) can be:
-     *  - NO_ERROR: successful operation
-     *  - INVALID_OPERATION: The effect is not an auxiliary effect.
-     *  - BAD_VALUE: The specified effect ID is invalid.
-     */
-    status_t attachAuxEffect(int effectId);
-
-    /* Set volume for this track, mostly used for games' sound effects
-     * left and right volumes. Levels must be >= 0.0 and <= 1.0.
-     * This is the older API.  New applications should use setVolume(float) when possible.
-     */
-    status_t setVolume(float left, float right);
-
-    /* Set volume for all channels. This is the preferred API for new applications,
-     * especially for multi-channel content.
-     */
-    status_t setVolume(float volume);
-
-    // TODO: Does this comment equally apply to the Java AudioTrack::play()?
-    /* After it's created the track is not active. Call start() to
-     * make it active. If set, the callback will start being called.
-     * If the track was previously paused, volume is ramped up over the first mix buffer.
-     */
-    status_t start();
-
-    // TODO: Does this comment still applies? It seems not. (obtainBuffer, AudioFlinger, ...)
-    /* As a convenience we provide a write() interface to the audio buffer.
-     * Input parameter 'size' is in byte units.
-     * This is implemented on top of obtainBuffer/releaseBuffer. For best
-     * performance use callbacks. Returns actual number of bytes written >= 0,
-     * or one of the following negative status codes:
-     *      INVALID_OPERATION   AudioTrack is configured for static buffer or streaming mode
-     *      BAD_VALUE           size is invalid
-     *      WOULD_BLOCK         when obtainBuffer() returns same, or
-     *                          AudioTrack was stopped during the write
-     *      DEAD_OBJECT         when AudioFlinger dies or the output device changes and
-     *                          the track cannot be automatically restored.
-     *                          The application needs to recreate the AudioTrack
-     *                          because the audio device changed or AudioFlinger died.
-     *                          This typically occurs for direct or offload tracks
-     *                          or if mDoNotReconnect is true.
-     *      or any other error code returned by IAudioTrack::start() or restoreTrack_l().
-     * Default behavior is to only return when all data has been transferred. Set 'blocking' to
-     * false for the method to return immediately without waiting to try multiple times to write
-     * the full content of the buffer.
-     */
-    ssize_t write(const void* buffer, size_t size, bool blocking = true);
-
-    // TODO: Does this comment equally apply to the Java AudioTrack::stop()?
-    /* Stop a track.
-     * In static buffer mode, the track is stopped immediately.
-     * In streaming mode, the callback will cease being called.  Note that obtainBuffer() still
-     * works and will fill up buffers until the pool is exhausted, and then will return WOULD_BLOCK.
-     * In streaming mode the stop does not occur immediately: any data remaining in the buffer
-     * is first drained, mixed, and output, and only then is the track marked as stopped.
-     */
-    void stop();
-    bool stopped() const;
-
-    // TODO: Does this comment equally apply to the Java AudioTrack::flush()?
-    /* Flush a stopped or paused track. All previously buffered data is discarded immediately.
-     * This has the effect of draining the buffers without mixing or output.
-     * Flush is intended for streaming mode, for example before switching to non-contiguous content.
-     * This function is a no-op if the track is not stopped or paused, or uses a static buffer.
-     */
-    void flush();
-
-    // TODO: Does this comment equally apply to the Java AudioTrack::pause()?
-    // At least we are not using obtainBuffer.
-    /* Pause a track. After pause, the callback will cease being called and
-     * obtainBuffer returns WOULD_BLOCK. Note that obtainBuffer() still works
-     * and will fill up buffers until the pool is exhausted.
-     * Volume is ramped down over the next mix buffer following the pause request,
-     * and then the track is marked as paused. It can be resumed with ramp up by start().
-     */
-    void pause();
-
-    bool isPlaying() const;
-
-    /* Return current source sample rate in Hz.
-     * If specified as zero in constructor, this will be the sink sample rate.
-     */
-    uint32_t getSampleRate();
-
-    /* Returns the buffer duration in microseconds at current playback rate. */
-    status_t getBufferDurationInUs(int64_t *duration);
-
-    audio_format_t format();
-
-    size_t frameSize();
-
-    /*
-     * Dumps the state of an audio track.
-     * Not a general-purpose API; intended only for use by media player service to dump its tracks.
-     */
-    status_t dump(int fd, const Vector<String16>& args) const;
-
-    /* Returns the AudioDeviceInfo used by the output to which this AudioTrack is
-     * attached.
-     */
-    jobject getRoutedDevice();
-
-    /* Returns the ID of the audio session this AudioTrack belongs to. */
-    int32_t getAudioSessionId();
-
-    /* Sets the preferred audio device to use for output of this AudioTrack.
-     *
-     * Parameters:
-     * Device: an AudioDeviceInfo object.
-     *
-     * Returned value:
-     *  - NO_ERROR: successful operation
-     *  - BAD_VALUE: failed to set the device
-     */
-    status_t setPreferredDevice(jobject device);
-
-    // TODO: Add AUDIO_OUTPUT_FLAG_DIRECT when it is possible to check.
-    // TODO: Add AUDIO_FLAG_HW_AV_SYNC when it is possible to check.
-    /* Returns the flags */
-    audio_output_flags_t getFlags() const { return mFlags; }
-
-    /* We don't keep stream type here,
-     * instead, we keep attributes and call getVolumeControlStream() to get stream type
-     */
-    audio_stream_type_t getAudioStreamType();
-
-    /* Obtain the pending duration in milliseconds for playback of pure PCM data remaining in
-     * AudioTrack.
-     *
-     * Returns NO_ERROR if successful.
-     *         INVALID_OPERATION if the AudioTrack does not contain pure PCM data.
-     *         BAD_VALUE if msec is nullptr.
-     */
-    status_t pendingDuration(int32_t *msec);
-
-    /* Adds an AudioDeviceCallback. The caller will be notified when the audio device to which this
-     * AudioTrack is routed is updated.
-     * Replaces any previously installed callback.
-     *
-     * Parameters:
-     * Listener: the listener to receive notification of rerouting events.
-     * Handler: the handler to handler the rerouting events.
-     *
-     * Returns NO_ERROR if successful.
-     *         (TODO) INVALID_OPERATION if the same callback is already installed.
-     *         (TODO) NO_INIT or PREMISSION_DENIED if AudioFlinger service is not reachable
-     *         (TODO) BAD_VALUE if the callback is NULL
-     */
-    status_t addAudioDeviceCallback(jobject listener, jobject rd);
-
-    /* Removes an AudioDeviceCallback.
-     *
-     * Parameters:
-     * Listener: the listener to receive notification of rerouting events.
-     *
-     * Returns NO_ERROR if successful.
-     *         (TODO) INVALID_OPERATION if the callback is not installed
-     *         (TODO) BAD_VALUE if the callback is NULL
-     */
-    status_t removeAudioDeviceCallback(jobject listener);
-
-    /* Register all backed-up routing delegates.
-     *
-     * Parameters:
-     * routingDelegates: backed-up routing delegates
-     *
-     */
-    void registerRoutingDelegates(
-            Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& routingDelegates);
-
-    /* get listener from RoutingDelegate object
-     */
-    static jobject getListener(const jobject routingDelegateObj);
-
-    /* get handler from RoutingDelegate object
-     */
-    static jobject getHandler(const jobject routingDelegateObj);
-
-    /*
-     * Parameters:
-     * map and key
-     *
-     * Returns value if key is in the map
-     *         nullptr if key is not in the map
-     */
-    static jobject findByKey(
-            Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& mp, const jobject key);
-
-    /*
-     * Parameters:
-     * map and key
-     */
-    static void eraseByKey(
-            Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& mp, const jobject key);
-
-private:
-    audio_output_flags_t mFlags;
-
-    jclass mAudioTrackCls;
-    jobject mAudioTrackObj;
-
-    /* Creates a Java VolumeShaper.Configuration object from VolumeShaper::Configuration */
-    jobject createVolumeShaperConfigurationObj(
-            const sp<media::VolumeShaper::Configuration>& config);
-
-    /* Creates a Java VolumeShaper.Operation object from VolumeShaper::Operation */
-    jobject createVolumeShaperOperationObj(
-            const sp<media::VolumeShaper::Operation>& operation);
-
-    /* Creates a Java StreamEventCallback object */
-    jobject createStreamEventCallback(callback_t cbf, void* user);
-
-    /* Creates a Java Executor object for running a callback */
-    jobject createCallbackExecutor();
-
-    status_t javaToNativeStatus(int javaStatus);
-};
-
-}; // namespace android
-
-#endif // ANDROID_JAUDIOTRACK_H
diff --git a/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPConnection.h b/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPConnection.h
deleted file mode 100644
index 15f7f83..0000000
--- a/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPConnection.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2017, 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.
- */
-
-#ifndef _J_MEDIA2_HTTP_CONNECTION_H_
-#define _J_MEDIA2_HTTP_CONNECTION_H_
-
-#include "jni.h"
-
-#include <media/MediaHTTPConnection.h>
-#include <media/stagefright/foundation/ABase.h>
-
-namespace android {
-
-struct JMedia2HTTPConnection : public MediaHTTPConnection {
-    JMedia2HTTPConnection(JNIEnv *env, jobject thiz);
-
-    virtual bool connect(
-            const char *uri, const KeyedVector<String8, String8> *headers) override;
-
-    virtual void disconnect() override;
-    virtual ssize_t readAt(off64_t offset, void *data, size_t size) override;
-    virtual off64_t getSize() override;
-    virtual status_t getMIMEType(String8 *mimeType) override;
-    virtual status_t getUri(String8 *uri) override;
-
-protected:
-    virtual ~JMedia2HTTPConnection();
-
-private:
-    jobject mMedia2HTTPConnectionObj;
-    jmethodID mConnectMethod;
-    jmethodID mDisconnectMethod;
-    jmethodID mReadAtMethod;
-    jmethodID mGetSizeMethod;
-    jmethodID mGetMIMETypeMethod;
-    jmethodID mGetUriMethod;
-
-    jbyteArray mByteArrayObj;
-
-    DISALLOW_EVIL_CONSTRUCTORS(JMedia2HTTPConnection);
-};
-
-}  // namespace android
-
-#endif  // _J_MEDIA2_HTTP_CONNECTION_H_
diff --git a/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPService.h b/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPService.h
deleted file mode 100644
index bf61a7f..0000000
--- a/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPService.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2017, 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.
- */
-
-#ifndef _J_MEDIA2_HTTP_SERVICE_H_
-#define _J_MEDIA2_HTTP_SERVICE_H_
-
-#include <jni.h>
-#include <utils/RefBase.h>
-
-#include <media/MediaHTTPService.h>
-#include <media/MediaHTTPConnection.h>
-#include <media/stagefright/foundation/ABase.h>
-
-namespace android {
-
-struct JMedia2HTTPService : public MediaHTTPService {
-    JMedia2HTTPService(JNIEnv *env, jobject thiz);
-
-    virtual sp<MediaHTTPConnection> makeHTTPConnection() override;
-
-protected:
-    virtual ~JMedia2HTTPService();
-
-private:
-    jobject mMedia2HTTPServiceObj;
-
-    jmethodID mMakeHTTPConnectionMethod;
-
-    DISALLOW_EVIL_CONSTRUCTORS(JMedia2HTTPService);
-};
-
-}  // namespace android
-
-#endif  // _J_MEDIA2_HTTP_SERVICE_H_
diff --git a/media/libmediaplayer2/include/mediaplayer2/JObjectHolder.h b/media/libmediaplayer2/include/mediaplayer2/JObjectHolder.h
deleted file mode 100644
index 93d8b40..0000000
--- a/media/libmediaplayer2/include/mediaplayer2/JObjectHolder.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2018, 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.
- */
-
-#ifndef JOBJECT_HOLDER_H_
-
-#define JOBJECT_HOLDER_H_
-
-#include "jni.h"
-#include <mediaplayer2/JavaVMHelper.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-// Helper class for managing global reference of jobject.
-struct JObjectHolder : public RefBase {
-    JObjectHolder(jobject obj) {
-        JNIEnv *env = JavaVMHelper::getJNIEnv();
-        mJObject = reinterpret_cast<jobject>(env->NewGlobalRef(obj));
-    }
-
-    virtual ~JObjectHolder() {
-        JNIEnv *env = JavaVMHelper::getJNIEnv();
-        env->DeleteGlobalRef(mJObject);
-    }
-
-    jobject getJObject() { return mJObject; }
-
-private:
-    jobject mJObject;
-};
-
-}  //" android
-
-#endif  // JOBJECT_HOLDER_H_
diff --git a/media/libmediaplayer2/include/mediaplayer2/JavaVMHelper.h b/media/libmediaplayer2/include/mediaplayer2/JavaVMHelper.h
deleted file mode 100644
index 4b56aca..0000000
--- a/media/libmediaplayer2/include/mediaplayer2/JavaVMHelper.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2018 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.
- */
-
-#ifndef JAVA_VM_HELPER_H_
-
-#define JAVA_VM_HELPER_H_
-
-#include "jni.h"
-
-#include <atomic>
-
-namespace android {
-
-struct JavaVMHelper {
-    static JNIEnv *getJNIEnv();
-    static JavaVM *getJavaVM();
-    static void setJavaVM(JavaVM *vm);
-
-private:
-    // Once a valid JavaVM has been set, it should never be reset or changed.
-    // However, as it may be accessed from multiple threads, access needs to be
-    // synchronized.
-    static std::atomic<JavaVM *> sJavaVM;
-};
-
-}  // namespace android
-
-#endif  // JAVA_VM_HELPER_H_
diff --git a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h
deleted file mode 100644
index f38b7cc..0000000
--- a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
-**
-** Copyright 2018, 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.
-*/
-
-#ifndef ANDROID_MEDIAPLAYER2AUDIOOUTPUT_H
-#define ANDROID_MEDIAPLAYER2AUDIOOUTPUT_H
-
-#include <mediaplayer2/MediaPlayer2Interface.h>
-#include <mediaplayer2/JAudioTrack.h>
-#include <mediaplayer2/JObjectHolder.h>
-
-#include <utility>
-#include <utils/String16.h>
-#include <utils/Vector.h>
-
-#include "jni.h"
-
-namespace android {
-
-class AudioTrack;
-
-class MediaPlayer2AudioOutput : public MediaPlayer2Interface::AudioSink
-{
-    class CallbackData;
-
-public:
-    MediaPlayer2AudioOutput(int32_t sessionId,
-                            uid_t uid,
-                            int pid,
-                            const jobject attributes);
-    virtual ~MediaPlayer2AudioOutput();
-
-    virtual bool ready() const {
-        return mJAudioTrack != nullptr;
-    }
-    virtual ssize_t bufferSize() const;
-    virtual ssize_t frameCount() const;
-    virtual ssize_t channelCount() const;
-    virtual ssize_t frameSize() const;
-    virtual uint32_t latency() const;
-    virtual float msecsPerFrame() const;
-    virtual status_t getPosition(uint32_t *position) const;
-    virtual status_t getTimestamp(AudioTimestamp &ts) const;
-    virtual int64_t getPlayedOutDurationUs(int64_t nowUs) const;
-    virtual status_t getFramesWritten(uint32_t *frameswritten) const;
-    virtual int32_t getSessionId() const;
-    virtual void setSessionId(const int32_t id);
-    virtual uint32_t getSampleRate() const;
-    virtual int64_t getBufferDurationInUs() const;
-
-    virtual status_t open(
-            uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
-            audio_format_t format,
-            AudioCallback cb, void *cookie,
-            audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
-            const audio_offload_info_t *offloadInfo = NULL,
-            uint32_t suggestedFrameCount = 0);
-
-    virtual status_t start();
-    virtual ssize_t write(const void* buffer, size_t size, bool blocking = true);
-    virtual void stop();
-    virtual void flush();
-    virtual void pause();
-    virtual void close();
-    void setAudioAttributes(const jobject attributes);
-    virtual audio_stream_type_t getAudioStreamType() const;
-
-    void setVolume(float volume);
-    virtual status_t setPlaybackRate(const AudioPlaybackRate& rate);
-    virtual status_t getPlaybackRate(AudioPlaybackRate* rate /* nonnull */);
-
-    status_t setAuxEffectSendLevel(float level);
-    status_t attachAuxEffect(int effectId);
-    virtual status_t dump(int fd, const Vector<String16>& args) const;
-
-    static bool isOnEmulator();
-    static int getMinBufferCount();
-    virtual bool needsTrailingPadding() {
-        return true;
-        // TODO: return correct value.
-        //return mNextOutput == NULL;
-    }
-    // AudioRouting
-    virtual status_t setPreferredDevice(jobject device);
-    virtual jobject getRoutedDevice();
-    virtual status_t addAudioDeviceCallback(jobject routingDelegate);
-    virtual status_t removeAudioDeviceCallback(jobject listener);
-
-private:
-    static void setMinBufferCount();
-    static void CallbackWrapper(int event, void *me, void *info);
-    void deleteRecycledTrack_l();
-    void close_l();
-    status_t updateTrack_l();
-
-    sp<JAudioTrack>         mJAudioTrack;
-    AudioCallback           mCallback;
-    void *                  mCallbackCookie;
-    CallbackData *          mCallbackData;
-    sp<JObjectHolder>       mAttributes;
-    float                   mVolume;
-    AudioPlaybackRate       mPlaybackRate;
-    uint32_t                mSampleRateHz; // sample rate of the content, as set in open()
-    float                   mMsecsPerFrame;
-    size_t                  mFrameSize;
-    int32_t                 mSessionId;
-    uid_t                   mUid;
-    int                     mPid;
-    float                   mSendLevel;
-    int                     mAuxEffectId;
-    audio_output_flags_t    mFlags;
-    sp<JObjectHolder>       mPreferredDevice;
-    mutable Mutex           mLock;
-
-    // <listener, routingDelegate>
-    Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>> mRoutingDelegates;
-
-    // static variables below not protected by mutex
-    static bool             mIsOnEmulator;
-    static int              mMinBufferCount;  // 12 for emulator; otherwise 4
-
-    // CallbackData is what is passed to the AudioTrack as the "user" data.
-    // We need to be able to target this to a different Output on the fly,
-    // so we can't use the Output itself for this.
-    class CallbackData {
-        friend MediaPlayer2AudioOutput;
-    public:
-        explicit CallbackData(MediaPlayer2AudioOutput *cookie) {
-            mData = cookie;
-            mSwitching = false;
-        }
-        MediaPlayer2AudioOutput *getOutput() const {
-            return mData;
-        }
-        void setOutput(MediaPlayer2AudioOutput* newcookie) {
-            mData = newcookie;
-        }
-        // lock/unlock are used by the callback before accessing the payload of this object
-        void lock() const {
-            mLock.lock();
-        }
-        void unlock() const {
-            mLock.unlock();
-        }
-
-        // tryBeginTrackSwitch/endTrackSwitch are used when the CallbackData is handed over
-        // to the next sink.
-
-        // tryBeginTrackSwitch() returns true only if it obtains the lock.
-        bool tryBeginTrackSwitch() {
-            LOG_ALWAYS_FATAL_IF(mSwitching, "tryBeginTrackSwitch() already called");
-            if (mLock.tryLock() != OK) {
-                return false;
-            }
-            mSwitching = true;
-            return true;
-        }
-        void endTrackSwitch() {
-            if (mSwitching) {
-                mLock.unlock();
-            }
-            mSwitching = false;
-        }
-
-    private:
-        MediaPlayer2AudioOutput *mData;
-        mutable Mutex mLock; // a recursive mutex might make this unnecessary.
-        bool mSwitching;
-        DISALLOW_EVIL_CONSTRUCTORS(CallbackData);
-    };
-};
-
-}; // namespace android
-
-#endif // ANDROID_MEDIAPLAYER2AUDIOOUTPUT_H
diff --git a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Interface.h b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Interface.h
deleted file mode 100644
index 7804a62..0000000
--- a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Interface.h
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-#ifndef ANDROID_MEDIAPLAYER2INTERFACE_H
-#define ANDROID_MEDIAPLAYER2INTERFACE_H
-
-#ifdef __cplusplus
-
-#include <sys/types.h>
-#include <utils/Errors.h>
-#include <utils/String8.h>
-#include <utils/RefBase.h>
-#include <jni.h>
-
-#include <media/AVSyncSettings.h>
-#include <media/AudioResamplerPublic.h>
-#include <media/AudioSystem.h>
-#include <media/AudioTimestamp.h>
-#include <media/BufferingSettings.h>
-#include <media/stagefright/foundation/AHandler.h>
-#include <mediaplayer2/MediaPlayer2Types.h>
-
-#include "jni.h"
-#include "mediaplayer2.pb.h"
-
-using android::media::MediaPlayer2Proto::PlayerMessage;
-
-// Fwd decl to make sure everyone agrees that the scope of struct sockaddr_in is
-// global, and not in android::
-struct sockaddr_in;
-
-namespace android {
-
-struct DataSourceDesc;
-class Parcel;
-struct ANativeWindowWrapper;
-
-#define DEFAULT_AUDIOSINK_BUFFERSIZE 1200
-#define DEFAULT_AUDIOSINK_SAMPLERATE 44100
-
-// when the channel mask isn't known, use the channel count to derive a mask in AudioSink::open()
-#define CHANNEL_MASK_USE_CHANNEL_ORDER 0
-
-// duration below which we do not allow deep audio buffering
-#define AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US 5000000
-
-class MediaPlayer2InterfaceListener: public RefBase
-{
-public:
-    virtual void notify(int64_t srcId, int msg, int ext1, int ext2,
-           const PlayerMessage *obj) = 0;
-};
-
-class MediaPlayer2Interface : public AHandler {
-public:
-    // AudioSink: abstraction layer for audio output
-    class AudioSink : public RefBase {
-    public:
-        enum cb_event_t {
-            CB_EVENT_FILL_BUFFER,   // Request to write more data to buffer.
-            CB_EVENT_STREAM_END,    // Sent after all the buffers queued in AF and HW are played
-                                    // back (after stop is called)
-            CB_EVENT_TEAR_DOWN      // The AudioTrack was invalidated due to use case change:
-                                    // Need to re-evaluate offloading options
-        };
-
-        // Callback returns the number of bytes actually written to the buffer.
-        typedef size_t (*AudioCallback)(
-                AudioSink *audioSink, void *buffer, size_t size, void *cookie, cb_event_t event);
-
-        virtual ~AudioSink() {}
-        virtual bool ready() const = 0; // audio output is open and ready
-        virtual ssize_t bufferSize() const = 0;
-        virtual ssize_t frameCount() const = 0;
-        virtual ssize_t channelCount() const = 0;
-        virtual ssize_t frameSize() const = 0;
-        virtual uint32_t latency() const = 0;
-        virtual float msecsPerFrame() const = 0;
-        virtual status_t getPosition(uint32_t *position) const = 0;
-        virtual status_t getTimestamp(AudioTimestamp &ts) const = 0;
-        virtual int64_t getPlayedOutDurationUs(int64_t nowUs) const = 0;
-        virtual status_t getFramesWritten(uint32_t *frameswritten) const = 0;
-        virtual int32_t getSessionId() const = 0;
-        virtual audio_stream_type_t getAudioStreamType() const = 0;
-        virtual uint32_t getSampleRate() const = 0;
-        virtual int64_t getBufferDurationInUs() const = 0;
-
-        // If no callback is specified, use the "write" API below to submit
-        // audio data.
-        virtual status_t open(
-                uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
-                audio_format_t format=AUDIO_FORMAT_PCM_16_BIT,
-                AudioCallback cb = NULL,
-                void *cookie = NULL,
-                audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
-                const audio_offload_info_t *offloadInfo = NULL,
-                uint32_t suggestedFrameCount = 0) = 0;
-
-        virtual status_t start() = 0;
-
-        /* Input parameter |size| is in byte units stored in |buffer|.
-         * Data is copied over and actual number of bytes written (>= 0)
-         * is returned, or no data is copied and a negative status code
-         * is returned (even when |blocking| is true).
-         * When |blocking| is false, AudioSink will immediately return after
-         * part of or full |buffer| is copied over.
-         * When |blocking| is true, AudioSink will wait to copy the entire
-         * buffer, unless an error occurs or the copy operation is
-         * prematurely stopped.
-         */
-        virtual ssize_t write(const void* buffer, size_t size, bool blocking = true) = 0;
-
-        virtual void stop() = 0;
-        virtual void flush() = 0;
-        virtual void pause() = 0;
-        virtual void close() = 0;
-
-        virtual status_t setPlaybackRate(const AudioPlaybackRate& rate) = 0;
-        virtual status_t getPlaybackRate(AudioPlaybackRate* rate /* nonnull */) = 0;
-        virtual bool needsTrailingPadding() {
-            return true;
-        }
-
-        virtual status_t setParameters(const String8& /* keyValuePairs */) {
-            return NO_ERROR;
-        }
-        virtual String8 getParameters(const String8& /* keys */) {
-            return String8::empty();
-        }
-
-        // AudioRouting
-        virtual status_t    setPreferredDevice(jobject device);
-        virtual jobject     getRoutedDevice();
-        virtual status_t    addAudioDeviceCallback(jobject routingDelegate);
-        virtual status_t    removeAudioDeviceCallback(jobject listener);
-    };
-
-    MediaPlayer2Interface() : mListener(NULL) { }
-    virtual ~MediaPlayer2Interface() { }
-    virtual status_t initCheck() = 0;
-
-    virtual void setAudioSink(const sp<AudioSink>& audioSink) {
-        mAudioSink = audioSink;
-    }
-
-    virtual status_t setDataSource(const sp<DataSourceDesc> &dsd) = 0;
-
-    virtual status_t prepareNextDataSource(const sp<DataSourceDesc> &dsd) = 0;
-
-    virtual status_t playNextDataSource(int64_t srcId) = 0;
-
-    // pass the buffered native window to the media player service
-    virtual status_t setVideoSurfaceTexture(const sp<ANativeWindowWrapper>& nww) = 0;
-
-    virtual status_t getBufferingSettings(BufferingSettings* buffering /* nonnull */) {
-        *buffering = BufferingSettings();
-        return OK;
-    }
-    virtual status_t setBufferingSettings(const BufferingSettings& /* buffering */) {
-        return OK;
-    }
-
-    virtual status_t prepareAsync() = 0;
-    virtual status_t start() = 0;
-    virtual status_t pause() = 0;
-    virtual bool isPlaying() = 0;
-    virtual status_t setPlaybackSettings(const AudioPlaybackRate& rate) {
-        // by default, players only support setting rate to the default
-        if (!isAudioPlaybackRateEqual(rate, AUDIO_PLAYBACK_RATE_DEFAULT)) {
-            return BAD_VALUE;
-        }
-        return OK;
-    }
-    virtual status_t getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */) {
-        *rate = AUDIO_PLAYBACK_RATE_DEFAULT;
-        return OK;
-    }
-    virtual status_t setSyncSettings(const AVSyncSettings& sync, float /* videoFps */) {
-        // By default, players only support setting sync source to default; all other sync
-        // settings are ignored. There is no requirement for getters to return set values.
-        if (sync.mSource != AVSYNC_SOURCE_DEFAULT) {
-            return BAD_VALUE;
-        }
-        return OK;
-    }
-    virtual status_t getSyncSettings(
-            AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */) {
-        *sync = AVSyncSettings();
-        *videoFps = -1.f;
-        return OK;
-    }
-    virtual status_t seekTo(
-            int64_t msec, MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC) = 0;
-    virtual status_t getCurrentPosition(int64_t *msec) = 0;
-    virtual status_t getDuration(int64_t *msec) = 0;
-    virtual status_t reset() = 0;
-    virtual status_t notifyAt(int64_t /* mediaTimeUs */) {
-        return INVALID_OPERATION;
-    }
-    virtual status_t setLooping(int loop) = 0;
-    virtual status_t setParameter(int key, const Parcel &request) = 0;
-    virtual status_t getParameter(int key, Parcel *reply) = 0;
-
-    virtual status_t getMetrics(char **buffer, size_t *length) = 0;
-
-    // Invoke a generic method on the player by using opaque parcels
-    // for the request and reply.
-    //
-    // @param request Parcel that is positioned at the start of the
-    //                data sent by the java layer.
-    // @param[out] reply Parcel to hold the reply data. Cannot be null.
-    // @return OK if the call was successful.
-    virtual status_t invoke(const PlayerMessage &request, PlayerMessage *reply) = 0;
-
-    void setListener(const sp<MediaPlayer2InterfaceListener> &listener) {
-        Mutex::Autolock autoLock(mListenerLock);
-        mListener = listener;
-    }
-
-    void sendEvent(int64_t srcId, int msg, int ext1=0, int ext2=0, const PlayerMessage *obj=NULL) {
-        sp<MediaPlayer2InterfaceListener> listener;
-        {
-            Mutex::Autolock autoLock(mListenerLock);
-            listener = mListener;
-        }
-
-        if (listener) {
-            listener->notify(srcId, msg, ext1, ext2, obj);
-        }
-    }
-
-    virtual status_t dump(int /* fd */, const Vector<String16>& /* args */) const {
-        return INVALID_OPERATION;
-    }
-
-    virtual void onMessageReceived(const sp<AMessage> & /* msg */) override { }
-
-    // Modular DRM
-    virtual status_t prepareDrm(int64_t /*srcId*/, const uint8_t /* uuid */[16],
-                                const Vector<uint8_t>& /* drmSessionId */) {
-        return INVALID_OPERATION;
-    }
-    virtual status_t releaseDrm(int64_t /*srcId*/) {
-        return INVALID_OPERATION;
-    }
-
-protected:
-    sp<AudioSink> mAudioSink;
-
-private:
-    Mutex mListenerLock;
-    sp<MediaPlayer2InterfaceListener> mListener;
-};
-
-}; // namespace android
-
-#endif // __cplusplus
-
-
-#endif // ANDROID_MEDIAPLAYER2INTERFACE_H
diff --git a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Types.h b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Types.h
deleted file mode 100644
index 2430289..0000000
--- a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Types.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright 2018 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.
- */
-
-#ifndef ANDROID_MEDIAPLAYER2_TYPES_H
-#define ANDROID_MEDIAPLAYER2_TYPES_H
-
-#include <media/mediaplayer_common.h>
-
-#include <media/MediaSource.h>
-
-namespace android {
-
-typedef MediaSource::ReadOptions::SeekMode MediaPlayer2SeekMode;
-
-enum media2_event_type {
-    MEDIA2_NOP               = 0, // interface test message
-    MEDIA2_PREPARED          = 1,
-    MEDIA2_PLAYBACK_COMPLETE = 2,
-    MEDIA2_BUFFERING_UPDATE  = 3,
-    MEDIA2_SEEK_COMPLETE     = 4,
-    MEDIA2_SET_VIDEO_SIZE    = 5,
-    MEDIA2_STARTED           = 6,
-    MEDIA2_PAUSED            = 7,
-    MEDIA2_SKIPPED           = 8,
-    MEDIA2_NOTIFY_TIME       = 98,
-    MEDIA2_TIMED_TEXT        = 99,
-    MEDIA2_ERROR             = 100,
-    MEDIA2_INFO              = 200,
-    MEDIA2_SUBTITLE_DATA     = 201,
-    MEDIA2_META_DATA         = 202,
-    MEDIA2_DRM_INFO          = 210,
-};
-
-// Generic error codes for the media player framework.  Errors are fatal, the
-// playback must abort.
-//
-// Errors are communicated back to the client using the
-// MediaPlayer2Listener::notify method defined below.
-// In this situation, 'notify' is invoked with the following:
-//   'msg' is set to MEDIA_ERROR.
-//   'ext1' should be a value from the enum media2_error_type.
-//   'ext2' contains an implementation dependant error code to provide
-//          more details. Should default to 0 when not used.
-//
-// The codes are distributed as follow:
-//   0xx: Reserved
-//   1xx: Android Player errors. Something went wrong inside the MediaPlayer2.
-//   2xx: Media errors (e.g Codec not supported). There is a problem with the
-//        media itself.
-//   3xx: Runtime errors. Some extraordinary condition arose making the playback
-//        impossible.
-//
-enum media2_error_type {
-    // 0xx
-    MEDIA2_ERROR_UNKNOWN = 1,
-    // 1xx
-    // MEDIA2_ERROR_SERVER_DIED = 100,
-    // 2xx
-    MEDIA2_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200,
-    // 3xx
-    MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE = 300,
-};
-
-
-// Info and warning codes for the media player framework.  These are non fatal,
-// the playback is going on but there might be some user visible issues.
-//
-// Info and warning messages are communicated back to the client using the
-// MediaPlayer2Listener::notify method defined below.  In this situation,
-// 'notify' is invoked with the following:
-//   'msg' is set to MEDIA_INFO.
-//   'ext1' should be a value from the enum media2_info_type.
-//   'ext2' contains an implementation dependant info code to provide
-//          more details. Should default to 0 when not used.
-//
-// The codes are distributed as follow:
-//   0xx: Reserved
-//   7xx: Android Player info/warning (e.g player lagging behind.)
-//   8xx: Media info/warning (e.g media badly interleaved.)
-//
-enum media2_info_type {
-    // 0xx
-    MEDIA2_INFO_UNKNOWN = 1,
-    // The player just started the playback of this data source.
-    MEDIA2_INFO_DATA_SOURCE_START = 2,
-    // The player just pushed the very first video frame for rendering
-    MEDIA2_INFO_VIDEO_RENDERING_START = 3,
-    // The player just pushed the very first audio frame for rendering
-    MEDIA2_INFO_AUDIO_RENDERING_START = 4,
-    // The player just completed the playback of this data source
-    MEDIA2_INFO_DATA_SOURCE_END = 5,
-    // The player just completed the playback of all data sources.
-    // But this is not visible in native code. Just keep this entry for completeness.
-    MEDIA2_INFO_DATA_SOURCE_LIST_END = 6,
-    // The player just completed an iteration of playback loop. This event is sent only when
-    // looping is enabled.
-    MEDIA2_INFO_DATA_SOURCE_REPEAT = 7,
-
-    //1xx
-    // The player just prepared a data source.
-    MEDIA2_INFO_PREPARED = 100,
-    // The player just completed a call play().
-    MEDIA2_INFO_COMPLETE_CALL_PLAY = 101,
-    // The player just completed a call pause().
-    MEDIA2_INFO_COMPLETE_CALL_PAUSE = 102,
-    // The player just completed a call seekTo.
-    MEDIA2_INFO_COMPLETE_CALL_SEEK = 103,
-
-    // 7xx
-    // The video is too complex for the decoder: it can't decode frames fast
-    // enough. Possibly only the audio plays fine at this stage.
-    MEDIA2_INFO_VIDEO_TRACK_LAGGING = 700,
-    // MediaPlayer2 is temporarily pausing playback internally in order to
-    // buffer more data.
-    MEDIA2_INFO_BUFFERING_START = 701,
-    // MediaPlayer2 is resuming playback after filling buffers.
-    MEDIA2_INFO_BUFFERING_END = 702,
-    // Bandwidth in recent past
-    MEDIA2_INFO_NETWORK_BANDWIDTH = 703,
-
-    // 8xx
-    // Bad interleaving means that a media has been improperly interleaved or not
-    // interleaved at all, e.g has all the video samples first then all the audio
-    // ones. Video is playing but a lot of disk seek may be happening.
-    MEDIA2_INFO_BAD_INTERLEAVING = 800,
-    // The media is not seekable (e.g live stream).
-    MEDIA2_INFO_NOT_SEEKABLE = 801,
-    // New media metadata is available.
-    MEDIA2_INFO_METADATA_UPDATE = 802,
-    // Audio can not be played.
-    MEDIA2_INFO_PLAY_AUDIO_ERROR = 804,
-    // Video can not be played.
-    MEDIA2_INFO_PLAY_VIDEO_ERROR = 805,
-
-    //9xx
-    MEDIA2_INFO_TIMED_TEXT_ERROR = 900,
-};
-
-// Do not change these values without updating their counterparts in MediaPlayer2.java
-enum mediaplayer2_states {
-    MEDIAPLAYER2_STATE_IDLE         = 1001,
-    MEDIAPLAYER2_STATE_PREPARED     = 1002,
-    MEDIAPLAYER2_STATE_PAUSED       = 1003,
-    MEDIAPLAYER2_STATE_PLAYING      = 1004,
-    MEDIAPLAYER2_STATE_ERROR        = 1005,
-};
-
-enum media_player2_internal_states {
-    MEDIA_PLAYER2_STATE_ERROR        = 0,
-    MEDIA_PLAYER2_IDLE               = 1 << 0,
-    MEDIA_PLAYER2_INITIALIZED        = 1 << 1,
-    MEDIA_PLAYER2_PREPARING          = 1 << 2,
-    MEDIA_PLAYER2_PREPARED           = 1 << 3,
-    MEDIA_PLAYER2_STARTED            = 1 << 4,
-    MEDIA_PLAYER2_PAUSED             = 1 << 5,
-    MEDIA_PLAYER2_PLAYBACK_COMPLETE  = 1 << 6
-};
-
-// Keep KEY_PARAMETER_* in sync with MediaPlayer2.java.
-// The same enum space is used for both set and get, in case there are future keys that
-// can be both set and get.  But as of now, all parameters are either set only or get only.
-enum media2_parameter_keys {
-    // Streaming/buffering parameters
-    MEDIA2_KEY_PARAMETER_CACHE_STAT_COLLECT_FREQ_MS = 1100,            // set only
-
-    // Return a Parcel containing a single int, which is the channel count of the
-    // audio track, or zero for error (e.g. no audio track) or unknown.
-    MEDIA2_KEY_PARAMETER_AUDIO_CHANNEL_COUNT = 1200,                   // get only
-
-    // Playback rate expressed in permille (1000 is normal speed), saved as int32_t, with negative
-    // values used for rewinding or reverse playback.
-    MEDIA2_KEY_PARAMETER_PLAYBACK_RATE_PERMILLE = 1300,                // set only
-
-    // Set a Parcel containing the value of a parcelled Java AudioAttribute instance
-    MEDIA2_KEY_PARAMETER_AUDIO_ATTRIBUTES = 1400                       // set only
-};
-
-// Keep INVOKE_ID_* in sync with MediaPlayer2.java.
-enum media_player2_invoke_ids {
-    MEDIA_PLAYER2_INVOKE_ID_GET_TRACK_INFO = 1,
-    MEDIA_PLAYER2_INVOKE_ID_ADD_EXTERNAL_SOURCE = 2,
-    MEDIA_PLAYER2_INVOKE_ID_ADD_EXTERNAL_SOURCE_FD = 3,
-    MEDIA_PLAYER2_INVOKE_ID_SELECT_TRACK = 4,
-    MEDIA_PLAYER2_INVOKE_ID_UNSELECT_TRACK = 5,
-    MEDIA_PLAYER2_INVOKE_ID_SET_VIDEO_SCALING_MODE = 6,
-    MEDIA_PLAYER2_INVOKE_ID_GET_SELECTED_TRACK = 7
-};
-
-}; // namespace android
-
-#endif // ANDROID_MEDIAPLAYER2_TYPES_H
diff --git a/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h b/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
deleted file mode 100644
index 1e8a1d5..0000000
--- a/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-#ifndef ANDROID_MEDIAPLAYER2_H
-#define ANDROID_MEDIAPLAYER2_H
-
-#include <media/AVSyncSettings.h>
-#include <media/AudioResamplerPublic.h>
-#include <media/BufferingSettings.h>
-#include <media/mediaplayer_common.h>
-#include <mediaplayer2/MediaPlayer2Interface.h>
-#include <mediaplayer2/MediaPlayer2Types.h>
-#include <mediaplayer2/JObjectHolder.h>
-
-#include <jni.h>
-#include <utils/Errors.h>
-#include <utils/Mutex.h>
-#include <utils/RefBase.h>
-#include <utils/String16.h>
-#include <utils/Vector.h>
-#include <system/audio-base.h>
-
-#include "jni.h"
-
-namespace android {
-
-struct ANativeWindowWrapper;
-struct DataSourceDesc;
-class MediaPlayer2AudioOutput;
-
-// ref-counted object for callbacks
-class MediaPlayer2Listener: virtual public RefBase
-{
-public:
-    virtual void notify(int64_t srcId, int msg, int ext1, int ext2,
-            const PlayerMessage *obj = NULL) = 0;
-};
-
-class MediaPlayer2 : public MediaPlayer2InterfaceListener
-{
-public:
-    ~MediaPlayer2();
-
-    static sp<MediaPlayer2> Create(int32_t sessionId, jobject context);
-    static status_t DumpAll(int fd, const Vector<String16>& args);
-
-            void            disconnect();
-
-            status_t        getSrcId(int64_t *srcId);
-            status_t        setDataSource(const sp<DataSourceDesc> &dsd);
-            status_t        prepareNextDataSource(const sp<DataSourceDesc> &dsd);
-            status_t        playNextDataSource(int64_t srcId);
-            status_t        setVideoSurfaceTexture(const sp<ANativeWindowWrapper>& nww);
-            status_t        setListener(const sp<MediaPlayer2Listener>& listener);
-            status_t        getBufferingSettings(BufferingSettings* buffering /* nonnull */);
-            status_t        setBufferingSettings(const BufferingSettings& buffering);
-            status_t        prepareAsync();
-            status_t        start();
-            status_t        pause();
-            bool            isPlaying();
-            mediaplayer2_states getState();
-            status_t        setPlaybackSettings(const AudioPlaybackRate& rate);
-            status_t        getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */);
-            status_t        setSyncSettings(const AVSyncSettings& sync, float videoFpsHint);
-            status_t        getSyncSettings(
-                                    AVSyncSettings* sync /* nonnull */,
-                                    float* videoFps /* nonnull */);
-            status_t        getVideoWidth(int *w);
-            status_t        getVideoHeight(int *h);
-            status_t        seekTo(
-                    int64_t msec,
-                    MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC);
-            status_t        notifyAt(int64_t mediaTimeUs);
-            status_t        getCurrentPosition(int64_t *msec);
-            status_t        getDuration(int64_t srcId, int64_t *msec);
-            status_t        reset();
-            status_t        setAudioStreamType(audio_stream_type_t type);
-            status_t        getAudioStreamType(audio_stream_type_t *type);
-            status_t        setLooping(int loop);
-            bool            isLooping();
-            status_t        setVolume(float volume);
-            void            notify(int64_t srcId, int msg, int ext1, int ext2,
-                                   const PlayerMessage *obj = NULL);
-            status_t        invoke(const PlayerMessage &request, PlayerMessage *reply);
-            status_t        setAudioSessionId(int32_t sessionId);
-            int32_t         getAudioSessionId();
-            status_t        setAuxEffectSendLevel(float level);
-            status_t        attachAuxEffect(int effectId);
-            status_t        setAudioAttributes(const jobject attributes);
-            jobject         getAudioAttributes();
-            status_t        getParameter(int key, Parcel* reply);
-            status_t        getMetrics(char **buffer, size_t *length);
-
-            // Modular DRM
-            status_t        prepareDrm(int64_t srcId,
-                                       const uint8_t uuid[16],
-                                       const Vector<uint8_t>& drmSessionId);
-            status_t        releaseDrm(int64_t srcId);
-            // AudioRouting
-            status_t        setPreferredDevice(jobject device);
-            jobject         getRoutedDevice();
-            status_t        addAudioDeviceCallback(jobject routingDelegate);
-            status_t        removeAudioDeviceCallback(jobject listener);
-
-            status_t        dump(int fd, const Vector<String16>& args);
-
-private:
-    MediaPlayer2(int32_t sessionId, jobject context);
-    bool init();
-
-    // Disconnect from the currently connected ANativeWindow.
-    void disconnectNativeWindow_l();
-
-    status_t setAudioAttributes_l(const jobject attributes);
-
-    void clear_l();
-    status_t seekTo_l(int64_t msec, MediaPlayer2SeekMode mode);
-    status_t prepareAsync_l();
-    status_t getDuration_l(int64_t *msec);
-    status_t reset_l();
-    status_t checkState_l();
-
-    pid_t                       mPid;
-    uid_t                       mUid;
-    sp<MediaPlayer2Interface>   mPlayer;
-    sp<MediaPlayer2AudioOutput> mAudioOutput;
-    int64_t                     mSrcId;
-    thread_id_t                 mLockThreadId;
-    mutable Mutex               mLock;
-    Mutex                       mNotifyLock;
-    sp<MediaPlayer2Listener>    mListener;
-    media_player2_internal_states mCurrentState;
-    bool                        mTransitionToNext;
-    int64_t                     mCurrentPosition;
-    MediaPlayer2SeekMode        mCurrentSeekMode;
-    int64_t                     mSeekPosition;
-    MediaPlayer2SeekMode        mSeekMode;
-    audio_stream_type_t         mStreamType;
-    bool                        mLoop;
-    float                       mVolume;
-    int                         mVideoWidth;
-    int                         mVideoHeight;
-    int32_t                     mAudioSessionId;
-    sp<JObjectHolder>           mAudioAttributes;
-    sp<JObjectHolder>           mContext;
-    float                       mSendLevel;
-    sp<ANativeWindowWrapper>    mConnectedWindow;
-};
-
-}; // namespace android
-
-#endif // ANDROID_MEDIAPLAYER2_H
diff --git a/media/libmediaplayer2/mediaplayer2.cpp b/media/libmediaplayer2/mediaplayer2.cpp
deleted file mode 100644
index de65f8d..0000000
--- a/media/libmediaplayer2/mediaplayer2.cpp
+++ /dev/null
@@ -1,1261 +0,0 @@
-/*
-**
-** Copyright 2017, 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 "MediaPlayer2Native"
-
-#include <android/binder_ibinder.h>
-#include <media/AudioSystem.h>
-#include <media/DataSourceDesc.h>
-#include <media/MemoryLeakTrackUtil.h>
-#include <media/NdkWrapper.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/ALooperRoster.h>
-#include <mediaplayer2/MediaPlayer2AudioOutput.h>
-#include <mediaplayer2/mediaplayer2.h>
-
-#include <utils/Log.h>
-#include <utils/SortedVector.h>
-#include <utils/String8.h>
-
-#include <system/audio.h>
-#include <system/window.h>
-
-#include <nuplayer2/NuPlayer2Driver.h>
-
-#include <dirent.h>
-#include <sys/stat.h>
-
-namespace android {
-
-extern ALooperRoster gLooperRoster;
-
-namespace {
-
-const int kDumpLockRetries = 50;
-const int kDumpLockSleepUs = 20000;
-
-class proxyListener : public MediaPlayer2InterfaceListener {
-public:
-    proxyListener(const wp<MediaPlayer2> &player)
-        : mPlayer(player) { }
-
-    ~proxyListener() { };
-
-    virtual void notify(int64_t srcId, int msg, int ext1, int ext2,
-            const PlayerMessage *obj) override {
-        sp<MediaPlayer2> player = mPlayer.promote();
-        if (player != NULL) {
-            player->notify(srcId, msg, ext1, ext2, obj);
-        }
-    }
-
-private:
-    wp<MediaPlayer2> mPlayer;
-};
-
-Mutex sRecordLock;
-SortedVector<wp<MediaPlayer2> > *sPlayers;
-
-void ensureInit_l() {
-    if (sPlayers == NULL) {
-        sPlayers = new SortedVector<wp<MediaPlayer2> >();
-    }
-}
-
-void addPlayer(const wp<MediaPlayer2>& player) {
-    Mutex::Autolock lock(sRecordLock);
-    ensureInit_l();
-    sPlayers->add(player);
-}
-
-void removePlayer(const wp<MediaPlayer2>& player) {
-    Mutex::Autolock lock(sRecordLock);
-    ensureInit_l();
-    sPlayers->remove(player);
-}
-
-/**
- * The only arguments this understands right now are -c, -von and -voff,
- * which are parsed by ALooperRoster::dump()
- */
-status_t dumpPlayers(int fd, const Vector<String16>& args) {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-    SortedVector< sp<MediaPlayer2> > players; //to serialise the mutex unlock & client destruction.
-
-    {
-        Mutex::Autolock lock(sRecordLock);
-        ensureInit_l();
-        for (int i = 0, n = sPlayers->size(); i < n; ++i) {
-            sp<MediaPlayer2> p = (*sPlayers)[i].promote();
-            if (p != 0) {
-                p->dump(fd, args);
-            }
-            players.add(p);
-        }
-    }
-
-    result.append(" Files opened and/or mapped:\n");
-    snprintf(buffer, SIZE, "/proc/%d/maps", getpid());
-    FILE *f = fopen(buffer, "r");
-    if (f) {
-        while (!feof(f)) {
-            fgets(buffer, SIZE, f);
-            if (strstr(buffer, " /storage/") ||
-                strstr(buffer, " /system/sounds/") ||
-                strstr(buffer, " /data/") ||
-                strstr(buffer, " /system/media/")) {
-                result.append("  ");
-                result.append(buffer);
-            }
-        }
-        fclose(f);
-    } else {
-        result.append("couldn't open ");
-        result.append(buffer);
-        result.append("\n");
-    }
-
-    snprintf(buffer, SIZE, "/proc/%d/fd", getpid());
-    DIR *d = opendir(buffer);
-    if (d) {
-        struct dirent *ent;
-        while((ent = readdir(d)) != NULL) {
-            if (strcmp(ent->d_name,".") && strcmp(ent->d_name,"..")) {
-                snprintf(buffer, SIZE, "/proc/%d/fd/%s", getpid(), ent->d_name);
-                struct stat s;
-                if (lstat(buffer, &s) == 0) {
-                    if ((s.st_mode & S_IFMT) == S_IFLNK) {
-                        char linkto[256];
-                        int len = readlink(buffer, linkto, sizeof(linkto));
-                        if(len > 0) {
-                            if(len > 255) {
-                                linkto[252] = '.';
-                                linkto[253] = '.';
-                                linkto[254] = '.';
-                                linkto[255] = 0;
-                            } else {
-                                linkto[len] = 0;
-                            }
-                            if (strstr(linkto, "/storage/") == linkto ||
-                                strstr(linkto, "/system/sounds/") == linkto ||
-                                strstr(linkto, "/data/") == linkto ||
-                                strstr(linkto, "/system/media/") == linkto) {
-                                result.append("  ");
-                                result.append(buffer);
-                                result.append(" -> ");
-                                result.append(linkto);
-                                result.append("\n");
-                            }
-                        }
-                    } else {
-                        result.append("  unexpected type for ");
-                        result.append(buffer);
-                        result.append("\n");
-                    }
-                }
-            }
-        }
-        closedir(d);
-    } else {
-        result.append("couldn't open ");
-        result.append(buffer);
-        result.append("\n");
-    }
-
-    gLooperRoster.dump(fd, args);
-
-    bool dumpMem = false;
-    bool unreachableMemory = false;
-    for (size_t i = 0; i < args.size(); i++) {
-        if (args[i] == String16("-m")) {
-            dumpMem = true;
-        } else if (args[i] == String16("--unreachable")) {
-            unreachableMemory = true;
-        }
-    }
-    if (dumpMem) {
-        result.append("\nDumping memory:\n");
-        std::string s = dumpMemoryAddresses(100 /* limit */);
-        result.append(s.c_str(), s.size());
-    }
-    if (unreachableMemory) {
-        result.append("\nDumping unreachable memory:\n");
-        // TODO - should limit be an argument parameter?
-        // TODO: enable GetUnreachableMemoryString if it's part of stable API
-        //std::string s = GetUnreachableMemoryString(true /* contents */, 10000 /* limit */);
-        //result.append(s.c_str(), s.size());
-    }
-
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-}  // anonymous namespace
-
-//static
-sp<MediaPlayer2> MediaPlayer2::Create(int32_t sessionId, jobject context) {
-    sp<MediaPlayer2> player = new MediaPlayer2(sessionId, context);
-
-    if (!player->init()) {
-        return NULL;
-    }
-
-    ALOGV("Create new player(%p)", player.get());
-
-    addPlayer(player);
-    return player;
-}
-
-// static
-status_t MediaPlayer2::DumpAll(int fd, const Vector<String16>& args) {
-    return dumpPlayers(fd, args);
-}
-
-MediaPlayer2::MediaPlayer2(int32_t sessionId, jobject context) {
-    ALOGV("constructor");
-    mSrcId = 0;
-    mLockThreadId = 0;
-    mListener = NULL;
-    mStreamType = AUDIO_STREAM_MUSIC;
-    mAudioAttributes = NULL;
-    mContext = new JObjectHolder(context);
-    mCurrentPosition = -1;
-    mCurrentSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
-    mSeekPosition = -1;
-    mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
-    mCurrentState = MEDIA_PLAYER2_IDLE;
-    mTransitionToNext = false;
-    mLoop = false;
-    mVolume = 1.0;
-    mVideoWidth = mVideoHeight = 0;
-    mSendLevel = 0;
-
-    mPid = AIBinder_getCallingPid();
-    mUid = AIBinder_getCallingUid();
-
-    mAudioOutput = new MediaPlayer2AudioOutput(sessionId, mUid, mPid, NULL /*attributes*/);
-}
-
-MediaPlayer2::~MediaPlayer2() {
-    ALOGV("destructor");
-    disconnect();
-    removePlayer(this);
-}
-
-bool MediaPlayer2::init() {
-    // TODO: after merge with NuPlayer2Driver, MediaPlayer2 will have its own
-    // looper for notification.
-    return true;
-}
-
-void MediaPlayer2::disconnect() {
-    ALOGV("disconnect");
-    sp<MediaPlayer2Interface> p;
-    {
-        Mutex::Autolock _l(mLock);
-        p = mPlayer;
-        mPlayer.clear();
-    }
-
-    if (p != 0) {
-        p->setListener(NULL);
-        p->reset();
-    }
-
-    {
-        Mutex::Autolock _l(mLock);
-        disconnectNativeWindow_l();
-    }
-}
-
-void MediaPlayer2::clear_l() {
-    mCurrentPosition = -1;
-    mCurrentSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
-    mSeekPosition = -1;
-    mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
-    mVideoWidth = mVideoHeight = 0;
-}
-
-status_t MediaPlayer2::setListener(const sp<MediaPlayer2Listener>& listener) {
-    ALOGV("setListener");
-    Mutex::Autolock _l(mLock);
-    mListener = listener;
-    return NO_ERROR;
-}
-
-status_t MediaPlayer2::getSrcId(int64_t *srcId) {
-    if (srcId == NULL) {
-        return BAD_VALUE;
-    }
-
-    Mutex::Autolock _l(mLock);
-    *srcId = mSrcId;
-    return OK;
-}
-
-status_t MediaPlayer2::setDataSource(const sp<DataSourceDesc> &dsd) {
-    if (dsd == NULL) {
-        return BAD_VALUE;
-    }
-    // Microsecond is used in NuPlayer2.
-    if (dsd->mStartPositionMs > DataSourceDesc::kMaxTimeMs) {
-        dsd->mStartPositionMs = DataSourceDesc::kMaxTimeMs;
-        ALOGW("setDataSource, start poistion clamped to %lld ms", (long long)dsd->mStartPositionMs);
-    }
-    if (dsd->mEndPositionMs > DataSourceDesc::kMaxTimeMs) {
-        dsd->mEndPositionMs = DataSourceDesc::kMaxTimeMs;
-        ALOGW("setDataSource, end poistion clamped to %lld ms", (long long)dsd->mStartPositionMs);
-    }
-    ALOGV("setDataSource type(%d), srcId(%lld)", dsd->mType, (long long)dsd->mId);
-
-    sp<MediaPlayer2Interface> oldPlayer;
-
-    {
-        Mutex::Autolock _l(mLock);
-        if (!((mCurrentState & MEDIA_PLAYER2_IDLE)
-              || mCurrentState == MEDIA_PLAYER2_STATE_ERROR)) {
-            ALOGE("setDataSource called in wrong state %d", mCurrentState);
-            return INVALID_OPERATION;
-        }
-
-        sp<MediaPlayer2Interface> player = new NuPlayer2Driver(mPid, mUid, mContext);
-        status_t err = player->initCheck();
-        if (err != NO_ERROR) {
-            ALOGE("Failed to create player object, initCheck failed(%d)", err);
-            return err;
-        }
-
-        clear_l();
-
-        player->setListener(new proxyListener(this));
-        player->setAudioSink(mAudioOutput);
-
-        err = player->setDataSource(dsd);
-        if (err != OK) {
-            ALOGE("setDataSource error: %d", err);
-            return err;
-        }
-
-        sp<MediaPlayer2Interface> oldPlayer = mPlayer;
-        mPlayer = player;
-        mSrcId = dsd->mId;
-        mCurrentState = MEDIA_PLAYER2_INITIALIZED;
-    }
-
-    if (oldPlayer != NULL) {
-        oldPlayer->setListener(NULL);
-        oldPlayer->reset();
-    }
-
-    return OK;
-}
-
-status_t MediaPlayer2::prepareNextDataSource(const sp<DataSourceDesc> &dsd) {
-    if (dsd == NULL) {
-        return BAD_VALUE;
-    }
-    ALOGV("prepareNextDataSource type(%d), srcId(%lld)", dsd->mType, (long long)dsd->mId);
-
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == NULL) {
-        ALOGE("prepareNextDataSource failed: state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
-        return INVALID_OPERATION;
-    }
-    return mPlayer->prepareNextDataSource(dsd);
-}
-
-status_t MediaPlayer2::playNextDataSource(int64_t srcId) {
-    ALOGV("playNextDataSource srcId(%lld)", (long long)srcId);
-
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == NULL) {
-        ALOGE("playNextDataSource failed: state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
-        return INVALID_OPERATION;
-    }
-    mSrcId = srcId;
-    mTransitionToNext = true;
-    return mPlayer->playNextDataSource(srcId);
-}
-
-status_t MediaPlayer2::invoke(const PlayerMessage &request, PlayerMessage *reply) {
-    Mutex::Autolock _l(mLock);
-    const bool hasBeenInitialized =
-            (mCurrentState != MEDIA_PLAYER2_STATE_ERROR) &&
-            ((mCurrentState & MEDIA_PLAYER2_IDLE) != MEDIA_PLAYER2_IDLE);
-    if ((mPlayer == NULL) || !hasBeenInitialized) {
-        ALOGE("invoke() failed: wrong state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
-        return INVALID_OPERATION;
-    }
-    return mPlayer->invoke(request, reply);
-}
-
-void MediaPlayer2::disconnectNativeWindow_l() {
-    if (mConnectedWindow != NULL && mConnectedWindow->getANativeWindow() != NULL) {
-        status_t err = native_window_api_disconnect(
-                mConnectedWindow->getANativeWindow(), NATIVE_WINDOW_API_MEDIA);
-
-        if (err != OK) {
-            ALOGW("nativeWindowDisconnect returned an error: %s (%d)",
-                  strerror(-err), err);
-        }
-    }
-    mConnectedWindow.clear();
-}
-
-status_t MediaPlayer2::setVideoSurfaceTexture(const sp<ANativeWindowWrapper>& nww) {
-    ANativeWindow *anw = (nww == NULL ? NULL : nww->getANativeWindow());
-    ALOGV("setVideoSurfaceTexture(%p)", anw);
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) {
-        return NO_INIT;
-    }
-
-    if (anw != NULL) {
-        if (mConnectedWindow != NULL
-            && mConnectedWindow->getANativeWindow() == anw) {
-            return OK;
-        }
-        status_t err = native_window_api_connect(anw, NATIVE_WINDOW_API_MEDIA);
-
-        if (err != OK) {
-            ALOGE("setVideoSurfaceTexture failed: %d", err);
-            // Note that we must do the reset before disconnecting from the ANW.
-            // Otherwise queue/dequeue calls could be made on the disconnected
-            // ANW, which may result in errors.
-            mPlayer->reset();
-            disconnectNativeWindow_l();
-            return err;
-        }
-    }
-
-    // Note that we must set the player's new GraphicBufferProducer before
-    // disconnecting the old one.  Otherwise queue/dequeue calls could be made
-    // on the disconnected ANW, which may result in errors.
-    status_t err = mPlayer->setVideoSurfaceTexture(nww);
-
-    disconnectNativeWindow_l();
-
-    if (err == OK) {
-        mConnectedWindow = nww;
-        mLock.unlock();
-    } else if (anw != NULL) {
-        mLock.unlock();
-        status_t err = native_window_api_disconnect(anw, NATIVE_WINDOW_API_MEDIA);
-
-        if (err != OK) {
-            ALOGW("nativeWindowDisconnect returned an error: %s (%d)",
-                  strerror(-err), err);
-        }
-    }
-
-    return err;
-}
-
-status_t MediaPlayer2::getBufferingSettings(BufferingSettings* buffering /* nonnull */) {
-    ALOGV("getBufferingSettings");
-
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) {
-        return NO_INIT;
-    }
-
-    status_t ret = mPlayer->getBufferingSettings(buffering);
-    if (ret == NO_ERROR) {
-        ALOGV("getBufferingSettings{%s}", buffering->toString().string());
-    } else {
-        ALOGE("getBufferingSettings returned %d", ret);
-    }
-    return ret;
-}
-
-status_t MediaPlayer2::setBufferingSettings(const BufferingSettings& buffering) {
-    ALOGV("setBufferingSettings{%s}", buffering.toString().string());
-
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) {
-        return NO_INIT;
-    }
-    return mPlayer->setBufferingSettings(buffering);
-}
-
-status_t MediaPlayer2::setAudioAttributes_l(const jobject attributes) {
-    if (mAudioOutput != NULL) {
-        mAudioOutput->setAudioAttributes(attributes);
-    }
-    return NO_ERROR;
-}
-
-status_t MediaPlayer2::prepareAsync() {
-    ALOGV("prepareAsync");
-    Mutex::Autolock _l(mLock);
-    if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER2_INITIALIZED)) {
-        if (mAudioAttributes != NULL) {
-            status_t err = setAudioAttributes_l(mAudioAttributes->getJObject());
-            if (err != OK) {
-                return err;
-            }
-        }
-        mCurrentState = MEDIA_PLAYER2_PREPARING;
-        return mPlayer->prepareAsync();
-    }
-    ALOGE("prepareAsync called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
-    return INVALID_OPERATION;
-}
-
-status_t MediaPlayer2::start() {
-    ALOGV("start");
-
-    status_t ret = NO_ERROR;
-    Mutex::Autolock _l(mLock);
-
-    mLockThreadId = getThreadId();
-
-    if (mCurrentState & MEDIA_PLAYER2_STARTED) {
-        ret = NO_ERROR;
-    } else if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER2_PREPARED |
-                    MEDIA_PLAYER2_PLAYBACK_COMPLETE | MEDIA_PLAYER2_PAUSED ) ) ) {
-        mPlayer->setLooping(mLoop);
-
-        if (mAudioOutput != 0) {
-            mAudioOutput->setVolume(mVolume);
-        }
-
-        if (mAudioOutput != 0) {
-            mAudioOutput->setAuxEffectSendLevel(mSendLevel);
-        }
-        mCurrentState = MEDIA_PLAYER2_STARTED;
-        ret = mPlayer->start();
-        if (ret != NO_ERROR) {
-            mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
-        } else {
-            if (mCurrentState == MEDIA_PLAYER2_PLAYBACK_COMPLETE) {
-                ALOGV("playback completed immediately following start()");
-            }
-        }
-    } else {
-        ALOGE("start called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
-        ret = INVALID_OPERATION;
-    }
-
-    mLockThreadId = 0;
-
-    return ret;
-}
-
-status_t MediaPlayer2::pause() {
-    ALOGV("pause");
-    Mutex::Autolock _l(mLock);
-    if (mCurrentState & (MEDIA_PLAYER2_PAUSED|MEDIA_PLAYER2_PLAYBACK_COMPLETE))
-        return NO_ERROR;
-    if ((mPlayer != 0) && (mCurrentState & (MEDIA_PLAYER2_STARTED | MEDIA_PLAYER2_PREPARED))) {
-        status_t ret = mPlayer->pause();
-        if (ret != NO_ERROR) {
-            mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
-        } else {
-            mCurrentState = MEDIA_PLAYER2_PAUSED;
-            mTransitionToNext = false;
-        }
-        return ret;
-    }
-    ALOGE("pause called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
-    return INVALID_OPERATION;
-}
-
-bool MediaPlayer2::isPlaying() {
-    Mutex::Autolock _l(mLock);
-    if (mPlayer != 0) {
-        bool temp = mPlayer->isPlaying();
-        ALOGV("isPlaying: %d", temp);
-        if ((mCurrentState & MEDIA_PLAYER2_STARTED) && ! temp) {
-            ALOGE("internal/external state mismatch corrected");
-            mCurrentState = MEDIA_PLAYER2_PAUSED;
-        } else if ((mCurrentState & MEDIA_PLAYER2_PAUSED) && temp) {
-            ALOGE("internal/external state mismatch corrected");
-            mCurrentState = MEDIA_PLAYER2_STARTED;
-        }
-        return temp;
-    }
-    ALOGV("isPlaying: no active player");
-    return false;
-}
-
-mediaplayer2_states MediaPlayer2::getState() {
-    Mutex::Autolock _l(mLock);
-    if (mCurrentState & MEDIA_PLAYER2_STATE_ERROR) {
-        return MEDIAPLAYER2_STATE_ERROR;
-    }
-    if (mPlayer == 0
-        || (mCurrentState &
-            (MEDIA_PLAYER2_IDLE | MEDIA_PLAYER2_INITIALIZED | MEDIA_PLAYER2_PREPARING))) {
-        return MEDIAPLAYER2_STATE_IDLE;
-    }
-    if (mCurrentState & MEDIA_PLAYER2_STARTED) {
-        return MEDIAPLAYER2_STATE_PLAYING;
-    }
-    if (mCurrentState & (MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE)) {
-        return MEDIAPLAYER2_STATE_PAUSED;
-    }
-    // now only mCurrentState & MEDIA_PLAYER2_PREPARED is true
-    return MEDIAPLAYER2_STATE_PREPARED;
-}
-
-status_t MediaPlayer2::setPlaybackSettings(const AudioPlaybackRate& rate) {
-    ALOGV("setPlaybackSettings: %f %f %d %d",
-            rate.mSpeed, rate.mPitch, rate.mFallbackMode, rate.mStretchMode);
-    // Negative speed and pitch does not make sense. Further validation will
-    // be done by the respective mediaplayers.
-    if (rate.mSpeed <= 0.f || rate.mPitch < 0.f) {
-        return BAD_VALUE;
-    }
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) {
-        return INVALID_OPERATION;
-    }
-
-    status_t err = mPlayer->setPlaybackSettings(rate);
-    return err;
-}
-
-status_t MediaPlayer2::getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */) {
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) {
-        return INVALID_OPERATION;
-    }
-    status_t ret = mPlayer->getPlaybackSettings(rate);
-    if (ret == NO_ERROR) {
-        ALOGV("getPlaybackSettings(%f, %f, %d, %d)",
-                rate->mSpeed, rate->mPitch, rate->mFallbackMode, rate->mStretchMode);
-    } else {
-        ALOGV("getPlaybackSettings returned %d", ret);
-    }
-    return ret;
-}
-
-status_t MediaPlayer2::setSyncSettings(const AVSyncSettings& sync, float videoFpsHint) {
-    ALOGV("setSyncSettings: %u %u %f %f",
-            sync.mSource, sync.mAudioAdjustMode, sync.mTolerance, videoFpsHint);
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) return INVALID_OPERATION;
-    return mPlayer->setSyncSettings(sync, videoFpsHint);
-}
-
-status_t MediaPlayer2::getSyncSettings(
-        AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */) {
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) {
-        return INVALID_OPERATION;
-    }
-    status_t ret = mPlayer->getSyncSettings(sync, videoFps);
-    if (ret == NO_ERROR) {
-        ALOGV("getSyncSettings(%u, %u, %f, %f)",
-                sync->mSource, sync->mAudioAdjustMode, sync->mTolerance, *videoFps);
-    } else {
-        ALOGV("getSyncSettings returned %d", ret);
-    }
-    return ret;
-
-}
-
-status_t MediaPlayer2::getVideoWidth(int *w) {
-    ALOGV("getVideoWidth");
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) {
-        return INVALID_OPERATION;
-    }
-    *w = mVideoWidth;
-    return NO_ERROR;
-}
-
-status_t MediaPlayer2::getVideoHeight(int *h) {
-    ALOGV("getVideoHeight");
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) {
-        return INVALID_OPERATION;
-    }
-    *h = mVideoHeight;
-    return NO_ERROR;
-}
-
-status_t MediaPlayer2::getCurrentPosition(int64_t *msec) {
-    ALOGV("getCurrentPosition");
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) {
-        return INVALID_OPERATION;
-    }
-    if (mCurrentPosition >= 0) {
-        ALOGV("Using cached seek position: %lld", (long long)mCurrentPosition);
-        *msec = mCurrentPosition;
-        return NO_ERROR;
-    }
-    status_t ret = mPlayer->getCurrentPosition(msec);
-    if (ret == NO_ERROR) {
-        ALOGV("getCurrentPosition = %lld", (long long)*msec);
-    } else {
-        ALOGE("getCurrentPosition returned %d", ret);
-    }
-    return ret;
-}
-
-status_t MediaPlayer2::getDuration(int64_t srcId, int64_t *msec) {
-    Mutex::Autolock _l(mLock);
-    // TODO: cache duration for currentSrcId and nextSrcId, and return correct
-    // value for nextSrcId.
-    if (srcId != mSrcId) {
-        *msec = -1;
-        return OK;
-    }
-
-    ALOGV("getDuration_l");
-    bool isValidState = (mCurrentState & (MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
-            MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE));
-    if (mPlayer == 0 || !isValidState) {
-        ALOGE("Attempt to call getDuration in wrong state: mPlayer=%p, mCurrentState=%u",
-                mPlayer.get(), mCurrentState);
-        return INVALID_OPERATION;
-    }
-    int64_t durationMs;
-    status_t ret = mPlayer->getDuration(&durationMs);
-
-    if (ret == NO_ERROR) {
-        ALOGV("getDuration = %lld", (long long)durationMs);
-    } else {
-        ALOGE("getDuration returned %d", ret);
-        // Do not enter error state just because no duration was available.
-        durationMs = -1;
-    }
-
-    if (msec) {
-        *msec = durationMs;
-    }
-    return OK;
-}
-
-status_t MediaPlayer2::seekTo_l(int64_t msec, MediaPlayer2SeekMode mode) {
-    ALOGV("seekTo (%lld, %d)", (long long)msec, mode);
-    if ((mPlayer == 0) || !(mCurrentState & (MEDIA_PLAYER2_STARTED | MEDIA_PLAYER2_PREPARED |
-            MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE))) {
-        ALOGE("Attempt to perform seekTo in wrong state: mPlayer=%p, mCurrentState=%u",
-              mPlayer.get(), mCurrentState);
-        return INVALID_OPERATION;
-    }
-    if (msec < 0) {
-        ALOGW("Attempt to seek to invalid position: %lld", (long long)msec);
-        msec = 0;
-    }
-
-    int64_t durationMs;
-    status_t err = mPlayer->getDuration(&durationMs);
-
-    if (err != OK) {
-        ALOGW("Stream has no duration and is therefore not seekable.");
-        return err;
-    }
-
-    if (msec > durationMs) {
-        ALOGW("Attempt to seek to past end of file: request = %lld, durationMs = %lld",
-              (long long)msec, (long long)durationMs);
-
-        msec = durationMs;
-    }
-
-    // cache duration
-    mCurrentPosition = msec;
-    mCurrentSeekMode = mode;
-    if (mSeekPosition < 0) {
-        mSeekPosition = msec;
-        mSeekMode = mode;
-        return mPlayer->seekTo(msec, mode);
-    }
-    ALOGV("Seek in progress - queue up seekTo[%lld, %d]", (long long)msec, mode);
-    return NO_ERROR;
-}
-
-status_t MediaPlayer2::seekTo(int64_t msec, MediaPlayer2SeekMode mode) {
-    mLockThreadId = getThreadId();
-    Mutex::Autolock _l(mLock);
-    status_t result = seekTo_l(msec, mode);
-    mLockThreadId = 0;
-
-    return result;
-}
-
-status_t MediaPlayer2::notifyAt(int64_t mediaTimeUs) {
-    Mutex::Autolock _l(mLock);
-    if (mPlayer != 0) {
-        return INVALID_OPERATION;
-    }
-
-    return mPlayer->notifyAt(mediaTimeUs);
-}
-
-status_t MediaPlayer2::reset_l() {
-    mLoop = false;
-    if (mCurrentState == MEDIA_PLAYER2_IDLE) {
-        return NO_ERROR;
-    }
-    if (mPlayer != 0) {
-        status_t ret = mPlayer->reset();
-        if (ret != NO_ERROR) {
-            ALOGE("reset() failed with return code (%d)", ret);
-            mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
-        } else {
-            mPlayer->setListener(NULL);
-            mCurrentState = MEDIA_PLAYER2_IDLE;
-            mTransitionToNext = false;
-        }
-        // setDataSource has to be called again to create a
-        // new mediaplayer.
-        mPlayer = 0;
-        return ret;
-    }
-    clear_l();
-    return NO_ERROR;
-}
-
-status_t MediaPlayer2::reset() {
-    ALOGV("reset");
-    mLockThreadId = getThreadId();
-    Mutex::Autolock _l(mLock);
-    status_t result = reset_l();
-    mLockThreadId = 0;
-
-    return result;
-}
-
-status_t MediaPlayer2::setAudioStreamType(audio_stream_type_t type) {
-    ALOGV("MediaPlayer2::setAudioStreamType");
-    Mutex::Autolock _l(mLock);
-    if (mStreamType == type) return NO_ERROR;
-    if (mCurrentState & ( MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
-                MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE ) ) {
-        // Can't change the stream type after prepare
-        ALOGE("setAudioStream called in state %d", mCurrentState);
-        return INVALID_OPERATION;
-    }
-    // cache
-    mStreamType = type;
-    return OK;
-}
-
-status_t MediaPlayer2::getAudioStreamType(audio_stream_type_t *type) {
-    ALOGV("getAudioStreamType");
-    Mutex::Autolock _l(mLock);
-    *type = mStreamType;
-    return OK;
-}
-
-status_t MediaPlayer2::setLooping(int loop) {
-    ALOGV("MediaPlayer2::setLooping");
-    Mutex::Autolock _l(mLock);
-    mLoop = (loop != 0);
-    if (mPlayer != 0) {
-        return mPlayer->setLooping(loop);
-    }
-    return OK;
-}
-
-bool MediaPlayer2::isLooping() {
-    ALOGV("isLooping");
-    Mutex::Autolock _l(mLock);
-    if (mPlayer != 0) {
-        return mLoop;
-    }
-    ALOGV("isLooping: no active player");
-    return false;
-}
-
-status_t MediaPlayer2::setVolume(float volume) {
-    ALOGV("MediaPlayer2::setVolume(%f)", volume);
-    Mutex::Autolock _l(mLock);
-    mVolume = volume;
-    if (mAudioOutput != 0) {
-        mAudioOutput->setVolume(volume);
-    }
-    return OK;
-}
-
-status_t MediaPlayer2::setAudioSessionId(int32_t sessionId) {
-    ALOGV("MediaPlayer2::setAudioSessionId(%d)", sessionId);
-    Mutex::Autolock _l(mLock);
-    if (!(mCurrentState & MEDIA_PLAYER2_IDLE)) {
-        ALOGE("setAudioSessionId called in state %d", mCurrentState);
-        return INVALID_OPERATION;
-    }
-    if (sessionId < 0) {
-        return BAD_VALUE;
-    }
-    if (mAudioOutput != NULL && sessionId != mAudioOutput->getSessionId()) {
-        mAudioOutput->setSessionId(sessionId);
-    }
-    return NO_ERROR;
-}
-
-int32_t MediaPlayer2::getAudioSessionId() {
-    Mutex::Autolock _l(mLock);
-    if (mAudioOutput != NULL) {
-        return mAudioOutput->getSessionId();
-    }
-    return 0;
-}
-
-status_t MediaPlayer2::setAuxEffectSendLevel(float level) {
-    ALOGV("MediaPlayer2::setAuxEffectSendLevel(%f)", level);
-    Mutex::Autolock _l(mLock);
-    mSendLevel = level;
-    if (mAudioOutput != 0) {
-        return mAudioOutput->setAuxEffectSendLevel(level);
-    }
-    return OK;
-}
-
-status_t MediaPlayer2::attachAuxEffect(int effectId) {
-    ALOGV("MediaPlayer2::attachAuxEffect(%d)", effectId);
-    Mutex::Autolock _l(mLock);
-    if (mAudioOutput == 0 ||
-        (mCurrentState & MEDIA_PLAYER2_IDLE) ||
-        (mCurrentState == MEDIA_PLAYER2_STATE_ERROR )) {
-        ALOGE("attachAuxEffect called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
-        return INVALID_OPERATION;
-    }
-
-    return mAudioOutput->attachAuxEffect(effectId);
-}
-
-// always call with lock held
-status_t MediaPlayer2::checkState_l() {
-    if (mCurrentState & ( MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
-            MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE) ) {
-        // Can't change the audio attributes after prepare
-        ALOGE("trying to set audio attributes called in state %d", mCurrentState);
-        return INVALID_OPERATION;
-    }
-    return OK;
-}
-
-status_t MediaPlayer2::setAudioAttributes(const jobject attributes) {
-    ALOGV("MediaPlayer2::setAudioAttributes");
-    status_t status = INVALID_OPERATION;
-    Mutex::Autolock _l(mLock);
-    if (checkState_l() != OK) {
-        return status;
-    }
-    mAudioAttributes = new JObjectHolder(attributes);
-    status = setAudioAttributes_l(attributes);
-    return status;
-}
-
-jobject MediaPlayer2::getAudioAttributes() {
-    ALOGV("MediaPlayer2::getAudioAttributes)");
-    Mutex::Autolock _l(mLock);
-    return mAudioAttributes != NULL ? mAudioAttributes->getJObject() : NULL;
-}
-
-status_t MediaPlayer2::getParameter(int key, Parcel *reply) {
-    ALOGV("MediaPlayer2::getParameter(%d)", key);
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == NULL) {
-        ALOGV("getParameter: no active player");
-        return INVALID_OPERATION;
-    }
-
-    status_t status =  mPlayer->getParameter(key, reply);
-    if (status != OK) {
-        ALOGD("getParameter returns %d", status);
-    }
-    return status;
-}
-
-// for mediametrics
-status_t MediaPlayer2::getMetrics(char **buffer, size_t *length) {
-    ALOGD("MediaPlayer2::getMetrics()");
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == NULL) {
-        ALOGV("getMetrics: no active player");
-        return INVALID_OPERATION;
-    }
-
-    status_t status =  mPlayer->getMetrics(buffer, length);
-    if (status != OK) {
-        ALOGD("getMetrics returns %d", status);
-    }
-    return status;
-}
-
-void MediaPlayer2::notify(int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *obj) {
-    ALOGV("message received srcId=%lld, msg=%d, ext1=%d, ext2=%d",
-          (long long)srcId, msg, ext1, ext2);
-
-    bool send = true;
-    bool locked = false;
-
-    // TODO: In the future, we might be on the same thread if the app is
-    // running in the same process as the media server. In that case,
-    // this will deadlock.
-    //
-    // The threadId hack below works around this for the care of prepare,
-    // seekTo, start, and reset within the same process.
-    // FIXME: Remember, this is a hack, it's not even a hack that is applied
-    // consistently for all use-cases, this needs to be revisited.
-    if (mLockThreadId != getThreadId()) {
-        mLock.lock();
-        locked = true;
-    }
-
-    // Allows calls from JNI in idle state to notify errors
-    if (!(msg == MEDIA2_ERROR && mCurrentState == MEDIA_PLAYER2_IDLE) && mPlayer == 0) {
-        ALOGV("notify(%lld, %d, %d, %d) callback on disconnected mediaplayer",
-              (long long)srcId, msg, ext1, ext2);
-        if (locked) mLock.unlock();   // release the lock when done.
-        return;
-    }
-
-    switch (msg) {
-    case MEDIA2_NOP: // interface test message
-        break;
-    case MEDIA2_PREPARED:
-        ALOGV("MediaPlayer2::notify() prepared, srcId=%lld", (long long)srcId);
-        if (srcId == mSrcId) {
-            mCurrentState = MEDIA_PLAYER2_PREPARED;
-        }
-        break;
-    case MEDIA2_DRM_INFO:
-        ALOGV("MediaPlayer2::notify() MEDIA2_DRM_INFO(%lld, %d, %d, %d, %p)",
-              (long long)srcId, msg, ext1, ext2, obj);
-        break;
-    case MEDIA2_PLAYBACK_COMPLETE:
-        ALOGV("playback complete");
-        if (mCurrentState == MEDIA_PLAYER2_IDLE) {
-            ALOGE("playback complete in idle state");
-        }
-        if (!mLoop && srcId == mSrcId) {
-            mCurrentState = MEDIA_PLAYER2_PLAYBACK_COMPLETE;
-        }
-        break;
-    case MEDIA2_ERROR:
-        // Always log errors.
-        // ext1: Media framework error code.
-        // ext2: Implementation dependant error code.
-        ALOGE("error (%d, %d)", ext1, ext2);
-        mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
-        break;
-    case MEDIA2_INFO:
-        // ext1: Media framework error code.
-        // ext2: Implementation dependant error code.
-        if (ext1 != MEDIA2_INFO_VIDEO_TRACK_LAGGING) {
-            ALOGW("info/warning (%d, %d)", ext1, ext2);
-
-            if (ext1 == MEDIA2_INFO_DATA_SOURCE_START && srcId == mSrcId && mTransitionToNext) {
-                mCurrentState = MEDIA_PLAYER2_STARTED;
-                mTransitionToNext = false;
-            }
-        }
-        break;
-    case MEDIA2_SEEK_COMPLETE:
-        ALOGV("Received seek complete");
-        if (mSeekPosition != mCurrentPosition || (mSeekMode != mCurrentSeekMode)) {
-            ALOGV("Executing queued seekTo(%lld, %d)",
-                  (long long)mCurrentPosition, mCurrentSeekMode);
-            mSeekPosition = -1;
-            mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
-            seekTo_l(mCurrentPosition, mCurrentSeekMode);
-        }
-        else {
-            ALOGV("All seeks complete - return to regularly scheduled program");
-            mCurrentPosition = mSeekPosition = -1;
-            mCurrentSeekMode = mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
-        }
-        break;
-    case MEDIA2_BUFFERING_UPDATE:
-        ALOGV("buffering %d", ext1);
-        break;
-    case MEDIA2_SET_VIDEO_SIZE:
-        ALOGV("New video size %d x %d", ext1, ext2);
-        mVideoWidth = ext1;
-        mVideoHeight = ext2;
-        break;
-    case MEDIA2_NOTIFY_TIME:
-        ALOGV("Received notify time message");
-        break;
-    case MEDIA2_TIMED_TEXT:
-        ALOGV("Received timed text message");
-        break;
-    case MEDIA2_SUBTITLE_DATA:
-        ALOGV("Received subtitle data message");
-        break;
-    case MEDIA2_META_DATA:
-        ALOGV("Received timed metadata message");
-        break;
-    default:
-        ALOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2);
-        break;
-    }
-
-    sp<MediaPlayer2Listener> listener = mListener;
-    if (locked) mLock.unlock();
-
-    // this prevents re-entrant calls into client code
-    if ((listener != 0) && send) {
-        Mutex::Autolock _l(mNotifyLock);
-        ALOGV("callback application");
-        listener->notify(srcId, msg, ext1, ext2, obj);
-        ALOGV("back from callback");
-    }
-}
-
-// Modular DRM
-status_t MediaPlayer2::prepareDrm(
-        int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId) {
-    // TODO change to ALOGV
-    ALOGD("prepareDrm: uuid: %p  drmSessionId: %p(%zu)", uuid,
-            drmSessionId.array(), drmSessionId.size());
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == NULL) {
-        return NO_INIT;
-    }
-
-    // Only allowed it in player's preparing/prepared state.
-    // We get here only if MEDIA_DRM_INFO has already arrived (e.g., prepare is half-way through or
-    // completed) so the state change to "prepared" might not have happened yet (e.g., buffering).
-    // Still, we can allow prepareDrm for the use case of being called in OnDrmInfoListener.
-    if (!(mCurrentState & (MEDIA_PLAYER2_PREPARING | MEDIA_PLAYER2_PREPARED))) {
-        ALOGW("prepareDrm(%lld) called in non-prepare state(%d)", (long long)srcId, mCurrentState);
-        if (srcId == mSrcId) {
-            return INVALID_OPERATION;
-        }
-    }
-
-    if (drmSessionId.isEmpty()) {
-        ALOGE("prepareDrm: Unexpected. Can't proceed with crypto. Empty drmSessionId.");
-        return INVALID_OPERATION;
-    }
-
-    // Passing down to mediaserver mainly for creating the crypto
-    status_t status = mPlayer->prepareDrm(srcId, uuid, drmSessionId);
-    ALOGE_IF(status != OK, "prepareDrm: Failed at mediaserver with ret: %d", status);
-
-    // TODO change to ALOGV
-    ALOGD("prepareDrm: mediaserver::prepareDrm ret=%d", status);
-
-    return status;
-}
-
-status_t MediaPlayer2::releaseDrm(int64_t srcId) {
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == NULL) {
-        return NO_INIT;
-    }
-
-    // Not allowing releaseDrm in an active/resumable state
-    if (mCurrentState & (MEDIA_PLAYER2_STARTED |
-                         MEDIA_PLAYER2_PAUSED |
-                         MEDIA_PLAYER2_PLAYBACK_COMPLETE |
-                         MEDIA_PLAYER2_STATE_ERROR)) {
-        ALOGE("releaseDrm Unexpected state %d. Can only be called in stopped/idle.", mCurrentState);
-        return INVALID_OPERATION;
-    }
-
-    status_t status = mPlayer->releaseDrm(srcId);
-    // TODO change to ALOGV
-    ALOGD("releaseDrm: mediaserver::releaseDrm ret: %d", status);
-    if (status != OK) {
-        ALOGE("releaseDrm: Failed at mediaserver with ret: %d", status);
-        // Overriding to OK so the client proceed with its own cleanup
-        // Client can't do more cleanup. mediaserver release its crypto at end of session anyway.
-        status = OK;
-    }
-
-    return status;
-}
-
-status_t MediaPlayer2::setPreferredDevice(jobject device) {
-    Mutex::Autolock _l(mLock);
-    if (mAudioOutput == NULL) {
-        ALOGV("setPreferredDevice: audio sink not init");
-        return NO_INIT;
-    }
-    return mAudioOutput->setPreferredDevice(device);
-}
-
-jobject MediaPlayer2::getRoutedDevice() {
-    Mutex::Autolock _l(mLock);
-    if (mAudioOutput == NULL) {
-        ALOGV("getRoutedDevice: audio sink not init");
-        return nullptr;
-    }
-    return mAudioOutput->getRoutedDevice();
-}
-
-status_t MediaPlayer2::addAudioDeviceCallback(jobject routingDelegate) {
-    Mutex::Autolock _l(mLock);
-    if (mAudioOutput == NULL) {
-        ALOGV("addAudioDeviceCallback: player not init");
-        return NO_INIT;
-    }
-    return mAudioOutput->addAudioDeviceCallback(routingDelegate);
-}
-
-status_t MediaPlayer2::removeAudioDeviceCallback(jobject listener) {
-    Mutex::Autolock _l(mLock);
-    if (mAudioOutput == NULL) {
-        ALOGV("addAudioDeviceCallback: player not init");
-        return NO_INIT;
-    }
-    return mAudioOutput->removeAudioDeviceCallback(listener);
-}
-
-status_t MediaPlayer2::dump(int fd, const Vector<String16>& args) {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-    result.append(" MediaPlayer2\n");
-    snprintf(buffer, 255, "  pid(%d), looping(%s)\n", mPid, mLoop?"true": "false");
-    result.append(buffer);
-
-    sp<MediaPlayer2Interface> player;
-    sp<MediaPlayer2AudioOutput> audioOutput;
-    bool locked = false;
-    for (int i = 0; i < kDumpLockRetries; ++i) {
-        if (mLock.tryLock() == NO_ERROR) {
-            locked = true;
-            break;
-        }
-        usleep(kDumpLockSleepUs);
-    }
-
-    if (locked) {
-        player = mPlayer;
-        audioOutput = mAudioOutput;
-        mLock.unlock();
-    } else {
-        result.append("  lock is taken, no dump from player and audio output\n");
-    }
-    write(fd, result.string(), result.size());
-
-    if (player != NULL) {
-        player->dump(fd, args);
-    }
-    if (audioOutput != 0) {
-        audioOutput->dump(fd, args);
-    }
-    write(fd, "\n", 1);
-    return NO_ERROR;
-}
-
-} // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/Android.bp b/media/libmediaplayer2/nuplayer2/Android.bp
deleted file mode 100644
index 0f69b2e..0000000
--- a/media/libmediaplayer2/nuplayer2/Android.bp
+++ /dev/null
@@ -1,72 +0,0 @@
-cc_library_static {
-
-    srcs: [
-        "JMediaPlayer2Utils.cpp",
-        "JWakeLock.cpp",
-        "GenericSource2.cpp",
-        "HTTPLiveSource2.cpp",
-        "NuPlayer2.cpp",
-        "NuPlayer2CCDecoder.cpp",
-        "NuPlayer2Decoder.cpp",
-        "NuPlayer2DecoderBase.cpp",
-        "NuPlayer2DecoderPassThrough.cpp",
-        "NuPlayer2Driver.cpp",
-        "NuPlayer2Drm.cpp",
-        "NuPlayer2Renderer.cpp",
-        "RTSPSource2.cpp",
-    ],
-
-    header_libs: [
-        "libbase_headers",
-        "libmediaplayer2_headers",
-        "media_plugin_headers",
-    ],
-
-    include_dirs: [
-        "frameworks/av/media/libstagefright",
-        "frameworks/av/media/libstagefright/httplive",
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/av/media/libstagefright/mpeg2ts",
-        "frameworks/av/media/libstagefright/rtsp",
-        "frameworks/av/media/libstagefright/timedtext",
-        "frameworks/av/media/ndk",
-        "frameworks/base/core/jni",
-    ],
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-    ],
-
-    product_variables: {
-        debuggable: {
-            cflags: [
-                "-DENABLE_STAGEFRIGHT_EXPERIMENTS",
-            ],
-        }
-    },
-
-    shared_libs: [
-        "libbinder",
-        "libui",
-        "libgui",
-        "libmedia",
-        "libmediametrics",
-        "libmediandk",
-        "libmediandk_utils",
-        "libpowermanager",
-    ],
-
-    static_libs: [
-        "libmedia_helper",
-        "libmediaplayer2-protos",
-        "libmedia2_jni_core",
-    ],
-
-    name: "libstagefright_nuplayer2",
-
-    sanitize: {
-        cfi: true,
-    },
-
-}
diff --git a/media/libmediaplayer2/nuplayer2/GenericSource2.cpp b/media/libmediaplayer2/nuplayer2/GenericSource2.cpp
deleted file mode 100644
index 9552580..0000000
--- a/media/libmediaplayer2/nuplayer2/GenericSource2.cpp
+++ /dev/null
@@ -1,1547 +0,0 @@
-/*
- * Copyright 2017 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 "GenericSource2"
-
-#include "GenericSource2.h"
-#include "NuPlayer2Drm.h"
-
-#include "AnotherPacketSource.h"
-#include <cutils/properties.h>
-#include <media/DataSource.h>
-#include <media/MediaBufferHolder.h>
-#include <media/NdkWrapper.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/MediaClock.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/NdkUtils.h>
-#include <media/stagefright/Utils.h>
-
-namespace android {
-
-static const int kInitialMarkMs        = 5000;  // 5secs
-
-//static const int kPausePlaybackMarkMs  = 2000;  // 2secs
-static const int kResumePlaybackMarkMs = 15000;  // 15secs
-
-NuPlayer2::GenericSource2::GenericSource2(
-        const sp<AMessage> &notify,
-        uid_t uid,
-        const sp<MediaClock> &mediaClock)
-    : Source(notify),
-      mAudioTimeUs(0),
-      mAudioLastDequeueTimeUs(0),
-      mVideoTimeUs(0),
-      mVideoLastDequeueTimeUs(0),
-      mPrevBufferPercentage(-1),
-      mPollBufferingGeneration(0),
-      mSentPauseOnBuffering(false),
-      mAudioDataGeneration(0),
-      mVideoDataGeneration(0),
-      mFetchSubtitleDataGeneration(0),
-      mFetchTimedTextDataGeneration(0),
-      mDurationUs(-1ll),
-      mAudioIsVorbis(false),
-      mIsSecure(false),
-      mIsStreaming(false),
-      mUID(uid),
-      mMediaClock(mediaClock),
-      mFd(-1),
-      mBitrate(-1ll),
-      mPendingReadBufferTypes(0) {
-    ALOGV("GenericSource2");
-    CHECK(mediaClock != NULL);
-
-    mBufferingSettings.mInitialMarkMs = kInitialMarkMs;
-    mBufferingSettings.mResumePlaybackMarkMs = kResumePlaybackMarkMs;
-    resetDataSource();
-}
-
-void NuPlayer2::GenericSource2::resetDataSource() {
-    ALOGV("resetDataSource");
-
-    mDisconnected = false;
-    mUri.clear();
-    mUriHeaders.clear();
-    if (mFd >= 0) {
-        close(mFd);
-        mFd = -1;
-    }
-    mOffset = 0;
-    mLength = 0;
-    mStarted = false;
-    mPreparing = false;
-
-    mIsDrmProtected = false;
-    mIsDrmReleased = false;
-    mIsSecure = false;
-    mMimes.clear();
-}
-
-status_t NuPlayer2::GenericSource2::setDataSource(
-        const char *url,
-        const KeyedVector<String8, String8> *headers) {
-    Mutex::Autolock _l(mLock);
-    ALOGV("setDataSource url: %s", url);
-
-    resetDataSource();
-
-    mUri = url;
-
-    if (headers) {
-        mUriHeaders = *headers;
-    }
-
-    // delay data source creation to prepareAsync() to avoid blocking
-    // the calling thread in setDataSource for any significant time.
-    return OK;
-}
-
-status_t NuPlayer2::GenericSource2::setDataSource(
-        int fd, int64_t offset, int64_t length) {
-    Mutex::Autolock _l(mLock);
-    ALOGV("setDataSource %d/%lld/%lld", fd, (long long)offset, (long long)length);
-
-    resetDataSource();
-
-    mFd = dup(fd);
-    mOffset = offset;
-    mLength = length;
-
-    // delay data source creation to prepareAsync() to avoid blocking
-    // the calling thread in setDataSource for any significant time.
-    return OK;
-}
-
-status_t NuPlayer2::GenericSource2::setDataSource(const sp<DataSource>& source) {
-    Mutex::Autolock _l(mLock);
-    ALOGV("setDataSource (source: %p)", source.get());
-
-    resetDataSource();
-    mDataSourceWrapper = new AMediaDataSourceWrapper(source);
-    return OK;
-}
-
-sp<MetaData> NuPlayer2::GenericSource2::getFileFormatMeta() const {
-    Mutex::Autolock _l(mLock);
-    return mFileMeta;
-}
-
-status_t NuPlayer2::GenericSource2::initFromDataSource() {
-    mExtractor = new AMediaExtractorWrapper(AMediaExtractor_new());
-    CHECK(mFd >=0 || mDataSourceWrapper != NULL);
-    sp<AMediaDataSourceWrapper> aSourceWrapper = mDataSourceWrapper;
-    const int fd = mFd;
-
-    mLock.unlock();
-    // This might take long time if data source is not reliable.
-    status_t err;
-    if (aSourceWrapper != NULL) {
-        err = mExtractor->setDataSource(aSourceWrapper->getAMediaDataSource());
-    } else {
-        err = mExtractor->setDataSource(fd, mOffset, mLength);
-    }
-
-    if (err != OK) {
-        ALOGE("initFromDataSource, failed to set extractor data source!");
-        mLock.lock();
-        return UNKNOWN_ERROR;
-    }
-
-    size_t numtracks = mExtractor->getTrackCount();
-    if (numtracks == 0) {
-        ALOGE("initFromDataSource, source has no track!");
-        mLock.lock();
-        return UNKNOWN_ERROR;
-    }
-
-    mFileMeta = convertMediaFormatWrapperToMetaData(mExtractor->getFormat());
-    mLock.lock();
-    if (mFileMeta != NULL) {
-        int64_t duration;
-        if (mFileMeta->findInt64(kKeyDuration, &duration)) {
-            mDurationUs = duration;
-        }
-    }
-
-    int32_t totalBitrate = 0;
-
-    mMimes.clear();
-
-    for (size_t i = 0; i < numtracks; ++i) {
-
-        sp<AMediaFormatWrapper> trackFormat = mExtractor->getTrackFormat(i);
-        if (trackFormat == NULL) {
-            ALOGE("no metadata for track %zu", i);
-            return UNKNOWN_ERROR;
-        }
-
-        sp<AMediaExtractorWrapper> trackExtractor = new AMediaExtractorWrapper(AMediaExtractor_new());
-        if (aSourceWrapper != NULL) {
-            trackExtractor->setDataSource(aSourceWrapper->getAMediaDataSource());
-        } else {
-            trackExtractor->setDataSource(fd, mOffset, mLength);
-        }
-
-        const char *mime;
-        sp<MetaData> meta = convertMediaFormatWrapperToMetaData(trackFormat);
-        CHECK(meta->findCString(kKeyMIMEType, &mime));
-
-        ALOGV("initFromDataSource track[%zu]: %s", i, mime);
-
-        // Do the string compare immediately with "mime",
-        // we can't assume "mime" would stay valid after another
-        // extractor operation, some extractors might modify meta
-        // during getTrack() and make it invalid.
-        if (!strncasecmp(mime, "audio/", 6)) {
-            if (mAudioTrack.mExtractor == NULL) {
-                mAudioTrack.mIndex = i;
-                mAudioTrack.mExtractor = trackExtractor;
-                mAudioTrack.mExtractor->selectTrack(i);
-                mAudioTrack.mPackets = new AnotherPacketSource(meta);
-
-                if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
-                    mAudioIsVorbis = true;
-                } else {
-                    mAudioIsVorbis = false;
-                }
-
-                mMimes.add(String8(mime));
-            }
-        } else if (!strncasecmp(mime, "video/", 6)) {
-            if (mVideoTrack.mExtractor == NULL) {
-                mVideoTrack.mIndex = i;
-                mVideoTrack.mExtractor = trackExtractor;
-                mVideoTrack.mExtractor->selectTrack(i);
-                mVideoTrack.mPackets = new AnotherPacketSource(meta);
-
-                // video always at the beginning
-                mMimes.insertAt(String8(mime), 0);
-            }
-        }
-
-        mExtractors.push(trackExtractor);
-        int64_t durationUs;
-        if (meta->findInt64(kKeyDuration, &durationUs)) {
-            if (durationUs > mDurationUs) {
-                mDurationUs = durationUs;
-            }
-        }
-
-        int32_t bitrate;
-        if (totalBitrate >= 0 && meta->findInt32(kKeyBitRate, &bitrate)) {
-            totalBitrate += bitrate;
-        } else {
-            totalBitrate = -1;
-        }
-    }
-
-    ALOGV("initFromDataSource mExtractors.size(): %zu  mIsSecure: %d  mime[0]: %s", mExtractors.size(),
-            mIsSecure, (mMimes.isEmpty() ? "NONE" : mMimes[0].string()));
-
-    if (mExtractors.size() == 0) {
-        ALOGE("b/23705695");
-        return UNKNOWN_ERROR;
-    }
-
-    // Modular DRM: The return value doesn't affect source initialization.
-    (void)checkDrmInfo();
-
-    mBitrate = totalBitrate;
-
-    return OK;
-}
-
-status_t NuPlayer2::GenericSource2::getBufferingSettings(
-        BufferingSettings* buffering /* nonnull */) {
-    {
-        Mutex::Autolock _l(mLock);
-        *buffering = mBufferingSettings;
-    }
-
-    ALOGV("getBufferingSettings{%s}", buffering->toString().string());
-    return OK;
-}
-
-status_t NuPlayer2::GenericSource2::setBufferingSettings(const BufferingSettings& buffering) {
-    ALOGV("setBufferingSettings{%s}", buffering.toString().string());
-
-    Mutex::Autolock _l(mLock);
-    mBufferingSettings = buffering;
-    return OK;
-}
-
-int64_t NuPlayer2::GenericSource2::getLastReadPosition() {
-    if (mAudioTrack.mExtractor != NULL) {
-        return mAudioTimeUs;
-    } else if (mVideoTrack.mExtractor != NULL) {
-        return mVideoTimeUs;
-    } else {
-        return 0;
-    }
-}
-
-bool NuPlayer2::GenericSource2::isStreaming() const {
-    Mutex::Autolock _l(mLock);
-    return mIsStreaming;
-}
-
-NuPlayer2::GenericSource2::~GenericSource2() {
-    ALOGV("~GenericSource2");
-    if (mLooper != NULL) {
-        mLooper->unregisterHandler(id());
-        mLooper->stop();
-    }
-    if (mDataSourceWrapper != NULL) {
-        mDataSourceWrapper->close();
-    }
-    resetDataSource();
-}
-
-void NuPlayer2::GenericSource2::prepareAsync(int64_t startTimeUs) {
-    Mutex::Autolock _l(mLock);
-    ALOGV("prepareAsync: (looper: %d)", (mLooper != NULL));
-
-    if (mLooper == NULL) {
-        mLooper = new ALooper;
-        mLooper->setName("generic2");
-        mLooper->start(false, /* runOnCallingThread */
-                       true,  /* canCallJava */
-                       PRIORITY_DEFAULT);
-
-        mLooper->registerHandler(this);
-    }
-
-    sp<AMessage> msg = new AMessage(kWhatPrepareAsync, this);
-    msg->setInt64("startTimeUs", startTimeUs);
-
-    msg->post();
-}
-
-void NuPlayer2::GenericSource2::onPrepareAsync(int64_t startTimeUs) {
-    ALOGV("onPrepareAsync: mFd %d mUri %s mDataSourceWrapper: %p",
-            mFd, mUri.c_str(), mDataSourceWrapper.get());
-
-    if (!mUri.empty()) {
-        const char* uri = mUri.c_str();
-        size_t numheaders = mUriHeaders.size();
-        const char **key_values = numheaders ? new const char *[numheaders * 2] : NULL;
-        for (size_t i = 0; i < numheaders; ++i) {
-            key_values[i * 2] = mUriHeaders.keyAt(i).c_str();
-            key_values[i * 2 + 1] =  mUriHeaders.valueAt(i).c_str();
-        }
-        mLock.unlock();
-        AMediaDataSource *aSource = AMediaDataSource_newUri(uri, numheaders, key_values);
-        mLock.lock();
-        mDataSourceWrapper = aSource ? new AMediaDataSourceWrapper(aSource) : NULL;
-        delete[] key_values;
-        // For cached streaming cases, we need to wait for enough
-        // buffering before reporting prepared.
-        mIsStreaming = !strncasecmp("http://", uri, 7) || !strncasecmp("https://", uri, 8);
-    }
-
-    if (mDisconnected || (mFd < 0 && mDataSourceWrapper == NULL)) {
-        ALOGE("mDisconnected(%d) or Failed to create data source!", mDisconnected);
-        notifyPreparedAndCleanup(UNKNOWN_ERROR);
-        return;
-    }
-
-    // init extractor from data source
-    status_t err = initFromDataSource();
-    if (mFd >= 0) {
-        close(mFd);
-        mFd = -1;
-    }
-
-    if (err != OK) {
-        ALOGE("Failed to init from data source!");
-        notifyPreparedAndCleanup(err);
-        return;
-    }
-
-    if (mVideoTrack.mExtractor != NULL) {
-        sp<MetaData> meta = getFormatMeta_l(false /* audio */);
-        sp<AMessage> msg = new AMessage;
-        err = convertMetaDataToMessage(meta, &msg);
-        if(err != OK) {
-            notifyPreparedAndCleanup(err);
-            return;
-        }
-        notifyVideoSizeChanged(msg);
-    }
-
-    notifyFlagsChanged(
-            // FLAG_SECURE will be known if/when prepareDrm is called by the app
-            // FLAG_PROTECTED will be known if/when prepareDrm is called by the app
-            FLAG_CAN_PAUSE |
-            FLAG_CAN_SEEK_BACKWARD |
-            FLAG_CAN_SEEK_FORWARD |
-            FLAG_CAN_SEEK);
-
-    doSeek(startTimeUs, MediaPlayer2SeekMode::SEEK_CLOSEST);
-    finishPrepareAsync();
-
-    ALOGV("onPrepareAsync: Done");
-}
-
-void NuPlayer2::GenericSource2::finishPrepareAsync() {
-    ALOGV("finishPrepareAsync");
-
-    if (mIsStreaming) {
-        mPreparing = true;
-        ++mPollBufferingGeneration;
-        schedulePollBuffering();
-    } else {
-        notifyPrepared();
-    }
-
-    if (mAudioTrack.mExtractor != NULL) {
-        postReadBuffer(MEDIA_TRACK_TYPE_AUDIO);
-    }
-
-    if (mVideoTrack.mExtractor != NULL) {
-        postReadBuffer(MEDIA_TRACK_TYPE_VIDEO);
-    }
-}
-
-void NuPlayer2::GenericSource2::notifyPreparedAndCleanup(status_t err) {
-    if (err != OK) {
-        mDataSourceWrapper.clear();
-
-        mBitrate = -1;
-        mPrevBufferPercentage = -1;
-        ++mPollBufferingGeneration;
-    }
-    notifyPrepared(err);
-}
-
-void NuPlayer2::GenericSource2::start() {
-    Mutex::Autolock _l(mLock);
-    ALOGI("start");
-
-    if (mAudioTrack.mExtractor != NULL) {
-        postReadBuffer(MEDIA_TRACK_TYPE_AUDIO);
-    }
-
-    if (mVideoTrack.mExtractor != NULL) {
-        postReadBuffer(MEDIA_TRACK_TYPE_VIDEO);
-    }
-
-    mStarted = true;
-}
-
-void NuPlayer2::GenericSource2::stop() {
-    Mutex::Autolock _l(mLock);
-    mStarted = false;
-}
-
-void NuPlayer2::GenericSource2::pause() {
-    Mutex::Autolock _l(mLock);
-    mStarted = false;
-}
-
-void NuPlayer2::GenericSource2::resume() {
-    Mutex::Autolock _l(mLock);
-    mStarted = true;
-}
-
-void NuPlayer2::GenericSource2::disconnect() {
-    {
-        Mutex::Autolock _l(mLock);
-        mDisconnected = true;
-    }
-    if (mDataSourceWrapper != NULL) {
-        mDataSourceWrapper->close();
-    }
-}
-
-status_t NuPlayer2::GenericSource2::feedMoreTSData() {
-    return OK;
-}
-
-void NuPlayer2::GenericSource2::onMessageReceived(const sp<AMessage> &msg) {
-    Mutex::Autolock _l(mLock);
-    switch (msg->what()) {
-      case kWhatPrepareAsync:
-      {
-          int64_t startTimeUs;
-          CHECK(msg->findInt64("startTimeUs", &startTimeUs));
-          onPrepareAsync(startTimeUs);
-          break;
-      }
-      case kWhatFetchSubtitleData:
-      {
-          fetchTextData(kWhatSendSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
-                  mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
-          break;
-      }
-
-      case kWhatFetchTimedTextData:
-      {
-          fetchTextData(kWhatSendTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
-                  mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
-          break;
-      }
-
-      case kWhatSendSubtitleData:
-      {
-          sendTextData(kWhatSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
-                  mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
-          break;
-      }
-
-      case kWhatSendGlobalTimedTextData:
-      {
-          sendGlobalTextData(kWhatTimedTextData, mFetchTimedTextDataGeneration, msg);
-          break;
-      }
-      case kWhatSendTimedTextData:
-      {
-          sendTextData(kWhatTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
-                  mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
-          break;
-      }
-
-      case kWhatChangeAVSource:
-      {
-          int32_t trackIndex;
-          CHECK(msg->findInt32("trackIndex", &trackIndex));
-          const sp<AMediaExtractorWrapper> extractor = mExtractors.itemAt(trackIndex);
-
-          Track* track;
-          AString mime;
-          media_track_type trackType, counterpartType;
-          sp<AMediaFormatWrapper> format = extractor->getTrackFormat(trackIndex);
-          format->getString(AMEDIAFORMAT_KEY_MIME, &mime);
-          if (!strncasecmp(mime.c_str(), "audio/", 6)) {
-              track = &mAudioTrack;
-              trackType = MEDIA_TRACK_TYPE_AUDIO;
-              counterpartType = MEDIA_TRACK_TYPE_VIDEO;;
-          } else {
-              CHECK(!strncasecmp(mime.c_str(), "video/", 6));
-              track = &mVideoTrack;
-              trackType = MEDIA_TRACK_TYPE_VIDEO;
-              counterpartType = MEDIA_TRACK_TYPE_AUDIO;;
-          }
-
-
-          track->mExtractor = extractor;
-          track->mExtractor->selectSingleTrack(trackIndex);
-          track->mIndex = trackIndex;
-          ++mAudioDataGeneration;
-          ++mVideoDataGeneration;
-
-          int64_t timeUs, actualTimeUs;
-          const bool formatChange = true;
-          if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
-              timeUs = mAudioLastDequeueTimeUs;
-          } else {
-              timeUs = mVideoLastDequeueTimeUs;
-          }
-          readBuffer(trackType, timeUs, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */,
-                  &actualTimeUs, formatChange);
-          readBuffer(counterpartType, -1, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */,
-                  NULL, !formatChange);
-          ALOGV("timeUs %lld actualTimeUs %lld", (long long)timeUs, (long long)actualTimeUs);
-
-          break;
-      }
-
-      case kWhatSeek:
-      {
-          onSeek(msg);
-          break;
-      }
-
-      case kWhatReadBuffer:
-      {
-          onReadBuffer(msg);
-          break;
-      }
-
-      case kWhatPollBuffering:
-      {
-          int32_t generation;
-          CHECK(msg->findInt32("generation", &generation));
-          if (generation == mPollBufferingGeneration) {
-              onPollBuffering();
-          }
-          break;
-      }
-
-      default:
-          Source::onMessageReceived(msg);
-          break;
-    }
-}
-
-void NuPlayer2::GenericSource2::fetchTextData(
-        uint32_t sendWhat,
-        media_track_type type,
-        int32_t curGen,
-        const sp<AnotherPacketSource>& packets,
-        const sp<AMessage>& msg) {
-    int32_t msgGeneration;
-    CHECK(msg->findInt32("generation", &msgGeneration));
-    if (msgGeneration != curGen) {
-        // stale
-        return;
-    }
-
-    int32_t avail;
-    if (packets->hasBufferAvailable(&avail)) {
-        return;
-    }
-
-    int64_t timeUs;
-    CHECK(msg->findInt64("timeUs", &timeUs));
-
-    int64_t subTimeUs = 0;
-    readBuffer(type, timeUs, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */, &subTimeUs);
-
-    status_t eosResult;
-    if (!packets->hasBufferAvailable(&eosResult)) {
-        return;
-    }
-
-    if (msg->what() == kWhatFetchSubtitleData) {
-        subTimeUs -= 1000000ll;  // send subtile data one second earlier
-    }
-    sp<AMessage> msg2 = new AMessage(sendWhat, this);
-    msg2->setInt32("generation", msgGeneration);
-    mMediaClock->addTimer(msg2, subTimeUs);
-}
-
-void NuPlayer2::GenericSource2::sendTextData(
-        uint32_t what,
-        media_track_type type,
-        int32_t curGen,
-        const sp<AnotherPacketSource>& packets,
-        const sp<AMessage>& msg) {
-    int32_t msgGeneration;
-    CHECK(msg->findInt32("generation", &msgGeneration));
-    if (msgGeneration != curGen) {
-        // stale
-        return;
-    }
-
-    int64_t subTimeUs;
-    if (packets->nextBufferTime(&subTimeUs) != OK) {
-        return;
-    }
-
-    int64_t nextSubTimeUs;
-    readBuffer(type, -1, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */, &nextSubTimeUs);
-
-    sp<ABuffer> buffer;
-    status_t dequeueStatus = packets->dequeueAccessUnit(&buffer);
-    if (dequeueStatus == OK) {
-        sp<AMessage> notify = dupNotify();
-        notify->setInt32("what", what);
-        notify->setBuffer("buffer", buffer);
-        notify->post();
-
-        if (msg->what() == kWhatSendSubtitleData) {
-            nextSubTimeUs -= 1000000ll;  // send subtile data one second earlier
-        }
-        mMediaClock->addTimer(msg, nextSubTimeUs);
-    }
-}
-
-void NuPlayer2::GenericSource2::sendGlobalTextData(
-        uint32_t what,
-        int32_t curGen,
-        sp<AMessage> msg) {
-    int32_t msgGeneration;
-    CHECK(msg->findInt32("generation", &msgGeneration));
-    if (msgGeneration != curGen) {
-        // stale
-        return;
-    }
-
-    void *data = NULL;
-    size_t size = 0;
-    if (mTimedTextTrack.mExtractor->getTrackFormat(mTimedTextTrack.mIndex)->getBuffer(
-                    "text", &data, &size)) {
-        mGlobalTimedText = new ABuffer(size);
-        if (mGlobalTimedText->data()) {
-            memcpy(mGlobalTimedText->data(), data, size);
-            sp<AMessage> globalMeta = mGlobalTimedText->meta();
-            globalMeta->setInt64("timeUs", 0);
-            globalMeta->setString("mime", MEDIA_MIMETYPE_TEXT_3GPP);
-            globalMeta->setInt32("global", 1);
-            sp<AMessage> notify = dupNotify();
-            notify->setInt32("what", what);
-            notify->setBuffer("buffer", mGlobalTimedText);
-            notify->post();
-        }
-    }
-}
-
-sp<AMessage> NuPlayer2::GenericSource2::getFormat(bool audio) {
-    Mutex::Autolock _l(mLock);
-    return getFormat_l(audio);
-}
-
-sp<MetaData> NuPlayer2::GenericSource2::getFormatMeta(bool audio) {
-    Mutex::Autolock _l(mLock);
-    return getFormatMeta_l(audio);
-}
-
-sp<AMessage> NuPlayer2::GenericSource2::getFormat_l(bool audio) {
-    sp<AMediaExtractorWrapper> extractor = audio ? mAudioTrack.mExtractor : mVideoTrack.mExtractor;
-    size_t trackIndex = audio ? mAudioTrack.mIndex : mVideoTrack.mIndex;
-
-    if (extractor == NULL) {
-        return NULL;
-    }
-
-    return extractor->getTrackFormat(trackIndex)->toAMessage();
-}
-
-sp<MetaData> NuPlayer2::GenericSource2::getFormatMeta_l(bool audio) {
-    sp<AMediaExtractorWrapper> extractor = audio ? mAudioTrack.mExtractor : mVideoTrack.mExtractor;
-    size_t trackIndex = audio ? mAudioTrack.mIndex : mVideoTrack.mIndex;
-
-    if (extractor == NULL) {
-        return NULL;
-    }
-
-    return convertMediaFormatWrapperToMetaData(extractor->getTrackFormat(trackIndex));
-}
-
-status_t NuPlayer2::GenericSource2::dequeueAccessUnit(
-        bool audio, sp<ABuffer> *accessUnit) {
-    Mutex::Autolock _l(mLock);
-    // If has gone through stop/releaseDrm sequence, we no longer send down any buffer b/c
-    // the codec's crypto object has gone away (b/37960096).
-    // Note: This will be unnecessary when stop() changes behavior and releases codec (b/35248283).
-    if (!mStarted && mIsDrmReleased) {
-        return -EWOULDBLOCK;
-    }
-
-    Track *track = audio ? &mAudioTrack : &mVideoTrack;
-
-    if (track->mExtractor == NULL) {
-        return -EWOULDBLOCK;
-    }
-
-    status_t finalResult;
-    if (!track->mPackets->hasBufferAvailable(&finalResult)) {
-        if (finalResult == OK) {
-            postReadBuffer(
-                    audio ? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO);
-            return -EWOULDBLOCK;
-        }
-        return finalResult;
-    }
-
-    status_t result = track->mPackets->dequeueAccessUnit(accessUnit);
-
-    // start pulling in more buffers if cache is running low
-    // so that decoder has less chance of being starved
-    if (!mIsStreaming) {
-        if (track->mPackets->getAvailableBufferCount(&finalResult) < 2) {
-            postReadBuffer(audio? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO);
-        }
-    } else {
-        int64_t durationUs = track->mPackets->getBufferedDurationUs(&finalResult);
-        // TODO: maxRebufferingMarkMs could be larger than
-        // mBufferingSettings.mResumePlaybackMarkMs
-        int64_t restartBufferingMarkUs =
-             mBufferingSettings.mResumePlaybackMarkMs * 1000ll / 2;
-        if (finalResult == OK) {
-            if (durationUs < restartBufferingMarkUs) {
-                postReadBuffer(audio? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO);
-            }
-            if (track->mPackets->getAvailableBufferCount(&finalResult) < 2
-                && !mSentPauseOnBuffering && !mPreparing) {
-                mSentPauseOnBuffering = true;
-                sp<AMessage> notify = dupNotify();
-                notify->setInt32("what", kWhatPauseOnBufferingStart);
-                notify->post();
-            }
-        }
-    }
-
-    if (result != OK) {
-        if (mSubtitleTrack.mExtractor != NULL) {
-            mSubtitleTrack.mPackets->clear();
-            mFetchSubtitleDataGeneration++;
-        }
-        if (mTimedTextTrack.mExtractor != NULL) {
-            mTimedTextTrack.mPackets->clear();
-            mFetchTimedTextDataGeneration++;
-        }
-        return result;
-    }
-
-    int64_t timeUs;
-    status_t eosResult; // ignored
-    CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs));
-    if (audio) {
-        mAudioLastDequeueTimeUs = timeUs;
-    } else {
-        mVideoLastDequeueTimeUs = timeUs;
-    }
-
-    if (mSubtitleTrack.mExtractor != NULL
-            && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
-        sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, this);
-        msg->setInt64("timeUs", timeUs);
-        msg->setInt32("generation", mFetchSubtitleDataGeneration);
-        msg->post();
-    }
-
-    if (mTimedTextTrack.mExtractor != NULL
-            && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) {
-        sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, this);
-        msg->setInt64("timeUs", timeUs);
-        msg->setInt32("generation", mFetchTimedTextDataGeneration);
-        msg->post();
-    }
-
-    return result;
-}
-
-status_t NuPlayer2::GenericSource2::getDuration(int64_t *durationUs) {
-    Mutex::Autolock _l(mLock);
-    *durationUs = mDurationUs;
-    return OK;
-}
-
-size_t NuPlayer2::GenericSource2::getTrackCount() const {
-    Mutex::Autolock _l(mLock);
-    return mExtractors.size();
-}
-
-sp<AMessage> NuPlayer2::GenericSource2::getTrackInfo(size_t trackIndex) const {
-    Mutex::Autolock _l(mLock);
-    size_t trackCount = mExtractors.size();
-    if (trackIndex >= trackCount) {
-        return NULL;
-    }
-
-    sp<AMessage> format = mExtractors.itemAt(trackIndex)->getTrackFormat(trackIndex)->toAMessage();
-    if (format == NULL) {
-        ALOGE("no metadata for track %zu", trackIndex);
-        return NULL;
-    }
-
-    AString mime;
-    CHECK(format->findString(AMEDIAFORMAT_KEY_MIME, &mime));
-
-    int32_t trackType;
-    if (!strncasecmp(mime.c_str(), "video/", 6)) {
-        trackType = MEDIA_TRACK_TYPE_VIDEO;
-    } else if (!strncasecmp(mime.c_str(), "audio/", 6)) {
-        trackType = MEDIA_TRACK_TYPE_AUDIO;
-    } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP)) {
-        trackType = MEDIA_TRACK_TYPE_TIMEDTEXT;
-    } else {
-        trackType = MEDIA_TRACK_TYPE_UNKNOWN;
-    }
-    format->setInt32("type", trackType);
-
-    AString lang;
-    if (!format->findString("language", &lang)) {
-        format->setString("language", "und");
-    }
-
-    if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
-        int32_t isAutoselect = 1, isDefault = 0, isForced = 0;
-        format->findInt32(AMEDIAFORMAT_KEY_IS_AUTOSELECT, &isAutoselect);
-        format->findInt32(AMEDIAFORMAT_KEY_IS_DEFAULT, &isDefault);
-        format->findInt32(AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE, &isForced);
-
-        format->setInt32("auto", !!isAutoselect);
-        format->setInt32("default", !!isDefault);
-        format->setInt32("forced", !!isForced);
-    }
-
-    return format;
-}
-
-ssize_t NuPlayer2::GenericSource2::getSelectedTrack(media_track_type type) const {
-    Mutex::Autolock _l(mLock);
-    const Track *track = NULL;
-    switch (type) {
-    case MEDIA_TRACK_TYPE_VIDEO:
-        track = &mVideoTrack;
-        break;
-    case MEDIA_TRACK_TYPE_AUDIO:
-        track = &mAudioTrack;
-        break;
-    case MEDIA_TRACK_TYPE_TIMEDTEXT:
-        track = &mTimedTextTrack;
-        break;
-    case MEDIA_TRACK_TYPE_SUBTITLE:
-        track = &mSubtitleTrack;
-        break;
-    default:
-        break;
-    }
-
-    if (track != NULL && track->mExtractor != NULL) {
-        return track->mIndex;
-    }
-
-    return -1;
-}
-
-status_t NuPlayer2::GenericSource2::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
-    Mutex::Autolock _l(mLock);
-    ALOGV("%s track: %zu", select ? "select" : "deselect", trackIndex);
-
-    if (trackIndex >= mExtractors.size()) {
-        return BAD_INDEX;
-    }
-
-    if (!select) {
-        Track* track = NULL;
-        if (mSubtitleTrack.mExtractor != NULL && trackIndex == mSubtitleTrack.mIndex) {
-            track = &mSubtitleTrack;
-            mFetchSubtitleDataGeneration++;
-        } else if (mTimedTextTrack.mExtractor != NULL && trackIndex == mTimedTextTrack.mIndex) {
-            track = &mTimedTextTrack;
-            mFetchTimedTextDataGeneration++;
-        }
-        if (track == NULL) {
-            return INVALID_OPERATION;
-        }
-        track->mExtractor = NULL;
-        track->mPackets->clear();
-        return OK;
-    }
-
-    const sp<AMediaExtractorWrapper> extractor = mExtractors.itemAt(trackIndex);
-    sp<MetaData> meta = convertMediaFormatWrapperToMetaData(extractor->getTrackFormat(trackIndex));
-    const char *mime;
-    CHECK(meta->findCString(kKeyMIMEType, &mime));
-    if (!strncasecmp(mime, "text/", 5)) {
-        bool isSubtitle = strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP);
-        Track *track = isSubtitle ? &mSubtitleTrack : &mTimedTextTrack;
-        if (track->mExtractor != NULL && track->mIndex == trackIndex) {
-            return OK;
-        }
-        track->mIndex = trackIndex;
-        track->mExtractor = mExtractors.itemAt(trackIndex);
-        track->mExtractor->selectSingleTrack(trackIndex);
-        if (track->mPackets == NULL) {
-            track->mPackets = new AnotherPacketSource(meta);
-        } else {
-            track->mPackets->clear();
-            track->mPackets->setFormat(meta);
-
-        }
-
-        if (isSubtitle) {
-            mFetchSubtitleDataGeneration++;
-        } else {
-            mFetchTimedTextDataGeneration++;
-        }
-
-        status_t eosResult; // ignored
-        if (mSubtitleTrack.mExtractor != NULL
-                && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
-            sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, this);
-            msg->setInt64("timeUs", timeUs);
-            msg->setInt32("generation", mFetchSubtitleDataGeneration);
-            msg->post();
-        }
-
-        sp<AMessage> msg2 = new AMessage(kWhatSendGlobalTimedTextData, this);
-        msg2->setInt32("generation", mFetchTimedTextDataGeneration);
-        msg2->post();
-
-        if (mTimedTextTrack.mExtractor != NULL
-                && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) {
-            sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, this);
-            msg->setInt64("timeUs", timeUs);
-            msg->setInt32("generation", mFetchTimedTextDataGeneration);
-            msg->post();
-        }
-
-        return OK;
-    } else if (!strncasecmp(mime, "audio/", 6) || !strncasecmp(mime, "video/", 6)) {
-        bool audio = !strncasecmp(mime, "audio/", 6);
-        Track *track = audio ? &mAudioTrack : &mVideoTrack;
-        if (track->mExtractor != NULL && track->mIndex == trackIndex) {
-            return OK;
-        }
-
-        sp<AMessage> msg = new AMessage(kWhatChangeAVSource, this);
-        msg->setInt32("trackIndex", trackIndex);
-        msg->post();
-        return OK;
-    }
-
-    return INVALID_OPERATION;
-}
-
-status_t NuPlayer2::GenericSource2::seekTo(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
-    ALOGV("seekTo: %lld, %d", (long long)seekTimeUs, mode);
-    sp<AMessage> msg = new AMessage(kWhatSeek, this);
-    msg->setInt64("seekTimeUs", seekTimeUs);
-    msg->setInt32("mode", mode);
-
-    // Need to call readBuffer on |mLooper| to ensure the calls to
-    // IMediaSource::read* are serialized. Note that IMediaSource::read*
-    // is called without |mLock| acquired and MediaSource is not thread safe.
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-    }
-
-    return err;
-}
-
-void NuPlayer2::GenericSource2::onSeek(const sp<AMessage>& msg) {
-    int64_t seekTimeUs;
-    int32_t mode;
-    CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
-    CHECK(msg->findInt32("mode", &mode));
-
-    sp<AMessage> response = new AMessage;
-    status_t err = doSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
-    response->setInt32("err", err);
-
-    sp<AReplyToken> replyID;
-    CHECK(msg->senderAwaitsResponse(&replyID));
-    response->postReply(replyID);
-}
-
-status_t NuPlayer2::GenericSource2::doSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
-    if (mVideoTrack.mExtractor != NULL) {
-        ++mVideoDataGeneration;
-
-        int64_t actualTimeUs;
-        readBuffer(MEDIA_TRACK_TYPE_VIDEO, seekTimeUs, mode, &actualTimeUs);
-
-        if (mode != MediaPlayer2SeekMode::SEEK_CLOSEST) {
-            seekTimeUs = actualTimeUs;
-        }
-        mVideoLastDequeueTimeUs = actualTimeUs;
-    }
-
-    if (mAudioTrack.mExtractor != NULL) {
-        ++mAudioDataGeneration;
-        readBuffer(MEDIA_TRACK_TYPE_AUDIO, seekTimeUs, MediaPlayer2SeekMode::SEEK_CLOSEST);
-        mAudioLastDequeueTimeUs = seekTimeUs;
-    }
-
-    if (mSubtitleTrack.mExtractor != NULL) {
-        mSubtitleTrack.mPackets->clear();
-        mFetchSubtitleDataGeneration++;
-    }
-
-    if (mTimedTextTrack.mExtractor != NULL) {
-        mTimedTextTrack.mPackets->clear();
-        mFetchTimedTextDataGeneration++;
-    }
-
-    ++mPollBufferingGeneration;
-    schedulePollBuffering();
-    return OK;
-}
-
-sp<ABuffer> NuPlayer2::GenericSource2::mediaBufferToABuffer(
-        MediaBufferBase* mb,
-        media_track_type trackType) {
-    bool audio = trackType == MEDIA_TRACK_TYPE_AUDIO;
-    size_t outLength = mb->range_length();
-
-    if (audio && mAudioIsVorbis) {
-        outLength += sizeof(int32_t);
-    }
-
-    sp<ABuffer> ab;
-
-    if (mIsDrmProtected)   {
-        // Modular DRM
-        // Enabled for both video/audio so 1) media buffer is reused without extra copying
-        // 2) meta data can be retrieved in onInputBufferFetched for calling queueSecureInputBuffer.
-
-        // data is already provided in the buffer
-        ab = new ABuffer(NULL, mb->range_length());
-        ab->meta()->setObject("mediaBufferHolder", new MediaBufferHolder(mb));
-
-        // Modular DRM: Required b/c of the above add_ref.
-        // If ref>0, there must be an observer, or it'll crash at release().
-        // TODO: MediaBuffer might need to be revised to ease such need.
-        mb->setObserver(this);
-        // setMediaBufferBase() interestingly doesn't increment the ref count on its own.
-        // Extra increment (since we want to keep mb alive and attached to ab beyond this function
-        // call. This is to counter the effect of mb->release() towards the end.
-        mb->add_ref();
-
-    } else {
-        ab = new ABuffer(outLength);
-        memcpy(ab->data(),
-               (const uint8_t *)mb->data() + mb->range_offset(),
-               mb->range_length());
-    }
-
-    if (audio && mAudioIsVorbis) {
-        int32_t numPageSamples;
-        if (!mb->meta_data().findInt32(kKeyValidSamples, &numPageSamples)) {
-            numPageSamples = -1;
-        }
-
-        uint8_t* abEnd = ab->data() + mb->range_length();
-        memcpy(abEnd, &numPageSamples, sizeof(numPageSamples));
-    }
-
-    sp<AMessage> meta = ab->meta();
-
-    int64_t timeUs;
-    CHECK(mb->meta_data().findInt64(kKeyTime, &timeUs));
-    meta->setInt64("timeUs", timeUs);
-
-    if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
-        int32_t layerId;
-        if (mb->meta_data().findInt32(kKeyTemporalLayerId, &layerId)) {
-            meta->setInt32("temporal-layer-id", layerId);
-        }
-    }
-
-    if (trackType == MEDIA_TRACK_TYPE_TIMEDTEXT) {
-        AString mime;
-        sp<AMediaExtractorWrapper> extractor = mTimedTextTrack.mExtractor;
-        size_t trackIndex = mTimedTextTrack.mIndex;
-        CHECK(extractor != NULL
-                && extractor->getTrackFormat(trackIndex)->getString(AMEDIAFORMAT_KEY_MIME, &mime));
-        meta->setString("mime", mime.c_str());
-    }
-
-    int64_t durationUs;
-    if (mb->meta_data().findInt64(kKeyDuration, &durationUs)) {
-        meta->setInt64("durationUs", durationUs);
-    }
-
-    if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
-        meta->setInt32(AMEDIAFORMAT_KEY_TRACK_INDEX, mSubtitleTrack.mIndex);
-    }
-
-    uint32_t dataType; // unused
-    const void *seiData;
-    size_t seiLength;
-    if (mb->meta_data().findData(kKeySEI, &dataType, &seiData, &seiLength)) {
-        sp<ABuffer> sei = ABuffer::CreateAsCopy(seiData, seiLength);;
-        meta->setBuffer("sei", sei);
-    }
-
-    const void *mpegUserDataPointer;
-    size_t mpegUserDataLength;
-    if (mb->meta_data().findData(
-            kKeyMpegUserData, &dataType, &mpegUserDataPointer, &mpegUserDataLength)) {
-        sp<ABuffer> mpegUserData = ABuffer::CreateAsCopy(mpegUserDataPointer, mpegUserDataLength);
-        meta->setBuffer(AMEDIAFORMAT_KEY_MPEG_USER_DATA, mpegUserData);
-    }
-
-    mb->release();
-    mb = NULL;
-
-    return ab;
-}
-
-int32_t NuPlayer2::GenericSource2::getDataGeneration(media_track_type type) const {
-    int32_t generation = -1;
-    switch (type) {
-    case MEDIA_TRACK_TYPE_VIDEO:
-        generation = mVideoDataGeneration;
-        break;
-    case MEDIA_TRACK_TYPE_AUDIO:
-        generation = mAudioDataGeneration;
-        break;
-    case MEDIA_TRACK_TYPE_TIMEDTEXT:
-        generation = mFetchTimedTextDataGeneration;
-        break;
-    case MEDIA_TRACK_TYPE_SUBTITLE:
-        generation = mFetchSubtitleDataGeneration;
-        break;
-    default:
-        break;
-    }
-
-    return generation;
-}
-
-void NuPlayer2::GenericSource2::postReadBuffer(media_track_type trackType) {
-    if ((mPendingReadBufferTypes & (1 << trackType)) == 0) {
-        mPendingReadBufferTypes |= (1 << trackType);
-        sp<AMessage> msg = new AMessage(kWhatReadBuffer, this);
-        msg->setInt32("trackType", trackType);
-        msg->post();
-    }
-}
-
-void NuPlayer2::GenericSource2::onReadBuffer(const sp<AMessage>& msg) {
-    int32_t tmpType;
-    CHECK(msg->findInt32("trackType", &tmpType));
-    media_track_type trackType = (media_track_type)tmpType;
-    mPendingReadBufferTypes &= ~(1 << trackType);
-    readBuffer(trackType);
-}
-
-void NuPlayer2::GenericSource2::readBuffer(
-        media_track_type trackType, int64_t seekTimeUs, MediaPlayer2SeekMode mode,
-        int64_t *actualTimeUs, bool formatChange) {
-    Track *track;
-    size_t maxBuffers = 1;
-    switch (trackType) {
-        case MEDIA_TRACK_TYPE_VIDEO:
-            track = &mVideoTrack;
-            maxBuffers = 8;  // too large of a number may influence seeks
-            break;
-        case MEDIA_TRACK_TYPE_AUDIO:
-            track = &mAudioTrack;
-            maxBuffers = 64;
-            break;
-        case MEDIA_TRACK_TYPE_SUBTITLE:
-            track = &mSubtitleTrack;
-            break;
-        case MEDIA_TRACK_TYPE_TIMEDTEXT:
-            track = &mTimedTextTrack;
-            break;
-        default:
-            TRESPASS();
-    }
-
-    if (track->mExtractor == NULL) {
-        return;
-    }
-
-    if (actualTimeUs) {
-        *actualTimeUs = seekTimeUs;
-    }
-
-
-    bool seeking = false;
-    sp<AMediaExtractorWrapper> extractor = track->mExtractor;
-    if (seekTimeUs >= 0) {
-        extractor->seekTo(seekTimeUs, mode);
-        seeking = true;
-    }
-
-    int32_t generation = getDataGeneration(trackType);
-    for (size_t numBuffers = 0; numBuffers < maxBuffers; ) {
-        Vector<sp<ABuffer> > aBuffers;
-
-        mLock.unlock();
-
-        sp<AMediaFormatWrapper> format;
-        ssize_t sampleSize = -1;
-        status_t err = extractor->getSampleFormat(format);
-        if (err == OK) {
-            sampleSize = extractor->getSampleSize();
-        }
-
-        if (err != OK || sampleSize < 0) {
-            mLock.lock();
-            track->mPackets->signalEOS(err != OK ? err : ERROR_END_OF_STREAM);
-            break;
-        }
-
-        sp<ABuffer> abuf = new ABuffer(sampleSize);
-        sampleSize = extractor->readSampleData(abuf);
-        mLock.lock();
-
-        // in case track has been changed since we don't have lock for some time.
-        if (generation != getDataGeneration(trackType)) {
-            break;
-        }
-
-        int64_t timeUs = extractor->getSampleTime();
-        if (timeUs < 0) {
-            track->mPackets->signalEOS(ERROR_MALFORMED);
-            break;
-        }
-
-        sp<AMessage> meta = abuf->meta();
-        format->writeToAMessage(meta);
-        meta->setInt64("timeUs", timeUs);
-        if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
-            mAudioTimeUs = timeUs;
-        } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
-            mVideoTimeUs = timeUs;
-        }
-
-        sp<AMediaCodecCryptoInfoWrapper> cryptInfo = extractor->getSampleCryptoInfo();
-        if (cryptInfo != NULL) {
-            meta->setObject("cryptInfo", cryptInfo);
-        }
-
-        queueDiscontinuityIfNeeded(seeking, formatChange, trackType, track);
-
-        if (numBuffers == 0 && actualTimeUs != nullptr) {
-            *actualTimeUs = timeUs;
-        }
-        if (seeking) {
-            if (meta != nullptr && mode == MediaPlayer2SeekMode::SEEK_CLOSEST
-                    && seekTimeUs > timeUs) {
-                sp<AMessage> extra = new AMessage;
-                extra->setInt64("resume-at-mediaTimeUs", seekTimeUs);
-                meta->setMessage("extra", extra);
-            }
-        }
-
-        track->mPackets->queueAccessUnit(abuf);
-        formatChange = false;
-        seeking = false;
-        ++numBuffers;
-        extractor->advance();
-
-    }
-
-    if (mIsStreaming
-        && (trackType == MEDIA_TRACK_TYPE_VIDEO || trackType == MEDIA_TRACK_TYPE_AUDIO)) {
-        status_t finalResult;
-        int64_t durationUs = track->mPackets->getBufferedDurationUs(&finalResult);
-
-        // TODO: maxRebufferingMarkMs could be larger than
-        // mBufferingSettings.mResumePlaybackMarkMs
-        int64_t markUs = (mPreparing ? mBufferingSettings.mInitialMarkMs
-            : mBufferingSettings.mResumePlaybackMarkMs) * 1000ll;
-        if (finalResult == ERROR_END_OF_STREAM || durationUs >= markUs) {
-            if (mPreparing || mSentPauseOnBuffering) {
-                Track *counterTrack =
-                    (trackType == MEDIA_TRACK_TYPE_VIDEO ? &mAudioTrack : &mVideoTrack);
-                if (counterTrack->mExtractor != NULL) {
-                    durationUs = counterTrack->mPackets->getBufferedDurationUs(&finalResult);
-                }
-                if (finalResult == ERROR_END_OF_STREAM || durationUs >= markUs) {
-                    if (mPreparing) {
-                        notifyPrepared();
-                        mPreparing = false;
-                    } else {
-                        mSentPauseOnBuffering = false;
-                        sp<AMessage> notify = dupNotify();
-                        notify->setInt32("what", kWhatResumeOnBufferingEnd);
-                        notify->post();
-                    }
-                }
-            }
-            return;
-        }
-
-        postReadBuffer(trackType);
-    }
-}
-
-void NuPlayer2::GenericSource2::queueDiscontinuityIfNeeded(
-        bool seeking, bool formatChange, media_track_type trackType, Track *track) {
-    // formatChange && seeking: track whose source is changed during selection
-    // formatChange && !seeking: track whose source is not changed during selection
-    // !formatChange: normal seek
-    if ((seeking || formatChange)
-            && (trackType == MEDIA_TRACK_TYPE_AUDIO
-            || trackType == MEDIA_TRACK_TYPE_VIDEO)) {
-        ATSParser::DiscontinuityType type = (formatChange && seeking)
-                ? ATSParser::DISCONTINUITY_FORMATCHANGE
-                : ATSParser::DISCONTINUITY_NONE;
-        track->mPackets->queueDiscontinuity(type, NULL /* extra */, true /* discard */);
-    }
-}
-
-void NuPlayer2::GenericSource2::notifyBufferingUpdate(int32_t percentage) {
-    // Buffering percent could go backward as it's estimated from remaining
-    // data and last access time. This could cause the buffering position
-    // drawn on media control to jitter slightly. Remember previously reported
-    // percentage and don't allow it to go backward.
-    if (percentage < mPrevBufferPercentage) {
-        percentage = mPrevBufferPercentage;
-    } else if (percentage > 100) {
-        percentage = 100;
-    }
-
-    mPrevBufferPercentage = percentage;
-
-    ALOGV("notifyBufferingUpdate: buffering %d%%", percentage);
-
-    sp<AMessage> notify = dupNotify();
-    notify->setInt32("what", kWhatBufferingUpdate);
-    notify->setInt32("percentage", percentage);
-    notify->post();
-}
-
-void NuPlayer2::GenericSource2::schedulePollBuffering() {
-    if (mIsStreaming) {
-        sp<AMessage> msg = new AMessage(kWhatPollBuffering, this);
-        msg->setInt32("generation", mPollBufferingGeneration);
-        // Enquires buffering status every second.
-        msg->post(1000000ll);
-    }
-}
-
-void NuPlayer2::GenericSource2::onPollBuffering() {
-    int64_t cachedDurationUs = -1ll;
-
-    sp<AMediaExtractorWrapper> extractor;
-    if (mVideoTrack.mExtractor != NULL) {
-        extractor = mVideoTrack.mExtractor;
-    } else if (mAudioTrack.mExtractor != NULL) {
-        extractor = mAudioTrack.mExtractor;
-    }
-
-    if (extractor != NULL) {
-        cachedDurationUs = extractor->getCachedDuration();
-    }
-
-    if (cachedDurationUs >= 0ll) {
-        ssize_t sampleSize = extractor->getSampleSize();
-        if (sampleSize >= 0ll) {
-            int64_t cachedPosUs = getLastReadPosition() + cachedDurationUs;
-            int percentage = 100.0 * cachedPosUs / mDurationUs;
-            if (percentage > 100) {
-                percentage = 100;
-            }
-
-            notifyBufferingUpdate(percentage);
-            ALOGV("onPollBuffering: cachedDurationUs %.1f sec", cachedDurationUs / 1000000.0f);
-        } else {
-            notifyBufferingUpdate(100);
-            ALOGV("onPollBuffering: EOS");
-        }
-    }
-
-    schedulePollBuffering();
-}
-
-// Modular DRM
-status_t NuPlayer2::GenericSource2::prepareDrm(
-        const uint8_t uuid[16],
-        const Vector<uint8_t> &drmSessionId,
-        sp<AMediaCryptoWrapper> *outCrypto) {
-    Mutex::Autolock _l(mLock);
-    ALOGV("prepareDrm");
-
-    mIsDrmProtected = false;
-    mIsDrmReleased = false;
-    mIsSecure = false;
-
-    status_t status = OK;
-    sp<AMediaCryptoWrapper> crypto =
-        new AMediaCryptoWrapper(uuid, drmSessionId.array(), drmSessionId.size());
-    if (crypto == NULL) {
-        ALOGE("prepareDrm: failed to create crypto.");
-        return UNKNOWN_ERROR;
-    }
-    ALOGV("prepareDrm: crypto created for uuid: %s",
-            DrmUUID::toHexString(uuid).string());
-
-    *outCrypto = crypto;
-    // as long a there is an active crypto
-    mIsDrmProtected = true;
-
-    if (mMimes.size() == 0) {
-        status = UNKNOWN_ERROR;
-        ALOGE("prepareDrm: Unexpected. Must have at least one track. status: %d", status);
-        return status;
-    }
-
-    // first mime in this list is either the video track, or the first audio track
-    const char *mime = mMimes[0].string();
-    mIsSecure = crypto->requiresSecureDecoderComponent(mime);
-    ALOGV("prepareDrm: requiresSecureDecoderComponent mime: %s  isSecure: %d",
-            mime, mIsSecure);
-
-    // Checking the member flags while in the looper to send out the notification.
-    // The legacy mDecryptHandle!=NULL check (for FLAG_PROTECTED) is equivalent to mIsDrmProtected.
-    notifyFlagsChanged(
-            (mIsSecure ? FLAG_SECURE : 0) |
-            // Setting "protected screen" only for L1: b/38390836
-            (mIsSecure ? FLAG_PROTECTED : 0) |
-            FLAG_CAN_PAUSE |
-            FLAG_CAN_SEEK_BACKWARD |
-            FLAG_CAN_SEEK_FORWARD |
-            FLAG_CAN_SEEK);
-
-    if (status == OK) {
-        ALOGV("prepareDrm: mCrypto: %p", outCrypto->get());
-        ALOGD("prepareDrm ret: %d ", status);
-    } else {
-        ALOGE("prepareDrm err: %d", status);
-    }
-    return status;
-}
-
-status_t NuPlayer2::GenericSource2::releaseDrm() {
-    Mutex::Autolock _l(mLock);
-    ALOGV("releaseDrm");
-
-    if (mIsDrmProtected) {
-        mIsDrmProtected = false;
-        // to prevent returning any more buffer after stop/releaseDrm (b/37960096)
-        mIsDrmReleased = true;
-        ALOGV("releaseDrm: mIsDrmProtected is reset.");
-    } else {
-        ALOGE("releaseDrm: mIsDrmProtected is already false.");
-    }
-
-    return OK;
-}
-
-status_t NuPlayer2::GenericSource2::checkDrmInfo()
-{
-    // clearing the flag at prepare in case the player is reused after stop/releaseDrm with the
-    // same source without being reset (called by prepareAsync/initFromDataSource)
-    mIsDrmReleased = false;
-
-    if (mExtractor == NULL) {
-        ALOGV("checkDrmInfo: No extractor");
-        return OK; // letting the caller responds accordingly
-    }
-
-    PsshInfo *psshInfo = mExtractor->getPsshInfo();
-    if (psshInfo == NULL) {
-        ALOGV("checkDrmInfo: No PSSH");
-        return OK; // source without DRM info
-    }
-
-    PlayerMessage playerMsg;
-    status_t ret = NuPlayer2Drm::retrieveDrmInfo(psshInfo, &playerMsg);
-    ALOGV("checkDrmInfo: MEDIA_DRM_INFO PSSH drm info size: %d", (int)playerMsg.ByteSize());
-
-    if (ret != OK) {
-        ALOGE("checkDrmInfo: failed to retrive DrmInfo %d", ret);
-        return UNKNOWN_ERROR;
-    }
-
-    int size = playerMsg.ByteSize();
-    sp<ABuffer> drmInfoBuf = new ABuffer(size);
-    playerMsg.SerializeToArray(drmInfoBuf->data(), size);
-    drmInfoBuf->setRange(0, size);
-    notifyDrmInfo(drmInfoBuf);
-
-    return OK;
-}
-
-void NuPlayer2::GenericSource2::signalBufferReturned(MediaBufferBase *buffer)
-{
-    //ALOGV("signalBufferReturned %p  refCount: %d", buffer, buffer->localRefcount());
-
-    buffer->setObserver(NULL);
-    buffer->release(); // this leads to delete since that there is no observor
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/GenericSource2.h b/media/libmediaplayer2/nuplayer2/GenericSource2.h
deleted file mode 100644
index ade1aa3..0000000
--- a/media/libmediaplayer2/nuplayer2/GenericSource2.h
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-#ifndef GENERIC_SOURCE2_H_
-
-#define GENERIC_SOURCE2_H_
-
-#include "NuPlayer2.h"
-#include "NuPlayer2Source.h"
-
-#include "ATSParser.h"
-
-#include <media/stagefright/MediaBuffer.h>
-#include <mediaplayer2/mediaplayer2.h>
-#include <media/NdkMediaDataSource.h>
-#include <media/NdkMediaExtractor.h>
-#include <media/NdkWrapper.h>
-
-namespace android {
-
-class DecryptHandle;
-struct AnotherPacketSource;
-struct ARTSPController;
-class DataSource;
-class IDataSource;
-class IMediaSource;
-struct MediaSource;
-class MediaBuffer;
-struct MediaClock;
-
-struct NuPlayer2::GenericSource2 : public NuPlayer2::Source,
-                                   public MediaBufferObserver // Modular DRM
-{
-    GenericSource2(const sp<AMessage> &notify, uid_t uid,
-                   const sp<MediaClock> &mediaClock);
-
-    status_t setDataSource(
-            const char *url,
-            const KeyedVector<String8, String8> *headers);
-
-    status_t setDataSource(int fd, int64_t offset, int64_t length);
-
-    status_t setDataSource(const sp<DataSource>& dataSource);
-
-    virtual status_t getBufferingSettings(
-            BufferingSettings* buffering /* nonnull */) override;
-    virtual status_t setBufferingSettings(const BufferingSettings& buffering) override;
-
-    virtual void prepareAsync(int64_t startTimeUs);
-
-    virtual void start();
-    virtual void stop();
-    virtual void pause();
-    virtual void resume();
-
-    virtual void disconnect();
-
-    virtual status_t feedMoreTSData();
-
-    virtual sp<MetaData> getFileFormatMeta() const;
-
-    virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);
-
-    virtual status_t getDuration(int64_t *durationUs);
-    virtual size_t getTrackCount() const;
-    virtual sp<AMessage> getTrackInfo(size_t trackIndex) const;
-    virtual ssize_t getSelectedTrack(media_track_type type) const;
-    virtual status_t selectTrack(size_t trackIndex, bool select, int64_t timeUs);
-    virtual status_t seekTo(
-        int64_t seekTimeUs,
-        MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC) override;
-
-    virtual bool isStreaming() const;
-
-    // Modular DRM
-    virtual void signalBufferReturned(MediaBufferBase *buffer);
-
-    virtual status_t prepareDrm(
-            const uint8_t uuid[16],
-            const Vector<uint8_t> &drmSessionId,
-            sp<AMediaCryptoWrapper> *outCrypto);
-
-    virtual status_t releaseDrm();
-
-
-protected:
-    virtual ~GenericSource2();
-
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-    virtual sp<AMessage> getFormat(bool audio);
-    virtual sp<MetaData> getFormatMeta(bool audio);
-
-private:
-    enum {
-        kWhatPrepareAsync,
-        kWhatFetchSubtitleData,
-        kWhatFetchTimedTextData,
-        kWhatSendSubtitleData,
-        kWhatSendGlobalTimedTextData,
-        kWhatSendTimedTextData,
-        kWhatChangeAVSource,
-        kWhatPollBuffering,
-        kWhatSeek,
-        kWhatReadBuffer,
-        kWhatStart,
-        kWhatResume,
-        kWhatSecureDecodersInstantiated,
-    };
-
-    struct Track {
-        size_t mIndex;
-        sp<AMediaExtractorWrapper> mExtractor;
-        sp<AnotherPacketSource> mPackets;
-    };
-
-    int64_t mAudioTimeUs;
-    int64_t mAudioLastDequeueTimeUs;
-    int64_t mVideoTimeUs;
-    int64_t mVideoLastDequeueTimeUs;
-
-    BufferingSettings mBufferingSettings;
-    int32_t mPrevBufferPercentage;
-    int32_t mPollBufferingGeneration;
-    bool mSentPauseOnBuffering;
-
-    int32_t mAudioDataGeneration;
-    int32_t mVideoDataGeneration;
-    int32_t mFetchSubtitleDataGeneration;
-    int32_t mFetchTimedTextDataGeneration;
-    int64_t mDurationUs;
-    bool mAudioIsVorbis;
-    // Secure codec is required.
-    bool mIsSecure;
-    bool mIsStreaming;
-    uid_t mUID;
-    const sp<MediaClock> mMediaClock;
-    AString mUri;
-    KeyedVector<String8, String8> mUriHeaders;
-    int mFd;
-    int64_t mOffset;
-    int64_t mLength;
-
-    bool mDisconnected;
-    sp<MetaData> mFileMeta;
-    sp<AMediaDataSourceWrapper> mDataSourceWrapper;
-    sp<AMediaExtractorWrapper> mExtractor;
-    Vector<sp<AMediaExtractorWrapper> > mExtractors;
-    bool mStarted;
-    bool mPreparing;
-    int64_t mBitrate;
-    uint32_t mPendingReadBufferTypes;
-    sp<ABuffer> mGlobalTimedText;
-
-    Track mVideoTrack;
-    Track mAudioTrack;
-    Track mSubtitleTrack;
-    Track mTimedTextTrack;
-
-    mutable Mutex mLock;
-
-    sp<ALooper> mLooper;
-
-    void resetDataSource();
-
-    status_t initFromDataSource();
-    int64_t getLastReadPosition();
-
-    void notifyPreparedAndCleanup(status_t err);
-    void onSecureDecodersInstantiated(status_t err);
-    void finishPrepareAsync();
-    status_t startSources();
-
-    void onSeek(const sp<AMessage>& msg);
-    status_t doSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode);
-
-    void onPrepareAsync(int64_t startTimeUs);
-
-    void fetchTextData(
-            uint32_t what, media_track_type type,
-            int32_t curGen, const sp<AnotherPacketSource>& packets, const sp<AMessage>& msg);
-
-    void sendGlobalTextData(
-            uint32_t what,
-            int32_t curGen, sp<AMessage> msg);
-
-    void sendTextData(
-            uint32_t what, media_track_type type,
-            int32_t curGen, const sp<AnotherPacketSource>& packets, const sp<AMessage>& msg);
-
-    sp<ABuffer> mediaBufferToABuffer(
-            MediaBufferBase *mbuf,
-            media_track_type trackType);
-
-    void postReadBuffer(media_track_type trackType);
-    void onReadBuffer(const sp<AMessage>& msg);
-    // When |mode| is MediaPlayer2SeekMode::SEEK_CLOSEST, the buffer read shall
-    // include an item indicating skipping rendering all buffers with timestamp
-    // earlier than |seekTimeUs|.
-    // For other modes, the buffer read will not include the item as above in order
-    // to facilitate fast seek operation.
-    void readBuffer(
-            media_track_type trackType,
-            int64_t seekTimeUs = -1ll,
-            MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC,
-            int64_t *actualTimeUs = NULL, bool formatChange = false);
-
-    void queueDiscontinuityIfNeeded(
-            bool seeking, bool formatChange, media_track_type trackType, Track *track);
-
-    void schedulePollBuffering();
-    void onPollBuffering();
-    void notifyBufferingUpdate(int32_t percentage);
-
-    sp<AMessage> getFormat_l(bool audio);
-    sp<MetaData> getFormatMeta_l(bool audio);
-    int32_t getDataGeneration(media_track_type type) const;
-
-    // Modular DRM
-    // The source is DRM protected and is prepared for DRM.
-    bool mIsDrmProtected;
-    // releaseDrm has been processed.
-    bool mIsDrmReleased;
-    Vector<String8> mMimes;
-
-    status_t checkDrmInfo();
-
-    DISALLOW_EVIL_CONSTRUCTORS(GenericSource2);
-};
-
-}  // namespace android
-
-#endif  // GENERIC_SOURCE2_H_
diff --git a/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.cpp b/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.cpp
deleted file mode 100644
index e53900b..0000000
--- a/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.cpp
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * Copyright 2017 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 "HTTPLiveSource2"
-#include <utils/Log.h>
-
-#include "HTTPLiveSource2.h"
-
-#include "AnotherPacketSource.h"
-#include "LiveDataSource.h"
-
-#include <media/MediaHTTPService.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/Utils.h>
-
-// default buffer prepare/ready/underflow marks
-static const int kReadyMarkMs     = 5000;  // 5 seconds
-static const int kPrepareMarkMs   = 1500;  // 1.5 seconds
-
-namespace android {
-
-NuPlayer2::HTTPLiveSource2::HTTPLiveSource2(
-        const sp<AMessage> &notify,
-        const sp<MediaHTTPService> &httpService,
-        const char *url,
-        const KeyedVector<String8, String8> *headers)
-    : Source(notify),
-      mHTTPService(httpService),
-      mURL(url),
-      mFlags(0),
-      mFinalResult(OK),
-      mOffset(0),
-      mFetchSubtitleDataGeneration(0),
-      mFetchMetaDataGeneration(0),
-      mHasMetadata(false),
-      mMetadataSelected(false) {
-    mBufferingSettings.mInitialMarkMs = kPrepareMarkMs;
-    mBufferingSettings.mResumePlaybackMarkMs = kReadyMarkMs;
-    if (headers) {
-        mExtraHeaders = *headers;
-
-        ssize_t index =
-            mExtraHeaders.indexOfKey(String8("x-hide-urls-from-log"));
-
-        if (index >= 0) {
-            mFlags |= kFlagIncognito;
-
-            mExtraHeaders.removeItemsAt(index);
-        }
-    }
-}
-
-NuPlayer2::HTTPLiveSource2::~HTTPLiveSource2() {
-    if (mLiveSession != NULL) {
-        mLiveSession->disconnect();
-
-        mLiveLooper->unregisterHandler(mLiveSession->id());
-        mLiveLooper->unregisterHandler(id());
-        mLiveLooper->stop();
-
-        mLiveSession.clear();
-        mLiveLooper.clear();
-    }
-}
-
-status_t NuPlayer2::HTTPLiveSource2::getBufferingSettings(
-            BufferingSettings* buffering /* nonnull */) {
-    *buffering = mBufferingSettings;
-
-    return OK;
-}
-
-status_t NuPlayer2::HTTPLiveSource2::setBufferingSettings(const BufferingSettings& buffering) {
-    mBufferingSettings = buffering;
-
-    if (mLiveSession != NULL) {
-        mLiveSession->setBufferingSettings(mBufferingSettings);
-    }
-
-    return OK;
-}
-
-// TODO: fetch data starting from |startTimeUs|
-void NuPlayer2::HTTPLiveSource2::prepareAsync(int64_t /* startTimeUs */) {
-    if (mLiveLooper == NULL) {
-        mLiveLooper = new ALooper;
-        mLiveLooper->setName("http live2");
-        mLiveLooper->start(false, /* runOnCallingThread */
-                           true /* canCallJava */);
-
-        mLiveLooper->registerHandler(this);
-    }
-
-    sp<AMessage> notify = new AMessage(kWhatSessionNotify, this);
-
-    mLiveSession = new LiveSession(
-            notify,
-            (mFlags & kFlagIncognito) ? LiveSession::kFlagIncognito : 0,
-            mHTTPService);
-
-    mLiveLooper->registerHandler(mLiveSession);
-
-    mLiveSession->setBufferingSettings(mBufferingSettings);
-    mLiveSession->connectAsync(
-            mURL.c_str(), mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders);
-}
-
-void NuPlayer2::HTTPLiveSource2::start() {
-}
-
-sp<MetaData> NuPlayer2::HTTPLiveSource2::getFormatMeta(bool audio) {
-    sp<MetaData> meta;
-    if (mLiveSession != NULL) {
-        mLiveSession->getStreamFormatMeta(
-                audio ? LiveSession::STREAMTYPE_AUDIO
-                      : LiveSession::STREAMTYPE_VIDEO,
-                &meta);
-    }
-
-    return meta;
-}
-
-sp<AMessage> NuPlayer2::HTTPLiveSource2::getFormat(bool audio) {
-    sp<MetaData> meta;
-    status_t err = -EWOULDBLOCK;
-    if (mLiveSession != NULL) {
-        err = mLiveSession->getStreamFormatMeta(
-                audio ? LiveSession::STREAMTYPE_AUDIO
-                      : LiveSession::STREAMTYPE_VIDEO,
-                &meta);
-    }
-
-    sp<AMessage> format;
-    if (err == -EWOULDBLOCK) {
-        format = new AMessage();
-        format->setInt32("err", err);
-        return format;
-    }
-
-    if (err != OK || convertMetaDataToMessage(meta, &format) != OK) {
-        return NULL;
-    }
-    return format;
-}
-
-status_t NuPlayer2::HTTPLiveSource2::feedMoreTSData() {
-    return OK;
-}
-
-status_t NuPlayer2::HTTPLiveSource2::dequeueAccessUnit(
-        bool audio, sp<ABuffer> *accessUnit) {
-    return mLiveSession->dequeueAccessUnit(
-            audio ? LiveSession::STREAMTYPE_AUDIO
-                  : LiveSession::STREAMTYPE_VIDEO,
-            accessUnit);
-}
-
-status_t NuPlayer2::HTTPLiveSource2::getDuration(int64_t *durationUs) {
-    return mLiveSession->getDuration(durationUs);
-}
-
-size_t NuPlayer2::HTTPLiveSource2::getTrackCount() const {
-    return mLiveSession->getTrackCount();
-}
-
-sp<AMessage> NuPlayer2::HTTPLiveSource2::getTrackInfo(size_t trackIndex) const {
-    return mLiveSession->getTrackInfo(trackIndex);
-}
-
-ssize_t NuPlayer2::HTTPLiveSource2::getSelectedTrack(media_track_type type) const {
-    if (mLiveSession == NULL) {
-        return -1;
-    } else if (type == MEDIA_TRACK_TYPE_METADATA) {
-        // MEDIA_TRACK_TYPE_METADATA is always last track
-        // mMetadataSelected can only be true when mHasMetadata is true
-        return mMetadataSelected ? (mLiveSession->getTrackCount() - 1) : -1;
-    } else {
-        return mLiveSession->getSelectedTrack(type);
-    }
-}
-
-status_t NuPlayer2::HTTPLiveSource2::selectTrack(size_t trackIndex, bool select, int64_t /*timeUs*/) {
-    if (mLiveSession == NULL) {
-        return INVALID_OPERATION;
-    }
-
-    status_t err = INVALID_OPERATION;
-    bool postFetchMsg = false, isSub = false;
-    if (!mHasMetadata || trackIndex != mLiveSession->getTrackCount() - 1) {
-        err = mLiveSession->selectTrack(trackIndex, select);
-        postFetchMsg = select;
-        isSub = true;
-    } else {
-        // metadata track; i.e. (mHasMetadata && trackIndex == mLiveSession->getTrackCount() - 1)
-        if (mMetadataSelected && !select) {
-            err = OK;
-        } else if (!mMetadataSelected && select) {
-            postFetchMsg = true;
-            err = OK;
-        } else {
-            err = BAD_VALUE; // behave as LiveSession::selectTrack
-        }
-
-        mMetadataSelected = select;
-    }
-
-    if (err == OK) {
-        int32_t &generation = isSub ? mFetchSubtitleDataGeneration : mFetchMetaDataGeneration;
-        generation++;
-        if (postFetchMsg) {
-            int32_t what = isSub ? kWhatFetchSubtitleData : kWhatFetchMetaData;
-            sp<AMessage> msg = new AMessage(what, this);
-            msg->setInt32("generation", generation);
-            msg->post();
-        }
-    }
-
-    // LiveSession::selectTrack returns BAD_VALUE when selecting the currently
-    // selected track, or unselecting a non-selected track. In this case it's an
-    // no-op so we return OK.
-    return (err == OK || err == BAD_VALUE) ? (status_t)OK : err;
-}
-
-status_t NuPlayer2::HTTPLiveSource2::seekTo(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
-    if (mLiveSession->isSeekable()) {
-        return mLiveSession->seekTo(seekTimeUs, mode);
-    } else {
-        return INVALID_OPERATION;
-    }
-}
-
-void NuPlayer2::HTTPLiveSource2::pollForRawData(
-        const sp<AMessage> &msg, int32_t currentGeneration,
-        LiveSession::StreamType fetchType, int32_t pushWhat) {
-
-    int32_t generation;
-    CHECK(msg->findInt32("generation", &generation));
-
-    if (generation != currentGeneration) {
-        return;
-    }
-
-    sp<ABuffer> buffer;
-    while (mLiveSession->dequeueAccessUnit(fetchType, &buffer) == OK) {
-
-        sp<AMessage> notify = dupNotify();
-        notify->setInt32("what", pushWhat);
-        notify->setBuffer("buffer", buffer);
-
-        int64_t timeUs, baseUs, delayUs;
-        CHECK(buffer->meta()->findInt64("baseUs", &baseUs));
-        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
-        delayUs = baseUs + timeUs - ALooper::GetNowUs();
-
-        if (fetchType == LiveSession::STREAMTYPE_SUBTITLES) {
-            notify->post();
-            msg->post(delayUs > 0LL ? delayUs : 0LL);
-            return;
-        } else if (fetchType == LiveSession::STREAMTYPE_METADATA) {
-            if (delayUs < -1000000LL) { // 1 second
-                continue;
-            }
-            notify->post();
-            // push all currently available metadata buffers in each invocation of pollForRawData
-            // continue;
-        } else {
-            TRESPASS();
-        }
-    }
-
-    // try again in 1 second
-    msg->post(1000000LL);
-}
-
-void NuPlayer2::HTTPLiveSource2::onMessageReceived(const sp<AMessage> &msg) {
-    switch (msg->what()) {
-        case kWhatSessionNotify:
-        {
-            onSessionNotify(msg);
-            break;
-        }
-
-        case kWhatFetchSubtitleData:
-        {
-            pollForRawData(
-                    msg, mFetchSubtitleDataGeneration,
-                    /* fetch */ LiveSession::STREAMTYPE_SUBTITLES,
-                    /* push */ kWhatSubtitleData);
-
-            break;
-        }
-
-        case kWhatFetchMetaData:
-        {
-            if (!mMetadataSelected) {
-                break;
-            }
-
-            pollForRawData(
-                    msg, mFetchMetaDataGeneration,
-                    /* fetch */ LiveSession::STREAMTYPE_METADATA,
-                    /* push */ kWhatTimedMetaData);
-
-            break;
-        }
-
-        default:
-            Source::onMessageReceived(msg);
-            break;
-    }
-}
-
-void NuPlayer2::HTTPLiveSource2::onSessionNotify(const sp<AMessage> &msg) {
-    int32_t what;
-    CHECK(msg->findInt32("what", &what));
-
-    switch (what) {
-        case LiveSession::kWhatPrepared:
-        {
-            // notify the current size here if we have it, otherwise report an initial size of (0,0)
-            sp<AMessage> format = getFormat(false /* audio */);
-            int32_t width;
-            int32_t height;
-            if (format != NULL &&
-                    format->findInt32("width", &width) && format->findInt32("height", &height)) {
-                notifyVideoSizeChanged(format);
-            } else {
-                notifyVideoSizeChanged();
-            }
-
-            uint32_t flags = 0;
-            if (mLiveSession->isSeekable()) {
-                flags |= FLAG_CAN_PAUSE;
-                flags |= FLAG_CAN_SEEK;
-                flags |= FLAG_CAN_SEEK_BACKWARD;
-                flags |= FLAG_CAN_SEEK_FORWARD;
-            }
-
-            if (mLiveSession->hasDynamicDuration()) {
-                flags |= FLAG_DYNAMIC_DURATION;
-            }
-
-            notifyFlagsChanged(flags);
-
-            notifyPrepared();
-            break;
-        }
-
-        case LiveSession::kWhatPreparationFailed:
-        {
-            status_t err;
-            CHECK(msg->findInt32("err", &err));
-
-            notifyPrepared(err);
-            break;
-        }
-
-        case LiveSession::kWhatStreamsChanged:
-        {
-            uint32_t changedMask;
-            CHECK(msg->findInt32(
-                        "changedMask", (int32_t *)&changedMask));
-
-            bool audio = changedMask & LiveSession::STREAMTYPE_AUDIO;
-            bool video = changedMask & LiveSession::STREAMTYPE_VIDEO;
-
-            sp<AMessage> reply;
-            CHECK(msg->findMessage("reply", &reply));
-
-            sp<AMessage> notify = dupNotify();
-            notify->setInt32("what", kWhatQueueDecoderShutdown);
-            notify->setInt32("audio", audio);
-            notify->setInt32("video", video);
-            notify->setMessage("reply", reply);
-            notify->post();
-            break;
-        }
-
-        case LiveSession::kWhatBufferingStart:
-        {
-            sp<AMessage> notify = dupNotify();
-            notify->setInt32("what", kWhatPauseOnBufferingStart);
-            notify->post();
-            break;
-        }
-
-        case LiveSession::kWhatBufferingEnd:
-        {
-            sp<AMessage> notify = dupNotify();
-            notify->setInt32("what", kWhatResumeOnBufferingEnd);
-            notify->post();
-            break;
-        }
-
-
-        case LiveSession::kWhatBufferingUpdate:
-        {
-            sp<AMessage> notify = dupNotify();
-            int32_t percentage;
-            CHECK(msg->findInt32("percentage", &percentage));
-            notify->setInt32("what", kWhatBufferingUpdate);
-            notify->setInt32("percentage", percentage);
-            notify->post();
-            break;
-        }
-
-        case LiveSession::kWhatMetadataDetected:
-        {
-            if (!mHasMetadata) {
-                mHasMetadata = true;
-
-                sp<AMessage> notify = dupNotify();
-                // notification without buffer triggers MEDIA2_INFO_METADATA_UPDATE
-                notify->setInt32("what", kWhatTimedMetaData);
-                notify->post();
-            }
-            break;
-        }
-
-        case LiveSession::kWhatError:
-        {
-            break;
-        }
-
-        default:
-            TRESPASS();
-    }
-}
-
-}  // namespace android
-
diff --git a/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.h b/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.h
deleted file mode 100644
index 8fc71e2..0000000
--- a/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-#ifndef HTTP_LIVE_SOURCE2_H_
-
-#define HTTP_LIVE_SOURCE2_H_
-
-#include "NuPlayer2.h"
-#include "NuPlayer2Source.h"
-
-#include "LiveSession.h"
-
-namespace android {
-
-struct LiveSession;
-
-struct NuPlayer2::HTTPLiveSource2 : public NuPlayer2::Source {
-    HTTPLiveSource2(
-            const sp<AMessage> &notify,
-            const sp<MediaHTTPService> &httpService,
-            const char *url,
-            const KeyedVector<String8, String8> *headers);
-
-    virtual status_t getBufferingSettings(
-            BufferingSettings* buffering /* nonnull */) override;
-    virtual status_t setBufferingSettings(const BufferingSettings& buffering) override;
-
-    virtual void prepareAsync(int64_t startTimeUs);
-    virtual void start();
-
-    virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);
-    virtual sp<MetaData> getFormatMeta(bool audio);
-    virtual sp<AMessage> getFormat(bool audio);
-
-    virtual status_t feedMoreTSData();
-    virtual status_t getDuration(int64_t *durationUs);
-    virtual size_t getTrackCount() const;
-    virtual sp<AMessage> getTrackInfo(size_t trackIndex) const;
-    virtual ssize_t getSelectedTrack(media_track_type /* type */) const;
-    virtual status_t selectTrack(size_t trackIndex, bool select, int64_t timeUs);
-    virtual status_t seekTo(
-            int64_t seekTimeUs,
-            MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC) override;
-
-protected:
-    virtual ~HTTPLiveSource2();
-
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
-    enum Flags {
-        // Don't log any URLs.
-        kFlagIncognito = 1,
-    };
-
-    enum {
-        kWhatSessionNotify,
-        kWhatFetchSubtitleData,
-        kWhatFetchMetaData,
-    };
-
-    sp<MediaHTTPService> mHTTPService;
-    AString mURL;
-    KeyedVector<String8, String8> mExtraHeaders;
-    uint32_t mFlags;
-    status_t mFinalResult;
-    off64_t mOffset;
-    sp<ALooper> mLiveLooper;
-    sp<LiveSession> mLiveSession;
-    int32_t mFetchSubtitleDataGeneration;
-    int32_t mFetchMetaDataGeneration;
-    bool mHasMetadata;
-    bool mMetadataSelected;
-    BufferingSettings mBufferingSettings;
-
-    void onSessionNotify(const sp<AMessage> &msg);
-    void pollForRawData(
-            const sp<AMessage> &msg, int32_t currentGeneration,
-            LiveSession::StreamType fetchType, int32_t pushWhat);
-
-    DISALLOW_EVIL_CONSTRUCTORS(HTTPLiveSource2);
-};
-
-}  // namespace android
-
-#endif  // HTTP_LIVE_SOURCE2_H_
diff --git a/media/libmediaplayer2/nuplayer2/JMediaPlayer2Utils.cpp b/media/libmediaplayer2/nuplayer2/JMediaPlayer2Utils.cpp
deleted file mode 100644
index 89703de..0000000
--- a/media/libmediaplayer2/nuplayer2/JMediaPlayer2Utils.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright 2018, 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 "JMediaPlayer2Utils"
-
-#include "JMediaPlayer2Utils.h"
-#include <mediaplayer2/JavaVMHelper.h>
-
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/Utils.h>
-#include <utils/Log.h>
-
-#include "log/log.h"
-
-namespace android {
-
-static const int64_t kOffloadMinDurationSec = 60;
-
-// static
-bool JMediaPlayer2Utils::isOffloadedAudioPlaybackSupported(
-        const sp<MetaData>& meta, bool hasVideo, bool isStreaming, audio_stream_type_t streamType)
-{
-    if (hasVideo || streamType != AUDIO_STREAM_MUSIC) {
-        return false;
-    }
-
-    audio_offload_info_t info = AUDIO_INFO_INITIALIZER;
-    if (OK != getAudioOffloadInfo(meta, hasVideo, isStreaming, streamType, &info)) {
-        return false;
-    }
-
-    if (info.duration_us < kOffloadMinDurationSec * 1000000) {
-        return false;
-    }
-
-    int32_t audioFormat = audioFormatFromNative(info.format);
-    int32_t channelMask = outChannelMaskFromNative(info.channel_mask);
-    if (audioFormat == ENCODING_INVALID || channelMask == CHANNEL_INVALID) {
-        return false;
-    }
-
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    jclass jMP2UtilsCls = env->FindClass("android/media/MediaPlayer2Utils");
-    jmethodID jSetAudioOutputDeviceById = env->GetStaticMethodID(
-            jMP2UtilsCls, "isOffloadedAudioPlaybackSupported", "(III)Z");
-    jboolean result = env->CallStaticBooleanMethod(
-            jMP2UtilsCls, jSetAudioOutputDeviceById, audioFormat, info.sample_rate, channelMask);
-    return result;
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/JMediaPlayer2Utils.h b/media/libmediaplayer2/nuplayer2/JMediaPlayer2Utils.h
deleted file mode 100644
index fcbd43c..0000000
--- a/media/libmediaplayer2/nuplayer2/JMediaPlayer2Utils.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2018, 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.
- */
-
-#ifndef _J_MEDIAPLAYER2_UTILS2_H_
-#define _J_MEDIAPLAYER2_UTILS2_H_
-
-#include <media/stagefright/MetaData.h>
-
-#include "jni.h"
-#include "android_media_AudioFormat.h"
-
-namespace android {
-
-struct JMediaPlayer2Utils {
-    static bool isOffloadedAudioPlaybackSupported(
-            const sp<MetaData>& meta, bool hasVideo, bool isStreaming,
-            audio_stream_type_t streamType);
-};
-
-}  // namespace android
-
-#endif  // _J_MEDIAPLAYER2_UTILS2_H_
diff --git a/media/libmediaplayer2/nuplayer2/JWakeLock.cpp b/media/libmediaplayer2/nuplayer2/JWakeLock.cpp
deleted file mode 100644
index 983d77e..0000000
--- a/media/libmediaplayer2/nuplayer2/JWakeLock.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2017 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 "JWakeLock"
-#include <utils/Log.h>
-
-#include "JWakeLock.h"
-
-#include <media/stagefright/foundation/ADebug.h>
-
-namespace android {
-
-JWakeLock::JWakeLock(const sp<JObjectHolder> &context) :
-    mWakeLockCount(0),
-    mWakeLock(NULL),
-    mContext(context) {}
-
-JWakeLock::~JWakeLock() {
-    clearJavaWakeLock();
-}
-
-bool JWakeLock::acquire() {
-    if (mWakeLockCount == 0) {
-        if (mWakeLock == NULL) {
-            JNIEnv *env = JavaVMHelper::getJNIEnv();
-            jclass jContextCls = env->FindClass("android/content/Context");
-            jclass jPowerManagerCls = env->FindClass("android/os/PowerManager");
-
-            jmethodID jGetSystemService = env->GetMethodID(jContextCls,
-                    "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
-            jobject javaPowerManagerObj = env->CallObjectMethod(mContext->getJObject(),
-                    jGetSystemService, env->NewStringUTF("power"));
-
-            jfieldID jPARTIAL_WAKE_LOCK = env->GetStaticFieldID(jPowerManagerCls,
-                    "PARTIAL_WAKE_LOCK", "I");
-            jint PARTIAL_WAKE_LOCK = env->GetStaticIntField(jPowerManagerCls, jPARTIAL_WAKE_LOCK);
-
-            jmethodID jNewWakeLock = env->GetMethodID(jPowerManagerCls,
-                    "newWakeLock", "(ILjava/lang/String;)Landroid/os/PowerManager$WakeLock;");
-            jobject javaWakeLock = env->CallObjectMethod(javaPowerManagerObj,
-                    jNewWakeLock, PARTIAL_WAKE_LOCK, env->NewStringUTF("JWakeLock"));
-            mWakeLock = new JObjectHolder(javaWakeLock);
-            env->DeleteLocalRef(javaPowerManagerObj);
-            env->DeleteLocalRef(javaWakeLock);
-        }
-        if (mWakeLock != NULL) {
-            JNIEnv *env = JavaVMHelper::getJNIEnv();
-            jclass wakeLockCls = env->FindClass("android/os/PowerManager$WakeLock");
-            jmethodID jAcquire = env->GetMethodID(wakeLockCls, "acquire", "()V");
-            env->CallVoidMethod(mWakeLock->getJObject(), jAcquire);
-            mWakeLockCount++;
-            return true;
-        }
-    } else {
-        mWakeLockCount++;
-        return true;
-    }
-    return false;
-}
-
-void JWakeLock::release(bool force) {
-    if (mWakeLockCount == 0) {
-        return;
-    }
-    if (force) {
-        // Force wakelock release below by setting reference count to 1.
-        mWakeLockCount = 1;
-    }
-    if (--mWakeLockCount == 0) {
-        if (mWakeLock != NULL) {
-            JNIEnv *env = JavaVMHelper::getJNIEnv();
-            jclass wakeLockCls = env->FindClass("android/os/PowerManager$WakeLock");
-            jmethodID jRelease = env->GetMethodID(wakeLockCls, "release", "()V");
-            env->CallVoidMethod(mWakeLock->getJObject(), jRelease);
-        }
-    }
-}
-
-void JWakeLock::clearJavaWakeLock() {
-    release(true);
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/JWakeLock.h b/media/libmediaplayer2/nuplayer2/JWakeLock.h
deleted file mode 100644
index 36c542e..0000000
--- a/media/libmediaplayer2/nuplayer2/JWakeLock.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-#ifndef J_WAKELOCK_H_
-#define J_WAKELOCK_H_
-
-#include <media/stagefright/foundation/ABase.h>
-#include <mediaplayer2/JObjectHolder.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-class JWakeLock : public RefBase {
-
-public:
-    JWakeLock(const sp<JObjectHolder> &context);
-
-    // NOTE: acquire and release are not thread safe
-
-    // returns true if wakelock was acquired
-    bool acquire();
-    void release(bool force = false);
-
-    virtual ~JWakeLock();
-
-private:
-    uint32_t                mWakeLockCount;
-    sp<JObjectHolder>       mWakeLock;
-    const sp<JObjectHolder> mContext;
-
-    void clearJavaWakeLock();
-
-    DISALLOW_EVIL_CONSTRUCTORS(JWakeLock);
-};
-
-}  // namespace android
-
-#endif  // J_WAKELOCK_H_
diff --git a/media/libmediaplayer2/nuplayer2/MODULE_LICENSE_APACHE2 b/media/libmediaplayer2/nuplayer2/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/media/libmediaplayer2/nuplayer2/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/media/libmediaplayer2/nuplayer2/NOTICE b/media/libmediaplayer2/nuplayer2/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/media/libmediaplayer2/nuplayer2/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   Copyright (c) 2005-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.
-
-   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.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
deleted file mode 100644
index d608d4a..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
+++ /dev/null
@@ -1,3308 +0,0 @@
-/*
- * Copyright 2017 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 "NuPlayer2"
-
-#include <inttypes.h>
-
-#include <utils/Log.h>
-
-#include "NuPlayer2.h"
-
-#include "HTTPLiveSource2.h"
-#include "JMediaPlayer2Utils.h"
-#include "NuPlayer2CCDecoder.h"
-#include "NuPlayer2Decoder.h"
-#include "NuPlayer2DecoderBase.h"
-#include "NuPlayer2DecoderPassThrough.h"
-#include "NuPlayer2Driver.h"
-#include "NuPlayer2Renderer.h"
-#include "NuPlayer2Source.h"
-#include "RTSPSource2.h"
-#include "GenericSource2.h"
-#include "TextDescriptions2.h"
-
-#include "ATSParser.h"
-
-#include <cutils/properties.h>
-
-#include <media/AudioParameter.h>
-#include <media/AudioResamplerPublic.h>
-#include <media/AVSyncSettings.h>
-#include <media/DataSourceDesc.h>
-#include <media/MediaCodecBuffer.h>
-#include <media/NdkWrapper.h>
-
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/avc_utils.h>
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/MediaClock.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MetaData.h>
-
-#include "ESDS.h"
-#include <media/stagefright/Utils.h>
-
-#include <system/window.h>
-
-namespace android {
-
-static status_t sendMetaDataToHal(sp<MediaPlayer2Interface::AudioSink>& sink,
-                                  const sp<MetaData>& meta) {
-    int32_t sampleRate = 0;
-    int32_t bitRate = 0;
-    int32_t channelMask = 0;
-    int32_t delaySamples = 0;
-    int32_t paddingSamples = 0;
-
-    AudioParameter param = AudioParameter();
-
-    if (meta->findInt32(kKeySampleRate, &sampleRate)) {
-        param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate);
-    }
-    if (meta->findInt32(kKeyChannelMask, &channelMask)) {
-        param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask);
-    }
-    if (meta->findInt32(kKeyBitRate, &bitRate)) {
-        param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate);
-    }
-    if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) {
-        param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples);
-    }
-    if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) {
-        param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples);
-    }
-
-    ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d,"
-          "delaySample %d, paddingSample %d", bitRate, sampleRate,
-          channelMask, delaySamples, paddingSamples);
-
-    sink->setParameters(param.toString());
-    return OK;
-}
-
-
-struct NuPlayer2::Action : public RefBase {
-    Action() {}
-
-    virtual void execute(NuPlayer2 *player) = 0;
-
-private:
-    DISALLOW_EVIL_CONSTRUCTORS(Action);
-};
-
-struct NuPlayer2::SeekAction : public Action {
-    explicit SeekAction(int64_t seekTimeUs, MediaPlayer2SeekMode mode)
-        : mSeekTimeUs(seekTimeUs),
-          mMode(mode) {
-    }
-
-    virtual void execute(NuPlayer2 *player) {
-        player->performSeek(mSeekTimeUs, mMode);
-    }
-
-private:
-    int64_t mSeekTimeUs;
-    MediaPlayer2SeekMode mMode;
-
-    DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
-};
-
-struct NuPlayer2::ResumeDecoderAction : public Action {
-    explicit ResumeDecoderAction(bool needNotify)
-        : mNeedNotify(needNotify) {
-    }
-
-    virtual void execute(NuPlayer2 *player) {
-        player->performResumeDecoders(mNeedNotify);
-    }
-
-private:
-    bool mNeedNotify;
-
-    DISALLOW_EVIL_CONSTRUCTORS(ResumeDecoderAction);
-};
-
-struct NuPlayer2::SetSurfaceAction : public Action {
-    explicit SetSurfaceAction(const sp<ANativeWindowWrapper> &nww)
-        : mNativeWindow(nww) {
-    }
-
-    virtual void execute(NuPlayer2 *player) {
-        player->performSetSurface(mNativeWindow);
-    }
-
-private:
-    sp<ANativeWindowWrapper> mNativeWindow;
-
-    DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
-};
-
-struct NuPlayer2::FlushDecoderAction : public Action {
-    FlushDecoderAction(FlushCommand audio, FlushCommand video)
-        : mAudio(audio),
-          mVideo(video) {
-    }
-
-    virtual void execute(NuPlayer2 *player) {
-        player->performDecoderFlush(mAudio, mVideo);
-    }
-
-private:
-    FlushCommand mAudio;
-    FlushCommand mVideo;
-
-    DISALLOW_EVIL_CONSTRUCTORS(FlushDecoderAction);
-};
-
-struct NuPlayer2::PostMessageAction : public Action {
-    explicit PostMessageAction(const sp<AMessage> &msg)
-        : mMessage(msg) {
-    }
-
-    virtual void execute(NuPlayer2 *) {
-        mMessage->post();
-    }
-
-private:
-    sp<AMessage> mMessage;
-
-    DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction);
-};
-
-// Use this if there's no state necessary to save in order to execute
-// the action.
-struct NuPlayer2::SimpleAction : public Action {
-    typedef void (NuPlayer2::*ActionFunc)();
-
-    explicit SimpleAction(ActionFunc func)
-        : mFunc(func) {
-    }
-
-    virtual void execute(NuPlayer2 *player) {
-        (player->*mFunc)();
-    }
-
-private:
-    ActionFunc mFunc;
-
-    DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-NuPlayer2::NuPlayer2(
-        pid_t pid, uid_t uid, const sp<MediaClock> &mediaClock, const sp<JObjectHolder> &context)
-    : mPID(pid),
-      mUID(uid),
-      mMediaClock(mediaClock),
-      mOffloadAudio(false),
-      mAudioDecoderGeneration(0),
-      mVideoDecoderGeneration(0),
-      mRendererGeneration(0),
-      mEOSMonitorGeneration(0),
-      mLastStartedPlayingTimeNs(0),
-      mPreviousSeekTimeUs(0),
-      mAudioEOS(false),
-      mVideoEOS(false),
-      mScanSourcesPending(false),
-      mScanSourcesGeneration(0),
-      mPollDurationGeneration(0),
-      mTimedTextGeneration(0),
-      mFlushingAudio(NONE),
-      mFlushingVideo(NONE),
-      mResumePending(false),
-      mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
-      mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT),
-      mVideoFpsHint(-1.f),
-      mStarted(false),
-      mPrepared(false),
-      mResetting(false),
-      mSourceStarted(false),
-      mAudioDecoderError(false),
-      mVideoDecoderError(false),
-      mPaused(false),
-      mPausedByClient(true),
-      mPausedForBuffering(false),
-      mContext(context) {
-    CHECK(mediaClock != NULL);
-    clearFlushComplete();
-}
-
-NuPlayer2::~NuPlayer2() {
-}
-
-void NuPlayer2::setDriver(const wp<NuPlayer2Driver> &driver) {
-    mDriver = driver;
-}
-
-static bool IsHTTPLiveURL(const char *url) {
-    if (!strncasecmp("http://", url, 7)
-            || !strncasecmp("https://", url, 8)
-            || !strncasecmp("file://", url, 7)) {
-        size_t len = strlen(url);
-        if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
-            return true;
-        }
-
-        if (strstr(url,"m3u8")) {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-status_t NuPlayer2::createNuPlayer2Source(const sp<DataSourceDesc> &dsd,
-                                          sp<Source> *source,
-                                          DATA_SOURCE_TYPE *dataSourceType) {
-    status_t err = NO_ERROR;
-    sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
-    notify->setInt64("srcId", dsd->mId);
-
-    switch (dsd->mType) {
-        case DataSourceDesc::TYPE_URL:
-        {
-            const char *url = dsd->mUrl.c_str();
-            size_t len = strlen(url);
-
-            const sp<MediaHTTPService> &httpService = dsd->mHttpService;
-            KeyedVector<String8, String8> *headers = &(dsd->mHeaders);
-
-            if (IsHTTPLiveURL(url)) {
-                *source = new HTTPLiveSource2(notify, httpService, url, headers);
-                ALOGV("createNuPlayer2Source HTTPLiveSource2 %s", url);
-                *dataSourceType = DATA_SOURCE_TYPE_HTTP_LIVE;
-            } else if (!strncasecmp(url, "rtsp://", 7)) {
-                *source = new RTSPSource2(
-                        notify, httpService, url, headers, mUID);
-                ALOGV("createNuPlayer2Source RTSPSource2 %s", url);
-                *dataSourceType = DATA_SOURCE_TYPE_RTSP;
-            } else if ((!strncasecmp(url, "http://", 7)
-                        || !strncasecmp(url, "https://", 8))
-                            && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
-                            || strstr(url, ".sdp?"))) {
-                *source = new RTSPSource2(
-                        notify, httpService, url, headers, mUID, true);
-                ALOGV("createNuPlayer2Source RTSPSource2 http/https/.sdp %s", url);
-                *dataSourceType = DATA_SOURCE_TYPE_RTSP;
-            } else {
-                ALOGV("createNuPlayer2Source GenericSource2 %s", url);
-
-                sp<GenericSource2> genericSource =
-                        new GenericSource2(notify, mUID, mMediaClock);
-
-                err = genericSource->setDataSource(url, headers);
-
-                if (err == OK) {
-                    *source = genericSource;
-                } else {
-                    *source = NULL;
-                    ALOGE("Failed to create NuPlayer2Source!");
-                }
-
-                // regardless of success/failure
-                *dataSourceType = DATA_SOURCE_TYPE_GENERIC_URL;
-            }
-            break;
-        }
-
-        case DataSourceDesc::TYPE_FD:
-        {
-            sp<GenericSource2> genericSource =
-                    new GenericSource2(notify, mUID, mMediaClock);
-
-            ALOGV("createNuPlayer2Source fd %d/%lld/%lld source: %p",
-                  dsd->mFD, (long long)dsd->mFDOffset, (long long)dsd->mFDLength,
-                  genericSource.get());
-
-            err = genericSource->setDataSource(dsd->mFD, dsd->mFDOffset, dsd->mFDLength);
-
-            if (err != OK) {
-                ALOGE("Failed to create NuPlayer2Source!");
-                *source = NULL;
-            } else {
-                *source = genericSource;
-            }
-
-            *dataSourceType = DATA_SOURCE_TYPE_GENERIC_FD;
-            break;
-        }
-
-        case DataSourceDesc::TYPE_CALLBACK:
-        {
-            sp<GenericSource2> genericSource =
-                    new GenericSource2(notify, mUID, mMediaClock);
-            err = genericSource->setDataSource(dsd->mCallbackSource);
-
-            if (err != OK) {
-                ALOGE("Failed to create NuPlayer2Source!");
-                *source = NULL;
-            } else {
-                *source = genericSource;
-            }
-
-            *dataSourceType = DATA_SOURCE_TYPE_MEDIA;
-            break;
-        }
-
-        default:
-            err = BAD_TYPE;
-            *source = NULL;
-            *dataSourceType = DATA_SOURCE_TYPE_NONE;
-            ALOGE("invalid data source type!");
-            break;
-    }
-
-    return err;
-}
-
-void NuPlayer2::setDataSourceAsync(const sp<DataSourceDesc> &dsd) {
-    DATA_SOURCE_TYPE dataSourceType;
-    sp<Source> source;
-    createNuPlayer2Source(dsd, &source, &dataSourceType);
-
-    // TODO: currently NuPlayer2Driver makes blocking call to setDataSourceAsync
-    // and expects notifySetDataSourceCompleted regardless of success or failure.
-    // This will be changed since setDataSource should be asynchronous at JAVA level.
-    // When it succeeds, app will get onInfo notification. Otherwise, onError
-    // will be called.
-    /*
-    if (err != OK) {
-        notifyListener(dsd->mId, MEDIA2_ERROR, MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE, err);
-        return;
-    }
-
-    // Now, source != NULL.
-    */
-
-    mCurrentSourceInfo.mDataSourceType = dataSourceType;
-
-    sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
-    msg->setObject("source", source);
-    msg->setInt64("srcId", dsd->mId);
-    msg->setInt64("startTimeUs", dsd->mStartPositionMs * 1000);
-    msg->setInt64("endTimeUs", dsd->mEndPositionMs * 1000);
-    msg->post();
-}
-
-void NuPlayer2::prepareNextDataSourceAsync(const sp<DataSourceDesc> &dsd) {
-    DATA_SOURCE_TYPE dataSourceType;
-    sp<Source> source;
-    createNuPlayer2Source(dsd, &source, &dataSourceType);
-
-    /*
-    if (err != OK) {
-        notifyListener(dsd->mId, MEDIA2_ERROR, MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE, err);
-        return;
-    }
-
-    // Now, source != NULL.
-    */
-
-    mNextSourceInfo.mDataSourceType = dataSourceType;
-
-    sp<AMessage> msg = new AMessage(kWhatPrepareNextDataSource, this);
-    msg->setObject("source", source);
-    msg->setInt64("srcId", dsd->mId);
-    msg->setInt64("startTimeUs", dsd->mStartPositionMs * 1000);
-    msg->setInt64("endTimeUs", dsd->mEndPositionMs * 1000);
-    msg->post();
-}
-
-void NuPlayer2::playNextDataSource(int64_t srcId) {
-    disconnectSource();
-
-    sp<AMessage> msg = new AMessage(kWhatPlayNextDataSource, this);
-    msg->setInt64("srcId", srcId);
-    msg->post();
-}
-
-status_t NuPlayer2::getBufferingSettings(
-        BufferingSettings *buffering /* nonnull */) {
-    sp<AMessage> msg = new AMessage(kWhatGetBufferingSettings, this);
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-        if (err == OK) {
-            readFromAMessage(response, buffering);
-        }
-    }
-    return err;
-}
-
-status_t NuPlayer2::setBufferingSettings(const BufferingSettings& buffering) {
-    sp<AMessage> msg = new AMessage(kWhatSetBufferingSettings, this);
-    writeToAMessage(msg, buffering);
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-    }
-    return err;
-}
-
-void NuPlayer2::prepareAsync() {
-    ALOGV("prepareAsync");
-
-    (new AMessage(kWhatPrepare, this))->post();
-}
-
-void NuPlayer2::setVideoSurfaceTextureAsync(const sp<ANativeWindowWrapper> &nww) {
-    sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
-
-    if (nww == NULL || nww->getANativeWindow() == NULL) {
-        msg->setObject("surface", NULL);
-    } else {
-        msg->setObject("surface", nww);
-    }
-
-    msg->post();
-}
-
-void NuPlayer2::setAudioSink(const sp<MediaPlayer2Interface::AudioSink> &sink) {
-    sp<AMessage> msg = new AMessage(kWhatSetAudioSink, this);
-    msg->setObject("sink", sink);
-    msg->post();
-}
-
-void NuPlayer2::start() {
-    (new AMessage(kWhatStart, this))->post();
-}
-
-status_t NuPlayer2::setPlaybackSettings(const AudioPlaybackRate &rate) {
-    // do some cursory validation of the settings here. audio modes are
-    // only validated when set on the audiosink.
-     if (rate.mSpeed < AUDIO_TIMESTRETCH_SPEED_MIN
-            || rate.mSpeed > AUDIO_TIMESTRETCH_SPEED_MAX
-            || rate.mPitch < AUDIO_TIMESTRETCH_SPEED_MIN
-            || rate.mPitch > AUDIO_TIMESTRETCH_SPEED_MAX) {
-        return BAD_VALUE;
-    }
-    sp<AMessage> msg = new AMessage(kWhatConfigPlayback, this);
-    writeToAMessage(msg, rate);
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-    }
-    return err;
-}
-
-status_t NuPlayer2::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
-    sp<AMessage> msg = new AMessage(kWhatGetPlaybackSettings, this);
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-        if (err == OK) {
-            readFromAMessage(response, rate);
-        }
-    }
-    return err;
-}
-
-status_t NuPlayer2::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) {
-    sp<AMessage> msg = new AMessage(kWhatConfigSync, this);
-    writeToAMessage(msg, sync, videoFpsHint);
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-    }
-    return err;
-}
-
-status_t NuPlayer2::getSyncSettings(
-        AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */) {
-    sp<AMessage> msg = new AMessage(kWhatGetSyncSettings, this);
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-        if (err == OK) {
-            readFromAMessage(response, sync, videoFps);
-        }
-    }
-    return err;
-}
-
-void NuPlayer2::pause() {
-    (new AMessage(kWhatPause, this))->post();
-}
-
-void NuPlayer2::resetAsync() {
-    disconnectSource();
-    (new AMessage(kWhatReset, this))->post();
-}
-
-void NuPlayer2::disconnectSource() {
-    sp<Source> source;
-    {
-        Mutex::Autolock autoLock(mSourceLock);
-        source = mCurrentSourceInfo.mSource;
-    }
-
-    if (source != NULL) {
-        // During a reset, the data source might be unresponsive already, we need to
-        // disconnect explicitly so that reads exit promptly.
-        // We can't queue the disconnect request to the looper, as it might be
-        // queued behind a stuck read and never gets processed.
-        // Doing a disconnect outside the looper to allows the pending reads to exit
-        // (either successfully or with error).
-        source->disconnect();
-    }
-
-}
-
-status_t NuPlayer2::notifyAt(int64_t mediaTimeUs) {
-    sp<AMessage> notify = new AMessage(kWhatNotifyTime, this);
-    notify->setInt64("timerUs", mediaTimeUs);
-    mMediaClock->addTimer(notify, mediaTimeUs);
-    return OK;
-}
-
-void NuPlayer2::seekToAsync(int64_t seekTimeUs, MediaPlayer2SeekMode mode, bool needNotify) {
-    sp<AMessage> msg = new AMessage(kWhatSeek, this);
-    msg->setInt64("seekTimeUs", seekTimeUs);
-    msg->setInt32("mode", mode);
-    msg->setInt32("needNotify", needNotify);
-    msg->post();
-}
-
-void NuPlayer2::rewind() {
-    sp<AMessage> msg = new AMessage(kWhatRewind, this);
-    msg->post();
-}
-
-void NuPlayer2::writeTrackInfo(
-        PlayerMessage* reply, const sp<AMessage>& format) const {
-    if (format == NULL) {
-        ALOGE("NULL format");
-        return;
-    }
-    int32_t trackType;
-    if (!format->findInt32("type", &trackType)) {
-        ALOGE("no track type");
-        return;
-    }
-
-    AString mime;
-    if (!format->findString("mime", &mime)) {
-        // Java MediaPlayer only uses mimetype for subtitle and timedtext tracks.
-        // If we can't find the mimetype here it means that we wouldn't be needing
-        // the mimetype on the Java end. We still write a placeholder mime to keep the
-        // (de)serialization logic simple.
-        if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
-            mime = "audio/";
-        } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
-            mime = "video/";
-        } else {
-            ALOGE("unknown track type: %d", trackType);
-            return;
-        }
-    }
-
-    AString lang;
-    if (!format->findString("language", &lang)) {
-        ALOGE("no language");
-        return;
-    }
-
-    reply->add_values()->set_int32_value(trackType);
-    reply->add_values()->set_string_value(mime.c_str());
-    reply->add_values()->set_string_value(lang.c_str());
-
-    if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
-        int32_t isAuto, isDefault, isForced;
-        CHECK(format->findInt32("auto", &isAuto));
-        CHECK(format->findInt32("default", &isDefault));
-        CHECK(format->findInt32("forced", &isForced));
-
-        reply->add_values()->set_int32_value(isAuto);
-        reply->add_values()->set_int32_value(isDefault);
-        reply->add_values()->set_int32_value(isForced);
-    }
-}
-
-void NuPlayer2::onMessageReceived(const sp<AMessage> &msg) {
-
-    switch (msg->what()) {
-        case kWhatSetDataSource:
-        {
-            ALOGV("kWhatSetDataSource");
-
-            CHECK(mCurrentSourceInfo.mSource == NULL);
-
-            status_t err = OK;
-            sp<RefBase> obj;
-            CHECK(msg->findObject("source", &obj));
-            if (obj != NULL) {
-                Mutex::Autolock autoLock(mSourceLock);
-                CHECK(msg->findInt64("srcId", &mCurrentSourceInfo.mSrcId));
-                CHECK(msg->findInt64("startTimeUs", &mCurrentSourceInfo.mStartTimeUs));
-                CHECK(msg->findInt64("endTimeUs", &mCurrentSourceInfo.mEndTimeUs));
-                mCurrentSourceInfo.mSource = static_cast<Source *>(obj.get());
-            } else {
-                err = UNKNOWN_ERROR;
-                ALOGE("kWhatSetDataSource, source should not be NULL");
-            }
-
-            CHECK(mDriver != NULL);
-            sp<NuPlayer2Driver> driver = mDriver.promote();
-            if (driver != NULL) {
-                driver->notifySetDataSourceCompleted(mCurrentSourceInfo.mSrcId, err);
-            }
-            break;
-        }
-
-        case kWhatPrepareNextDataSource:
-        {
-            ALOGV("kWhatPrepareNextDataSource");
-
-            status_t err = OK;
-            sp<RefBase> obj;
-            CHECK(msg->findObject("source", &obj));
-            if (obj != NULL) {
-                Mutex::Autolock autoLock(mSourceLock);
-                CHECK(msg->findInt64("srcId", &mNextSourceInfo.mSrcId));
-                CHECK(msg->findInt64("startTimeUs", &mNextSourceInfo.mStartTimeUs));
-                CHECK(msg->findInt64("endTimeUs", &mNextSourceInfo.mEndTimeUs));
-                mNextSourceInfo.mSource = static_cast<Source *>(obj.get());
-                mNextSourceInfo.mSource->prepareAsync(mNextSourceInfo.mStartTimeUs);
-            } else {
-                err = UNKNOWN_ERROR;
-            }
-
-            break;
-        }
-
-        case kWhatPlayNextDataSource:
-        {
-            ALOGV("kWhatPlayNextDataSource");
-            int64_t srcId;
-            CHECK(msg->findInt64("srcId", &srcId));
-            if (srcId != mNextSourceInfo.mSrcId) {
-                notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, 0);
-                return;
-            }
-
-            mResetting = true;
-            stopPlaybackTimer("kWhatPlayNextDataSource");
-            stopRebufferingTimer(true);
-
-            mDeferredActions.push_back(
-                    new FlushDecoderAction(
-                        FLUSH_CMD_SHUTDOWN /* audio */,
-                        FLUSH_CMD_SHUTDOWN /* video */));
-
-            mDeferredActions.push_back(
-                    new SimpleAction(&NuPlayer2::performPlayNextDataSource));
-
-            processDeferredActions();
-            break;
-        }
-
-        case kWhatEOSMonitor:
-        {
-            int32_t generation;
-            CHECK(msg->findInt32("generation", &generation));
-            int32_t reason;
-            CHECK(msg->findInt32("reason", &reason));
-
-            if (generation != mEOSMonitorGeneration || reason != MediaClock::TIMER_REASON_REACHED) {
-                break;  // stale or reset
-            }
-
-            ALOGV("kWhatEOSMonitor");
-            notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
-            break;
-        }
-
-        case kWhatGetBufferingSettings:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-
-            ALOGV("kWhatGetBufferingSettings");
-            BufferingSettings buffering;
-            status_t err = OK;
-            if (mCurrentSourceInfo.mSource != NULL) {
-                err = mCurrentSourceInfo.mSource->getBufferingSettings(&buffering);
-            } else {
-                err = INVALID_OPERATION;
-            }
-            sp<AMessage> response = new AMessage;
-            if (err == OK) {
-                writeToAMessage(response, buffering);
-            }
-            response->setInt32("err", err);
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatSetBufferingSettings:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-
-            ALOGV("kWhatSetBufferingSettings");
-            BufferingSettings buffering;
-            readFromAMessage(msg, &buffering);
-            status_t err = OK;
-            if (mCurrentSourceInfo.mSource != NULL) {
-                err = mCurrentSourceInfo.mSource->setBufferingSettings(buffering);
-            } else {
-                err = INVALID_OPERATION;
-            }
-            sp<AMessage> response = new AMessage;
-            response->setInt32("err", err);
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatPrepare:
-        {
-            ALOGV("onMessageReceived kWhatPrepare");
-
-            mCurrentSourceInfo.mSource->prepareAsync(mCurrentSourceInfo.mStartTimeUs);
-            break;
-        }
-
-        case kWhatGetTrackInfo:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-
-            int64_t srcId;
-            CHECK(msg->findInt64("srcId", (int64_t*)&srcId));
-
-            PlayerMessage* reply;
-            CHECK(msg->findPointer("reply", (void**)&reply));
-
-            // TODO: use correct source info based on srcId.
-            size_t inbandTracks = 0;
-            if (mCurrentSourceInfo.mSource != NULL) {
-                inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
-            }
-
-            size_t ccTracks = 0;
-            if (mCCDecoder != NULL) {
-                ccTracks = mCCDecoder->getTrackCount();
-            }
-
-            // total track count
-            reply->add_values()->set_int32_value(inbandTracks + ccTracks);
-
-            // write inband tracks
-            for (size_t i = 0; i < inbandTracks; ++i) {
-                writeTrackInfo(reply, mCurrentSourceInfo.mSource->getTrackInfo(i));
-            }
-
-            // write CC track
-            for (size_t i = 0; i < ccTracks; ++i) {
-                writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
-            }
-
-            sp<AMessage> response = new AMessage;
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatGetSelectedTrack:
-        {
-            int64_t srcId;
-            CHECK(msg->findInt64("srcId", (int64_t*)&srcId));
-
-            int32_t type32;
-            CHECK(msg->findInt32("type", (int32_t*)&type32));
-            media_track_type type = (media_track_type)type32;
-
-            // TODO: use correct source info based on srcId.
-            size_t inbandTracks = 0;
-            status_t err = INVALID_OPERATION;
-            ssize_t selectedTrack = -1;
-            if (mCurrentSourceInfo.mSource != NULL) {
-                err = OK;
-                inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
-                selectedTrack = mCurrentSourceInfo.mSource->getSelectedTrack(type);
-            }
-
-            if (selectedTrack == -1 && mCCDecoder != NULL) {
-                err = OK;
-                selectedTrack = mCCDecoder->getSelectedTrack(type);
-                if (selectedTrack != -1) {
-                    selectedTrack += inbandTracks;
-                }
-            }
-
-            PlayerMessage* reply;
-            CHECK(msg->findPointer("reply", (void**)&reply));
-            reply->add_values()->set_int32_value(selectedTrack);
-
-            sp<AMessage> response = new AMessage;
-            response->setInt32("err", err);
-
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatSelectTrack:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-
-            int64_t srcId;
-            size_t trackIndex;
-            int32_t select;
-            int64_t timeUs;
-            CHECK(msg->findInt64("srcId", (int64_t*)&srcId));
-            CHECK(msg->findSize("trackIndex", &trackIndex));
-            CHECK(msg->findInt32("select", &select));
-            CHECK(msg->findInt64("timeUs", &timeUs));
-
-            status_t err = INVALID_OPERATION;
-
-            // TODO: use correct source info based on srcId.
-            size_t inbandTracks = 0;
-            if (mCurrentSourceInfo.mSource != NULL) {
-                inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
-            }
-            size_t ccTracks = 0;
-            if (mCCDecoder != NULL) {
-                ccTracks = mCCDecoder->getTrackCount();
-            }
-
-            if (trackIndex < inbandTracks) {
-                err = mCurrentSourceInfo.mSource->selectTrack(trackIndex, select, timeUs);
-
-                if (!select && err == OK) {
-                    int32_t type;
-                    sp<AMessage> info = mCurrentSourceInfo.mSource->getTrackInfo(trackIndex);
-                    if (info != NULL
-                            && info->findInt32("type", &type)
-                            && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
-                        ++mTimedTextGeneration;
-                    }
-                }
-            } else {
-                trackIndex -= inbandTracks;
-
-                if (trackIndex < ccTracks) {
-                    err = mCCDecoder->selectTrack(trackIndex, select);
-                }
-            }
-
-            sp<AMessage> response = new AMessage;
-            response->setInt32("err", err);
-
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatPollDuration:
-        {
-            int32_t generation;
-            CHECK(msg->findInt32("generation", &generation));
-
-            if (generation != mPollDurationGeneration) {
-                // stale
-                break;
-            }
-
-            int64_t durationUs;
-            if (mDriver != NULL && mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
-                sp<NuPlayer2Driver> driver = mDriver.promote();
-                if (driver != NULL) {
-                    driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
-                }
-            }
-
-            msg->post(1000000LL);  // poll again in a second.
-            break;
-        }
-
-        case kWhatSetVideoSurface:
-        {
-
-            sp<RefBase> obj;
-            CHECK(msg->findObject("surface", &obj));
-            sp<ANativeWindowWrapper> nww = static_cast<ANativeWindowWrapper *>(obj.get());
-
-            ALOGD("onSetVideoSurface(%p, %s video decoder)",
-                    (nww == NULL ? NULL : nww->getANativeWindow()),
-                    (mCurrentSourceInfo.mSource != NULL && mStarted
-                            && mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL
-                            && mVideoDecoder != NULL) ? "have" : "no");
-
-            // Need to check mStarted before calling mCurrentSourceInfo.mSource->getFormat
-            // because NuPlayer2 might be in preparing state and it could take long time.
-            // When mStarted is true, mCurrentSourceInfo.mSource must have been set.
-            if (mCurrentSourceInfo.mSource == NULL || !mStarted
-                    || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
-                    // NOTE: mVideoDecoder's mNativeWindow is always non-null
-                    || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(nww) == OK)) {
-                performSetSurface(nww);
-                break;
-            }
-
-            mDeferredActions.push_back(
-                    new FlushDecoderAction(
-                            (obj != NULL ? FLUSH_CMD_FLUSH : FLUSH_CMD_NONE) /* audio */,
-                                           FLUSH_CMD_SHUTDOWN /* video */));
-
-            mDeferredActions.push_back(new SetSurfaceAction(nww));
-
-            if (obj != NULL) {
-                if (mStarted) {
-                    // Issue a seek to refresh the video screen only if started otherwise
-                    // the extractor may not yet be started and will assert.
-                    // If the video decoder is not set (perhaps audio only in this case)
-                    // do not perform a seek as it is not needed.
-                    int64_t currentPositionUs = 0;
-                    if (getCurrentPosition(&currentPositionUs) == OK) {
-                        mDeferredActions.push_back(
-                                new SeekAction(currentPositionUs,
-                                        MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */));
-                    }
-                }
-
-                // If there is a new surface texture, instantiate decoders
-                // again if possible.
-                mDeferredActions.push_back(
-                        new SimpleAction(&NuPlayer2::performScanSources));
-
-                // After a flush without shutdown, decoder is paused.
-                // Don't resume it until source seek is done, otherwise it could
-                // start pulling stale data too soon.
-                mDeferredActions.push_back(
-                        new ResumeDecoderAction(false /* needNotify */));
-            }
-
-            processDeferredActions();
-            break;
-        }
-
-        case kWhatSetAudioSink:
-        {
-            ALOGV("kWhatSetAudioSink");
-
-            sp<RefBase> obj;
-            CHECK(msg->findObject("sink", &obj));
-
-            mAudioSink = static_cast<MediaPlayer2Interface::AudioSink *>(obj.get());
-            break;
-        }
-
-        case kWhatStart:
-        {
-            ALOGV("kWhatStart");
-            if (mStarted) {
-                // do not resume yet if the source is still buffering
-                if (!mPausedForBuffering) {
-                    onResume();
-                }
-            } else {
-                onStart(true /* play */);
-            }
-            mPausedByClient = false;
-            notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
-            break;
-        }
-
-        case kWhatConfigPlayback:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-            AudioPlaybackRate rate /* sanitized */;
-            readFromAMessage(msg, &rate);
-            status_t err = OK;
-            if (mRenderer != NULL) {
-                // AudioSink allows only 1.f and 0.f for offload mode.
-                // For other speed, switch to non-offload mode.
-                if (mOffloadAudio && (rate.mSpeed != 1.f || rate.mPitch != 1.f)) {
-                    int64_t currentPositionUs;
-                    if (getCurrentPosition(&currentPositionUs) != OK) {
-                        currentPositionUs = mPreviousSeekTimeUs;
-                    }
-
-                    // Set mPlaybackSettings so that the new audio decoder can
-                    // be created correctly.
-                    mPlaybackSettings = rate;
-                    if (!mPaused) {
-                        mRenderer->pause();
-                    }
-                    restartAudio(
-                            currentPositionUs, true /* forceNonOffload */,
-                            true /* needsToCreateAudioDecoder */);
-                    if (!mPaused) {
-                        mRenderer->resume();
-                    }
-                }
-
-                err = mRenderer->setPlaybackSettings(rate);
-            }
-            if (err == OK) {
-                mPlaybackSettings = rate;
-
-                if (mVideoDecoder != NULL) {
-                    sp<AMessage> params = new AMessage();
-                    params->setFloat("playback-speed", mPlaybackSettings.mSpeed);
-                    mVideoDecoder->setParameters(params);
-                }
-            }
-
-            sp<AMessage> response = new AMessage;
-            response->setInt32("err", err);
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatGetPlaybackSettings:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-            AudioPlaybackRate rate = mPlaybackSettings;
-            status_t err = OK;
-            if (mRenderer != NULL) {
-                err = mRenderer->getPlaybackSettings(&rate);
-            }
-            if (err == OK) {
-                // get playback settings used by renderer, as it may be
-                // slightly off due to audiosink not taking small changes.
-                mPlaybackSettings = rate;
-            }
-            sp<AMessage> response = new AMessage;
-            if (err == OK) {
-                writeToAMessage(response, rate);
-            }
-            response->setInt32("err", err);
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatConfigSync:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-
-            ALOGV("kWhatConfigSync");
-            AVSyncSettings sync;
-            float videoFpsHint;
-            readFromAMessage(msg, &sync, &videoFpsHint);
-            status_t err = OK;
-            if (mRenderer != NULL) {
-                err = mRenderer->setSyncSettings(sync, videoFpsHint);
-            }
-            if (err == OK) {
-                mSyncSettings = sync;
-                mVideoFpsHint = videoFpsHint;
-            }
-            sp<AMessage> response = new AMessage;
-            response->setInt32("err", err);
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatGetSyncSettings:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-            AVSyncSettings sync = mSyncSettings;
-            float videoFps = mVideoFpsHint;
-            status_t err = OK;
-            if (mRenderer != NULL) {
-                err = mRenderer->getSyncSettings(&sync, &videoFps);
-                if (err == OK) {
-                    mSyncSettings = sync;
-                    mVideoFpsHint = videoFps;
-                }
-            }
-            sp<AMessage> response = new AMessage;
-            if (err == OK) {
-                writeToAMessage(response, sync, videoFps);
-            }
-            response->setInt32("err", err);
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatScanSources:
-        {
-            int32_t generation;
-            CHECK(msg->findInt32("generation", &generation));
-            if (generation != mScanSourcesGeneration) {
-                // Drop obsolete msg.
-                break;
-            }
-
-            mScanSourcesPending = false;
-
-            ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
-                 mAudioDecoder != NULL, mVideoDecoder != NULL);
-
-            bool mHadAnySourcesBefore =
-                (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
-            bool rescan = false;
-
-            // initialize video before audio because successful initialization of
-            // video may change deep buffer mode of audio.
-            if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
-                if (instantiateDecoder(false, &mVideoDecoder) == -EWOULDBLOCK) {
-                    rescan = true;
-                }
-            }
-
-            // Don't try to re-open audio sink if there's an existing decoder.
-            if (mAudioSink != NULL && mAudioDecoder == NULL) {
-                if (instantiateDecoder(true, &mAudioDecoder) == -EWOULDBLOCK) {
-                    rescan = true;
-                }
-            }
-
-            if (!mHadAnySourcesBefore
-                    && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
-                // This is the first time we've found anything playable.
-
-                if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
-                    schedulePollDuration();
-                }
-            }
-
-            status_t err;
-            if ((err = mCurrentSourceInfo.mSource->feedMoreTSData()) != OK) {
-                if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
-                    // We're not currently decoding anything (no audio or
-                    // video tracks found) and we just ran out of input data.
-
-                    if (err == ERROR_END_OF_STREAM) {
-                        notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
-                    } else {
-                        notifyListener(
-                                mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
-                    }
-                }
-                break;
-            }
-
-            if (rescan) {
-                msg->post(100000LL);
-                mScanSourcesPending = true;
-            }
-            break;
-        }
-
-        case kWhatVideoNotify:
-        case kWhatAudioNotify:
-        {
-            bool audio = msg->what() == kWhatAudioNotify;
-
-            int32_t currentDecoderGeneration =
-                (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
-            int32_t requesterGeneration = currentDecoderGeneration - 1;
-            CHECK(msg->findInt32("generation", &requesterGeneration));
-
-            if (requesterGeneration != currentDecoderGeneration) {
-                ALOGV("got message from old %s decoder, generation(%d:%d)",
-                        audio ? "audio" : "video", requesterGeneration,
-                        currentDecoderGeneration);
-                sp<AMessage> reply;
-                if (!(msg->findMessage("reply", &reply))) {
-                    return;
-                }
-
-                reply->setInt32("err", INFO_DISCONTINUITY);
-                reply->post();
-                return;
-            }
-
-            int32_t what;
-            CHECK(msg->findInt32("what", &what));
-
-            if (what == DecoderBase::kWhatInputDiscontinuity) {
-                int32_t formatChange;
-                CHECK(msg->findInt32("formatChange", &formatChange));
-
-                ALOGV("%s discontinuity: formatChange %d",
-                        audio ? "audio" : "video", formatChange);
-
-                if (formatChange) {
-                    mDeferredActions.push_back(
-                            new FlushDecoderAction(
-                                audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
-                                audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
-                }
-
-                mDeferredActions.push_back(
-                        new SimpleAction(
-                                &NuPlayer2::performScanSources));
-
-                processDeferredActions();
-            } else if (what == DecoderBase::kWhatEOS) {
-                int32_t err;
-                CHECK(msg->findInt32("err", &err));
-
-                if (err == ERROR_END_OF_STREAM) {
-                    ALOGV("got %s decoder EOS", audio ? "audio" : "video");
-                } else {
-                    ALOGV("got %s decoder EOS w/ error %d",
-                         audio ? "audio" : "video",
-                         err);
-                }
-
-                mRenderer->queueEOS(audio, err);
-            } else if (what == DecoderBase::kWhatFlushCompleted) {
-                ALOGV("decoder %s flush completed", audio ? "audio" : "video");
-
-                handleFlushComplete(audio, true /* isDecoder */);
-                finishFlushIfPossible();
-            } else if (what == DecoderBase::kWhatVideoSizeChanged) {
-                sp<AMessage> format;
-                CHECK(msg->findMessage("format", &format));
-
-                sp<AMessage> inputFormat =
-                        mCurrentSourceInfo.mSource->getFormat(false /* audio */);
-
-                setVideoScalingMode(mVideoScalingMode);
-                updateVideoSize(mCurrentSourceInfo.mSrcId, inputFormat, format);
-            } else if (what == DecoderBase::kWhatShutdownCompleted) {
-                ALOGV("%s shutdown completed", audio ? "audio" : "video");
-                if (audio) {
-                    Mutex::Autolock autoLock(mDecoderLock);
-                    mAudioDecoder.clear();
-                    mAudioDecoderError = false;
-                    ++mAudioDecoderGeneration;
-
-                    CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
-                    mFlushingAudio = SHUT_DOWN;
-                } else {
-                    Mutex::Autolock autoLock(mDecoderLock);
-                    mVideoDecoder.clear();
-                    mVideoDecoderError = false;
-                    ++mVideoDecoderGeneration;
-
-                    CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
-                    mFlushingVideo = SHUT_DOWN;
-                }
-
-                finishFlushIfPossible();
-            } else if (what == DecoderBase::kWhatResumeCompleted) {
-                finishResume();
-            } else if (what == DecoderBase::kWhatError) {
-                status_t err;
-                if (!msg->findInt32("err", &err) || err == OK) {
-                    err = UNKNOWN_ERROR;
-                }
-
-                // Decoder errors can be due to Source (e.g. from streaming),
-                // or from decoding corrupted bitstreams, or from other decoder
-                // MediaCodec operations (e.g. from an ongoing reset or seek).
-                // They may also be due to openAudioSink failure at
-                // decoder start or after a format change.
-                //
-                // We try to gracefully shut down the affected decoder if possible,
-                // rather than trying to force the shutdown with something
-                // similar to performReset(). This method can lead to a hang
-                // if MediaCodec functions block after an error, but they should
-                // typically return INVALID_OPERATION instead of blocking.
-
-                FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo;
-                ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down",
-                        err, audio ? "audio" : "video", *flushing);
-
-                switch (*flushing) {
-                    case NONE:
-                        mDeferredActions.push_back(
-                                new FlushDecoderAction(
-                                    audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
-                                    audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
-                        processDeferredActions();
-                        break;
-                    case FLUSHING_DECODER:
-                        *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush.
-                        break; // Wait for flush to complete.
-                    case FLUSHING_DECODER_SHUTDOWN:
-                        break; // Wait for flush to complete.
-                    case SHUTTING_DOWN_DECODER:
-                        break; // Wait for shutdown to complete.
-                    case FLUSHED:
-                        getDecoder(audio)->initiateShutdown(); // In the middle of a seek.
-                        *flushing = SHUTTING_DOWN_DECODER;     // Shut down.
-                        break;
-                    case SHUT_DOWN:
-                        finishFlushIfPossible();  // Should not occur.
-                        break;                    // Finish anyways.
-                }
-                if (mCurrentSourceInfo.mSource != nullptr) {
-                    if (audio) {
-                        if (mVideoDecoderError
-                                || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
-                                || mNativeWindow == NULL
-                                || mNativeWindow->getANativeWindow() == NULL
-                                || mVideoDecoder == NULL) {
-                            // When both audio and video have error, or this stream has only audio
-                            // which has error, notify client of error.
-                            notifyListener(
-                                    mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
-                                    MEDIA2_ERROR_UNKNOWN, err);
-                        } else {
-                            // Only audio track has error. Video track could be still good to play.
-                            notifyListener(
-                                    mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
-                                    MEDIA2_INFO_PLAY_AUDIO_ERROR, err);
-                        }
-                        mAudioDecoderError = true;
-                    } else {
-                        if (mAudioDecoderError
-                                || mCurrentSourceInfo.mSource->getFormat(true /* audio */) == NULL
-                                || mAudioSink == NULL || mAudioDecoder == NULL) {
-                            // When both audio and video have error, or this stream has only video
-                            // which has error, notify client of error.
-                            notifyListener(
-                                    mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
-                                    MEDIA2_ERROR_UNKNOWN, err);
-                        } else {
-                            // Only video track has error. Audio track could be still good to play.
-                            notifyListener(
-                                    mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
-                                    MEDIA2_INFO_PLAY_VIDEO_ERROR, err);
-                        }
-                        mVideoDecoderError = true;
-                    }
-                }
-            } else {
-                ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
-                      what,
-                      what >> 24,
-                      (what >> 16) & 0xff,
-                      (what >> 8) & 0xff,
-                      what & 0xff);
-            }
-
-            break;
-        }
-
-        case kWhatRendererNotify:
-        {
-            int32_t requesterGeneration = mRendererGeneration - 1;
-            CHECK(msg->findInt32("generation", &requesterGeneration));
-            if (requesterGeneration != mRendererGeneration) {
-                ALOGV("got message from old renderer, generation(%d:%d)",
-                        requesterGeneration, mRendererGeneration);
-                return;
-            }
-
-            int32_t what;
-            CHECK(msg->findInt32("what", &what));
-
-            if (what == Renderer::kWhatEOS) {
-                int32_t audio;
-                CHECK(msg->findInt32("audio", &audio));
-
-                int32_t finalResult;
-                CHECK(msg->findInt32("finalResult", &finalResult));
-
-                if (audio) {
-                    mAudioEOS = true;
-                } else {
-                    mVideoEOS = true;
-                }
-
-                if (finalResult == ERROR_END_OF_STREAM) {
-                    ALOGV("reached %s EOS", audio ? "audio" : "video");
-                } else {
-                    ALOGE("%s track encountered an error (%d)",
-                         audio ? "audio" : "video", finalResult);
-
-                    notifyListener(
-                            mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
-                            MEDIA2_ERROR_UNKNOWN, finalResult);
-                }
-
-                if ((mAudioEOS || mAudioDecoder == NULL)
-                        && (mVideoEOS || mVideoDecoder == NULL)) {
-                    notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
-                }
-            } else if (what == Renderer::kWhatFlushComplete) {
-                int32_t audio;
-                CHECK(msg->findInt32("audio", &audio));
-
-                if (audio) {
-                    mAudioEOS = false;
-                } else {
-                    mVideoEOS = false;
-                }
-
-                ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
-                if (audio && (mFlushingAudio == NONE || mFlushingAudio == FLUSHED
-                        || mFlushingAudio == SHUT_DOWN)) {
-                    // Flush has been handled by tear down.
-                    break;
-                }
-                handleFlushComplete(audio, false /* isDecoder */);
-                finishFlushIfPossible();
-            } else if (what == Renderer::kWhatVideoRenderingStart) {
-                notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
-                               MEDIA2_INFO_VIDEO_RENDERING_START, 0);
-            } else if (what == Renderer::kWhatMediaRenderingStart) {
-                ALOGV("media rendering started");
-                notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
-            } else if (what == Renderer::kWhatAudioTearDown) {
-                int32_t reason;
-                CHECK(msg->findInt32("reason", &reason));
-                ALOGV("Tear down audio with reason %d.", reason);
-                if (reason == Renderer::kDueToTimeout && !(mPaused && mOffloadAudio)) {
-                    // TimeoutWhenPaused is only for offload mode.
-                    ALOGW("Receive a stale message for teardown.");
-                    break;
-                }
-                int64_t positionUs;
-                if (!msg->findInt64("positionUs", &positionUs)) {
-                    positionUs = mPreviousSeekTimeUs;
-                }
-
-                restartAudio(
-                        positionUs, reason == Renderer::kForceNonOffload /* forceNonOffload */,
-                        reason != Renderer::kDueToTimeout /* needsToCreateAudioDecoder */);
-            }
-            break;
-        }
-
-        case kWhatMoreDataQueued:
-        {
-            break;
-        }
-
-        case kWhatReset:
-        {
-            ALOGV("kWhatReset");
-
-            mResetting = true;
-            stopPlaybackTimer("kWhatReset");
-            stopRebufferingTimer(true);
-
-            mDeferredActions.push_back(
-                    new FlushDecoderAction(
-                        FLUSH_CMD_SHUTDOWN /* audio */,
-                        FLUSH_CMD_SHUTDOWN /* video */));
-
-            mDeferredActions.push_back(
-                    new SimpleAction(&NuPlayer2::performReset));
-
-            processDeferredActions();
-            break;
-        }
-
-        case kWhatNotifyTime:
-        {
-            ALOGV("kWhatNotifyTime");
-            int64_t timerUs;
-            CHECK(msg->findInt64("timerUs", &timerUs));
-
-            notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_NOTIFY_TIME, timerUs, 0);
-            break;
-        }
-
-        case kWhatSeek:
-        {
-            int64_t seekTimeUs;
-            int32_t mode;
-            int32_t needNotify;
-            CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
-            CHECK(msg->findInt32("mode", &mode));
-            CHECK(msg->findInt32("needNotify", &needNotify));
-
-            ALOGV("kWhatSeek seekTimeUs=%lld us, mode=%d, needNotify=%d",
-                    (long long)seekTimeUs, mode, needNotify);
-
-            if (!mStarted) {
-                if (!mSourceStarted) {
-                    mSourceStarted = true;
-                    mCurrentSourceInfo.mSource->start();
-                }
-                if (seekTimeUs > 0) {
-                    performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
-                }
-
-                if (needNotify) {
-                    notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
-                }
-                break;
-            }
-
-            // seeks can take a while, so we essentially paused
-            notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
-
-            mDeferredActions.push_back(
-                    new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
-                                           FLUSH_CMD_FLUSH /* video */));
-
-            mDeferredActions.push_back(
-                    new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
-
-            // After a flush without shutdown, decoder is paused.
-            // Don't resume it until source seek is done, otherwise it could
-            // start pulling stale data too soon.
-            mDeferredActions.push_back(
-                    new ResumeDecoderAction(needNotify));
-
-            processDeferredActions();
-            break;
-        }
-
-        case kWhatRewind:
-        {
-            ALOGV("kWhatRewind");
-
-            int64_t seekTimeUs = mCurrentSourceInfo.mStartTimeUs;
-            int32_t mode = MediaPlayer2SeekMode::SEEK_CLOSEST;
-
-            if (!mStarted) {
-                if (!mSourceStarted) {
-                    mSourceStarted = true;
-                    mCurrentSourceInfo.mSource->start();
-                }
-                performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
-                break;
-            }
-
-            // seeks can take a while, so we essentially paused
-            notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
-
-            mDeferredActions.push_back(
-                    new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
-                                           FLUSH_CMD_FLUSH /* video */));
-
-            mDeferredActions.push_back(
-                    new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
-
-            // After a flush without shutdown, decoder is paused.
-            // Don't resume it until source seek is done, otherwise it could
-            // start pulling stale data too soon.
-            mDeferredActions.push_back(
-                    new ResumeDecoderAction(false /* needNotify */));
-
-            processDeferredActions();
-            break;
-        }
-
-        case kWhatPause:
-        {
-            if (!mStarted) {
-                onStart(false /* play */);
-            }
-            onPause();
-            notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
-            mPausedByClient = true;
-            break;
-        }
-
-        case kWhatSourceNotify:
-        {
-            onSourceNotify(msg);
-            break;
-        }
-
-        case kWhatClosedCaptionNotify:
-        {
-            onClosedCaptionNotify(msg);
-            break;
-        }
-
-        case kWhatPrepareDrm:
-        {
-            status_t status = onPrepareDrm(msg);
-
-            sp<AMessage> response = new AMessage;
-            response->setInt32("status", status);
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatReleaseDrm:
-        {
-            status_t status = onReleaseDrm(msg);
-
-            sp<AMessage> response = new AMessage;
-            response->setInt32("status", status);
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-            response->postReply(replyID);
-            break;
-        }
-
-        default:
-            TRESPASS();
-            break;
-    }
-}
-
-void NuPlayer2::onResume() {
-    if (!mPaused || mResetting) {
-        ALOGD_IF(mResetting, "resetting, onResume discarded");
-        return;
-    }
-    mPaused = false;
-    if (mCurrentSourceInfo.mSource != NULL) {
-        mCurrentSourceInfo.mSource->resume();
-    } else {
-        ALOGW("resume called when source is gone or not set");
-    }
-    // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
-    // needed.
-    if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
-        instantiateDecoder(true /* audio */, &mAudioDecoder);
-    }
-    if (mRenderer != NULL) {
-        mRenderer->resume();
-    } else {
-        ALOGW("resume called when renderer is gone or not set");
-    }
-
-    startPlaybackTimer("onresume");
-}
-
-void NuPlayer2::onStart(bool play) {
-    ALOGV("onStart: mCrypto: %p", mCurrentSourceInfo.mCrypto.get());
-
-    if (!mSourceStarted) {
-        mSourceStarted = true;
-        mCurrentSourceInfo.mSource->start();
-    }
-
-    mOffloadAudio = false;
-    mAudioEOS = false;
-    mVideoEOS = false;
-    mStarted = true;
-    mPaused = false;
-
-    uint32_t flags = 0;
-
-    if (mCurrentSourceInfo.mSource->isRealTime()) {
-        flags |= Renderer::FLAG_REAL_TIME;
-    }
-
-    bool hasAudio = (mCurrentSourceInfo.mSource->getFormat(true /* audio */) != NULL);
-    bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL);
-    if (!hasAudio && !hasVideo) {
-        ALOGE("no metadata for either audio or video source");
-        mCurrentSourceInfo.mSource->stop();
-        mSourceStarted = false;
-        notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
-                       MEDIA2_ERROR_UNKNOWN, ERROR_MALFORMED);
-        return;
-    }
-    ALOGV_IF(!hasAudio, "no metadata for audio source");  // video only stream
-
-    sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
-
-    audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
-    if (mAudioSink != NULL) {
-        streamType = mAudioSink->getAudioStreamType();
-    }
-
-    mOffloadAudio =
-        JMediaPlayer2Utils::isOffloadedAudioPlaybackSupported(
-                audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
-                && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
-
-    // Modular DRM: Disabling audio offload if the source is protected
-    if (mOffloadAudio && mCurrentSourceInfo.mIsDrmProtected) {
-        mOffloadAudio = false;
-        ALOGV("onStart: Disabling mOffloadAudio now that the source is protected.");
-    }
-
-    if (mOffloadAudio) {
-        flags |= Renderer::FLAG_OFFLOAD_AUDIO;
-    }
-
-    sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
-    ++mRendererGeneration;
-    notify->setInt32("generation", mRendererGeneration);
-    mRenderer = new Renderer(mAudioSink, mMediaClock, notify, mContext, flags);
-    mRendererLooper = new ALooper;
-    mRendererLooper->setName("NuPlayer2Renderer");
-    mRendererLooper->start(false, true, ANDROID_PRIORITY_AUDIO);
-    mRendererLooper->registerHandler(mRenderer);
-
-    status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings);
-    if (err != OK) {
-        mCurrentSourceInfo.mSource->stop();
-        mSourceStarted = false;
-        notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
-        return;
-    }
-
-    float rate = getFrameRate();
-    if (rate > 0) {
-        mRenderer->setVideoFrameRate(rate);
-    }
-
-    addEndTimeMonitor();
-    // Renderer is created in paused state.
-    if (play) {
-        mRenderer->resume();
-    }
-
-    if (mVideoDecoder != NULL) {
-        mVideoDecoder->setRenderer(mRenderer);
-    }
-    if (mAudioDecoder != NULL) {
-        mAudioDecoder->setRenderer(mRenderer);
-    }
-
-    startPlaybackTimer("onstart");
-    notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
-
-    postScanSources();
-}
-
-void NuPlayer2::addEndTimeMonitor() {
-    ++mEOSMonitorGeneration;
-
-    if (mCurrentSourceInfo.mEndTimeUs == DataSourceDesc::kMaxTimeUs) {
-        return;
-    }
-
-    sp<AMessage> msg = new AMessage(kWhatEOSMonitor, this);
-    msg->setInt32("generation", mEOSMonitorGeneration);
-    mMediaClock->addTimer(msg, mCurrentSourceInfo.mEndTimeUs);
-}
-
-void NuPlayer2::startPlaybackTimer(const char *where) {
-    Mutex::Autolock autoLock(mPlayingTimeLock);
-    if (mLastStartedPlayingTimeNs == 0) {
-        mLastStartedPlayingTimeNs = systemTime();
-        ALOGV("startPlaybackTimer() time %20" PRId64 " (%s)",  mLastStartedPlayingTimeNs, where);
-    }
-}
-
-void NuPlayer2::stopPlaybackTimer(const char *where) {
-    Mutex::Autolock autoLock(mPlayingTimeLock);
-
-    ALOGV("stopPlaybackTimer()  time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
-
-    if (mLastStartedPlayingTimeNs != 0) {
-        sp<NuPlayer2Driver> driver = mDriver.promote();
-        if (driver != NULL) {
-            int64_t now = systemTime();
-            int64_t played = now - mLastStartedPlayingTimeNs;
-            ALOGV("stopPlaybackTimer()  log  %20" PRId64 "", played);
-
-            if (played > 0) {
-                driver->notifyMorePlayingTimeUs(mCurrentSourceInfo.mSrcId, (played+500)/1000);
-            }
-        }
-        mLastStartedPlayingTimeNs = 0;
-    }
-}
-
-void NuPlayer2::startRebufferingTimer() {
-    Mutex::Autolock autoLock(mPlayingTimeLock);
-    if (mLastStartedRebufferingTimeNs == 0) {
-        mLastStartedRebufferingTimeNs = systemTime();
-        ALOGV("startRebufferingTimer() time %20" PRId64 "",  mLastStartedRebufferingTimeNs);
-    }
-}
-
-void NuPlayer2::stopRebufferingTimer(bool exitingPlayback) {
-    Mutex::Autolock autoLock(mPlayingTimeLock);
-
-    ALOGV("stopRebufferTimer()  time %20" PRId64 " (exiting %d)",
-          mLastStartedRebufferingTimeNs, exitingPlayback);
-
-    if (mLastStartedRebufferingTimeNs != 0) {
-        sp<NuPlayer2Driver> driver = mDriver.promote();
-        if (driver != NULL) {
-            int64_t now = systemTime();
-            int64_t rebuffered = now - mLastStartedRebufferingTimeNs;
-            ALOGV("stopRebufferingTimer()  log  %20" PRId64 "", rebuffered);
-
-            if (rebuffered > 0) {
-                driver->notifyMoreRebufferingTimeUs(
-                        mCurrentSourceInfo.mSrcId, (rebuffered+500)/1000);
-                if (exitingPlayback) {
-                    driver->notifyRebufferingWhenExit(mCurrentSourceInfo.mSrcId, true);
-                }
-            }
-        }
-        mLastStartedRebufferingTimeNs = 0;
-    }
-}
-
-void NuPlayer2::onPause() {
-
-    stopPlaybackTimer("onPause");
-
-    if (mPaused) {
-        return;
-    }
-    mPaused = true;
-    if (mCurrentSourceInfo.mSource != NULL) {
-        mCurrentSourceInfo.mSource->pause();
-    } else {
-        ALOGW("pause called when source is gone or not set");
-    }
-    if (mRenderer != NULL) {
-        mRenderer->pause();
-    } else {
-        ALOGW("pause called when renderer is gone or not set");
-    }
-
-}
-
-bool NuPlayer2::audioDecoderStillNeeded() {
-    // Audio decoder is no longer needed if it's in shut/shutting down status.
-    return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
-}
-
-void NuPlayer2::handleFlushComplete(bool audio, bool isDecoder) {
-    // We wait for both the decoder flush and the renderer flush to complete
-    // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
-
-    mFlushComplete[audio][isDecoder] = true;
-    if (!mFlushComplete[audio][!isDecoder]) {
-        return;
-    }
-
-    FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
-    switch (*state) {
-        case FLUSHING_DECODER:
-        {
-            *state = FLUSHED;
-            break;
-        }
-
-        case FLUSHING_DECODER_SHUTDOWN:
-        {
-            *state = SHUTTING_DOWN_DECODER;
-
-            ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
-            getDecoder(audio)->initiateShutdown();
-            break;
-        }
-
-        default:
-            // decoder flush completes only occur in a flushing state.
-            LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
-            break;
-    }
-}
-
-void NuPlayer2::finishFlushIfPossible() {
-    if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
-            && mFlushingAudio != SHUT_DOWN) {
-        return;
-    }
-
-    if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
-            && mFlushingVideo != SHUT_DOWN) {
-        return;
-    }
-
-    ALOGV("both audio and video are flushed now.");
-
-    mFlushingAudio = NONE;
-    mFlushingVideo = NONE;
-
-    clearFlushComplete();
-
-    processDeferredActions();
-}
-
-void NuPlayer2::postScanSources() {
-    if (mScanSourcesPending) {
-        return;
-    }
-
-    sp<AMessage> msg = new AMessage(kWhatScanSources, this);
-    msg->setInt32("generation", mScanSourcesGeneration);
-    msg->post();
-
-    mScanSourcesPending = true;
-}
-
-void NuPlayer2::tryOpenAudioSinkForOffload(
-        const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo) {
-    // Note: This is called early in NuPlayer2 to determine whether offloading
-    // is possible; otherwise the decoders call the renderer openAudioSink directly.
-
-    status_t err = mRenderer->openAudioSink(
-            format, true /* offloadOnly */, hasVideo,
-            AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mCurrentSourceInfo.mSource->isStreaming());
-    if (err != OK) {
-        // Any failure we turn off mOffloadAudio.
-        mOffloadAudio = false;
-    } else if (mOffloadAudio) {
-        sendMetaDataToHal(mAudioSink, audioMeta);
-    }
-}
-
-void NuPlayer2::closeAudioSink() {
-    mRenderer->closeAudioSink();
-}
-
-void NuPlayer2::restartAudio(
-        int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) {
-    if (mAudioDecoder != NULL) {
-        mAudioDecoder->pause();
-        Mutex::Autolock autoLock(mDecoderLock);
-        mAudioDecoder.clear();
-        mAudioDecoderError = false;
-        ++mAudioDecoderGeneration;
-    }
-    if (mFlushingAudio == FLUSHING_DECODER) {
-        mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
-        mFlushingAudio = FLUSHED;
-        finishFlushIfPossible();
-    } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN
-            || mFlushingAudio == SHUTTING_DOWN_DECODER) {
-        mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
-        mFlushingAudio = SHUT_DOWN;
-        finishFlushIfPossible();
-        needsToCreateAudioDecoder = false;
-    }
-    if (mRenderer == NULL) {
-        return;
-    }
-    closeAudioSink();
-    mRenderer->flush(true /* audio */, false /* notifyComplete */);
-    if (mVideoDecoder != NULL) {
-        mDeferredActions.push_back(
-                new FlushDecoderAction(FLUSH_CMD_NONE /* audio */,
-                                       FLUSH_CMD_FLUSH /* video */));
-        mDeferredActions.push_back(
-                new SeekAction(currentPositionUs,
-                MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */));
-        // After a flush without shutdown, decoder is paused.
-        // Don't resume it until source seek is done, otherwise it could
-        // start pulling stale data too soon.
-        mDeferredActions.push_back(new ResumeDecoderAction(false));
-        processDeferredActions();
-    } else {
-        performSeek(currentPositionUs, MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */);
-    }
-
-    if (forceNonOffload) {
-        mRenderer->signalDisableOffloadAudio();
-        mOffloadAudio = false;
-    }
-    if (needsToCreateAudioDecoder) {
-        instantiateDecoder(true /* audio */, &mAudioDecoder, !forceNonOffload);
-    }
-}
-
-void NuPlayer2::determineAudioModeChange(const sp<AMessage> &audioFormat) {
-    if (mCurrentSourceInfo.mSource == NULL || mAudioSink == NULL) {
-        return;
-    }
-
-    if (mRenderer == NULL) {
-        ALOGW("No renderer can be used to determine audio mode. Use non-offload for safety.");
-        mOffloadAudio = false;
-        return;
-    }
-
-    sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
-    sp<AMessage> videoFormat = mCurrentSourceInfo.mSource->getFormat(false /* audio */);
-    audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
-    const bool hasVideo = (videoFormat != NULL);
-    bool canOffload = JMediaPlayer2Utils::isOffloadedAudioPlaybackSupported(
-            audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
-                    && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
-
-    // Modular DRM: Disabling audio offload if the source is protected
-    if (canOffload && mCurrentSourceInfo.mIsDrmProtected) {
-        canOffload = false;
-        ALOGV("determineAudioModeChange: Disabling mOffloadAudio b/c the source is protected.");
-    }
-
-    if (canOffload) {
-        if (!mOffloadAudio) {
-            mRenderer->signalEnableOffloadAudio();
-        }
-        // open audio sink early under offload mode.
-        tryOpenAudioSinkForOffload(audioFormat, audioMeta, hasVideo);
-    } else {
-        if (mOffloadAudio) {
-            mRenderer->signalDisableOffloadAudio();
-            mOffloadAudio = false;
-        }
-    }
-}
-
-status_t NuPlayer2::instantiateDecoder(
-        bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) {
-    // The audio decoder could be cleared by tear down. If still in shut down
-    // process, no need to create a new audio decoder.
-    if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) {
-        return OK;
-    }
-
-    sp<AMessage> format = mCurrentSourceInfo.mSource->getFormat(audio);
-
-    if (format == NULL) {
-        return UNKNOWN_ERROR;
-    } else {
-        status_t err;
-        if (format->findInt32("err", &err) && err) {
-            return err;
-        }
-    }
-
-    format->setInt32("priority", 0 /* realtime */);
-
-    if (!audio) {
-        AString mime;
-        CHECK(format->findString("mime", &mime));
-
-        sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
-        if (mCCDecoder == NULL) {
-            mCCDecoder = new CCDecoder(ccNotify);
-        }
-
-        if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) {
-            format->setInt32("secure", true);
-        }
-
-        if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_PROTECTED) {
-            format->setInt32("protected", true);
-        }
-
-        float rate = getFrameRate();
-        if (rate > 0) {
-            format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
-        }
-    }
-
-    Mutex::Autolock autoLock(mDecoderLock);
-
-    if (audio) {
-        sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
-        ++mAudioDecoderGeneration;
-        notify->setInt32("generation", mAudioDecoderGeneration);
-
-        if (checkAudioModeChange) {
-            determineAudioModeChange(format);
-        }
-        if (mOffloadAudio) {
-            mCurrentSourceInfo.mSource->setOffloadAudio(true /* offload */);
-
-            const bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /*audio */) != NULL);
-            format->setInt32("has-video", hasVideo);
-            *decoder = new DecoderPassThrough(notify, mCurrentSourceInfo.mSource, mRenderer);
-            ALOGV("instantiateDecoder audio DecoderPassThrough  hasVideo: %d", hasVideo);
-        } else {
-            mCurrentSourceInfo.mSource->setOffloadAudio(false /* offload */);
-
-            *decoder = new Decoder(notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer);
-            ALOGV("instantiateDecoder audio Decoder");
-        }
-        mAudioDecoderError = false;
-    } else {
-        sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
-        ++mVideoDecoderGeneration;
-        notify->setInt32("generation", mVideoDecoderGeneration);
-
-        *decoder = new Decoder(
-                notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer, mNativeWindow,
-                mCCDecoder);
-        mVideoDecoderError = false;
-
-        // enable FRC if high-quality AV sync is requested, even if not
-        // directly queuing to display, as this will even improve textureview
-        // playback.
-        {
-            if (property_get_bool("persist.sys.media.avsync", false)) {
-                format->setInt32("auto-frc", 1);
-            }
-        }
-    }
-    (*decoder)->init();
-
-    // Modular DRM
-    if (mCurrentSourceInfo.mIsDrmProtected) {
-        format->setObject("crypto", mCurrentSourceInfo.mCrypto);
-        ALOGV("instantiateDecoder: mCrypto: %p isSecure: %d",
-                mCurrentSourceInfo.mCrypto.get(),
-                (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) != 0);
-    }
-
-    (*decoder)->configure(format);
-
-    if (!audio) {
-        sp<AMessage> params = new AMessage();
-        float rate = getFrameRate();
-        if (rate > 0) {
-            params->setFloat("frame-rate-total", rate);
-        }
-
-        sp<MetaData> fileMeta = getFileMeta();
-        if (fileMeta != NULL) {
-            int32_t videoTemporalLayerCount;
-            if (fileMeta->findInt32(kKeyTemporalLayerCount, &videoTemporalLayerCount)
-                    && videoTemporalLayerCount > 0) {
-                params->setInt32("temporal-layer-count", videoTemporalLayerCount);
-            }
-        }
-
-        if (params->countEntries() > 0) {
-            (*decoder)->setParameters(params);
-        }
-    }
-    return OK;
-}
-
-void NuPlayer2::updateVideoSize(
-        int64_t srcId,
-        const sp<AMessage> &inputFormat,
-        const sp<AMessage> &outputFormat) {
-    if (inputFormat == NULL) {
-        ALOGW("Unknown video size, reporting 0x0!");
-        notifyListener(srcId, MEDIA2_SET_VIDEO_SIZE, 0, 0);
-        return;
-    }
-    int32_t err = OK;
-    inputFormat->findInt32("err", &err);
-    if (err == -EWOULDBLOCK) {
-        ALOGW("Video meta is not available yet!");
-        return;
-    }
-    if (err != OK) {
-        ALOGW("Something is wrong with video meta!");
-        return;
-    }
-
-    int32_t displayWidth, displayHeight;
-    if (outputFormat != NULL) {
-        int32_t width, height;
-        CHECK(outputFormat->findInt32("width", &width));
-        CHECK(outputFormat->findInt32("height", &height));
-
-        int32_t cropLeft, cropTop, cropRight, cropBottom;
-        CHECK(outputFormat->findRect(
-                    "crop",
-                    &cropLeft, &cropTop, &cropRight, &cropBottom));
-
-        displayWidth = cropRight - cropLeft + 1;
-        displayHeight = cropBottom - cropTop + 1;
-
-        ALOGV("Video output format changed to %d x %d "
-             "(crop: %d x %d @ (%d, %d))",
-             width, height,
-             displayWidth,
-             displayHeight,
-             cropLeft, cropTop);
-    } else {
-        CHECK(inputFormat->findInt32("width", &displayWidth));
-        CHECK(inputFormat->findInt32("height", &displayHeight));
-
-        ALOGV("Video input format %d x %d", displayWidth, displayHeight);
-    }
-
-    // Take into account sample aspect ratio if necessary:
-    int32_t sarWidth, sarHeight;
-    if (inputFormat->findInt32("sar-width", &sarWidth)
-            && inputFormat->findInt32("sar-height", &sarHeight)
-            && sarWidth > 0 && sarHeight > 0) {
-        ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
-
-        displayWidth = (displayWidth * sarWidth) / sarHeight;
-
-        ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
-    } else {
-        int32_t width, height;
-        if (inputFormat->findInt32("display-width", &width)
-                && inputFormat->findInt32("display-height", &height)
-                && width > 0 && height > 0
-                && displayWidth > 0 && displayHeight > 0) {
-            if (displayHeight * (int64_t)width / height > (int64_t)displayWidth) {
-                displayHeight = (int32_t)(displayWidth * (int64_t)height / width);
-            } else {
-                displayWidth = (int32_t)(displayHeight * (int64_t)width / height);
-            }
-            ALOGV("Video display width and height are overridden to %d x %d",
-                 displayWidth, displayHeight);
-        }
-    }
-
-    int32_t rotationDegrees;
-    if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
-        rotationDegrees = 0;
-    }
-
-    if (rotationDegrees == 90 || rotationDegrees == 270) {
-        int32_t tmp = displayWidth;
-        displayWidth = displayHeight;
-        displayHeight = tmp;
-    }
-
-    notifyListener(
-            srcId,
-            MEDIA2_SET_VIDEO_SIZE,
-            displayWidth,
-            displayHeight);
-}
-
-void NuPlayer2::notifyListener(
-        int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
-    if (mDriver == NULL) {
-        return;
-    }
-
-    sp<NuPlayer2Driver> driver = mDriver.promote();
-
-    if (driver == NULL) {
-        return;
-    }
-
-    driver->notifyListener(srcId, msg, ext1, ext2, in);
-}
-
-void NuPlayer2::flushDecoder(bool audio, bool needShutdown) {
-    ALOGV("[%s] flushDecoder needShutdown=%d",
-          audio ? "audio" : "video", needShutdown);
-
-    const sp<DecoderBase> &decoder = getDecoder(audio);
-    if (decoder == NULL) {
-        ALOGI("flushDecoder %s without decoder present",
-             audio ? "audio" : "video");
-        return;
-    }
-
-    // Make sure we don't continue to scan sources until we finish flushing.
-    ++mScanSourcesGeneration;
-    if (mScanSourcesPending) {
-        if (!needShutdown) {
-            mDeferredActions.push_back(
-                    new SimpleAction(&NuPlayer2::performScanSources));
-        }
-        mScanSourcesPending = false;
-    }
-
-    decoder->signalFlush();
-
-    FlushStatus newStatus =
-        needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
-
-    mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
-    mFlushComplete[audio][true /* isDecoder */] = false;
-    if (audio) {
-        ALOGE_IF(mFlushingAudio != NONE,
-                "audio flushDecoder() is called in state %d", mFlushingAudio);
-        mFlushingAudio = newStatus;
-    } else {
-        ALOGE_IF(mFlushingVideo != NONE,
-                "video flushDecoder() is called in state %d", mFlushingVideo);
-        mFlushingVideo = newStatus;
-    }
-}
-
-void NuPlayer2::queueDecoderShutdown(
-        bool audio, bool video, const sp<AMessage> &reply) {
-    ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
-
-    mDeferredActions.push_back(
-            new FlushDecoderAction(
-                audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
-                video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
-
-    mDeferredActions.push_back(
-            new SimpleAction(&NuPlayer2::performScanSources));
-
-    mDeferredActions.push_back(new PostMessageAction(reply));
-
-    processDeferredActions();
-}
-
-status_t NuPlayer2::setVideoScalingMode(int32_t mode) {
-    mVideoScalingMode = mode;
-    if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
-        status_t ret = native_window_set_scaling_mode(
-                mNativeWindow->getANativeWindow(), mVideoScalingMode);
-        if (ret != OK) {
-            ALOGE("Failed to set scaling mode (%d): %s",
-                -ret, strerror(-ret));
-            return ret;
-        }
-    }
-    return OK;
-}
-
-status_t NuPlayer2::getTrackInfo(int64_t srcId, PlayerMessage* reply) const {
-    sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
-    msg->setInt64("srcId", srcId);
-    msg->setPointer("reply", reply);
-
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    return err;
-}
-
-status_t NuPlayer2::getSelectedTrack(int64_t srcId, int32_t type, PlayerMessage* reply) const {
-    sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
-    msg->setPointer("reply", reply);
-    msg->setInt64("srcId", srcId);
-    msg->setInt32("type", type);
-
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-    }
-    return err;
-}
-
-status_t NuPlayer2::selectTrack(int64_t srcId, size_t trackIndex, bool select, int64_t timeUs) {
-    sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
-    msg->setInt64("srcId", srcId);
-    msg->setSize("trackIndex", trackIndex);
-    msg->setInt32("select", select);
-    msg->setInt64("timeUs", timeUs);
-
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-
-    if (err != OK) {
-        return err;
-    }
-
-    if (!response->findInt32("err", &err)) {
-        err = OK;
-    }
-
-    return err;
-}
-
-status_t NuPlayer2::getCurrentPosition(int64_t *mediaUs) {
-    sp<Renderer> renderer = mRenderer;
-    if (renderer == NULL) {
-        return NO_INIT;
-    }
-
-    return renderer->getCurrentPosition(mediaUs);
-}
-
-void NuPlayer2::getStats(Vector<sp<AMessage> > *mTrackStats) {
-    CHECK(mTrackStats != NULL);
-
-    mTrackStats->clear();
-
-    Mutex::Autolock autoLock(mDecoderLock);
-    if (mVideoDecoder != NULL) {
-        mTrackStats->push_back(mVideoDecoder->getStats());
-    }
-    if (mAudioDecoder != NULL) {
-        mTrackStats->push_back(mAudioDecoder->getStats());
-    }
-}
-
-sp<MetaData> NuPlayer2::getFileMeta() {
-    return mCurrentSourceInfo.mSource->getFileFormatMeta();
-}
-
-float NuPlayer2::getFrameRate() {
-    sp<MetaData> meta = mCurrentSourceInfo.mSource->getFormatMeta(false /* audio */);
-    if (meta == NULL) {
-        return 0;
-    }
-    int32_t rate;
-    if (!meta->findInt32(kKeyFrameRate, &rate)) {
-        // fall back to try file meta
-        sp<MetaData> fileMeta = getFileMeta();
-        if (fileMeta == NULL) {
-            ALOGW("source has video meta but not file meta");
-            return -1;
-        }
-        int32_t fileMetaRate;
-        if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) {
-            return -1;
-        }
-        return fileMetaRate;
-    }
-    return rate;
-}
-
-void NuPlayer2::schedulePollDuration() {
-    sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
-    msg->setInt32("generation", mPollDurationGeneration);
-    msg->post();
-}
-
-void NuPlayer2::cancelPollDuration() {
-    ++mPollDurationGeneration;
-}
-
-void NuPlayer2::processDeferredActions() {
-    while (!mDeferredActions.empty()) {
-        // We won't execute any deferred actions until we're no longer in
-        // an intermediate state, i.e. one more more decoders are currently
-        // flushing or shutting down.
-
-        if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
-            // We're currently flushing, postpone the reset until that's
-            // completed.
-
-            ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
-                  mFlushingAudio, mFlushingVideo);
-
-            break;
-        }
-
-        sp<Action> action = *mDeferredActions.begin();
-        mDeferredActions.erase(mDeferredActions.begin());
-
-        action->execute(this);
-    }
-}
-
-void NuPlayer2::performSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
-    ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
-          (long long)seekTimeUs, seekTimeUs / 1E6, mode);
-
-    if (mCurrentSourceInfo.mSource == NULL) {
-        // This happens when reset occurs right before the loop mode
-        // asynchronously seeks to the start of the stream.
-        LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
-                "mCurrentSourceInfo.mSource is NULL and decoders not NULL audio(%p) video(%p)",
-                mAudioDecoder.get(), mVideoDecoder.get());
-        return;
-    }
-    mPreviousSeekTimeUs = seekTimeUs;
-    mCurrentSourceInfo.mSource->seekTo(seekTimeUs, mode);
-    ++mTimedTextGeneration;
-
-    // everything's flushed, continue playback.
-}
-
-void NuPlayer2::performDecoderFlush(FlushCommand audio, FlushCommand video) {
-    ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
-
-    if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
-            && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
-        return;
-    }
-
-    if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
-        flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
-    }
-
-    if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
-        flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
-    }
-}
-
-void NuPlayer2::performReset() {
-    ALOGV("performReset");
-
-    CHECK(mAudioDecoder == NULL);
-    CHECK(mVideoDecoder == NULL);
-
-    stopPlaybackTimer("performReset");
-    stopRebufferingTimer(true);
-
-    cancelPollDuration();
-
-    ++mScanSourcesGeneration;
-    mScanSourcesPending = false;
-
-    if (mRendererLooper != NULL) {
-        if (mRenderer != NULL) {
-            mRendererLooper->unregisterHandler(mRenderer->id());
-        }
-        mRendererLooper->stop();
-        mRendererLooper.clear();
-    }
-    mRenderer.clear();
-    ++mRendererGeneration;
-
-    resetSourceInfo(mCurrentSourceInfo);
-    resetSourceInfo(mNextSourceInfo);
-
-    if (mDriver != NULL) {
-        sp<NuPlayer2Driver> driver = mDriver.promote();
-        if (driver != NULL) {
-            driver->notifyResetComplete(mCurrentSourceInfo.mSrcId);
-        }
-    }
-
-    mStarted = false;
-    mPrepared = false;
-    mResetting = false;
-    mSourceStarted = false;
-
-}
-
-void NuPlayer2::performPlayNextDataSource() {
-    ALOGV("performPlayNextDataSource");
-
-    CHECK(mAudioDecoder == NULL);
-    CHECK(mVideoDecoder == NULL);
-
-    stopPlaybackTimer("performPlayNextDataSource");
-    stopRebufferingTimer(true);
-
-    cancelPollDuration();
-
-    ++mScanSourcesGeneration;
-    mScanSourcesPending = false;
-
-    ++mRendererGeneration;
-
-    if (mCurrentSourceInfo.mSource != NULL) {
-        mCurrentSourceInfo.mSource->stop();
-    }
-
-    long previousSrcId;
-    {
-        Mutex::Autolock autoLock(mSourceLock);
-        previousSrcId = mCurrentSourceInfo.mSrcId;
-
-        mCurrentSourceInfo = mNextSourceInfo;
-        mNextSourceInfo = SourceInfo();
-        mNextSourceInfo.mSrcId = ~mCurrentSourceInfo.mSrcId;  // to distinguish the two sources.
-    }
-
-    if (mDriver != NULL) {
-        sp<NuPlayer2Driver> driver = mDriver.promote();
-        if (driver != NULL) {
-            notifyListener(previousSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_END, 0);
-
-            int64_t durationUs;
-            if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
-                driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
-            }
-            notifyListener(
-                    mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
-        }
-    }
-
-    mStarted = false;
-    mPrepared = true;  // TODO: what if it's not prepared
-    mResetting = false;
-    mSourceStarted = false;
-
-    addEndTimeMonitor();
-
-    if (mRenderer != NULL) {
-        mRenderer->resume();
-    }
-
-    onStart(true /* play */);
-    mPausedByClient = false;
-    notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
-}
-
-void NuPlayer2::performScanSources() {
-    ALOGV("performScanSources");
-
-    if (!mStarted) {
-        return;
-    }
-
-    if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
-        postScanSources();
-    }
-}
-
-void NuPlayer2::performSetSurface(const sp<ANativeWindowWrapper> &nww) {
-    ALOGV("performSetSurface");
-
-    mNativeWindow = nww;
-
-    // XXX - ignore error from setVideoScalingMode for now
-    setVideoScalingMode(mVideoScalingMode);
-
-    if (mDriver != NULL) {
-        sp<NuPlayer2Driver> driver = mDriver.promote();
-        if (driver != NULL) {
-            driver->notifySetSurfaceComplete(mCurrentSourceInfo.mSrcId);
-        }
-    }
-}
-
-void NuPlayer2::performResumeDecoders(bool needNotify) {
-    if (needNotify) {
-        mResumePending = true;
-        if (mVideoDecoder == NULL) {
-            // if audio-only, we can notify seek complete now,
-            // as the resume operation will be relatively fast.
-            finishResume();
-        }
-    }
-
-    if (mVideoDecoder != NULL) {
-        // When there is continuous seek, MediaPlayer will cache the seek
-        // position, and send down new seek request when previous seek is
-        // complete. Let's wait for at least one video output frame before
-        // notifying seek complete, so that the video thumbnail gets updated
-        // when seekbar is dragged.
-        mVideoDecoder->signalResume(needNotify);
-    }
-
-    if (mAudioDecoder != NULL) {
-        mAudioDecoder->signalResume(false /* needNotify */);
-    }
-}
-
-void NuPlayer2::finishResume() {
-    if (mResumePending) {
-        mResumePending = false;
-        notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
-    }
-}
-
-void NuPlayer2::notifyDriverSeekComplete(int64_t srcId) {
-    if (mDriver != NULL) {
-        sp<NuPlayer2Driver> driver = mDriver.promote();
-        if (driver != NULL) {
-            driver->notifySeekComplete(srcId);
-        }
-    }
-}
-
-void NuPlayer2::onSourceNotify(const sp<AMessage> &msg) {
-    int32_t what;
-    CHECK(msg->findInt32("what", &what));
-
-    int64_t srcId;
-    CHECK(msg->findInt64("srcId", &srcId));
-    switch (what) {
-        case Source::kWhatPrepared:
-        {
-            ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source:%p, Id(%lld)",
-                  mCurrentSourceInfo.mSource.get(), (long long)srcId);
-            if (srcId == mCurrentSourceInfo.mSrcId) {
-                if (mCurrentSourceInfo.mSource == NULL) {
-                    // This is a stale notification from a source that was
-                    // asynchronously preparing when the client called reset().
-                    // We handled the reset, the source is gone.
-                    break;
-                }
-
-                int32_t err;
-                CHECK(msg->findInt32("err", &err));
-
-                if (err != OK) {
-                    // shut down potential secure codecs in case client never calls reset
-                    mDeferredActions.push_back(
-                            new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
-                                                   FLUSH_CMD_SHUTDOWN /* video */));
-                    processDeferredActions();
-                } else {
-                    mPrepared = true;
-                }
-
-                sp<NuPlayer2Driver> driver = mDriver.promote();
-                if (driver != NULL) {
-                    // notify duration first, so that it's definitely set when
-                    // the app received the "prepare complete" callback.
-                    int64_t durationUs;
-                    if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
-                        driver->notifyDuration(srcId, durationUs);
-                    }
-                    driver->notifyPrepareCompleted(srcId, err);
-                }
-            } else if (srcId == mNextSourceInfo.mSrcId) {
-                if (mNextSourceInfo.mSource == NULL) {
-                    break;  // stale
-                }
-
-                sp<NuPlayer2Driver> driver = mDriver.promote();
-                if (driver != NULL) {
-                    int32_t err;
-                    CHECK(msg->findInt32("err", &err));
-                    driver->notifyPrepareCompleted(srcId, err);
-                }
-            }
-
-            break;
-        }
-
-        // Modular DRM
-        case Source::kWhatDrmInfo:
-        {
-            PlayerMessage playerMsg;
-            sp<ABuffer> drmInfo;
-            CHECK(msg->findBuffer("drmInfo", &drmInfo));
-            playerMsg.ParseFromArray(drmInfo->data(), drmInfo->size());
-
-            ALOGV("onSourceNotify() kWhatDrmInfo MEDIA2_DRM_INFO drmInfo: %p  playerMsg size: %d",
-                    drmInfo.get(), playerMsg.ByteSize());
-
-            notifyListener(srcId, MEDIA2_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &playerMsg);
-
-            break;
-        }
-
-        case Source::kWhatFlagsChanged:
-        {
-            uint32_t flags;
-            CHECK(msg->findInt32("flags", (int32_t *)&flags));
-
-            sp<NuPlayer2Driver> driver = mDriver.promote();
-            if (driver != NULL) {
-
-                ALOGV("onSourceNotify() kWhatFlagsChanged  FLAG_CAN_PAUSE: %d  "
-                        "FLAG_CAN_SEEK_BACKWARD: %d \n\t\t\t\t FLAG_CAN_SEEK_FORWARD: %d  "
-                        "FLAG_CAN_SEEK: %d  FLAG_DYNAMIC_DURATION: %d \n"
-                        "\t\t\t\t FLAG_SECURE: %d  FLAG_PROTECTED: %d",
-                        (flags & Source::FLAG_CAN_PAUSE) != 0,
-                        (flags & Source::FLAG_CAN_SEEK_BACKWARD) != 0,
-                        (flags & Source::FLAG_CAN_SEEK_FORWARD) != 0,
-                        (flags & Source::FLAG_CAN_SEEK) != 0,
-                        (flags & Source::FLAG_DYNAMIC_DURATION) != 0,
-                        (flags & Source::FLAG_SECURE) != 0,
-                        (flags & Source::FLAG_PROTECTED) != 0);
-
-                if ((flags & NuPlayer2::Source::FLAG_CAN_SEEK) == 0) {
-                    driver->notifyListener(
-                            srcId, MEDIA2_INFO, MEDIA2_INFO_NOT_SEEKABLE, 0);
-                }
-                if (srcId == mCurrentSourceInfo.mSrcId) {
-                    driver->notifyFlagsChanged(srcId, flags);
-                }
-            }
-
-            if (srcId == mCurrentSourceInfo.mSrcId) {
-                if ((mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
-                        && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
-                    cancelPollDuration();
-                } else if (!(mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
-                        && (flags & Source::FLAG_DYNAMIC_DURATION)
-                        && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
-                    schedulePollDuration();
-                }
-
-                mCurrentSourceInfo.mSourceFlags = flags;
-            } else if (srcId == mNextSourceInfo.mSrcId) {
-                // TODO: handle duration polling for next source.
-                mNextSourceInfo.mSourceFlags = flags;
-            }
-            break;
-        }
-
-        case Source::kWhatVideoSizeChanged:
-        {
-            sp<AMessage> format;
-            CHECK(msg->findMessage("format", &format));
-
-            updateVideoSize(srcId, format);
-            break;
-        }
-
-        case Source::kWhatBufferingUpdate:
-        {
-            int32_t percentage;
-            CHECK(msg->findInt32("percentage", &percentage));
-
-            notifyListener(srcId, MEDIA2_BUFFERING_UPDATE, percentage, 0);
-            break;
-        }
-
-        case Source::kWhatPauseOnBufferingStart:
-        {
-            // ignore if not playing
-            if (mStarted) {
-                ALOGI("buffer low, pausing...");
-
-                startRebufferingTimer();
-                mPausedForBuffering = true;
-                onPause();
-            }
-            notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_START, 0);
-            break;
-        }
-
-        case Source::kWhatResumeOnBufferingEnd:
-        {
-            // ignore if not playing
-            if (mStarted) {
-                ALOGI("buffer ready, resuming...");
-
-                stopRebufferingTimer(false);
-                mPausedForBuffering = false;
-
-                // do not resume yet if client didn't unpause
-                if (!mPausedByClient) {
-                    onResume();
-                }
-            }
-            notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_END, 0);
-            break;
-        }
-
-        case Source::kWhatCacheStats:
-        {
-            int32_t kbps;
-            CHECK(msg->findInt32("bandwidth", &kbps));
-
-            notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_NETWORK_BANDWIDTH, kbps);
-            break;
-        }
-
-        case Source::kWhatSubtitleData:
-        {
-            sp<ABuffer> buffer;
-            CHECK(msg->findBuffer("buffer", &buffer));
-
-            sendSubtitleData(buffer, 0 /* baseIndex */);
-            break;
-        }
-
-        case Source::kWhatTimedMetaData:
-        {
-            sp<ABuffer> buffer;
-            if (!msg->findBuffer("buffer", &buffer)) {
-                notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
-            } else {
-                sendTimedMetaData(buffer);
-            }
-            break;
-        }
-
-        case Source::kWhatTimedTextData:
-        {
-            int32_t generation;
-            if (msg->findInt32("generation", &generation)
-                    && generation != mTimedTextGeneration) {
-                break;
-            }
-
-            sp<ABuffer> buffer;
-            CHECK(msg->findBuffer("buffer", &buffer));
-
-            sp<NuPlayer2Driver> driver = mDriver.promote();
-            if (driver == NULL) {
-                break;
-            }
-
-            int64_t posMs;
-            int64_t timeUs, posUs;
-            driver->getCurrentPosition(&posMs);
-            posUs = posMs * 1000LL;
-            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
-
-            if (posUs < timeUs) {
-                if (!msg->findInt32("generation", &generation)) {
-                    msg->setInt32("generation", mTimedTextGeneration);
-                }
-                msg->post(timeUs - posUs);
-            } else {
-                sendTimedTextData(buffer);
-            }
-            break;
-        }
-
-        case Source::kWhatQueueDecoderShutdown:
-        {
-            int32_t audio, video;
-            CHECK(msg->findInt32("audio", &audio));
-            CHECK(msg->findInt32("video", &video));
-
-            sp<AMessage> reply;
-            CHECK(msg->findMessage("reply", &reply));
-
-            queueDecoderShutdown(audio, video, reply);
-            break;
-        }
-
-        case Source::kWhatDrmNoLicense:
-        {
-            notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
-            break;
-        }
-
-        default:
-            TRESPASS();
-    }
-}
-
-void NuPlayer2::onClosedCaptionNotify(const sp<AMessage> &msg) {
-    int32_t what;
-    CHECK(msg->findInt32("what", &what));
-
-    switch (what) {
-        case NuPlayer2::CCDecoder::kWhatClosedCaptionData:
-        {
-            sp<ABuffer> buffer;
-            CHECK(msg->findBuffer("buffer", &buffer));
-
-            size_t inbandTracks = 0;
-            if (mCurrentSourceInfo.mSource != NULL) {
-                inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
-            }
-
-            sendSubtitleData(buffer, inbandTracks);
-            break;
-        }
-
-        case NuPlayer2::CCDecoder::kWhatTrackAdded:
-        {
-            notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
-
-            break;
-        }
-
-        default:
-            TRESPASS();
-    }
-
-
-}
-
-void NuPlayer2::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
-    int32_t trackIndex;
-    int64_t timeUs, durationUs;
-    CHECK(buffer->meta()->findInt32(AMEDIAFORMAT_KEY_TRACK_INDEX, &trackIndex));
-    CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
-    CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
-
-    PlayerMessage playerMsg;
-    playerMsg.add_values()->set_int32_value(trackIndex + baseIndex);
-    playerMsg.add_values()->set_int64_value(timeUs);
-    playerMsg.add_values()->set_int64_value(durationUs);
-    playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
-
-    notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_SUBTITLE_DATA, 0, 0, &playerMsg);
-}
-
-void NuPlayer2::sendTimedMetaData(const sp<ABuffer> &buffer) {
-    int64_t timeUs;
-    CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
-
-    PlayerMessage playerMsg;
-    playerMsg.add_values()->set_int64_value(timeUs);
-    playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
-
-    notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_META_DATA, 0, 0, &playerMsg);
-}
-
-void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) {
-    const void *data;
-    size_t size = 0;
-    int64_t timeUs;
-    int32_t flag = TextDescriptions2::IN_BAND_TEXT_3GPP;
-
-    AString mime;
-    CHECK(buffer->meta()->findString("mime", &mime));
-    CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
-
-    data = buffer->data();
-    size = buffer->size();
-
-    PlayerMessage playerMsg;
-    if (size > 0) {
-        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
-        int32_t global = 0;
-        if (buffer->meta()->findInt32("global", &global) && global) {
-            flag |= TextDescriptions2::GLOBAL_DESCRIPTIONS;
-        } else {
-            flag |= TextDescriptions2::LOCAL_DESCRIPTIONS;
-        }
-        TextDescriptions2::getPlayerMessageOfDescriptions(
-                (const uint8_t *)data, size, flag, timeUs / 1000, &playerMsg);
-    }
-
-    if (playerMsg.values_size() > 0) {
-        notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &playerMsg);
-    } else {  // send an empty timed text
-        notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0);
-    }
-}
-
-const char *NuPlayer2::getDataSourceType() {
-    switch (mCurrentSourceInfo.mDataSourceType) {
-        case DATA_SOURCE_TYPE_HTTP_LIVE:
-            return "HTTPLive";
-
-        case DATA_SOURCE_TYPE_RTSP:
-            return "RTSP";
-
-        case DATA_SOURCE_TYPE_GENERIC_URL:
-            return "GenURL";
-
-        case DATA_SOURCE_TYPE_GENERIC_FD:
-            return "GenFD";
-
-        case DATA_SOURCE_TYPE_MEDIA:
-            return "Media";
-
-        case DATA_SOURCE_TYPE_NONE:
-        default:
-            return "None";
-    }
- }
-
-NuPlayer2::SourceInfo* NuPlayer2::getSourceInfoByIdInMsg(const sp<AMessage> &msg) {
-    int64_t srcId;
-    CHECK(msg->findInt64("srcId", &srcId));
-    if (mCurrentSourceInfo.mSrcId == srcId) {
-        return &mCurrentSourceInfo;
-    } else if (mNextSourceInfo.mSrcId == srcId) {
-        return &mNextSourceInfo;
-    } else {
-        return NULL;
-    }
-}
-
-void NuPlayer2::resetSourceInfo(NuPlayer2::SourceInfo &srcInfo) {
-    if (srcInfo.mSource != NULL) {
-        srcInfo.mSource->stop();
-
-        Mutex::Autolock autoLock(mSourceLock);
-        srcInfo.mSource.clear();
-    }
-    // Modular DRM
-    ALOGD("performReset mCrypto: %p", srcInfo.mCrypto.get());
-    srcInfo.mCrypto.clear();
-    srcInfo.mIsDrmProtected = false;
-}
-
-// Modular DRM begin
-status_t NuPlayer2::prepareDrm(
-        int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
-{
-    ALOGV("prepareDrm ");
-
-    // Passing to the looper anyway; called in a pre-config prepared state so no race on mCrypto
-    sp<AMessage> msg = new AMessage(kWhatPrepareDrm, this);
-    // synchronous call so just passing the address but with local copies of "const" args
-    uint8_t UUID[16];
-    memcpy(UUID, uuid, sizeof(UUID));
-    Vector<uint8_t> sessionId = drmSessionId;
-    msg->setInt64("srcId", srcId);
-    msg->setPointer("uuid", (void*)UUID);
-    msg->setPointer("drmSessionId", (void*)&sessionId);
-
-    sp<AMessage> response;
-    status_t status = msg->postAndAwaitResponse(&response);
-
-    if (status == OK && response != NULL) {
-        CHECK(response->findInt32("status", &status));
-        ALOGV("prepareDrm ret: %d ", status);
-    } else {
-        ALOGE("prepareDrm err: %d", status);
-    }
-
-    return status;
-}
-
-status_t NuPlayer2::releaseDrm(int64_t srcId)
-{
-    ALOGV("releaseDrm ");
-
-    sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
-    msg->setInt64("srcId", srcId);
-
-    sp<AMessage> response;
-    status_t status = msg->postAndAwaitResponse(&response);
-
-    if (status == OK && response != NULL) {
-        CHECK(response->findInt32("status", &status));
-        ALOGV("releaseDrm ret: %d ", status);
-    } else {
-        ALOGE("releaseDrm err: %d", status);
-    }
-
-    return status;
-}
-
-status_t NuPlayer2::onPrepareDrm(const sp<AMessage> &msg)
-{
-    // TODO change to ALOGV
-    ALOGD("onPrepareDrm ");
-
-    status_t status = INVALID_OPERATION;
-    SourceInfo *srcInfo = getSourceInfoByIdInMsg(msg);
-    if (srcInfo == NULL) {
-        return status;
-    }
-
-    int64_t srcId = srcInfo->mSrcId;
-    if (srcInfo->mSource == NULL) {
-        ALOGE("onPrepareDrm: srcInfo(%lld) No source. onPrepareDrm failed with %d.",
-                (long long)srcId, status);
-        return status;
-    }
-
-    uint8_t *uuid;
-    Vector<uint8_t> *drmSessionId;
-    CHECK(msg->findPointer("uuid", (void**)&uuid));
-    CHECK(msg->findPointer("drmSessionId", (void**)&drmSessionId));
-
-    status = OK;
-    sp<AMediaCryptoWrapper> crypto = NULL;
-
-    status = srcInfo->mSource->prepareDrm(uuid, *drmSessionId, &crypto);
-    if (crypto == NULL) {
-        ALOGE("onPrepareDrm: srcInfo(%lld).mSource->prepareDrm failed. status: %d",
-                (long long)srcId, status);
-        return status;
-    }
-    ALOGV("onPrepareDrm: srcInfo(%lld).mSource->prepareDrm succeeded", (long long)srcId);
-
-    if (srcInfo->mCrypto != NULL) {
-        ALOGE("onPrepareDrm: srcInfo(%lld) Unexpected. Already having mCrypto: %p",
-                (long long)srcId, srcInfo->mCrypto.get());
-        srcInfo->mCrypto.clear();
-    }
-
-    srcInfo->mCrypto = crypto;
-    srcInfo->mIsDrmProtected = true;
-    // TODO change to ALOGV
-    ALOGD("onPrepareDrm: mCrypto: %p", srcInfo->mCrypto.get());
-
-    return status;
-}
-
-status_t NuPlayer2::onReleaseDrm(const sp<AMessage> &msg)
-{
-    // TODO change to ALOGV
-    ALOGD("onReleaseDrm ");
-    SourceInfo *srcInfo = getSourceInfoByIdInMsg(msg);;
-    if (srcInfo == NULL) {
-        return INVALID_OPERATION;
-    }
-
-    int64_t srcId = srcInfo->mSrcId;
-    if (!srcInfo->mIsDrmProtected) {
-        ALOGW("onReleaseDrm: srcInfo(%lld) Unexpected. mIsDrmProtected is already false.",
-                (long long)srcId);
-    }
-
-    srcInfo->mIsDrmProtected = false;
-
-    status_t status;
-    if (srcInfo->mCrypto != NULL) {
-        // notifying the source first before removing crypto from codec
-        if (srcInfo->mSource != NULL) {
-            srcInfo->mSource->releaseDrm();
-        }
-
-        status=OK;
-        // first making sure the codecs have released their crypto reference
-        const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/);
-        if (videoDecoder != NULL) {
-            status = videoDecoder->releaseCrypto();
-            ALOGV("onReleaseDrm: video decoder ret: %d", status);
-        }
-
-        const sp<DecoderBase> &audioDecoder = getDecoder(true/*audio*/);
-        if (audioDecoder != NULL) {
-            status_t status_audio = audioDecoder->releaseCrypto();
-            if (status == OK) {   // otherwise, returning the first error
-                status = status_audio;
-            }
-            ALOGV("onReleaseDrm: audio decoder ret: %d", status_audio);
-        }
-
-        // TODO change to ALOGV
-        ALOGD("onReleaseDrm: mCrypto: %p", srcInfo->mCrypto.get());
-        srcInfo->mCrypto.clear();
-    } else {   // srcInfo->mCrypto == NULL
-        ALOGE("onReleaseDrm: Unexpected. There is no crypto.");
-        status = INVALID_OPERATION;
-    }
-
-    return status;
-}
-// Modular DRM end
-////////////////////////////////////////////////////////////////////////////////
-
-sp<AMessage> NuPlayer2::Source::getFormat(bool audio) {
-    sp<MetaData> meta = getFormatMeta(audio);
-
-    if (meta == NULL) {
-        return NULL;
-    }
-
-    sp<AMessage> msg = new AMessage;
-
-    if(convertMetaDataToMessage(meta, &msg) == OK) {
-        return msg;
-    }
-    return NULL;
-}
-
-void NuPlayer2::Source::notifyFlagsChanged(uint32_t flags) {
-    sp<AMessage> notify = dupNotify();
-    notify->setInt32("what", kWhatFlagsChanged);
-    notify->setInt32("flags", flags);
-    notify->post();
-}
-
-void NuPlayer2::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
-    sp<AMessage> notify = dupNotify();
-    notify->setInt32("what", kWhatVideoSizeChanged);
-    notify->setMessage("format", format);
-    notify->post();
-}
-
-void NuPlayer2::Source::notifyPrepared(status_t err) {
-    ALOGV("Source::notifyPrepared %d", err);
-    sp<AMessage> notify = dupNotify();
-    notify->setInt32("what", kWhatPrepared);
-    notify->setInt32("err", err);
-    notify->post();
-}
-
-void NuPlayer2::Source::notifyDrmInfo(const sp<ABuffer> &drmInfoBuffer)
-{
-    ALOGV("Source::notifyDrmInfo");
-
-    sp<AMessage> notify = dupNotify();
-    notify->setInt32("what", kWhatDrmInfo);
-    notify->setBuffer("drmInfo", drmInfoBuffer);
-
-    notify->post();
-}
-
-void NuPlayer2::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
-    TRESPASS();
-}
-
-NuPlayer2::SourceInfo::SourceInfo()
-    : mDataSourceType(DATA_SOURCE_TYPE_NONE),
-      mSrcId(0),
-      mSourceFlags(0),
-      mStartTimeUs(0),
-      mEndTimeUs(DataSourceDesc::kMaxTimeUs) {
-}
-
-NuPlayer2::SourceInfo & NuPlayer2::SourceInfo::operator=(const NuPlayer2::SourceInfo &other) {
-    mSource = other.mSource;
-    mCrypto = other.mCrypto;
-    mDataSourceType = (DATA_SOURCE_TYPE)other.mDataSourceType;
-    mSrcId = other.mSrcId;
-    mSourceFlags = other.mSourceFlags;
-    mStartTimeUs = other.mStartTimeUs;
-    mEndTimeUs = other.mEndTimeUs;
-    mIsDrmProtected = other.mIsDrmProtected;
-    return *this;
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2.h b/media/libmediaplayer2/nuplayer2/NuPlayer2.h
deleted file mode 100644
index b8fb988..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2.h
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-#ifndef NU_PLAYER2_H_
-
-#define NU_PLAYER2_H_
-
-#include <media/AudioResamplerPublic.h>
-#include <media/stagefright/foundation/AHandler.h>
-
-#include <mediaplayer2/MediaPlayer2Interface.h>
-#include <mediaplayer2/JObjectHolder.h>
-
-#include "mediaplayer2.pb.h"
-
-using android::media::MediaPlayer2Proto::PlayerMessage;
-
-namespace android {
-
-struct ABuffer;
-struct AMediaCryptoWrapper;
-struct AMessage;
-struct ANativeWindowWrapper;
-struct AudioPlaybackRate;
-struct AVSyncSettings;
-struct DataSourceDesc;
-struct MediaClock;
-struct MediaHTTPService;
-class MetaData;
-struct NuPlayer2Driver;
-
-struct NuPlayer2 : public AHandler {
-    explicit NuPlayer2(pid_t pid, uid_t uid,
-            const sp<MediaClock> &mediaClock, const sp<JObjectHolder> &context);
-
-    void setDriver(const wp<NuPlayer2Driver> &driver);
-
-    void setDataSourceAsync(const sp<DataSourceDesc> &dsd);
-    void prepareNextDataSourceAsync(const sp<DataSourceDesc> &dsd);
-    void playNextDataSource(int64_t srcId);
-
-    status_t getBufferingSettings(BufferingSettings* buffering /* nonnull */);
-    status_t setBufferingSettings(const BufferingSettings& buffering);
-
-    void prepareAsync();
-
-    void setVideoSurfaceTextureAsync(const sp<ANativeWindowWrapper> &nww);
-
-    void setAudioSink(const sp<MediaPlayer2Interface::AudioSink> &sink);
-    status_t setPlaybackSettings(const AudioPlaybackRate &rate);
-    status_t getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */);
-    status_t setSyncSettings(const AVSyncSettings &sync, float videoFpsHint);
-    status_t getSyncSettings(AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */);
-
-    void start();
-
-    void pause();
-
-    // Will notify the driver through "notifyResetComplete" once finished.
-    void resetAsync();
-
-    // Request a notification when specified media time is reached.
-    status_t notifyAt(int64_t mediaTimeUs);
-
-    // Will notify the driver through "notifySeekComplete" once finished
-    // and needNotify is true.
-    void seekToAsync(
-            int64_t seekTimeUs,
-            MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC,
-            bool needNotify = false);
-    void rewind();
-
-    status_t setVideoScalingMode(int32_t mode);
-    status_t getTrackInfo(int64_t srcId, PlayerMessage* reply) const;
-    status_t getSelectedTrack(int64_t srcId, int32_t type, PlayerMessage* reply) const;
-    status_t selectTrack(int64_t srcId, size_t trackIndex, bool select, int64_t timeUs);
-    status_t getCurrentPosition(int64_t *mediaUs);
-    void getStats(Vector<sp<AMessage> > *mTrackStats);
-
-    sp<MetaData> getFileMeta();
-    float getFrameRate();
-
-    // Modular DRM
-    status_t prepareDrm(int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId);
-    status_t releaseDrm(int64_t srcId);
-
-    const char *getDataSourceType();
-
-protected:
-    virtual ~NuPlayer2();
-
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-public:
-    struct StreamListener;
-    struct Source;
-
-private:
-    struct Decoder;
-    struct DecoderBase;
-    struct DecoderPassThrough;
-    struct CCDecoder;
-    struct GenericSource2;
-    struct HTTPLiveSource2;
-    struct Renderer;
-    struct RTSPSource2;
-    struct Action;
-    struct SeekAction;
-    struct SetSurfaceAction;
-    struct ResumeDecoderAction;
-    struct FlushDecoderAction;
-    struct PostMessageAction;
-    struct SimpleAction;
-
-    enum {
-        kWhatSetDataSource              = '=DaS',
-        kWhatPrepare                    = 'prep',
-        kWhatPrepareNextDataSource      = 'pNDS',
-        kWhatPlayNextDataSource         = 'plNS',
-        kWhatSetVideoSurface            = '=VSu',
-        kWhatSetAudioSink               = '=AuS',
-        kWhatMoreDataQueued             = 'more',
-        kWhatConfigPlayback             = 'cfPB',
-        kWhatConfigSync                 = 'cfSy',
-        kWhatGetPlaybackSettings        = 'gPbS',
-        kWhatGetSyncSettings            = 'gSyS',
-        kWhatStart                      = 'strt',
-        kWhatScanSources                = 'scan',
-        kWhatVideoNotify                = 'vidN',
-        kWhatAudioNotify                = 'audN',
-        kWhatClosedCaptionNotify        = 'capN',
-        kWhatRendererNotify             = 'renN',
-        kWhatReset                      = 'rset',
-        kWhatNotifyTime                 = 'nfyT',
-        kWhatSeek                       = 'seek',
-        kWhatPause                      = 'paus',
-        kWhatResume                     = 'rsme',
-        kWhatPollDuration               = 'polD',
-        kWhatSourceNotify               = 'srcN',
-        kWhatGetTrackInfo               = 'gTrI',
-        kWhatGetSelectedTrack           = 'gSel',
-        kWhatSelectTrack                = 'selT',
-        kWhatGetBufferingSettings       = 'gBus',
-        kWhatSetBufferingSettings       = 'sBuS',
-        kWhatPrepareDrm                 = 'pDrm',
-        kWhatReleaseDrm                 = 'rDrm',
-        kWhatRewind                     = 'reWd',
-        kWhatEOSMonitor                 = 'eosM',
-    };
-
-    typedef enum {
-        DATA_SOURCE_TYPE_NONE,
-        DATA_SOURCE_TYPE_HTTP_LIVE,
-        DATA_SOURCE_TYPE_RTSP,
-        DATA_SOURCE_TYPE_GENERIC_URL,
-        DATA_SOURCE_TYPE_GENERIC_FD,
-        DATA_SOURCE_TYPE_MEDIA,
-    } DATA_SOURCE_TYPE;
-
-    struct SourceInfo {
-        SourceInfo();
-        SourceInfo &operator=(const SourceInfo &);
-
-        sp<Source> mSource;
-        std::atomic<DATA_SOURCE_TYPE> mDataSourceType;
-        int64_t mSrcId;
-        uint32_t mSourceFlags;
-        int64_t mStartTimeUs;
-        int64_t mEndTimeUs;
-        // Modular DRM
-        sp<AMediaCryptoWrapper> mCrypto;
-        bool mIsDrmProtected = false;
-    };
-
-    wp<NuPlayer2Driver> mDriver;
-    pid_t mPID;
-    uid_t mUID;
-    const sp<MediaClock> mMediaClock;
-    Mutex mSourceLock;  // guard |mSource|.
-    SourceInfo mCurrentSourceInfo;
-    SourceInfo mNextSourceInfo;
-    sp<ANativeWindowWrapper> mNativeWindow;
-    sp<MediaPlayer2Interface::AudioSink> mAudioSink;
-    sp<DecoderBase> mVideoDecoder;
-    bool mOffloadAudio;
-    sp<DecoderBase> mAudioDecoder;
-    Mutex mDecoderLock;  // guard |mAudioDecoder| and |mVideoDecoder|.
-    sp<CCDecoder> mCCDecoder;
-    sp<Renderer> mRenderer;
-    sp<ALooper> mRendererLooper;
-    int32_t mAudioDecoderGeneration;
-    int32_t mVideoDecoderGeneration;
-    int32_t mRendererGeneration;
-    int32_t mEOSMonitorGeneration;
-
-    Mutex mPlayingTimeLock;
-    int64_t mLastStartedPlayingTimeNs;
-    void stopPlaybackTimer(const char *where);
-    void startPlaybackTimer(const char *where);
-
-    int64_t mLastStartedRebufferingTimeNs;
-    void startRebufferingTimer();
-    void stopRebufferingTimer(bool exitingPlayback);
-
-    int64_t mPreviousSeekTimeUs;
-
-    List<sp<Action> > mDeferredActions;
-
-    bool mAudioEOS;
-    bool mVideoEOS;
-
-    bool mScanSourcesPending;
-    int32_t mScanSourcesGeneration;
-
-    int32_t mPollDurationGeneration;
-    int32_t mTimedTextGeneration;
-
-    enum FlushStatus {
-        NONE,
-        FLUSHING_DECODER,
-        FLUSHING_DECODER_SHUTDOWN,
-        SHUTTING_DOWN_DECODER,
-        FLUSHED,
-        SHUT_DOWN,
-    };
-
-    enum FlushCommand {
-        FLUSH_CMD_NONE,
-        FLUSH_CMD_FLUSH,
-        FLUSH_CMD_SHUTDOWN,
-    };
-
-    // Status of flush responses from the decoder and renderer.
-    bool mFlushComplete[2][2];
-
-    FlushStatus mFlushingAudio;
-    FlushStatus mFlushingVideo;
-
-    // Status of flush responses from the decoder and renderer.
-    bool mResumePending;
-
-    int32_t mVideoScalingMode;
-
-    AudioPlaybackRate mPlaybackSettings;
-    AVSyncSettings mSyncSettings;
-    float mVideoFpsHint;
-    bool mStarted;
-    bool mPrepared;
-    bool mResetting;
-    bool mSourceStarted;
-    bool mAudioDecoderError;
-    bool mVideoDecoderError;
-
-    // Actual pause state, either as requested by client or due to buffering.
-    bool mPaused;
-
-    // Pause state as requested by client. Note that if mPausedByClient is
-    // true, mPaused is always true; if mPausedByClient is false, mPaused could
-    // still become true, when we pause internally due to buffering.
-    bool mPausedByClient;
-
-    // Pause state as requested by source (internally) due to buffering
-    bool mPausedForBuffering;
-
-    // Passed from JAVA
-    const sp<JObjectHolder> mContext;
-
-    inline const sp<DecoderBase> &getDecoder(bool audio) {
-        return audio ? mAudioDecoder : mVideoDecoder;
-    }
-
-    inline void clearFlushComplete() {
-        mFlushComplete[0][0] = false;
-        mFlushComplete[0][1] = false;
-        mFlushComplete[1][0] = false;
-        mFlushComplete[1][1] = false;
-    }
-
-    void disconnectSource();
-
-    status_t createNuPlayer2Source(const sp<DataSourceDesc> &dsd,
-                                   sp<Source> *source,
-                                   DATA_SOURCE_TYPE *dataSourceType);
-
-    void tryOpenAudioSinkForOffload(
-            const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo);
-    void closeAudioSink();
-    void restartAudio(
-            int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder);
-    void determineAudioModeChange(const sp<AMessage> &audioFormat);
-
-    status_t instantiateDecoder(
-            bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange = true);
-
-    void updateVideoSize(
-            int64_t srcId,
-            const sp<AMessage> &inputFormat,
-            const sp<AMessage> &outputFormat = NULL);
-
-    void notifyListener(int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in = NULL);
-
-    void addEndTimeMonitor();
-
-    void handleFlushComplete(bool audio, bool isDecoder);
-    void finishFlushIfPossible();
-
-    void onStart(bool play);
-    void onResume();
-    void onPause();
-
-    bool audioDecoderStillNeeded();
-
-    void flushDecoder(bool audio, bool needShutdown);
-
-    void finishResume();
-    void notifyDriverSeekComplete(int64_t srcId);
-
-    void postScanSources();
-
-    void schedulePollDuration();
-    void cancelPollDuration();
-
-    void processDeferredActions();
-
-    void performSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode);
-    void performDecoderFlush(FlushCommand audio, FlushCommand video);
-    void performReset();
-    void performPlayNextDataSource();
-    void performScanSources();
-    void performSetSurface(const sp<ANativeWindowWrapper> &nw);
-    void performResumeDecoders(bool needNotify);
-
-    void onSourceNotify(const sp<AMessage> &msg);
-    void onClosedCaptionNotify(const sp<AMessage> &msg);
-
-    void queueDecoderShutdown(
-            bool audio, bool video, const sp<AMessage> &reply);
-
-    void sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex);
-    void sendTimedMetaData(const sp<ABuffer> &buffer);
-    void sendTimedTextData(const sp<ABuffer> &buffer);
-
-    void writeTrackInfo(PlayerMessage* reply, const sp<AMessage>& format) const;
-
-    status_t onPrepareDrm(const sp<AMessage> &msg);
-    status_t onReleaseDrm(const sp<AMessage> &msg);
-
-    SourceInfo* getSourceInfoByIdInMsg(const sp<AMessage> &msg);
-    void resetSourceInfo(SourceInfo &srcInfo);
-
-    DISALLOW_EVIL_CONSTRUCTORS(NuPlayer2);
-};
-
-}  // namespace android
-
-#endif  // NU_PLAYER2_H_
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.cpp
deleted file mode 100644
index 98c3403..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.cpp
+++ /dev/null
@@ -1,606 +0,0 @@
-/*
- * Copyright 2017 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 "NuPlayer2CCDecoder"
-#include <utils/Log.h>
-#include <inttypes.h>
-
-#include "NuPlayer2CCDecoder.h"
-
-#include <media/NdkMediaFormat.h>
-#include <media/stagefright/foundation/ABitReader.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/avc_utils.h>
-#include <media/stagefright/MediaDefs.h>
-
-namespace android {
-
-// In CEA-708B, the maximum bandwidth of CC is set to 9600bps.
-static const size_t kMaxBandwithSizeBytes = 9600 / 8;
-
-struct CCData {
-    CCData(uint8_t type, uint8_t data1, uint8_t data2)
-        : mType(type), mData1(data1), mData2(data2) {
-    }
-    bool getChannel(size_t *channel) const {
-        if (mData1 >= 0x10 && mData1 <= 0x1f) {
-            *channel = (mData1 >= 0x18 ? 1 : 0) + (mType ? 2 : 0);
-            return true;
-        }
-        return false;
-    }
-
-    uint8_t mType;
-    uint8_t mData1;
-    uint8_t mData2;
-};
-
-static bool isNullPad(CCData *cc) {
-    return cc->mData1 < 0x10 && cc->mData2 < 0x10;
-}
-
-static void dumpBytePair(const sp<ABuffer> &ccBuf) __attribute__ ((unused));
-static void dumpBytePair(const sp<ABuffer> &ccBuf) {
-    size_t offset = 0;
-    AString out;
-
-    while (offset < ccBuf->size()) {
-        char tmp[128];
-
-        CCData *cc = (CCData *) (ccBuf->data() + offset);
-
-        if (isNullPad(cc)) {
-            // 1 null pad or XDS metadata, ignore
-            offset += sizeof(CCData);
-            continue;
-        }
-
-        if (cc->mData1 >= 0x20 && cc->mData1 <= 0x7f) {
-            // 2 basic chars
-            snprintf(tmp, sizeof(tmp), "[%d]Basic: %c %c", cc->mType, cc->mData1, cc->mData2);
-        } else if ((cc->mData1 == 0x11 || cc->mData1 == 0x19)
-                 && cc->mData2 >= 0x30 && cc->mData2 <= 0x3f) {
-            // 1 special char
-            snprintf(tmp, sizeof(tmp), "[%d]Special: %02x %02x", cc->mType, cc->mData1, cc->mData2);
-        } else if ((cc->mData1 == 0x12 || cc->mData1 == 0x1A)
-                 && cc->mData2 >= 0x20 && cc->mData2 <= 0x3f){
-            // 1 Spanish/French char
-            snprintf(tmp, sizeof(tmp), "[%d]Spanish: %02x %02x", cc->mType, cc->mData1, cc->mData2);
-        } else if ((cc->mData1 == 0x13 || cc->mData1 == 0x1B)
-                 && cc->mData2 >= 0x20 && cc->mData2 <= 0x3f){
-            // 1 Portuguese/German/Danish char
-            snprintf(tmp, sizeof(tmp), "[%d]German: %02x %02x", cc->mType, cc->mData1, cc->mData2);
-        } else if ((cc->mData1 == 0x11 || cc->mData1 == 0x19)
-                 && cc->mData2 >= 0x20 && cc->mData2 <= 0x2f){
-            // Mid-Row Codes (Table 69)
-            snprintf(tmp, sizeof(tmp), "[%d]Mid-row: %02x %02x", cc->mType, cc->mData1, cc->mData2);
-        } else if (((cc->mData1 == 0x14 || cc->mData1 == 0x1c)
-                  && cc->mData2 >= 0x20 && cc->mData2 <= 0x2f)
-                  ||
-                   ((cc->mData1 == 0x17 || cc->mData1 == 0x1f)
-                  && cc->mData2 >= 0x21 && cc->mData2 <= 0x23)){
-            // Misc Control Codes (Table 70)
-            snprintf(tmp, sizeof(tmp), "[%d]Ctrl: %02x %02x", cc->mType, cc->mData1, cc->mData2);
-        } else if ((cc->mData1 & 0x70) == 0x10
-                && (cc->mData2 & 0x40) == 0x40
-                && ((cc->mData1 & 0x07) || !(cc->mData2 & 0x20)) ) {
-            // Preamble Address Codes (Table 71)
-            snprintf(tmp, sizeof(tmp), "[%d]PAC: %02x %02x", cc->mType, cc->mData1, cc->mData2);
-        } else {
-            snprintf(tmp, sizeof(tmp), "[%d]Invalid: %02x %02x", cc->mType, cc->mData1, cc->mData2);
-        }
-
-        if (out.size() > 0) {
-            out.append(", ");
-        }
-
-        out.append(tmp);
-
-        offset += sizeof(CCData);
-    }
-
-    ALOGI("%s", out.c_str());
-}
-
-NuPlayer2::CCDecoder::CCDecoder(const sp<AMessage> &notify)
-    : mNotify(notify),
-      mSelectedTrack(-1),
-      mDTVCCPacket(new ABuffer(kMaxBandwithSizeBytes)) {
-    mDTVCCPacket->setRange(0, 0);
-
-    // In CEA-608, streams from packets which have the value 0 of cc_type contain CC1 and CC2, and
-    // streams from packets which have the value 1 of cc_type contain CC3 and CC4.
-    // The following array indicates the current transmitting channels for each value of cc_type.
-    mLine21Channels[0] = 0; // CC1
-    mLine21Channels[1] = 2; // CC3
-}
-
-size_t NuPlayer2::CCDecoder::getTrackCount() const {
-    return mTracks.size();
-}
-
-sp<AMessage> NuPlayer2::CCDecoder::getTrackInfo(size_t index) const {
-    if (!isTrackValid(index)) {
-        return NULL;
-    }
-
-    sp<AMessage> format = new AMessage();
-
-    CCTrack track = mTracks[index];
-
-    format->setInt32("type", MEDIA_TRACK_TYPE_SUBTITLE);
-    format->setString("language", "und");
-
-    switch (track.mTrackType) {
-        case kTrackTypeCEA608:
-            format->setString("mime", MEDIA_MIMETYPE_TEXT_CEA_608);
-            break;
-        case kTrackTypeCEA708:
-            format->setString("mime", MEDIA_MIMETYPE_TEXT_CEA_708);
-            break;
-        default:
-            ALOGE("Unknown track type: %d", track.mTrackType);
-            return NULL;
-    }
-
-    // For CEA-608 CC1, field 0 channel 0
-    bool isDefaultAuto = track.mTrackType == kTrackTypeCEA608
-            && track.mTrackChannel == 0;
-    // For CEA-708, Primary Caption Service.
-    bool isDefaultOnly = track.mTrackType == kTrackTypeCEA708
-            && track.mTrackChannel == 1;
-    format->setInt32("auto", isDefaultAuto);
-    format->setInt32("default", isDefaultAuto || isDefaultOnly);
-    format->setInt32("forced", 0);
-
-    return format;
-}
-
-status_t NuPlayer2::CCDecoder::selectTrack(size_t index, bool select) {
-    if (!isTrackValid(index)) {
-        return BAD_VALUE;
-    }
-
-    if (select) {
-        if (mSelectedTrack == (ssize_t)index) {
-            ALOGE("track %zu already selected", index);
-            return BAD_VALUE;
-        }
-        ALOGV("selected track %zu", index);
-        mSelectedTrack = index;
-    } else {
-        if (mSelectedTrack != (ssize_t)index) {
-            ALOGE("track %zu is not selected", index);
-            return BAD_VALUE;
-        }
-        ALOGV("unselected track %zu", index);
-        mSelectedTrack = -1;
-    }
-
-    // Clear the previous track payloads
-    mCCMap.clear();
-
-    return OK;
-}
-
-ssize_t NuPlayer2::CCDecoder::getSelectedTrack(media_track_type type) const {
-    if (mSelectedTrack != -1) {
-        CCTrack track = mTracks[mSelectedTrack];
-        if (track.mTrackType == kTrackTypeCEA608 || track.mTrackType == kTrackTypeCEA708) {
-            return (type == MEDIA_TRACK_TYPE_SUBTITLE ? mSelectedTrack : -1);
-        }
-        return (type == MEDIA_TRACK_TYPE_UNKNOWN ? mSelectedTrack : -1);
-    }
-
-    return -1;
-}
-
-bool NuPlayer2::CCDecoder::isSelected() const {
-    return mSelectedTrack >= 0 && mSelectedTrack < (int32_t)getTrackCount();
-}
-
-bool NuPlayer2::CCDecoder::isTrackValid(size_t index) const {
-    return index < getTrackCount();
-}
-
-// returns true if a new CC track is found
-bool NuPlayer2::CCDecoder::extractFromSEI(const sp<ABuffer> &accessUnit) {
-    sp<ABuffer> sei;
-    if (!accessUnit->meta()->findBuffer("sei", &sei) || sei == NULL) {
-        return false;
-    }
-
-    int64_t timeUs;
-    CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
-
-    bool trackAdded = false;
-
-    const NALPosition *nal = (NALPosition *)sei->data();
-
-    for (size_t i = 0; i < sei->size() / sizeof(NALPosition); ++i, ++nal) {
-        trackAdded |= parseSEINalUnit(
-                timeUs, accessUnit->data() + nal->nalOffset, nal->nalSize);
-    }
-
-    return trackAdded;
-}
-
-// returns true if a new CC track is found
-bool NuPlayer2::CCDecoder::parseSEINalUnit(int64_t timeUs, const uint8_t *data, size_t size) {
-    unsigned nalType = data[0] & 0x1f;
-
-    // the buffer should only have SEI in it
-    if (nalType != 6) {
-        return false;
-    }
-
-    bool trackAdded = false;
-    NALBitReader br(data + 1, size - 1);
-
-    // sei_message()
-    while (br.atLeastNumBitsLeft(16)) { // at least 16-bit for sei_message()
-        uint32_t payload_type = 0;
-        size_t payload_size = 0;
-        uint8_t last_byte;
-
-        do {
-            last_byte = br.getBits(8);
-            payload_type += last_byte;
-        } while (last_byte == 0xFF);
-
-        do {
-            last_byte = br.getBits(8);
-            payload_size += last_byte;
-        } while (last_byte == 0xFF);
-
-        if (payload_size > SIZE_MAX / 8
-                || !br.atLeastNumBitsLeft(payload_size * 8)) {
-            ALOGV("Malformed SEI payload");
-            break;
-        }
-
-        // sei_payload()
-        if (payload_type == 4) {
-            bool isCC = false;
-            if (payload_size > 1 + 2 + 4 + 1) {
-                // user_data_registered_itu_t_t35()
-
-                // ATSC A/72: 6.4.2
-                uint8_t itu_t_t35_country_code = br.getBits(8);
-                uint16_t itu_t_t35_provider_code = br.getBits(16);
-                uint32_t user_identifier = br.getBits(32);
-                uint8_t user_data_type_code = br.getBits(8);
-
-                payload_size -= 1 + 2 + 4 + 1;
-
-                isCC = itu_t_t35_country_code == 0xB5
-                        && itu_t_t35_provider_code == 0x0031
-                        && user_identifier == 'GA94'
-                        && user_data_type_code == 0x3;
-            }
-
-            if (isCC && payload_size > 2) {
-                trackAdded |= parseMPEGCCData(timeUs, br.data(), br.numBitsLeft() / 8);
-            } else {
-                ALOGV("Malformed SEI payload type 4");
-            }
-        } else {
-            ALOGV("Unsupported SEI payload type %d", payload_type);
-        }
-
-        // skipping remaining bits of this payload
-        br.skipBits(payload_size * 8);
-    }
-
-    return trackAdded;
-}
-
-// returns true if a new CC track is found
-bool NuPlayer2::CCDecoder::extractFromMPEGUserData(const sp<ABuffer> &accessUnit) {
-    sp<ABuffer> mpegUserData;
-    if (!accessUnit->meta()->findBuffer(AMEDIAFORMAT_KEY_MPEG_USER_DATA, &mpegUserData)
-            || mpegUserData == NULL) {
-        return false;
-    }
-
-    int64_t timeUs;
-    CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
-
-    bool trackAdded = false;
-
-    const size_t *userData = (size_t *)mpegUserData->data();
-
-    for (size_t i = 0; i < mpegUserData->size() / sizeof(size_t); ++i) {
-        trackAdded |= parseMPEGUserDataUnit(
-                timeUs, accessUnit->data() + userData[i], accessUnit->size() - userData[i]);
-    }
-
-    return trackAdded;
-}
-
-// returns true if a new CC track is found
-bool NuPlayer2::CCDecoder::parseMPEGUserDataUnit(int64_t timeUs, const uint8_t *data, size_t size) {
-    ABitReader br(data + 4, 5);
-
-    uint32_t user_identifier = br.getBits(32);
-    uint8_t user_data_type = br.getBits(8);
-
-    if (user_identifier == 'GA94' && user_data_type == 0x3) {
-        return parseMPEGCCData(timeUs, data + 9, size - 9);
-    }
-
-    return false;
-}
-
-// returns true if a new CC track is found
-bool NuPlayer2::CCDecoder::parseMPEGCCData(int64_t timeUs, const uint8_t *data, size_t size) {
-    bool trackAdded = false;
-
-    // MPEG_cc_data()
-    // ATSC A/53 Part 4: 6.2.3.1
-    ABitReader br(data, size);
-
-    if (br.numBitsLeft() <= 16) {
-        return false;
-    }
-
-    br.skipBits(1);
-    bool process_cc_data_flag = br.getBits(1);
-    br.skipBits(1);
-    size_t cc_count = br.getBits(5);
-    br.skipBits(8);
-
-    if (!process_cc_data_flag || 3 * 8 * cc_count >= br.numBitsLeft()) {
-        return false;
-    }
-
-    sp<ABuffer> line21CCBuf = NULL;
-
-    for (size_t i = 0; i < cc_count; ++i) {
-        br.skipBits(5);
-        bool cc_valid = br.getBits(1);
-        uint8_t cc_type = br.getBits(2);
-
-        if (cc_valid) {
-            if (cc_type == 3) {
-                if (mDTVCCPacket->size() > 0) {
-                    trackAdded |= parseDTVCCPacket(
-                            timeUs, mDTVCCPacket->data(), mDTVCCPacket->size());
-                    mDTVCCPacket->setRange(0, 0);
-                }
-                if (mDTVCCPacket->size() + 2 > mDTVCCPacket->capacity()) {
-                    return false;
-                }
-                memcpy(mDTVCCPacket->data() + mDTVCCPacket->size(), br.data(), 2);
-                mDTVCCPacket->setRange(0, mDTVCCPacket->size() + 2);
-                br.skipBits(16);
-            } else if (mDTVCCPacket->size() > 0 && cc_type == 2) {
-                if (mDTVCCPacket->size() + 2 > mDTVCCPacket->capacity()) {
-                    return false;
-                }
-                memcpy(mDTVCCPacket->data() + mDTVCCPacket->size(), br.data(), 2);
-                mDTVCCPacket->setRange(0, mDTVCCPacket->size() + 2);
-                br.skipBits(16);
-            } else if (cc_type == 0 || cc_type == 1) {
-                uint8_t cc_data_1 = br.getBits(8) & 0x7f;
-                uint8_t cc_data_2 = br.getBits(8) & 0x7f;
-
-                CCData cc(cc_type, cc_data_1, cc_data_2);
-
-                if (isNullPad(&cc)) {
-                    continue;
-                }
-
-                size_t channel;
-                if (cc.getChannel(&channel)) {
-                    mLine21Channels[cc_type] = channel;
-
-                    // create a new track if it does not exist.
-                    getTrackIndex(kTrackTypeCEA608, channel, &trackAdded);
-                }
-
-                if (isSelected() && mTracks[mSelectedTrack].mTrackType == kTrackTypeCEA608
-                        && mTracks[mSelectedTrack].mTrackChannel == mLine21Channels[cc_type]) {
-                    if (line21CCBuf == NULL) {
-                        line21CCBuf = new ABuffer((cc_count - i) * sizeof(CCData));
-                        line21CCBuf->setRange(0, 0);
-                    }
-                    if (line21CCBuf->size() + sizeof(cc) > line21CCBuf->capacity()) {
-                        return false;
-                    }
-                    memcpy(line21CCBuf->data() + line21CCBuf->size(), &cc, sizeof(cc));
-                    line21CCBuf->setRange(0, line21CCBuf->size() + sizeof(CCData));
-                }
-            } else {
-                br.skipBits(16);
-            }
-        } else {
-            if ((cc_type == 3 || cc_type == 2) && mDTVCCPacket->size() > 0) {
-                trackAdded |= parseDTVCCPacket(timeUs, mDTVCCPacket->data(), mDTVCCPacket->size());
-                mDTVCCPacket->setRange(0, 0);
-            }
-            br.skipBits(16);
-        }
-    }
-
-    if (isSelected() && mTracks[mSelectedTrack].mTrackType == kTrackTypeCEA608
-            && line21CCBuf != NULL && line21CCBuf->size() > 0) {
-        mCCMap.add(timeUs, line21CCBuf);
-    }
-
-    return trackAdded;
-}
-
-// returns true if a new CC track is found
-bool NuPlayer2::CCDecoder::parseDTVCCPacket(int64_t timeUs, const uint8_t *data, size_t size) {
-    // CEA-708B 5 DTVCC Packet Layer.
-    ABitReader br(data, size);
-    br.skipBits(2);
-
-    size_t packet_size = br.getBits(6);
-    if (packet_size == 0) packet_size = 64;
-    packet_size *= 2;
-
-    if (size != packet_size) {
-        return false;
-    }
-
-    bool trackAdded = false;
-
-    while (br.numBitsLeft() >= 16) {
-        // CEA-708B Figure 5 and 6.
-        uint8_t service_number = br.getBits(3);
-        size_t block_size = br.getBits(5);
-
-        if (service_number == 64) {
-            br.skipBits(2);
-            service_number = br.getBits(6);
-
-            if (service_number < 64) {
-                return trackAdded;
-            }
-        }
-
-        if (br.numBitsLeft() < block_size * 8) {
-            return trackAdded;
-        }
-
-        if (block_size > 0) {
-            size_t trackIndex = getTrackIndex(kTrackTypeCEA708, service_number, &trackAdded);
-            if (mSelectedTrack == (ssize_t)trackIndex) {
-                sp<ABuffer> ccPacket = new ABuffer(block_size);
-                if (ccPacket->capacity() == 0) {
-                    return false;
-                }
-                memcpy(ccPacket->data(), br.data(), block_size);
-                mCCMap.add(timeUs, ccPacket);
-            }
-        }
-        br.skipBits(block_size * 8);
-    }
-
-    return trackAdded;
-}
-
-// return the track index for a given type and channel.
-// if the track does not exist, creates a new one.
-size_t NuPlayer2::CCDecoder::getTrackIndex(
-        int32_t trackType, size_t channel, bool *trackAdded) {
-    CCTrack track(trackType, channel);
-    ssize_t index = mTrackIndices.indexOfKey(track);
-
-    if (index < 0) {
-        // A new track is added.
-        index = mTracks.size();
-        mTrackIndices.add(track, index);
-        mTracks.add(track);
-        *trackAdded = true;
-        return index;
-    }
-
-    return mTrackIndices.valueAt(index);
-}
-
-void NuPlayer2::CCDecoder::decode(const sp<ABuffer> &accessUnit) {
-    if (extractFromMPEGUserData(accessUnit) || extractFromSEI(accessUnit)) {
-        sp<AMessage> msg = mNotify->dup();
-        msg->setInt32("what", kWhatTrackAdded);
-        msg->post();
-    }
-    // TODO: extract CC from other sources
-}
-
-void NuPlayer2::CCDecoder::display(int64_t timeUs) {
-    if (!isSelected()) {
-        return;
-    }
-
-    ssize_t index = mCCMap.indexOfKey(timeUs);
-    if (index < 0) {
-        ALOGV("cc for timestamp %" PRId64 " not found", timeUs);
-        return;
-    }
-
-    sp<ABuffer> ccBuf;
-
-    if (index == 0) {
-        ccBuf = mCCMap.valueAt(index);
-    } else {
-        size_t size = 0;
-
-        for (ssize_t i = 0; i <= index; ++i) {
-            size += mCCMap.valueAt(i)->size();
-        }
-
-        ccBuf = new ABuffer(size);
-        ccBuf->setRange(0, 0);
-
-        if (ccBuf->capacity() > 0) {
-            for (ssize_t i = 0; i <= index; ++i) {
-                sp<ABuffer> buf = mCCMap.valueAt(i);
-                memcpy(ccBuf->data() + ccBuf->size(), buf->data(), buf->size());
-                ccBuf->setRange(0, ccBuf->size() + buf->size());
-            }
-        }
-    }
-
-    if (ccBuf->size() > 0) {
-#if 0
-        dumpBytePair(ccBuf);
-#endif
-
-        ccBuf->meta()->setInt32(AMEDIAFORMAT_KEY_TRACK_INDEX, mSelectedTrack);
-        ccBuf->meta()->setInt64("timeUs", timeUs);
-        ccBuf->meta()->setInt64("durationUs", 0LL);
-
-        sp<AMessage> msg = mNotify->dup();
-        msg->setInt32("what", kWhatClosedCaptionData);
-        msg->setBuffer("buffer", ccBuf);
-        msg->post();
-    }
-
-    // remove all entries before timeUs
-    mCCMap.removeItemsAt(0, index + 1);
-}
-
-void NuPlayer2::CCDecoder::flush() {
-    mCCMap.clear();
-    mDTVCCPacket->setRange(0, 0);
-}
-
-int32_t NuPlayer2::CCDecoder::CCTrack::compare(const NuPlayer2::CCDecoder::CCTrack& rhs) const {
-    int32_t cmp = mTrackType - rhs.mTrackType;
-    if (cmp != 0) return cmp;
-    return mTrackChannel - rhs.mTrackChannel;
-}
-
-bool NuPlayer2::CCDecoder::CCTrack::operator<(const NuPlayer2::CCDecoder::CCTrack& rhs) const {
-    return compare(rhs) < 0;
-}
-
-bool NuPlayer2::CCDecoder::CCTrack::operator==(const NuPlayer2::CCDecoder::CCTrack& rhs) const {
-    return compare(rhs) == 0;
-}
-
-bool NuPlayer2::CCDecoder::CCTrack::operator!=(const NuPlayer2::CCDecoder::CCTrack& rhs) const {
-    return compare(rhs) != 0;
-}
-
-}  // namespace android
-
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.h b/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.h
deleted file mode 100644
index 97834d1..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-#ifndef NUPLAYER2_CCDECODER_H_
-
-#define NUPLAYER2_CCDECODER_H_
-
-#include "NuPlayer2.h"
-
-namespace android {
-
-struct NuPlayer2::CCDecoder : public RefBase {
-    enum {
-        kWhatClosedCaptionData,
-        kWhatTrackAdded,
-    };
-
-    enum {
-        kTrackTypeCEA608,
-        kTrackTypeCEA708,
-    };
-
-    explicit CCDecoder(const sp<AMessage> &notify);
-
-    size_t getTrackCount() const;
-    sp<AMessage> getTrackInfo(size_t index) const;
-    status_t selectTrack(size_t index, bool select);
-    ssize_t getSelectedTrack(media_track_type type) const;
-    bool isSelected() const;
-    void decode(const sp<ABuffer> &accessUnit);
-    void display(int64_t timeUs);
-    void flush();
-
-private:
-    // CC track identifier.
-    struct CCTrack {
-        CCTrack() : mTrackType(0), mTrackChannel(0) { }
-
-        CCTrack(const int32_t trackType, const size_t trackChannel)
-            : mTrackType(trackType), mTrackChannel(trackChannel) { }
-
-        int32_t mTrackType;
-        size_t mTrackChannel;
-
-        // The ordering of CCTracks is to build a map of track to index.
-        // It is necessary to find the index of the matched CCTrack when CC data comes.
-        int compare(const NuPlayer2::CCDecoder::CCTrack& rhs) const;
-        inline bool operator<(const NuPlayer2::CCDecoder::CCTrack& rhs) const;
-        inline bool operator==(const NuPlayer2::CCDecoder::CCTrack& rhs) const;
-        inline bool operator!=(const NuPlayer2::CCDecoder::CCTrack& rhs) const;
-    };
-
-    sp<AMessage> mNotify;
-    KeyedVector<int64_t, sp<ABuffer> > mCCMap;
-    ssize_t mSelectedTrack;
-    KeyedVector<CCTrack, size_t> mTrackIndices;
-    Vector<CCTrack> mTracks;
-
-    // CEA-608 closed caption
-    size_t mLine21Channels[2]; // The current channels of NTSC_CC_FIELD_{1, 2}
-
-    // CEA-708 closed caption
-    sp<ABuffer> mDTVCCPacket;
-
-    bool isTrackValid(size_t index) const;
-    size_t getTrackIndex(int32_t trackType, size_t channel, bool *trackAdded);
-
-    // Extract from H.264 SEIs
-    bool extractFromSEI(const sp<ABuffer> &accessUnit);
-    bool parseSEINalUnit(int64_t timeUs, const uint8_t *data, size_t size);
-
-    // Extract from MPEG user data
-    bool extractFromMPEGUserData(const sp<ABuffer> &accessUnit);
-    bool parseMPEGUserDataUnit(int64_t timeUs, const uint8_t *data, size_t size);
-
-    // Extract CC tracks from MPEG_cc_data
-    bool parseMPEGCCData(int64_t timeUs, const uint8_t *data, size_t size);
-    bool parseDTVCCPacket(int64_t timeUs, const uint8_t *data, size_t size);
-
-    DISALLOW_EVIL_CONSTRUCTORS(CCDecoder);
-};
-
-}  // namespace android
-
-#endif  // NUPLAYER2_CCDECODER_H_
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.cpp
deleted file mode 100644
index 66bfae5..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.cpp
+++ /dev/null
@@ -1,1315 +0,0 @@
-/*
- * Copyright 2017 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 "NuPlayer2Decoder"
-#include <utils/Log.h>
-#include <inttypes.h>
-
-#include <algorithm>
-
-#include "NuPlayer2CCDecoder.h"
-#include "NuPlayer2Decoder.h"
-#include "NuPlayer2Drm.h"
-#include "NuPlayer2Renderer.h"
-#include "NuPlayer2Source.h"
-
-#include <cutils/properties.h>
-#include <media/MediaBufferHolder.h>
-#include <media/MediaCodecBuffer.h>
-#include <media/NdkMediaCodec.h>
-#include <media/NdkWrapper.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/avc_utils.h>
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/SurfaceUtils.h>
-
-#include <system/window.h>
-#include "ATSParser.h"
-
-namespace android {
-
-static float kDisplayRefreshingRate = 60.f; // TODO: get this from the display
-
-// The default total video frame rate of a stream when that info is not available from
-// the source.
-static float kDefaultVideoFrameRateTotal = 30.f;
-
-static inline bool getAudioDeepBufferSetting() {
-    return property_get_bool("media.stagefright.audio.deep", false /* default_value */);
-}
-
-NuPlayer2::Decoder::Decoder(
-        const sp<AMessage> &notify,
-        const sp<Source> &source,
-        pid_t pid,
-        uid_t uid,
-        const sp<Renderer> &renderer,
-        const sp<ANativeWindowWrapper> &nww,
-        const sp<CCDecoder> &ccDecoder)
-    : DecoderBase(notify),
-      mNativeWindow(nww),
-      mSource(source),
-      mRenderer(renderer),
-      mCCDecoder(ccDecoder),
-      mPid(pid),
-      mUid(uid),
-      mSkipRenderingUntilMediaTimeUs(-1LL),
-      mNumFramesTotal(0LL),
-      mNumInputFramesDropped(0LL),
-      mNumOutputFramesDropped(0LL),
-      mVideoWidth(0),
-      mVideoHeight(0),
-      mIsAudio(true),
-      mIsVideoAVC(false),
-      mIsSecure(false),
-      mIsEncrypted(false),
-      mIsEncryptedObservedEarlier(false),
-      mFormatChangePending(false),
-      mTimeChangePending(false),
-      mFrameRateTotal(kDefaultVideoFrameRateTotal),
-      mPlaybackSpeed(1.0f),
-      mNumVideoTemporalLayerTotal(1), // decode all layers
-      mNumVideoTemporalLayerAllowed(1),
-      mCurrentMaxVideoTemporalLayerId(0),
-      mResumePending(false),
-      mComponentName("decoder") {
-    mVideoTemporalLayerAggregateFps[0] = mFrameRateTotal;
-}
-
-NuPlayer2::Decoder::~Decoder() {
-    // Need to stop looper first since mCodec could be accessed on the mDecoderLooper.
-    stopLooper();
-    if (mCodec != NULL) {
-        mCodec->release();
-    }
-    releaseAndResetMediaBuffers();
-}
-
-sp<AMessage> NuPlayer2::Decoder::getStats() const {
-    mStats->setInt64("frames-total", mNumFramesTotal);
-    mStats->setInt64("frames-dropped-input", mNumInputFramesDropped);
-    mStats->setInt64("frames-dropped-output", mNumOutputFramesDropped);
-    mStats->setFloat("frame-rate-total", mFrameRateTotal);
-
-    // i'm mutexed right now.
-    // make our own copy, so we aren't victim to any later changes.
-    sp<AMessage> copiedStats = mStats->dup();
-    return copiedStats;
-}
-
-status_t NuPlayer2::Decoder::setVideoSurface(const sp<ANativeWindowWrapper> &nww) {
-    if (nww == NULL || nww->getANativeWindow() == NULL
-        || ADebug::isExperimentEnabled("legacy-setsurface")) {
-        return BAD_VALUE;
-    }
-
-    sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
-
-    msg->setObject("surface", nww);
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-    }
-    return err;
-}
-
-void NuPlayer2::Decoder::onMessageReceived(const sp<AMessage> &msg) {
-    ALOGV("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str());
-
-    switch (msg->what()) {
-        case kWhatCodecNotify:
-        {
-            int32_t cbID;
-            CHECK(msg->findInt32("callbackID", &cbID));
-
-            ALOGV("[%s] kWhatCodecNotify: cbID = %d, paused = %d",
-                    mIsAudio ? "audio" : "video", cbID, mPaused);
-
-            if (mPaused) {
-                break;
-            }
-
-            switch (cbID) {
-                case AMediaCodecWrapper::CB_INPUT_AVAILABLE:
-                {
-                    int32_t index;
-                    CHECK(msg->findInt32("index", &index));
-
-                    handleAnInputBuffer(index);
-                    break;
-                }
-
-                case AMediaCodecWrapper::CB_OUTPUT_AVAILABLE:
-                {
-                    int32_t index;
-                    size_t offset;
-                    size_t size;
-                    int64_t timeUs;
-                    int32_t flags;
-
-                    CHECK(msg->findInt32("index", &index));
-                    CHECK(msg->findSize("offset", &offset));
-                    CHECK(msg->findSize("size", &size));
-                    CHECK(msg->findInt64("timeUs", &timeUs));
-                    CHECK(msg->findInt32("flags", &flags));
-
-                    handleAnOutputBuffer(index, offset, size, timeUs, flags);
-                    break;
-                }
-
-                case AMediaCodecWrapper::CB_OUTPUT_FORMAT_CHANGED:
-                {
-                    sp<AMessage> format;
-                    CHECK(msg->findMessage("format", &format));
-
-                    handleOutputFormatChange(format);
-                    break;
-                }
-
-                case AMediaCodecWrapper::CB_ERROR:
-                {
-                    status_t err;
-                    CHECK(msg->findInt32("err", &err));
-                    ALOGE("Decoder (%s) reported error : 0x%x",
-                            mIsAudio ? "audio" : "video", err);
-
-                    handleError(err);
-                    break;
-                }
-
-                default:
-                {
-                    TRESPASS();
-                    break;
-                }
-            }
-
-            break;
-        }
-
-        case kWhatRenderBuffer:
-        {
-            if (!isStaleReply(msg)) {
-                onRenderBuffer(msg);
-            }
-            break;
-        }
-
-        case kWhatAudioOutputFormatChanged:
-        {
-            if (!isStaleReply(msg)) {
-                status_t err;
-                if (msg->findInt32("err", &err) && err != OK) {
-                    ALOGE("Renderer reported 0x%x when changing audio output format", err);
-                    handleError(err);
-                }
-            }
-            break;
-        }
-
-        case kWhatSetVideoSurface:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-
-            sp<RefBase> obj;
-            CHECK(msg->findObject("surface", &obj));
-            sp<ANativeWindowWrapper> nww =
-                static_cast<ANativeWindowWrapper *>(obj.get()); // non-null
-            if (nww == NULL || nww->getANativeWindow() == NULL) {
-                break;
-            }
-            int32_t err = INVALID_OPERATION;
-            // NOTE: in practice mNativeWindow is always non-null,
-            // but checking here for completeness
-            if (mCodec != NULL
-                && mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
-                // TODO: once AwesomePlayer is removed, remove this automatic connecting
-                // to the surface by MediaPlayerService.
-                //
-                // at this point MediaPlayer2Manager::client has already connected to the
-                // surface, which MediaCodec does not expect
-                err = native_window_api_disconnect(nww->getANativeWindow(),
-                                                   NATIVE_WINDOW_API_MEDIA);
-                if (err == OK) {
-                    err = mCodec->setOutputSurface(nww);
-                    ALOGI_IF(err, "codec setOutputSurface returned: %d", err);
-                    if (err == OK) {
-                        // reconnect to the old surface as MPS::Client will expect to
-                        // be able to disconnect from it.
-                        (void)native_window_api_connect(mNativeWindow->getANativeWindow(),
-                                                        NATIVE_WINDOW_API_MEDIA);
-
-                        mNativeWindow = nww;
-                    }
-                }
-                if (err != OK) {
-                    // reconnect to the new surface on error as MPS::Client will expect to
-                    // be able to disconnect from it.
-                    (void)native_window_api_connect(nww->getANativeWindow(),
-                                                    NATIVE_WINDOW_API_MEDIA);
-                }
-            }
-
-            sp<AMessage> response = new AMessage;
-            response->setInt32("err", err);
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatDrmReleaseCrypto:
-        {
-            ALOGV("kWhatDrmReleaseCrypto");
-            onReleaseCrypto(msg);
-            break;
-        }
-
-        default:
-            DecoderBase::onMessageReceived(msg);
-            break;
-    }
-}
-
-void NuPlayer2::Decoder::onConfigure(const sp<AMessage> &format) {
-    ALOGV("[%s] onConfigure (format=%s)", mComponentName.c_str(), format->debugString().c_str());
-    CHECK(mCodec == NULL);
-
-    mFormatChangePending = false;
-    mTimeChangePending = false;
-
-    ++mBufferGeneration;
-
-    AString mime;
-    CHECK(format->findString("mime", &mime));
-
-    mIsAudio = !strncasecmp("audio/", mime.c_str(), 6);
-    mIsVideoAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
-
-    mComponentName = mime;
-    mComponentName.append(" decoder");
-    ALOGV("[%s] onConfigure (nww=%p)", mComponentName.c_str(),
-          (mNativeWindow == NULL ? NULL : mNativeWindow->getANativeWindow()));
-
-    mCodec = AMediaCodecWrapper::CreateDecoderByType(mime);
-    int32_t secure = 0;
-    if (format->findInt32("secure", &secure) && secure != 0) {
-        if (mCodec != NULL) {
-            if (mCodec->getName(&mComponentName) == OK) {
-                mComponentName.append(".secure");
-                mCodec->release();
-                ALOGI("[%s] creating", mComponentName.c_str());
-                mCodec = AMediaCodecWrapper::CreateCodecByName(mComponentName);
-            } else {
-                mCodec = NULL;
-            }
-        }
-    }
-    if (mCodec == NULL) {
-        ALOGE("Failed to create %s%s decoder",
-                (secure ? "secure " : ""), mime.c_str());
-        handleError(NO_INIT);
-        return;
-    }
-    mIsSecure = secure;
-
-    mCodec->getName(&mComponentName);
-
-    status_t err;
-    if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
-        // disconnect from surface as MediaCodec will reconnect
-        err = native_window_api_disconnect(mNativeWindow->getANativeWindow(),
-                                           NATIVE_WINDOW_API_MEDIA);
-        // We treat this as a warning, as this is a preparatory step.
-        // Codec will try to connect to the surface, which is where
-        // any error signaling will occur.
-        ALOGW_IF(err != OK, "failed to disconnect from surface: %d", err);
-    }
-
-    // Modular DRM
-    sp<RefBase> objCrypto;
-    format->findObject("crypto", &objCrypto);
-    sp<AMediaCryptoWrapper> crypto = static_cast<AMediaCryptoWrapper *>(objCrypto.get());
-    // non-encrypted source won't have a crypto
-    mIsEncrypted = (crypto != NULL);
-    // configure is called once; still using OR in case the behavior changes.
-    mIsEncryptedObservedEarlier = mIsEncryptedObservedEarlier || mIsEncrypted;
-    ALOGV("onConfigure mCrypto: %p, mIsSecure: %d", crypto.get(), mIsSecure);
-
-    err = mCodec->configure(
-            AMediaFormatWrapper::Create(format),
-            mNativeWindow,
-            crypto,
-            0 /* flags */);
-
-    if (err != OK) {
-        ALOGE("Failed to configure [%s] decoder (err=%d)", mComponentName.c_str(), err);
-        mCodec->release();
-        mCodec.clear();
-        handleError(err);
-        return;
-    }
-    rememberCodecSpecificData(format);
-
-    // the following should work in configured state
-    sp<AMediaFormatWrapper> outputFormat = mCodec->getOutputFormat();
-    if (outputFormat == NULL) {
-        handleError(INVALID_OPERATION);
-        return;
-    }
-    mInputFormat = mCodec->getInputFormat();
-    if (mInputFormat == NULL) {
-        handleError(INVALID_OPERATION);
-        return;
-    }
-
-    mStats->setString("mime", mime.c_str());
-    mStats->setString("component-name", mComponentName.c_str());
-
-    if (!mIsAudio) {
-        int32_t width, height;
-        if (outputFormat->getInt32("width", &width)
-                && outputFormat->getInt32("height", &height)) {
-            mStats->setInt32("width", width);
-            mStats->setInt32("height", height);
-        }
-    }
-
-    sp<AMessage> reply = new AMessage(kWhatCodecNotify, this);
-    mCodec->setCallback(reply);
-
-    err = mCodec->start();
-    if (err != OK) {
-        ALOGE("Failed to start [%s] decoder (err=%d)", mComponentName.c_str(), err);
-        mCodec->release();
-        mCodec.clear();
-        handleError(err);
-        return;
-    }
-
-    releaseAndResetMediaBuffers();
-
-    mPaused = false;
-    mResumePending = false;
-}
-
-void NuPlayer2::Decoder::onSetParameters(const sp<AMessage> &params) {
-    bool needAdjustLayers = false;
-    float frameRateTotal;
-    if (params->findFloat("frame-rate-total", &frameRateTotal)
-            && mFrameRateTotal != frameRateTotal) {
-        needAdjustLayers = true;
-        mFrameRateTotal = frameRateTotal;
-    }
-
-    int32_t numVideoTemporalLayerTotal;
-    if (params->findInt32("temporal-layer-count", &numVideoTemporalLayerTotal)
-            && numVideoTemporalLayerTotal >= 0
-            && numVideoTemporalLayerTotal <= kMaxNumVideoTemporalLayers
-            && mNumVideoTemporalLayerTotal != numVideoTemporalLayerTotal) {
-        needAdjustLayers = true;
-        mNumVideoTemporalLayerTotal = std::max(numVideoTemporalLayerTotal, 1);
-    }
-
-    if (needAdjustLayers && mNumVideoTemporalLayerTotal > 1) {
-        // TODO: For now, layer fps is calculated for some specific architectures.
-        // But it really should be extracted from the stream.
-        mVideoTemporalLayerAggregateFps[0] =
-            mFrameRateTotal / (float)(1LL << (mNumVideoTemporalLayerTotal - 1));
-        for (int32_t i = 1; i < mNumVideoTemporalLayerTotal; ++i) {
-            mVideoTemporalLayerAggregateFps[i] =
-                mFrameRateTotal / (float)(1LL << (mNumVideoTemporalLayerTotal - i))
-                + mVideoTemporalLayerAggregateFps[i - 1];
-        }
-    }
-
-    float playbackSpeed;
-    if (params->findFloat("playback-speed", &playbackSpeed)
-            && mPlaybackSpeed != playbackSpeed) {
-        needAdjustLayers = true;
-        mPlaybackSpeed = playbackSpeed;
-    }
-
-    if (needAdjustLayers) {
-        float decodeFrameRate = mFrameRateTotal;
-        // enable temporal layering optimization only if we know the layering depth
-        if (mNumVideoTemporalLayerTotal > 1) {
-            int32_t layerId;
-            for (layerId = 0; layerId < mNumVideoTemporalLayerTotal - 1; ++layerId) {
-                if (mVideoTemporalLayerAggregateFps[layerId] * mPlaybackSpeed
-                        >= kDisplayRefreshingRate * 0.9) {
-                    break;
-                }
-            }
-            mNumVideoTemporalLayerAllowed = layerId + 1;
-            decodeFrameRate = mVideoTemporalLayerAggregateFps[layerId];
-        }
-        ALOGV("onSetParameters: allowed layers=%d, decodeFps=%g",
-                mNumVideoTemporalLayerAllowed, decodeFrameRate);
-
-        if (mCodec == NULL) {
-            ALOGW("onSetParameters called before codec is created.");
-            return;
-        }
-
-        sp<AMediaFormatWrapper> codecParams = new AMediaFormatWrapper();
-        codecParams->setFloat("operating-rate", decodeFrameRate * mPlaybackSpeed);
-        mCodec->setParameters(codecParams);
-    }
-}
-
-void NuPlayer2::Decoder::onSetRenderer(const sp<Renderer> &renderer) {
-    mRenderer = renderer;
-}
-
-void NuPlayer2::Decoder::onResume(bool notifyComplete) {
-    mPaused = false;
-
-    if (notifyComplete) {
-        mResumePending = true;
-    }
-
-    if (mCodec == NULL) {
-        ALOGE("[%s] onResume without a valid codec", mComponentName.c_str());
-        handleError(NO_INIT);
-        return;
-    }
-    mCodec->start();
-}
-
-void NuPlayer2::Decoder::doFlush(bool notifyComplete) {
-    if (mCCDecoder != NULL) {
-        mCCDecoder->flush();
-    }
-
-    if (mRenderer != NULL) {
-        mRenderer->flush(mIsAudio, notifyComplete);
-        mRenderer->signalTimeDiscontinuity();
-    }
-
-    status_t err = OK;
-    if (mCodec != NULL) {
-        err = mCodec->flush();
-        mCSDsToSubmit = mCSDsForCurrentFormat; // copy operator
-        ++mBufferGeneration;
-    }
-
-    if (err != OK) {
-        ALOGE("failed to flush [%s] (err=%d)", mComponentName.c_str(), err);
-        handleError(err);
-        // finish with posting kWhatFlushCompleted.
-        // we attempt to release the buffers even if flush fails.
-    }
-    releaseAndResetMediaBuffers();
-    mPaused = true;
-}
-
-
-void NuPlayer2::Decoder::onFlush() {
-    doFlush(true);
-
-    if (isDiscontinuityPending()) {
-        // This could happen if the client starts seeking/shutdown
-        // after we queued an EOS for discontinuities.
-        // We can consider discontinuity handled.
-        finishHandleDiscontinuity(false /* flushOnTimeChange */);
-    }
-
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatFlushCompleted);
-    notify->post();
-}
-
-void NuPlayer2::Decoder::onShutdown(bool notifyComplete) {
-    status_t err = OK;
-
-    // if there is a pending resume request, notify complete now
-    notifyResumeCompleteIfNecessary();
-
-    if (mCodec != NULL) {
-        err = mCodec->release();
-        mCodec = NULL;
-        ++mBufferGeneration;
-
-        if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
-            // reconnect to surface as MediaCodec disconnected from it
-            status_t error = native_window_api_connect(mNativeWindow->getANativeWindow(),
-                                                       NATIVE_WINDOW_API_MEDIA);
-            ALOGW_IF(error != NO_ERROR,
-                    "[%s] failed to connect to native window, error=%d",
-                    mComponentName.c_str(), error);
-        }
-        mComponentName = "decoder";
-    }
-
-    releaseAndResetMediaBuffers();
-
-    if (err != OK) {
-        ALOGE("failed to release [%s] (err=%d)", mComponentName.c_str(), err);
-        handleError(err);
-        // finish with posting kWhatShutdownCompleted.
-    }
-
-    if (notifyComplete) {
-        sp<AMessage> notify = mNotify->dup();
-        notify->setInt32("what", kWhatShutdownCompleted);
-        notify->post();
-        mPaused = true;
-    }
-}
-
-/*
- * returns true if we should request more data
- */
-bool NuPlayer2::Decoder::doRequestBuffers() {
-    if (isDiscontinuityPending()) {
-        return false;
-    }
-    status_t err = OK;
-    while (err == OK && !mDequeuedInputBuffers.empty()) {
-        size_t bufferIx = *mDequeuedInputBuffers.begin();
-        sp<AMessage> msg = new AMessage();
-        msg->setSize("buffer-ix", bufferIx);
-        err = fetchInputData(msg);
-        if (err != OK && err != ERROR_END_OF_STREAM) {
-            // if EOS, need to queue EOS buffer
-            break;
-        }
-        mDequeuedInputBuffers.erase(mDequeuedInputBuffers.begin());
-
-        if (!mPendingInputMessages.empty()
-                || !onInputBufferFetched(msg)) {
-            mPendingInputMessages.push_back(msg);
-        }
-    }
-
-    return err == -EWOULDBLOCK
-            && mSource->feedMoreTSData() == OK;
-}
-
-void NuPlayer2::Decoder::handleError(int32_t err)
-{
-    // We cannot immediately release the codec due to buffers still outstanding
-    // in the renderer.  We signal to the player the error so it can shutdown/release the
-    // decoder after flushing and increment the generation to discard unnecessary messages.
-
-    ++mBufferGeneration;
-
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatError);
-    notify->setInt32("err", err);
-    notify->post();
-}
-
-status_t NuPlayer2::Decoder::releaseCrypto()
-{
-    ALOGV("releaseCrypto");
-
-    sp<AMessage> msg = new AMessage(kWhatDrmReleaseCrypto, this);
-
-    sp<AMessage> response;
-    status_t status = msg->postAndAwaitResponse(&response);
-    if (status == OK && response != NULL) {
-        CHECK(response->findInt32("status", &status));
-        ALOGV("releaseCrypto ret: %d ", status);
-    } else {
-        ALOGE("releaseCrypto err: %d", status);
-    }
-
-    return status;
-}
-
-void NuPlayer2::Decoder::onReleaseCrypto(const sp<AMessage>& msg)
-{
-    status_t status = INVALID_OPERATION;
-    if (mCodec != NULL) {
-        status = mCodec->releaseCrypto();
-    } else {
-        // returning OK if the codec has been already released
-        status = OK;
-        ALOGE("onReleaseCrypto No mCodec. err: %d", status);
-    }
-
-    sp<AMessage> response = new AMessage;
-    response->setInt32("status", status);
-    // Clearing the state as it's tied to crypto. mIsEncryptedObservedEarlier is sticky though
-    // and lasts for the lifetime of this codec. See its use in fetchInputData.
-    mIsEncrypted = false;
-
-    sp<AReplyToken> replyID;
-    CHECK(msg->senderAwaitsResponse(&replyID));
-    response->postReply(replyID);
-}
-
-bool NuPlayer2::Decoder::handleAnInputBuffer(size_t index) {
-    if (isDiscontinuityPending()) {
-        return false;
-    }
-
-    if (mCodec == NULL) {
-        ALOGE("[%s] handleAnInputBuffer without a valid codec", mComponentName.c_str());
-        handleError(NO_INIT);
-        return false;
-    }
-
-    size_t bufferSize = 0;
-    uint8_t *bufferBase = mCodec->getInputBuffer(index, &bufferSize);
-
-    if (bufferBase == NULL) {
-        ALOGE("[%s] handleAnInputBuffer, failed to get input buffer", mComponentName.c_str());
-        handleError(UNKNOWN_ERROR);
-        return false;
-    }
-
-    sp<MediaCodecBuffer> buffer =
-        new MediaCodecBuffer(NULL /* format */, new ABuffer(bufferBase, bufferSize));
-
-    if (index >= mInputBuffers.size()) {
-        for (size_t i = mInputBuffers.size(); i <= index; ++i) {
-            mInputBuffers.add();
-            mMediaBuffers.add();
-            mInputBufferIsDequeued.add();
-            mMediaBuffers.editItemAt(i) = NULL;
-            mInputBufferIsDequeued.editItemAt(i) = false;
-        }
-    }
-    mInputBuffers.editItemAt(index) = buffer;
-
-    //CHECK_LT(bufferIx, mInputBuffers.size());
-
-    if (mMediaBuffers[index] != NULL) {
-        mMediaBuffers[index]->release();
-        mMediaBuffers.editItemAt(index) = NULL;
-    }
-    mInputBufferIsDequeued.editItemAt(index) = true;
-
-    if (!mCSDsToSubmit.isEmpty()) {
-        sp<AMessage> msg = new AMessage();
-        msg->setSize("buffer-ix", index);
-
-        sp<ABuffer> buffer = mCSDsToSubmit.itemAt(0);
-        ALOGI("[%s] resubmitting CSD", mComponentName.c_str());
-        msg->setBuffer("buffer", buffer);
-        mCSDsToSubmit.removeAt(0);
-        if (!onInputBufferFetched(msg)) {
-            handleError(UNKNOWN_ERROR);
-            return false;
-        }
-        return true;
-    }
-
-    while (!mPendingInputMessages.empty()) {
-        sp<AMessage> msg = *mPendingInputMessages.begin();
-        if (!onInputBufferFetched(msg)) {
-            break;
-        }
-        mPendingInputMessages.erase(mPendingInputMessages.begin());
-    }
-
-    if (!mInputBufferIsDequeued.editItemAt(index)) {
-        return true;
-    }
-
-    mDequeuedInputBuffers.push_back(index);
-
-    onRequestInputBuffers();
-    return true;
-}
-
-bool NuPlayer2::Decoder::handleAnOutputBuffer(
-        size_t index,
-        size_t offset,
-        size_t size,
-        int64_t timeUs,
-        int32_t flags) {
-    if (mCodec == NULL) {
-        ALOGE("[%s] handleAnOutputBuffer without a valid codec", mComponentName.c_str());
-        handleError(NO_INIT);
-        return false;
-    }
-
-//    CHECK_LT(bufferIx, mOutputBuffers.size());
-
-    size_t bufferSize = 0;
-    uint8_t *bufferBase = mCodec->getOutputBuffer(index, &bufferSize);
-
-    if (bufferBase == NULL) {
-        ALOGE("[%s] handleAnOutputBuffer, failed to get output buffer", mComponentName.c_str());
-        handleError(UNKNOWN_ERROR);
-        return false;
-    }
-
-    sp<MediaCodecBuffer> buffer =
-        new MediaCodecBuffer(NULL /* format */, new ABuffer(bufferBase, bufferSize));
-
-    if (index >= mOutputBuffers.size()) {
-        for (size_t i = mOutputBuffers.size(); i <= index; ++i) {
-            mOutputBuffers.add();
-        }
-    }
-
-    mOutputBuffers.editItemAt(index) = buffer;
-
-    buffer->setRange(offset, size);
-    buffer->meta()->clear();
-    buffer->meta()->setInt64("timeUs", timeUs);
-
-    bool eos = flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM;
-    // we do not expect CODECCONFIG or SYNCFRAME for decoder
-
-    sp<AMessage> reply = new AMessage(kWhatRenderBuffer, this);
-    reply->setSize("buffer-ix", index);
-    reply->setInt32("generation", mBufferGeneration);
-
-    if (eos) {
-        ALOGI("[%s] saw output EOS", mIsAudio ? "audio" : "video");
-
-        buffer->meta()->setInt32("eos", true);
-        reply->setInt32("eos", true);
-    }
-
-    mNumFramesTotal += !mIsAudio;
-
-    if (mSkipRenderingUntilMediaTimeUs >= 0) {
-        if (timeUs < mSkipRenderingUntilMediaTimeUs) {
-            ALOGV("[%s] dropping buffer at time %lld as requested.",
-                     mComponentName.c_str(), (long long)timeUs);
-
-            reply->post();
-            if (eos) {
-                notifyResumeCompleteIfNecessary();
-                if (mRenderer != NULL && !isDiscontinuityPending()) {
-                    mRenderer->queueEOS(mIsAudio, ERROR_END_OF_STREAM);
-                }
-            }
-            return true;
-        }
-
-        mSkipRenderingUntilMediaTimeUs = -1;
-    }
-
-    // wait until 1st frame comes out to signal resume complete
-    notifyResumeCompleteIfNecessary();
-
-    if (mRenderer != NULL) {
-        // send the buffer to renderer.
-        mRenderer->queueBuffer(mIsAudio, buffer, reply);
-        if (eos && !isDiscontinuityPending()) {
-            mRenderer->queueEOS(mIsAudio, ERROR_END_OF_STREAM);
-        }
-    }
-
-    return true;
-}
-
-void NuPlayer2::Decoder::handleOutputFormatChange(const sp<AMessage> &format) {
-    if (!mIsAudio) {
-        int32_t width, height;
-        if (format->findInt32("width", &width)
-                && format->findInt32("height", &height)) {
-            mStats->setInt32("width", width);
-            mStats->setInt32("height", height);
-        }
-        sp<AMessage> notify = mNotify->dup();
-        notify->setInt32("what", kWhatVideoSizeChanged);
-        notify->setMessage("format", format);
-        notify->post();
-    } else if (mRenderer != NULL) {
-        uint32_t flags;
-        int64_t durationUs;
-        bool hasVideo = (mSource->getFormat(false /* audio */) != NULL);
-        if (getAudioDeepBufferSetting() // override regardless of source duration
-                || (mSource->getDuration(&durationUs) == OK
-                        && durationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US)) {
-            flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
-        } else {
-            flags = AUDIO_OUTPUT_FLAG_NONE;
-        }
-
-        sp<AMessage> reply = new AMessage(kWhatAudioOutputFormatChanged, this);
-        reply->setInt32("generation", mBufferGeneration);
-        mRenderer->changeAudioFormat(
-                format, false /* offloadOnly */, hasVideo,
-                flags, mSource->isStreaming(), reply);
-    }
-}
-
-void NuPlayer2::Decoder::releaseAndResetMediaBuffers() {
-    for (size_t i = 0; i < mMediaBuffers.size(); i++) {
-        if (mMediaBuffers[i] != NULL) {
-            mMediaBuffers[i]->release();
-            mMediaBuffers.editItemAt(i) = NULL;
-        }
-    }
-    mMediaBuffers.resize(mInputBuffers.size());
-    for (size_t i = 0; i < mMediaBuffers.size(); i++) {
-        mMediaBuffers.editItemAt(i) = NULL;
-    }
-    mInputBufferIsDequeued.clear();
-    mInputBufferIsDequeued.resize(mInputBuffers.size());
-    for (size_t i = 0; i < mInputBufferIsDequeued.size(); i++) {
-        mInputBufferIsDequeued.editItemAt(i) = false;
-    }
-
-    mPendingInputMessages.clear();
-    mDequeuedInputBuffers.clear();
-    mSkipRenderingUntilMediaTimeUs = -1;
-}
-
-bool NuPlayer2::Decoder::isStaleReply(const sp<AMessage> &msg) {
-    int32_t generation;
-    CHECK(msg->findInt32("generation", &generation));
-    return generation != mBufferGeneration;
-}
-
-status_t NuPlayer2::Decoder::fetchInputData(sp<AMessage> &reply) {
-    sp<ABuffer> accessUnit;
-    bool dropAccessUnit = true;
-    do {
-        status_t err = mSource->dequeueAccessUnit(mIsAudio, &accessUnit);
-
-        if (err == -EWOULDBLOCK) {
-            return err;
-        } else if (err != OK) {
-            if (err == INFO_DISCONTINUITY) {
-                int32_t type;
-                CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
-
-                bool formatChange =
-                    (mIsAudio &&
-                     (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
-                    || (!mIsAudio &&
-                            (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
-
-                bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
-
-                ALOGI("%s discontinuity (format=%d, time=%d)",
-                        mIsAudio ? "audio" : "video", formatChange, timeChange);
-
-                bool seamlessFormatChange = false;
-                sp<AMessage> newFormat = mSource->getFormat(mIsAudio);
-                if (formatChange) {
-                    seamlessFormatChange =
-                        supportsSeamlessFormatChange(newFormat);
-                    // treat seamless format change separately
-                    formatChange = !seamlessFormatChange;
-                }
-
-                // For format or time change, return EOS to queue EOS input,
-                // then wait for EOS on output.
-                if (formatChange /* not seamless */) {
-                    mFormatChangePending = true;
-                    err = ERROR_END_OF_STREAM;
-                } else if (timeChange) {
-                    rememberCodecSpecificData(newFormat);
-                    mTimeChangePending = true;
-                    err = ERROR_END_OF_STREAM;
-                } else if (seamlessFormatChange) {
-                    // reuse existing decoder and don't flush
-                    rememberCodecSpecificData(newFormat);
-                    continue;
-                } else {
-                    // This stream is unaffected by the discontinuity
-                    return -EWOULDBLOCK;
-                }
-            }
-
-            // reply should only be returned without a buffer set
-            // when there is an error (including EOS)
-            CHECK(err != OK);
-
-            reply->setInt32("err", err);
-            return ERROR_END_OF_STREAM;
-        }
-
-        dropAccessUnit = false;
-        if (!mIsAudio && !mIsEncrypted) {
-            // Extra safeguard if higher-level behavior changes. Otherwise, not required now.
-            // Preventing the buffer from being processed (and sent to codec) if this is a later
-            // round of playback but this time without prepareDrm. Or if there is a race between
-            // stop (which is not blocking) and releaseDrm allowing buffers being processed after
-            // Crypto has been released (GenericSource currently prevents this race though).
-            // Particularly doing this check before IsAVCReferenceFrame call to prevent parsing
-            // of encrypted data.
-            if (mIsEncryptedObservedEarlier) {
-                ALOGE("fetchInputData: mismatched mIsEncrypted/mIsEncryptedObservedEarlier (0/1)");
-
-                return INVALID_OPERATION;
-            }
-
-            int32_t layerId = 0;
-            bool haveLayerId = accessUnit->meta()->findInt32("temporal-layer-id", &layerId);
-            if (mRenderer->getVideoLateByUs() > 100000LL
-                    && mIsVideoAVC
-                    && !IsAVCReferenceFrame(accessUnit)) {
-                dropAccessUnit = true;
-            } else if (haveLayerId && mNumVideoTemporalLayerTotal > 1) {
-                // Add only one layer each time.
-                if (layerId > mCurrentMaxVideoTemporalLayerId + 1
-                        || layerId >= mNumVideoTemporalLayerAllowed) {
-                    dropAccessUnit = true;
-                    ALOGV("dropping layer(%d), speed=%g, allowed layer count=%d, max layerId=%d",
-                            layerId, mPlaybackSpeed, mNumVideoTemporalLayerAllowed,
-                            mCurrentMaxVideoTemporalLayerId);
-                } else if (layerId > mCurrentMaxVideoTemporalLayerId) {
-                    mCurrentMaxVideoTemporalLayerId = layerId;
-                } else if (layerId == 0 && mNumVideoTemporalLayerTotal > 1
-                        && IsIDR(accessUnit->data(), accessUnit->size())) {
-                    mCurrentMaxVideoTemporalLayerId = mNumVideoTemporalLayerTotal - 1;
-                }
-            }
-            if (dropAccessUnit) {
-                if (layerId <= mCurrentMaxVideoTemporalLayerId && layerId > 0) {
-                    mCurrentMaxVideoTemporalLayerId = layerId - 1;
-                }
-                ++mNumInputFramesDropped;
-            }
-        }
-    } while (dropAccessUnit);
-
-    // ALOGV("returned a valid buffer of %s data", mIsAudio ? "mIsAudio" : "video");
-#if 0
-    int64_t mediaTimeUs;
-    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
-    ALOGV("[%s] feeding input buffer at media time %.3f",
-         mIsAudio ? "audio" : "video",
-         mediaTimeUs / 1E6);
-#endif
-
-    if (mCCDecoder != NULL) {
-        mCCDecoder->decode(accessUnit);
-    }
-
-    reply->setBuffer("buffer", accessUnit);
-
-    return OK;
-}
-
-bool NuPlayer2::Decoder::onInputBufferFetched(const sp<AMessage> &msg) {
-    if (mCodec == NULL) {
-        ALOGE("[%s] onInputBufferFetched without a valid codec", mComponentName.c_str());
-        handleError(NO_INIT);
-        return false;
-    }
-
-    size_t bufferIx;
-    CHECK(msg->findSize("buffer-ix", &bufferIx));
-    CHECK_LT(bufferIx, mInputBuffers.size());
-    sp<MediaCodecBuffer> codecBuffer = mInputBuffers[bufferIx];
-
-    sp<ABuffer> buffer;
-    bool hasBuffer = msg->findBuffer("buffer", &buffer);
-    bool needsCopy = true;
-
-    if (buffer == NULL /* includes !hasBuffer */) {
-        int32_t streamErr = ERROR_END_OF_STREAM;
-        CHECK(msg->findInt32("err", &streamErr) || !hasBuffer);
-
-        CHECK(streamErr != OK);
-
-        // attempt to queue EOS
-        status_t err = mCodec->queueInputBuffer(
-                bufferIx,
-                0,
-                0,
-                0,
-                AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM);
-        if (err == OK) {
-            mInputBufferIsDequeued.editItemAt(bufferIx) = false;
-        } else if (streamErr == ERROR_END_OF_STREAM) {
-            streamErr = err;
-            // err will not be ERROR_END_OF_STREAM
-        }
-
-        if (streamErr != ERROR_END_OF_STREAM) {
-            ALOGE("Stream error for [%s] (err=%d), EOS %s queued",
-                    mComponentName.c_str(),
-                    streamErr,
-                    err == OK ? "successfully" : "unsuccessfully");
-            handleError(streamErr);
-        }
-    } else {
-        sp<AMessage> extra;
-        if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) {
-            int64_t resumeAtMediaTimeUs;
-            if (extra->findInt64(
-                        "resume-at-mediaTimeUs", &resumeAtMediaTimeUs)) {
-                ALOGI("[%s] suppressing rendering until %lld us",
-                        mComponentName.c_str(), (long long)resumeAtMediaTimeUs);
-                mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs;
-            }
-        }
-
-        int64_t timeUs = 0;
-        uint32_t flags = 0;
-        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
-
-        int32_t eos, csd;
-        // we do not expect SYNCFRAME for decoder
-        if (buffer->meta()->findInt32("eos", &eos) && eos) {
-            flags |= AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM;
-        } else if (buffer->meta()->findInt32("csd", &csd) && csd) {
-            flags |= AMEDIACODEC_BUFFER_FLAG_CODEC_CONFIG;
-        }
-
-        // Modular DRM
-        MediaBufferBase *mediaBuf = NULL;
-        sp<AMediaCodecCryptoInfoWrapper> cryptInfo;
-
-        // copy into codec buffer
-        if (needsCopy) {
-            if (buffer->size() > codecBuffer->capacity()) {
-                handleError(ERROR_BUFFER_TOO_SMALL);
-                mDequeuedInputBuffers.push_back(bufferIx);
-                return false;
-            }
-
-            if (buffer->data() != NULL) {
-                codecBuffer->setRange(0, buffer->size());
-                memcpy(codecBuffer->data(), buffer->data(), buffer->size());
-            } else { // No buffer->data()
-                //Modular DRM
-                sp<RefBase> holder;
-                if (buffer->meta()->findObject("mediaBufferHolder", &holder)) {
-                    mediaBuf = (holder != nullptr) ?
-                        static_cast<MediaBufferHolder*>(holder.get())->mediaBuffer() : nullptr;
-                }
-                if (mediaBuf != NULL) {
-                    if (mediaBuf->size() > codecBuffer->capacity()) {
-                        handleError(ERROR_BUFFER_TOO_SMALL);
-                        mDequeuedInputBuffers.push_back(bufferIx);
-                        return false;
-                    }
-
-                    codecBuffer->setRange(0, mediaBuf->size());
-                    memcpy(codecBuffer->data(), mediaBuf->data(), mediaBuf->size());
-
-                    MetaDataBase &meta_data = mediaBuf->meta_data();
-                    cryptInfo = AMediaCodecCryptoInfoWrapper::Create(meta_data);
-                } else { // No mediaBuf
-                    ALOGE("onInputBufferFetched: buffer->data()/mediaBuf are NULL for %p",
-                            buffer.get());
-                    handleError(UNKNOWN_ERROR);
-                    return false;
-                }
-            } // buffer->data()
-        } // needsCopy
-
-        sp<RefBase> cryptInfoObj;
-        if (buffer->meta()->findObject("cryptInfo", &cryptInfoObj)) {
-            cryptInfo = static_cast<AMediaCodecCryptoInfoWrapper *>(cryptInfoObj.get());
-        }
-
-        status_t err;
-        if (cryptInfo != NULL) {
-            err = mCodec->queueSecureInputBuffer(
-                    bufferIx,
-                    codecBuffer->offset(),
-                    cryptInfo,
-                    timeUs,
-                    flags);
-            // synchronous call so done with cryptInfo here
-        } else {
-            err = mCodec->queueInputBuffer(
-                    bufferIx,
-                    codecBuffer->offset(),
-                    codecBuffer->size(),
-                    timeUs,
-                    flags);
-        } // no cryptInfo
-
-        if (err != OK) {
-            ALOGE("onInputBufferFetched: queue%sInputBuffer failed for [%s] (err=%d)",
-                    (cryptInfo != NULL ? "Secure" : ""),
-                    mComponentName.c_str(), err);
-            handleError(err);
-        } else {
-            mInputBufferIsDequeued.editItemAt(bufferIx) = false;
-        }
-
-    }   // buffer != NULL
-    return true;
-}
-
-void NuPlayer2::Decoder::onRenderBuffer(const sp<AMessage> &msg) {
-    status_t err;
-    int32_t render;
-    size_t bufferIx;
-    int32_t eos;
-    CHECK(msg->findSize("buffer-ix", &bufferIx));
-
-    if (!mIsAudio) {
-        int64_t timeUs;
-        sp<MediaCodecBuffer> buffer = mOutputBuffers[bufferIx];
-        buffer->meta()->findInt64("timeUs", &timeUs);
-
-        if (mCCDecoder != NULL && mCCDecoder->isSelected()) {
-            mCCDecoder->display(timeUs);
-        }
-    }
-
-    if (mCodec == NULL) {
-        err = NO_INIT;
-    } else if (msg->findInt32("render", &render) && render) {
-        int64_t timestampNs;
-        CHECK(msg->findInt64("timestampNs", &timestampNs));
-        err = mCodec->releaseOutputBufferAtTime(bufferIx, timestampNs);
-    } else {
-        mNumOutputFramesDropped += !mIsAudio;
-        err = mCodec->releaseOutputBuffer(bufferIx, false /* render */);
-    }
-    if (err != OK) {
-        ALOGE("failed to release output buffer for [%s] (err=%d)",
-                mComponentName.c_str(), err);
-        handleError(err);
-    }
-    if (msg->findInt32("eos", &eos) && eos
-            && isDiscontinuityPending()) {
-        finishHandleDiscontinuity(true /* flushOnTimeChange */);
-    }
-}
-
-bool NuPlayer2::Decoder::isDiscontinuityPending() const {
-    return mFormatChangePending || mTimeChangePending;
-}
-
-void NuPlayer2::Decoder::finishHandleDiscontinuity(bool flushOnTimeChange) {
-    ALOGV("finishHandleDiscontinuity: format %d, time %d, flush %d",
-            mFormatChangePending, mTimeChangePending, flushOnTimeChange);
-
-    // If we have format change, pause and wait to be killed;
-    // If we have time change only, flush and restart fetching.
-
-    if (mFormatChangePending) {
-        mPaused = true;
-    } else if (mTimeChangePending) {
-        if (flushOnTimeChange) {
-            doFlush(false /* notifyComplete */);
-            signalResume(false /* notifyComplete */);
-        }
-    }
-
-    // Notify NuPlayer2 to either shutdown decoder, or rescan sources
-    sp<AMessage> msg = mNotify->dup();
-    msg->setInt32("what", kWhatInputDiscontinuity);
-    msg->setInt32("formatChange", mFormatChangePending);
-    msg->post();
-
-    mFormatChangePending = false;
-    mTimeChangePending = false;
-}
-
-bool NuPlayer2::Decoder::supportsSeamlessAudioFormatChange(
-        const sp<AMessage> &targetFormat) const {
-    if (targetFormat == NULL) {
-        return true;
-    }
-
-    AString mime;
-    if (!targetFormat->findString("mime", &mime)) {
-        return false;
-    }
-
-    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
-        // field-by-field comparison
-        const char * keys[] = { "channel-count", "sample-rate", "is-adts" };
-        for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) {
-            int32_t oldVal, newVal;
-            if (!mInputFormat->getInt32(keys[i], &oldVal) ||
-                    !targetFormat->findInt32(keys[i], &newVal) ||
-                    oldVal != newVal) {
-                return false;
-            }
-        }
-
-        sp<ABuffer> newBuf;
-        uint8_t *oldBufData = NULL;
-        size_t oldBufSize = 0;
-        if (mInputFormat->getBuffer("csd-0", (void**)&oldBufData, &oldBufSize) &&
-                targetFormat->findBuffer("csd-0", &newBuf)) {
-            if (oldBufSize != newBuf->size()) {
-                return false;
-            }
-            return !memcmp(oldBufData, newBuf->data(), oldBufSize);
-        }
-    }
-    return false;
-}
-
-bool NuPlayer2::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const {
-    if (mInputFormat == NULL) {
-        return false;
-    }
-
-    if (targetFormat == NULL) {
-        return true;
-    }
-
-    AString oldMime, newMime;
-    if (!mInputFormat->getString("mime", &oldMime)
-            || !targetFormat->findString("mime", &newMime)
-            || !(oldMime == newMime)) {
-        return false;
-    }
-
-    bool audio = !strncasecmp(oldMime.c_str(), "audio/", strlen("audio/"));
-    bool seamless;
-    if (audio) {
-        seamless = supportsSeamlessAudioFormatChange(targetFormat);
-    } else {
-        int32_t isAdaptive;
-        seamless = (mCodec != NULL &&
-                mInputFormat->getInt32("adaptive-playback", &isAdaptive) &&
-                isAdaptive);
-    }
-
-    ALOGV("%s seamless support for %s", seamless ? "yes" : "no", oldMime.c_str());
-    return seamless;
-}
-
-void NuPlayer2::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) {
-    if (format == NULL) {
-        return;
-    }
-    mCSDsForCurrentFormat.clear();
-    for (int32_t i = 0; ; ++i) {
-        AString tag = "csd-";
-        tag.append(i);
-        sp<ABuffer> buffer;
-        if (!format->findBuffer(tag.c_str(), &buffer)) {
-            break;
-        }
-        mCSDsForCurrentFormat.push(buffer);
-    }
-}
-
-void NuPlayer2::Decoder::notifyResumeCompleteIfNecessary() {
-    if (mResumePending) {
-        mResumePending = false;
-
-        sp<AMessage> notify = mNotify->dup();
-        notify->setInt32("what", kWhatResumeCompleted);
-        notify->post();
-    }
-}
-
-}  // namespace android
-
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.h b/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.h
deleted file mode 100644
index fdfb10e..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-#ifndef NUPLAYER2_DECODER_H_
-#define NUPLAYER2_DECODER_H_
-
-#include "NuPlayer2.h"
-
-#include "NuPlayer2DecoderBase.h"
-
-namespace android {
-
-class MediaCodecBuffer;
-
-struct AMediaCodecWrapper;
-struct AMediaFormatWrapper;
-
-struct NuPlayer2::Decoder : public DecoderBase {
-    Decoder(const sp<AMessage> &notify,
-            const sp<Source> &source,
-            pid_t pid,
-            uid_t uid,
-            const sp<Renderer> &renderer = NULL,
-            const sp<ANativeWindowWrapper> &nww = NULL,
-            const sp<CCDecoder> &ccDecoder = NULL);
-
-    virtual sp<AMessage> getStats() const;
-
-    // sets the output surface of video decoders.
-    virtual status_t setVideoSurface(const sp<ANativeWindowWrapper> &nww);
-
-    virtual status_t releaseCrypto();
-
-protected:
-    virtual ~Decoder();
-
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-    virtual void onConfigure(const sp<AMessage> &format);
-    virtual void onSetParameters(const sp<AMessage> &params);
-    virtual void onSetRenderer(const sp<Renderer> &renderer);
-    virtual void onResume(bool notifyComplete);
-    virtual void onFlush();
-    virtual void onShutdown(bool notifyComplete);
-    virtual bool doRequestBuffers();
-
-private:
-    enum {
-        kWhatCodecNotify         = 'cdcN',
-        kWhatRenderBuffer        = 'rndr',
-        kWhatSetVideoSurface     = 'sSur',
-        kWhatAudioOutputFormatChanged = 'aofc',
-        kWhatDrmReleaseCrypto    = 'rDrm',
-    };
-
-    enum {
-        kMaxNumVideoTemporalLayers = 32,
-    };
-
-    sp<ANativeWindowWrapper> mNativeWindow;
-
-    sp<Source> mSource;
-    sp<Renderer> mRenderer;
-    sp<CCDecoder> mCCDecoder;
-
-    sp<AMediaFormatWrapper> mInputFormat;
-    sp<AMediaCodecWrapper> mCodec;
-
-    List<sp<AMessage> > mPendingInputMessages;
-
-    Vector<sp<MediaCodecBuffer> > mInputBuffers;
-    Vector<sp<MediaCodecBuffer> > mOutputBuffers;
-    Vector<sp<ABuffer> > mCSDsForCurrentFormat;
-    Vector<sp<ABuffer> > mCSDsToSubmit;
-    Vector<bool> mInputBufferIsDequeued;
-    Vector<MediaBuffer *> mMediaBuffers;
-    Vector<size_t> mDequeuedInputBuffers;
-
-    const pid_t mPid;
-    const uid_t mUid;
-    int64_t mSkipRenderingUntilMediaTimeUs;
-    int64_t mNumFramesTotal;
-    int64_t mNumInputFramesDropped;
-    int64_t mNumOutputFramesDropped;
-    int32_t mVideoWidth;
-    int32_t mVideoHeight;
-    bool mIsAudio;
-    bool mIsVideoAVC;
-    bool mIsSecure;
-    bool mIsEncrypted;
-    bool mIsEncryptedObservedEarlier;
-    bool mFormatChangePending;
-    bool mTimeChangePending;
-    float mFrameRateTotal;
-    float mPlaybackSpeed;
-    int32_t mNumVideoTemporalLayerTotal;
-    int32_t mNumVideoTemporalLayerAllowed;
-    int32_t mCurrentMaxVideoTemporalLayerId;
-    float mVideoTemporalLayerAggregateFps[kMaxNumVideoTemporalLayers];
-
-    bool mResumePending;
-    AString mComponentName;
-
-    void handleError(int32_t err);
-    bool handleAnInputBuffer(size_t index);
-    bool handleAnOutputBuffer(
-            size_t index,
-            size_t offset,
-            size_t size,
-            int64_t timeUs,
-            int32_t flags);
-    void handleOutputFormatChange(const sp<AMessage> &format);
-
-    void releaseAndResetMediaBuffers();
-    bool isStaleReply(const sp<AMessage> &msg);
-
-    void doFlush(bool notifyComplete);
-    status_t fetchInputData(sp<AMessage> &reply);
-    bool onInputBufferFetched(const sp<AMessage> &msg);
-    void onRenderBuffer(const sp<AMessage> &msg);
-
-    bool supportsSeamlessFormatChange(const sp<AMessage> &to) const;
-    bool supportsSeamlessAudioFormatChange(const sp<AMessage> &targetFormat) const;
-    void rememberCodecSpecificData(const sp<AMessage> &format);
-    bool isDiscontinuityPending() const;
-    void finishHandleDiscontinuity(bool flushOnTimeChange);
-
-    void notifyResumeCompleteIfNecessary();
-
-    void onReleaseCrypto(const sp<AMessage>& msg);
-
-    DISALLOW_EVIL_CONSTRUCTORS(Decoder);
-};
-
-}  // namespace android
-
-#endif  // NUPLAYER2_DECODER_H_
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderBase.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderBase.cpp
deleted file mode 100644
index 914f29f..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderBase.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright 2017 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 "NuPlayer2DecoderBase"
-#include <utils/Log.h>
-#include <inttypes.h>
-
-#include "NuPlayer2DecoderBase.h"
-
-#include "NuPlayer2Renderer.h"
-
-#include <media/MediaCodecBuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-
-namespace android {
-
-NuPlayer2::DecoderBase::DecoderBase(const sp<AMessage> &notify)
-    :  mNotify(notify),
-       mBufferGeneration(0),
-       mPaused(false),
-       mStats(new AMessage),
-       mRequestInputBuffersPending(false) {
-    // Every decoder has its own looper because MediaCodec operations
-    // are blocking, but NuPlayer2 needs asynchronous operations.
-    mDecoderLooper = new ALooper;
-    mDecoderLooper->setName("NP2Decoder");
-    mDecoderLooper->start(false, /* runOnCallingThread */
-                          true,  /* canCallJava */
-                          ANDROID_PRIORITY_AUDIO);
-}
-
-NuPlayer2::DecoderBase::~DecoderBase() {
-    stopLooper();
-}
-
-static
-status_t PostAndAwaitResponse(
-        const sp<AMessage> &msg, sp<AMessage> *response) {
-    status_t err = msg->postAndAwaitResponse(response);
-
-    if (err != OK) {
-        return err;
-    }
-
-    if (!(*response)->findInt32("err", &err)) {
-        err = OK;
-    }
-
-    return err;
-}
-
-void NuPlayer2::DecoderBase::configure(const sp<AMessage> &format) {
-    sp<AMessage> msg = new AMessage(kWhatConfigure, this);
-    msg->setMessage("format", format);
-    msg->post();
-}
-
-void NuPlayer2::DecoderBase::init() {
-    mDecoderLooper->registerHandler(this);
-}
-
-void NuPlayer2::DecoderBase::stopLooper() {
-    mDecoderLooper->unregisterHandler(id());
-    mDecoderLooper->stop();
-}
-
-void NuPlayer2::DecoderBase::setParameters(const sp<AMessage> &params) {
-    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
-    msg->setMessage("params", params);
-    msg->post();
-}
-
-void NuPlayer2::DecoderBase::setRenderer(const sp<Renderer> &renderer) {
-    sp<AMessage> msg = new AMessage(kWhatSetRenderer, this);
-    msg->setObject("renderer", renderer);
-    msg->post();
-}
-
-void NuPlayer2::DecoderBase::pause() {
-    sp<AMessage> msg = new AMessage(kWhatPause, this);
-
-    sp<AMessage> response;
-    PostAndAwaitResponse(msg, &response);
-}
-
-void NuPlayer2::DecoderBase::signalFlush() {
-    (new AMessage(kWhatFlush, this))->post();
-}
-
-void NuPlayer2::DecoderBase::signalResume(bool notifyComplete) {
-    sp<AMessage> msg = new AMessage(kWhatResume, this);
-    msg->setInt32("notifyComplete", notifyComplete);
-    msg->post();
-}
-
-void NuPlayer2::DecoderBase::initiateShutdown() {
-    (new AMessage(kWhatShutdown, this))->post();
-}
-
-void NuPlayer2::DecoderBase::onRequestInputBuffers() {
-    if (mRequestInputBuffersPending) {
-        return;
-    }
-
-    // doRequestBuffers() return true if we should request more data
-    if (doRequestBuffers()) {
-        mRequestInputBuffersPending = true;
-
-        sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, this);
-        msg->post(10 * 1000LL);
-    }
-}
-
-void NuPlayer2::DecoderBase::onMessageReceived(const sp<AMessage> &msg) {
-
-    switch (msg->what()) {
-        case kWhatConfigure:
-        {
-            sp<AMessage> format;
-            CHECK(msg->findMessage("format", &format));
-            onConfigure(format);
-            break;
-        }
-
-        case kWhatSetParameters:
-        {
-            sp<AMessage> params;
-            CHECK(msg->findMessage("params", &params));
-            onSetParameters(params);
-            break;
-        }
-
-        case kWhatSetRenderer:
-        {
-            sp<RefBase> obj;
-            CHECK(msg->findObject("renderer", &obj));
-            onSetRenderer(static_cast<Renderer *>(obj.get()));
-            break;
-        }
-
-        case kWhatPause:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-
-            mPaused = true;
-
-            (new AMessage)->postReply(replyID);
-            break;
-        }
-
-        case kWhatRequestInputBuffers:
-        {
-            mRequestInputBuffersPending = false;
-            onRequestInputBuffers();
-            break;
-        }
-
-        case kWhatFlush:
-        {
-            onFlush();
-            break;
-        }
-
-        case kWhatResume:
-        {
-            int32_t notifyComplete;
-            CHECK(msg->findInt32("notifyComplete", &notifyComplete));
-
-            onResume(notifyComplete);
-            break;
-        }
-
-        case kWhatShutdown:
-        {
-            onShutdown(true);
-            break;
-        }
-
-        default:
-            TRESPASS();
-            break;
-    }
-}
-
-void NuPlayer2::DecoderBase::handleError(int32_t err)
-{
-    // We cannot immediately release the codec due to buffers still outstanding
-    // in the renderer.  We signal to the player the error so it can shutdown/release the
-    // decoder after flushing and increment the generation to discard unnecessary messages.
-
-    ++mBufferGeneration;
-
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatError);
-    notify->setInt32("err", err);
-    notify->post();
-}
-
-}  // namespace android
-
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderBase.h b/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderBase.h
deleted file mode 100644
index 1e57f0d..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderBase.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-#ifndef NUPLAYER2_DECODER_BASE_H_
-
-#define NUPLAYER2_DECODER_BASE_H_
-
-#include "NuPlayer2.h"
-
-#include <media/stagefright/foundation/AHandler.h>
-
-namespace android {
-
-struct ABuffer;
-struct ANativeWindowWrapper;
-struct MediaCodec;
-class MediaBuffer;
-class MediaCodecBuffer;
-
-struct NuPlayer2::DecoderBase : public AHandler {
-    explicit DecoderBase(const sp<AMessage> &notify);
-
-    void configure(const sp<AMessage> &format);
-    void init();
-    void setParameters(const sp<AMessage> &params);
-
-    // Synchronous call to ensure decoder will not request or send out data.
-    void pause();
-
-    void setRenderer(const sp<Renderer> &renderer);
-    virtual status_t setVideoSurface(const sp<ANativeWindowWrapper> &) { return INVALID_OPERATION; }
-
-    void signalFlush();
-    void signalResume(bool notifyComplete);
-    void initiateShutdown();
-
-    virtual sp<AMessage> getStats() const {
-        return mStats;
-    }
-
-    virtual status_t releaseCrypto() {
-        return INVALID_OPERATION;
-    }
-
-    enum {
-        kWhatInputDiscontinuity  = 'inDi',
-        kWhatVideoSizeChanged    = 'viSC',
-        kWhatFlushCompleted      = 'flsC',
-        kWhatShutdownCompleted   = 'shDC',
-        kWhatResumeCompleted     = 'resC',
-        kWhatEOS                 = 'eos ',
-        kWhatError               = 'err ',
-    };
-
-protected:
-
-    virtual ~DecoderBase();
-
-    void stopLooper();
-
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-    virtual void onConfigure(const sp<AMessage> &format) = 0;
-    virtual void onSetParameters(const sp<AMessage> &params) = 0;
-    virtual void onSetRenderer(const sp<Renderer> &renderer) = 0;
-    virtual void onResume(bool notifyComplete) = 0;
-    virtual void onFlush() = 0;
-    virtual void onShutdown(bool notifyComplete) = 0;
-
-    void onRequestInputBuffers();
-    virtual bool doRequestBuffers() = 0;
-    virtual void handleError(int32_t err);
-
-    sp<AMessage> mNotify;
-    int32_t mBufferGeneration;
-    bool mPaused;
-    sp<AMessage> mStats;
-
-private:
-    enum {
-        kWhatConfigure           = 'conf',
-        kWhatSetParameters       = 'setP',
-        kWhatSetRenderer         = 'setR',
-        kWhatPause               = 'paus',
-        kWhatRequestInputBuffers = 'reqB',
-        kWhatFlush               = 'flus',
-        kWhatShutdown            = 'shuD',
-    };
-
-    sp<ALooper> mDecoderLooper;
-    bool mRequestInputBuffersPending;
-
-    DISALLOW_EVIL_CONSTRUCTORS(DecoderBase);
-};
-
-}  // namespace android
-
-#endif  // NUPLAYER2_DECODER_BASE_H_
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderPassThrough.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderPassThrough.cpp
deleted file mode 100644
index 0514e88..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderPassThrough.cpp
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * Copyright 2017 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 "NuPlayer2DecoderPassThrough"
-#include <utils/Log.h>
-#include <inttypes.h>
-
-#include "NuPlayer2DecoderPassThrough.h"
-
-#include "NuPlayer2Renderer.h"
-#include "NuPlayer2Source.h"
-
-#include <media/MediaCodecBuffer.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/MediaErrors.h>
-
-#include "ATSParser.h"
-
-namespace android {
-
-// TODO optimize buffer size for power consumption
-// The offload read buffer size is 32 KB but 24 KB uses less power.
-static const size_t kAggregateBufferSizeBytes = 24 * 1024;
-static const size_t kMaxCachedBytes = 200000;
-
-NuPlayer2::DecoderPassThrough::DecoderPassThrough(
-        const sp<AMessage> &notify,
-        const sp<Source> &source,
-        const sp<Renderer> &renderer)
-    : DecoderBase(notify),
-      mSource(source),
-      mRenderer(renderer),
-      mSkipRenderingUntilMediaTimeUs(-1LL),
-      mReachedEOS(true),
-      mPendingAudioErr(OK),
-      mPendingBuffersToDrain(0),
-      mCachedBytes(0),
-      mComponentName("pass through decoder") {
-    ALOGW_IF(renderer == NULL, "expect a non-NULL renderer");
-}
-
-NuPlayer2::DecoderPassThrough::~DecoderPassThrough() {
-}
-
-void NuPlayer2::DecoderPassThrough::onConfigure(const sp<AMessage> &format) {
-    ALOGV("[%s] onConfigure", mComponentName.c_str());
-    mCachedBytes = 0;
-    mPendingBuffersToDrain = 0;
-    mReachedEOS = false;
-    ++mBufferGeneration;
-
-    onRequestInputBuffers();
-
-    int32_t hasVideo = 0;
-    format->findInt32("has-video", &hasVideo);
-
-    // The audio sink is already opened before the PassThrough decoder is created.
-    // Opening again might be relevant if decoder is instantiated after shutdown and
-    // format is different.
-    status_t err = mRenderer->openAudioSink(
-            format, true /* offloadOnly */, hasVideo,
-            AUDIO_OUTPUT_FLAG_NONE /* flags */, NULL /* isOffloaded */, mSource->isStreaming());
-    if (err != OK) {
-        handleError(err);
-    }
-}
-
-void NuPlayer2::DecoderPassThrough::onSetParameters(const sp<AMessage> &/*params*/) {
-    ALOGW("onSetParameters() called unexpectedly");
-}
-
-void NuPlayer2::DecoderPassThrough::onSetRenderer(
-        const sp<Renderer> &renderer) {
-    // renderer can't be changed during offloading
-    ALOGW_IF(renderer != mRenderer,
-            "ignoring request to change renderer");
-}
-
-bool NuPlayer2::DecoderPassThrough::isStaleReply(const sp<AMessage> &msg) {
-    int32_t generation;
-    CHECK(msg->findInt32("generation", &generation));
-    return generation != mBufferGeneration;
-}
-
-bool NuPlayer2::DecoderPassThrough::isDoneFetching() const {
-    ALOGV("[%s] mCachedBytes = %zu, mReachedEOS = %d mPaused = %d",
-            mComponentName.c_str(), mCachedBytes, mReachedEOS, mPaused);
-
-    return mCachedBytes >= kMaxCachedBytes || mReachedEOS || mPaused;
-}
-
-/*
- * returns true if we should request more data
- */
-bool NuPlayer2::DecoderPassThrough::doRequestBuffers() {
-    status_t err = OK;
-    while (!isDoneFetching()) {
-        sp<AMessage> msg = new AMessage();
-
-        err = fetchInputData(msg);
-        if (err != OK) {
-            break;
-        }
-
-        onInputBufferFetched(msg);
-    }
-
-    return err == -EWOULDBLOCK
-            && mSource->feedMoreTSData() == OK;
-}
-
-status_t NuPlayer2::DecoderPassThrough::dequeueAccessUnit(sp<ABuffer> *accessUnit) {
-    status_t err;
-
-    // Did we save an accessUnit earlier because of a discontinuity?
-    if (mPendingAudioAccessUnit != NULL) {
-        *accessUnit = mPendingAudioAccessUnit;
-        mPendingAudioAccessUnit.clear();
-        err = mPendingAudioErr;
-        ALOGV("feedDecoderInputData() use mPendingAudioAccessUnit");
-    } else {
-        err = mSource->dequeueAccessUnit(true /* audio */, accessUnit);
-    }
-
-    if (err == INFO_DISCONTINUITY || err == ERROR_END_OF_STREAM) {
-        if (mAggregateBuffer != NULL) {
-            // We already have some data so save this for later.
-            mPendingAudioErr = err;
-            mPendingAudioAccessUnit = *accessUnit;
-            (*accessUnit).clear();
-            ALOGD("return aggregated buffer and save err(=%d) for later", err);
-            err = OK;
-        }
-    }
-
-    return err;
-}
-
-sp<ABuffer> NuPlayer2::DecoderPassThrough::aggregateBuffer(
-        const sp<ABuffer> &accessUnit) {
-    sp<ABuffer> aggregate;
-
-    if (accessUnit == NULL) {
-        // accessUnit is saved to mPendingAudioAccessUnit
-        // return current mAggregateBuffer
-        aggregate = mAggregateBuffer;
-        mAggregateBuffer.clear();
-        return aggregate;
-    }
-
-    size_t smallSize = accessUnit->size();
-    if ((mAggregateBuffer == NULL)
-            // Don't bother if only room for a few small buffers.
-            && (smallSize < (kAggregateBufferSizeBytes / 3))) {
-        // Create a larger buffer for combining smaller buffers from the extractor.
-        mAggregateBuffer = new ABuffer(kAggregateBufferSizeBytes);
-        mAggregateBuffer->setRange(0, 0); // start empty
-    }
-
-    if (mAggregateBuffer != NULL) {
-        int64_t timeUs;
-        int64_t dummy;
-        bool smallTimestampValid = accessUnit->meta()->findInt64("timeUs", &timeUs);
-        bool bigTimestampValid = mAggregateBuffer->meta()->findInt64("timeUs", &dummy);
-        // Will the smaller buffer fit?
-        size_t bigSize = mAggregateBuffer->size();
-        size_t roomLeft = mAggregateBuffer->capacity() - bigSize;
-        // Should we save this small buffer for the next big buffer?
-        // If the first small buffer did not have a timestamp then save
-        // any buffer that does have a timestamp until the next big buffer.
-        if ((smallSize > roomLeft)
-            || (!bigTimestampValid && (bigSize > 0) && smallTimestampValid)) {
-            mPendingAudioErr = OK;
-            mPendingAudioAccessUnit = accessUnit;
-            aggregate = mAggregateBuffer;
-            mAggregateBuffer.clear();
-        } else {
-            // Grab time from first small buffer if available.
-            if ((bigSize == 0) && smallTimestampValid) {
-                mAggregateBuffer->meta()->setInt64("timeUs", timeUs);
-            }
-            // Append small buffer to the bigger buffer.
-            memcpy(mAggregateBuffer->base() + bigSize, accessUnit->data(), smallSize);
-            bigSize += smallSize;
-            mAggregateBuffer->setRange(0, bigSize);
-
-            ALOGV("feedDecoderInputData() smallSize = %zu, bigSize = %zu, capacity = %zu",
-                    smallSize, bigSize, mAggregateBuffer->capacity());
-        }
-    } else {
-        // decided not to aggregate
-        aggregate = accessUnit;
-    }
-
-    return aggregate;
-}
-
-status_t NuPlayer2::DecoderPassThrough::fetchInputData(sp<AMessage> &reply) {
-    sp<ABuffer> accessUnit;
-
-    do {
-        status_t err = dequeueAccessUnit(&accessUnit);
-
-        if (err == -EWOULDBLOCK) {
-            // Flush out the aggregate buffer to try to avoid underrun.
-            accessUnit = aggregateBuffer(NULL /* accessUnit */);
-            if (accessUnit != NULL) {
-                break;
-            }
-            return err;
-        } else if (err != OK) {
-            if (err == INFO_DISCONTINUITY) {
-                int32_t type;
-                CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
-
-                bool formatChange =
-                        (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT) != 0;
-
-                bool timeChange =
-                        (type & ATSParser::DISCONTINUITY_TIME) != 0;
-
-                ALOGI("audio discontinuity (formatChange=%d, time=%d)",
-                        formatChange, timeChange);
-
-                if (formatChange || timeChange) {
-                    sp<AMessage> msg = mNotify->dup();
-                    msg->setInt32("what", kWhatInputDiscontinuity);
-                    // will perform seamless format change,
-                    // only notify NuPlayer2 to scan sources
-                    msg->setInt32("formatChange", false);
-                    msg->post();
-                }
-
-                if (timeChange) {
-                    doFlush(false /* notifyComplete */);
-                    err = OK;
-                } else if (formatChange) {
-                    // do seamless format change
-                    err = OK;
-                } else {
-                    // This stream is unaffected by the discontinuity
-                    return -EWOULDBLOCK;
-                }
-            }
-
-            reply->setInt32("err", err);
-            return OK;
-        }
-
-        accessUnit = aggregateBuffer(accessUnit);
-    } while (accessUnit == NULL);
-
-#if 0
-    int64_t mediaTimeUs;
-    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
-    ALOGV("feeding audio input buffer at media time %.2f secs",
-         mediaTimeUs / 1E6);
-#endif
-
-    reply->setBuffer("buffer", accessUnit);
-
-    return OK;
-}
-
-void NuPlayer2::DecoderPassThrough::onInputBufferFetched(
-        const sp<AMessage> &msg) {
-    if (mReachedEOS) {
-        return;
-    }
-
-    sp<ABuffer> buffer;
-    bool hasBuffer = msg->findBuffer("buffer", &buffer);
-    if (buffer == NULL) {
-        int32_t streamErr = ERROR_END_OF_STREAM;
-        CHECK(msg->findInt32("err", &streamErr) || !hasBuffer);
-        if (streamErr == OK) {
-            return;
-        }
-
-        if (streamErr != ERROR_END_OF_STREAM) {
-            handleError(streamErr);
-        }
-        mReachedEOS = true;
-        if (mRenderer != NULL) {
-            mRenderer->queueEOS(true /* audio */, ERROR_END_OF_STREAM);
-        }
-        return;
-    }
-
-    sp<AMessage> extra;
-    if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) {
-        int64_t resumeAtMediaTimeUs;
-        if (extra->findInt64(
-                    "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
-            ALOGI("[%s] suppressing rendering until %lld us",
-                    mComponentName.c_str(), (long long)resumeAtMediaTimeUs);
-            mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs;
-        }
-    }
-
-    int32_t bufferSize = buffer->size();
-    mCachedBytes += bufferSize;
-
-    int64_t timeUs = 0;
-    CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
-    if (mSkipRenderingUntilMediaTimeUs >= 0) {
-        if (timeUs < mSkipRenderingUntilMediaTimeUs) {
-            ALOGV("[%s] dropping buffer at time %lld as requested.",
-                     mComponentName.c_str(), (long long)timeUs);
-
-            onBufferConsumed(bufferSize);
-            return;
-        }
-
-        mSkipRenderingUntilMediaTimeUs = -1;
-    }
-
-    if (mRenderer == NULL) {
-        onBufferConsumed(bufferSize);
-        return;
-    }
-
-    sp<AMessage> reply = new AMessage(kWhatBufferConsumed, this);
-    reply->setInt32("generation", mBufferGeneration);
-    reply->setInt32("size", bufferSize);
-
-    sp<MediaCodecBuffer> mcBuffer = new MediaCodecBuffer(nullptr, buffer);
-    mcBuffer->meta()->setInt64("timeUs", timeUs);
-
-    mRenderer->queueBuffer(true /* audio */, mcBuffer, reply);
-
-    ++mPendingBuffersToDrain;
-    ALOGV("onInputBufferFilled: #ToDrain = %zu, cachedBytes = %zu",
-            mPendingBuffersToDrain, mCachedBytes);
-}
-
-void NuPlayer2::DecoderPassThrough::onBufferConsumed(int32_t size) {
-    --mPendingBuffersToDrain;
-    mCachedBytes -= size;
-    ALOGV("onBufferConsumed: #ToDrain = %zu, cachedBytes = %zu",
-            mPendingBuffersToDrain, mCachedBytes);
-    onRequestInputBuffers();
-}
-
-void NuPlayer2::DecoderPassThrough::onResume(bool notifyComplete) {
-    mPaused = false;
-
-    onRequestInputBuffers();
-
-    if (notifyComplete) {
-        sp<AMessage> notify = mNotify->dup();
-        notify->setInt32("what", kWhatResumeCompleted);
-        notify->post();
-    }
-}
-
-void NuPlayer2::DecoderPassThrough::doFlush(bool notifyComplete) {
-    ++mBufferGeneration;
-    mSkipRenderingUntilMediaTimeUs = -1;
-    mPendingAudioAccessUnit.clear();
-    mPendingAudioErr = OK;
-    mAggregateBuffer.clear();
-
-    if (mRenderer != NULL) {
-        mRenderer->flush(true /* audio */, notifyComplete);
-        mRenderer->signalTimeDiscontinuity();
-    }
-
-    mPendingBuffersToDrain = 0;
-    mCachedBytes = 0;
-    mReachedEOS = false;
-}
-
-void NuPlayer2::DecoderPassThrough::onFlush() {
-    doFlush(true /* notifyComplete */);
-
-    mPaused = true;
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatFlushCompleted);
-    notify->post();
-
-}
-
-void NuPlayer2::DecoderPassThrough::onShutdown(bool notifyComplete) {
-    ++mBufferGeneration;
-    mSkipRenderingUntilMediaTimeUs = -1;
-
-    if (notifyComplete) {
-        sp<AMessage> notify = mNotify->dup();
-        notify->setInt32("what", kWhatShutdownCompleted);
-        notify->post();
-    }
-
-    mReachedEOS = true;
-}
-
-void NuPlayer2::DecoderPassThrough::onMessageReceived(const sp<AMessage> &msg) {
-    ALOGV("[%s] onMessage: %s", mComponentName.c_str(),
-            msg->debugString().c_str());
-
-    switch (msg->what()) {
-        case kWhatBufferConsumed:
-        {
-            if (!isStaleReply(msg)) {
-                int32_t size;
-                CHECK(msg->findInt32("size", &size));
-                onBufferConsumed(size);
-            }
-            break;
-        }
-
-        default:
-            DecoderBase::onMessageReceived(msg);
-            break;
-    }
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderPassThrough.h b/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderPassThrough.h
deleted file mode 100644
index 838c60a..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderPassThrough.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-#ifndef NUPLAYER2_DECODER_PASS_THROUGH_H_
-
-#define NUPLAYER2_DECODER_PASS_THROUGH_H_
-
-#include "NuPlayer2.h"
-
-#include "NuPlayer2DecoderBase.h"
-
-namespace android {
-
-struct NuPlayer2::DecoderPassThrough : public DecoderBase {
-    DecoderPassThrough(const sp<AMessage> &notify,
-                       const sp<Source> &source,
-                       const sp<Renderer> &renderer);
-
-protected:
-
-    virtual ~DecoderPassThrough();
-
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-    virtual void onConfigure(const sp<AMessage> &format);
-    virtual void onSetParameters(const sp<AMessage> &params);
-    virtual void onSetRenderer(const sp<Renderer> &renderer);
-    virtual void onResume(bool notifyComplete);
-    virtual void onFlush();
-    virtual void onShutdown(bool notifyComplete);
-    virtual bool doRequestBuffers();
-
-private:
-    enum {
-        kWhatBufferConsumed     = 'bufC',
-    };
-
-    sp<Source> mSource;
-    sp<Renderer> mRenderer;
-    int64_t mSkipRenderingUntilMediaTimeUs;
-
-    bool    mReachedEOS;
-
-    // Used by feedDecoderInputData to aggregate small buffers into
-    // one large buffer.
-    sp<ABuffer> mPendingAudioAccessUnit;
-    status_t    mPendingAudioErr;
-    sp<ABuffer> mAggregateBuffer;
-
-    // mPendingBuffersToDrain are only for debugging. It can be removed
-    // when the power investigation is done.
-    size_t  mPendingBuffersToDrain;
-    size_t  mCachedBytes;
-    AString mComponentName;
-
-    bool isStaleReply(const sp<AMessage> &msg);
-    bool isDoneFetching() const;
-
-    status_t dequeueAccessUnit(sp<ABuffer> *accessUnit);
-    sp<ABuffer> aggregateBuffer(const sp<ABuffer> &accessUnit);
-    status_t fetchInputData(sp<AMessage> &reply);
-    void doFlush(bool notifyComplete);
-
-    void onInputBufferFetched(const sp<AMessage> &msg);
-    void onBufferConsumed(int32_t size);
-
-    DISALLOW_EVIL_CONSTRUCTORS(DecoderPassThrough);
-};
-
-}  // namespace android
-
-#endif  // NUPLAYER2_DECODER_PASS_THROUGH_H_
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
deleted file mode 100644
index 1876496..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
+++ /dev/null
@@ -1,1010 +0,0 @@
-/*
- * Copyright 2017 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 "NuPlayer2Driver"
-#include <inttypes.h>
-#include <android-base/macros.h>
-#include <utils/Log.h>
-#include <cutils/properties.h>
-
-#include "NuPlayer2Driver.h"
-
-#include "NuPlayer2.h"
-#include "NuPlayer2Source.h"
-
-#include <media/DataSourceDesc.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/foundation/AUtils.h>
-#include <media/stagefright/foundation/ByteUtils.h>
-#include <media/stagefright/MediaClock.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/Utils.h>
-
-#include <media/IMediaAnalyticsService.h>
-
-using google::protobuf::RepeatedPtrField;
-using android::media::MediaPlayer2Proto::Value;
-
-static const int kDumpLockRetries = 50;
-static const int kDumpLockSleepUs = 20000;
-
-namespace android {
-
-struct PlayerMessageWrapper : public RefBase {
-    static sp<PlayerMessageWrapper> Create(const PlayerMessage *p) {
-        if (p != NULL) {
-            sp<PlayerMessageWrapper> pw = new PlayerMessageWrapper();
-            pw->copyFrom(p);
-            return pw;
-        }
-        return NULL;
-    }
-
-    const PlayerMessage *getPlayerMessage() {
-        return mPlayerMessage;
-    }
-
-protected:
-    virtual ~PlayerMessageWrapper() {
-        if (mPlayerMessage != NULL) {
-            delete mPlayerMessage;
-        }
-    }
-
-private:
-    PlayerMessageWrapper()
-        : mPlayerMessage(NULL) { }
-
-    void copyFrom(const PlayerMessage *p) {
-        if (mPlayerMessage == NULL) {
-            mPlayerMessage = new PlayerMessage;
-        }
-        mPlayerMessage->CopyFrom(*p);
-    }
-
-    PlayerMessage *mPlayerMessage;
-};
-
-// key for media statistics
-static const char *kKeyPlayer = "nuplayer2";
-// attrs for media statistics
-    // NB: these are matched with public Java API constants defined
-    // in frameworks/base/media/java/android/media/MediaPlayer2.java
-    // These must be kept synchronized with the constants there.
-static const char *kPlayerVMime = "android.media.mediaplayer.video.mime";
-static const char *kPlayerVCodec = "android.media.mediaplayer.video.codec";
-static const char *kPlayerWidth = "android.media.mediaplayer.width";
-static const char *kPlayerHeight = "android.media.mediaplayer.height";
-static const char *kPlayerFrames = "android.media.mediaplayer.frames";
-static const char *kPlayerFramesDropped = "android.media.mediaplayer.dropped";
-static const char *kPlayerFrameRate = "android.media.mediaplayer.fps";
-static const char *kPlayerAMime = "android.media.mediaplayer.audio.mime";
-static const char *kPlayerACodec = "android.media.mediaplayer.audio.codec";
-static const char *kPlayerDuration = "android.media.mediaplayer.durationMs";
-static const char *kPlayerPlaying = "android.media.mediaplayer.playingMs";
-static const char *kPlayerError = "android.media.mediaplayer.err";
-static const char *kPlayerErrorCode = "android.media.mediaplayer.errcode";
-
-// NB: These are not yet exposed as public Java API constants.
-static const char *kPlayerErrorState = "android.media.mediaplayer.errstate";
-static const char *kPlayerDataSourceType = "android.media.mediaplayer.dataSource";
-//
-static const char *kPlayerRebuffering = "android.media.mediaplayer.rebufferingMs";
-static const char *kPlayerRebufferingCount = "android.media.mediaplayer.rebuffers";
-static const char *kPlayerRebufferingAtExit = "android.media.mediaplayer.rebufferExit";
-
-static const char *kPlayerVersion = "android.media.mediaplayer.version";
-
-
-NuPlayer2Driver::NuPlayer2Driver(pid_t pid, uid_t uid, const sp<JObjectHolder> &context)
-    : mState(STATE_IDLE),
-      mAsyncResult(UNKNOWN_ERROR),
-      mSrcId(0),
-      mSetSurfaceInProgress(false),
-      mDurationUs(-1),
-      mPositionUs(-1),
-      mSeekInProgress(false),
-      mPlayingTimeUs(0),
-      mRebufferingTimeUs(0),
-      mRebufferingEvents(0),
-      mRebufferingAtExit(false),
-      mLooper(new ALooper),
-      mNuPlayer2Looper(new ALooper),
-      mMediaClock(new MediaClock),
-      mPlayer(new NuPlayer2(pid, uid, mMediaClock, context)),
-      mPlayerFlags(0),
-      mMetricsHandle(0),
-      mPlayerVersion(0),
-      mClientUid(uid),
-      mAtEOS(false),
-      mLooping(false),
-      mAutoLoop(false) {
-    ALOGD("NuPlayer2Driver(%p) created, clientPid(%d)", this, pid);
-    mLooper->setName("NuPlayer2Driver Looper");
-    mNuPlayer2Looper->setName("NuPlayer2 Looper");
-
-    mMediaClock->init();
-
-    // XXX: what version are we?
-    // Ideally, this ticks with the apk version info for the APEX packaging
-
-    // set up media metrics record
-    mMetricsHandle = mediametrics_create(kKeyPlayer);
-    mediametrics_setUid(mMetricsHandle, mClientUid);
-    mediametrics_setInt64(mMetricsHandle, kPlayerVersion, mPlayerVersion);
-
-    mNuPlayer2Looper->start(
-            false, /* runOnCallingThread */
-            true,  /* canCallJava */
-            PRIORITY_AUDIO);
-
-    mNuPlayer2Looper->registerHandler(mPlayer);
-
-    mPlayer->setDriver(this);
-}
-
-NuPlayer2Driver::~NuPlayer2Driver() {
-    ALOGV("~NuPlayer2Driver(%p)", this);
-    mNuPlayer2Looper->stop();
-    mLooper->stop();
-
-    // finalize any pending metrics, usually a no-op.
-    updateMetrics("destructor");
-    logMetrics("destructor");
-
-    mediametrics_delete(mMetricsHandle);
-}
-
-status_t NuPlayer2Driver::initCheck() {
-    mLooper->start(
-            false, /* runOnCallingThread */
-            true,  /* canCallJava */
-            PRIORITY_AUDIO);
-
-    mLooper->registerHandler(this);
-    return OK;
-}
-
-status_t NuPlayer2Driver::setDataSource(const sp<DataSourceDesc> &dsd) {
-    ALOGV("setDataSource(%p)", this);
-    Mutex::Autolock autoLock(mLock);
-
-    if (mState != STATE_IDLE) {
-        return INVALID_OPERATION;
-    }
-
-    mSrcId = dsd->mId;
-    mState = STATE_SET_DATASOURCE_PENDING;
-
-    mPlayer->setDataSourceAsync(dsd);
-
-    while (mState == STATE_SET_DATASOURCE_PENDING) {
-        mCondition.wait(mLock);
-    }
-
-    return mAsyncResult;
-}
-
-status_t NuPlayer2Driver::prepareNextDataSource(const sp<DataSourceDesc> &dsd) {
-    ALOGV("prepareNextDataSource(%p)", this);
-    Mutex::Autolock autoLock(mLock);
-
-    mPlayer->prepareNextDataSourceAsync(dsd);
-
-    return OK;
-}
-
-status_t NuPlayer2Driver::playNextDataSource(int64_t srcId) {
-    ALOGV("playNextDataSource(%p)", this);
-    Mutex::Autolock autoLock(mLock);
-
-    mSrcId = srcId;
-    mPlayer->playNextDataSource(srcId);
-
-    return OK;
-}
-
-status_t NuPlayer2Driver::setVideoSurfaceTexture(const sp<ANativeWindowWrapper> &nww) {
-    ALOGV("setVideoSurfaceTexture(%p)", this);
-    Mutex::Autolock autoLock(mLock);
-
-    if (mSetSurfaceInProgress) {
-        return INVALID_OPERATION;
-    }
-
-    switch (mState) {
-        case STATE_SET_DATASOURCE_PENDING:
-        case STATE_RESET_IN_PROGRESS:
-            return INVALID_OPERATION;
-
-        default:
-            break;
-    }
-
-    mSetSurfaceInProgress = true;
-
-    mPlayer->setVideoSurfaceTextureAsync(nww);
-
-    while (mSetSurfaceInProgress) {
-        mCondition.wait(mLock);
-    }
-
-    return OK;
-}
-
-status_t NuPlayer2Driver::getBufferingSettings(BufferingSettings* buffering) {
-    ALOGV("getBufferingSettings(%p)", this);
-    {
-        Mutex::Autolock autoLock(mLock);
-        if (mState == STATE_IDLE) {
-            return INVALID_OPERATION;
-        }
-    }
-
-    return mPlayer->getBufferingSettings(buffering);
-}
-
-status_t NuPlayer2Driver::setBufferingSettings(const BufferingSettings& buffering) {
-    ALOGV("setBufferingSettings(%p)", this);
-    {
-        Mutex::Autolock autoLock(mLock);
-        if (mState == STATE_IDLE) {
-            return INVALID_OPERATION;
-        }
-    }
-
-    return mPlayer->setBufferingSettings(buffering);
-}
-
-status_t NuPlayer2Driver::prepareAsync() {
-    ALOGV("prepareAsync(%p)", this);
-    Mutex::Autolock autoLock(mLock);
-
-    switch (mState) {
-        case STATE_UNPREPARED:
-            mState = STATE_PREPARING;
-            mPlayer->prepareAsync();
-            return OK;
-        default:
-            return INVALID_OPERATION;
-    };
-}
-
-status_t NuPlayer2Driver::start() {
-    ALOGD("start(%p), state is %d, eos is %d", this, mState, mAtEOS);
-    Mutex::Autolock autoLock(mLock);
-    return start_l();
-}
-
-status_t NuPlayer2Driver::start_l() {
-    switch (mState) {
-        case STATE_PAUSED:
-        case STATE_PREPARED:
-        {
-            mPlayer->start();
-            FALLTHROUGH_INTENDED;
-        }
-
-        case STATE_RUNNING:
-        {
-            if (mAtEOS) {
-                mPlayer->rewind();
-                mAtEOS = false;
-                mPositionUs = -1;
-            }
-            break;
-        }
-
-        default:
-            return INVALID_OPERATION;
-    }
-
-    mState = STATE_RUNNING;
-
-    return OK;
-}
-
-status_t NuPlayer2Driver::pause() {
-    ALOGD("pause(%p)", this);
-    // The NuPlayerRenderer may get flushed if pause for long enough, e.g. the pause timeout tear
-    // down for audio offload mode. If that happens, the NuPlayerRenderer will no longer know the
-    // current position. So similar to seekTo, update |mPositionUs| to the pause position by calling
-    // getCurrentPosition here.
-    int64_t unused;
-    getCurrentPosition(&unused);
-
-    Mutex::Autolock autoLock(mLock);
-
-    switch (mState) {
-        case STATE_PAUSED:
-            return OK;
-
-        case STATE_PREPARED:
-        case STATE_RUNNING:
-            mState = STATE_PAUSED;
-            mPlayer->pause();
-            break;
-
-        default:
-            return INVALID_OPERATION;
-    }
-
-    return OK;
-}
-
-bool NuPlayer2Driver::isPlaying() {
-    return mState == STATE_RUNNING && !mAtEOS;
-}
-
-status_t NuPlayer2Driver::setPlaybackSettings(const AudioPlaybackRate &rate) {
-    status_t err = mPlayer->setPlaybackSettings(rate);
-    if (err == OK) {
-        // try to update position
-        int64_t unused;
-        getCurrentPosition(&unused);
-    }
-    return err;
-}
-
-status_t NuPlayer2Driver::getPlaybackSettings(AudioPlaybackRate *rate) {
-    return mPlayer->getPlaybackSettings(rate);
-}
-
-status_t NuPlayer2Driver::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) {
-    return mPlayer->setSyncSettings(sync, videoFpsHint);
-}
-
-status_t NuPlayer2Driver::getSyncSettings(AVSyncSettings *sync, float *videoFps) {
-    return mPlayer->getSyncSettings(sync, videoFps);
-}
-
-status_t NuPlayer2Driver::seekTo(int64_t msec, MediaPlayer2SeekMode mode) {
-    ALOGD("seekTo(%p) (%lld ms, %d) at state %d", this, (long long)msec, mode, mState);
-    Mutex::Autolock autoLock(mLock);
-
-    int64_t seekTimeUs = msec * 1000LL;
-
-    switch (mState) {
-        case STATE_PREPARED:
-        case STATE_PAUSED:
-        case STATE_RUNNING:
-        {
-            mAtEOS = false;
-            mSeekInProgress = true;
-            mPlayer->seekToAsync(seekTimeUs, mode, true /* needNotify */);
-            break;
-        }
-
-        default:
-            return INVALID_OPERATION;
-    }
-
-    mPositionUs = seekTimeUs;
-    return OK;
-}
-
-status_t NuPlayer2Driver::getCurrentPosition(int64_t *msec) {
-    int64_t tempUs = 0;
-    {
-        Mutex::Autolock autoLock(mLock);
-        if (mSeekInProgress || (mState == STATE_PAUSED && !mAtEOS)) {
-            tempUs = (mPositionUs <= 0) ? 0 : mPositionUs;
-            *msec = divRound(tempUs, (int64_t)(1000));
-            return OK;
-        }
-    }
-
-    status_t ret = mPlayer->getCurrentPosition(&tempUs);
-
-    Mutex::Autolock autoLock(mLock);
-    // We need to check mSeekInProgress here because mPlayer->seekToAsync is an async call, which
-    // means getCurrentPosition can be called before seek is completed. Iow, renderer may return a
-    // position value that's different the seek to position.
-    if (ret != OK) {
-        tempUs = (mPositionUs <= 0) ? 0 : mPositionUs;
-    } else {
-        mPositionUs = tempUs;
-    }
-    *msec = divRound(tempUs, (int64_t)(1000));
-    return OK;
-}
-
-status_t NuPlayer2Driver::getDuration(int64_t *msec) {
-    Mutex::Autolock autoLock(mLock);
-
-    if (mDurationUs < 0) {
-        return UNKNOWN_ERROR;
-    }
-
-    *msec = (mDurationUs + 500LL) / 1000;
-
-    return OK;
-}
-
-void NuPlayer2Driver::updateMetrics(const char *where) {
-    if (where == NULL) {
-        where = "unknown";
-    }
-    ALOGV("updateMetrics(%p) from %s at state %d", this, where, mState);
-
-    // gather the final stats for this record
-    Vector<sp<AMessage>> trackStats;
-    mPlayer->getStats(&trackStats);
-
-    if (trackStats.size() > 0) {
-        for (size_t i = 0; i < trackStats.size(); ++i) {
-            const sp<AMessage> &stats = trackStats.itemAt(i);
-
-            AString mime;
-            stats->findString("mime", &mime);
-
-            AString name;
-            stats->findString("component-name", &name);
-
-            if (mime.startsWith("video/")) {
-                int32_t width, height;
-                mediametrics_setCString(mMetricsHandle, kPlayerVMime, mime.c_str());
-                if (!name.empty()) {
-                    mediametrics_setCString(mMetricsHandle, kPlayerVCodec, name.c_str());
-                }
-
-                if (stats->findInt32("width", &width)
-                        && stats->findInt32("height", &height)) {
-                    mediametrics_setInt32(mMetricsHandle, kPlayerWidth, width);
-                    mediametrics_setInt32(mMetricsHandle, kPlayerHeight, height);
-                }
-
-                int64_t numFramesTotal = 0;
-                int64_t numFramesDropped = 0;
-                stats->findInt64("frames-total", &numFramesTotal);
-                stats->findInt64("frames-dropped-output", &numFramesDropped);
-
-                mediametrics_setInt64(mMetricsHandle, kPlayerFrames, numFramesTotal);
-                mediametrics_setInt64(mMetricsHandle, kPlayerFramesDropped, numFramesDropped);
-
-                float frameRate = 0;
-                if (stats->findFloat("frame-rate-output", &frameRate)) {
-                    mediametrics_setInt64(mMetricsHandle, kPlayerFrameRate, frameRate);
-                }
-
-            } else if (mime.startsWith("audio/")) {
-                mediametrics_setCString(mMetricsHandle, kPlayerAMime, mime.c_str());
-                if (!name.empty()) {
-                    mediametrics_setCString(mMetricsHandle, kPlayerACodec, name.c_str());
-                }
-            }
-        }
-    }
-
-    // always provide duration and playing time, even if they have 0/unknown values.
-
-    // getDuration() uses mLock for mutex -- careful where we use it.
-    int64_t duration_ms = -1;
-    getDuration(&duration_ms);
-    mediametrics_setInt64(mMetricsHandle, kPlayerDuration, duration_ms);
-
-    mediametrics_setInt64(mMetricsHandle, kPlayerPlaying, (mPlayingTimeUs+500)/1000 );
-
-    if (mRebufferingEvents != 0) {
-        mediametrics_setInt64(mMetricsHandle, kPlayerRebuffering, (mRebufferingTimeUs+500)/1000 );
-        mediametrics_setInt32(mMetricsHandle, kPlayerRebufferingCount, mRebufferingEvents);
-        mediametrics_setInt32(mMetricsHandle, kPlayerRebufferingAtExit, mRebufferingAtExit);
-    }
-
-    mediametrics_setCString(mMetricsHandle, kPlayerDataSourceType, mPlayer->getDataSourceType());
-}
-
-
-void NuPlayer2Driver::logMetrics(const char *where) {
-    if (where == NULL) {
-        where = "unknown";
-    }
-    ALOGV("logMetrics(%p) from %s at state %d", this, where, mState);
-
-    if (mMetricsHandle == 0 || mediametrics_isEnabled() == false) {
-        return;
-    }
-
-    // log only non-empty records
-    // we always updateMetrics() before we get here
-    // and that always injects 3 fields (duration, playing time, and
-    // datasource) into the record.
-    // So the canonical "empty" record has 3 elements in it.
-    if (mediametrics_count(mMetricsHandle) > 3) {
-        mediametrics_selfRecord(mMetricsHandle);
-        // re-init in case we prepare() and start() again.
-        mediametrics_delete(mMetricsHandle);
-        mMetricsHandle = mediametrics_create(kKeyPlayer);
-        mediametrics_setUid(mMetricsHandle, mClientUid);
-        mediametrics_setInt64(mMetricsHandle, kPlayerVersion, mPlayerVersion);
-    } else {
-        ALOGV("did not have anything to record");
-    }
-}
-
-status_t NuPlayer2Driver::reset() {
-    ALOGD("reset(%p) at state %d", this, mState);
-
-    updateMetrics("reset");
-    logMetrics("reset");
-
-    Mutex::Autolock autoLock(mLock);
-
-    switch (mState) {
-        case STATE_IDLE:
-            return OK;
-
-        case STATE_SET_DATASOURCE_PENDING:
-        case STATE_RESET_IN_PROGRESS:
-            return INVALID_OPERATION;
-
-        case STATE_PREPARING:
-        {
-            notifyListener_l(mSrcId, MEDIA2_PREPARED);
-            break;
-        }
-
-        default:
-            break;
-    }
-
-    mState = STATE_RESET_IN_PROGRESS;
-    mPlayer->resetAsync();
-
-    while (mState == STATE_RESET_IN_PROGRESS) {
-        mCondition.wait(mLock);
-    }
-
-    mDurationUs = -1;
-    mPositionUs = -1;
-    mLooping = false;
-    mPlayingTimeUs = 0;
-    mRebufferingTimeUs = 0;
-    mRebufferingEvents = 0;
-    mRebufferingAtExit = false;
-
-    return OK;
-}
-
-status_t NuPlayer2Driver::notifyAt(int64_t mediaTimeUs) {
-    ALOGV("notifyAt(%p), time:%lld", this, (long long)mediaTimeUs);
-    return mPlayer->notifyAt(mediaTimeUs);
-}
-
-status_t NuPlayer2Driver::setLooping(int loop) {
-    mLooping = loop != 0;
-    return OK;
-}
-
-status_t NuPlayer2Driver::invoke(const PlayerMessage &request, PlayerMessage *response) {
-    if (response == NULL) {
-        ALOGE("reply is a NULL pointer");
-        return BAD_VALUE;
-    }
-
-    RepeatedPtrField<const Value>::const_iterator it = request.values().cbegin();
-    int32_t methodId = (it++)->int32_value();
-
-    switch (methodId) {
-        case MEDIA_PLAYER2_INVOKE_ID_SET_VIDEO_SCALING_MODE:
-        {
-            int mode = (it++)->int32_value();
-            return mPlayer->setVideoScalingMode(mode);
-        }
-
-        case MEDIA_PLAYER2_INVOKE_ID_GET_TRACK_INFO:
-        {
-            int64_t srcId = (it++)->int64_value();
-            return mPlayer->getTrackInfo(srcId, response);
-        }
-
-        case MEDIA_PLAYER2_INVOKE_ID_SELECT_TRACK:
-        {
-            int64_t srcId = (it++)->int64_value();
-            int trackIndex = (it++)->int32_value();
-            int64_t msec = 0;
-            // getCurrentPosition should always return OK
-            getCurrentPosition(&msec);
-            return mPlayer->selectTrack(srcId, trackIndex, true /* select */, msec * 1000LL);
-        }
-
-        case MEDIA_PLAYER2_INVOKE_ID_UNSELECT_TRACK:
-        {
-            int64_t srcId = (it++)->int64_value();
-            int trackIndex = (it++)->int32_value();
-            return mPlayer->selectTrack(
-                    srcId, trackIndex, false /* select */, 0xdeadbeef /* not used */);
-        }
-
-        case MEDIA_PLAYER2_INVOKE_ID_GET_SELECTED_TRACK:
-        {
-            int64_t srcId = (it++)->int64_value();
-            int32_t type = (it++)->int32_value();
-            return mPlayer->getSelectedTrack(srcId, type, response);
-        }
-
-        default:
-        {
-            return INVALID_OPERATION;
-        }
-    }
-}
-
-void NuPlayer2Driver::setAudioSink(const sp<AudioSink> &audioSink) {
-    mPlayer->setAudioSink(audioSink);
-    mAudioSink = audioSink;
-}
-
-status_t NuPlayer2Driver::setParameter(
-        int /* key */, const Parcel & /* request */) {
-    return INVALID_OPERATION;
-}
-
-status_t NuPlayer2Driver::getParameter(int key __unused, Parcel *reply __unused) {
-    return INVALID_OPERATION;
-}
-
-status_t NuPlayer2Driver::getMetrics(char **buffer, size_t *length) {
-    updateMetrics("api");
-    if (mediametrics_getAttributes(mMetricsHandle, buffer, length))
-        return OK;
-    else
-        return FAILED_TRANSACTION;
-}
-
-void NuPlayer2Driver::notifyResetComplete(int64_t /* srcId */) {
-    ALOGD("notifyResetComplete(%p)", this);
-    Mutex::Autolock autoLock(mLock);
-
-    CHECK_EQ(mState, STATE_RESET_IN_PROGRESS);
-    mState = STATE_IDLE;
-    mCondition.broadcast();
-}
-
-void NuPlayer2Driver::notifySetSurfaceComplete(int64_t /* srcId */) {
-    ALOGV("notifySetSurfaceComplete(%p)", this);
-    Mutex::Autolock autoLock(mLock);
-
-    CHECK(mSetSurfaceInProgress);
-    mSetSurfaceInProgress = false;
-
-    mCondition.broadcast();
-}
-
-void NuPlayer2Driver::notifyDuration(int64_t /* srcId */, int64_t durationUs) {
-    Mutex::Autolock autoLock(mLock);
-    mDurationUs = durationUs;
-}
-
-void NuPlayer2Driver::notifyMorePlayingTimeUs(int64_t /* srcId */, int64_t playingUs) {
-    Mutex::Autolock autoLock(mLock);
-    mPlayingTimeUs += playingUs;
-}
-
-void NuPlayer2Driver::notifyMoreRebufferingTimeUs(int64_t /* srcId */, int64_t rebufferingUs) {
-    Mutex::Autolock autoLock(mLock);
-    mRebufferingTimeUs += rebufferingUs;
-    mRebufferingEvents++;
-}
-
-void NuPlayer2Driver::notifyRebufferingWhenExit(int64_t /* srcId */, bool status) {
-    Mutex::Autolock autoLock(mLock);
-    mRebufferingAtExit = status;
-}
-
-void NuPlayer2Driver::notifySeekComplete(int64_t srcId) {
-    ALOGV("notifySeekComplete(%p)", this);
-    Mutex::Autolock autoLock(mLock);
-    mSeekInProgress = false;
-    notifyListener_l(srcId, MEDIA2_SEEK_COMPLETE);
-}
-
-status_t NuPlayer2Driver::dump(
-        int fd, const Vector<String16> & /* args */) const {
-
-    Vector<sp<AMessage> > trackStats;
-    mPlayer->getStats(&trackStats);
-
-    AString logString(" NuPlayer2\n");
-    char buf[256] = {0};
-
-    bool locked = false;
-    for (int i = 0; i < kDumpLockRetries; ++i) {
-        if (mLock.tryLock() == NO_ERROR) {
-            locked = true;
-            break;
-        }
-        usleep(kDumpLockSleepUs);
-    }
-
-    if (locked) {
-        snprintf(buf, sizeof(buf), "  state(%d), atEOS(%d), looping(%d), autoLoop(%d)\n",
-                mState, mAtEOS, mLooping, mAutoLoop);
-        mLock.unlock();
-    } else {
-        snprintf(buf, sizeof(buf), "  NPD(%p) lock is taken\n", this);
-    }
-    logString.append(buf);
-
-    for (size_t i = 0; i < trackStats.size(); ++i) {
-        const sp<AMessage> &stats = trackStats.itemAt(i);
-
-        AString mime;
-        if (stats->findString("mime", &mime)) {
-            snprintf(buf, sizeof(buf), "  mime(%s)\n", mime.c_str());
-            logString.append(buf);
-        }
-
-        AString name;
-        if (stats->findString("component-name", &name)) {
-            snprintf(buf, sizeof(buf), "    decoder(%s)\n", name.c_str());
-            logString.append(buf);
-        }
-
-        if (mime.startsWith("video/")) {
-            int32_t width, height;
-            if (stats->findInt32("width", &width)
-                    && stats->findInt32("height", &height)) {
-                snprintf(buf, sizeof(buf), "    resolution(%d x %d)\n", width, height);
-                logString.append(buf);
-            }
-
-            int64_t numFramesTotal = 0;
-            int64_t numFramesDropped = 0;
-
-            stats->findInt64("frames-total", &numFramesTotal);
-            stats->findInt64("frames-dropped-output", &numFramesDropped);
-            snprintf(buf, sizeof(buf), "    numFramesTotal(%lld), numFramesDropped(%lld), "
-                     "percentageDropped(%.2f%%)\n",
-                     (long long)numFramesTotal,
-                     (long long)numFramesDropped,
-                     numFramesTotal == 0
-                            ? 0.0 : (double)(numFramesDropped * 100) / numFramesTotal);
-            logString.append(buf);
-        }
-    }
-
-    ALOGI("%s", logString.c_str());
-
-    if (fd >= 0) {
-        FILE *out = fdopen(dup(fd), "w");
-        fprintf(out, "%s", logString.c_str());
-        fclose(out);
-        out = NULL;
-    }
-
-    return OK;
-}
-
-void NuPlayer2Driver::onMessageReceived(const sp<AMessage> &msg) {
-    switch (msg->what()) {
-        case kWhatNotifyListener: {
-            int64_t srcId;
-            int32_t msgId;
-            int32_t ext1 = 0;
-            int32_t ext2 = 0;
-            CHECK(msg->findInt64("srcId", &srcId));
-            CHECK(msg->findInt32("messageId", &msgId));
-            msg->findInt32("ext1", &ext1);
-            msg->findInt32("ext2", &ext2);
-            sp<PlayerMessageWrapper> in;
-            sp<RefBase> obj;
-            if (msg->findObject("obj", &obj) && obj != NULL) {
-                in = static_cast<PlayerMessageWrapper *>(obj.get());
-            }
-            sendEvent(srcId, msgId, ext1, ext2, (in == NULL ? NULL : in->getPlayerMessage()));
-            break;
-        }
-        default:
-            break;
-    }
-}
-
-void NuPlayer2Driver::notifyListener(
-        int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
-    Mutex::Autolock autoLock(mLock);
-    notifyListener_l(srcId, msg, ext1, ext2, in);
-}
-
-void NuPlayer2Driver::notifyListener_l(
-        int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
-    ALOGD("notifyListener_l(%p), (%lld, %d, %d, %d, %d), loop setting(%d, %d)",
-            this, (long long)srcId, msg, ext1, ext2,
-            (in == NULL ? -1 : (int)in->ByteSize()), mAutoLoop, mLooping);
-    if (srcId == mSrcId) {
-        switch (msg) {
-            case MEDIA2_PLAYBACK_COMPLETE:
-            {
-                if (mState != STATE_RESET_IN_PROGRESS) {
-                    if (mAutoLoop) {
-                        audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
-                        if (mAudioSink != NULL) {
-                            streamType = mAudioSink->getAudioStreamType();
-                        }
-                        if (streamType == AUDIO_STREAM_NOTIFICATION) {
-                            ALOGW("disabling auto-loop for notification");
-                            mAutoLoop = false;
-                        }
-                    }
-                    if (mLooping || mAutoLoop) {
-                        mPlayer->rewind();
-                        if (mAudioSink != NULL) {
-                            // The renderer has stopped the sink at the end in order to play out
-                            // the last little bit of audio. In looping mode, we need to restart it.
-                            mAudioSink->start();
-                        }
-
-                        sp<AMessage> notify = new AMessage(kWhatNotifyListener, this);
-                        notify->setInt64("srcId", srcId);
-                        notify->setInt32("messageId", MEDIA2_INFO);
-                        notify->setInt32("ext1", MEDIA2_INFO_DATA_SOURCE_REPEAT);
-                        notify->post();
-                        return;
-                    }
-                    if (property_get_bool("persist.debug.sf.stats", false)) {
-                        Vector<String16> args;
-                        dump(-1, args);
-                    }
-                    mPlayer->pause();
-                    mState = STATE_PAUSED;
-                }
-                FALLTHROUGH_INTENDED;
-            }
-
-            case MEDIA2_ERROR:
-            {
-                // when we have an error, add it to the analytics for this playback.
-                // ext1 is our primary 'error type' value. Only add ext2 when non-zero.
-                // [test against msg is due to fall through from previous switch value]
-                if (msg == MEDIA2_ERROR) {
-                    mediametrics_setInt32(mMetricsHandle, kPlayerError, ext1);
-                    if (ext2 != 0) {
-                        mediametrics_setInt32(mMetricsHandle, kPlayerErrorCode, ext2);
-                    }
-                    mediametrics_setCString(mMetricsHandle, kPlayerErrorState, stateString(mState).c_str());
-                }
-                mAtEOS = true;
-                break;
-            }
-
-            default:
-                break;
-        }
-    }
-
-    sp<AMessage> notify = new AMessage(kWhatNotifyListener, this);
-    notify->setInt64("srcId", srcId);
-    notify->setInt32("messageId", msg);
-    notify->setInt32("ext1", ext1);
-    notify->setInt32("ext2", ext2);
-    notify->setObject("obj", PlayerMessageWrapper::Create((PlayerMessage*)in));
-    notify->post();
-}
-
-void NuPlayer2Driver::notifySetDataSourceCompleted(int64_t /* srcId */, status_t err) {
-    Mutex::Autolock autoLock(mLock);
-
-    CHECK_EQ(mState, STATE_SET_DATASOURCE_PENDING);
-
-    mAsyncResult = err;
-    mState = (err == OK) ? STATE_UNPREPARED : STATE_IDLE;
-    mCondition.broadcast();
-}
-
-void NuPlayer2Driver::notifyPrepareCompleted(int64_t srcId, status_t err) {
-    ALOGV("notifyPrepareCompleted %d", err);
-
-    Mutex::Autolock autoLock(mLock);
-
-    if (srcId != mSrcId) {
-        if (err == OK) {
-            notifyListener_l(srcId, MEDIA2_PREPARED);
-        } else {
-            notifyListener_l(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
-        }
-        return;
-    }
-
-    if (mState != STATE_PREPARING) {
-        // We were preparing asynchronously when the client called
-        // reset(), we sent a premature "prepared" notification and
-        // then initiated the reset. This notification is stale.
-        CHECK(mState == STATE_RESET_IN_PROGRESS || mState == STATE_IDLE);
-        return;
-    }
-
-    CHECK_EQ(mState, STATE_PREPARING);
-
-    mAsyncResult = err;
-
-    if (err == OK) {
-        // update state before notifying client, so that if client calls back into NuPlayer2Driver
-        // in response, NuPlayer2Driver has the right state
-        mState = STATE_PREPARED;
-        notifyListener_l(srcId, MEDIA2_PREPARED);
-    } else {
-        mState = STATE_UNPREPARED;
-        notifyListener_l(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
-    }
-
-    sp<MetaData> meta = mPlayer->getFileMeta();
-    int32_t loop;
-    if (meta != NULL
-            && meta->findInt32(kKeyAutoLoop, &loop) && loop != 0) {
-        mAutoLoop = true;
-    }
-
-    mCondition.broadcast();
-}
-
-void NuPlayer2Driver::notifyFlagsChanged(int64_t /* srcId */, uint32_t flags) {
-    Mutex::Autolock autoLock(mLock);
-
-    mPlayerFlags = flags;
-}
-
-// Modular DRM
-status_t NuPlayer2Driver::prepareDrm(
-        int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
-{
-    ALOGV("prepareDrm(%p) state: %d", this, mState);
-
-    // leaving the state verification for mediaplayer.cpp
-    status_t ret = mPlayer->prepareDrm(srcId, uuid, drmSessionId);
-
-    ALOGV("prepareDrm ret: %d", ret);
-
-    return ret;
-}
-
-status_t NuPlayer2Driver::releaseDrm(int64_t srcId)
-{
-    ALOGV("releaseDrm(%p) state: %d", this, mState);
-
-    // leaving the state verification for mediaplayer.cpp
-    status_t ret = mPlayer->releaseDrm(srcId);
-
-    ALOGV("releaseDrm ret: %d", ret);
-
-    return ret;
-}
-
-std::string NuPlayer2Driver::stateString(State state) {
-    const char *rval = NULL;
-    char rawbuffer[16];  // allows "%d"
-
-    switch (state) {
-        case STATE_IDLE: rval = "IDLE"; break;
-        case STATE_SET_DATASOURCE_PENDING: rval = "SET_DATASOURCE_PENDING"; break;
-        case STATE_UNPREPARED: rval = "UNPREPARED"; break;
-        case STATE_PREPARING: rval = "PREPARING"; break;
-        case STATE_PREPARED: rval = "PREPARED"; break;
-        case STATE_RUNNING: rval = "RUNNING"; break;
-        case STATE_PAUSED: rval = "PAUSED"; break;
-        case STATE_RESET_IN_PROGRESS: rval = "RESET_IN_PROGRESS"; break;
-        default:
-            // yes, this buffer is shared and vulnerable to races
-            snprintf(rawbuffer, sizeof(rawbuffer), "%d", state);
-            rval = rawbuffer;
-            break;
-    }
-
-    return rval;
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.h b/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.h
deleted file mode 100644
index c97e247..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-#include <mediaplayer2/MediaPlayer2Interface.h>
-
-#include <media/MediaMetrics.h>
-#include <media/stagefright/foundation/ABase.h>
-#include <mediaplayer2/JObjectHolder.h>
-
-namespace android {
-
-struct ALooper;
-struct MediaClock;
-struct NuPlayer2;
-
-struct NuPlayer2Driver : public MediaPlayer2Interface {
-    explicit NuPlayer2Driver(pid_t pid, uid_t uid, const sp<JObjectHolder> &context);
-
-    virtual status_t initCheck() override;
-
-    virtual status_t setDataSource(const sp<DataSourceDesc> &dsd) override;
-    virtual status_t prepareNextDataSource(const sp<DataSourceDesc> &dsd) override;
-    virtual status_t playNextDataSource(int64_t srcId) override;
-
-    virtual status_t setVideoSurfaceTexture(const sp<ANativeWindowWrapper> &nww) override;
-
-    virtual status_t getBufferingSettings(
-            BufferingSettings* buffering /* nonnull */) override;
-    virtual status_t setBufferingSettings(const BufferingSettings& buffering) override;
-
-    virtual status_t prepareAsync() override;
-    virtual status_t start() override;
-    virtual status_t pause() override;
-    virtual bool isPlaying() override;
-    virtual status_t setPlaybackSettings(const AudioPlaybackRate &rate) override;
-    virtual status_t getPlaybackSettings(AudioPlaybackRate *rate) override;
-    virtual status_t setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) override;
-    virtual status_t getSyncSettings(AVSyncSettings *sync, float *videoFps) override;
-    virtual status_t seekTo(
-            int64_t msec,
-            MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC) override;
-    virtual status_t getCurrentPosition(int64_t *msec) override;
-    virtual status_t getDuration(int64_t *msec) override;
-    virtual status_t reset() override;
-    virtual status_t notifyAt(int64_t mediaTimeUs) override;
-    virtual status_t setLooping(int loop) override;
-    virtual status_t invoke(const PlayerMessage &request, PlayerMessage *response) override;
-    virtual void setAudioSink(const sp<AudioSink> &audioSink) override;
-    virtual status_t setParameter(int key, const Parcel &request) override;
-    virtual status_t getParameter(int key, Parcel *reply) override;
-    virtual status_t getMetrics(char **buf, size_t *length) override;
-
-    virtual status_t dump(int fd, const Vector<String16> &args) const override;
-
-    virtual void onMessageReceived(const sp<AMessage> &msg) override;
-
-    void notifySetDataSourceCompleted(int64_t srcId, status_t err);
-    void notifyPrepareCompleted(int64_t srcId, status_t err);
-    void notifyResetComplete(int64_t srcId);
-    void notifySetSurfaceComplete(int64_t srcId);
-    void notifyDuration(int64_t srcId, int64_t durationUs);
-    void notifyMorePlayingTimeUs(int64_t srcId, int64_t timeUs);
-    void notifyMoreRebufferingTimeUs(int64_t srcId, int64_t timeUs);
-    void notifyRebufferingWhenExit(int64_t srcId, bool status);
-    void notifySeekComplete(int64_t srcId);
-    void notifyListener(int64_t srcId, int msg, int ext1 = 0, int ext2 = 0,
-                        const PlayerMessage *in = NULL);
-    void notifyFlagsChanged(int64_t srcId, uint32_t flags);
-
-    // Modular DRM
-    virtual status_t prepareDrm(
-            int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId);
-    virtual status_t releaseDrm(int64_t srcId);
-
-protected:
-    virtual ~NuPlayer2Driver();
-
-private:
-    enum State {
-        STATE_IDLE,
-        STATE_SET_DATASOURCE_PENDING,
-        STATE_UNPREPARED,
-        STATE_PREPARING,
-        STATE_PREPARED,
-        STATE_RUNNING,
-        STATE_PAUSED,
-        STATE_RESET_IN_PROGRESS,
-    };
-
-    std::string stateString(State state);
-
-    enum {
-        kWhatNotifyListener,
-    };
-
-    mutable Mutex mLock;
-    Condition mCondition;
-
-    State mState;
-
-    status_t mAsyncResult;
-
-    // The following are protected through "mLock"
-    // >>>
-    int64_t mSrcId;
-    bool mSetSurfaceInProgress;
-    int64_t mDurationUs;
-    int64_t mPositionUs;
-    bool mSeekInProgress;
-    int64_t mPlayingTimeUs;
-    int64_t mRebufferingTimeUs;
-    int32_t mRebufferingEvents;
-    bool mRebufferingAtExit;
-    // <<<
-
-    sp<ALooper> mLooper;
-    sp<ALooper> mNuPlayer2Looper;
-    const sp<MediaClock> mMediaClock;
-    const sp<NuPlayer2> mPlayer;
-    sp<AudioSink> mAudioSink;
-    uint32_t mPlayerFlags;
-
-    mediametrics_handle_t mMetricsHandle;
-    int64_t mPlayerVersion;
-    uid_t mClientUid;
-
-    bool mAtEOS;
-    bool mLooping;
-    bool mAutoLoop;
-
-    void updateMetrics(const char *where);
-    void logMetrics(const char *where);
-
-    status_t start_l();
-    void notifyListener_l(int64_t srcId, int msg, int ext1 = 0, int ext2 = 0,
-                          const PlayerMessage *in = NULL);
-
-    DISALLOW_EVIL_CONSTRUCTORS(NuPlayer2Driver);
-};
-
-}  // namespace android
-
-
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.cpp
deleted file mode 100644
index f41a431..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright 2017 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 "NuPlayer2Drm"
-
-#include "NuPlayer2Drm.h"
-
-#include <media/NdkWrapper.h>
-#include <utils/Log.h>
-#include <sstream>
-
-namespace android {
-
-Vector<DrmUUID> NuPlayer2Drm::parsePSSH(const void *pssh, size_t psshsize)
-{
-    Vector<DrmUUID> drmSchemes, empty;
-    const int DATALEN_SIZE = 4;
-
-    // the format of the buffer is 1 or more of:
-    //    {
-    //        16 byte uuid
-    //        4 byte data length N
-    //        N bytes of data
-    //    }
-    // Determine the number of entries in the source data.
-    // Since we got the data from stagefright, we trust it is valid and properly formatted.
-
-    const uint8_t *data = (const uint8_t*)pssh;
-    size_t len = psshsize;
-    size_t numentries = 0;
-    while (len > 0) {
-        if (len < DrmUUID::UUID_SIZE) {
-            ALOGE("ParsePSSH: invalid PSSH data");
-            return empty;
-        }
-
-        const uint8_t *uuidPtr = data;
-
-        // skip uuid
-        data += DrmUUID::UUID_SIZE;
-        len -= DrmUUID::UUID_SIZE;
-
-        // get data length
-        if (len < DATALEN_SIZE) {
-            ALOGE("ParsePSSH: invalid PSSH data");
-            return empty;
-        }
-
-        uint32_t datalen = *((uint32_t*)data);
-        data += DATALEN_SIZE;
-        len -= DATALEN_SIZE;
-
-        if (len < datalen) {
-            ALOGE("ParsePSSH: invalid PSSH data");
-            return empty;
-        }
-
-        // skip the data
-        data += datalen;
-        len -= datalen;
-
-        DrmUUID _uuid(uuidPtr);
-        drmSchemes.add(_uuid);
-
-        ALOGV("ParsePSSH[%zu]: %s: %s", numentries,
-                _uuid.toHexString().string(),
-                DrmUUID::arrayToHex(data, datalen).string()
-             );
-
-        numentries++;
-    }
-
-    return drmSchemes;
-}
-
-Vector<DrmUUID> NuPlayer2Drm::getSupportedDrmSchemes(const void *pssh, size_t psshsize)
-{
-    Vector<DrmUUID> psshDRMs = parsePSSH(pssh, psshsize);
-
-    Vector<DrmUUID> supportedDRMs;
-    for (size_t i = 0; i < psshDRMs.size(); i++) {
-        DrmUUID uuid = psshDRMs[i];
-        if (AMediaDrmWrapper::isCryptoSchemeSupported(uuid.ptr(), NULL)) {
-            supportedDRMs.add(uuid);
-        }
-    }
-
-    ALOGV("getSupportedDrmSchemes: psshDRMs: %zu supportedDRMs: %zu",
-            psshDRMs.size(), supportedDRMs.size());
-
-    return supportedDRMs;
-}
-
-sp<ABuffer> NuPlayer2Drm::retrieveDrmInfo(const void *pssh, uint32_t psshsize)
-{
-    std::ostringstream buf;
-
-    // 1) PSSH bytes
-    buf.write(reinterpret_cast<const char *>(&psshsize), sizeof(psshsize));
-    buf.write(reinterpret_cast<const char *>(pssh), psshsize);
-
-    ALOGV("retrieveDrmInfo: MEDIA2_DRM_INFO  PSSH: size: %u %s", psshsize,
-            DrmUUID::arrayToHex((uint8_t*)pssh, psshsize).string());
-
-    // 2) supportedDRMs
-    Vector<DrmUUID> supportedDRMs = getSupportedDrmSchemes(pssh, psshsize);
-    uint32_t n = supportedDRMs.size();
-    buf.write(reinterpret_cast<char *>(&n), sizeof(n));
-    for (size_t i = 0; i < n; i++) {
-        DrmUUID uuid = supportedDRMs[i];
-        buf.write(reinterpret_cast<const char *>(&n), sizeof(n));
-        buf.write(reinterpret_cast<const char *>(uuid.ptr()), DrmUUID::UUID_SIZE);
-
-        ALOGV("retrieveDrmInfo: MEDIA2_DRM_INFO  supportedScheme[%zu] %s", i,
-                uuid.toHexString().string());
-    }
-
-    sp<ABuffer> drmInfoBuffer = ABuffer::CreateAsCopy(buf.str().c_str(), buf.tellp());
-    return drmInfoBuffer;
-}
-
-status_t NuPlayer2Drm::retrieveDrmInfo(PsshInfo *psshInfo, PlayerMessage *playerMsg)
-{
-    std::ostringstream pssh, drmInfo;
-
-    // 0) Generate PSSH bytes
-    for (size_t i = 0; i < psshInfo->numentries; i++) {
-        PsshEntry *entry = &psshInfo->entries[i];
-        uint32_t datalen = entry->datalen;
-        pssh.write(reinterpret_cast<const char *>(&entry->uuid), sizeof(entry->uuid));
-        pssh.write(reinterpret_cast<const char *>(&datalen), sizeof(datalen));
-        pssh.write(reinterpret_cast<const char *>(entry->data), datalen);
-    }
-
-    uint32_t psshSize = pssh.tellp();
-    std::string psshBase = pssh.str();
-    const auto* psshPtr = reinterpret_cast<const uint8_t*>(psshBase.c_str());
-    ALOGV("retrieveDrmInfo: MEDIA_DRM_INFO  PSSH: size: %u %s", psshSize,
-            DrmUUID::arrayToHex(psshPtr, psshSize).string());
-
-    // 1) Write PSSH bytes
-    playerMsg->add_values()->set_bytes_value(
-            reinterpret_cast<const char *>(pssh.str().c_str()), psshSize);
-
-    // 2) Write supportedDRMs
-    uint32_t numentries = psshInfo->numentries;
-    playerMsg->add_values()->set_int32_value(numentries);
-    for (size_t i = 0; i < numentries; i++) {
-        PsshEntry *entry = &psshInfo->entries[i];
-        playerMsg->add_values()->set_bytes_value(
-                reinterpret_cast<const char *>(&entry->uuid), sizeof(entry->uuid));
-        ALOGV("retrieveDrmInfo: MEDIA_DRM_INFO  supportedScheme[%zu] %s", i,
-                DrmUUID::arrayToHex((const uint8_t*)&entry->uuid, sizeof(AMediaUUID)).string());
-    }
-    return OK;
-}
-
-}   // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.h b/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.h
deleted file mode 100644
index 968d1be..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-#ifndef NUPLAYER2_DRM_H_
-#define NUPLAYER2_DRM_H_
-
-#include <media/NdkMediaExtractor.h>
-#include <media/stagefright/foundation/ABuffer.h>
-
-#include <utils/String8.h>
-#include <utils/Vector.h>
-
-#include "mediaplayer2.pb.h"
-
-using android::media::MediaPlayer2Proto::PlayerMessage;
-
-namespace android {
-
-    struct DrmUUID {
-        static const int UUID_SIZE = 16;
-
-        DrmUUID() {
-            memset(this->uuid, 0, sizeof(uuid));
-        }
-
-        // to allow defining Vector/KeyedVector of UUID type
-        DrmUUID(const DrmUUID &a) {
-            memcpy(this->uuid, a.uuid, sizeof(uuid));
-        }
-
-        // to allow defining Vector/KeyedVector of UUID type
-        DrmUUID(const uint8_t uuid_in[UUID_SIZE]) {
-            memcpy(this->uuid, uuid_in, sizeof(uuid));
-        }
-
-        const uint8_t *ptr() const {
-            return uuid;
-        }
-
-        String8 toHexString() const {
-            return arrayToHex(uuid, UUID_SIZE);
-        }
-
-        static String8 toHexString(const uint8_t uuid_in[UUID_SIZE]) {
-            return arrayToHex(uuid_in, UUID_SIZE);
-        }
-
-        static String8 arrayToHex(const uint8_t *array, int bytes) {
-            String8 result;
-            for (int i = 0; i < bytes; i++) {
-                result.appendFormat("%02x", array[i]);
-            }
-
-            return result;
-        }
-
-    protected:
-        uint8_t uuid[UUID_SIZE];
-    };
-
-
-    struct NuPlayer2Drm {
-
-        // static helpers - internal
-
-    protected:
-        static Vector<DrmUUID> parsePSSH(const void *pssh, size_t psshsize);
-        static Vector<DrmUUID> getSupportedDrmSchemes(const void *pssh, size_t psshsize);
-
-        // static helpers - public
-
-    public:
-        static sp<ABuffer> retrieveDrmInfo(const void *pssh, uint32_t psshsize);
-        static status_t retrieveDrmInfo(PsshInfo *, PlayerMessage *);
-
-    };  // NuPlayer2Drm
-
-}   // android
-
-#endif     //NUPLAYER2_DRM_H_
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.cpp
deleted file mode 100644
index fd459df..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.cpp
+++ /dev/null
@@ -1,2096 +0,0 @@
-/*
- * Copyright (C) 2010 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 "NuPlayer2Renderer"
-#include <utils/Log.h>
-
-#include "JWakeLock.h"
-#include "NuPlayer2Renderer.h"
-#include <algorithm>
-#include <cutils/properties.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/AUtils.h>
-#include <media/stagefright/MediaClock.h>
-#include <media/stagefright/MediaCodecConstants.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/Utils.h>
-#include <media/stagefright/VideoFrameScheduler2.h>
-#include <media/MediaCodecBuffer.h>
-
-#include <inttypes.h>
-
-namespace android {
-
-/*
- * Example of common configuration settings in shell script form
-
-   #Turn offload audio off (use PCM for Play Music) -- AudioPolicyManager
-   adb shell setprop audio.offload.disable 1
-
-   #Allow offload audio with video (requires offloading to be enabled) -- AudioPolicyManager
-   adb shell setprop audio.offload.video 1
-
-   #Use audio callbacks for PCM data
-   adb shell setprop media.stagefright.audio.cbk 1
-
-   #Use deep buffer for PCM data with video (it is generally enabled for audio-only)
-   adb shell setprop media.stagefright.audio.deep 1
-
-   #Set size of buffers for pcm audio sink in msec (example: 1000 msec)
-   adb shell setprop media.stagefright.audio.sink 1000
-
- * These configurations take effect for the next track played (not the current track).
- */
-
-static inline bool getUseAudioCallbackSetting() {
-    return property_get_bool("media.stagefright.audio.cbk", false /* default_value */);
-}
-
-static inline int32_t getAudioSinkPcmMsSetting() {
-    return property_get_int32(
-            "media.stagefright.audio.sink", 500 /* default_value */);
-}
-
-// Maximum time in paused state when offloading audio decompression. When elapsed, the AudioSink
-// is closed to allow the audio DSP to power down.
-static const int64_t kOffloadPauseMaxUs = 10000000LL;
-
-// Maximum allowed delay from AudioSink, 1.5 seconds.
-static const int64_t kMaxAllowedAudioSinkDelayUs = 1500000LL;
-
-static const int64_t kMinimumAudioClockUpdatePeriodUs = 20 /* msec */ * 1000;
-
-// Default video frame display duration when only video exists.
-// Used to set max media time in MediaClock.
-static const int64_t kDefaultVideoFrameIntervalUs = 100000LL;
-
-// static
-const NuPlayer2::Renderer::PcmInfo NuPlayer2::Renderer::AUDIO_PCMINFO_INITIALIZER = {
-        AUDIO_CHANNEL_NONE,
-        AUDIO_OUTPUT_FLAG_NONE,
-        AUDIO_FORMAT_INVALID,
-        0, // mNumChannels
-        0 // mSampleRate
-};
-
-// static
-const int64_t NuPlayer2::Renderer::kMinPositionUpdateDelayUs = 100000LL;
-
-static audio_format_t constexpr audioFormatFromEncoding(int32_t pcmEncoding) {
-    switch (pcmEncoding) {
-    case kAudioEncodingPcmFloat:
-        return AUDIO_FORMAT_PCM_FLOAT;
-    case kAudioEncodingPcm16bit:
-        return AUDIO_FORMAT_PCM_16_BIT;
-    case kAudioEncodingPcm8bit:
-        return AUDIO_FORMAT_PCM_8_BIT;  // TODO: do we want to support this?
-    default:
-        ALOGE("%s: Invalid encoding: %d", __func__, pcmEncoding);
-        return AUDIO_FORMAT_INVALID;
-    }
-}
-
-NuPlayer2::Renderer::Renderer(
-        const sp<MediaPlayer2Interface::AudioSink> &sink,
-        const sp<MediaClock> &mediaClock,
-        const sp<AMessage> &notify,
-        const sp<JObjectHolder> &context,
-        uint32_t flags)
-    : mAudioSink(sink),
-      mUseVirtualAudioSink(false),
-      mNotify(notify),
-      mFlags(flags),
-      mNumFramesWritten(0),
-      mDrainAudioQueuePending(false),
-      mDrainVideoQueuePending(false),
-      mAudioQueueGeneration(0),
-      mVideoQueueGeneration(0),
-      mAudioDrainGeneration(0),
-      mVideoDrainGeneration(0),
-      mAudioEOSGeneration(0),
-      mMediaClock(mediaClock),
-      mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT),
-      mAudioFirstAnchorTimeMediaUs(-1),
-      mAnchorTimeMediaUs(-1),
-      mAnchorNumFramesWritten(-1),
-      mVideoLateByUs(0LL),
-      mNextVideoTimeMediaUs(-1),
-      mHasAudio(false),
-      mHasVideo(false),
-      mNotifyCompleteAudio(false),
-      mNotifyCompleteVideo(false),
-      mSyncQueues(false),
-      mPaused(true),
-      mPauseDrainAudioAllowedUs(0),
-      mVideoSampleReceived(false),
-      mVideoRenderingStarted(false),
-      mVideoRenderingStartGeneration(0),
-      mAudioRenderingStartGeneration(0),
-      mRenderingDataDelivered(false),
-      mNextAudioClockUpdateTimeUs(-1),
-      mLastAudioMediaTimeUs(-1),
-      mAudioOffloadPauseTimeoutGeneration(0),
-      mAudioTornDown(false),
-      mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER),
-      mCurrentPcmInfo(AUDIO_PCMINFO_INITIALIZER),
-      mTotalBuffersQueued(0),
-      mLastAudioBufferDrained(0),
-      mUseAudioCallback(false),
-      mWakeLock(new JWakeLock(context)) {
-    CHECK(mediaClock != NULL);
-    mMediaClock->setPlaybackRate(mPlaybackSettings.mSpeed);
-}
-
-NuPlayer2::Renderer::~Renderer() {
-    if (offloadingAudio()) {
-        mAudioSink->stop();
-        mAudioSink->flush();
-        mAudioSink->close();
-    }
-
-    // Try to avoid racing condition in case callback is still on.
-    Mutex::Autolock autoLock(mLock);
-    if (mUseAudioCallback) {
-        flushQueue(&mAudioQueue);
-        flushQueue(&mVideoQueue);
-    }
-    mWakeLock.clear();
-    mVideoScheduler.clear();
-    mNotify.clear();
-    mAudioSink.clear();
-}
-
-void NuPlayer2::Renderer::queueBuffer(
-        bool audio,
-        const sp<MediaCodecBuffer> &buffer,
-        const sp<AMessage> &notifyConsumed) {
-    sp<AMessage> msg = new AMessage(kWhatQueueBuffer, this);
-    msg->setInt32("queueGeneration", getQueueGeneration(audio));
-    msg->setInt32("audio", static_cast<int32_t>(audio));
-    msg->setObject("buffer", buffer);
-    msg->setMessage("notifyConsumed", notifyConsumed);
-    msg->post();
-}
-
-void NuPlayer2::Renderer::queueEOS(bool audio, status_t finalResult) {
-    CHECK_NE(finalResult, (status_t)OK);
-
-    sp<AMessage> msg = new AMessage(kWhatQueueEOS, this);
-    msg->setInt32("queueGeneration", getQueueGeneration(audio));
-    msg->setInt32("audio", static_cast<int32_t>(audio));
-    msg->setInt32("finalResult", finalResult);
-    msg->post();
-}
-
-status_t NuPlayer2::Renderer::setPlaybackSettings(const AudioPlaybackRate &rate) {
-    sp<AMessage> msg = new AMessage(kWhatConfigPlayback, this);
-    writeToAMessage(msg, rate);
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-    }
-    return err;
-}
-
-status_t NuPlayer2::Renderer::onConfigPlayback(const AudioPlaybackRate &rate /* sanitized */) {
-    if (rate.mSpeed <= 0.f) {
-        ALOGW("playback rate cannot be %f", rate.mSpeed);
-        return BAD_VALUE;
-    }
-
-    if (mAudioSink != NULL && mAudioSink->ready()) {
-        status_t err = mAudioSink->setPlaybackRate(rate);
-        if (err != OK) {
-            ALOGW("failed to get playback rate from audio sink, err(%d)", err);
-            return err;
-        }
-    }
-    mPlaybackSettings = rate;
-    mMediaClock->setPlaybackRate(mPlaybackSettings.mSpeed);
-    return OK;
-}
-
-status_t NuPlayer2::Renderer::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
-    sp<AMessage> msg = new AMessage(kWhatGetPlaybackSettings, this);
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-        if (err == OK) {
-            readFromAMessage(response, rate);
-        }
-    }
-    return err;
-}
-
-status_t NuPlayer2::Renderer::onGetPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
-    if (mAudioSink != NULL && mAudioSink->ready()) {
-        status_t err = mAudioSink->getPlaybackRate(rate);
-        if (err == OK) {
-            if (!isAudioPlaybackRateEqual(*rate, mPlaybackSettings)) {
-                ALOGW("correcting mismatch in internal/external playback rate, %f vs %f",
-                      rate->mSpeed, mPlaybackSettings.mSpeed);
-            }
-            // get playback settings used by audiosink, as it may be
-            // slightly off due to audiosink not taking small changes.
-            mPlaybackSettings = *rate;
-        }
-        return err;
-    }
-    *rate = mPlaybackSettings;
-    return OK;
-}
-
-status_t NuPlayer2::Renderer::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) {
-    sp<AMessage> msg = new AMessage(kWhatConfigSync, this);
-    writeToAMessage(msg, sync, videoFpsHint);
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-    }
-    return err;
-}
-
-status_t NuPlayer2::Renderer::onConfigSync(const AVSyncSettings &sync, float videoFpsHint __unused) {
-    if (sync.mSource != AVSYNC_SOURCE_DEFAULT) {
-        return BAD_VALUE;
-    }
-    // TODO: support sync sources
-    return INVALID_OPERATION;
-}
-
-status_t NuPlayer2::Renderer::getSyncSettings(AVSyncSettings *sync, float *videoFps) {
-    sp<AMessage> msg = new AMessage(kWhatGetSyncSettings, this);
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-        if (err == OK) {
-            readFromAMessage(response, sync, videoFps);
-        }
-    }
-    return err;
-}
-
-status_t NuPlayer2::Renderer::onGetSyncSettings(
-        AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */) {
-    *sync = mSyncSettings;
-    *videoFps = -1.f;
-    return OK;
-}
-
-void NuPlayer2::Renderer::flush(bool audio, bool notifyComplete) {
-    {
-        Mutex::Autolock autoLock(mLock);
-        if (audio) {
-            mNotifyCompleteAudio |= notifyComplete;
-            clearAudioFirstAnchorTime_l();
-            ++mAudioQueueGeneration;
-            ++mAudioDrainGeneration;
-        } else {
-            mNotifyCompleteVideo |= notifyComplete;
-            ++mVideoQueueGeneration;
-            ++mVideoDrainGeneration;
-            mNextVideoTimeMediaUs = -1;
-        }
-
-        mMediaClock->clearAnchor();
-        mVideoLateByUs = 0;
-        mSyncQueues = false;
-    }
-
-    sp<AMessage> msg = new AMessage(kWhatFlush, this);
-    msg->setInt32("audio", static_cast<int32_t>(audio));
-    msg->post();
-}
-
-void NuPlayer2::Renderer::signalTimeDiscontinuity() {
-}
-
-void NuPlayer2::Renderer::signalDisableOffloadAudio() {
-    (new AMessage(kWhatDisableOffloadAudio, this))->post();
-}
-
-void NuPlayer2::Renderer::signalEnableOffloadAudio() {
-    (new AMessage(kWhatEnableOffloadAudio, this))->post();
-}
-
-void NuPlayer2::Renderer::pause() {
-    (new AMessage(kWhatPause, this))->post();
-}
-
-void NuPlayer2::Renderer::resume() {
-    (new AMessage(kWhatResume, this))->post();
-}
-
-void NuPlayer2::Renderer::setVideoFrameRate(float fps) {
-    sp<AMessage> msg = new AMessage(kWhatSetVideoFrameRate, this);
-    msg->setFloat("frame-rate", fps);
-    msg->post();
-}
-
-// Called on any threads without mLock acquired.
-status_t NuPlayer2::Renderer::getCurrentPosition(int64_t *mediaUs) {
-    status_t result = mMediaClock->getMediaTime(ALooper::GetNowUs(), mediaUs);
-    if (result == OK) {
-        return result;
-    }
-
-    // MediaClock has not started yet. Try to start it if possible.
-    {
-        Mutex::Autolock autoLock(mLock);
-        if (mAudioFirstAnchorTimeMediaUs == -1) {
-            return result;
-        }
-
-        AudioTimestamp ts;
-        status_t res = mAudioSink->getTimestamp(ts);
-        if (res != OK) {
-            return result;
-        }
-
-        // AudioSink has rendered some frames.
-        int64_t nowUs = ALooper::GetNowUs();
-        int64_t nowMediaUs = mAudioSink->getPlayedOutDurationUs(nowUs)
-                + mAudioFirstAnchorTimeMediaUs;
-        mMediaClock->updateAnchor(nowMediaUs, nowUs, -1);
-    }
-
-    return mMediaClock->getMediaTime(ALooper::GetNowUs(), mediaUs);
-}
-
-void NuPlayer2::Renderer::clearAudioFirstAnchorTime_l() {
-    mAudioFirstAnchorTimeMediaUs = -1;
-    mMediaClock->setStartingTimeMedia(-1);
-}
-
-void NuPlayer2::Renderer::setAudioFirstAnchorTimeIfNeeded_l(int64_t mediaUs) {
-    if (mAudioFirstAnchorTimeMediaUs == -1) {
-        mAudioFirstAnchorTimeMediaUs = mediaUs;
-        mMediaClock->setStartingTimeMedia(mediaUs);
-    }
-}
-
-// Called on renderer looper.
-void NuPlayer2::Renderer::clearAnchorTime() {
-    mMediaClock->clearAnchor();
-    mAnchorTimeMediaUs = -1;
-    mAnchorNumFramesWritten = -1;
-}
-
-void NuPlayer2::Renderer::setVideoLateByUs(int64_t lateUs) {
-    Mutex::Autolock autoLock(mLock);
-    mVideoLateByUs = lateUs;
-}
-
-int64_t NuPlayer2::Renderer::getVideoLateByUs() {
-    Mutex::Autolock autoLock(mLock);
-    return mVideoLateByUs;
-}
-
-status_t NuPlayer2::Renderer::openAudioSink(
-        const sp<AMessage> &format,
-        bool offloadOnly,
-        bool hasVideo,
-        uint32_t flags,
-        bool *isOffloaded,
-        bool isStreaming) {
-    sp<AMessage> msg = new AMessage(kWhatOpenAudioSink, this);
-    msg->setMessage("format", format);
-    msg->setInt32("offload-only", offloadOnly);
-    msg->setInt32("has-video", hasVideo);
-    msg->setInt32("flags", flags);
-    msg->setInt32("isStreaming", isStreaming);
-
-    sp<AMessage> response;
-    status_t postStatus = msg->postAndAwaitResponse(&response);
-
-    int32_t err;
-    if (postStatus != OK || response.get() == nullptr || !response->findInt32("err", &err)) {
-        err = INVALID_OPERATION;
-    } else if (err == OK && isOffloaded != NULL) {
-        int32_t offload;
-        CHECK(response->findInt32("offload", &offload));
-        *isOffloaded = (offload != 0);
-    }
-    return err;
-}
-
-void NuPlayer2::Renderer::closeAudioSink() {
-    sp<AMessage> msg = new AMessage(kWhatCloseAudioSink, this);
-
-    sp<AMessage> response;
-    msg->postAndAwaitResponse(&response);
-}
-
-void NuPlayer2::Renderer::changeAudioFormat(
-        const sp<AMessage> &format,
-        bool offloadOnly,
-        bool hasVideo,
-        uint32_t flags,
-        bool isStreaming,
-        const sp<AMessage> &notify) {
-    sp<AMessage> meta = new AMessage;
-    meta->setMessage("format", format);
-    meta->setInt32("offload-only", offloadOnly);
-    meta->setInt32("has-video", hasVideo);
-    meta->setInt32("flags", flags);
-    meta->setInt32("isStreaming", isStreaming);
-
-    sp<AMessage> msg = new AMessage(kWhatChangeAudioFormat, this);
-    msg->setInt32("queueGeneration", getQueueGeneration(true /* audio */));
-    msg->setMessage("notify", notify);
-    msg->setMessage("meta", meta);
-    msg->post();
-}
-
-void NuPlayer2::Renderer::onMessageReceived(const sp<AMessage> &msg) {
-    switch (msg->what()) {
-        case kWhatOpenAudioSink:
-        {
-            sp<AMessage> format;
-            CHECK(msg->findMessage("format", &format));
-
-            int32_t offloadOnly;
-            CHECK(msg->findInt32("offload-only", &offloadOnly));
-
-            int32_t hasVideo;
-            CHECK(msg->findInt32("has-video", &hasVideo));
-
-            uint32_t flags;
-            CHECK(msg->findInt32("flags", (int32_t *)&flags));
-
-            uint32_t isStreaming;
-            CHECK(msg->findInt32("isStreaming", (int32_t *)&isStreaming));
-
-            status_t err = onOpenAudioSink(format, offloadOnly, hasVideo, flags, isStreaming);
-
-            sp<AMessage> response = new AMessage;
-            response->setInt32("err", err);
-            response->setInt32("offload", offloadingAudio());
-
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-            response->postReply(replyID);
-
-            break;
-        }
-
-        case kWhatCloseAudioSink:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-
-            onCloseAudioSink();
-
-            sp<AMessage> response = new AMessage;
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatStopAudioSink:
-        {
-            mAudioSink->stop();
-            break;
-        }
-
-        case kWhatChangeAudioFormat:
-        {
-            int32_t queueGeneration;
-            CHECK(msg->findInt32("queueGeneration", &queueGeneration));
-
-            sp<AMessage> notify;
-            CHECK(msg->findMessage("notify", &notify));
-
-            if (offloadingAudio()) {
-                ALOGW("changeAudioFormat should NOT be called in offload mode");
-                notify->setInt32("err", INVALID_OPERATION);
-                notify->post();
-                break;
-            }
-
-            sp<AMessage> meta;
-            CHECK(msg->findMessage("meta", &meta));
-
-            if (queueGeneration != getQueueGeneration(true /* audio */)
-                    || mAudioQueue.empty()) {
-                onChangeAudioFormat(meta, notify);
-                break;
-            }
-
-            QueueEntry entry;
-            entry.mNotifyConsumed = notify;
-            entry.mMeta = meta;
-
-            Mutex::Autolock autoLock(mLock);
-            mAudioQueue.push_back(entry);
-            postDrainAudioQueue_l();
-
-            break;
-        }
-
-        case kWhatDrainAudioQueue:
-        {
-            mDrainAudioQueuePending = false;
-
-            int32_t generation;
-            CHECK(msg->findInt32("drainGeneration", &generation));
-            if (generation != getDrainGeneration(true /* audio */)) {
-                break;
-            }
-
-            if (onDrainAudioQueue()) {
-                uint32_t numFramesPlayed;
-                CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed),
-                         (status_t)OK);
-
-                // Handle AudioTrack race when start is immediately called after flush.
-                uint32_t numFramesPendingPlayout =
-                    (mNumFramesWritten > numFramesPlayed ?
-                        mNumFramesWritten - numFramesPlayed : 0);
-
-                // This is how long the audio sink will have data to
-                // play back.
-                int64_t delayUs =
-                    mAudioSink->msecsPerFrame()
-                        * numFramesPendingPlayout * 1000ll;
-                if (mPlaybackSettings.mSpeed > 1.0f) {
-                    delayUs /= mPlaybackSettings.mSpeed;
-                }
-
-                // Let's give it more data after about half that time
-                // has elapsed.
-                delayUs /= 2;
-                // check the buffer size to estimate maximum delay permitted.
-                const int64_t maxDrainDelayUs = std::max(
-                        mAudioSink->getBufferDurationInUs(), (int64_t)500000 /* half second */);
-                ALOGD_IF(delayUs > maxDrainDelayUs, "postDrainAudioQueue long delay: %lld > %lld",
-                        (long long)delayUs, (long long)maxDrainDelayUs);
-                Mutex::Autolock autoLock(mLock);
-                postDrainAudioQueue_l(delayUs);
-            }
-            break;
-        }
-
-        case kWhatDrainVideoQueue:
-        {
-            int32_t generation;
-            CHECK(msg->findInt32("drainGeneration", &generation));
-            if (generation != getDrainGeneration(false /* audio */)) {
-                break;
-            }
-
-            mDrainVideoQueuePending = false;
-
-            onDrainVideoQueue();
-
-            postDrainVideoQueue();
-            break;
-        }
-
-        case kWhatPostDrainVideoQueue:
-        {
-            int32_t generation;
-            CHECK(msg->findInt32("drainGeneration", &generation));
-            if (generation != getDrainGeneration(false /* audio */)) {
-                break;
-            }
-
-            mDrainVideoQueuePending = false;
-            postDrainVideoQueue();
-            break;
-        }
-
-        case kWhatQueueBuffer:
-        {
-            onQueueBuffer(msg);
-            break;
-        }
-
-        case kWhatQueueEOS:
-        {
-            onQueueEOS(msg);
-            break;
-        }
-
-        case kWhatEOS:
-        {
-            int32_t generation;
-            CHECK(msg->findInt32("audioEOSGeneration", &generation));
-            if (generation != mAudioEOSGeneration) {
-                break;
-            }
-            status_t finalResult;
-            CHECK(msg->findInt32("finalResult", &finalResult));
-            notifyEOS(true /* audio */, finalResult);
-            break;
-        }
-
-        case kWhatConfigPlayback:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-            AudioPlaybackRate rate;
-            readFromAMessage(msg, &rate);
-            status_t err = onConfigPlayback(rate);
-            sp<AMessage> response = new AMessage;
-            response->setInt32("err", err);
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatGetPlaybackSettings:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-            AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT;
-            status_t err = onGetPlaybackSettings(&rate);
-            sp<AMessage> response = new AMessage;
-            if (err == OK) {
-                writeToAMessage(response, rate);
-            }
-            response->setInt32("err", err);
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatConfigSync:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-            AVSyncSettings sync;
-            float videoFpsHint;
-            readFromAMessage(msg, &sync, &videoFpsHint);
-            status_t err = onConfigSync(sync, videoFpsHint);
-            sp<AMessage> response = new AMessage;
-            response->setInt32("err", err);
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatGetSyncSettings:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-
-            ALOGV("kWhatGetSyncSettings");
-            AVSyncSettings sync;
-            float videoFps = -1.f;
-            status_t err = onGetSyncSettings(&sync, &videoFps);
-            sp<AMessage> response = new AMessage;
-            if (err == OK) {
-                writeToAMessage(response, sync, videoFps);
-            }
-            response->setInt32("err", err);
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatFlush:
-        {
-            onFlush(msg);
-            break;
-        }
-
-        case kWhatDisableOffloadAudio:
-        {
-            onDisableOffloadAudio();
-            break;
-        }
-
-        case kWhatEnableOffloadAudio:
-        {
-            onEnableOffloadAudio();
-            break;
-        }
-
-        case kWhatPause:
-        {
-            onPause();
-            break;
-        }
-
-        case kWhatResume:
-        {
-            onResume();
-            break;
-        }
-
-        case kWhatSetVideoFrameRate:
-        {
-            float fps;
-            CHECK(msg->findFloat("frame-rate", &fps));
-            onSetVideoFrameRate(fps);
-            break;
-        }
-
-        case kWhatAudioTearDown:
-        {
-            int32_t reason;
-            CHECK(msg->findInt32("reason", &reason));
-
-            onAudioTearDown((AudioTearDownReason)reason);
-            break;
-        }
-
-        case kWhatAudioOffloadPauseTimeout:
-        {
-            int32_t generation;
-            CHECK(msg->findInt32("drainGeneration", &generation));
-            if (generation != mAudioOffloadPauseTimeoutGeneration) {
-                break;
-            }
-            ALOGV("Audio Offload tear down due to pause timeout.");
-            onAudioTearDown(kDueToTimeout);
-            mWakeLock->release();
-            break;
-        }
-
-        default:
-            TRESPASS();
-            break;
-    }
-}
-
-void NuPlayer2::Renderer::postDrainAudioQueue_l(int64_t delayUs) {
-    if (mDrainAudioQueuePending || mSyncQueues || mUseAudioCallback) {
-        return;
-    }
-
-    if (mAudioQueue.empty()) {
-        return;
-    }
-
-    // FIXME: if paused, wait until AudioTrack stop() is complete before delivering data.
-    if (mPaused) {
-        const int64_t diffUs = mPauseDrainAudioAllowedUs - ALooper::GetNowUs();
-        if (diffUs > delayUs) {
-            delayUs = diffUs;
-        }
-    }
-
-    mDrainAudioQueuePending = true;
-    sp<AMessage> msg = new AMessage(kWhatDrainAudioQueue, this);
-    msg->setInt32("drainGeneration", mAudioDrainGeneration);
-    msg->post(delayUs);
-}
-
-void NuPlayer2::Renderer::prepareForMediaRenderingStart_l() {
-    mAudioRenderingStartGeneration = mAudioDrainGeneration;
-    mVideoRenderingStartGeneration = mVideoDrainGeneration;
-    mRenderingDataDelivered = false;
-}
-
-void NuPlayer2::Renderer::notifyIfMediaRenderingStarted_l() {
-    if (mVideoRenderingStartGeneration == mVideoDrainGeneration &&
-        mAudioRenderingStartGeneration == mAudioDrainGeneration) {
-        mRenderingDataDelivered = true;
-        if (mPaused) {
-            return;
-        }
-        mVideoRenderingStartGeneration = -1;
-        mAudioRenderingStartGeneration = -1;
-
-        sp<AMessage> notify = mNotify->dup();
-        notify->setInt32("what", kWhatMediaRenderingStart);
-        notify->post();
-    }
-}
-
-// static
-size_t NuPlayer2::Renderer::AudioSinkCallback(
-        MediaPlayer2Interface::AudioSink * /* audioSink */,
-        void *buffer,
-        size_t size,
-        void *cookie,
-        MediaPlayer2Interface::AudioSink::cb_event_t event) {
-    NuPlayer2::Renderer *me = (NuPlayer2::Renderer *)cookie;
-
-    switch (event) {
-        case MediaPlayer2Interface::AudioSink::CB_EVENT_FILL_BUFFER:
-        {
-            return me->fillAudioBuffer(buffer, size);
-            break;
-        }
-
-        case MediaPlayer2Interface::AudioSink::CB_EVENT_STREAM_END:
-        {
-            ALOGV("AudioSink::CB_EVENT_STREAM_END");
-            me->notifyEOSCallback();
-            break;
-        }
-
-        case MediaPlayer2Interface::AudioSink::CB_EVENT_TEAR_DOWN:
-        {
-            ALOGV("AudioSink::CB_EVENT_TEAR_DOWN");
-            me->notifyAudioTearDown(kDueToError);
-            break;
-        }
-    }
-
-    return 0;
-}
-
-void NuPlayer2::Renderer::notifyEOSCallback() {
-    Mutex::Autolock autoLock(mLock);
-
-    if (!mUseAudioCallback) {
-        return;
-    }
-
-    notifyEOS_l(true /* audio */, ERROR_END_OF_STREAM);
-}
-
-size_t NuPlayer2::Renderer::fillAudioBuffer(void *buffer, size_t size) {
-    Mutex::Autolock autoLock(mLock);
-
-    if (!mUseAudioCallback) {
-        return 0;
-    }
-
-    bool hasEOS = false;
-
-    size_t sizeCopied = 0;
-    bool firstEntry = true;
-    QueueEntry *entry;  // will be valid after while loop if hasEOS is set.
-    while (sizeCopied < size && !mAudioQueue.empty()) {
-        entry = &*mAudioQueue.begin();
-
-        if (entry->mBuffer == NULL) { // EOS
-            hasEOS = true;
-            mAudioQueue.erase(mAudioQueue.begin());
-            break;
-        }
-
-        if (firstEntry && entry->mOffset == 0) {
-            firstEntry = false;
-            int64_t mediaTimeUs;
-            CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
-            ALOGV("fillAudioBuffer: rendering audio at media time %.2f secs", mediaTimeUs / 1E6);
-            setAudioFirstAnchorTimeIfNeeded_l(mediaTimeUs);
-        }
-
-        size_t copy = entry->mBuffer->size() - entry->mOffset;
-        size_t sizeRemaining = size - sizeCopied;
-        if (copy > sizeRemaining) {
-            copy = sizeRemaining;
-        }
-
-        memcpy((char *)buffer + sizeCopied,
-               entry->mBuffer->data() + entry->mOffset,
-               copy);
-
-        entry->mOffset += copy;
-        if (entry->mOffset == entry->mBuffer->size()) {
-            entry->mNotifyConsumed->post();
-            mAudioQueue.erase(mAudioQueue.begin());
-            entry = NULL;
-        }
-        sizeCopied += copy;
-
-        notifyIfMediaRenderingStarted_l();
-    }
-
-    if (mAudioFirstAnchorTimeMediaUs >= 0) {
-        int64_t nowUs = ALooper::GetNowUs();
-        int64_t nowMediaUs =
-            mAudioFirstAnchorTimeMediaUs + mAudioSink->getPlayedOutDurationUs(nowUs);
-        // we don't know how much data we are queueing for offloaded tracks.
-        mMediaClock->updateAnchor(nowMediaUs, nowUs, INT64_MAX);
-    }
-
-    // for non-offloaded audio, we need to compute the frames written because
-    // there is no EVENT_STREAM_END notification. The frames written gives
-    // an estimate on the pending played out duration.
-    if (!offloadingAudio()) {
-        mNumFramesWritten += sizeCopied / mAudioSink->frameSize();
-    }
-
-    if (hasEOS) {
-        (new AMessage(kWhatStopAudioSink, this))->post();
-        // As there is currently no EVENT_STREAM_END callback notification for
-        // non-offloaded audio tracks, we need to post the EOS ourselves.
-        if (!offloadingAudio()) {
-            int64_t postEOSDelayUs = 0;
-            if (mAudioSink->needsTrailingPadding()) {
-                postEOSDelayUs = getPendingAudioPlayoutDurationUs(ALooper::GetNowUs());
-            }
-            ALOGV("fillAudioBuffer: notifyEOS_l "
-                    "mNumFramesWritten:%u  finalResult:%d  postEOSDelay:%lld",
-                    mNumFramesWritten, entry->mFinalResult, (long long)postEOSDelayUs);
-            notifyEOS_l(true /* audio */, entry->mFinalResult, postEOSDelayUs);
-        }
-    }
-    return sizeCopied;
-}
-
-void NuPlayer2::Renderer::drainAudioQueueUntilLastEOS() {
-    List<QueueEntry>::iterator it = mAudioQueue.begin(), itEOS = it;
-    bool foundEOS = false;
-    while (it != mAudioQueue.end()) {
-        int32_t eos;
-        QueueEntry *entry = &*it++;
-        if ((entry->mBuffer == nullptr && entry->mNotifyConsumed == nullptr)
-                || (entry->mNotifyConsumed->findInt32("eos", &eos) && eos != 0)) {
-            itEOS = it;
-            foundEOS = true;
-        }
-    }
-
-    if (foundEOS) {
-        // post all replies before EOS and drop the samples
-        for (it = mAudioQueue.begin(); it != itEOS; it++) {
-            if (it->mBuffer == nullptr) {
-                if (it->mNotifyConsumed == nullptr) {
-                    // delay doesn't matter as we don't even have an AudioTrack
-                    notifyEOS(true /* audio */, it->mFinalResult);
-                } else {
-                    // TAG for re-opening audio sink.
-                    onChangeAudioFormat(it->mMeta, it->mNotifyConsumed);
-                }
-            } else {
-                it->mNotifyConsumed->post();
-            }
-        }
-        mAudioQueue.erase(mAudioQueue.begin(), itEOS);
-    }
-}
-
-bool NuPlayer2::Renderer::onDrainAudioQueue() {
-    // do not drain audio during teardown as queued buffers may be invalid.
-    if (mAudioTornDown) {
-        return false;
-    }
-    // TODO: This call to getPosition checks if AudioTrack has been created
-    // in AudioSink before draining audio. If AudioTrack doesn't exist, then
-    // CHECKs on getPosition will fail.
-    // We still need to figure out why AudioTrack is not created when
-    // this function is called. One possible reason could be leftover
-    // audio. Another possible place is to check whether decoder
-    // has received INFO_FORMAT_CHANGED as the first buffer since
-    // AudioSink is opened there, and possible interactions with flush
-    // immediately after start. Investigate error message
-    // "vorbis_dsp_synthesis returned -135", along with RTSP.
-    uint32_t numFramesPlayed;
-    if (mAudioSink->getPosition(&numFramesPlayed) != OK) {
-        // When getPosition fails, renderer will not reschedule the draining
-        // unless new samples are queued.
-        // If we have pending EOS (or "eos" marker for discontinuities), we need
-        // to post these now as NuPlayer2Decoder might be waiting for it.
-        drainAudioQueueUntilLastEOS();
-
-        ALOGW("onDrainAudioQueue(): audio sink is not ready");
-        return false;
-    }
-
-#if 0
-    ssize_t numFramesAvailableToWrite =
-        mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed);
-
-    if (numFramesAvailableToWrite == mAudioSink->frameCount()) {
-        ALOGI("audio sink underrun");
-    } else {
-        ALOGV("audio queue has %d frames left to play",
-             mAudioSink->frameCount() - numFramesAvailableToWrite);
-    }
-#endif
-
-    uint32_t prevFramesWritten = mNumFramesWritten;
-    while (!mAudioQueue.empty()) {
-        QueueEntry *entry = &*mAudioQueue.begin();
-
-        if (entry->mBuffer == NULL) {
-            if (entry->mNotifyConsumed != nullptr) {
-                // TAG for re-open audio sink.
-                onChangeAudioFormat(entry->mMeta, entry->mNotifyConsumed);
-                mAudioQueue.erase(mAudioQueue.begin());
-                continue;
-            }
-
-            // EOS
-            if (mPaused) {
-                // Do not notify EOS when paused.
-                // This is needed to avoid switch to next clip while in pause.
-                ALOGV("onDrainAudioQueue(): Do not notify EOS when paused");
-                return false;
-            }
-
-            int64_t postEOSDelayUs = 0;
-            if (mAudioSink->needsTrailingPadding()) {
-                postEOSDelayUs = getPendingAudioPlayoutDurationUs(ALooper::GetNowUs());
-            }
-            notifyEOS(true /* audio */, entry->mFinalResult, postEOSDelayUs);
-            mLastAudioMediaTimeUs = getDurationUsIfPlayedAtSampleRate(mNumFramesWritten);
-
-            mAudioQueue.erase(mAudioQueue.begin());
-            entry = NULL;
-            if (mAudioSink->needsTrailingPadding()) {
-                // If we're not in gapless playback (i.e. through setNextPlayer), we
-                // need to stop the track here, because that will play out the last
-                // little bit at the end of the file. Otherwise short files won't play.
-                mAudioSink->stop();
-                mNumFramesWritten = 0;
-            }
-            return false;
-        }
-
-        mLastAudioBufferDrained = entry->mBufferOrdinal;
-
-        // ignore 0-sized buffer which could be EOS marker with no data
-        if (entry->mOffset == 0 && entry->mBuffer->size() > 0) {
-            int64_t mediaTimeUs;
-            CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
-            ALOGV("onDrainAudioQueue: rendering audio at media time %.2f secs",
-                    mediaTimeUs / 1E6);
-            onNewAudioMediaTime(mediaTimeUs);
-        }
-
-        size_t copy = entry->mBuffer->size() - entry->mOffset;
-
-        ssize_t written = mAudioSink->write(entry->mBuffer->data() + entry->mOffset,
-                                            copy, false /* blocking */);
-        if (written < 0) {
-            // An error in AudioSink write. Perhaps the AudioSink was not properly opened.
-            if (written == WOULD_BLOCK) {
-                ALOGV("AudioSink write would block when writing %zu bytes", copy);
-            } else {
-                ALOGE("AudioSink write error(%zd) when writing %zu bytes", written, copy);
-                // This can only happen when AudioSink was opened with doNotReconnect flag set to
-                // true, in which case the NuPlayer2 will handle the reconnect.
-                notifyAudioTearDown(kDueToError);
-            }
-            break;
-        }
-
-        entry->mOffset += written;
-        size_t remainder = entry->mBuffer->size() - entry->mOffset;
-        if ((ssize_t)remainder < mAudioSink->frameSize()) {
-            if (remainder > 0) {
-                ALOGW("Corrupted audio buffer has fractional frames, discarding %zu bytes.",
-                        remainder);
-                entry->mOffset += remainder;
-                copy -= remainder;
-            }
-
-            entry->mNotifyConsumed->post();
-            mAudioQueue.erase(mAudioQueue.begin());
-
-            entry = NULL;
-        }
-
-        size_t copiedFrames = written / mAudioSink->frameSize();
-        mNumFramesWritten += copiedFrames;
-
-        {
-            Mutex::Autolock autoLock(mLock);
-            int64_t maxTimeMedia;
-            maxTimeMedia =
-                mAnchorTimeMediaUs +
-                        (int64_t)(max((long long)mNumFramesWritten - mAnchorNumFramesWritten, 0LL)
-                                * 1000LL * mAudioSink->msecsPerFrame());
-            mMediaClock->updateMaxTimeMedia(maxTimeMedia);
-
-            notifyIfMediaRenderingStarted_l();
-        }
-
-        if (written != (ssize_t)copy) {
-            // A short count was received from AudioSink::write()
-            //
-            // AudioSink write is called in non-blocking mode.
-            // It may return with a short count when:
-            //
-            // 1) Size to be copied is not a multiple of the frame size. Fractional frames are
-            //    discarded.
-            // 2) The data to be copied exceeds the available buffer in AudioSink.
-            // 3) An error occurs and data has been partially copied to the buffer in AudioSink.
-            // 4) AudioSink is an AudioCache for data retrieval, and the AudioCache is exceeded.
-
-            // (Case 1)
-            // Must be a multiple of the frame size.  If it is not a multiple of a frame size, it
-            // needs to fail, as we should not carry over fractional frames between calls.
-            CHECK_EQ(copy % mAudioSink->frameSize(), 0u);
-
-            // (Case 2, 3, 4)
-            // Return early to the caller.
-            // Beware of calling immediately again as this may busy-loop if you are not careful.
-            ALOGV("AudioSink write short frame count %zd < %zu", written, copy);
-            break;
-        }
-    }
-
-    // calculate whether we need to reschedule another write.
-    bool reschedule = !mAudioQueue.empty()
-            && (!mPaused
-                || prevFramesWritten != mNumFramesWritten); // permit pause to fill buffers
-    //ALOGD("reschedule:%d  empty:%d  mPaused:%d  prevFramesWritten:%u  mNumFramesWritten:%u",
-    //        reschedule, mAudioQueue.empty(), mPaused, prevFramesWritten, mNumFramesWritten);
-    return reschedule;
-}
-
-int64_t NuPlayer2::Renderer::getDurationUsIfPlayedAtSampleRate(uint32_t numFrames) {
-    int32_t sampleRate = offloadingAudio() ?
-            mCurrentOffloadInfo.sample_rate : mCurrentPcmInfo.mSampleRate;
-    if (sampleRate == 0) {
-        ALOGE("sampleRate is 0 in %s mode", offloadingAudio() ? "offload" : "non-offload");
-        return 0;
-    }
-    return (int64_t)(numFrames * 1000000LL / sampleRate);
-}
-
-// Calculate duration of pending samples if played at normal rate (i.e., 1.0).
-int64_t NuPlayer2::Renderer::getPendingAudioPlayoutDurationUs(int64_t nowUs) {
-    int64_t writtenAudioDurationUs = getDurationUsIfPlayedAtSampleRate(mNumFramesWritten);
-    if (mUseVirtualAudioSink) {
-        int64_t nowUs = ALooper::GetNowUs();
-        int64_t mediaUs;
-        if (mMediaClock->getMediaTime(nowUs, &mediaUs) != OK) {
-            return 0LL;
-        } else {
-            return writtenAudioDurationUs - (mediaUs - mAudioFirstAnchorTimeMediaUs);
-        }
-    }
-
-    const int64_t audioSinkPlayedUs = mAudioSink->getPlayedOutDurationUs(nowUs);
-    int64_t pendingUs = writtenAudioDurationUs - audioSinkPlayedUs;
-    if (pendingUs < 0) {
-        // This shouldn't happen unless the timestamp is stale.
-        ALOGW("%s: pendingUs %lld < 0, clamping to zero, potential resume after pause "
-                "writtenAudioDurationUs: %lld, audioSinkPlayedUs: %lld",
-                __func__, (long long)pendingUs,
-                (long long)writtenAudioDurationUs, (long long)audioSinkPlayedUs);
-        pendingUs = 0;
-    }
-    return pendingUs;
-}
-
-int64_t NuPlayer2::Renderer::getRealTimeUs(int64_t mediaTimeUs, int64_t nowUs) {
-    int64_t realUs;
-    if (mMediaClock->getRealTimeFor(mediaTimeUs, &realUs) != OK) {
-        // If failed to get current position, e.g. due to audio clock is
-        // not ready, then just play out video immediately without delay.
-        return nowUs;
-    }
-    return realUs;
-}
-
-void NuPlayer2::Renderer::onNewAudioMediaTime(int64_t mediaTimeUs) {
-    Mutex::Autolock autoLock(mLock);
-    // TRICKY: vorbis decoder generates multiple frames with the same
-    // timestamp, so only update on the first frame with a given timestamp
-    if (mediaTimeUs == mAnchorTimeMediaUs) {
-        return;
-    }
-    setAudioFirstAnchorTimeIfNeeded_l(mediaTimeUs);
-
-    // mNextAudioClockUpdateTimeUs is -1 if we're waiting for audio sink to start
-    if (mNextAudioClockUpdateTimeUs == -1) {
-        AudioTimestamp ts;
-        if (mAudioSink->getTimestamp(ts) == OK && ts.mPosition > 0) {
-            mNextAudioClockUpdateTimeUs = 0; // start our clock updates
-        }
-    }
-    int64_t nowUs = ALooper::GetNowUs();
-    if (mNextAudioClockUpdateTimeUs >= 0) {
-        if (nowUs >= mNextAudioClockUpdateTimeUs) {
-            int64_t nowMediaUs = mediaTimeUs - getPendingAudioPlayoutDurationUs(nowUs);
-            mMediaClock->updateAnchor(nowMediaUs, nowUs, mediaTimeUs);
-            mUseVirtualAudioSink = false;
-            mNextAudioClockUpdateTimeUs = nowUs + kMinimumAudioClockUpdatePeriodUs;
-        }
-    } else {
-        int64_t unused;
-        if ((mMediaClock->getMediaTime(nowUs, &unused) != OK)
-                && (getDurationUsIfPlayedAtSampleRate(mNumFramesWritten)
-                        > kMaxAllowedAudioSinkDelayUs)) {
-            // Enough data has been sent to AudioSink, but AudioSink has not rendered
-            // any data yet. Something is wrong with AudioSink, e.g., the device is not
-            // connected to audio out.
-            // Switch to system clock. This essentially creates a virtual AudioSink with
-            // initial latenty of getDurationUsIfPlayedAtSampleRate(mNumFramesWritten).
-            // This virtual AudioSink renders audio data starting from the very first sample
-            // and it's paced by system clock.
-            ALOGW("AudioSink stuck. ARE YOU CONNECTED TO AUDIO OUT? Switching to system clock.");
-            mMediaClock->updateAnchor(mAudioFirstAnchorTimeMediaUs, nowUs, mediaTimeUs);
-            mUseVirtualAudioSink = true;
-        }
-    }
-    mAnchorNumFramesWritten = mNumFramesWritten;
-    mAnchorTimeMediaUs = mediaTimeUs;
-}
-
-// Called without mLock acquired.
-void NuPlayer2::Renderer::postDrainVideoQueue() {
-    if (mDrainVideoQueuePending
-            || getSyncQueues()
-            || (mPaused && mVideoSampleReceived)) {
-        return;
-    }
-
-    if (mVideoQueue.empty()) {
-        return;
-    }
-
-    QueueEntry &entry = *mVideoQueue.begin();
-
-    sp<AMessage> msg = new AMessage(kWhatDrainVideoQueue, this);
-    msg->setInt32("drainGeneration", getDrainGeneration(false /* audio */));
-
-    if (entry.mBuffer == NULL) {
-        // EOS doesn't carry a timestamp.
-        msg->post();
-        mDrainVideoQueuePending = true;
-        return;
-    }
-
-    int64_t nowUs = ALooper::GetNowUs();
-    if (mFlags & FLAG_REAL_TIME) {
-        int64_t realTimeUs;
-        CHECK(entry.mBuffer->meta()->findInt64("timeUs", &realTimeUs));
-
-        realTimeUs = mVideoScheduler->schedule(realTimeUs * 1000) / 1000;
-
-        int64_t twoVsyncsUs = 2 * (mVideoScheduler->getVsyncPeriod() / 1000);
-
-        int64_t delayUs = realTimeUs - nowUs;
-
-        ALOGW_IF(delayUs > 500000, "unusually high delayUs: %lld", (long long)delayUs);
-        // post 2 display refreshes before rendering is due
-        msg->post(delayUs > twoVsyncsUs ? delayUs - twoVsyncsUs : 0);
-
-        mDrainVideoQueuePending = true;
-        return;
-    }
-
-    int64_t mediaTimeUs;
-    CHECK(entry.mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
-
-    {
-        Mutex::Autolock autoLock(mLock);
-        if (mAnchorTimeMediaUs < 0) {
-            mMediaClock->updateAnchor(mediaTimeUs, nowUs, mediaTimeUs);
-            mAnchorTimeMediaUs = mediaTimeUs;
-        }
-    }
-    mNextVideoTimeMediaUs = mediaTimeUs;
-    if (!mHasAudio) {
-        // smooth out videos >= 10fps
-        mMediaClock->updateMaxTimeMedia(mediaTimeUs + kDefaultVideoFrameIntervalUs);
-    }
-
-    if (!mVideoSampleReceived || mediaTimeUs < mAudioFirstAnchorTimeMediaUs) {
-        msg->post();
-    } else {
-        int64_t twoVsyncsUs = 2 * (mVideoScheduler->getVsyncPeriod() / 1000);
-
-        // post 2 display refreshes before rendering is due
-        mMediaClock->addTimer(msg, mediaTimeUs, -twoVsyncsUs);
-    }
-
-    mDrainVideoQueuePending = true;
-}
-
-void NuPlayer2::Renderer::onDrainVideoQueue() {
-    if (mVideoQueue.empty()) {
-        return;
-    }
-
-    QueueEntry *entry = &*mVideoQueue.begin();
-
-    if (entry->mBuffer == NULL) {
-        // EOS
-
-        notifyEOS(false /* audio */, entry->mFinalResult);
-
-        mVideoQueue.erase(mVideoQueue.begin());
-        entry = NULL;
-
-        setVideoLateByUs(0);
-        return;
-    }
-
-    int64_t nowUs = ALooper::GetNowUs();
-    int64_t realTimeUs;
-    int64_t mediaTimeUs = -1;
-    if (mFlags & FLAG_REAL_TIME) {
-        CHECK(entry->mBuffer->meta()->findInt64("timeUs", &realTimeUs));
-    } else {
-        CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
-
-        realTimeUs = getRealTimeUs(mediaTimeUs, nowUs);
-    }
-    realTimeUs = mVideoScheduler->schedule(realTimeUs * 1000) / 1000;
-
-    bool tooLate = false;
-
-    if (!mPaused) {
-        setVideoLateByUs(nowUs - realTimeUs);
-        tooLate = (mVideoLateByUs > 40000);
-
-        if (tooLate) {
-            ALOGV("video late by %lld us (%.2f secs)",
-                 (long long)mVideoLateByUs, mVideoLateByUs / 1E6);
-        } else {
-            int64_t mediaUs = 0;
-            mMediaClock->getMediaTime(realTimeUs, &mediaUs);
-            ALOGV("rendering video at media time %.2f secs",
-                    (mFlags & FLAG_REAL_TIME ? realTimeUs :
-                    mediaUs) / 1E6);
-
-            if (!(mFlags & FLAG_REAL_TIME)
-                    && mLastAudioMediaTimeUs != -1
-                    && mediaTimeUs > mLastAudioMediaTimeUs) {
-                // If audio ends before video, video continues to drive media clock.
-                // Also smooth out videos >= 10fps.
-                mMediaClock->updateMaxTimeMedia(mediaTimeUs + kDefaultVideoFrameIntervalUs);
-            }
-        }
-    } else {
-        setVideoLateByUs(0);
-        if (!mVideoSampleReceived && !mHasAudio) {
-            // This will ensure that the first frame after a flush won't be used as anchor
-            // when renderer is in paused state, because resume can happen any time after seek.
-            clearAnchorTime();
-        }
-    }
-
-    // Always render the first video frame while keeping stats on A/V sync.
-    if (!mVideoSampleReceived) {
-        realTimeUs = nowUs;
-        tooLate = false;
-    }
-
-    entry->mNotifyConsumed->setInt64("timestampNs", realTimeUs * 1000LL);
-    entry->mNotifyConsumed->setInt32("render", !tooLate);
-    entry->mNotifyConsumed->post();
-    mVideoQueue.erase(mVideoQueue.begin());
-    entry = NULL;
-
-    mVideoSampleReceived = true;
-
-    if (!mPaused) {
-        if (!mVideoRenderingStarted) {
-            mVideoRenderingStarted = true;
-            notifyVideoRenderingStart();
-        }
-        Mutex::Autolock autoLock(mLock);
-        notifyIfMediaRenderingStarted_l();
-    }
-}
-
-void NuPlayer2::Renderer::notifyVideoRenderingStart() {
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatVideoRenderingStart);
-    notify->post();
-}
-
-void NuPlayer2::Renderer::notifyEOS(bool audio, status_t finalResult, int64_t delayUs) {
-    Mutex::Autolock autoLock(mLock);
-    notifyEOS_l(audio, finalResult, delayUs);
-}
-
-void NuPlayer2::Renderer::notifyEOS_l(bool audio, status_t finalResult, int64_t delayUs) {
-    if (audio && delayUs > 0) {
-        sp<AMessage> msg = new AMessage(kWhatEOS, this);
-        msg->setInt32("audioEOSGeneration", mAudioEOSGeneration);
-        msg->setInt32("finalResult", finalResult);
-        msg->post(delayUs);
-        return;
-    }
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatEOS);
-    notify->setInt32("audio", static_cast<int32_t>(audio));
-    notify->setInt32("finalResult", finalResult);
-    notify->post(delayUs);
-
-    if (audio) {
-        // Video might outlive audio. Clear anchor to enable video only case.
-        mAnchorTimeMediaUs = -1;
-        mHasAudio = false;
-        if (mNextVideoTimeMediaUs >= 0) {
-            int64_t mediaUs = 0;
-            int64_t nowUs = ALooper::GetNowUs();
-            status_t result = mMediaClock->getMediaTime(nowUs, &mediaUs);
-            if (result == OK) {
-                if (mNextVideoTimeMediaUs > mediaUs) {
-                    mMediaClock->updateMaxTimeMedia(mNextVideoTimeMediaUs);
-                }
-            } else {
-                mMediaClock->updateAnchor(
-                        mNextVideoTimeMediaUs, nowUs,
-                        mNextVideoTimeMediaUs + kDefaultVideoFrameIntervalUs);
-            }
-        }
-    }
-}
-
-void NuPlayer2::Renderer::notifyAudioTearDown(AudioTearDownReason reason) {
-    sp<AMessage> msg = new AMessage(kWhatAudioTearDown, this);
-    msg->setInt32("reason", reason);
-    msg->post();
-}
-
-void NuPlayer2::Renderer::onQueueBuffer(const sp<AMessage> &msg) {
-    int32_t audio;
-    CHECK(msg->findInt32("audio", &audio));
-
-    if (dropBufferIfStale(audio, msg)) {
-        return;
-    }
-
-    if (audio) {
-        mHasAudio = true;
-    } else {
-        mHasVideo = true;
-    }
-
-    if (mHasVideo) {
-        if (mVideoScheduler == NULL) {
-            mVideoScheduler = new VideoFrameScheduler2();
-            mVideoScheduler->init();
-        }
-    }
-
-    sp<RefBase> obj;
-    CHECK(msg->findObject("buffer", &obj));
-    sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get());
-
-    sp<AMessage> notifyConsumed;
-    CHECK(msg->findMessage("notifyConsumed", &notifyConsumed));
-
-    QueueEntry entry;
-    entry.mBuffer = buffer;
-    entry.mNotifyConsumed = notifyConsumed;
-    entry.mOffset = 0;
-    entry.mFinalResult = OK;
-    entry.mBufferOrdinal = ++mTotalBuffersQueued;
-
-    if (audio) {
-        Mutex::Autolock autoLock(mLock);
-        mAudioQueue.push_back(entry);
-        postDrainAudioQueue_l();
-    } else {
-        mVideoQueue.push_back(entry);
-        postDrainVideoQueue();
-    }
-
-    Mutex::Autolock autoLock(mLock);
-    if (!mSyncQueues || mAudioQueue.empty() || mVideoQueue.empty()) {
-        return;
-    }
-
-    sp<MediaCodecBuffer> firstAudioBuffer = (*mAudioQueue.begin()).mBuffer;
-    sp<MediaCodecBuffer> firstVideoBuffer = (*mVideoQueue.begin()).mBuffer;
-
-    if (firstAudioBuffer == NULL || firstVideoBuffer == NULL) {
-        // EOS signalled on either queue.
-        syncQueuesDone_l();
-        return;
-    }
-
-    int64_t firstAudioTimeUs;
-    int64_t firstVideoTimeUs;
-    CHECK(firstAudioBuffer->meta()
-            ->findInt64("timeUs", &firstAudioTimeUs));
-    CHECK(firstVideoBuffer->meta()
-            ->findInt64("timeUs", &firstVideoTimeUs));
-
-    int64_t diff = firstVideoTimeUs - firstAudioTimeUs;
-
-    ALOGV("queueDiff = %.2f secs", diff / 1E6);
-
-    if (diff > 100000LL) {
-        // Audio data starts More than 0.1 secs before video.
-        // Drop some audio.
-
-        (*mAudioQueue.begin()).mNotifyConsumed->post();
-        mAudioQueue.erase(mAudioQueue.begin());
-        return;
-    }
-
-    syncQueuesDone_l();
-}
-
-void NuPlayer2::Renderer::syncQueuesDone_l() {
-    if (!mSyncQueues) {
-        return;
-    }
-
-    mSyncQueues = false;
-
-    if (!mAudioQueue.empty()) {
-        postDrainAudioQueue_l();
-    }
-
-    if (!mVideoQueue.empty()) {
-        mLock.unlock();
-        postDrainVideoQueue();
-        mLock.lock();
-    }
-}
-
-void NuPlayer2::Renderer::onQueueEOS(const sp<AMessage> &msg) {
-    int32_t audio;
-    CHECK(msg->findInt32("audio", &audio));
-
-    if (dropBufferIfStale(audio, msg)) {
-        return;
-    }
-
-    int32_t finalResult;
-    CHECK(msg->findInt32("finalResult", &finalResult));
-
-    QueueEntry entry;
-    entry.mOffset = 0;
-    entry.mFinalResult = finalResult;
-
-    if (audio) {
-        Mutex::Autolock autoLock(mLock);
-        if (mAudioQueue.empty() && mSyncQueues) {
-            syncQueuesDone_l();
-        }
-        mAudioQueue.push_back(entry);
-        postDrainAudioQueue_l();
-    } else {
-        if (mVideoQueue.empty() && getSyncQueues()) {
-            Mutex::Autolock autoLock(mLock);
-            syncQueuesDone_l();
-        }
-        mVideoQueue.push_back(entry);
-        postDrainVideoQueue();
-    }
-}
-
-void NuPlayer2::Renderer::onFlush(const sp<AMessage> &msg) {
-    int32_t audio, notifyComplete;
-    CHECK(msg->findInt32("audio", &audio));
-
-    {
-        Mutex::Autolock autoLock(mLock);
-        if (audio) {
-            notifyComplete = mNotifyCompleteAudio;
-            mNotifyCompleteAudio = false;
-            mLastAudioMediaTimeUs = -1;
-
-            mHasAudio = false;
-            if (mNextVideoTimeMediaUs >= 0) {
-                int64_t nowUs = ALooper::GetNowUs();
-                mMediaClock->updateAnchor(
-                        mNextVideoTimeMediaUs, nowUs,
-                        mNextVideoTimeMediaUs + kDefaultVideoFrameIntervalUs);
-            }
-        } else {
-            notifyComplete = mNotifyCompleteVideo;
-            mNotifyCompleteVideo = false;
-            mVideoRenderingStarted = false;
-        }
-
-        // If we're currently syncing the queues, i.e. dropping audio while
-        // aligning the first audio/video buffer times and only one of the
-        // two queues has data, we may starve that queue by not requesting
-        // more buffers from the decoder. If the other source then encounters
-        // a discontinuity that leads to flushing, we'll never find the
-        // corresponding discontinuity on the other queue.
-        // Therefore we'll stop syncing the queues if at least one of them
-        // is flushed.
-        syncQueuesDone_l();
-    }
-    clearAnchorTime();
-
-    ALOGV("flushing %s", audio ? "audio" : "video");
-    if (audio) {
-        {
-            Mutex::Autolock autoLock(mLock);
-            flushQueue(&mAudioQueue);
-
-            ++mAudioDrainGeneration;
-            ++mAudioEOSGeneration;
-            prepareForMediaRenderingStart_l();
-
-            // the frame count will be reset after flush.
-            clearAudioFirstAnchorTime_l();
-        }
-
-        mDrainAudioQueuePending = false;
-
-        if (offloadingAudio()) {
-            mAudioSink->pause();
-            mAudioSink->flush();
-            if (!mPaused) {
-                mAudioSink->start();
-            }
-        } else {
-            mAudioSink->pause();
-            mAudioSink->flush();
-            // Call stop() to signal to the AudioSink to completely fill the
-            // internal buffer before resuming playback.
-            // FIXME: this is ignored after flush().
-            mAudioSink->stop();
-            if (mPaused) {
-                // Race condition: if renderer is paused and audio sink is stopped,
-                // we need to make sure that the audio track buffer fully drains
-                // before delivering data.
-                // FIXME: remove this if we can detect if stop() is complete.
-                const int delayUs = 2 * 50 * 1000; // (2 full mixer thread cycles at 50ms)
-                mPauseDrainAudioAllowedUs = ALooper::GetNowUs() + delayUs;
-            } else {
-                mAudioSink->start();
-            }
-            mNumFramesWritten = 0;
-        }
-        mNextAudioClockUpdateTimeUs = -1;
-    } else {
-        flushQueue(&mVideoQueue);
-
-        mDrainVideoQueuePending = false;
-
-        if (mVideoScheduler != NULL) {
-            mVideoScheduler->restart();
-        }
-
-        Mutex::Autolock autoLock(mLock);
-        ++mVideoDrainGeneration;
-        prepareForMediaRenderingStart_l();
-    }
-
-    mVideoSampleReceived = false;
-
-    if (notifyComplete) {
-        notifyFlushComplete(audio);
-    }
-}
-
-void NuPlayer2::Renderer::flushQueue(List<QueueEntry> *queue) {
-    while (!queue->empty()) {
-        QueueEntry *entry = &*queue->begin();
-
-        if (entry->mBuffer != NULL) {
-            entry->mNotifyConsumed->post();
-        } else if (entry->mNotifyConsumed != nullptr) {
-            // Is it needed to open audio sink now?
-            onChangeAudioFormat(entry->mMeta, entry->mNotifyConsumed);
-        }
-
-        queue->erase(queue->begin());
-        entry = NULL;
-    }
-}
-
-void NuPlayer2::Renderer::notifyFlushComplete(bool audio) {
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatFlushComplete);
-    notify->setInt32("audio", static_cast<int32_t>(audio));
-    notify->post();
-}
-
-bool NuPlayer2::Renderer::dropBufferIfStale(
-        bool audio, const sp<AMessage> &msg) {
-    int32_t queueGeneration;
-    CHECK(msg->findInt32("queueGeneration", &queueGeneration));
-
-    if (queueGeneration == getQueueGeneration(audio)) {
-        return false;
-    }
-
-    sp<AMessage> notifyConsumed;
-    if (msg->findMessage("notifyConsumed", &notifyConsumed)) {
-        notifyConsumed->post();
-    }
-
-    return true;
-}
-
-void NuPlayer2::Renderer::onAudioSinkChanged() {
-    if (offloadingAudio()) {
-        return;
-    }
-    CHECK(!mDrainAudioQueuePending);
-    mNumFramesWritten = 0;
-    mAnchorNumFramesWritten = -1;
-    uint32_t written;
-    if (mAudioSink->getFramesWritten(&written) == OK) {
-        mNumFramesWritten = written;
-    }
-}
-
-void NuPlayer2::Renderer::onDisableOffloadAudio() {
-    Mutex::Autolock autoLock(mLock);
-    mFlags &= ~FLAG_OFFLOAD_AUDIO;
-    ++mAudioDrainGeneration;
-    if (mAudioRenderingStartGeneration != -1) {
-        prepareForMediaRenderingStart_l();
-    }
-}
-
-void NuPlayer2::Renderer::onEnableOffloadAudio() {
-    Mutex::Autolock autoLock(mLock);
-    mFlags |= FLAG_OFFLOAD_AUDIO;
-    ++mAudioDrainGeneration;
-    if (mAudioRenderingStartGeneration != -1) {
-        prepareForMediaRenderingStart_l();
-    }
-}
-
-void NuPlayer2::Renderer::onPause() {
-    if (mPaused) {
-        return;
-    }
-
-    {
-        Mutex::Autolock autoLock(mLock);
-        // we do not increment audio drain generation so that we fill audio buffer during pause.
-        ++mVideoDrainGeneration;
-        prepareForMediaRenderingStart_l();
-        mPaused = true;
-        mMediaClock->setPlaybackRate(0.0);
-    }
-
-    mDrainAudioQueuePending = false;
-    mDrainVideoQueuePending = false;
-
-    // Note: audio data may not have been decoded, and the AudioSink may not be opened.
-    mAudioSink->pause();
-    startAudioOffloadPauseTimeout();
-
-    ALOGV("now paused audio queue has %zu entries, video has %zu entries",
-          mAudioQueue.size(), mVideoQueue.size());
-}
-
-void NuPlayer2::Renderer::onResume() {
-    if (!mPaused) {
-        return;
-    }
-
-    // Note: audio data may not have been decoded, and the AudioSink may not be opened.
-    cancelAudioOffloadPauseTimeout();
-    if (mAudioSink->ready()) {
-        status_t err = mAudioSink->start();
-        if (err != OK) {
-            ALOGE("cannot start AudioSink err %d", err);
-            notifyAudioTearDown(kDueToError);
-        }
-    }
-
-    {
-        Mutex::Autolock autoLock(mLock);
-        mPaused = false;
-        // rendering started message may have been delayed if we were paused.
-        if (mRenderingDataDelivered) {
-            notifyIfMediaRenderingStarted_l();
-        }
-        // configure audiosink as we did not do it when pausing
-        if (mAudioSink != NULL && mAudioSink->ready()) {
-            mAudioSink->setPlaybackRate(mPlaybackSettings);
-        }
-
-        mMediaClock->setPlaybackRate(mPlaybackSettings.mSpeed);
-
-        if (!mAudioQueue.empty()) {
-            postDrainAudioQueue_l();
-        }
-    }
-
-    if (!mVideoQueue.empty()) {
-        postDrainVideoQueue();
-    }
-}
-
-void NuPlayer2::Renderer::onSetVideoFrameRate(float fps) {
-    if (mVideoScheduler == NULL) {
-        mVideoScheduler = new VideoFrameScheduler2();
-    }
-    mVideoScheduler->init(fps);
-}
-
-int32_t NuPlayer2::Renderer::getQueueGeneration(bool audio) {
-    Mutex::Autolock autoLock(mLock);
-    return (audio ? mAudioQueueGeneration : mVideoQueueGeneration);
-}
-
-int32_t NuPlayer2::Renderer::getDrainGeneration(bool audio) {
-    Mutex::Autolock autoLock(mLock);
-    return (audio ? mAudioDrainGeneration : mVideoDrainGeneration);
-}
-
-bool NuPlayer2::Renderer::getSyncQueues() {
-    Mutex::Autolock autoLock(mLock);
-    return mSyncQueues;
-}
-
-void NuPlayer2::Renderer::onAudioTearDown(AudioTearDownReason reason) {
-    if (mAudioTornDown) {
-        return;
-    }
-    mAudioTornDown = true;
-
-    int64_t currentPositionUs;
-    sp<AMessage> notify = mNotify->dup();
-    if (getCurrentPosition(&currentPositionUs) == OK) {
-        notify->setInt64("positionUs", currentPositionUs);
-    }
-
-    mAudioSink->stop();
-    mAudioSink->flush();
-
-    notify->setInt32("what", kWhatAudioTearDown);
-    notify->setInt32("reason", reason);
-    notify->post();
-}
-
-void NuPlayer2::Renderer::startAudioOffloadPauseTimeout() {
-    if (offloadingAudio()) {
-        mWakeLock->acquire();
-        sp<AMessage> msg = new AMessage(kWhatAudioOffloadPauseTimeout, this);
-        msg->setInt32("drainGeneration", mAudioOffloadPauseTimeoutGeneration);
-        msg->post(kOffloadPauseMaxUs);
-    }
-}
-
-void NuPlayer2::Renderer::cancelAudioOffloadPauseTimeout() {
-    // We may have called startAudioOffloadPauseTimeout() without
-    // the AudioSink open and with offloadingAudio enabled.
-    //
-    // When we cancel, it may be that offloadingAudio is subsequently disabled, so regardless
-    // we always release the wakelock and increment the pause timeout generation.
-    //
-    // Note: The acquired wakelock prevents the device from suspending
-    // immediately after offload pause (in case a resume happens shortly thereafter).
-    mWakeLock->release(true);
-    ++mAudioOffloadPauseTimeoutGeneration;
-}
-
-status_t NuPlayer2::Renderer::onOpenAudioSink(
-        const sp<AMessage> &format,
-        bool offloadOnly,
-        bool hasVideo,
-        uint32_t flags,
-        bool isStreaming) {
-    ALOGV("openAudioSink: offloadOnly(%d) offloadingAudio(%d)",
-            offloadOnly, offloadingAudio());
-
-    bool audioSinkChanged = false;
-
-    int32_t numChannels;
-    CHECK(format->findInt32("channel-count", &numChannels));
-
-    int32_t channelMask;
-    if (!format->findInt32("channel-mask", &channelMask)) {
-        // signal to the AudioSink to derive the mask from count.
-        channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
-    }
-
-    int32_t sampleRate;
-    CHECK(format->findInt32("sample-rate", &sampleRate));
-
-    // read pcm encoding from MediaCodec output format, if available
-    int32_t pcmEncoding;
-    audio_format_t audioFormat =
-            format->findInt32(KEY_PCM_ENCODING, &pcmEncoding) ?
-                    audioFormatFromEncoding(pcmEncoding) : AUDIO_FORMAT_PCM_16_BIT;
-
-    if (offloadingAudio()) {
-        AString mime;
-        CHECK(format->findString("mime", &mime));
-        status_t err = mapMimeToAudioFormat(audioFormat, mime.c_str());
-
-        if (err != OK) {
-            ALOGE("Couldn't map mime \"%s\" to a valid "
-                    "audio_format", mime.c_str());
-            onDisableOffloadAudio();
-        } else {
-            ALOGV("Mime \"%s\" mapped to audio_format 0x%x",
-                    mime.c_str(), audioFormat);
-
-            int avgBitRate = -1;
-            format->findInt32("bitrate", &avgBitRate);
-
-            int32_t aacProfile = -1;
-            if (audioFormat == AUDIO_FORMAT_AAC
-                    && format->findInt32("aac-profile", &aacProfile)) {
-                // Redefine AAC format as per aac profile
-                mapAACProfileToAudioFormat(
-                        audioFormat,
-                        aacProfile);
-            }
-
-            audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
-            offloadInfo.duration_us = -1;
-            format->findInt64(
-                    "durationUs", &offloadInfo.duration_us);
-            offloadInfo.sample_rate = sampleRate;
-            offloadInfo.channel_mask = channelMask;
-            offloadInfo.format = audioFormat;
-            offloadInfo.stream_type = AUDIO_STREAM_MUSIC;
-            offloadInfo.bit_rate = avgBitRate;
-            offloadInfo.has_video = hasVideo;
-            offloadInfo.is_streaming = isStreaming;
-
-            if (memcmp(&mCurrentOffloadInfo, &offloadInfo, sizeof(offloadInfo)) == 0) {
-                ALOGV("openAudioSink: no change in offload mode");
-                // no change from previous configuration, everything ok.
-                return OK;
-            }
-            mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER;
-
-            ALOGV("openAudioSink: try to open AudioSink in offload mode");
-            uint32_t offloadFlags = flags;
-            offloadFlags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
-            offloadFlags &= ~AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
-            audioSinkChanged = true;
-            mAudioSink->close();
-
-            err = mAudioSink->open(
-                    sampleRate,
-                    numChannels,
-                    (audio_channel_mask_t)channelMask,
-                    audioFormat,
-                    &NuPlayer2::Renderer::AudioSinkCallback,
-                    this,
-                    (audio_output_flags_t)offloadFlags,
-                    &offloadInfo);
-
-            if (err == OK) {
-                err = mAudioSink->setPlaybackRate(mPlaybackSettings);
-            }
-
-            if (err == OK) {
-                // If the playback is offloaded to h/w, we pass
-                // the HAL some metadata information.
-                // We don't want to do this for PCM because it
-                // will be going through the AudioFlinger mixer
-                // before reaching the hardware.
-                // TODO
-                mCurrentOffloadInfo = offloadInfo;
-                if (!mPaused) { // for preview mode, don't start if paused
-                    err = mAudioSink->start();
-                }
-                ALOGV_IF(err == OK, "openAudioSink: offload succeeded");
-            }
-            if (err != OK) {
-                // Clean up, fall back to non offload mode.
-                mAudioSink->close();
-                onDisableOffloadAudio();
-                mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
-                ALOGV("openAudioSink: offload failed");
-                if (offloadOnly) {
-                    notifyAudioTearDown(kForceNonOffload);
-                }
-            } else {
-                mUseAudioCallback = true;  // offload mode transfers data through callback
-                ++mAudioDrainGeneration;  // discard pending kWhatDrainAudioQueue message.
-            }
-        }
-    }
-    if (!offloadOnly && !offloadingAudio()) {
-        ALOGV("openAudioSink: open AudioSink in NON-offload mode");
-        uint32_t pcmFlags = flags;
-        pcmFlags &= ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
-
-        const PcmInfo info = {
-                (audio_channel_mask_t)channelMask,
-                (audio_output_flags_t)pcmFlags,
-                audioFormat,
-                numChannels,
-                sampleRate
-        };
-        if (memcmp(&mCurrentPcmInfo, &info, sizeof(info)) == 0) {
-            ALOGV("openAudioSink: no change in pcm mode");
-            // no change from previous configuration, everything ok.
-            return OK;
-        }
-
-        audioSinkChanged = true;
-        mAudioSink->close();
-        mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
-        // Note: It is possible to set up the callback, but not use it to send audio data.
-        // This requires a fix in AudioSink to explicitly specify the transfer mode.
-        mUseAudioCallback = getUseAudioCallbackSetting();
-        if (mUseAudioCallback) {
-            ++mAudioDrainGeneration;  // discard pending kWhatDrainAudioQueue message.
-        }
-
-        // Compute the desired buffer size.
-        // For callback mode, the amount of time before wakeup is about half the buffer size.
-        const uint32_t frameCount =
-                (unsigned long long)sampleRate * getAudioSinkPcmMsSetting() / 1000;
-
-        // We should always be able to set our playback settings if the sink is closed.
-        LOG_ALWAYS_FATAL_IF(mAudioSink->setPlaybackRate(mPlaybackSettings) != OK,
-                "onOpenAudioSink: can't set playback rate on closed sink");
-        status_t err = mAudioSink->open(
-                    sampleRate,
-                    numChannels,
-                    (audio_channel_mask_t)channelMask,
-                    audioFormat,
-                    mUseAudioCallback ? &NuPlayer2::Renderer::AudioSinkCallback : NULL,
-                    mUseAudioCallback ? this : NULL,
-                    (audio_output_flags_t)pcmFlags,
-                    NULL,
-                    frameCount);
-        if (err != OK) {
-            ALOGW("openAudioSink: non offloaded open failed status: %d", err);
-            mAudioSink->close();
-            mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER;
-            return err;
-        }
-        mCurrentPcmInfo = info;
-        if (!mPaused) { // for preview mode, don't start if paused
-            mAudioSink->start();
-        }
-    }
-    if (audioSinkChanged) {
-        onAudioSinkChanged();
-    }
-    mAudioTornDown = false;
-    return OK;
-}
-
-void NuPlayer2::Renderer::onCloseAudioSink() {
-    mAudioSink->close();
-    mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
-    mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER;
-}
-
-void NuPlayer2::Renderer::onChangeAudioFormat(
-        const sp<AMessage> &meta, const sp<AMessage> &notify) {
-    sp<AMessage> format;
-    CHECK(meta->findMessage("format", &format));
-
-    int32_t offloadOnly;
-    CHECK(meta->findInt32("offload-only", &offloadOnly));
-
-    int32_t hasVideo;
-    CHECK(meta->findInt32("has-video", &hasVideo));
-
-    uint32_t flags;
-    CHECK(meta->findInt32("flags", (int32_t *)&flags));
-
-    uint32_t isStreaming;
-    CHECK(meta->findInt32("isStreaming", (int32_t *)&isStreaming));
-
-    status_t err = onOpenAudioSink(format, offloadOnly, hasVideo, flags, isStreaming);
-
-    if (err != OK) {
-        notify->setInt32("err", err);
-    }
-    notify->post();
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.h b/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.h
deleted file mode 100644
index d065dee..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.h
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-#ifndef NUPLAYER2_RENDERER_H_
-
-#define NUPLAYER2_RENDERER_H_
-
-#include <media/AudioResamplerPublic.h>
-#include <media/AVSyncSettings.h>
-#include <mediaplayer2/JObjectHolder.h>
-
-#include "NuPlayer2.h"
-
-namespace android {
-
-class  JWakeLock;
-struct MediaClock;
-class MediaCodecBuffer;
-struct VideoFrameSchedulerBase;
-
-struct NuPlayer2::Renderer : public AHandler {
-    enum Flags {
-        FLAG_REAL_TIME = 1,
-        FLAG_OFFLOAD_AUDIO = 2,
-    };
-    Renderer(const sp<MediaPlayer2Interface::AudioSink> &sink,
-             const sp<MediaClock> &mediaClock,
-             const sp<AMessage> &notify,
-             const sp<JObjectHolder> &context,
-             uint32_t flags = 0);
-
-    static size_t AudioSinkCallback(
-            MediaPlayer2Interface::AudioSink *audioSink,
-            void *data, size_t size, void *me,
-            MediaPlayer2Interface::AudioSink::cb_event_t event);
-
-    void queueBuffer(
-            bool audio,
-            const sp<MediaCodecBuffer> &buffer,
-            const sp<AMessage> &notifyConsumed);
-
-    void queueEOS(bool audio, status_t finalResult);
-
-    status_t setPlaybackSettings(const AudioPlaybackRate &rate /* sanitized */);
-    status_t getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */);
-    status_t setSyncSettings(const AVSyncSettings &sync, float videoFpsHint);
-    status_t getSyncSettings(AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */);
-
-    void flush(bool audio, bool notifyComplete);
-
-    void signalTimeDiscontinuity();
-
-    void signalDisableOffloadAudio();
-    void signalEnableOffloadAudio();
-
-    void pause();
-    void resume();
-
-    void setVideoFrameRate(float fps);
-
-    status_t getCurrentPosition(int64_t *mediaUs);
-    int64_t getVideoLateByUs();
-
-    status_t openAudioSink(
-            const sp<AMessage> &format,
-            bool offloadOnly,
-            bool hasVideo,
-            uint32_t flags,
-            bool *isOffloaded,
-            bool isStreaming);
-    void closeAudioSink();
-
-    // re-open audio sink after all pending audio buffers played.
-    void changeAudioFormat(
-            const sp<AMessage> &format,
-            bool offloadOnly,
-            bool hasVideo,
-            uint32_t flags,
-            bool isStreaming,
-            const sp<AMessage> &notify);
-
-    enum {
-        kWhatEOS                      = 'eos ',
-        kWhatFlushComplete            = 'fluC',
-        kWhatPosition                 = 'posi',
-        kWhatVideoRenderingStart      = 'vdrd',
-        kWhatMediaRenderingStart      = 'mdrd',
-        kWhatAudioTearDown            = 'adTD',
-        kWhatAudioOffloadPauseTimeout = 'aOPT',
-    };
-
-    enum AudioTearDownReason {
-        kDueToError = 0,   // Could restart with either offload or non-offload.
-        kDueToTimeout,
-        kForceNonOffload,  // Restart only with non-offload.
-    };
-
-protected:
-    virtual ~Renderer();
-
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
-    enum {
-        kWhatDrainAudioQueue     = 'draA',
-        kWhatDrainVideoQueue     = 'draV',
-        kWhatPostDrainVideoQueue = 'pDVQ',
-        kWhatQueueBuffer         = 'queB',
-        kWhatQueueEOS            = 'qEOS',
-        kWhatConfigPlayback      = 'cfPB',
-        kWhatConfigSync          = 'cfSy',
-        kWhatGetPlaybackSettings = 'gPbS',
-        kWhatGetSyncSettings     = 'gSyS',
-        kWhatFlush               = 'flus',
-        kWhatPause               = 'paus',
-        kWhatResume              = 'resm',
-        kWhatOpenAudioSink       = 'opnA',
-        kWhatCloseAudioSink      = 'clsA',
-        kWhatChangeAudioFormat   = 'chgA',
-        kWhatStopAudioSink       = 'stpA',
-        kWhatDisableOffloadAudio = 'noOA',
-        kWhatEnableOffloadAudio  = 'enOA',
-        kWhatSetVideoFrameRate   = 'sVFR',
-    };
-
-    // if mBuffer != nullptr, it's a buffer containing real data.
-    // else if mNotifyConsumed == nullptr, it's EOS.
-    // else it's a tag for re-opening audio sink in different format.
-    struct QueueEntry {
-        sp<MediaCodecBuffer> mBuffer;
-        sp<AMessage> mMeta;
-        sp<AMessage> mNotifyConsumed;
-        size_t mOffset;
-        status_t mFinalResult;
-        int32_t mBufferOrdinal;
-    };
-
-    static const int64_t kMinPositionUpdateDelayUs;
-
-    sp<MediaPlayer2Interface::AudioSink> mAudioSink;
-    bool mUseVirtualAudioSink;
-    sp<AMessage> mNotify;
-    Mutex mLock;
-    uint32_t mFlags;
-    List<QueueEntry> mAudioQueue;
-    List<QueueEntry> mVideoQueue;
-    uint32_t mNumFramesWritten;
-    sp<VideoFrameSchedulerBase> mVideoScheduler;
-
-    bool mDrainAudioQueuePending;
-    bool mDrainVideoQueuePending;
-    int32_t mAudioQueueGeneration;
-    int32_t mVideoQueueGeneration;
-    int32_t mAudioDrainGeneration;
-    int32_t mVideoDrainGeneration;
-    int32_t mAudioEOSGeneration;
-
-    const sp<MediaClock> mMediaClock;
-
-    AudioPlaybackRate mPlaybackSettings;
-    AVSyncSettings mSyncSettings;
-    float mVideoFpsHint;
-
-    int64_t mAudioFirstAnchorTimeMediaUs;
-    int64_t mAnchorTimeMediaUs;
-    int64_t mAnchorNumFramesWritten;
-    int64_t mVideoLateByUs;
-    int64_t mNextVideoTimeMediaUs;
-    bool mHasAudio;
-    bool mHasVideo;
-
-    bool mNotifyCompleteAudio;
-    bool mNotifyCompleteVideo;
-
-    bool mSyncQueues;
-
-    // modified on only renderer's thread.
-    bool mPaused;
-    int64_t mPauseDrainAudioAllowedUs; // time when we can drain/deliver audio in pause mode.
-
-    bool mVideoSampleReceived;
-    bool mVideoRenderingStarted;
-    int32_t mVideoRenderingStartGeneration;
-    int32_t mAudioRenderingStartGeneration;
-    bool mRenderingDataDelivered;
-
-    int64_t mNextAudioClockUpdateTimeUs;
-    // the media timestamp of last audio sample right before EOS.
-    int64_t mLastAudioMediaTimeUs;
-
-    int32_t mAudioOffloadPauseTimeoutGeneration;
-    bool mAudioTornDown;
-    audio_offload_info_t mCurrentOffloadInfo;
-
-    struct PcmInfo {
-        audio_channel_mask_t mChannelMask;
-        audio_output_flags_t mFlags;
-        audio_format_t mFormat;
-        int32_t mNumChannels;
-        int32_t mSampleRate;
-    };
-    PcmInfo mCurrentPcmInfo;
-    static const PcmInfo AUDIO_PCMINFO_INITIALIZER;
-
-    int32_t mTotalBuffersQueued;
-    int32_t mLastAudioBufferDrained;
-    bool mUseAudioCallback;
-
-    sp<JWakeLock> mWakeLock;
-
-    status_t getCurrentPositionOnLooper(int64_t *mediaUs);
-    status_t getCurrentPositionOnLooper(
-            int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo = false);
-    bool getCurrentPositionIfPaused_l(int64_t *mediaUs);
-    status_t getCurrentPositionFromAnchor(
-            int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo = false);
-
-    void notifyEOSCallback();
-    size_t fillAudioBuffer(void *buffer, size_t size);
-
-    bool onDrainAudioQueue();
-    void drainAudioQueueUntilLastEOS();
-    int64_t getPendingAudioPlayoutDurationUs(int64_t nowUs);
-    void postDrainAudioQueue_l(int64_t delayUs = 0);
-
-    void clearAnchorTime();
-    void clearAudioFirstAnchorTime_l();
-    void setAudioFirstAnchorTimeIfNeeded_l(int64_t mediaUs);
-    void setVideoLateByUs(int64_t lateUs);
-
-    void onNewAudioMediaTime(int64_t mediaTimeUs);
-    int64_t getRealTimeUs(int64_t mediaTimeUs, int64_t nowUs);
-
-    void onDrainVideoQueue();
-    void postDrainVideoQueue();
-
-    void prepareForMediaRenderingStart_l();
-    void notifyIfMediaRenderingStarted_l();
-
-    void onQueueBuffer(const sp<AMessage> &msg);
-    void onQueueEOS(const sp<AMessage> &msg);
-    void onFlush(const sp<AMessage> &msg);
-    void onAudioSinkChanged();
-    void onDisableOffloadAudio();
-    void onEnableOffloadAudio();
-    status_t onConfigPlayback(const AudioPlaybackRate &rate /* sanitized */);
-    status_t onGetPlaybackSettings(AudioPlaybackRate *rate /* nonnull */);
-    status_t onConfigSync(const AVSyncSettings &sync, float videoFpsHint);
-    status_t onGetSyncSettings(AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */);
-
-    void onPause();
-    void onResume();
-    void onSetVideoFrameRate(float fps);
-    int32_t getQueueGeneration(bool audio);
-    int32_t getDrainGeneration(bool audio);
-    bool getSyncQueues();
-    void onAudioTearDown(AudioTearDownReason reason);
-    status_t onOpenAudioSink(
-            const sp<AMessage> &format,
-            bool offloadOnly,
-            bool hasVideo,
-            uint32_t flags,
-            bool isStreaming);
-    void onCloseAudioSink();
-    void onChangeAudioFormat(const sp<AMessage> &meta, const sp<AMessage> &notify);
-
-    void notifyEOS(bool audio, status_t finalResult, int64_t delayUs = 0);
-    void notifyEOS_l(bool audio, status_t finalResult, int64_t delayUs = 0);
-    void notifyFlushComplete(bool audio);
-    void notifyPosition();
-    void notifyVideoLateBy(int64_t lateByUs);
-    void notifyVideoRenderingStart();
-    void notifyAudioTearDown(AudioTearDownReason reason);
-
-    void flushQueue(List<QueueEntry> *queue);
-    bool dropBufferIfStale(bool audio, const sp<AMessage> &msg);
-    void syncQueuesDone_l();
-
-    bool offloadingAudio() const { return (mFlags & FLAG_OFFLOAD_AUDIO) != 0; }
-
-    void startAudioOffloadPauseTimeout();
-    void cancelAudioOffloadPauseTimeout();
-
-    int64_t getDurationUsIfPlayedAtSampleRate(uint32_t numFrames);
-
-    DISALLOW_EVIL_CONSTRUCTORS(Renderer);
-};
-
-} // namespace android
-
-#endif  // NUPLAYER2_RENDERER_H_
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Source.h b/media/libmediaplayer2/nuplayer2/NuPlayer2Source.h
deleted file mode 100644
index 9298a99..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Source.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-#ifndef NUPLAYER2_SOURCE_H_
-
-#define NUPLAYER2_SOURCE_H_
-
-#include "NuPlayer2.h"
-
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/MetaData.h>
-#include <mediaplayer2/mediaplayer2.h>
-#include <utils/Vector.h>
-
-namespace android {
-
-struct ABuffer;
-struct AMediaCryptoWrapper;
-class MediaBuffer;
-
-struct NuPlayer2::Source : public AHandler {
-    enum Flags {
-        FLAG_CAN_PAUSE          = 1,
-        FLAG_CAN_SEEK_BACKWARD  = 2,  // the "10 sec back button"
-        FLAG_CAN_SEEK_FORWARD   = 4,  // the "10 sec forward button"
-        FLAG_CAN_SEEK           = 8,  // the "seek bar"
-        FLAG_DYNAMIC_DURATION   = 16,
-        FLAG_SECURE             = 32, // Secure codec is required.
-        FLAG_PROTECTED          = 64, // The screen needs to be protected (screenshot is disabled).
-    };
-
-    enum {
-        kWhatPrepared,
-        kWhatFlagsChanged,
-        kWhatVideoSizeChanged,
-        kWhatBufferingUpdate,
-        kWhatPauseOnBufferingStart,
-        kWhatResumeOnBufferingEnd,
-        kWhatCacheStats,
-        kWhatSubtitleData,
-        kWhatTimedTextData,
-        kWhatTimedMetaData,
-        kWhatQueueDecoderShutdown,
-        kWhatDrmNoLicense,
-        // Modular DRM
-        kWhatDrmInfo,
-    };
-
-    // The provides message is used to notify the player about various
-    // events.
-    explicit Source(const sp<AMessage> &notify)
-        : mNotify(notify) {
-    }
-
-    virtual status_t getBufferingSettings(
-            BufferingSettings* buffering /* nonnull */) = 0;
-    virtual status_t setBufferingSettings(const BufferingSettings& buffering) = 0;
-
-    virtual void prepareAsync(int64_t startTimeUs) = 0;
-
-    virtual void start() = 0;
-    virtual void stop() {}
-    virtual void pause() {}
-    virtual void resume() {}
-
-    // Explicitly disconnect the underling data source
-    virtual void disconnect() {}
-
-    // Returns OK iff more data was available,
-    // an error or ERROR_END_OF_STREAM if not.
-    virtual status_t feedMoreTSData() = 0;
-
-    // Returns non-NULL format when the specified track exists.
-    // When the format has "err" set to -EWOULDBLOCK, source needs more time to get valid meta data.
-    // Returns NULL if the specified track doesn't exist or is invalid;
-    virtual sp<AMessage> getFormat(bool audio);
-
-    virtual sp<MetaData> getFormatMeta(bool /* audio */) { return NULL; }
-    virtual sp<MetaData> getFileFormatMeta() const { return NULL; }
-
-    virtual status_t dequeueAccessUnit(
-            bool audio, sp<ABuffer> *accessUnit) = 0;
-
-    virtual status_t getDuration(int64_t * /* durationUs */) {
-        return INVALID_OPERATION;
-    }
-
-    virtual size_t getTrackCount() const {
-        return 0;
-    }
-
-    virtual sp<AMessage> getTrackInfo(size_t /* trackIndex */) const {
-        return NULL;
-    }
-
-    virtual ssize_t getSelectedTrack(media_track_type /* type */) const {
-        return INVALID_OPERATION;
-    }
-
-    virtual status_t selectTrack(size_t /* trackIndex */, bool /* select */, int64_t /* timeUs*/) {
-        return INVALID_OPERATION;
-    }
-
-    virtual status_t seekTo(
-            int64_t /* seekTimeUs */,
-            MediaPlayer2SeekMode /* mode */ = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC) {
-        return INVALID_OPERATION;
-    }
-
-    virtual bool isRealTime() const {
-        return false;
-    }
-
-    virtual bool isStreaming() const {
-        return true;
-    }
-
-    virtual void setOffloadAudio(bool /* offload */) {}
-
-    // Modular DRM
-    virtual status_t prepareDrm(
-            const uint8_t /* uuid */[16], const Vector<uint8_t> & /* drmSessionId */,
-            sp<AMediaCryptoWrapper> * /* crypto */) {
-        return INVALID_OPERATION;
-    }
-
-    virtual status_t releaseDrm() {
-        return INVALID_OPERATION;
-    }
-
-protected:
-    virtual ~Source() {}
-
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-    sp<AMessage> dupNotify() const { return mNotify->dup(); }
-
-    void notifyFlagsChanged(uint32_t flags);
-    void notifyVideoSizeChanged(const sp<AMessage> &format = NULL);
-    void notifyPrepared(status_t err = OK);
-    // Modular DRM
-    void notifyDrmInfo(const sp<ABuffer> &buffer);
-
-private:
-    sp<AMessage> mNotify;
-
-    DISALLOW_EVIL_CONSTRUCTORS(Source);
-};
-
-}  // namespace android
-
-#endif  // NUPLAYER2_SOURCE_H_
-
diff --git a/media/libmediaplayer2/nuplayer2/RTSPSource2.cpp b/media/libmediaplayer2/nuplayer2/RTSPSource2.cpp
deleted file mode 100644
index a70269e..0000000
--- a/media/libmediaplayer2/nuplayer2/RTSPSource2.cpp
+++ /dev/null
@@ -1,903 +0,0 @@
-/*
- * Copyright 2017 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 "RTSPSource2"
-#include <utils/Log.h>
-
-#include "RTSPSource2.h"
-
-#include "AnotherPacketSource.h"
-#include "MyHandler.h"
-#include "SDPLoader.h"
-
-#include <media/MediaHTTPService.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MetaData.h>
-
-namespace android {
-
-const int64_t kNearEOSTimeoutUs = 2000000LL; // 2 secs
-
-// Default Buffer Underflow/Prepare/StartServer/Overflow Marks
-static const int kUnderflowMarkMs   =  1000;  // 1 second
-static const int kPrepareMarkMs     =  3000;  // 3 seconds
-//static const int kStartServerMarkMs =  5000;
-static const int kOverflowMarkMs    = 10000;  // 10 seconds
-
-NuPlayer2::RTSPSource2::RTSPSource2(
-        const sp<AMessage> &notify,
-        const sp<MediaHTTPService> &httpService,
-        const char *url,
-        const KeyedVector<String8, String8> *headers,
-        uid_t uid,
-        bool isSDP)
-    : Source(notify),
-      mHTTPService(httpService),
-      mURL(url),
-      mUID(uid),
-      mFlags(0),
-      mIsSDP(isSDP),
-      mState(DISCONNECTED),
-      mFinalResult(OK),
-      mDisconnectReplyID(0),
-      mBuffering(false),
-      mInPreparationPhase(true),
-      mEOSPending(false),
-      mSeekGeneration(0),
-      mEOSTimeoutAudio(0),
-      mEOSTimeoutVideo(0) {
-    mBufferingSettings.mInitialMarkMs = kPrepareMarkMs;
-    mBufferingSettings.mResumePlaybackMarkMs = kOverflowMarkMs;
-    if (headers) {
-        mExtraHeaders = *headers;
-
-        ssize_t index =
-            mExtraHeaders.indexOfKey(String8("x-hide-urls-from-log"));
-
-        if (index >= 0) {
-            mFlags |= kFlagIncognito;
-
-            mExtraHeaders.removeItemsAt(index);
-        }
-    }
-}
-
-NuPlayer2::RTSPSource2::~RTSPSource2() {
-    if (mLooper != NULL) {
-        mLooper->unregisterHandler(id());
-        mLooper->stop();
-    }
-}
-
-status_t NuPlayer2::RTSPSource2::getBufferingSettings(
-            BufferingSettings* buffering /* nonnull */) {
-    Mutex::Autolock _l(mBufferingSettingsLock);
-    *buffering = mBufferingSettings;
-    return OK;
-}
-
-status_t NuPlayer2::RTSPSource2::setBufferingSettings(const BufferingSettings& buffering) {
-    Mutex::Autolock _l(mBufferingSettingsLock);
-    mBufferingSettings = buffering;
-    return OK;
-}
-
-// TODO: fetch data starting from |startTimeUs|
-void NuPlayer2::RTSPSource2::prepareAsync(int64_t /* startTimeUs */) {
-    if (mIsSDP && mHTTPService == NULL) {
-        notifyPrepared(BAD_VALUE);
-        return;
-    }
-
-    if (mLooper == NULL) {
-        mLooper = new ALooper;
-        mLooper->setName("rtsp2");
-        mLooper->start();
-
-        mLooper->registerHandler(this);
-    }
-
-    CHECK(mHandler == NULL);
-    CHECK(mSDPLoader == NULL);
-
-    sp<AMessage> notify = new AMessage(kWhatNotify, this);
-
-    CHECK_EQ(mState, (int)DISCONNECTED);
-    mState = CONNECTING;
-
-    if (mIsSDP) {
-        mSDPLoader = new SDPLoader(notify,
-                (mFlags & kFlagIncognito) ? SDPLoader::kFlagIncognito : 0,
-                mHTTPService);
-
-        mSDPLoader->load(
-                mURL.c_str(), mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders);
-    } else {
-        mHandler = new MyHandler(mURL.c_str(), notify, true /* uidValid */, mUID);
-        mLooper->registerHandler(mHandler);
-
-        mHandler->connect();
-    }
-
-    startBufferingIfNecessary();
-}
-
-void NuPlayer2::RTSPSource2::start() {
-}
-
-void NuPlayer2::RTSPSource2::stop() {
-    if (mLooper == NULL) {
-        return;
-    }
-    sp<AMessage> msg = new AMessage(kWhatDisconnect, this);
-
-    sp<AMessage> dummy;
-    msg->postAndAwaitResponse(&dummy);
-}
-
-status_t NuPlayer2::RTSPSource2::feedMoreTSData() {
-    Mutex::Autolock _l(mBufferingLock);
-    return mFinalResult;
-}
-
-sp<MetaData> NuPlayer2::RTSPSource2::getFormatMeta(bool audio) {
-    sp<AnotherPacketSource> source = getSource(audio);
-
-    if (source == NULL) {
-        return NULL;
-    }
-
-    return source->getFormat();
-}
-
-bool NuPlayer2::RTSPSource2::haveSufficientDataOnAllTracks() {
-    // We're going to buffer at least 2 secs worth data on all tracks before
-    // starting playback (both at startup and after a seek).
-
-    static const int64_t kMinDurationUs = 2000000LL;
-
-    int64_t mediaDurationUs = 0;
-    getDuration(&mediaDurationUs);
-    if ((mAudioTrack != NULL && mAudioTrack->isFinished(mediaDurationUs))
-            || (mVideoTrack != NULL && mVideoTrack->isFinished(mediaDurationUs))) {
-        return true;
-    }
-
-    status_t err;
-    int64_t durationUs;
-    if (mAudioTrack != NULL
-            && (durationUs = mAudioTrack->getBufferedDurationUs(&err))
-                    < kMinDurationUs
-            && err == OK) {
-        ALOGV("audio track doesn't have enough data yet. (%.2f secs buffered)",
-              durationUs / 1E6);
-        return false;
-    }
-
-    if (mVideoTrack != NULL
-            && (durationUs = mVideoTrack->getBufferedDurationUs(&err))
-                    < kMinDurationUs
-            && err == OK) {
-        ALOGV("video track doesn't have enough data yet. (%.2f secs buffered)",
-              durationUs / 1E6);
-        return false;
-    }
-
-    return true;
-}
-
-status_t NuPlayer2::RTSPSource2::dequeueAccessUnit(
-        bool audio, sp<ABuffer> *accessUnit) {
-    if (!stopBufferingIfNecessary()) {
-        return -EWOULDBLOCK;
-    }
-
-    sp<AnotherPacketSource> source = getSource(audio);
-
-    if (source == NULL) {
-        return -EWOULDBLOCK;
-    }
-
-    status_t finalResult;
-    if (!source->hasBufferAvailable(&finalResult)) {
-        if (finalResult == OK) {
-
-            // If other source already signaled EOS, this source should also return EOS
-            if (sourceReachedEOS(!audio)) {
-                return ERROR_END_OF_STREAM;
-            }
-
-            // If this source has detected near end, give it some time to retrieve more
-            // data before returning EOS
-            int64_t mediaDurationUs = 0;
-            getDuration(&mediaDurationUs);
-            if (source->isFinished(mediaDurationUs)) {
-                int64_t eosTimeout = audio ? mEOSTimeoutAudio : mEOSTimeoutVideo;
-                if (eosTimeout == 0) {
-                    setEOSTimeout(audio, ALooper::GetNowUs());
-                } else if ((ALooper::GetNowUs() - eosTimeout) > kNearEOSTimeoutUs) {
-                    setEOSTimeout(audio, 0);
-                    return ERROR_END_OF_STREAM;
-                }
-                return -EWOULDBLOCK;
-            }
-
-            if (!sourceNearEOS(!audio)) {
-                // We should not enter buffering mode
-                // if any of the sources already have detected EOS.
-                startBufferingIfNecessary();
-            }
-
-            return -EWOULDBLOCK;
-        }
-        return finalResult;
-    }
-
-    setEOSTimeout(audio, 0);
-
-    return source->dequeueAccessUnit(accessUnit);
-}
-
-sp<AnotherPacketSource> NuPlayer2::RTSPSource2::getSource(bool audio) {
-    if (mTSParser != NULL) {
-        sp<MediaSource> source = mTSParser->getSource(
-                audio ? ATSParser::AUDIO : ATSParser::VIDEO);
-
-        return static_cast<AnotherPacketSource *>(source.get());
-    }
-
-    return audio ? mAudioTrack : mVideoTrack;
-}
-
-void NuPlayer2::RTSPSource2::setEOSTimeout(bool audio, int64_t timeout) {
-    if (audio) {
-        mEOSTimeoutAudio = timeout;
-    } else {
-        mEOSTimeoutVideo = timeout;
-    }
-}
-
-status_t NuPlayer2::RTSPSource2::getDuration(int64_t *durationUs) {
-    *durationUs = -1LL;
-
-    int64_t audioDurationUs;
-    if (mAudioTrack != NULL
-            && mAudioTrack->getFormat()->findInt64(
-                kKeyDuration, &audioDurationUs)
-            && audioDurationUs > *durationUs) {
-        *durationUs = audioDurationUs;
-    }
-
-    int64_t videoDurationUs;
-    if (mVideoTrack != NULL
-            && mVideoTrack->getFormat()->findInt64(
-                kKeyDuration, &videoDurationUs)
-            && videoDurationUs > *durationUs) {
-        *durationUs = videoDurationUs;
-    }
-
-    return OK;
-}
-
-status_t NuPlayer2::RTSPSource2::seekTo(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
-    sp<AMessage> msg = new AMessage(kWhatPerformSeek, this);
-    msg->setInt32("generation", ++mSeekGeneration);
-    msg->setInt64("timeUs", seekTimeUs);
-    msg->setInt32("mode", mode);
-
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-    }
-
-    return err;
-}
-
-void NuPlayer2::RTSPSource2::performSeek(int64_t seekTimeUs) {
-    if (mState != CONNECTED) {
-        finishSeek(INVALID_OPERATION);
-        return;
-    }
-
-    mState = SEEKING;
-    mHandler->seek(seekTimeUs);
-    mEOSPending = false;
-}
-
-void NuPlayer2::RTSPSource2::schedulePollBuffering() {
-    sp<AMessage> msg = new AMessage(kWhatPollBuffering, this);
-    msg->post(1000000LL); // 1 second intervals
-}
-
-void NuPlayer2::RTSPSource2::checkBuffering(
-        bool *prepared, bool *underflow, bool *overflow, bool *startServer, bool *finished) {
-    size_t numTracks = mTracks.size();
-    size_t preparedCount, underflowCount, overflowCount, startCount, finishedCount;
-    preparedCount = underflowCount = overflowCount = startCount = finishedCount = 0;
-
-    size_t count = numTracks;
-    for (size_t i = 0; i < count; ++i) {
-        status_t finalResult;
-        TrackInfo *info = &mTracks.editItemAt(i);
-        sp<AnotherPacketSource> src = info->mSource;
-        if (src == NULL) {
-            --numTracks;
-            continue;
-        }
-        int64_t bufferedDurationUs = src->getBufferedDurationUs(&finalResult);
-
-        int64_t initialMarkUs;
-        int64_t maxRebufferingMarkUs;
-        {
-            Mutex::Autolock _l(mBufferingSettingsLock);
-            initialMarkUs = mBufferingSettings.mInitialMarkMs * 1000LL;
-            // TODO: maxRebufferingMarkUs could be larger than
-            // mBufferingSettings.mResumePlaybackMarkMs * 1000ll.
-            maxRebufferingMarkUs = mBufferingSettings.mResumePlaybackMarkMs * 1000LL;
-        }
-        // isFinished when duration is 0 checks for EOS result only
-        if (bufferedDurationUs > initialMarkUs
-                || src->isFinished(/* duration */ 0)) {
-            ++preparedCount;
-        }
-
-        if (src->isFinished(/* duration */ 0)) {
-            ++overflowCount;
-            ++finishedCount;
-        } else {
-            // TODO: redefine kUnderflowMarkMs to a fair value,
-            if (bufferedDurationUs < kUnderflowMarkMs * 1000) {
-                ++underflowCount;
-            }
-            if (bufferedDurationUs > maxRebufferingMarkUs) {
-                ++overflowCount;
-            }
-            int64_t startServerMarkUs =
-                    (kUnderflowMarkMs * 1000LL + maxRebufferingMarkUs) / 2;
-            if (bufferedDurationUs < startServerMarkUs) {
-                ++startCount;
-            }
-        }
-    }
-
-    *prepared    = (preparedCount == numTracks);
-    *underflow   = (underflowCount > 0);
-    *overflow    = (overflowCount == numTracks);
-    *startServer = (startCount > 0);
-    *finished    = (finishedCount > 0);
-}
-
-void NuPlayer2::RTSPSource2::onPollBuffering() {
-    bool prepared, underflow, overflow, startServer, finished;
-    checkBuffering(&prepared, &underflow, &overflow, &startServer, &finished);
-
-    if (prepared && mInPreparationPhase) {
-        mInPreparationPhase = false;
-        notifyPrepared();
-    }
-
-    if (!mInPreparationPhase && underflow) {
-        startBufferingIfNecessary();
-    }
-
-    if (haveSufficientDataOnAllTracks()) {
-        stopBufferingIfNecessary();
-    }
-
-    if (overflow && mHandler != NULL) {
-        mHandler->pause();
-    }
-
-    if (startServer && mHandler != NULL) {
-        mHandler->resume();
-    }
-
-    if (finished && mHandler != NULL) {
-        mHandler->cancelAccessUnitTimeoutCheck();
-    }
-
-    schedulePollBuffering();
-}
-
-void NuPlayer2::RTSPSource2::signalSourceEOS(status_t result) {
-    const bool audio = true;
-    const bool video = false;
-
-    sp<AnotherPacketSource> source = getSource(audio);
-    if (source != NULL) {
-        source->signalEOS(result);
-    }
-
-    source = getSource(video);
-    if (source != NULL) {
-        source->signalEOS(result);
-    }
-}
-
-bool NuPlayer2::RTSPSource2::sourceReachedEOS(bool audio) {
-    sp<AnotherPacketSource> source = getSource(audio);
-    status_t finalResult;
-    return (source != NULL &&
-            !source->hasBufferAvailable(&finalResult) &&
-            finalResult == ERROR_END_OF_STREAM);
-}
-
-bool NuPlayer2::RTSPSource2::sourceNearEOS(bool audio) {
-    sp<AnotherPacketSource> source = getSource(audio);
-    int64_t mediaDurationUs = 0;
-    getDuration(&mediaDurationUs);
-    return (source != NULL && source->isFinished(mediaDurationUs));
-}
-
-void NuPlayer2::RTSPSource2::onSignalEOS(const sp<AMessage> &msg) {
-    int32_t generation;
-    CHECK(msg->findInt32("generation", &generation));
-
-    if (generation != mSeekGeneration) {
-        return;
-    }
-
-    if (mEOSPending) {
-        signalSourceEOS(ERROR_END_OF_STREAM);
-        mEOSPending = false;
-    }
-}
-
-void NuPlayer2::RTSPSource2::postSourceEOSIfNecessary() {
-    const bool audio = true;
-    const bool video = false;
-    // If a source has detected near end, give it some time to retrieve more
-    // data before signaling EOS
-    if (sourceNearEOS(audio) || sourceNearEOS(video)) {
-        if (!mEOSPending) {
-            sp<AMessage> msg = new AMessage(kWhatSignalEOS, this);
-            msg->setInt32("generation", mSeekGeneration);
-            msg->post(kNearEOSTimeoutUs);
-            mEOSPending = true;
-        }
-    }
-}
-
-void NuPlayer2::RTSPSource2::onMessageReceived(const sp<AMessage> &msg) {
-    if (msg->what() == kWhatDisconnect) {
-        sp<AReplyToken> replyID;
-        CHECK(msg->senderAwaitsResponse(&replyID));
-
-        mDisconnectReplyID = replyID;
-        finishDisconnectIfPossible();
-        return;
-    } else if (msg->what() == kWhatPerformSeek) {
-        int32_t generation;
-        CHECK(msg->findInt32("generation", &generation));
-        CHECK(msg->senderAwaitsResponse(&mSeekReplyID));
-
-        if (generation != mSeekGeneration) {
-            // obsolete.
-            finishSeek(OK);
-            return;
-        }
-
-        int64_t seekTimeUs;
-        int32_t mode;
-        CHECK(msg->findInt64("timeUs", &seekTimeUs));
-        CHECK(msg->findInt32("mode", &mode));
-
-        // TODO: add "mode" to performSeek.
-        performSeek(seekTimeUs/*, (MediaPlayer2SeekMode)mode */);
-        return;
-    } else if (msg->what() == kWhatPollBuffering) {
-        onPollBuffering();
-        return;
-    } else if (msg->what() == kWhatSignalEOS) {
-        onSignalEOS(msg);
-        return;
-    }
-
-    CHECK_EQ(msg->what(), kWhatNotify);
-
-    int32_t what;
-    CHECK(msg->findInt32("what", &what));
-
-    switch (what) {
-        case MyHandler::kWhatConnected:
-        {
-            onConnected();
-
-            notifyVideoSizeChanged();
-
-            uint32_t flags = 0;
-
-            if (mHandler->isSeekable()) {
-                flags = FLAG_CAN_PAUSE
-                        | FLAG_CAN_SEEK
-                        | FLAG_CAN_SEEK_BACKWARD
-                        | FLAG_CAN_SEEK_FORWARD;
-            }
-
-            notifyFlagsChanged(flags);
-            schedulePollBuffering();
-            break;
-        }
-
-        case MyHandler::kWhatDisconnected:
-        {
-            onDisconnected(msg);
-            break;
-        }
-
-        case MyHandler::kWhatSeekDone:
-        {
-            mState = CONNECTED;
-            // Unblock seekTo here in case we attempted to seek in a live stream
-            finishSeek(OK);
-            break;
-        }
-
-        case MyHandler::kWhatSeekPaused:
-        {
-            sp<AnotherPacketSource> source = getSource(true /* audio */);
-            if (source != NULL) {
-                source->queueDiscontinuity(ATSParser::DISCONTINUITY_NONE,
-                        /* extra */ NULL,
-                        /* discard */ true);
-            }
-            source = getSource(false /* video */);
-            if (source != NULL) {
-                source->queueDiscontinuity(ATSParser::DISCONTINUITY_NONE,
-                        /* extra */ NULL,
-                        /* discard */ true);
-            };
-
-            status_t err = OK;
-            msg->findInt32("err", &err);
-
-            if (err == OK) {
-                int64_t timeUs;
-                CHECK(msg->findInt64("time", &timeUs));
-                mHandler->continueSeekAfterPause(timeUs);
-            } else {
-                finishSeek(err);
-            }
-            break;
-        }
-
-        case MyHandler::kWhatAccessUnit:
-        {
-            size_t trackIndex;
-            CHECK(msg->findSize("trackIndex", &trackIndex));
-
-            if (mTSParser == NULL) {
-                CHECK_LT(trackIndex, mTracks.size());
-            } else {
-                CHECK_EQ(trackIndex, 0u);
-            }
-
-            sp<ABuffer> accessUnit;
-            CHECK(msg->findBuffer("accessUnit", &accessUnit));
-
-            int32_t damaged;
-            if (accessUnit->meta()->findInt32("damaged", &damaged)
-                    && damaged) {
-                ALOGI("dropping damaged access unit.");
-                break;
-            }
-
-            if (mTSParser != NULL) {
-                size_t offset = 0;
-                status_t err = OK;
-                while (offset + 188 <= accessUnit->size()) {
-                    err = mTSParser->feedTSPacket(
-                            accessUnit->data() + offset, 188);
-                    if (err != OK) {
-                        break;
-                    }
-
-                    offset += 188;
-                }
-
-                if (offset < accessUnit->size()) {
-                    err = ERROR_MALFORMED;
-                }
-
-                if (err != OK) {
-                    signalSourceEOS(err);
-                }
-
-                postSourceEOSIfNecessary();
-                break;
-            }
-
-            TrackInfo *info = &mTracks.editItemAt(trackIndex);
-
-            sp<AnotherPacketSource> source = info->mSource;
-            if (source != NULL) {
-                uint32_t rtpTime;
-                CHECK(accessUnit->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
-
-                if (!info->mNPTMappingValid) {
-                    // This is a live stream, we didn't receive any normal
-                    // playtime mapping. We won't map to npt time.
-                    source->queueAccessUnit(accessUnit);
-                    break;
-                }
-
-                int64_t nptUs =
-                    ((double)rtpTime - (double)info->mRTPTime)
-                        / info->mTimeScale
-                        * 1000000LL
-                        + info->mNormalPlaytimeUs;
-
-                accessUnit->meta()->setInt64("timeUs", nptUs);
-
-                source->queueAccessUnit(accessUnit);
-            }
-            postSourceEOSIfNecessary();
-            break;
-        }
-
-        case MyHandler::kWhatEOS:
-        {
-            int32_t finalResult;
-            CHECK(msg->findInt32("finalResult", &finalResult));
-            CHECK_NE(finalResult, (status_t)OK);
-
-            if (mTSParser != NULL) {
-                signalSourceEOS(finalResult);
-            }
-
-            size_t trackIndex;
-            CHECK(msg->findSize("trackIndex", &trackIndex));
-            CHECK_LT(trackIndex, mTracks.size());
-
-            TrackInfo *info = &mTracks.editItemAt(trackIndex);
-            sp<AnotherPacketSource> source = info->mSource;
-            if (source != NULL) {
-                source->signalEOS(finalResult);
-            }
-
-            break;
-        }
-
-        case MyHandler::kWhatSeekDiscontinuity:
-        {
-            size_t trackIndex;
-            CHECK(msg->findSize("trackIndex", &trackIndex));
-            CHECK_LT(trackIndex, mTracks.size());
-
-            TrackInfo *info = &mTracks.editItemAt(trackIndex);
-            sp<AnotherPacketSource> source = info->mSource;
-            if (source != NULL) {
-                source->queueDiscontinuity(
-                        ATSParser::DISCONTINUITY_TIME,
-                        NULL,
-                        true /* discard */);
-            }
-
-            break;
-        }
-
-        case MyHandler::kWhatNormalPlayTimeMapping:
-        {
-            size_t trackIndex;
-            CHECK(msg->findSize("trackIndex", &trackIndex));
-            CHECK_LT(trackIndex, mTracks.size());
-
-            uint32_t rtpTime;
-            CHECK(msg->findInt32("rtpTime", (int32_t *)&rtpTime));
-
-            int64_t nptUs;
-            CHECK(msg->findInt64("nptUs", &nptUs));
-
-            TrackInfo *info = &mTracks.editItemAt(trackIndex);
-            info->mRTPTime = rtpTime;
-            info->mNormalPlaytimeUs = nptUs;
-            info->mNPTMappingValid = true;
-            break;
-        }
-
-        case SDPLoader::kWhatSDPLoaded:
-        {
-            onSDPLoaded(msg);
-            break;
-        }
-
-        default:
-            TRESPASS();
-    }
-}
-
-void NuPlayer2::RTSPSource2::onConnected() {
-    CHECK(mAudioTrack == NULL);
-    CHECK(mVideoTrack == NULL);
-
-    size_t numTracks = mHandler->countTracks();
-    for (size_t i = 0; i < numTracks; ++i) {
-        int32_t timeScale;
-        sp<MetaData> format = mHandler->getTrackFormat(i, &timeScale);
-
-        const char *mime;
-        CHECK(format->findCString(kKeyMIMEType, &mime));
-
-        if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
-            // Very special case for MPEG2 Transport Streams.
-            CHECK_EQ(numTracks, 1u);
-
-            mTSParser = new ATSParser;
-            return;
-        }
-
-        bool isAudio = !strncasecmp(mime, "audio/", 6);
-        bool isVideo = !strncasecmp(mime, "video/", 6);
-
-        TrackInfo info;
-        info.mTimeScale = timeScale;
-        info.mRTPTime = 0;
-        info.mNormalPlaytimeUs = 0LL;
-        info.mNPTMappingValid = false;
-
-        if ((isAudio && mAudioTrack == NULL)
-                || (isVideo && mVideoTrack == NULL)) {
-            sp<AnotherPacketSource> source = new AnotherPacketSource(format);
-
-            if (isAudio) {
-                mAudioTrack = source;
-            } else {
-                mVideoTrack = source;
-            }
-
-            info.mSource = source;
-        }
-
-        mTracks.push(info);
-    }
-
-    mState = CONNECTED;
-}
-
-void NuPlayer2::RTSPSource2::onSDPLoaded(const sp<AMessage> &msg) {
-    status_t err;
-    CHECK(msg->findInt32("result", &err));
-
-    mSDPLoader.clear();
-
-    if (mDisconnectReplyID != 0) {
-        err = UNKNOWN_ERROR;
-    }
-
-    if (err == OK) {
-        sp<ASessionDescription> desc;
-        sp<RefBase> obj;
-        CHECK(msg->findObject("description", &obj));
-        desc = static_cast<ASessionDescription *>(obj.get());
-
-        AString rtspUri;
-        if (!desc->findAttribute(0, "a=control", &rtspUri)) {
-            ALOGE("Unable to find url in SDP");
-            err = UNKNOWN_ERROR;
-        } else {
-            sp<AMessage> notify = new AMessage(kWhatNotify, this);
-
-            mHandler = new MyHandler(rtspUri.c_str(), notify, true /* uidValid */, mUID);
-            mLooper->registerHandler(mHandler);
-
-            mHandler->loadSDP(desc);
-        }
-    }
-
-    if (err != OK) {
-        if (mState == CONNECTING) {
-            // We're still in the preparation phase, signal that it
-            // failed.
-            notifyPrepared(err);
-        }
-
-        mState = DISCONNECTED;
-        setError(err);
-
-        if (mDisconnectReplyID != 0) {
-            finishDisconnectIfPossible();
-        }
-    }
-}
-
-void NuPlayer2::RTSPSource2::onDisconnected(const sp<AMessage> &msg) {
-    if (mState == DISCONNECTED) {
-        return;
-    }
-
-    status_t err;
-    CHECK(msg->findInt32("result", &err));
-    CHECK_NE(err, (status_t)OK);
-
-    mLooper->unregisterHandler(mHandler->id());
-    mHandler.clear();
-
-    if (mState == CONNECTING) {
-        // We're still in the preparation phase, signal that it
-        // failed.
-        notifyPrepared(err);
-    }
-
-    mState = DISCONNECTED;
-    setError(err);
-
-    if (mDisconnectReplyID != 0) {
-        finishDisconnectIfPossible();
-    }
-}
-
-void NuPlayer2::RTSPSource2::finishDisconnectIfPossible() {
-    if (mState != DISCONNECTED) {
-        if (mHandler != NULL) {
-            mHandler->disconnect();
-        } else if (mSDPLoader != NULL) {
-            mSDPLoader->cancel();
-        }
-        return;
-    }
-
-    (new AMessage)->postReply(mDisconnectReplyID);
-    mDisconnectReplyID = 0;
-}
-
-void NuPlayer2::RTSPSource2::setError(status_t err) {
-    Mutex::Autolock _l(mBufferingLock);
-    mFinalResult = err;
-}
-
-void NuPlayer2::RTSPSource2::startBufferingIfNecessary() {
-    Mutex::Autolock _l(mBufferingLock);
-
-    if (!mBuffering) {
-        mBuffering = true;
-
-        sp<AMessage> notify = dupNotify();
-        notify->setInt32("what", kWhatPauseOnBufferingStart);
-        notify->post();
-    }
-}
-
-bool NuPlayer2::RTSPSource2::stopBufferingIfNecessary() {
-    Mutex::Autolock _l(mBufferingLock);
-
-    if (mBuffering) {
-        if (!haveSufficientDataOnAllTracks()) {
-            return false;
-        }
-
-        mBuffering = false;
-
-        sp<AMessage> notify = dupNotify();
-        notify->setInt32("what", kWhatResumeOnBufferingEnd);
-        notify->post();
-    }
-
-    return true;
-}
-
-void NuPlayer2::RTSPSource2::finishSeek(status_t err) {
-    if (mSeekReplyID == NULL) {
-        return;
-    }
-    sp<AMessage> seekReply = new AMessage;
-    seekReply->setInt32("err", err);
-    seekReply->postReply(mSeekReplyID);
-    mSeekReplyID = NULL;
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/RTSPSource2.h b/media/libmediaplayer2/nuplayer2/RTSPSource2.h
deleted file mode 100644
index e5f1716..0000000
--- a/media/libmediaplayer2/nuplayer2/RTSPSource2.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-#ifndef RTSP_SOURCE2_H_
-
-#define RTSP_SOURCE2_H_
-
-#include "NuPlayer2Source.h"
-
-#include "ATSParser.h"
-
-namespace android {
-
-struct ALooper;
-struct AReplyToken;
-struct AnotherPacketSource;
-struct MyHandler;
-struct SDPLoader;
-
-struct NuPlayer2::RTSPSource2 : public NuPlayer2::Source {
-    RTSPSource2(
-            const sp<AMessage> &notify,
-            const sp<MediaHTTPService> &httpService,
-            const char *url,
-            const KeyedVector<String8, String8> *headers,
-            uid_t uid = 0,
-            bool isSDP = false);
-
-    virtual status_t getBufferingSettings(
-            BufferingSettings* buffering /* nonnull */) override;
-    virtual status_t setBufferingSettings(const BufferingSettings& buffering) override;
-
-    virtual void prepareAsync(int64_t startTimeUs);
-    virtual void start();
-    virtual void stop();
-
-    virtual status_t feedMoreTSData();
-
-    virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);
-
-    virtual status_t getDuration(int64_t *durationUs);
-    virtual status_t seekTo(
-            int64_t seekTimeUs,
-            MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC) override;
-
-    void onMessageReceived(const sp<AMessage> &msg);
-
-protected:
-    virtual ~RTSPSource2();
-
-    virtual sp<MetaData> getFormatMeta(bool audio);
-
-private:
-    enum {
-        kWhatNotify          = 'noti',
-        kWhatDisconnect      = 'disc',
-        kWhatPerformSeek     = 'seek',
-        kWhatPollBuffering   = 'poll',
-        kWhatSignalEOS       = 'eos ',
-    };
-
-    enum State {
-        DISCONNECTED,
-        CONNECTING,
-        CONNECTED,
-        SEEKING,
-    };
-
-    enum Flags {
-        // Don't log any URLs.
-        kFlagIncognito = 1,
-    };
-
-    struct TrackInfo {
-        sp<AnotherPacketSource> mSource;
-
-        int32_t mTimeScale;
-        uint32_t mRTPTime;
-        int64_t mNormalPlaytimeUs;
-        bool mNPTMappingValid;
-    };
-
-    sp<MediaHTTPService> mHTTPService;
-    AString mURL;
-    KeyedVector<String8, String8> mExtraHeaders;
-    uid_t mUID;
-    uint32_t mFlags;
-    bool mIsSDP;
-    State mState;
-    status_t mFinalResult;
-    sp<AReplyToken> mDisconnectReplyID;
-    Mutex mBufferingLock;
-    bool mBuffering;
-    bool mInPreparationPhase;
-    bool mEOSPending;
-
-    Mutex mBufferingSettingsLock;
-    BufferingSettings mBufferingSettings;
-
-    sp<ALooper> mLooper;
-    sp<MyHandler> mHandler;
-    sp<SDPLoader> mSDPLoader;
-
-    Vector<TrackInfo> mTracks;
-    sp<AnotherPacketSource> mAudioTrack;
-    sp<AnotherPacketSource> mVideoTrack;
-
-    sp<ATSParser> mTSParser;
-
-    int32_t mSeekGeneration;
-
-    int64_t mEOSTimeoutAudio;
-    int64_t mEOSTimeoutVideo;
-
-    sp<AReplyToken> mSeekReplyID;
-
-    sp<AnotherPacketSource> getSource(bool audio);
-
-    void onConnected();
-    void onSDPLoaded(const sp<AMessage> &msg);
-    void onDisconnected(const sp<AMessage> &msg);
-    void finishDisconnectIfPossible();
-
-    void performSeek(int64_t seekTimeUs);
-    void schedulePollBuffering();
-    void checkBuffering(
-            bool *prepared,
-            bool *underflow,
-            bool *overflow,
-            bool *startServer,
-            bool *finished);
-    void onPollBuffering();
-
-    bool haveSufficientDataOnAllTracks();
-
-    void setEOSTimeout(bool audio, int64_t timeout);
-    void setError(status_t err);
-    void startBufferingIfNecessary();
-    bool stopBufferingIfNecessary();
-    void finishSeek(status_t err);
-
-    void postSourceEOSIfNecessary();
-    void signalSourceEOS(status_t result);
-    void onSignalEOS(const sp<AMessage> &msg);
-
-    bool sourceNearEOS(bool audio);
-    bool sourceReachedEOS(bool audio);
-
-    DISALLOW_EVIL_CONSTRUCTORS(RTSPSource2);
-};
-
-}  // namespace android
-
-#endif  // RTSP_SOURCE2_H_
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 3d67c91..d198d39 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -4505,22 +4505,38 @@
 status_t ACodec::configureImageGrid(
         const sp<AMessage> &msg, sp<AMessage> &outputFormat) {
     int32_t tileWidth, tileHeight, gridRows, gridCols;
-    if (!msg->findInt32("tile-width", &tileWidth) ||
-        !msg->findInt32("tile-height", &tileHeight) ||
-        !msg->findInt32("grid-rows", &gridRows) ||
-        !msg->findInt32("grid-cols", &gridCols)) {
+    OMX_BOOL useGrid = OMX_FALSE;
+    if (msg->findInt32("tile-width", &tileWidth) &&
+        msg->findInt32("tile-height", &tileHeight) &&
+        msg->findInt32("grid-rows", &gridRows) &&
+        msg->findInt32("grid-cols", &gridCols)) {
+        useGrid = OMX_TRUE;
+    } else {
+        // when bEnabled is false, the tile info is not used,
+        // but clear out these too.
+        tileWidth = tileHeight = gridRows = gridCols = 0;
+    }
+
+    if (!mIsImage && !useGrid) {
         return OK;
     }
 
     OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE gridType;
     InitOMXParams(&gridType);
     gridType.nPortIndex = kPortIndexOutput;
-    gridType.bEnabled = OMX_TRUE;
+    gridType.bEnabled = useGrid;
     gridType.nTileWidth = tileWidth;
     gridType.nTileHeight = tileHeight;
     gridType.nGridRows = gridRows;
     gridType.nGridCols = gridCols;
 
+    ALOGV("sending image grid info to component: bEnabled %d, tile %dx%d, grid %dx%d",
+            gridType.bEnabled,
+            gridType.nTileWidth,
+            gridType.nTileHeight,
+            gridType.nGridRows,
+            gridType.nGridCols);
+
     status_t err = mOMXNode->setParameter(
             (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidImageGrid,
             &gridType, sizeof(gridType));
@@ -4541,6 +4557,13 @@
             (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidImageGrid,
             &gridType, sizeof(gridType));
 
+    ALOGV("received image grid info from component: bEnabled %d, tile %dx%d, grid %dx%d",
+            gridType.bEnabled,
+            gridType.nTileWidth,
+            gridType.nTileHeight,
+            gridType.nGridRows,
+            gridType.nGridCols);
+
     if (err == OK && gridType.bEnabled) {
         outputFormat->setInt32("tile-width", gridType.nTileWidth);
         outputFormat->setInt32("tile-height", gridType.nTileHeight);
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 353044c8..bb7f2a5 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -261,62 +261,3 @@
     },
 }
 
-cc_library_static {
-    name: "libstagefright_player2",
-
-    srcs: [
-        "ClearFileSource.cpp",
-        "DataURISource.cpp",
-        "DataSourceBase.cpp",
-        "HTTPBase.cpp",
-        "HevcUtils.cpp",
-        "MediaClock.cpp",
-        "MediaSource.cpp",
-        "NdkUtils.cpp",
-        "Utils.cpp",
-        "VideoFrameSchedulerBase.cpp",
-        "VideoFrameScheduler2.cpp",
-        "http/ClearMediaHTTP.cpp",
-    ],
-
-    shared_libs: [
-        "libgui",
-        "liblog",
-        "libnetd_client",
-        "libutils",
-        "libstagefright_foundation",
-        "libandroid",
-    ],
-
-    static_libs: [
-        "libmedia_player2_util",
-        "libmedia2_jni_core",
-    ],
-
-    export_include_dirs: [
-        "include",
-    ],
-
-    cflags: [
-        "-Wno-multichar",
-        "-Werror",
-        "-Wno-error=deprecated-declarations",
-        "-Wall",
-    ],
-
-    product_variables: {
-        debuggable: {
-            // enable experiments only in userdebug and eng builds
-            cflags: ["-DENABLE_STAGEFRIGHT_EXPERIMENTS"],
-        },
-    },
-
-    sanitize: {
-        cfi: true,
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-    },
-}
-
diff --git a/media/libstagefright/VideoFrameScheduler2.cpp b/media/libstagefright/VideoFrameScheduler2.cpp
deleted file mode 100644
index 23671f2..0000000
--- a/media/libstagefright/VideoFrameScheduler2.cpp
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * Copyright (C) 2018 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 "VideoFrameScheduler2"
-#include <utils/Log.h>
-#define ATRACE_TAG ATRACE_TAG_VIDEO
-#include <utils/Mutex.h>
-#include <utils/Thread.h>
-#include <utils/Trace.h>
-
-#include <algorithm>
-#include <jni.h>
-#include <math.h>
-
-#include <android/choreographer.h>
-#include <android/looper.h>
-#include <media/stagefright/VideoFrameScheduler2.h>
-#include <mediaplayer2/JavaVMHelper.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AUtils.h>
-
-namespace android {
-
-static void getVsyncOffset(nsecs_t* appVsyncOffsetPtr, nsecs_t* sfVsyncOffsetPtr);
-
-/* ======================================================================= */
-/*                               VsyncTracker                              */
-/* ======================================================================= */
-
-class VsyncTracker : public RefBase{
-public:
-    VsyncTracker();
-    ~VsyncTracker() {}
-    nsecs_t getVsyncPeriod();
-    nsecs_t getVsyncTime(nsecs_t periodOffset);
-    void addSample(nsecs_t timestamp);
-
-private:
-    static const int kMaxSamples = 32;
-    static const int kMinSamplesForUpdate = 6;
-    int mNumSamples;
-    int mFirstSample;
-    nsecs_t mReferenceTime;
-    nsecs_t mPhase;
-    nsecs_t mPeriod;
-    nsecs_t mTimestampSamples[kMaxSamples];
-    Mutex mLock;
-
-    void updateModelLocked();
-};
-
-VsyncTracker::VsyncTracker()
-    : mNumSamples(0),
-      mFirstSample(0),
-      mReferenceTime(0),
-      mPhase(0),
-      mPeriod(0) {
-    for (int i = 0; i < kMaxSamples; i++) {
-        mTimestampSamples[i] = 0;
-    }
-}
-
-nsecs_t VsyncTracker::getVsyncPeriod() {
-    Mutex::Autolock dataLock(mLock);
-    return mPeriod;
-}
-
-nsecs_t VsyncTracker::getVsyncTime(nsecs_t periodOffset) {
-    Mutex::Autolock dataLock(mLock);
-    const nsecs_t now = systemTime();
-    nsecs_t phase = mReferenceTime + mPhase;
-
-    // result = (((now - phase) / mPeriod) + periodOffset + 1) * mPeriod + phase
-    // prevent overflow
-    nsecs_t result = (now - phase) / mPeriod;
-    if (result > LONG_LONG_MAX - periodOffset - 1) {
-        return LONG_LONG_MAX;
-    } else {
-        result += periodOffset + 1;
-    }
-    if (result > LONG_LONG_MAX / mPeriod) {
-        return LONG_LONG_MAX;
-    } else {
-        result *= mPeriod;
-    }
-    if (result > LONG_LONG_MAX - phase) {
-        return LONG_LONG_MAX;
-    } else {
-        result += phase;
-    }
-
-    return result;
-}
-
-void VsyncTracker::addSample(nsecs_t timestamp) {
-    Mutex::Autolock dataLock(mLock);
-    if (mNumSamples == 0) {
-        mPhase = 0;
-        mReferenceTime = timestamp;
-    }
-    int idx = (mFirstSample + mNumSamples) % kMaxSamples;
-    mTimestampSamples[idx] = timestamp;
-    if (mNumSamples < kMaxSamples) {
-        mNumSamples++;
-    } else {
-        mFirstSample = (mFirstSample + 1) % kMaxSamples;
-    }
-    updateModelLocked();
-}
-
-void VsyncTracker::updateModelLocked() {
-    if (mNumSamples < kMinSamplesForUpdate) {
-        return;
-    }
-    nsecs_t durationSum = 0;
-    nsecs_t minDuration = LONG_MAX;
-    nsecs_t maxDuration = 0;
-
-    for (int i = 1; i < mNumSamples; i++) {
-        int idx = (mFirstSample + i) % kMaxSamples;
-        int prev = (idx + kMaxSamples - 1) % kMaxSamples;
-        long duration = mTimestampSamples[idx] - mTimestampSamples[prev];
-        durationSum += duration;
-        if (minDuration > duration) { minDuration = duration; }
-        if (maxDuration < duration) { maxDuration = duration; }
-    }
-
-    durationSum -= (minDuration + maxDuration);
-    mPeriod = durationSum / (mNumSamples - 3);
-
-    double sampleAvgX = 0.0;
-    double sampleAvgY = 0.0;
-    double scale = 2.0 * M_PI / (double) mPeriod;
-
-    for (int i = 1; i < mNumSamples; i++) {
-        int idx = (mFirstSample + i) % kMaxSamples;
-        long sample = mTimestampSamples[idx] - mReferenceTime;
-        double samplePhase = (double) (sample % mPeriod) * scale;
-        sampleAvgX += cos(samplePhase);
-        sampleAvgY += sin(samplePhase);
-    }
-
-    sampleAvgX /= (double) mNumSamples - 1.0;
-    sampleAvgY /= (double) mNumSamples - 1.0;
-    mPhase = (long) (atan2(sampleAvgY, sampleAvgX) / scale);
-}
-
-static void frameCallback(int64_t frameTimeNanos, void* data) {
-    if (data == NULL) {
-        return;
-    }
-    sp<VsyncTracker> vsyncTracker(static_cast<VsyncTracker*>(data));
-    vsyncTracker->addSample(frameTimeNanos);
-    AChoreographer_postFrameCallback64(AChoreographer_getInstance(),
-            frameCallback, static_cast<void*>(vsyncTracker.get()));
-}
-
-/* ======================================================================= */
-/*                                   JNI                                   */
-/* ======================================================================= */
-
-static void getVsyncOffset(nsecs_t* appVsyncOffsetPtr, nsecs_t* sfVsyncOffsetPtr) {
-    static const nsecs_t kOneMillisecInNanosec = 1000000;
-    static const nsecs_t kOneSecInNanosec = kOneMillisecInNanosec * 1000;
-
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jclass jDisplayManagerGlobalCls = env->FindClass(
-            "android/hardware/display/DisplayManagerGlobal");
-    jclass jDisplayCls = env->FindClass("android/view/Display");
-
-    jmethodID jGetInstance = env->GetStaticMethodID(jDisplayManagerGlobalCls,
-            "getInstance", "()Landroid/hardware/display/DisplayManagerGlobal;");
-    jobject javaDisplayManagerGlobalObj = env->CallStaticObjectMethod(
-            jDisplayManagerGlobalCls, jGetInstance);
-
-    jfieldID jDEFAULT_DISPLAY = env->GetStaticFieldID(jDisplayCls, "DEFAULT_DISPLAY", "I");
-    jint DEFAULT_DISPLAY = env->GetStaticIntField(jDisplayCls, jDEFAULT_DISPLAY);
-
-    jmethodID jgetRealDisplay = env->GetMethodID(jDisplayManagerGlobalCls,
-            "getRealDisplay", "(I)Landroid/view/Display;");
-    jobject javaDisplayObj = env->CallObjectMethod(
-            javaDisplayManagerGlobalObj, jgetRealDisplay, DEFAULT_DISPLAY);
-
-    jmethodID jGetRefreshRate = env->GetMethodID(jDisplayCls, "getRefreshRate", "()F");
-    jfloat javaRefreshRate = env->CallFloatMethod(javaDisplayObj, jGetRefreshRate);
-    nsecs_t vsyncPeriod = (nsecs_t) (kOneSecInNanosec / (float) javaRefreshRate);
-
-    jmethodID jGetAppVsyncOffsetNanos = env->GetMethodID(
-            jDisplayCls, "getAppVsyncOffsetNanos", "()J");
-    jlong javaAppVsyncOffset = env->CallLongMethod(javaDisplayObj, jGetAppVsyncOffsetNanos);
-    *appVsyncOffsetPtr = (nsecs_t) javaAppVsyncOffset;
-
-    jmethodID jGetPresentationDeadlineNanos = env->GetMethodID(
-            jDisplayCls, "getPresentationDeadlineNanos", "()J");
-    jlong javaPresentationDeadline = env->CallLongMethod(
-            javaDisplayObj, jGetPresentationDeadlineNanos);
-
-    *sfVsyncOffsetPtr = vsyncPeriod - ((nsecs_t) javaPresentationDeadline - kOneMillisecInNanosec);
-}
-
-/* ======================================================================= */
-/*                          Choreographer Thread                           */
-/* ======================================================================= */
-
-struct ChoreographerThread : public Thread {
-    ChoreographerThread(bool canCallJava);
-    status_t init(void* data);
-    virtual status_t readyToRun() override;
-    virtual bool threadLoop() override;
-
-protected:
-    virtual ~ChoreographerThread() {}
-
-private:
-    DISALLOW_EVIL_CONSTRUCTORS(ChoreographerThread);
-    void* mData;
-};
-
-ChoreographerThread::ChoreographerThread(bool canCallJava) : Thread(canCallJava) {
-}
-
-status_t ChoreographerThread::init(void* data) {
-    if (data == NULL) {
-        return NO_INIT;
-    }
-    mData = data;
-    return OK;
-}
-
-status_t ChoreographerThread::readyToRun() {
-    ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
-    if (AChoreographer_getInstance() == NULL) {
-        return NO_INIT;
-    }
-    AChoreographer_postFrameCallback64(AChoreographer_getInstance(), frameCallback, mData);
-    return OK;
-}
-
-bool ChoreographerThread::threadLoop() {
-    ALooper_pollOnce(-1, nullptr, nullptr, nullptr);
-    return true;
-}
-
-/* ======================================================================= */
-/*                             Frame Scheduler                             */
-/* ======================================================================= */
-
-VideoFrameScheduler2::VideoFrameScheduler2() : VideoFrameSchedulerBase() {
-
-    getVsyncOffset(&mAppVsyncOffset, &mSfVsyncOffset);
-
-    Mutex::Autolock threadLock(mLock);
-    mChoreographerThread = new ChoreographerThread(true);
-
-    mVsyncTracker = new VsyncTracker();
-    if (mChoreographerThread->init(static_cast<void*>(mVsyncTracker.get())) != OK) {
-        mChoreographerThread.clear();
-    }
-    if (mChoreographerThread != NULL && mChoreographerThread->run("Choreographer") != OK) {
-        mChoreographerThread.clear();
-    }
-}
-
-void VideoFrameScheduler2::updateVsync() {
-    mVsyncTime = 0;
-    mVsyncPeriod = 0;
-
-    if (mVsyncTracker != NULL) {
-        mVsyncPeriod = mVsyncTracker->getVsyncPeriod();
-        mVsyncTime = mVsyncTracker->getVsyncTime(mSfVsyncOffset - mAppVsyncOffset);
-    }
-    mVsyncRefreshAt = systemTime(SYSTEM_TIME_MONOTONIC) + kVsyncRefreshPeriod;
-}
-
-void VideoFrameScheduler2::release() {
-    // Do not change order
-    {
-        Mutex::Autolock threadLock(mLock);
-        mChoreographerThread->requestExitAndWait();
-        mChoreographerThread.clear();
-    }
-
-    mVsyncTracker.clear();
-}
-
-VideoFrameScheduler2::~VideoFrameScheduler2() {
-    release();
-}
-
-} // namespace android
diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
index cf91405..4711315 100644
--- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp
+++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
@@ -31,9 +31,14 @@
 
 namespace android {
 
-static int ALIGN(int x, int y) {
-    // y must be a power of 2.
-    return (x + y - 1) & ~(y - 1);
+inline void initDstYUV(
+        const android_ycbcr &ycbcr, int32_t cropTop, int32_t cropLeft,
+        uint8_t **dst_y, uint8_t **dst_u, uint8_t **dst_v) {
+    *dst_y = (uint8_t *)ycbcr.y + cropTop * ycbcr.ystride + cropLeft;
+
+    int32_t c_offset = (cropTop / 2) * ycbcr.cstride + cropLeft / 2;
+    *dst_v = (uint8_t *)ycbcr.cr + c_offset;
+    *dst_u = (uint8_t *)ycbcr.cb + c_offset;
 }
 
 SoftwareRenderer::SoftwareRenderer(
@@ -300,20 +305,14 @@
         const uint8_t *src_u = (const uint8_t *)data + mStride * mHeight + mCropTop * mStride / 4;
         const uint8_t *src_v = (const uint8_t *)src_u + mStride * mHeight / 4;
 
-        uint8_t *dst_y = (uint8_t *)ycbcr.y;
-        uint8_t *dst_v = (uint8_t *)ycbcr.cr;
-        uint8_t *dst_u = (uint8_t *)ycbcr.cb;
-        size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
-
-        dst_y += mCropTop * buf->stride + mCropLeft;
-        dst_v += (mCropTop/2) * dst_c_stride + mCropLeft/2;
-        dst_u += (mCropTop/2) * dst_c_stride + mCropLeft/2;
+        uint8_t *dst_y, *dst_u, *dst_v;
+        initDstYUV(ycbcr, mCropTop, mCropLeft, &dst_y, &dst_u, &dst_v);
 
         for (int y = 0; y < mCropHeight; ++y) {
             memcpy(dst_y, src_y, mCropWidth);
 
             src_y += mStride;
-            dst_y += buf->stride;
+            dst_y += ycbcr.ystride;
         }
 
         for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
@@ -322,22 +321,16 @@
 
             src_u += mStride / 2;
             src_v += mStride / 2;
-            dst_u += dst_c_stride;
-            dst_v += dst_c_stride;
+            dst_u += ycbcr.cstride;
+            dst_v += ycbcr.cstride;
         }
     } else if (mColorFormat == OMX_COLOR_FormatYUV420Planar16) {
         const uint8_t *src_y = (const uint8_t *)data + mCropTop * mStride + mCropLeft * 2;
         const uint8_t *src_u = (const uint8_t *)data + mStride * mHeight + mCropTop * mStride / 4;
         const uint8_t *src_v = (const uint8_t *)src_u + mStride * mHeight / 4;
 
-        uint8_t *dst_y = (uint8_t *)ycbcr.y;
-        uint8_t *dst_v = (uint8_t *)ycbcr.cr;
-        uint8_t *dst_u = (uint8_t *)ycbcr.cb;
-        size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
-
-        dst_y += mCropTop * buf->stride + mCropLeft;
-        dst_v += (mCropTop / 2) * dst_c_stride + mCropLeft / 2;
-        dst_u += (mCropTop / 2) * dst_c_stride + mCropLeft / 2;
+        uint8_t *dst_y, *dst_u, *dst_v;
+        initDstYUV(ycbcr, mCropTop, mCropLeft, &dst_y, &dst_u, &dst_v);
 
         for (int y = 0; y < mCropHeight; ++y) {
             for (int x = 0; x < mCropWidth; ++x) {
@@ -345,7 +338,7 @@
             }
 
             src_y += mStride;
-            dst_y += buf->stride;
+            dst_y += ycbcr.ystride;
         }
 
         for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
@@ -356,8 +349,8 @@
 
             src_u += mStride / 2;
             src_v += mStride / 2;
-            dst_u += dst_c_stride;
-            dst_v += dst_c_stride;
+            dst_u += ycbcr.cstride;
+            dst_v += ycbcr.cstride;
         }
     } else if (mColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
             || mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
@@ -368,20 +361,14 @@
         src_y += mCropLeft + mCropTop * mWidth;
         src_uv += (mCropLeft + mCropTop * mWidth) / 2;
 
-        uint8_t *dst_y = (uint8_t *)ycbcr.y;
-        uint8_t *dst_v = (uint8_t *)ycbcr.cr;
-        uint8_t *dst_u = (uint8_t *)ycbcr.cb;
-        size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
-
-        dst_y += mCropTop * buf->stride + mCropLeft;
-        dst_v += (mCropTop/2) * dst_c_stride + mCropLeft/2;
-        dst_u += (mCropTop/2) * dst_c_stride + mCropLeft/2;
+        uint8_t *dst_y, *dst_u, *dst_v;
+        initDstYUV(ycbcr, mCropTop, mCropLeft, &dst_y, &dst_u, &dst_v);
 
         for (int y = 0; y < mCropHeight; ++y) {
             memcpy(dst_y, src_y, mCropWidth);
 
             src_y += mWidth;
-            dst_y += buf->stride;
+            dst_y += ycbcr.ystride;
         }
 
         for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
@@ -392,8 +379,8 @@
             }
 
             src_uv += mWidth;
-            dst_u += dst_c_stride;
-            dst_v += dst_c_stride;
+            dst_u += ycbcr.cstride;
+            dst_v += ycbcr.cstride;
         }
     } else if (mColorFormat == OMX_COLOR_Format24bitRGB888) {
         uint8_t* srcPtr = (uint8_t*)data + mWidth * mCropTop * 3 + mCropLeft * 3;
diff --git a/media/libstagefright/timedtext/Android.bp b/media/libstagefright/timedtext/Android.bp
index 6935655..4f4ceb1 100644
--- a/media/libstagefright/timedtext/Android.bp
+++ b/media/libstagefright/timedtext/Android.bp
@@ -23,32 +23,4 @@
     shared_libs: ["libmedia"],
 }
 
-cc_library_static {
-    name: "libstagefright_timedtext2",
 
-    srcs: ["TextDescriptions2.cpp"],
-
-    static_libs: [
-        "libmediaplayer2-protos",
-        "libprotobuf-cpp-lite",
-    ],
-
-    cflags: [
-        "-Wno-multichar",
-        "-Werror",
-        "-Wall",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-        ],
-        cfi: true,
-    },
-
-    include_dirs: [
-        "frameworks/av/media/libstagefright",
-    ],
-
-    shared_libs: ["libmedia"],
-}
diff --git a/media/libstagefright/timedtext/TextDescriptions2.cpp b/media/libstagefright/timedtext/TextDescriptions2.cpp
deleted file mode 100644
index f48eacc..0000000
--- a/media/libstagefright/timedtext/TextDescriptions2.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#include "TextDescriptions2.h"
-#include <media/stagefright/foundation/ByteUtils.h>
-#include <media/stagefright/MediaErrors.h>
-
-namespace android {
-
-TextDescriptions2::TextDescriptions2() {
-}
-
-status_t TextDescriptions2::getPlayerMessageOfDescriptions(
-        const uint8_t *data, ssize_t size,
-        uint32_t flags, int timeMs, PlayerMessage *playerMsg) {
-    if (flags & IN_BAND_TEXT_3GPP) {
-        if (flags & GLOBAL_DESCRIPTIONS) {
-            return extract3GPPGlobalDescriptions(data, size, playerMsg);
-        } else if (flags & LOCAL_DESCRIPTIONS) {
-            return extract3GPPLocalDescriptions(data, size, timeMs, playerMsg);
-        }
-    } else if (flags & OUT_OF_BAND_TEXT_SRT) {
-        if (flags & LOCAL_DESCRIPTIONS) {
-            return extractSRTLocalDescriptions(data, size, timeMs, playerMsg);
-        }
-    }
-
-    return ERROR_UNSUPPORTED;
-}
-
-// Parse the SRT text sample, and store the timing and text sample in a PlayerMessage.
-// The PlayerMessage will be sent to MediaPlayer2.java through event, and will be
-// parsed in TimedText.java.
-status_t TextDescriptions2::extractSRTLocalDescriptions(
-        const uint8_t *data, ssize_t size, int timeMs, PlayerMessage *playerMsg) {
-    playerMsg->add_values()->set_int32_value(KEY_LOCAL_SETTING);
-    playerMsg->add_values()->set_int32_value(KEY_START_TIME);
-    playerMsg->add_values()->set_int32_value(timeMs);
-
-    playerMsg->add_values()->set_int32_value(KEY_STRUCT_TEXT);
-    playerMsg->add_values()->set_bytes_value(data, size);
-
-    return OK;
-}
-
-// Extract the local 3GPP display descriptions. 3GPP local descriptions
-// are appended to the text sample if any.
-status_t TextDescriptions2::extract3GPPLocalDescriptions(
-        const uint8_t *data, ssize_t size,
-        int timeMs, PlayerMessage *playerMsg) {
-
-    playerMsg->add_values()->set_int32_value(KEY_LOCAL_SETTING);
-
-    // write start time to display this text sample
-    playerMsg->add_values()->set_int32_value(KEY_START_TIME);
-    playerMsg->add_values()->set_int32_value(timeMs);
-
-    if (size < 2) {
-        return OK;
-    }
-    ssize_t textLen = (*data) << 8 | (*(data + 1));
-
-    if (size < textLen + 2) {
-        return OK;
-    }
-
-    // write text sample length and text sample itself
-    playerMsg->add_values()->set_int32_value(KEY_STRUCT_TEXT);
-    playerMsg->add_values()->set_bytes_value(data + 2, textLen);
-
-    if (size > textLen + 2) {
-        data += (textLen + 2);
-        size -= (textLen + 2);
-    } else {
-        return OK;
-    }
-
-    while (size >= 8) {
-        const uint8_t *tmpData = data;
-        ssize_t chunkSize = U32_AT(tmpData);      // size includes size and type
-        uint32_t chunkType = U32_AT(tmpData + 4);
-
-        if (chunkSize <= 8 || chunkSize > size) {
-            return OK;
-        }
-
-        size_t remaining = chunkSize - 8;
-
-        tmpData += 8;
-
-        switch(chunkType) {
-            // 'tbox' box to indicate the position of the text with values
-            // of top, left, bottom and right
-            case FOURCC('t', 'b', 'o', 'x'):
-            {
-                if (remaining < 8) {
-                    return OK;
-                }
-                playerMsg->add_values()->set_int32_value(KEY_STRUCT_TEXT_POS);
-                playerMsg->add_values()->set_int32_value(U16_AT(tmpData));
-                playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 2));
-                playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 4));
-                playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 6));
-
-                tmpData += 8;
-                remaining -= 8;
-                break;
-            }
-            default:
-            {
-                break;
-            }
-        }
-
-        data += chunkSize;
-        size -= chunkSize;
-    }
-
-    return OK;
-}
-
-// To extract box 'tx3g' defined in 3GPP TS 26.245, and store it in a PlayerMessage
-status_t TextDescriptions2::extract3GPPGlobalDescriptions(
-        const uint8_t *data, ssize_t size, PlayerMessage *playerMsg) {
-
-    playerMsg->add_values()->set_int32_value(KEY_GLOBAL_SETTING);
-
-    while (size >= 8) {
-        ssize_t chunkSize = U32_AT(data);
-        uint32_t chunkType = U32_AT(data + 4);
-        const uint8_t *tmpData = data;
-        tmpData += 8;
-        size_t remaining = size - 8;
-
-        if (size < chunkSize) {
-            return OK;
-        }
-        switch(chunkType) {
-            case FOURCC('t', 'x', '3', 'g'):
-            {
-                if (remaining < 18) {
-                    return OK;
-                }
-                // Skip DISPLAY_FLAGS, STRUCT_JUSTIFICATION, and BACKGROUND_COLOR_RGBA
-                tmpData += 18;
-                remaining -= 18;
-
-                if (remaining < 8) {
-                    return OK;
-                }
-                playerMsg->add_values()->set_int32_value(KEY_STRUCT_TEXT_POS);
-                playerMsg->add_values()->set_int32_value(U16_AT(tmpData));
-                playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 2));
-                playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 4));
-                playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 6));
-
-                tmpData += 8;
-                remaining -= 18;
-                // Ignore remaining data.
-                break;
-            }
-            default:
-            {
-                break;
-            }
-        }
-
-        data += chunkSize;
-        size -= chunkSize;
-    }
-
-    return OK;
-}
-
-}  // namespace android
diff --git a/media/libstagefright/timedtext/TextDescriptions2.h b/media/libstagefright/timedtext/TextDescriptions2.h
deleted file mode 100644
index 7c7d2d0..0000000
--- a/media/libstagefright/timedtext/TextDescriptions2.h
+++ /dev/null
@@ -1,88 +0,0 @@
- /*
- * Copyright (C) 2018 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.
- */
-
-#ifndef TEXT_DESCRIPTIONS2_H_
-
-#define TEXT_DESCRIPTIONS2_H_
-
-#include <binder/Parcel.h>
-#include <media/stagefright/foundation/ABase.h>
-
-#include "mediaplayer2.pb.h"
-
-using android::media::MediaPlayer2Proto::PlayerMessage;
-
-namespace android {
-
-class TextDescriptions2 {
-public:
-    enum {
-        IN_BAND_TEXT_3GPP             = 0x01,
-        OUT_OF_BAND_TEXT_SRT          = 0x02,
-
-        GLOBAL_DESCRIPTIONS           = 0x100,
-        LOCAL_DESCRIPTIONS            = 0x200,
-    };
-
-    static status_t getPlayerMessageOfDescriptions(
-            const uint8_t *data, ssize_t size,
-            uint32_t flags, int timeMs, PlayerMessage *playerMsg);
-private:
-    TextDescriptions2();
-
-    enum {
-        // These keys must be in sync with the keys in TimedText.java
-        KEY_DISPLAY_FLAGS                 = 1, // int
-        KEY_STYLE_FLAGS                   = 2, // int
-        KEY_BACKGROUND_COLOR_RGBA         = 3, // int
-        KEY_HIGHLIGHT_COLOR_RGBA          = 4, // int
-        KEY_SCROLL_DELAY                  = 5, // int
-        KEY_WRAP_TEXT                     = 6, // int
-        KEY_START_TIME                    = 7, // int
-        KEY_STRUCT_BLINKING_TEXT_LIST     = 8, // List<CharPos>
-        KEY_STRUCT_FONT_LIST              = 9, // List<Font>
-        KEY_STRUCT_HIGHLIGHT_LIST         = 10, // List<CharPos>
-        KEY_STRUCT_HYPER_TEXT_LIST        = 11, // List<HyperText>
-        KEY_STRUCT_KARAOKE_LIST           = 12, // List<Karaoke>
-        KEY_STRUCT_STYLE_LIST             = 13, // List<Style>
-        KEY_STRUCT_TEXT_POS               = 14, // TextPos
-        KEY_STRUCT_JUSTIFICATION          = 15, // Justification
-        KEY_STRUCT_TEXT                   = 16, // Text
-
-        KEY_GLOBAL_SETTING                = 101,
-        KEY_LOCAL_SETTING                 = 102,
-        KEY_START_CHAR                    = 103,
-        KEY_END_CHAR                      = 104,
-        KEY_FONT_ID                       = 105,
-        KEY_FONT_SIZE                     = 106,
-        KEY_TEXT_COLOR_RGBA               = 107,
-    };
-
-    static status_t extractSRTLocalDescriptions(
-            const uint8_t *data, ssize_t size,
-            int timeMs, PlayerMessage *playerMsg);
-    static status_t extract3GPPGlobalDescriptions(
-            const uint8_t *data, ssize_t size,
-            PlayerMessage *playerMsg);
-    static status_t extract3GPPLocalDescriptions(
-            const uint8_t *data, ssize_t size,
-            int timeMs, PlayerMessage *playerMsg);
-
-    DISALLOW_EVIL_CONSTRUCTORS(TextDescriptions2);
-};
-
-}  // namespace android
-#endif  // TEXT_DESCRIPTIONS2_H_
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index a3cabd8..78c8df5 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -90,7 +90,6 @@
         "libhidlbase",
         "libgui",
         "libui",
-        "libmedia2_jni_core",
         "libmediandk_utils",
     ],
 
diff --git a/media/ndk/NdkMediaCodec.cpp b/media/ndk/NdkMediaCodec.cpp
index c23f19b..51b516a 100644
--- a/media/ndk/NdkMediaCodec.cpp
+++ b/media/ndk/NdkMediaCodec.cpp
@@ -244,8 +244,8 @@
                          ALOGE("CB_ERROR: err is expected.");
                          break;
                      }
-                     if (!msg->findInt32("action", &actionCode)) {
-                         ALOGE("CB_ERROR: action is expected.");
+                     if (!msg->findInt32("actionCode", &actionCode)) {
+                         ALOGE("CB_ERROR: actionCode is expected.");
                          break;
                      }
                      msg->findString("detail", &detail);
diff --git a/media/ndk/NdkMediaDataSource.cpp b/media/ndk/NdkMediaDataSource.cpp
index 7979c2f..e567613 100644
--- a/media/ndk/NdkMediaDataSource.cpp
+++ b/media/ndk/NdkMediaDataSource.cpp
@@ -33,8 +33,6 @@
 #include <media/NdkMediaDataSource.h>
 #include <media/stagefright/DataSourceFactory.h>
 #include <media/stagefright/InterfaceUtils.h>
-#include <mediaplayer2/JavaVMHelper.h>
-#include <mediaplayer2/JMedia2HTTPService.h>
 
 #include "../../libstagefright/include/HTTPBase.h"
 #include "../../libstagefright/include/NuCachedSource2.h"
@@ -120,18 +118,11 @@
     return size >= 0 ? OK : UNKNOWN_ERROR;
 }
 
-static sp<MediaHTTPService> createMediaHttpServiceFromJavaObj(JNIEnv *env, jobject obj, int version) {
+static sp<MediaHTTPService> createMediaHttpServiceFromJavaObj(JNIEnv *env, jobject obj) {
     if (obj == NULL) {
         return NULL;
     }
-    switch (version) {
-        case 1:
-            return interface_cast<IMediaHTTPService>(ibinderForJavaObject(env, obj));
-        case 2:
-            return new JMedia2HTTPService(env, obj);
-        default:
-            return NULL;
-    }
+    return interface_cast<IMediaHTTPService>(ibinderForJavaObject(env, obj));
 }
 
 static sp<MediaHTTPService> createMediaHttpServiceTemplate(
@@ -139,8 +130,7 @@
         const char *uri,
         const char *clazz,
         const char *method,
-        const char *signature,
-        int version) {
+        const char *signature) {
     jobject service = NULL;
     if (env == NULL) {
         ALOGE("http service must be created from Java thread");
@@ -167,34 +157,22 @@
     env->DeleteLocalRef(juri);
 
     env->ExceptionClear();
-    sp<MediaHTTPService> httpService = createMediaHttpServiceFromJavaObj(env, service, version);
+    sp<MediaHTTPService> httpService = createMediaHttpServiceFromJavaObj(env, service);
     return httpService;
 
 }
 
-sp<MediaHTTPService> createMediaHttpService(const char *uri, int version) {
+sp<MediaHTTPService> createMediaHttpService(const char *uri) {
 
     JNIEnv *env;
     const char *clazz, *method, *signature;
 
-    switch (version) {
-        case 1:
-            env = AndroidRuntime::getJNIEnv();
-            clazz = "android/media/MediaHTTPService";
-            method = "createHttpServiceBinderIfNecessary";
-            signature = "(Ljava/lang/String;)Landroid/os/IBinder;";
-            break;
-        case 2:
-            env = JavaVMHelper::getJNIEnv();
-            clazz = "android/media/Media2HTTPService";
-            method = "createHTTPService";
-            signature = "(Ljava/lang/String;)Landroid/media/Media2HTTPService;";
-            break;
-        default:
-            return NULL;
-    }
+    env = AndroidRuntime::getJNIEnv();
+    clazz = "android/media/MediaHTTPService";
+    method = "createHttpServiceBinderIfNecessary";
+    signature = "(Ljava/lang/String;)Landroid/os/IBinder;";
 
-    return createMediaHttpServiceTemplate(env, uri, clazz, method, signature, version);
+    return createMediaHttpServiceTemplate(env, uri, clazz, method, signature);
 
 }
 
@@ -216,7 +194,7 @@
         int numheaders,
         const char * const *key_values) {
 
-    sp<MediaHTTPService> service = createMediaHttpService(uri, /* version = */ 1);
+    sp<MediaHTTPService> service = createMediaHttpService(uri);
     KeyedVector<String8, String8> headers;
     for (int i = 0; i < numheaders; ++i) {
         String8 key8(key_values[i * 2]);
diff --git a/media/ndk/NdkMediaDataSourcePriv.h b/media/ndk/NdkMediaDataSourcePriv.h
index 16ff974..ddcd7da 100644
--- a/media/ndk/NdkMediaDataSourcePriv.h
+++ b/media/ndk/NdkMediaDataSourcePriv.h
@@ -62,7 +62,7 @@
 
 };
 
-sp<MediaHTTPService> createMediaHttpService(const char *uri, int version);
+sp<MediaHTTPService> createMediaHttpService(const char *uri);
 
 #endif // _NDK_MEDIA_DATASOURCE_PRIV_H
 
diff --git a/media/ndk/NdkMediaExtractor.cpp b/media/ndk/NdkMediaExtractor.cpp
index c83b255..0da0740 100644
--- a/media/ndk/NdkMediaExtractor.cpp
+++ b/media/ndk/NdkMediaExtractor.cpp
@@ -89,7 +89,7 @@
 
     ALOGV("setDataSource(%s)", uri);
 
-    sp<MediaHTTPService> httpService = createMediaHttpService(uri, /* version = */ 1);
+    sp<MediaHTTPService> httpService = createMediaHttpService(uri);
     if (httpService == NULL) {
         ALOGE("can't create http service");
         return AMEDIA_ERROR_UNSUPPORTED;
diff --git a/media/tests/benchmark/README.md b/media/tests/benchmark/README.md
index 0acfab8..8db3fd3 100644
--- a/media/tests/benchmark/README.md
+++ b/media/tests/benchmark/README.md
@@ -48,3 +48,13 @@
 ```
 adb shell /data/local/tmp/muxerTest -P /sdcard/res/
 ```
+
+## Encoder
+
+The test encodes input stream and benchmarks the encoders available in NDK.
+
+Setup steps are same as extractor.
+
+```
+adb shell /data/local/tmp/encoderTest -P /sdcard/res/
+```
diff --git a/media/tests/benchmark/src/native/common/Android.bp b/media/tests/benchmark/src/native/common/Android.bp
index 64ea1ee..527f588 100644
--- a/media/tests/benchmark/src/native/common/Android.bp
+++ b/media/tests/benchmark/src/native/common/Android.bp
@@ -23,7 +23,7 @@
 
     srcs: [
         "BenchmarkCommon.cpp",
-        "Timer.cpp",
+        "Stats.cpp",
     ],
 
     export_include_dirs: ["."],
diff --git a/media/tests/benchmark/src/native/common/BenchmarkCommon.cpp b/media/tests/benchmark/src/native/common/BenchmarkCommon.cpp
index bbc8790..5bdb48a 100644
--- a/media/tests/benchmark/src/native/common/BenchmarkCommon.cpp
+++ b/media/tests/benchmark/src/native/common/BenchmarkCommon.cpp
@@ -31,7 +31,7 @@
 void OnInputAvailableCB(AMediaCodec *codec, void *userdata, int32_t index) {
     ALOGV("OnInputAvailableCB: index(%d)", index);
     CallBackHandle *self = (CallBackHandle *)userdata;
-    self->getTimer()->addInputTime();
+    self->getStats()->addInputTime();
     self->mIOQueue.push([self, codec, index]() { self->onInputAvailable(codec, index); });
 }
 
@@ -40,7 +40,7 @@
     ALOGV("OnOutputAvailableCB: index(%d), (%d, %d, %lld, 0x%x)", index, bufferInfo->offset,
           bufferInfo->size, (long long)bufferInfo->presentationTimeUs, bufferInfo->flags);
     CallBackHandle *self = (CallBackHandle *)userdata;
-    self->getTimer()->addOutputTime();
+    self->getStats()->addOutputTime();
     AMediaCodecBufferInfo bufferInfoCopy = *bufferInfo;
     self->mIOQueue.push([self, codec, index, bufferInfoCopy]() {
         AMediaCodecBufferInfo bc = bufferInfoCopy;
diff --git a/media/tests/benchmark/src/native/common/BenchmarkCommon.h b/media/tests/benchmark/src/native/common/BenchmarkCommon.h
index 7b87c04..df16baf 100644
--- a/media/tests/benchmark/src/native/common/BenchmarkCommon.h
+++ b/media/tests/benchmark/src/native/common/BenchmarkCommon.h
@@ -27,7 +27,7 @@
 #include <media/NdkMediaCodec.h>
 #include <media/NdkMediaError.h>
 
-#include "Timer.h"
+#include "Stats.h"
 
 using namespace std;
 
@@ -69,11 +69,13 @@
 
 class CallBackHandle {
   public:
-    CallBackHandle() : mSawError(false), mIsDone(false), mTimer(nullptr) {}
+    CallBackHandle() : mSawError(false), mIsDone(false), mStats(nullptr) {
+        mStats = new Stats();
+    }
 
     virtual ~CallBackHandle() {
         if (mIOThread.joinable()) mIOThread.join();
-        if (mTimer) delete mTimer;
+        if (mStats) delete mStats;
     }
 
     void ioThread();
@@ -94,7 +96,7 @@
         (void)bufferInfo;
     }
 
-    virtual Timer *getTimer() { return mTimer; }
+    Stats *getStats() { return mStats; }
 
     // Keep a queue of all function callbacks.
     typedef function<void()> IOTask;
@@ -103,8 +105,8 @@
     bool mSawError;
     bool mIsDone;
 
-  private:
-    Timer *mTimer;
+  protected:
+    Stats *mStats;
 };
 
 // Async API's callback
diff --git a/media/tests/benchmark/src/native/common/Timer.cpp b/media/tests/benchmark/src/native/common/Stats.cpp
similarity index 90%
rename from media/tests/benchmark/src/native/common/Timer.cpp
rename to media/tests/benchmark/src/native/common/Stats.cpp
index 0487123..6bcd3ce 100644
--- a/media/tests/benchmark/src/native/common/Timer.cpp
+++ b/media/tests/benchmark/src/native/common/Stats.cpp
@@ -15,13 +15,13 @@
  */
 
 //#define LOG_NDEBUG 0
-#define LOG_TAG "Timer"
+#define LOG_TAG "Stats"
 
 #include <iostream>
 #include <stdint.h>
 #include <utils/Log.h>
 
-#include "Timer.h"
+#include "Stats.h"
 
 /**
  * Dumps the stats of the operation for a given input media.
@@ -31,7 +31,7 @@
  * \param inputReference input media
  * \param duarationUs    is a duration of the input media in microseconds.
  */
-void Timer::dumpStatistics(std::string operation, std::string inputReference, int64_t duarationUs) {
+void Stats::dumpStatistics(std::string operation, std::string inputReference, int64_t duarationUs) {
     ALOGV("In %s", __func__);
     if (!mOutputTimer.size()) {
         ALOGE("No output produced");
@@ -40,6 +40,7 @@
     nsecs_t totalTimeTakenNs = getTotalTime();
     nsecs_t timeTakenPerSec = (totalTimeTakenNs * 1000000) / duarationUs;
     nsecs_t timeToFirstFrameNs = *mOutputTimer.begin() - mStartTimeNs;
+    int32_t size = std::accumulate(mFrameSizes.begin(), mFrameSizes.end(), 0);
     // get min and max output intervals.
     nsecs_t intervalNs;
     nsecs_t minTimeTakenNs = INT64_MAX;
@@ -59,6 +60,7 @@
     std::cout << "Time to first frame in nano sec : " << timeToFirstFrameNs << endl;
     std::cout << "Time taken (in nano sec) to " << operation
               << " 1 sec of content : " << timeTakenPerSec << endl;
+    std::cout << "Total bytes " << operation << "ed : " << size << endl;
     std::cout << "Minimum Time in nano sec : " << minTimeTakenNs << endl;
     std::cout << "Maximum Time in nano sec : " << maxTimeTakenNs << endl;
     std::cout << "Destroy Time in nano sec : " << mDeInitTimeNs << endl;
diff --git a/media/tests/benchmark/src/native/common/Timer.h b/media/tests/benchmark/src/native/common/Stats.h
similarity index 86%
rename from media/tests/benchmark/src/native/common/Timer.h
rename to media/tests/benchmark/src/native/common/Stats.h
index 92af86f..024319a 100644
--- a/media/tests/benchmark/src/native/common/Timer.h
+++ b/media/tests/benchmark/src/native/common/Stats.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef __TIMER_H__
-#define __TIMER_H__
+#ifndef __STATS_H__
+#define __STATS_H__
 
 #include <sys/time.h>
 #include <algorithm>
@@ -25,22 +25,22 @@
 
 using namespace std;
 
-class Timer {
+class Stats {
   public:
-    Timer() {
+    Stats() {
         mInitTimeNs = 0;
         mDeInitTimeNs = 0;
     }
 
-    ~Timer() {
-        if (!mInputTimer.empty()) mInputTimer.clear();
-        if (!mOutputTimer.empty()) mOutputTimer.clear();
+    ~Stats() {
+        reset();
     }
 
   private:
     nsecs_t mInitTimeNs;
     nsecs_t mDeInitTimeNs;
     nsecs_t mStartTimeNs;
+    std::vector<int32_t> mFrameSizes;
     std::vector<nsecs_t> mInputTimer;
     std::vector<nsecs_t> mOutputTimer;
 
@@ -53,11 +53,14 @@
 
     void setStartTime() { mStartTimeNs = systemTime(CLOCK_MONOTONIC); }
 
+    void addFrameSize(int32_t size) { mFrameSizes.push_back(size); }
+
     void addInputTime() { mInputTimer.push_back(systemTime(CLOCK_MONOTONIC)); }
 
     void addOutputTime() { mOutputTimer.push_back(systemTime(CLOCK_MONOTONIC)); }
 
-    void resetTimers() {
+    void reset() {
+        if (!mFrameSizes.empty()) mFrameSizes.clear();
         if (!mInputTimer.empty()) mInputTimer.clear();
         if (!mOutputTimer.empty()) mOutputTimer.clear();
     }
@@ -78,4 +81,4 @@
     void dumpStatistics(std::string operation, std::string inputReference, int64_t duarationUs);
 };
 
-#endif  // __TIMER_H__
+#endif  // __STATS_H__
diff --git a/media/tests/benchmark/src/native/decoder/Decoder.cpp b/media/tests/benchmark/src/native/decoder/Decoder.cpp
index 21fc420..ef84537 100644
--- a/media/tests/benchmark/src/native/decoder/Decoder.cpp
+++ b/media/tests/benchmark/src/native/decoder/Decoder.cpp
@@ -81,6 +81,7 @@
             mDecoderDoneCondition.notify_one();
             return;
         }
+        mStats->addFrameSize(bytesRead);
         mNumInputFrame++;
     }
 }
@@ -96,6 +97,15 @@
             return;
         }
 
+        if (mOutFp != nullptr) {
+            size_t bufSize;
+            uint8_t *buf = AMediaCodec_getOutputBuffer(mCodec, bufIdx, &bufSize);
+            if (buf) {
+                fwrite(buf, sizeof(char), bufferInfo->size, mOutFp);
+                ALOGV("bytes written into file  %d\n", bufferInfo->size);
+            }
+        }
+
         AMediaCodec_releaseOutputBuffer(mCodec, bufIdx, false);
         mSawOutputEOS = (0 != (bufferInfo->flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM));
         mNumOutputFrame++;
@@ -119,21 +129,21 @@
 
 void Decoder::setupDecoder() {
     if (!mFormat) mFormat = mExtractor->getFormat();
-    if (!mTimer) mTimer = new Timer();
 }
 
 int32_t Decoder::decode(uint8_t *inputBuffer, vector<AMediaCodecBufferInfo> &frameInfo,
-                        string &codecName, bool asyncMode) {
+                        string &codecName, bool asyncMode, FILE *outFp) {
     ALOGV("In %s", __func__);
     mInputBuffer = inputBuffer;
     mFrameMetaData = frameInfo;
     mOffset = 0;
+    mOutFp = outFp;
 
     const char *mime = nullptr;
     AMediaFormat_getString(mFormat, AMEDIAFORMAT_KEY_MIME, &mime);
     if (!mime) return AMEDIA_ERROR_INVALID_OBJECT;
 
-    int64_t sTime = mTimer->getCurTime();
+    int64_t sTime = mStats->getCurTime();
     mCodec = createMediaCodec(mFormat, mime, codecName, false /*isEncoder*/);
     if (!mCodec) return AMEDIA_ERROR_INVALID_OBJECT;
 
@@ -142,16 +152,15 @@
                                                 OnFormatChangedCB, OnErrorCB};
         AMediaCodec_setAsyncNotifyCallback(mCodec, aCB, this);
 
-        CallBackHandle *callbackHandle = new CallBackHandle();
-        callbackHandle->mIOThread = thread(&CallBackHandle::ioThread, this);
+        mIOThread = thread(&CallBackHandle::ioThread, this);
     }
 
     AMediaCodec_start(mCodec);
-    int64_t eTime = mTimer->getCurTime();
-    int64_t timeTaken = mTimer->getTimeDiff(sTime, eTime);
-    mTimer->setInitTime(timeTaken);
+    int64_t eTime = mStats->getCurTime();
+    int64_t timeTaken = mStats->getTimeDiff(sTime, eTime);
+    mStats->setInitTime(timeTaken);
 
-    mTimer->setStartTime();
+    mStats->setStartTime();
     if (!asyncMode) {
         while (!mSawOutputEOS && !mSignalledError) {
             /* Queue input data */
@@ -161,7 +170,7 @@
                     ALOGE("AMediaCodec_dequeueInputBuffer returned invalid index %zd\n", inIdx);
                     return AMEDIA_ERROR_IO;
                 } else if (inIdx >= 0) {
-                    mTimer->addInputTime();
+                    mStats->addInputTime();
                     onInputAvailable(mCodec, inIdx);
                 }
             }
@@ -174,7 +183,7 @@
                 const char *s = AMediaFormat_toString(mFormat);
                 ALOGI("Output format: %s\n", s);
             } else if (outIdx >= 0) {
-                mTimer->addOutputTime();
+                mStats->addOutputTime();
                 onOutputAvailable(mCodec, outIdx, &info);
             } else if (!(outIdx == AMEDIACODEC_INFO_TRY_AGAIN_LATER ||
                          outIdx == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED)) {
@@ -197,7 +206,7 @@
 }
 
 void Decoder::deInitCodec() {
-    int64_t sTime = mTimer->getCurTime();
+    int64_t sTime = mStats->getCurTime();
     if (mFormat) {
         AMediaFormat_delete(mFormat);
         mFormat = nullptr;
@@ -205,19 +214,19 @@
     if (!mCodec) return;
     AMediaCodec_stop(mCodec);
     AMediaCodec_delete(mCodec);
-    int64_t eTime = mTimer->getCurTime();
-    int64_t timeTaken = mTimer->getTimeDiff(sTime, eTime);
-    mTimer->setDeInitTime(timeTaken);
+    int64_t eTime = mStats->getCurTime();
+    int64_t timeTaken = mStats->getTimeDiff(sTime, eTime);
+    mStats->setDeInitTime(timeTaken);
 }
 
 void Decoder::dumpStatistics(string inputReference) {
     int64_t durationUs = mExtractor->getClipDuration();
     string operation = "decode";
-    mTimer->dumpStatistics(operation, inputReference, durationUs);
+    mStats->dumpStatistics(operation, inputReference, durationUs);
 }
 
 void Decoder::resetDecoder() {
-    if (mTimer) mTimer->resetTimers();
+    if (mStats) mStats->reset();
     if (mInputBuffer) mInputBuffer = nullptr;
     if (!mFrameMetaData.empty()) mFrameMetaData.clear();
 }
diff --git a/media/tests/benchmark/src/native/decoder/Decoder.h b/media/tests/benchmark/src/native/decoder/Decoder.h
index 0a64128..7630e7b 100644
--- a/media/tests/benchmark/src/native/decoder/Decoder.h
+++ b/media/tests/benchmark/src/native/decoder/Decoder.h
@@ -25,7 +25,7 @@
 
 #include "BenchmarkCommon.h"
 #include "Extractor.h"
-#include "Timer.h"
+#include "Stats.h"
 
 class Decoder : public CallBackHandle {
   public:
@@ -33,23 +33,20 @@
         : mCodec(nullptr),
           mFormat(nullptr),
           mExtractor(nullptr),
-          mTimer(nullptr),
           mNumInputFrame(0),
           mNumOutputFrame(0),
           mSawInputEOS(false),
           mSawOutputEOS(false),
           mSignalledError(false),
-          mInputBuffer(nullptr) {
+          mInputBuffer(nullptr),
+          mOutFp(nullptr) {
         mExtractor = new Extractor();
     }
 
     virtual ~Decoder() {
-        if (mTimer) delete mTimer;
         if (mExtractor) delete mExtractor;
     }
 
-    Timer *getTimer() override { return mTimer; }
-
     Extractor *getExtractor() { return mExtractor; }
 
     // Decoder related utilities
@@ -69,7 +66,7 @@
 
     // Process the frames and give decoded output
     int32_t decode(uint8_t *inputBuffer, vector<AMediaCodecBufferInfo> &frameInfo,
-                   string &codecName, bool asyncMode);
+                   string &codecName, bool asyncMode, FILE *outFp = nullptr);
 
     void dumpStatistics(string inputReference);
 
@@ -79,8 +76,6 @@
 
     Extractor *mExtractor;
 
-    Timer *mTimer;
-
     int32_t mNumInputFrame;
     int32_t mNumOutputFrame;
 
@@ -91,6 +86,7 @@
     int32_t mOffset;
     uint8_t *mInputBuffer;
     vector<AMediaCodecBufferInfo> mFrameMetaData;
+    FILE *mOutFp;
 
     /* Asynchronous locks */
     mutex mMutex;
diff --git a/media/tests/benchmark/src/native/encoder/Android.bp b/media/tests/benchmark/src/native/encoder/Android.bp
new file mode 100644
index 0000000..c14c319
--- /dev/null
+++ b/media/tests/benchmark/src/native/encoder/Android.bp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+cc_library_static {
+    name: "libbenchmark_encoder",
+    defaults: [
+        "libbenchmark_common-defaults",
+        "libbenchmark_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["Encoder.cpp"],
+
+    static_libs: ["libbenchmark_extractor",
+                  "libbenchmark_decoder",
+    ],
+
+    export_include_dirs: ["."],
+
+    ldflags: ["-Wl,-Bsymbolic"]
+}
diff --git a/media/tests/benchmark/src/native/encoder/Encoder.cpp b/media/tests/benchmark/src/native/encoder/Encoder.cpp
new file mode 100644
index 0000000..5fdf9e3
--- /dev/null
+++ b/media/tests/benchmark/src/native/encoder/Encoder.cpp
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2019 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 "encoder"
+
+#include <fstream>
+
+#include "Encoder.h"
+
+void Encoder::onInputAvailable(AMediaCodec *mediaCodec, int32_t bufIdx) {
+    ALOGV("In %s", __func__);
+    if (mediaCodec == mCodec && mediaCodec) {
+        if (mSawInputEOS || bufIdx < 0) return;
+        if (mSignalledError) {
+            CallBackHandle::mSawError = true;
+            mEncoderDoneCondition.notify_one();
+            return;
+        }
+
+        size_t bufSize = 0;
+        char *buf = (char *)AMediaCodec_getInputBuffer(mCodec, bufIdx, &bufSize);
+        if (!buf) {
+            mSignalledError = true;
+            mEncoderDoneCondition.notify_one();
+            return;
+        }
+
+        if (mInputBufferSize < mOffset) {
+            ALOGE("Out of bound access of input buffer\n");
+            mSignalledError = true;
+            mEncoderDoneCondition.notify_one();
+            return;
+        }
+        size_t bytesRead = mParams.frameSize;
+        if (mInputBufferSize - mOffset < mParams.frameSize) {
+            bytesRead = mInputBufferSize - mOffset;
+        }
+        if (bufSize < bytesRead) {
+            ALOGE("bytes to read %zu bufSize %zu \n", bytesRead, bufSize);
+            mSignalledError = true;
+            mEncoderDoneCondition.notify_one();
+            return;
+        }
+        if (bytesRead < mParams.frameSize && mNumInputFrame < mParams.numFrames - 1) {
+            ALOGE("Partial frame at frameID %d bytesRead %zu frameSize %d total numFrames %d\n",
+                  mNumInputFrame, bytesRead, mParams.frameSize, mParams.numFrames);
+            mSignalledError = true;
+            mEncoderDoneCondition.notify_one();
+            return;
+        }
+        mEleStream->read(buf, bytesRead);
+        size_t bytesgcount = mEleStream->gcount();
+        if (bytesgcount != bytesRead) {
+            ALOGE("bytes to read %zu actual bytes read %zu \n", bytesRead, bytesgcount);
+            mSignalledError = true;
+            mEncoderDoneCondition.notify_one();
+            return;
+        }
+
+        uint32_t flag = 0;
+        if (mNumInputFrame == mParams.numFrames - 1 || bytesRead == 0) {
+            ALOGD("Sending EOS on input Last frame\n");
+            flag |= AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM;
+        }
+
+        uint64_t presentationTimeUs;
+        if (!strncmp(mMime, "video/", 6)) {
+            presentationTimeUs = mNumInputFrame * (1000000 / mParams.frameRate);
+        } else {
+            presentationTimeUs =
+                    (uint64_t)mNumInputFrame * mParams.frameSize * 1000000 / mParams.sampleRate;
+        }
+
+        if (flag == AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) mSawInputEOS = true;
+        ALOGV("%s bytesRead : %zd presentationTimeUs : %" PRIu64 " mSawInputEOS : %s", __FUNCTION__,
+              bytesRead, presentationTimeUs, mSawInputEOS ? "TRUE" : "FALSE");
+
+        int status = AMediaCodec_queueInputBuffer(mCodec, bufIdx, 0 /* offset */, bytesRead,
+                                                  presentationTimeUs, flag);
+        if (AMEDIA_OK != status) {
+            mSignalledError = true;
+            mEncoderDoneCondition.notify_one();
+            return;
+        }
+        mNumInputFrame++;
+        mOffset += bytesRead;
+    }
+}
+
+void Encoder::onOutputAvailable(AMediaCodec *mediaCodec, int32_t bufIdx,
+                                AMediaCodecBufferInfo *bufferInfo) {
+    ALOGV("In %s", __func__);
+    if (mediaCodec == mCodec && mediaCodec) {
+        if (mSawOutputEOS || bufIdx < 0) return;
+        if (mSignalledError) {
+            CallBackHandle::mSawError = true;
+            mEncoderDoneCondition.notify_one();
+            return;
+        }
+
+        mStats->addFrameSize(bufferInfo->size);
+        AMediaCodec_releaseOutputBuffer(mCodec, bufIdx, false);
+        mSawOutputEOS = (0 != (bufferInfo->flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM));
+        mNumOutputFrame++;
+        ALOGV("%s index : %d  mSawOutputEOS : %s count : %u", __FUNCTION__, bufIdx,
+              mSawOutputEOS ? "TRUE" : "FALSE", mNumOutputFrame);
+        if (mSawOutputEOS) {
+            CallBackHandle::mIsDone = true;
+            mEncoderDoneCondition.notify_one();
+        }
+    }
+}
+
+void Encoder::onFormatChanged(AMediaCodec *mediaCodec, AMediaFormat *format) {
+    ALOGV("In %s", __func__);
+    if (mediaCodec == mCodec && mediaCodec) {
+        ALOGV("%s { %s }", __FUNCTION__, AMediaFormat_toString(format));
+        mFormat = format;
+    }
+}
+
+void Encoder::setupEncoder() {
+    if (!mFormat) mFormat = AMediaFormat_new();
+}
+
+void Encoder::deInitCodec() {
+    int64_t sTime = mStats->getCurTime();
+    if (mFormat) {
+        AMediaFormat_delete(mFormat);
+        mFormat = nullptr;
+    }
+    AMediaCodec_stop(mCodec);
+    AMediaCodec_delete(mCodec);
+    int64_t eTime = mStats->getCurTime();
+    int64_t timeTaken = mStats->getTimeDiff(sTime, eTime);
+    mStats->setDeInitTime(timeTaken);
+}
+
+void Encoder::resetEncoder() {
+    if (mStats) mStats->reset();
+    if (mEleStream) mEleStream = nullptr;
+    if (mMime) mMime = nullptr;
+    mInputBufferSize = 0;
+    memset(&mParams, 0, sizeof mParams);
+}
+
+void Encoder::dumpStatistics(string inputReference, int64_t durationUs) {
+    string operation = "encode";
+    mStats->dumpStatistics(operation, inputReference, durationUs);
+}
+
+int32_t Encoder::encode(string &codecName, ifstream &eleStream, size_t eleSize,
+                        bool asyncMode, encParameter encParams, char *mime) {
+    ALOGV("In %s", __func__);
+    mEleStream = &eleStream;
+    mInputBufferSize = eleSize;
+    mParams = encParams;
+    mOffset = 0;
+    mMime = mime;
+    AMediaFormat_setString(mFormat, AMEDIAFORMAT_KEY_MIME, mMime);
+
+    // Set Format
+    if (!strncmp(mMime, "video/", 6)) {
+        AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_WIDTH, mParams.width);
+        AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_HEIGHT, mParams.height);
+        AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_FRAME_RATE, mParams.frameRate);
+        AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_BIT_RATE, mParams.bitrate);
+        AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_I_FRAME_INTERVAL, 1);
+        if (mParams.profile && mParams.level) {
+            AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_PROFILE, mParams.profile);
+            AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_LEVEL, mParams.level);
+        }
+    } else {
+        AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_SAMPLE_RATE, mParams.sampleRate);
+        AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_CHANNEL_COUNT, mParams.numChannels);
+        AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_BIT_RATE, mParams.bitrate);
+    }
+    const char *s = AMediaFormat_toString(mFormat);
+    ALOGV("Input format: %s\n", s);
+
+    int64_t sTime = mStats->getCurTime();
+    mCodec = createMediaCodec(mFormat, mMime, codecName, true /*isEncoder*/);
+    if (!mCodec) return AMEDIA_ERROR_INVALID_OBJECT;
+    int64_t eTime = mStats->getCurTime();
+    int64_t timeTaken = mStats->getTimeDiff(sTime, eTime);
+
+    if (!strncmp(mMime, "video/", 6)) {
+        mParams.frameSize = mParams.width * mParams.height * 3 / 2;
+    } else {
+        mParams.frameSize = 4096;
+        // Get mInputMaxBufSize
+        AMediaFormat *inputFormat = AMediaCodec_getInputFormat(mCodec);
+        AMediaFormat_getInt32(inputFormat, AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, &mParams.maxFrameSize);
+        if (mParams.maxFrameSize < 0) {
+            ALOGE("Invalid mParams.maxFrameSize %d\n", mParams.maxFrameSize);
+            return AMEDIA_ERROR_INVALID_PARAMETER;
+        }
+        if (mParams.frameSize > mParams.maxFrameSize) {
+            mParams.frameSize = mParams.maxFrameSize;
+        }
+    }
+    mParams.numFrames = (mInputBufferSize + mParams.frameSize - 1) / mParams.frameSize;
+
+    sTime = mStats->getCurTime();
+    if (asyncMode) {
+        AMediaCodecOnAsyncNotifyCallback aCB = {OnInputAvailableCB, OnOutputAvailableCB,
+                                                OnFormatChangedCB, OnErrorCB};
+        AMediaCodec_setAsyncNotifyCallback(mCodec, aCB, this);
+        mIOThread = thread(&CallBackHandle::ioThread, this);
+    }
+    AMediaCodec_start(mCodec);
+    eTime = mStats->getCurTime();
+    timeTaken += mStats->getTimeDiff(sTime, eTime);
+    mStats->setInitTime(timeTaken);
+
+    mStats->setStartTime();
+    if (!asyncMode) {
+        while (!mSawOutputEOS && !mSignalledError) {
+            // Queue input data
+            if (!mSawInputEOS) {
+                ssize_t inIdx = AMediaCodec_dequeueInputBuffer(mCodec, kQueueDequeueTimeoutUs);
+                if (inIdx < 0 && inIdx != AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
+                    ALOGE("AMediaCodec_dequeueInputBuffer returned invalid index %zd\n", inIdx);
+                    return AMEDIA_ERROR_IO;
+                } else if (inIdx >= 0) {
+                    mStats->addInputTime();
+                    onInputAvailable(mCodec, inIdx);
+                }
+            }
+
+            // Dequeue output data
+            AMediaCodecBufferInfo info;
+            ssize_t outIdx = AMediaCodec_dequeueOutputBuffer(mCodec, &info, kQueueDequeueTimeoutUs);
+            if (outIdx == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) {
+                mFormat = AMediaCodec_getOutputFormat(mCodec);
+                const char *s = AMediaFormat_toString(mFormat);
+                ALOGI("Output format: %s\n", s);
+            } else if (outIdx >= 0) {
+                mStats->addOutputTime();
+                onOutputAvailable(mCodec, outIdx, &info);
+            } else if (!(outIdx == AMEDIACODEC_INFO_TRY_AGAIN_LATER ||
+                         outIdx == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED)) {
+                ALOGE("AMediaCodec_dequeueOutputBuffer returned invalid index %zd\n", outIdx);
+                return AMEDIA_ERROR_IO;
+            }
+        }
+    } else {
+        unique_lock<mutex> lock(mMutex);
+        mEncoderDoneCondition.wait(lock, [this]() { return (mSawOutputEOS || mSignalledError); });
+    }
+
+    if (codecName.empty()) {
+        char *encName;
+        AMediaCodec_getName(mCodec, &encName);
+        codecName.assign(encName);
+        AMediaCodec_releaseName(mCodec, encName);
+    }
+    return AMEDIA_OK;
+}
diff --git a/media/tests/benchmark/src/native/encoder/Encoder.h b/media/tests/benchmark/src/native/encoder/Encoder.h
new file mode 100644
index 0000000..75d9941
--- /dev/null
+++ b/media/tests/benchmark/src/native/encoder/Encoder.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef __ENCODER_H__
+#define __ENCODER_H__
+
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+#include <queue>
+#include <thread>
+
+#include "BenchmarkCommon.h"
+#include "Stats.h"
+
+struct encParameter {
+    int32_t bitrate = -1;
+    int32_t numFrames = -1;
+    int32_t frameSize = -1;
+    int32_t sampleRate = 0;
+    int32_t numChannels = 0;
+    int32_t maxFrameSize = -1;
+    int32_t width = 0;
+    int32_t height = 0;
+    int32_t frameRate = -1;
+    int32_t profile = 0;
+    int32_t level = 0;
+};
+
+class Encoder : public CallBackHandle {
+  public:
+    Encoder()
+        : mCodec(nullptr),
+          mFormat(nullptr),
+          mNumInputFrame(0),
+          mNumOutputFrame(0),
+          mSawInputEOS(false),
+          mSawOutputEOS(false),
+          mSignalledError(false) {}
+
+    virtual ~Encoder() {}
+
+    // Encoder related utilities
+    void setupEncoder();
+
+    void deInitCodec();
+
+    void resetEncoder();
+
+    // Async callback APIs
+    void onInputAvailable(AMediaCodec *codec, int32_t index) override;
+
+    void onFormatChanged(AMediaCodec *codec, AMediaFormat *format) override;
+
+    void onOutputAvailable(AMediaCodec *codec, int32_t index,
+                           AMediaCodecBufferInfo *bufferInfo) override;
+
+    // Process the frames and give encoded output
+    int32_t encode(std::string &codecName, std::ifstream &eleStream, size_t eleSize, bool asyncMode,
+                   encParameter encParams, char *mime);
+
+    void dumpStatistics(string inputReference, int64_t durationUs);
+
+  private:
+    AMediaCodec *mCodec;
+    AMediaFormat *mFormat;
+
+    int32_t mNumInputFrame;
+    int32_t mNumOutputFrame;
+    bool mSawInputEOS;
+    bool mSawOutputEOS;
+    bool mSignalledError;
+
+    char *mMime;
+    int32_t mOffset;
+    std::ifstream *mEleStream;
+    size_t mInputBufferSize;
+    encParameter mParams;
+
+    // Asynchronous locks
+    std::mutex mMutex;
+    std::condition_variable mEncoderDoneCondition;
+};
+#endif  // __ENCODER_H__
diff --git a/media/tests/benchmark/src/native/extractor/Extractor.cpp b/media/tests/benchmark/src/native/extractor/Extractor.cpp
index 0726ae3..b4cad0b 100644
--- a/media/tests/benchmark/src/native/extractor/Extractor.cpp
+++ b/media/tests/benchmark/src/native/extractor/Extractor.cpp
@@ -22,21 +22,21 @@
 #include "Extractor.h"
 
 int32_t Extractor::initExtractor(int32_t fd, size_t fileSize) {
-    mTimer = new Timer();
+    mStats = new Stats();
 
     mFrameBuf = (uint8_t *)calloc(kMaxBufferSize, sizeof(uint8_t));
     if (!mFrameBuf) return -1;
 
-    int64_t sTime = mTimer->getCurTime();
+    int64_t sTime = mStats->getCurTime();
 
     mExtractor = AMediaExtractor_new();
     if (!mExtractor) return AMEDIACODEC_ERROR_INSUFFICIENT_RESOURCE;
     media_status_t status = AMediaExtractor_setDataSourceFd(mExtractor, fd, 0, fileSize);
     if (status != AMEDIA_OK) return status;
 
-    int64_t eTime = mTimer->getCurTime();
-    int64_t timeTaken = mTimer->getTimeDiff(sTime, eTime);
-    mTimer->setInitTime(timeTaken);
+    int64_t eTime = mStats->getCurTime();
+    int64_t timeTaken = mStats->getTimeDiff(sTime, eTime);
+    mStats->setInitTime(timeTaken);
 
     return AMediaExtractor_getTrackCount(mExtractor);
 }
@@ -52,6 +52,7 @@
     bool csdFound = AMediaFormat_getBuffer(mFormat, csdName, &csdBuffer, &size);
     if (!csdFound) return nullptr;
     frameInfo.size = (int32_t)size;
+    mStats->addFrameSize(frameInfo.size);
 
     return csdBuffer;
 }
@@ -62,6 +63,7 @@
 
     frameInfo.flags = AMediaExtractor_getSampleFlags(mExtractor);
     frameInfo.size = size;
+    mStats->addFrameSize(frameInfo.size);
     frameInfo.presentationTimeUs = AMediaExtractor_getSampleTime(mExtractor);
     AMediaExtractor_advance(mExtractor);
 
@@ -92,11 +94,11 @@
         idx++;
     }
 
-    mTimer->setStartTime();
+    mStats->setStartTime();
     while (1) {
         int32_t status = getFrameSample(frameInfo);
         if (status || !frameInfo.size) break;
-        mTimer->addOutputTime();
+        mStats->addOutputTime();
     }
 
     if (mFormat) {
@@ -111,7 +113,7 @@
 
 void Extractor::dumpStatistics(string inputReference) {
     string operation = "extract";
-    mTimer->dumpStatistics(operation, inputReference, mDurationUs);
+    mStats->dumpStatistics(operation, inputReference, mDurationUs);
 }
 
 void Extractor::deInitExtractor() {
@@ -120,14 +122,14 @@
         mFrameBuf = nullptr;
     }
 
-    int64_t sTime = mTimer->getCurTime();
+    int64_t sTime = mStats->getCurTime();
     if (mExtractor) {
         // TODO: (b/140128505) Multiple calls result in DoS.
         // Uncomment call to AMediaExtractor_delete() once this is resolved
         // AMediaExtractor_delete(mExtractor);
         mExtractor = nullptr;
     }
-    int64_t eTime = mTimer->getCurTime();
-    int64_t deInitTime = mTimer->getTimeDiff(sTime, eTime);
-    mTimer->setDeInitTime(deInitTime);
+    int64_t eTime = mStats->getCurTime();
+    int64_t deInitTime = mStats->getTimeDiff(sTime, eTime);
+    mStats->setDeInitTime(deInitTime);
 }
diff --git a/media/tests/benchmark/src/native/extractor/Extractor.h b/media/tests/benchmark/src/native/extractor/Extractor.h
index 361bcd7..4c39a72 100644
--- a/media/tests/benchmark/src/native/extractor/Extractor.h
+++ b/media/tests/benchmark/src/native/extractor/Extractor.h
@@ -20,19 +20,19 @@
 #include <media/NdkMediaExtractor.h>
 
 #include "BenchmarkCommon.h"
-#include "Timer.h"
+#include "Stats.h"
 
 class Extractor {
   public:
     Extractor()
         : mFormat(nullptr),
           mExtractor(nullptr),
-          mTimer(nullptr),
+          mStats(nullptr),
           mFrameBuf{nullptr},
           mDurationUs{0} {}
 
     ~Extractor() {
-        if (mTimer) delete mTimer;
+        if (mStats) delete mStats;
     }
 
     int32_t initExtractor(int32_t fd, size_t fileSize);
@@ -58,7 +58,7 @@
   private:
     AMediaFormat *mFormat;
     AMediaExtractor *mExtractor;
-    Timer *mTimer;
+    Stats *mStats;
     uint8_t *mFrameBuf;
     int64_t mDurationUs;
 };
diff --git a/media/tests/benchmark/src/native/muxer/Muxer.cpp b/media/tests/benchmark/src/native/muxer/Muxer.cpp
index 877f7ad..b297a66 100644
--- a/media/tests/benchmark/src/native/muxer/Muxer.cpp
+++ b/media/tests/benchmark/src/native/muxer/Muxer.cpp
@@ -24,9 +24,9 @@
 
 int32_t Muxer::initMuxer(int32_t fd, MUXER_OUTPUT_T outputFormat) {
     if (!mFormat) mFormat = mExtractor->getFormat();
-    if (!mTimer) mTimer = new Timer();
+    if (!mStats) mStats = new Stats();
 
-    int64_t sTime = mTimer->getCurTime();
+    int64_t sTime = mStats->getCurTime();
     mMuxer = AMediaMuxer_new(fd, (OutputFormat)outputFormat);
     if (!mMuxer) {
         cout << "[   WARN   ] Test Skipped. Unable to create muxer \n";
@@ -42,14 +42,14 @@
         return index;
     }
     AMediaMuxer_start(mMuxer);
-    int64_t eTime = mTimer->getCurTime();
-    int64_t timeTaken = mTimer->getTimeDiff(sTime, eTime);
-    mTimer->setInitTime(timeTaken);
+    int64_t eTime = mStats->getCurTime();
+    int64_t timeTaken = mStats->getTimeDiff(sTime, eTime);
+    mStats->setInitTime(timeTaken);
     return AMEDIA_OK;
 }
 
 void Muxer::deInitMuxer() {
-    int64_t sTime = mTimer->getCurTime();
+    int64_t sTime = mStats->getCurTime();
     if (mFormat) {
         AMediaFormat_delete(mFormat);
         mFormat = nullptr;
@@ -57,24 +57,24 @@
     if (!mMuxer) return;
     AMediaMuxer_stop(mMuxer);
     AMediaMuxer_delete(mMuxer);
-    int64_t eTime = mTimer->getCurTime();
-    int64_t timeTaken = mTimer->getTimeDiff(sTime, eTime);
-    mTimer->setDeInitTime(timeTaken);
+    int64_t eTime = mStats->getCurTime();
+    int64_t timeTaken = mStats->getTimeDiff(sTime, eTime);
+    mStats->setDeInitTime(timeTaken);
 }
 
 void Muxer::resetMuxer() {
-    if (mTimer) mTimer->resetTimers();
+    if (mStats) mStats->reset();
 }
 
 void Muxer::dumpStatistics(string inputReference) {
     string operation = "mux";
-    mTimer->dumpStatistics(operation, inputReference, mExtractor->getClipDuration());
+    mStats->dumpStatistics(operation, inputReference, mExtractor->getClipDuration());
 }
 
 int32_t Muxer::mux(uint8_t *inputBuffer, vector<AMediaCodecBufferInfo> &frameInfos) {
     // Mux frame data
     size_t frameIdx = 0;
-    mTimer->setStartTime();
+    mStats->setStartTime();
     while (frameIdx < frameInfos.size()) {
         AMediaCodecBufferInfo info = frameInfos.at(frameIdx);
         media_status_t status = AMediaMuxer_writeSampleData(mMuxer, 0, inputBuffer, &info);
@@ -82,7 +82,8 @@
             ALOGE("Error in AMediaMuxer_writeSampleData");
             return status;
         }
-        mTimer->addOutputTime();
+        mStats->addOutputTime();
+        mStats->addFrameSize(info.size);
         frameIdx++;
     }
     return AMEDIA_OK;
diff --git a/media/tests/benchmark/src/native/muxer/Muxer.h b/media/tests/benchmark/src/native/muxer/Muxer.h
index 154fd20..eee3146 100644
--- a/media/tests/benchmark/src/native/muxer/Muxer.h
+++ b/media/tests/benchmark/src/native/muxer/Muxer.h
@@ -20,7 +20,7 @@
 #include <media/NdkMediaMuxer.h>
 
 #include "BenchmarkCommon.h"
-#include "Timer.h"
+#include "Stats.h"
 #include "Extractor.h"
 
 typedef enum {
@@ -33,14 +33,14 @@
 
 class Muxer {
   public:
-    Muxer() : mFormat(nullptr), mMuxer(nullptr), mTimer(nullptr) { mExtractor = new Extractor(); }
+    Muxer() : mFormat(nullptr), mMuxer(nullptr), mStats(nullptr) { mExtractor = new Extractor(); }
 
     virtual ~Muxer() {
-        if (mTimer) delete mTimer;
+        if (mStats) delete mStats;
         if (mExtractor) delete mExtractor;
     }
 
-    Timer *getTimer() { return mTimer; }
+    Stats *getStats() { return mStats; }
     Extractor *getExtractor() { return mExtractor; }
 
     /* Muxer related utilities */
@@ -57,7 +57,7 @@
     AMediaFormat *mFormat;
     AMediaMuxer *mMuxer;
     Extractor *mExtractor;
-    Timer *mTimer;
+    Stats *mStats;
 };
 
 #endif  // __MUXER_H__
diff --git a/media/tests/benchmark/tests/Android.bp b/media/tests/benchmark/tests/Android.bp
index 353d60e..fc21ef7 100644
--- a/media/tests/benchmark/tests/Android.bp
+++ b/media/tests/benchmark/tests/Android.bp
@@ -58,3 +58,20 @@
         "libbenchmark_muxer",
     ],
 }
+
+cc_test {
+    name: "encoderTest",
+    gtest: true,
+    defaults: [
+        "libbenchmark_common-defaults",
+        "libbenchmark_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["EncoderTest.cpp"],
+
+    static_libs: [
+        "libbenchmark_extractor",
+        "libbenchmark_decoder",
+        "libbenchmark_encoder",
+    ],
+}
diff --git a/media/tests/benchmark/tests/EncoderTest.cpp b/media/tests/benchmark/tests/EncoderTest.cpp
new file mode 100644
index 0000000..574083d
--- /dev/null
+++ b/media/tests/benchmark/tests/EncoderTest.cpp
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2019 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 "encoderTest"
+
+#include <fstream>
+
+#include "BenchmarkTestEnvironment.h"
+#include "Encoder.h"
+#include "Decoder.h"
+
+static BenchmarkTestEnvironment *gEnv = nullptr;
+
+class EncoderTest : public ::testing::TestWithParam<tuple<string, string, bool>> {};
+
+TEST_P(EncoderTest, Encode) {
+    ALOGD("Encode test for all codecs");
+    tuple<string /* InputFile */, string /* CodecName */, bool /* asyncMode */> params = GetParam();
+
+    string inputFile = gEnv->getRes() + get<0>(params);
+    FILE *inputFp = fopen(inputFile.c_str(), "rb");
+    if (!inputFp) {
+        cout << "[   WARN   ] Test Skipped. Unable to open input file for reading \n";
+        return;
+    }
+
+    Decoder *decoder = new Decoder();
+    Extractor *extractor = decoder->getExtractor();
+    if (!extractor) {
+        cout << "[   WARN   ] Test Skipped. Extractor creation failed \n";
+        return;
+    }
+    // Read file properties
+    fseek(inputFp, 0, SEEK_END);
+    size_t fileSize = ftell(inputFp);
+    fseek(inputFp, 0, SEEK_SET);
+    int32_t fd = fileno(inputFp);
+
+    int32_t trackCount = extractor->initExtractor(fd, fileSize);
+    if (trackCount <= 0) {
+        cout << "[   WARN   ] Test Skipped. initExtractor failed\n";
+        return;
+    }
+
+    Encoder *encoder = new Encoder();
+    for (int curTrack = 0; curTrack < trackCount; curTrack++) {
+        int32_t status = extractor->setupTrackFormat(curTrack);
+        if (status != 0) {
+            cout << "[   WARN   ] Test Skipped. Track Format invalid \n";
+            return;
+        }
+
+        uint8_t *inputBuffer = (uint8_t *)malloc(kMaxBufferSize);
+        if (!inputBuffer) {
+            cout << "[   WARN   ] Test Skipped. Insufficient memory \n";
+            return;
+        }
+        vector<AMediaCodecBufferInfo> frameInfo;
+        AMediaCodecBufferInfo info;
+        uint32_t inputBufferOffset = 0;
+        int32_t idx = 0;
+
+        // Get CSD data
+        while (1) {
+            void *csdBuffer = extractor->getCSDSample(info, idx);
+            if (!csdBuffer || !info.size) break;
+
+            // copy the meta data and buffer to be passed to decoder
+            if (inputBufferOffset + info.size > kMaxBufferSize) {
+                cout << "[   WARN   ] Test Skipped. Memory allocated not sufficient\n";
+                free(inputBuffer);
+                return;
+            }
+            memcpy(inputBuffer + inputBufferOffset, csdBuffer, info.size);
+            frameInfo.push_back(info);
+            inputBufferOffset += info.size;
+            idx++;
+        }
+
+        // Get frame data
+        while (1) {
+            status = extractor->getFrameSample(info);
+            if (status || !info.size) break;
+            // copy the meta data and buffer to be passed to decoder
+            if (inputBufferOffset + info.size > kMaxBufferSize) {
+                cout << "[   WARN   ] Test Skipped. Memory allocated not sufficient\n";
+                free(inputBuffer);
+                return;
+            }
+            memcpy(inputBuffer + inputBufferOffset, extractor->getFrameBuf(), info.size);
+            frameInfo.push_back(info);
+            inputBufferOffset += info.size;
+        }
+
+        string decName = "";
+        string outputFileName = "decode.out";
+        FILE *outFp = fopen(outputFileName.c_str(), "wb");
+        if (outFp == nullptr) {
+            ALOGE("Unable to open output file for writing");
+            return;
+        }
+        decoder->setupDecoder();
+        status = decoder->decode(inputBuffer, frameInfo, decName, false /*asyncMode */, outFp);
+        if (status != AMEDIA_OK) {
+            cout << "[   WARN   ] Test Skipped. Decode returned error \n";
+            return;
+        }
+
+        ifstream eleStream;
+        eleStream.open(outputFileName.c_str(), ifstream::binary | ifstream::ate);
+        ASSERT_EQ(eleStream.is_open(), true) << outputFileName.c_str() << " - file not found";
+        size_t eleSize = eleStream.tellg();
+        eleStream.seekg(0, ifstream::beg);
+
+        AMediaFormat *format = extractor->getFormat();
+        const char *mime = nullptr;
+        AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime);
+        if (!mime) {
+            ALOGE("Error in AMediaFormat_getString");
+            return;
+        }
+        // Get encoder params
+        encParameter encParams;
+        if (!strncmp(mime, "video/", 6)) {
+            AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_WIDTH, &encParams.width);
+            AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_HEIGHT, &encParams.height);
+            AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_FRAME_RATE, &encParams.frameRate);
+            AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, &encParams.bitrate);
+            if (encParams.bitrate <= 0 || encParams.frameRate <= 0) {
+                encParams.frameRate = 25;
+                if (!strcmp(mime, "video/3gpp") || !strcmp(mime, "video/mp4v-es")) {
+                    encParams.bitrate = 600000 /* 600 Kbps */;
+                } else {
+                    encParams.bitrate = 8000000 /* 8 Mbps */;
+                }
+            }
+            AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_PROFILE, &encParams.profile);
+            AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_LEVEL, &encParams.level);
+        } else {
+            AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, &encParams.sampleRate);
+            AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &encParams.numChannels);
+            encParams.bitrate =
+                    encParams.sampleRate * encParams.numChannels * 16 /* bitsPerSample */;
+        }
+
+        encoder->setupEncoder();
+        string codecName = get<1>(params);
+        bool asyncMode = get<2>(params);
+        status = encoder->encode(codecName, eleStream, eleSize, asyncMode, encParams, (char *)mime);
+        ASSERT_EQ(status, 0);
+        encoder->deInitCodec();
+        cout << "codec : " << codecName << endl;
+        string inputReference = get<0>(params);
+        encoder->dumpStatistics(inputReference, extractor->getClipDuration());
+        eleStream.close();
+        if (outFp) fclose(outFp);
+
+        if (format) {
+            AMediaFormat_delete(format);
+            format = nullptr;
+        }
+        encoder->resetEncoder();
+        decoder->deInitCodec();
+        free(inputBuffer);
+        decoder->resetDecoder();
+    }
+    delete encoder;
+    fclose(inputFp);
+    extractor->deInitExtractor();
+    delete decoder;
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        AudioEncoderSyncTest, EncoderTest,
+        ::testing::Values(make_tuple("bbb_44100hz_2ch_128kbps_aac_30sec.mp4", "", false),
+                          make_tuple("bbb_8000hz_1ch_8kbps_amrnb_30sec.3gp", "", false),
+                          make_tuple("bbb_16000hz_1ch_9kbps_amrwb_30sec.3gp", "", false),
+                          make_tuple("bbb_48000hz_2ch_100kbps_opus_30sec.webm", "", false)));
+
+INSTANTIATE_TEST_SUITE_P(
+        AudioEncoderAsyncTest, EncoderTest,
+        ::testing::Values(make_tuple("bbb_44100hz_2ch_128kbps_aac_30sec.mp4", "", true),
+                          make_tuple("bbb_8000hz_1ch_8kbps_amrnb_30sec.3gp", "", true),
+                          make_tuple("bbb_16000hz_1ch_9kbps_amrwb_30sec.3gp", "", true),
+                          make_tuple("bbb_48000hz_2ch_100kbps_opus_30sec.webm", "", true)));
+
+INSTANTIATE_TEST_SUITE_P(VideEncoderSyncTest, EncoderTest,
+                         ::testing::Values(
+                                 // Hardware codecs
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_vp8.webm", "", false),
+                                 make_tuple("crowd_1920x1080_25fps_6700kbps_h264.ts", "", false),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_h265.mkv", "", false),
+                                 // Software codecs
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_vp9.webm",
+                                            "c2.android.vp9.encoder", false),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_vp8.webm",
+                                            "c2.android.vp8.encoder", false),
+                                 make_tuple("crowd_176x144_25fps_6000kbps_mpeg4.mp4",
+                                            "c2.android.mpeg4.encoder", false),
+                                 make_tuple("crowd_176x144_25fps_6000kbps_h263.3gp",
+                                            "c2.android.h263.encoder", false),
+                                 make_tuple("crowd_1920x1080_25fps_6700kbps_h264.ts",
+                                            "c2.android.avc.encoder", false),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_h265.mkv",
+                                            "c2.android.hevc.encoder", false)));
+
+INSTANTIATE_TEST_SUITE_P(VideoEncoderAsyncTest, EncoderTest,
+                         ::testing::Values(
+                                 // Hardware codecs
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_vp8.webm", "", true),
+                                 make_tuple("crowd_1920x1080_25fps_6700kbps_h264.ts", "", true),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_h265.mkv", "", true),
+                                 // Software codecs
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_vp9.webm",
+                                            "c2.android.vp9.encoder", true),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_vp8.webm",
+                                            "c2.android.vp8.encoder", true),
+                                 make_tuple("crowd_176x144_25fps_6000kbps_mpeg4.mp4",
+                                            "c2.android.mpeg4.encoder", true),
+                                 make_tuple("crowd_176x144_25fps_6000kbps_h263.3gp",
+                                            "c2.android.h263.encoder", true),
+                                 make_tuple("crowd_1920x1080_25fps_6700kbps_h264.ts",
+                                            "c2.android.avc.encoder", true),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_h265.mkv",
+                                            "c2.android.hevc.encoder", true)));
+
+int main(int argc, char **argv) {
+    gEnv = new BenchmarkTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        ALOGD("Encoder Test result = %d\n", status);
+    }
+    return status;
+}
diff --git a/services/audiopolicy/audio_policy.conf b/services/audiopolicy/audio_policy.conf
deleted file mode 100644
index 9b83fef..0000000
--- a/services/audiopolicy/audio_policy.conf
+++ /dev/null
@@ -1,145 +0,0 @@
-#
-# Template audio policy configuration file
-#
-
-# Global configuration section:
-# - before audio HAL version 3.0:
-#   lists input and output devices always present on the device
-#   as well as the output device selected by default.
-#   Devices are designated by a string that corresponds to the enum in audio.h
-#
-#  global_configuration {
-#    attached_output_devices AUDIO_DEVICE_OUT_SPEAKER
-#    default_output_device AUDIO_DEVICE_OUT_SPEAKER
-#    attached_input_devices AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_REMOTE_SUBMIX
-#  }
-#
-# - after and including audio HAL 3.0 the global_configuration section is included in each
-#   hardware module section.
-#   it also includes the audio HAL version of this hw module:
-#  global_configuration {
-#    ...
-#     audio_hal_version <major.minor>  # audio HAL version in e.g. 3.0
-#  }
-#   other attributes (attached devices, default device) have to be included in the
-#   global_configuration section of each hardware module
-
-
-# audio hardware module section: contains descriptors for all audio hw modules present on the
-# device. Each hw module node is named after the corresponding hw module library base name.
-# For instance, "primary" corresponds to audio.primary.<device>.so.
-# The "primary" module is mandatory and must include at least one output with
-# AUDIO_OUTPUT_FLAG_PRIMARY flag.
-# Each module descriptor contains one or more output profile descriptors and zero or more
-# input profile descriptors. Each profile lists all the parameters supported by a given output
-# or input stream category.
-# The "channel_masks", "formats", "devices" and "flags" are specified using strings corresponding
-# to enums in audio.h and audio_policy.h. They are concatenated by use of "|" without space or "\n".
-#
-# For audio HAL version posterior to 3.0 the following sections or sub sections can be present in
-# a hw module section:
-# - A "global_configuration" section: see above
-# - Optionally a "devices" section:
-#   This section contains descriptors for audio devices with attributes like an address or a
-#   gain controller. The syntax for the devices section and device descriptor is as follows:
-#    devices {
-#      <device name> {              # <device name>: any string without space
-#        type <device type>         # <device type> e.g. AUDIO_DEVICE_OUT_SPEAKER
-#        address <address>          # optional: device address, char string less than 64 in length
-#      }
-#    }
-# - one or more "gains" sections can be present in a device descriptor section.
-#   If present, they describe the capabilities of gain controllers attached to this input or
-#   output device. e.g. :
-#   <device name> {                  # <device name>: any string without space
-#     type <device type>             # <device type> e.g. AUDIO_DEVICE_OUT_SPEAKER
-#     address <address>              # optional: device address, char string less than 64 in length
-#     gains {
-#       <gain name> {
-#         mode <gain modes supported>              # e.g. AUDIO_GAIN_MODE_CHANNELS
-#         channel_mask <controlled channels>       # needed if mode AUDIO_GAIN_MODE_CHANNELS
-#         min_value_mB <min value in millibel>
-#         max_value_mB <max value in millibel>
-#         default_value_mB <default value in millibel>
-#         step_value_mB <step value in millibel>
-#         min_ramp_ms <min duration in ms>         # needed if mode AUDIO_GAIN_MODE_RAMP
-#         max_ramp_ms <max duration ms>            # needed if mode AUDIO_GAIN_MODE_RAMP
-#       }
-#     }
-#   }
-# - when a device descriptor is present, output and input profiles can refer to this device by
-# its name in their "devices" section instead of specifying a device type. e.g. :
-#   outputs {
-#     primary {
-#       sampling_rates 44100
-#       channel_masks AUDIO_CHANNEL_OUT_STEREO
-#       formats AUDIO_FORMAT_PCM_16_BIT
-#       devices <device name>
-#       flags AUDIO_OUTPUT_FLAG_PRIMARY
-#     }
-#   }
-# sample audio_policy.conf file below
-
-audio_hw_modules {
-  primary {
-    global_configuration {
-      attached_output_devices AUDIO_DEVICE_OUT_SPEAKER
-      default_output_device AUDIO_DEVICE_OUT_SPEAKER
-      attached_input_devices AUDIO_DEVICE_IN_BUILTIN_MIC
-      audio_hal_version 3.0
-    }
-    devices {
-      speaker {
-        type AUDIO_DEVICE_OUT_SPEAKER
-        gains {
-          gain_1 {
-            mode AUDIO_GAIN_MODE_JOINT
-            min_value_mB -8400
-            max_value_mB 4000
-            default_value_mB 0
-            step_value_mB 100
-          }
-        }
-      }
-    }
-    outputs {
-      primary {
-        sampling_rates 48000
-        channel_masks AUDIO_CHANNEL_OUT_STEREO
-        formats AUDIO_FORMAT_PCM_16_BIT
-        devices speaker
-        flags AUDIO_OUTPUT_FLAG_PRIMARY
-      }
-    }
-    inputs {
-      primary {
-        sampling_rates 8000|16000
-        channel_masks AUDIO_CHANNEL_IN_MONO
-        formats AUDIO_FORMAT_PCM_16_BIT
-        devices AUDIO_DEVICE_IN_BUILTIN_MIC
-      }
-    }
-  }
-  r_submix {
-    global_configuration {
-      attached_input_devices AUDIO_DEVICE_IN_REMOTE_SUBMIX
-      audio_hal_version 2.0
-    }
-    outputs {
-      submix {
-        sampling_rates 48000
-        channel_masks AUDIO_CHANNEL_OUT_STEREO
-        formats AUDIO_FORMAT_PCM_16_BIT
-        devices AUDIO_DEVICE_OUT_REMOTE_SUBMIX
-      }
-    }
-    inputs {
-      submix {
-        sampling_rates 48000
-        channel_masks AUDIO_CHANNEL_IN_STEREO
-        formats AUDIO_FORMAT_PCM_16_BIT
-        devices AUDIO_DEVICE_IN_REMOTE_SUBMIX
-      }
-    }
-  }
-}
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
index 2264d8f..0776a8d 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
@@ -40,7 +40,8 @@
                       DeviceVector &availableOutputDevices,
                       DeviceVector &availableInputDevices,
                       sp<DeviceDescriptor> &defaultOutputDevice)
-        : mHwModules(hwModules),
+        : mEngineLibraryNameSuffix(kDefaultEngineLibraryNameSuffix),
+          mHwModules(hwModules),
           mAvailableOutputDevices(availableOutputDevices),
           mAvailableInputDevices(availableInputDevices),
           mDefaultOutputDevice(defaultOutputDevice),
@@ -55,6 +56,14 @@
         mSource = file;
     }
 
+    const std::string& getEngineLibraryNameSuffix() const {
+        return mEngineLibraryNameSuffix;
+    }
+
+    void setEngineLibraryNameSuffix(const std::string& suffix) {
+        mEngineLibraryNameSuffix = suffix;
+    }
+
     void setHwModules(const HwModuleCollection &hwModules)
     {
         mHwModules = hwModules;
@@ -108,6 +117,7 @@
     void setDefault(void)
     {
         mSource = "AudioPolicyConfig::setDefault";
+        mEngineLibraryNameSuffix = kDefaultEngineLibraryNameSuffix;
         mDefaultOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPEAKER);
         mDefaultOutputDevice->addAudioProfile(AudioProfile::createFullDynamic());
         sp<DeviceDescriptor> defaultInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_BUILTIN_MIC);
@@ -167,7 +177,10 @@
     }
 
 private:
+    static const constexpr char* const kDefaultEngineLibraryNameSuffix = "default";
+
     std::string mSource;
+    std::string mEngineLibraryNameSuffix;
     HwModuleCollection &mHwModules; /**< Collection of Module, with Profiles, i.e. Mix Ports. */
     DeviceVector &mAvailableOutputDevices;
     DeviceVector &mAvailableInputDevices;
diff --git a/services/audiopolicy/common/managerdefinitions/include/audio_policy_conf.h b/services/audiopolicy/common/managerdefinitions/include/audio_policy_conf.h
deleted file mode 100644
index 0a27947..0000000
--- a/services/audiopolicy/common/managerdefinitions/include/audio_policy_conf.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#pragma once
-
-
-/////////////////////////////////////////////////
-//      Definitions for audio policy configuration file (audio_policy.conf)
-/////////////////////////////////////////////////
-
-#define AUDIO_HARDWARE_MODULE_ID_MAX_LEN 32
-
-#define AUDIO_POLICY_CONFIG_FILE "/system/etc/audio_policy.conf"
-#define AUDIO_POLICY_VENDOR_CONFIG_FILE "/vendor/etc/audio_policy.conf"
-
-// global configuration
-#define GLOBAL_CONFIG_TAG "global_configuration"
-
-#define ATTACHED_OUTPUT_DEVICES_TAG "attached_output_devices"
-#define DEFAULT_OUTPUT_DEVICE_TAG "default_output_device"
-#define ATTACHED_INPUT_DEVICES_TAG "attached_input_devices"
-#define SPEAKER_DRC_ENABLED_TAG "speaker_drc_enabled"
-#define AUDIO_HAL_VERSION_TAG "audio_hal_version"
-
-// hw modules descriptions
-#define AUDIO_HW_MODULE_TAG "audio_hw_modules"
-
-#define OUTPUTS_TAG "outputs"
-#define INPUTS_TAG "inputs"
-
-#define SAMPLING_RATES_TAG "sampling_rates"
-#define FORMATS_TAG "formats"
-#define CHANNELS_TAG "channel_masks"
-#define DEVICES_TAG "devices"
-#define FLAGS_TAG "flags"
-
-#define APM_DEVICES_TAG "devices"
-#define APM_DEVICE_TYPE "type"
-#define APM_DEVICE_ADDRESS "address"
-
-#define MIXERS_TAG "mixers"
-#define MIXER_TYPE "type"
-#define MIXER_TYPE_MUX "mux"
-#define MIXER_TYPE_MIX "mix"
-
-#define GAINS_TAG "gains"
-#define GAIN_MODE "mode"
-#define GAIN_CHANNELS "channel_mask"
-#define GAIN_MIN_VALUE "min_value_mB"
-#define GAIN_MAX_VALUE "max_value_mB"
-#define GAIN_DEFAULT_VALUE "default_value_mB"
-#define GAIN_STEP_VALUE "step_value_mB"
-#define GAIN_MIN_RAMP_MS "min_ramp_ms"
-#define GAIN_MAX_RAMP_MS "max_ramp_ms"
-
-#define DYNAMIC_VALUE_TAG "dynamic" // special value for "channel_masks", "sampling_rates" and
-                                    // "formats" in outputs descriptors indicating that supported
-                                    // values should be queried after opening the output.
diff --git a/services/audiopolicy/engine/common/include/EngineBase.h b/services/audiopolicy/engine/common/include/EngineBase.h
index cedc78f..fca9a60 100644
--- a/services/audiopolicy/engine/common/include/EngineBase.h
+++ b/services/audiopolicy/engine/common/include/EngineBase.h
@@ -17,18 +17,18 @@
 #pragma once
 
 #include <EngineConfig.h>
-#include <AudioPolicyManagerInterface.h>
+#include <EngineInterface.h>
 #include <ProductStrategy.h>
 #include <VolumeGroup.h>
 
 namespace android {
 namespace audio_policy {
 
-class EngineBase : public AudioPolicyManagerInterface
+class EngineBase : public EngineInterface
 {
 public:
     ///
-    /// from AudioPolicyManagerInterface
+    /// from EngineInterface
     ///
     android::status_t initCheck() override;
 
diff --git a/services/audiopolicy/engine/common/include/ProductStrategy.h b/services/audiopolicy/engine/common/include/ProductStrategy.h
index 1a2a198..c538f52 100644
--- a/services/audiopolicy/engine/common/include/ProductStrategy.h
+++ b/services/audiopolicy/engine/common/include/ProductStrategy.h
@@ -19,7 +19,6 @@
 #include "VolumeGroup.h"
 
 #include <system/audio.h>
-#include <AudioPolicyManagerInterface.h>
 #include <utils/RefBase.h>
 #include <HandleGenerator.h>
 #include <string>
@@ -27,6 +26,7 @@
 #include <map>
 #include <utils/Errors.h>
 #include <utils/String8.h>
+#include <media/AudioAttributes.h>
 
 namespace android {
 
diff --git a/services/audiopolicy/engine/common/include/VolumeCurve.h b/services/audiopolicy/engine/common/include/VolumeCurve.h
index 54314e3..d3d0904 100644
--- a/services/audiopolicy/engine/common/include/VolumeCurve.h
+++ b/services/audiopolicy/engine/common/include/VolumeCurve.h
@@ -18,7 +18,6 @@
 
 #include "IVolumeCurves.h"
 #include <policy.h>
-#include <AudioPolicyManagerInterface.h>
 #include <utils/RefBase.h>
 #include <HandleGenerator.h>
 #include <utils/String8.h>
diff --git a/services/audiopolicy/engine/common/include/VolumeGroup.h b/services/audiopolicy/engine/common/include/VolumeGroup.h
index c34b406..5378f64 100644
--- a/services/audiopolicy/engine/common/include/VolumeGroup.h
+++ b/services/audiopolicy/engine/common/include/VolumeGroup.h
@@ -16,7 +16,6 @@
 
 #pragma once
 
-#include <AudioPolicyManagerInterface.h>
 #include <VolumeCurve.h>
 #include <system/audio.h>
 #include <utils/RefBase.h>
diff --git a/services/audiopolicy/engine/common/src/ProductStrategy.cpp b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
index f74f190..ac3e462 100644
--- a/services/audiopolicy/engine/common/src/ProductStrategy.cpp
+++ b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
@@ -19,6 +19,7 @@
 
 #include "ProductStrategy.h"
 
+#include <media/AudioProductStrategy.h>
 #include <media/TypeConverter.h>
 #include <utils/String8.h>
 #include <cstdint>
diff --git a/services/audiopolicy/engine/config/src/EngineConfig.cpp b/services/audiopolicy/engine/config/src/EngineConfig.cpp
index 1ad7739..d47fbd2 100644
--- a/services/audiopolicy/engine/config/src/EngineConfig.cpp
+++ b/services/audiopolicy/engine/config/src/EngineConfig.cpp
@@ -32,9 +32,9 @@
 #include <istream>
 
 #include <cstdint>
+#include <stdarg.h>
 #include <string>
 
-
 namespace android {
 
 using utilities::convertTo;
@@ -603,7 +603,39 @@
     return NO_ERROR;
 }
 
+namespace {
+
+class XmlErrorHandler {
+public:
+    XmlErrorHandler() {
+        xmlSetGenericErrorFunc(this, &xmlErrorHandler);
+    }
+    XmlErrorHandler(const XmlErrorHandler&) = delete;
+    XmlErrorHandler(XmlErrorHandler&&) = delete;
+    XmlErrorHandler& operator=(const XmlErrorHandler&) = delete;
+    XmlErrorHandler& operator=(XmlErrorHandler&&) = delete;
+    ~XmlErrorHandler() {
+        xmlSetGenericErrorFunc(NULL, NULL);
+        if (!mErrorMessage.empty()) {
+            ALOG(LOG_ERROR, "libxml2", "%s", mErrorMessage.c_str());
+        }
+    }
+    static void xmlErrorHandler(void* ctx, const char* msg, ...) {
+        char buffer[256];
+        va_list args;
+        va_start(args, msg);
+        vsnprintf(buffer, sizeof(buffer), msg, args);
+        va_end(args);
+        static_cast<XmlErrorHandler*>(ctx)->mErrorMessage += buffer;
+    }
+private:
+    std::string mErrorMessage;
+};
+
+}  // namespace
+
 ParsingResult parse(const char* path) {
+    XmlErrorHandler errorHandler;
     xmlDocPtr doc;
     doc = xmlParseFile(path);
     if (doc == NULL) {
@@ -641,6 +673,7 @@
 }
 
 android::status_t parseLegacyVolumeFile(const char* path, VolumeGroups &volumeGroups) {
+    XmlErrorHandler errorHandler;
     xmlDocPtr doc;
     doc = xmlParseFile(path);
     if (doc == NULL) {
diff --git a/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h b/services/audiopolicy/engine/interface/EngineInterface.h
similarity index 97%
rename from services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
rename to services/audiopolicy/engine/interface/EngineInterface.h
index b7fd031..0c58a7c 100644
--- a/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
+++ b/services/audiopolicy/engine/interface/EngineInterface.h
@@ -38,7 +38,7 @@
 /**
  * This interface is dedicated to the policy manager that a Policy Engine shall implement.
  */
-class AudioPolicyManagerInterface
+class EngineInterface
 {
 public:
     /**
@@ -295,7 +295,13 @@
     virtual void dump(String8 *dst) const = 0;
 
 protected:
-    virtual ~AudioPolicyManagerInterface() {}
+    virtual ~EngineInterface() {}
 };
 
+__attribute__((visibility("default")))
+extern "C" EngineInterface* createEngineInstance();
+
+__attribute__((visibility("default")))
+extern "C" void destroyEngineInstance(EngineInterface *engine);
+
 } // namespace android
diff --git a/services/audiopolicy/engineconfigurable/include/AudioPolicyEngineInstance.h b/services/audiopolicy/engineconfigurable/include/AudioPolicyEngineInstance.h
index efc69da..f52de21 100644
--- a/services/audiopolicy/engineconfigurable/include/AudioPolicyEngineInstance.h
+++ b/services/audiopolicy/engineconfigurable/include/AudioPolicyEngineInstance.h
@@ -16,7 +16,7 @@
 
 #pragma once
 
-class AudioPolicyManagerInterface;
+class EngineInterface;
 class AudioPolicyPluginInterface;
 
 namespace android {
@@ -69,7 +69,7 @@
  * Compile time error will claim if invalid interface is requested.
  */
 template <>
-AudioPolicyManagerInterface *EngineInstance::queryInterface() const;
+EngineInterface *EngineInstance::queryInterface() const;
 
 template <>
 AudioPolicyPluginInterface *EngineInstance::queryInterface() const;
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.cpp b/services/audiopolicy/engineconfigurable/src/Engine.cpp
index cb45fcf..c37efca 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Engine.cpp
@@ -361,7 +361,7 @@
 }
 
 template <>
-AudioPolicyManagerInterface *Engine::queryInterface()
+EngineInterface *Engine::queryInterface()
 {
     return this;
 }
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.h b/services/audiopolicy/engineconfigurable/src/Engine.h
index 4662e7e..3b371d8 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.h
+++ b/services/audiopolicy/engineconfigurable/src/Engine.h
@@ -17,7 +17,7 @@
 #pragma once
 
 #include "EngineBase.h"
-#include <AudioPolicyManagerInterface.h>
+#include <EngineInterface.h>
 #include <AudioPolicyPluginInterface.h>
 #include "Collection.h"
 
diff --git a/services/audiopolicy/engineconfigurable/src/EngineInstance.cpp b/services/audiopolicy/engineconfigurable/src/EngineInstance.cpp
index 2442590..b127796 100644
--- a/services/audiopolicy/engineconfigurable/src/EngineInstance.cpp
+++ b/services/audiopolicy/engineconfigurable/src/EngineInstance.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include <AudioPolicyManagerInterface.h>
+#include <EngineInterface.h>
 #include <AudioPolicyPluginInterface.h>
 #include "AudioPolicyEngineInstance.h"
 #include "Engine.h"
@@ -45,9 +45,9 @@
 }
 
 template <>
-AudioPolicyManagerInterface *EngineInstance::queryInterface() const
+EngineInterface *EngineInstance::queryInterface() const
 {
-    return getEngine()->queryInterface<AudioPolicyManagerInterface>();
+    return getEngine()->queryInterface<EngineInterface>();
 }
 
 template <>
@@ -57,5 +57,16 @@
 }
 
 } // namespace audio_policy
+
+extern "C" EngineInterface* createEngineInstance()
+{
+    return audio_policy::EngineInstance::getInstance()->queryInterface<EngineInterface>();
+}
+
+extern "C" void destroyEngineInstance(EngineInterface*)
+{
+    // The engine is a singleton.
+}
+
 } // namespace android
 
diff --git a/services/audiopolicy/enginedefault/Android.bp b/services/audiopolicy/enginedefault/Android.bp
index 7b42c6a..2b9cf09 100644
--- a/services/audiopolicy/enginedefault/Android.bp
+++ b/services/audiopolicy/enginedefault/Android.bp
@@ -1,16 +1,15 @@
 cc_library_shared {
     name: "libaudiopolicyenginedefault",
-    export_include_dirs: ["include"],
     srcs: [
         "src/Engine.cpp",
         "src/EngineInstance.cpp",
     ],
     cflags: [
+        "-fvisibility=hidden",
         "-Wall",
         "-Werror",
         "-Wextra",
     ],
-    local_include_dirs: ["include"],
     header_libs: [
         "libbase_headers",
         "libaudiopolicycommon",
diff --git a/services/audiopolicy/enginedefault/include/AudioPolicyEngineInstance.h b/services/audiopolicy/enginedefault/include/AudioPolicyEngineInstance.h
deleted file mode 100644
index 1e329f0..0000000
--- a/services/audiopolicy/enginedefault/include/AudioPolicyEngineInstance.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#pragma once
-
-class AudioPolicyManagerInterface;
-
-namespace android
-{
-namespace audio_policy
-{
-
-class Engine;
-
-class EngineInstance
-{
-protected:
-    EngineInstance();
-
-public:
-    virtual ~EngineInstance();
-
-    /**
-     * Get Audio Policy Engine instance.
-     *
-     * @return pointer to Route Manager Instance object.
-     */
-    static EngineInstance *getInstance();
-
-    /**
-     * Interface query.
-     * The first client of an interface of the policy engine will start the singleton.
-     *
-     * @tparam RequestedInterface: interface that the client is wishing to retrieve.
-     *
-     * @return interface handle.
-     */
-    template <class RequestedInterface>
-    RequestedInterface *queryInterface() const;
-
-protected:
-    /**
-     * Get Audio Policy Engine instance.
-     *
-     * @return Audio Policy Engine singleton.
-     */
-    Engine *getEngine() const;
-
-private:
-    /* Copy facilities are put private to disable copy. */
-    EngineInstance(const EngineInstance &object);
-    EngineInstance &operator=(const EngineInstance &object);
-};
-
-/**
- * Limit template instantation to supported type interfaces.
- * Compile time error will claim if invalid interface is requested.
- */
-template <>
-AudioPolicyManagerInterface *EngineInstance::queryInterface() const;
-
-} // namespace audio_policy
-} // namespace android
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 04170ac..c602f3a 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -762,12 +762,6 @@
                                            AUDIO_FORMAT_DEFAULT);
 }
 
-template <>
-AudioPolicyManagerInterface *Engine::queryInterface()
-{
-    return this;
-}
-
 } // namespace audio_policy
 } // namespace android
 
diff --git a/services/audiopolicy/enginedefault/src/Engine.h b/services/audiopolicy/enginedefault/src/Engine.h
index d5dfacc..62938cf 100644
--- a/services/audiopolicy/enginedefault/src/Engine.h
+++ b/services/audiopolicy/enginedefault/src/Engine.h
@@ -17,7 +17,7 @@
 #pragma once
 
 #include "EngineBase.h"
-#include "AudioPolicyManagerInterface.h"
+#include "EngineInterface.h"
 #include <AudioGain.h>
 #include <policy.h>
 
@@ -48,12 +48,9 @@
     Engine();
     virtual ~Engine() = default;
 
-    template <class RequestedInterface>
-    RequestedInterface *queryInterface();
-
 private:
     ///
-    /// from EngineBase, so from AudioPolicyManagerInterface
+    /// from EngineBase, so from EngineInterface
     ///
     status_t setForceUse(audio_policy_force_use_t usage,
                          audio_policy_forced_cfg_t config) override;
diff --git a/services/audiopolicy/enginedefault/src/EngineInstance.cpp b/services/audiopolicy/enginedefault/src/EngineInstance.cpp
index 17e9832..eeb3758 100644
--- a/services/audiopolicy/enginedefault/src/EngineInstance.cpp
+++ b/services/audiopolicy/enginedefault/src/EngineInstance.cpp
@@ -14,41 +14,21 @@
  * limitations under the License.
  */
 
-#include <AudioPolicyManagerInterface.h>
-#include "AudioPolicyEngineInstance.h"
+#include <EngineInterface.h>
 #include "Engine.h"
 
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
 
-EngineInstance::EngineInstance()
+extern "C" EngineInterface* createEngineInstance()
 {
+    return new (std::nothrow) Engine();
 }
 
-EngineInstance *EngineInstance::getInstance()
+extern "C" void destroyEngineInstance(EngineInterface *engine)
 {
-    static EngineInstance instance;
-    return &instance;
-}
-
-EngineInstance::~EngineInstance()
-{
-}
-
-Engine *EngineInstance::getEngine() const
-{
-    static Engine engine;
-    return &engine;
-}
-
-template <>
-AudioPolicyManagerInterface *EngineInstance::queryInterface() const
-{
-    return getEngine()->queryInterface<AudioPolicyManagerInterface>();
+    delete static_cast<Engine*>(engine);
 }
 
 } // namespace audio_policy
 } // namespace android
-
diff --git a/services/audiopolicy/managerdefault/Android.bp b/services/audiopolicy/managerdefault/Android.bp
new file mode 100644
index 0000000..8fbeff9
--- /dev/null
+++ b/services/audiopolicy/managerdefault/Android.bp
@@ -0,0 +1,43 @@
+cc_library_shared {
+    name: "libaudiopolicymanagerdefault",
+
+    srcs: [
+        "AudioPolicyManager.cpp",
+        "EngineLibrary.cpp",
+    ],
+
+    export_include_dirs: ["."],
+
+    shared_libs: [
+        "libcutils",
+        "libdl",
+        "libutils",
+        "liblog",
+        "libaudiopolicy",
+        "libsoundtrigger",
+        "libmedia_helper",
+        "libmediametrics",
+        "libbinder",
+        "libhidlbase",
+        "libxml2",
+        // The default audio policy engine is always present in the system image.
+        // libaudiopolicyengineconfigurable can be built in addition by specifying
+        // a dependency on it in the device makefile. There will be no build time
+        // conflict with libaudiopolicyenginedefault.
+        "libaudiopolicyenginedefault",
+    ],
+
+    header_libs: [
+        "libaudiopolicycommon",
+        "libaudiopolicyengine_interface_headers",
+        "libaudiopolicymanager_interface_headers",
+    ],
+
+    static_libs: ["libaudiopolicycomponents"],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+
+}
diff --git a/services/audiopolicy/managerdefault/Android.mk b/services/audiopolicy/managerdefault/Android.mk
deleted file mode 100644
index 684fc9f..0000000
--- a/services/audiopolicy/managerdefault/Android.mk
+++ /dev/null
@@ -1,56 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= AudioPolicyManager.cpp
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
-
-LOCAL_SHARED_LIBRARIES := \
-    libcutils \
-    libutils \
-    liblog \
-    libaudiopolicy \
-    libsoundtrigger
-
-ifeq ($(USE_CONFIGURABLE_AUDIO_POLICY), 1)
-
-ifneq ($(USE_XML_AUDIO_POLICY_CONF), 1)
-$(error Configurable policy does not support legacy conf file)
-endif #ifneq ($(USE_XML_AUDIO_POLICY_CONF), 1)
-
-LOCAL_SHARED_LIBRARIES += libaudiopolicyengineconfigurable
-
-else
-
-LOCAL_SHARED_LIBRARIES += libaudiopolicyenginedefault
-
-endif # ifeq ($(USE_CONFIGURABLE_AUDIO_POLICY), 1)
-
-LOCAL_C_INCLUDES += \
-    $(call include-path-for, audio-utils)
-
-LOCAL_HEADER_LIBRARIES := \
-    libaudiopolicycommon \
-    libaudiopolicyengine_interface_headers \
-    libaudiopolicymanager_interface_headers
-
-LOCAL_STATIC_LIBRARIES := \
-    libaudiopolicycomponents
-
-LOCAL_SHARED_LIBRARIES += libmedia_helper
-LOCAL_SHARED_LIBRARIES += libmediametrics
-
-LOCAL_SHARED_LIBRARIES += libbinder libhidlbase libxml2
-
-ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
-LOCAL_CFLAGS += -DUSE_XML_AUDIO_POLICY_CONF
-endif #ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
-
-LOCAL_CFLAGS += -Wall -Werror
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
-LOCAL_MODULE:= libaudiopolicymanagerdefault
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 1d4dacd..39f4072 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -42,15 +42,12 @@
 #include <set>
 #include <unordered_set>
 #include <vector>
-#include <AudioPolicyManagerInterface.h>
-#include <AudioPolicyEngineInstance.h>
 #include <cutils/properties.h>
 #include <utils/Log.h>
 #include <media/AudioParameter.h>
 #include <private/android_filesystem_config.h>
 #include <soundtrigger/SoundTrigger.h>
 #include <system/audio.h>
-#include <audio_policy_conf.h>
 #include "AudioPolicyManager.h"
 #include <Serializer.h>
 #include "TypeConverter.h"
@@ -4297,14 +4294,6 @@
     initialize();
 }
 
-//  This check is to catch any legacy platform updating to Q without having
-//  switched to XML since its deprecation on O.
-// TODO: after Q release, remove this check and flag as XML is now the only
-//        option and all legacy platform should have transitioned to XML.
-#ifndef USE_XML_AUDIO_POLICY_CONF
-#error Audio policy no longer supports legacy .conf configuration format
-#endif
-
 void AudioPolicyManager::loadConfig() {
     if (deserializeAudioPolicyXmlConfig(getConfig()) != NO_ERROR) {
         ALOGE("could not load audio policy configuration file, setting defaults");
@@ -4313,17 +4302,18 @@
 }
 
 status_t AudioPolicyManager::initialize() {
-    // Once policy config has been parsed, retrieve an instance of the engine and initialize it.
-    audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();
-    if (!engineInstance) {
-        ALOGE("%s:  Could not get an instance of policy engine", __FUNCTION__);
-        return NO_INIT;
-    }
-    // Retrieve the Policy Manager Interface
-    mEngine = engineInstance->queryInterface<AudioPolicyManagerInterface>();
-    if (mEngine == NULL) {
-        ALOGE("%s: Failed to get Policy Engine Interface", __FUNCTION__);
-        return NO_INIT;
+    {
+        auto engLib = EngineLibrary::load(
+                        "libaudiopolicyengine" + getConfig().getEngineLibraryNameSuffix() + ".so");
+        if (!engLib) {
+            ALOGE("%s: Failed to load the engine library", __FUNCTION__);
+            return NO_INIT;
+        }
+        mEngine = engLib->createEngine();
+        if (mEngine == nullptr) {
+            ALOGE("%s: Failed to instantiate the APM engine", __FUNCTION__);
+            return NO_INIT;
+        }
     }
     mEngine->setObserver(this);
     status_t status = mEngine->initCheck();
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 612bd8f..d88d1ec 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -34,7 +34,6 @@
 #include <media/PatchBuilder.h>
 #include "AudioPolicyInterface.h"
 
-#include <AudioPolicyManagerInterface.h>
 #include <AudioPolicyManagerObserver.h>
 #include <AudioGain.h>
 #include <AudioPolicyConfig.h>
@@ -49,6 +48,7 @@
 #include <AudioPolicyMix.h>
 #include <EffectDescriptor.h>
 #include <SoundTriggerSession.h>
+#include "EngineLibrary.h"
 #include "TypeConverter.h"
 
 namespace android {
@@ -752,7 +752,7 @@
         uint32_t nextAudioPortGeneration();
 
         // Audio Policy Engine Interface.
-        AudioPolicyManagerInterface *mEngine;
+        EngineInstance mEngine;
 
         // Surround formats that are enabled manually. Taken into account when
         // "encoded surround" is forced into "manual" mode.
diff --git a/services/audiopolicy/managerdefault/EngineLibrary.cpp b/services/audiopolicy/managerdefault/EngineLibrary.cpp
new file mode 100644
index 0000000..ef699aa
--- /dev/null
+++ b/services/audiopolicy/managerdefault/EngineLibrary.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2019 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_TAG "APM_EngineLoader"
+
+#include <dlfcn.h>
+#include <utils/Log.h>
+
+#include "EngineLibrary.h"
+
+namespace android {
+
+// static
+std::shared_ptr<EngineLibrary> EngineLibrary::load(std::string libraryPath)
+{
+    std::shared_ptr<EngineLibrary> engLib(new EngineLibrary());
+    return engLib->init(std::move(libraryPath)) ? engLib : nullptr;
+}
+
+EngineLibrary::~EngineLibrary()
+{
+    close();
+}
+
+bool EngineLibrary::init(std::string libraryPath)
+{
+    mLibraryHandle = dlopen(libraryPath.c_str(), 0);
+    if (mLibraryHandle == nullptr) {
+        ALOGE("Could not dlopen %s: %s", libraryPath.c_str(), dlerror());
+        return false;
+    }
+    mCreateEngineInstance = (EngineInterface* (*)())dlsym(mLibraryHandle, "createEngineInstance");
+    mDestroyEngineInstance = (void (*)(EngineInterface*))dlsym(
+            mLibraryHandle, "destroyEngineInstance");
+    if (mCreateEngineInstance == nullptr || mDestroyEngineInstance == nullptr) {
+        ALOGE("Could not find engine interface functions in %s", libraryPath.c_str());
+        close();
+        return false;
+    }
+    ALOGD("Loaded engine from %s", libraryPath.c_str());
+    return true;
+}
+
+EngineInstance EngineLibrary::createEngine()
+{
+    if (mCreateEngineInstance == nullptr || mDestroyEngineInstance == nullptr) {
+        return EngineInstance();
+    }
+    return EngineInstance(mCreateEngineInstance(),
+            [lib = shared_from_this(), destroy = mDestroyEngineInstance] (EngineInterface* e) {
+                destroy(e);
+            });
+}
+
+void EngineLibrary::close()
+{
+    if (mLibraryHandle != nullptr) {
+        dlclose(mLibraryHandle);
+    }
+    mLibraryHandle = nullptr;
+    mCreateEngineInstance = nullptr;
+    mDestroyEngineInstance = nullptr;
+}
+
+}  // namespace android
diff --git a/services/audiopolicy/managerdefault/EngineLibrary.h b/services/audiopolicy/managerdefault/EngineLibrary.h
new file mode 100644
index 0000000..f143916
--- /dev/null
+++ b/services/audiopolicy/managerdefault/EngineLibrary.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2019 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.
+ */
+
+#pragma once
+
+#include <functional>
+#include <memory>
+#include <string>
+
+#include <EngineInterface.h>
+
+namespace android {
+
+using EngineInstance = std::unique_ptr<EngineInterface, std::function<void (EngineInterface*)>>;
+
+class EngineLibrary : public std::enable_shared_from_this<EngineLibrary> {
+public:
+    static std::shared_ptr<EngineLibrary> load(std::string libraryPath);
+    ~EngineLibrary();
+
+    EngineLibrary(const EngineLibrary&) = delete;
+    EngineLibrary(EngineLibrary&&) = delete;
+    EngineLibrary& operator=(const EngineLibrary&) = delete;
+    EngineLibrary& operator=(EngineLibrary&&) = delete;
+
+    EngineInstance createEngine();
+
+private:
+    EngineLibrary() = default;
+    bool init(std::string libraryPath);
+    void close();
+
+    void *mLibraryHandle = nullptr;
+    EngineInterface* (*mCreateEngineInstance)() = nullptr;
+    void (*mDestroyEngineInstance)(EngineInterface*) = nullptr;
+};
+
+}  // namespace android
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index de5670c..e10a716 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -30,7 +30,16 @@
 
 using namespace android;
 
-TEST(AudioPolicyManagerTestInit, Failure) {
+TEST(AudioPolicyManagerTestInit, EngineFailure) {
+    AudioPolicyTestClient client;
+    AudioPolicyTestManager manager(&client);
+    manager.getConfig().setDefault();
+    manager.getConfig().setEngineLibraryNameSuffix("non-existent");
+    ASSERT_EQ(NO_INIT, manager.initialize());
+    ASSERT_EQ(NO_INIT, manager.initCheck());
+}
+
+TEST(AudioPolicyManagerTestInit, ClientFailure) {
     AudioPolicyTestClient client;
     AudioPolicyTestManager manager(&client);
     manager.getConfig().setDefault();
