Merge "MediaTesting: Add Mpeg4 H263 Decoder Test"
am: 5bebb2dfa9

Change-Id: Ib2cda3fa7c5b5bbc2d2bdb3c6ff151b7e1578e46
diff --git a/media/libstagefright/codecs/m4v_h263/dec/test/Android.bp b/media/libstagefright/codecs/m4v_h263/dec/test/Android.bp
new file mode 100644
index 0000000..e335c9b
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/test/Android.bp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2020 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_test {
+    name: "Mpeg4H263DecoderTest",
+    gtest: true,
+
+    srcs: [
+        "Mpeg4H263DecoderTest.cpp",
+    ],
+
+    shared_libs: [
+        "liblog",
+    ],
+
+    static_libs: [
+        "libstagefright_m4vh263dec",
+        "libstagefright_foundation",
+    ],
+
+    cflags: [
+        "-DOSCL_IMPORT_REF=",
+        "-Werror",
+        "-Wall",
+    ],
+
+    sanitize: {
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+        cfi: true,
+    },
+}
diff --git a/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTest.cpp b/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTest.cpp
new file mode 100644
index 0000000..967c1ea
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTest.cpp
@@ -0,0 +1,423 @@
+/*
+ * Copyright (C) 2020 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 "Mpeg4H263DecoderTest"
+#include <utils/Log.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <utils/String8.h>
+#include <fstream>
+
+#include <media/stagefright/foundation/AUtils.h>
+#include "mp4dec_api.h"
+
+#include "Mpeg4H263DecoderTestEnvironment.h"
+
+using namespace android;
+
+#define OUTPUT_FILE_NAME "/data/local/tmp/Output.yuv"
+#define CODEC_CONFIG_FLAG 32
+#define SYNC_FRAME 1
+#define MPEG4_MAX_WIDTH 1920
+#define MPEG4_MAX_HEIGHT 1080
+#define H263_MAX_WIDTH 352
+#define H263_MAX_HEIGHT 288
+
+constexpr uint32_t kNumOutputBuffers = 2;
+
+struct FrameInfo {
+    int32_t bytesCount;
+    uint32_t flags;
+    int64_t timestamp;
+};
+
+struct tagvideoDecControls;
+
+static Mpeg4H263DecoderTestEnvironment *gEnv = nullptr;
+
+class Mpeg4H263DecoderTest : public ::testing::TestWithParam<tuple<string, string, bool>> {
+  public:
+    Mpeg4H263DecoderTest()
+        : mDecHandle(nullptr),
+          mInputBuffer(nullptr),
+          mInitialized(false),
+          mFramesConfigured(false),
+          mNumSamplesOutput(0),
+          mWidth(352),
+          mHeight(288) {
+        memset(mOutputBuffer, 0x0, sizeof(mOutputBuffer));
+    }
+
+    ~Mpeg4H263DecoderTest() {
+        if (mEleStream.is_open()) mEleStream.close();
+        if (mDecHandle) {
+            delete mDecHandle;
+            mDecHandle = nullptr;
+        }
+        if (mInputBuffer) {
+            free(mInputBuffer);
+            mInputBuffer = nullptr;
+        }
+        freeOutputBuffer();
+    }
+
+    status_t initDecoder();
+    void allocOutputBuffer(size_t outputBufferSize);
+    void dumpOutput(ofstream &ostrm);
+    void freeOutputBuffer();
+    void processMpeg4H263Decoder(vector<FrameInfo> Info, int32_t offset, int32_t range,
+                                 ifstream &mEleStream, ofstream &ostrm, MP4DecodingMode inputMode);
+    void deInitDecoder();
+
+    ifstream mEleStream;
+    tagvideoDecControls *mDecHandle;
+    char *mInputBuffer;
+    uint8_t *mOutputBuffer[kNumOutputBuffers];
+    bool mInitialized;
+    bool mFramesConfigured;
+    uint32_t mNumSamplesOutput;
+    uint32_t mWidth;
+    uint32_t mHeight;
+};
+
+status_t Mpeg4H263DecoderTest::initDecoder() {
+    if (!mDecHandle) {
+        mDecHandle = new tagvideoDecControls;
+    }
+    if (!mDecHandle) {
+        return NO_MEMORY;
+    }
+    memset(mDecHandle, 0, sizeof(tagvideoDecControls));
+
+    return OK;
+}
+
+void Mpeg4H263DecoderTest::allocOutputBuffer(size_t outputBufferSize) {
+    for (int32_t i = 0; i < kNumOutputBuffers; ++i) {
+        if (!mOutputBuffer[i]) {
+            mOutputBuffer[i] = (uint8_t *)malloc(outputBufferSize);
+            ASSERT_NE(mOutputBuffer[i], nullptr) << "Output buffer allocation failed";
+        }
+    }
+}
+
+void Mpeg4H263DecoderTest::dumpOutput(ofstream &ostrm) {
+    uint8_t *src = mOutputBuffer[mNumSamplesOutput & 1];
+    size_t vStride = align(mHeight, 16);
+    size_t srcYStride = align(mWidth, 16);
+    size_t srcUVStride = srcYStride / 2;
+    uint8_t *srcStart = src;
+
+    /* Y buffer */
+    for (size_t i = 0; i < mHeight; ++i) {
+        ostrm.write(reinterpret_cast<char *>(src), mWidth);
+        src += srcYStride;
+    }
+    /* U buffer */
+    src = srcStart + vStride * srcYStride;
+    for (size_t i = 0; i < mHeight / 2; ++i) {
+        ostrm.write(reinterpret_cast<char *>(src), mWidth / 2);
+        src += srcUVStride;
+    }
+    /* V buffer */
+    src = srcStart + vStride * srcYStride * 5 / 4;
+    for (size_t i = 0; i < mHeight / 2; ++i) {
+        ostrm.write(reinterpret_cast<char *>(src), mWidth / 2);
+        src += srcUVStride;
+    }
+}
+
+void Mpeg4H263DecoderTest::freeOutputBuffer() {
+    for (int32_t i = 0; i < kNumOutputBuffers; ++i) {
+        if (mOutputBuffer[i]) {
+            free(mOutputBuffer[i]);
+            mOutputBuffer[i] = nullptr;
+        }
+    }
+}
+
+void Mpeg4H263DecoderTest::processMpeg4H263Decoder(vector<FrameInfo> Info, int32_t offset,
+                                                   int32_t range, ifstream &mEleStream,
+                                                   ofstream &ostrm, MP4DecodingMode inputMode) {
+    size_t maxWidth = (inputMode == MPEG4_MODE) ? MPEG4_MAX_WIDTH : H263_MAX_WIDTH;
+    size_t maxHeight = (inputMode == MPEG4_MODE) ? MPEG4_MAX_HEIGHT : H263_MAX_HEIGHT;
+    size_t outputBufferSize = align(maxWidth, 16) * align(maxHeight, 16) * 3 / 2;
+    uint32_t frameIndex = offset;
+    bool status = true;
+    ASSERT_GE(range, 0) << "Invalid range";
+    ASSERT_TRUE(offset >= 0 && offset <= Info.size() - 1) << "Invalid offset";
+    ASSERT_LE(range + offset, Info.size()) << "range+offset can't be greater than the no of frames";
+
+    while (1) {
+        if (frameIndex == Info.size() || frameIndex == (offset + range)) break;
+
+        int32_t bytesCount = Info[frameIndex].bytesCount;
+        ASSERT_GT(bytesCount, 0) << "Size for the memory allocation is negative";
+        mInputBuffer = (char *)malloc(bytesCount);
+        ASSERT_NE(mInputBuffer, nullptr) << "Insufficient memory to read frame";
+        mEleStream.read(mInputBuffer, bytesCount);
+        ASSERT_EQ(mEleStream.gcount(), bytesCount) << "mEleStream.gcount() != bytesCount";
+        static const uint8_t volInfo[] = {0x00, 0x00, 0x01, 0xB0};
+        bool volHeader = memcmp(mInputBuffer, volInfo, 4) == 0;
+        if (volHeader) {
+            PVCleanUpVideoDecoder(mDecHandle);
+            mInitialized = false;
+        }
+
+        if (!mInitialized) {
+            uint8_t *volData[1]{};
+            int32_t volSize = 0;
+
+            uint32_t flags = Info[frameIndex].flags;
+            bool codecConfig = flags == CODEC_CONFIG_FLAG;
+            if (codecConfig || volHeader) {
+                volData[0] = reinterpret_cast<uint8_t *>(mInputBuffer);
+                volSize = bytesCount;
+            }
+
+            status = PVInitVideoDecoder(mDecHandle, volData, &volSize, 1, maxWidth, maxHeight,
+                                        inputMode);
+            ASSERT_TRUE(status) << "PVInitVideoDecoder failed. Unsupported content";
+
+            mInitialized = true;
+            MP4DecodingMode actualMode = PVGetDecBitstreamMode(mDecHandle);
+            ASSERT_EQ(inputMode, actualMode)
+                    << "Decoded mode not same as actual mode of the decoder";
+
+            PVSetPostProcType(mDecHandle, 0);
+
+            int32_t dispWidth, dispHeight;
+            PVGetVideoDimensions(mDecHandle, &dispWidth, &dispHeight);
+
+            int32_t bufWidth, bufHeight;
+            PVGetBufferDimensions(mDecHandle, &bufWidth, &bufHeight);
+
+            ASSERT_LE(dispWidth, bufWidth) << "Display width is greater than buffer width";
+            ASSERT_LE(dispHeight, bufHeight) << "Display height is greater than buffer height";
+
+            if (dispWidth != mWidth || dispHeight != mHeight) {
+                mWidth = dispWidth;
+                mHeight = dispHeight;
+                freeOutputBuffer();
+                if (inputMode == H263_MODE) {
+                    PVCleanUpVideoDecoder(mDecHandle);
+
+                    uint8_t *volData[1]{};
+                    int32_t volSize = 0;
+
+                    status = PVInitVideoDecoder(mDecHandle, volData, &volSize, 1, maxWidth,
+                                                maxHeight, H263_MODE);
+                    ASSERT_TRUE(status) << "PVInitVideoDecoder failed for H263";
+                }
+                mFramesConfigured = false;
+            }
+
+            if (codecConfig) {
+                frameIndex++;
+                continue;
+            }
+        }
+
+        uint32_t yFrameSize = sizeof(uint8) * mDecHandle->size;
+        ASSERT_GE(outputBufferSize, yFrameSize * 3 / 2)
+                << "Too small output buffer: " << outputBufferSize << " bytes";
+        ASSERT_NO_FATAL_FAILURE(allocOutputBuffer(outputBufferSize));
+
+        if (!mFramesConfigured) {
+            PVSetReferenceYUV(mDecHandle, mOutputBuffer[1]);
+            mFramesConfigured = true;
+        }
+
+        // Need to check if header contains new info, e.g., width/height, etc.
+        VopHeaderInfo headerInfo;
+        uint32_t useExtTimestamp = 1;
+        int32_t inputSize = (Info)[frameIndex].bytesCount;
+        uint32_t timestamp = frameIndex;
+
+        uint8_t *bitstreamTmp = reinterpret_cast<uint8_t *>(mInputBuffer);
+
+        status = PVDecodeVopHeader(mDecHandle, &bitstreamTmp, &timestamp, &inputSize, &headerInfo,
+                                   &useExtTimestamp, mOutputBuffer[mNumSamplesOutput & 1]);
+        ASSERT_EQ(status, PV_TRUE) << "failed to decode vop header";
+
+        // H263 doesn't have VOL header, the frame size information is in short header, i.e. the
+        // decoder may detect size change after PVDecodeVopHeader.
+        int32_t dispWidth, dispHeight;
+        PVGetVideoDimensions(mDecHandle, &dispWidth, &dispHeight);
+
+        int32_t bufWidth, bufHeight;
+        PVGetBufferDimensions(mDecHandle, &bufWidth, &bufHeight);
+
+        ASSERT_LE(dispWidth, bufWidth) << "Display width is greater than buffer width";
+        ASSERT_LE(dispHeight, bufHeight) << "Display height is greater than buffer height";
+        if (dispWidth != mWidth || dispHeight != mHeight) {
+            mWidth = dispWidth;
+            mHeight = dispHeight;
+        }
+
+        status = PVDecodeVopBody(mDecHandle, &inputSize);
+        ASSERT_EQ(status, PV_TRUE) << "failed to decode video frame No = %d" << frameIndex;
+
+        dumpOutput(ostrm);
+
+        ++mNumSamplesOutput;
+        ++frameIndex;
+    }
+    freeOutputBuffer();
+}
+
+void Mpeg4H263DecoderTest::deInitDecoder() {
+    if (mInitialized) {
+        if (mDecHandle) {
+            PVCleanUpVideoDecoder(mDecHandle);
+            delete mDecHandle;
+            mDecHandle = nullptr;
+        }
+        mInitialized = false;
+    }
+    freeOutputBuffer();
+}
+
+void getInfo(string infoFileName, vector<FrameInfo> &Info) {
+    ifstream eleInfo;
+    eleInfo.open(infoFileName);
+    ASSERT_EQ(eleInfo.is_open(), true) << "Failed to open " << infoFileName;
+    int32_t bytesCount = 0;
+    uint32_t flags = 0;
+    uint32_t timestamp = 0;
+    while (1) {
+        if (!(eleInfo >> bytesCount)) {
+            break;
+        }
+        eleInfo >> flags;
+        eleInfo >> timestamp;
+        Info.push_back({bytesCount, flags, timestamp});
+    }
+    if (eleInfo.is_open()) eleInfo.close();
+}
+
+TEST_P(Mpeg4H263DecoderTest, DecodeTest) {
+    tuple<string /* InputFileName */, string /* InfoFileName */, bool /* mode */> params =
+            GetParam();
+
+    string inputFileName = gEnv->getRes() + get<0>(params);
+    mEleStream.open(inputFileName, ifstream::binary);
+    ASSERT_EQ(mEleStream.is_open(), true) << "Failed to open " << get<0>(params);
+
+    string infoFileName = gEnv->getRes() + get<1>(params);
+    vector<FrameInfo> Info;
+    ASSERT_NO_FATAL_FAILURE(getInfo(infoFileName, Info));
+    ASSERT_NE(Info.empty(), true) << "Invalid Info file";
+
+    ofstream ostrm;
+    ostrm.open(OUTPUT_FILE_NAME, std::ofstream::binary);
+    ASSERT_EQ(ostrm.is_open(), true) << "Failed to open output stream for " << get<0>(params);
+
+    status_t err = initDecoder();
+    ASSERT_EQ(err, OK) << "initDecoder: failed to create decoder " << err;
+
+    bool isMpeg4 = get<2>(params);
+    MP4DecodingMode inputMode = isMpeg4 ? MPEG4_MODE : H263_MODE;
+    ASSERT_NO_FATAL_FAILURE(
+            processMpeg4H263Decoder(Info, 0, Info.size(), mEleStream, ostrm, inputMode));
+    deInitDecoder();
+    ostrm.close();
+    Info.clear();
+}
+
+TEST_P(Mpeg4H263DecoderTest, FlushTest) {
+    tuple<string /* InputFileName */, string /* InfoFileName */, bool /* mode */> params =
+            GetParam();
+
+    string inputFileName = gEnv->getRes() + get<0>(params);
+    mEleStream.open(inputFileName, ifstream::binary);
+    ASSERT_EQ(mEleStream.is_open(), true) << "Failed to open " << get<0>(params);
+
+    string infoFileName = gEnv->getRes() + get<1>(params);
+    vector<FrameInfo> Info;
+    ASSERT_NO_FATAL_FAILURE(getInfo(infoFileName, Info));
+    ASSERT_NE(Info.empty(), true) << "Invalid Info file";
+
+    ofstream ostrm;
+    ostrm.open(OUTPUT_FILE_NAME, std::ofstream::binary);
+    ASSERT_EQ(ostrm.is_open(), true) << "Failed to open output stream for " << get<0>(params);
+
+    status_t err = initDecoder();
+    ASSERT_EQ(err, OK) << "initDecoder: failed to create decoder " << err;
+
+    bool isMpeg4 = get<2>(params);
+    MP4DecodingMode inputMode = isMpeg4 ? MPEG4_MODE : H263_MODE;
+    // Number of frames to be decoded before flush
+    int32_t numFrames = Info.size() / 3;
+    ASSERT_NO_FATAL_FAILURE(
+            processMpeg4H263Decoder(Info, 0, numFrames, mEleStream, ostrm, inputMode));
+
+    if (mInitialized) {
+        int32_t status = PVResetVideoDecoder(mDecHandle);
+        ASSERT_EQ(status, PV_TRUE);
+    }
+
+    // Seek to next key frame and start decoding till the end
+    int32_t index = numFrames;
+    bool keyFrame = false;
+    uint32_t flags = 0;
+    while (index < (int32_t)Info.size()) {
+        if (Info[index].flags) flags = 1u << (Info[index].flags - 1);
+        if ((flags & SYNC_FRAME) == SYNC_FRAME) {
+            keyFrame = true;
+            break;
+        }
+        flags = 0;
+        mEleStream.ignore(Info[index].bytesCount);
+        index++;
+    }
+    ALOGV("Index= %d", index);
+    if (keyFrame) {
+        mNumSamplesOutput = 0;
+        ASSERT_NO_FATAL_FAILURE(processMpeg4H263Decoder(Info, index, (int32_t)Info.size() - index,
+                                                        mEleStream, ostrm, inputMode));
+    }
+    deInitDecoder();
+    ostrm.close();
+    Info.clear();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        Mpeg4H263DecoderTestAll, Mpeg4H263DecoderTest,
+        ::testing::Values(make_tuple("swirl_128x96_h263.h263", "swirl_128x96_h263.info", false),
+                          make_tuple("swirl_176x144_h263.h263", "swirl_176x144_h263.info", false),
+                          make_tuple("swirl_352x288_h263.h263", "swirl_352x288_h263.info", false),
+                          make_tuple("bbb_352x288_h263.h263", "bbb_352x288_h263.info", false),
+                          make_tuple("bbb_352x288_mpeg4.m4v", "bbb_352x288_mpeg4.info", true),
+                          make_tuple("swirl_128x128_mpeg4.m4v", "swirl_128x128_mpeg4.info", true),
+                          make_tuple("swirl_130x132_mpeg4.m4v", "swirl_130x132_mpeg4.info", true),
+                          make_tuple("swirl_132x130_mpeg4.m4v", "swirl_132x130_mpeg4.info", true),
+                          make_tuple("swirl_136x144_mpeg4.m4v", "swirl_136x144_mpeg4.info", true),
+                          make_tuple("swirl_144x136_mpeg4.m4v", "swirl_144x136_mpeg4.info", true)));
+
+int main(int argc, char **argv) {
+    gEnv = new Mpeg4H263DecoderTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        ALOGD("Decoder Test Result = %d\n", status);
+    }
+    return status;
+}
diff --git a/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTestEnvironment.h b/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTestEnvironment.h
new file mode 100644
index 0000000..f085845
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/test/Mpeg4H263DecoderTestEnvironment.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 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 __MPEG4_H263_DECODER_TEST_ENVIRONMENT_H__
+#define __MPEG4_H263_DECODER_TEST_ENVIRONMENT_H__
+
+#include <gtest/gtest.h>
+
+#include <getopt.h>
+
+using namespace std;
+
+class Mpeg4H263DecoderTestEnvironment : public ::testing::Environment {
+  public:
+    Mpeg4H263DecoderTestEnvironment() : res("/data/local/tmp/") {}
+
+    // Parses the command line arguments
+    int initFromOptions(int argc, char **argv);
+
+    void setRes(const char *_res) { res = _res; }
+
+    const string getRes() const { return res; }
+
+  private:
+    string res;
+};
+
+int Mpeg4H263DecoderTestEnvironment::initFromOptions(int argc, char **argv) {
+    static struct option options[] = {{"path", required_argument, 0, 'P'}, {0, 0, 0, 0}};
+
+    while (true) {
+        int index = 0;
+        int c = getopt_long(argc, argv, "P:", options, &index);
+        if (c == -1) {
+            break;
+        }
+
+        switch (c) {
+            case 'P': {
+                setRes(optarg);
+                break;
+            }
+            default:
+                break;
+        }
+    }
+
+    if (optind < argc) {
+        fprintf(stderr,
+                "unrecognized option: %s\n\n"
+                "usage: %s <gtest options> <test options>\n\n"
+                "test options are:\n\n"
+                "-P, --path: Resource files directory location\n",
+                argv[optind ?: 1], argv[0]);
+        return 2;
+    }
+    return 0;
+}
+
+#endif  // __MPEG4_H263_DECODER_TEST_ENVIRONMENT_H__
diff --git a/media/libstagefright/codecs/m4v_h263/dec/test/README.md b/media/libstagefright/codecs/m4v_h263/dec/test/README.md
new file mode 100644
index 0000000..3f46529
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/test/README.md
@@ -0,0 +1,34 @@
+## Media Testing ##
+---
+#### Mpeg4H263Decoder :
+The Mpeg4H263Decoder Test Suite validates the Mpeg4 and H263 decoder available in libstagefright.
+
+Run the following steps to build the test suite:
+```
+m Mpeg4H263DecoderTest
+```
+
+The 32-bit binaries will be created in the following path : ${OUT}/data/nativetest/
+
+The 64-bit binaries will be created in the following path : ${OUT}/data/nativetest64/
+
+To test 64-bit binary push binaries from nativetest64.
+```
+adb push ${OUT}/data/nativetest64/Mpeg4H263DecoderTest/Mpeg4H263DecoderTest /data/local/tmp/
+```
+
+To test 32-bit binary push binaries from nativetest.
+```
+adb push ${OUT}/data/nativetest/Mpeg4H263DecoderTest/Mpeg4H263DecoderTest /data/local/tmp/
+```
+
+The resource file for the tests is taken from [here](https://drive.google.com/drive/folders/13cM4tAaVFrmr-zGFqaAzFBbKs75pnm9b).
+Download Mpeg4H263Decoder folder and push all the files in this folder to /data/local/tmp/ on the device for testing.
+```
+adb push Mpeg4H263Decoder/. /data/local/tmp/
+```
+
+usage: Mpeg4H263DecoderTest -P \<path_to_folder\>
+```
+adb shell /data/local/tmp/Mpeg4H263DecoderTest -P /data/local/tmp/
+```