[
  {
    "path": ".classpath",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<classpath>\n\t<classpathentry kind=\"src\" path=\"src\"/>\n\t<classpathentry kind=\"src\" path=\"gen\"/>\n\t<classpathentry kind=\"con\" path=\"com.android.ide.eclipse.adt.ANDROID_FRAMEWORK\"/>\n\t<classpathentry kind=\"con\" path=\"com.android.ide.eclipse.adt.LIBRARIES\"/>\n\t<classpathentry kind=\"lib\" path=\"libs/xom-1.2.7.jar\"/>\n\t<classpathentry kind=\"output\" path=\"bin/classes\"/>\n</classpath>\n"
  },
  {
    "path": ".gitignore",
    "content": "gen\nbin\nobj\n"
  },
  {
    "path": ".project",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projectDescription>\n\t<name>aac-enc</name>\n\t<comment></comment>\n\t<projects>\n\t</projects>\n\t<buildSpec>\n\t\t<buildCommand>\n\t\t\t<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t\t<buildCommand>\n\t\t\t<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t\t<buildCommand>\n\t\t\t<name>org.eclipse.jdt.core.javabuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t\t<buildCommand>\n\t\t\t<name>com.android.ide.eclipse.adt.ApkBuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t</buildSpec>\n\t<natures>\n\t\t<nature>com.android.ide.eclipse.adt.AndroidNature</nature>\n\t\t<nature>org.eclipse.jdt.core.javanature</nature>\n\t</natures>\n</projectDescription>\n"
  },
  {
    "path": "AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.todoroo.aacenc\"\n    android:versionCode=\"1\"\n    android:versionName=\"1.0\" >\n\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.RECORD_AUDIO\" />\n    <uses-permission android:name=\"android.permission.INTERNET\"/>\n    \n\n    <uses-sdk android:minSdkVersion=\"7\" />\n\n    <application\n        android:icon=\"@drawable/ic_launcher\"\n        android:label=\"@string/app_name\" >\n        <activity\n            android:label=\"@string/app_name\"\n            android:name=\".Main\" >\n            <intent-filter >\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "README.md",
    "content": "Android AAC Encoder project\n============================\n\nExtraction of Android Stagefright VO AAC encoder with a nice Java API.\n\nIn addition, includes a patched [MP4Parser](http://code.google.com/p/mp4parser) Java library for wrapping AAC files in an MP4 container to produce M4A audio files playable by Google Chrome and Apple QuickTime.\n\nThis project is set up as a single Eclipse project with a Main.java example activity. AAC encoding logic is found in jni/aac-enc.c, which needs to be built with the [Android NDK](https://developer.android.com/ndk/index.html). I used NDK r7c, but any version should work.\n\nFor more information, check out the [original blog article](http://betaful.com/post/82668810035/encoding-aac-audio-in-android).\n\nWhy?\n----\n\n- smaller code footprint than FFmpeg (< 500k compared to > 2M)\n- less native code to compile = less work to support new architectures\n- easiest way to make an M4A file\n\n\nLicense\n-------\n\nThis project is released under the [Apache License, version 2](http://www.apache.org/licenses/LICENSE-2.0)\n\nPatents\n-------\n\nThis project grants you no rights to any of the patents this technology may require. However, since Android version 4.0 and up ship with the Stagefright VO AAC encoder, it is my understanding that you can release code that depends on these libraries for any version of Android. Please note that I am not a lawyer.\n\n\nHave changes?\n-------------\n\nPull requests are accepted!\n"
  },
  {
    "path": "build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project name=\"Main\" default=\"help\">\n\n    <!-- The local.properties file is created and updated by the 'android' tool.\n         It contains the path to the SDK. It should *NOT* be checked into\n         Version Control Systems. -->\n    <property file=\"local.properties\" />\n\n    <!-- The ant.properties file can be created by you. It is only edited by the\n         'android' tool to add properties to it.\n         This is the place to change some Ant specific build properties.\n         Here are some properties you may want to change/update:\n\n         source.dir\n             The name of the source directory. Default is 'src'.\n         out.dir\n             The name of the output directory. Default is 'bin'.\n\n         For other overridable properties, look at the beginning of the rules\n         files in the SDK, at tools/ant/build.xml\n\n         Properties related to the SDK location or the project target should\n         be updated using the 'android' tool with the 'update' action.\n\n         This file is an integral part of the build system for your\n         application and should be checked into Version Control Systems.\n\n         -->\n    <property file=\"ant.properties\" />\n\n    <!-- The project.properties file is created and updated by the 'android'\n         tool, as well as ADT.\n\n         This contains project specific properties such as project target, and library\n         dependencies. Lower level build properties are stored in ant.properties\n         (or in .classpath for Eclipse projects).\n\n         This file is an integral part of the build system for your\n         application and should be checked into Version Control Systems. -->\n    <loadproperties srcFile=\"project.properties\" />\n\n    <!-- quick check on sdk.dir -->\n    <fail\n            message=\"sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through an env var\"\n            unless=\"sdk.dir\"\n    />\n\n\n<!-- extension targets. Uncomment the ones where you want to do custom work\n     in between standard targets -->\n<!--\n    <target name=\"-pre-build\">\n    </target>\n    <target name=\"-pre-compile\">\n    </target>\n\n    /* This is typically used for code obfuscation.\n       Compiled code location: ${out.classes.absolute.dir}\n       If this is not done in place, override ${out.dex.input.absolute.dir} */\n    <target name=\"-post-compile\">\n    </target>\n-->\n\n    <!-- Import the actual build file.\n\n         To customize existing targets, there are two options:\n         - Customize only one target:\n             - copy/paste the target into this file, *before* the\n               <import> task.\n             - customize it to your needs.\n         - Customize the whole content of build.xml\n             - copy/paste the content of the rules files (minus the top node)\n               into this file, replacing the <import> task.\n             - customize to your needs.\n\n         ***********************\n         ****** IMPORTANT ******\n         ***********************\n         In all cases you must update the value of version-tag below to read 'custom' instead of an integer,\n         in order to avoid having your file be overridden by tools such as \"android update project\"\n    -->\n    <!-- version-tag: 1 -->\n    <import file=\"${sdk.dir}/tools/ant/build.xml\" />\n\n</project>\n"
  },
  {
    "path": "jni/Android.mk",
    "content": "LOCAL_PATH := $(call my-dir)\n\ninclude $(CLEAR_VARS)\ninclude $(LOCAL_PATH)/Config.mk\n\nLOCAL_MODULE := aac-encoder\n\nENC_SRC := src\n\nLOCAL_C_INCLUDES := $(LOCAL_PATH)/inc\n\nLOCAL_SRC_FILES = \\\n    aac-enc.c \\\n    $(ENC_SRC)/cmnMemory.c \\\n    basic_op/basicop2.c \\\n    basic_op/oper_32b.c \\\n    $(ENC_SRC)/aac_rom.c \\\n    $(ENC_SRC)/aacenc.c \\\n    $(ENC_SRC)/aacenc_core.c \\\n    $(ENC_SRC)/adj_thr.c \\\n    $(ENC_SRC)/band_nrg.c \\\n    $(ENC_SRC)/bit_cnt.c \\\n    $(ENC_SRC)/bitbuffer.c \\\n    $(ENC_SRC)/bitenc.c \\\n    $(ENC_SRC)/block_switch.c \\\n    $(ENC_SRC)/channel_map.c \\\n    $(ENC_SRC)/dyn_bits.c \\\n    $(ENC_SRC)/grp_data.c \\\n    $(ENC_SRC)/interface.c \\\n    $(ENC_SRC)/line_pe.c \\\n    $(ENC_SRC)/memalign.c \\\n    $(ENC_SRC)/ms_stereo.c \\\n    $(ENC_SRC)/pre_echo_control.c \\\n    $(ENC_SRC)/psy_configuration.c \\\n    $(ENC_SRC)/psy_main.c \\\n    $(ENC_SRC)/qc_main.c \\\n    $(ENC_SRC)/quantize.c \\\n    $(ENC_SRC)/sf_estim.c \\\n    $(ENC_SRC)/spreading.c \\\n    $(ENC_SRC)/stat_bits.c \\\n    $(ENC_SRC)/tns.c \\\n    $(ENC_SRC)/transform.c\n\nifeq ($(VOTT), v5)\nLOCAL_SRC_FILES += \\\n\t$(ENC_SRC)/asm/ARMV5E/AutoCorrelation_v5.s \\\n\t$(ENC_SRC)/asm/ARMV5E/band_nrg_v5.s \\\n\t$(ENC_SRC)/asm/ARMV5E/CalcWindowEnergy_v5.s \\\n\t$(ENC_SRC)/asm/ARMV5E/PrePostMDCT_v5.s \\\n\t$(ENC_SRC)/asm/ARMV5E/R4R8First_v5.s \\\n\t$(ENC_SRC)/asm/ARMV5E/Radix4FFT_v5.s\nendif\n\nifeq ($(VOTT), v7)\nLOCAL_SRC_FILES += \\\n\t$(ENC_SRC)/asm/ARMV5E/AutoCorrelation_v5.s \\\n\t$(ENC_SRC)/asm/ARMV5E/band_nrg_v5.s \\\n\t$(ENC_SRC)/asm/ARMV5E/CalcWindowEnergy_v5.s \\\n\t$(ENC_SRC)/asm/ARMV7/PrePostMDCT_v7.s \\\n\t$(ENC_SRC)/asm/ARMV7/R4R8First_v7.s \\\n\t$(ENC_SRC)/asm/ARMV7/Radix4FFT_v7.s\nendif\n\nLOCAL_ARM_MODE := arm\n\nLOCAL_LDLIBS := -llog\n\nLOCAL_STATIC_LIBRARIES := \nLOCAL_SHARED_LIBRARIES :=\n\nLOCAL_CFLAGS := $(VO_CFLAGS)\n\nifeq ($(VOTT), v5)\nLOCAL_CFLAGS += -DARMV5E -DARM_INASM -DARMV5_INASM\nLOCAL_C_INCLUDES += $(ENC_SRC)/asm/ARMV5E\nendif\n\nifeq ($(VOTT), v7)\nLOCAL_CFLAGS += -DARMV5E -DARMV7Neon -DARM_INASM -DARMV5_INASM -DARMV6_INASM\nLOCAL_C_INCLUDES += $(ENC_SRC)/asm/ARMV5E\nLOCAL_C_INCLUDES += $(ENC_SRC)/asm/ARMV7\nendif\n\ninclude $(BUILD_SHARED_LIBRARY)\n\n"
  },
  {
    "path": "jni/Config.mk",
    "content": "#\n# This configure file is just for Linux projects against Android\n#\n\nVOPRJ :=\nVONJ :=\n\n# WARNING:\n# Using v7 breaks generic build\nifeq ($(TARGET_ARCH),arm)\nVOTT := v5\nelse\nVOTT := pc\nendif\n\n# Do we also need to check on ARCH_ARM_HAVE_ARMV7A? - probably not\nifeq ($(ARCH_ARM_HAVE_NEON),true)\nVOTT := v7\nendif\n\nVOTEST := 0\n\nVO_CFLAGS:=-DLINUX\n\n"
  },
  {
    "path": "jni/aac-enc.c",
    "content": "#include <string.h>\n#include <stdio.h>\n#include <jni.h>\n#include <inc/voAAC.h>\n#include <inc/cmnMemory.h>\n#include <android/log.h> \n\n#define DEBUG 0\n\n#if DEBUG\n#define LOG(msg, args...) __android_log_print(ANDROID_LOG_ERROR, \"aac-enc\", msg, ## args)\n#else\n#define LOG(msg, args...)\n#endif\n\n/* utility functions */\n\nvoid throwException(JNIEnv* env, const char *name, const char *msg)\n{\n  jclass cls = (*env)->FindClass(env, name);\n  /* if cls is NULL, an exception has already been thrown */\n  if (cls != NULL) {\n    (*env)->ThrowNew(env, cls, msg);\n  }\n  /* free the local ref */\n  (*env)->DeleteLocalRef(env, cls);\n}\n\n/* internal storage */\n\nFILE* outfile;\n\nVO_AUDIO_CODECAPI codec_api;\nVO_HANDLE handle = 0;\nVO_AUDIO_CODECAPI codec_api = { 0 };\nVO_MEM_OPERATOR mem_operator = { 0 };\nVO_CODEC_INIT_USERDATA user_data;\nAACENC_PARAM params = { 0 };\n\n/* java native functions */\n\nvoid\nJava_com_todoroo_aacenc_AACEncoder_init( JNIEnv* env,\n                                         jobject thiz,\n                                         int bitrate,\n                                         int channels,\n                                         int sampleRate,\n                                         int bitsPerSample,\n                                         jstring outputFile)\n{\n\n  if (bitsPerSample != 16) {\n    throwException(env, \"java/lang/IllegalArgumentException\", \n                   \"Unsupported sample depth. Only 16 bits per sample is supported\");\n    return;\n  }\n  \n  voGetAACEncAPI(&codec_api);\n\n  mem_operator.Alloc = cmnMemAlloc;\n  mem_operator.Copy = cmnMemCopy;\n  mem_operator.Free = cmnMemFree;\n  mem_operator.Set = cmnMemSet;\n  mem_operator.Check = cmnMemCheck;\n  user_data.memflag = VO_IMF_USERMEMOPERATOR;\n  user_data.memData = &mem_operator;\n  codec_api.Init(&handle, VO_AUDIO_CodingAAC, &user_data);\n\n  params.sampleRate = sampleRate;\n  params.bitRate = bitrate;\n  params.nChannels = channels;\n  params.adtsUsed = 1;\n\n  if (codec_api.SetParam(handle, VO_PID_AAC_ENCPARAM, &params) != VO_ERR_NONE) {\n    throwException(env, \"java/lang/IllegalArgumentException\", \n                   \"Unable to set encoding parameters\");\n    return;\n  }\n\n  const char* output_file = (*env)->GetStringUTFChars(env, outputFile, (jboolean) 0);\n  outfile = fopen(output_file, \"wb\");\n  LOG(\"writing to %s\", output_file);\n  (*env)->ReleaseStringUTFChars(env, outputFile, output_file);\n\n  LOG(\"initialized handle: %x\", handle);\n\n}\n\nvoid\nJava_com_todoroo_aacenc_AACEncoder_encode( JNIEnv* env,\n                                           jobject thiz,\n                                           jbyteArray inputArray)\n{\n\n  LOG(\"writing to handle: %x\", handle);\n\n  jbyte* buffer = (*env)->GetByteArrayElements(env, inputArray, (jboolean) 0);\n  int inputSize = (*env)->GetArrayLength(env, inputArray);\n\n  VO_CODECBUFFER input = { 0 }, output = { 0 };\n  VO_AUDIO_OUTPUTINFO output_info = { 0 };\n\n  int readSize = params.nChannels * 2 * 1024;\n  uint16_t* outbuf = (uint16_t*) malloc(readSize * 2);\n\n  LOG(\"input buffer: %d\", inputSize);\n\n  /* GET OUTPUT DATA */\n  int i;\n  int byteLeft = inputSize;\n\n  for(i = 0; i < inputSize; i += readSize) {\n\n    input.Buffer = buffer + i;\n    input.Length = (byteLeft < readSize) ? byteLeft : readSize;\n    codec_api.SetInputData(handle, &input);\n\n    output.Buffer = outbuf;\n    output.Length = readSize * 2;\n\n    int status = codec_api.GetOutputData(handle, &output, &output_info);\n    if (status == VO_ERR_INPUT_BUFFER_SMALL)\n      break;\n\n    if (status == VO_ERR_OUTPUT_BUFFER_SMALL) {\n      LOG(\"output buffer was too small, read %d\", output_info.InputUsed);\n    } else if (status != VO_ERR_NONE) {\n      char message[100];\n      sprintf(message, \"Unable to encode frame: %x\", status);\n      throwException(env, \"java/lang/RuntimeException\", message);\n      return;\n    }\n\n    fwrite(outbuf, 1, output.Length, outfile);\n    byteLeft -= readSize;\n  }\n\n  LOG(\"finished output\");\n  (*env)->ReleaseByteArrayElements(env, inputArray, buffer, JNI_ABORT);\n  free(outbuf);\n}\n\nvoid\nJava_com_todoroo_aacenc_AACEncoder_uninit( JNIEnv* env,\n                                           jobject thiz)\n{\n\n  fclose(outfile);\n  codec_api.Uninit(handle);\n\n}\n\nJNIEXPORT jint JNICALL \nJNI_OnLoad (JavaVM * vm, void * reserved) \n{ \n  return JNI_VERSION_1_6; \n} \n"
  },
  {
    "path": "jni/basic_op/basicop2.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tbasicop2.c\n\n\tContent:\tBasic arithmetic operators.\n\n*******************************************************************************/\n\n#include \"typedef.h\"\n#include \"basic_op.h\"\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Functions                                                               |\n |___________________________________________________________________________|\n*/\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : saturate                                                |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |    Limit the 32 bit input to the range of a 16 bit word.                  |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1                                                                 |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.                 |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\n\n#if (!SATRUATE_IS_INLINE)\nWord16 saturate(Word32 L_var1)\n{\n    Word16 var_out;\n\n    if (L_var1 > 0X00007fffL)\n    {\n        var_out = MAX_16;\n    }\n    else if (L_var1 < (Word32) 0xffff8000L)\n    {\n        var_out = MIN_16;\n    }\n    else\n    {\n        var_out = extract_l(L_var1);\n    }\n\n    return (var_out);\n}\n#endif\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : add                                                     |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |    Performs the addition (var1+var2) with overflow control and saturation;|\n |    the 16 bit result is set at +32767 when overflow occurs or at -32768   |\n |    when underflow occurs.                                                 |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\n\n#if (!ADD_IS_INLINE)\nWord16 add (Word16 var1, Word16 var2)\n{\n    Word16 var_out;\n    Word32 L_sum;\n\n    L_sum = (Word32)var1 + (Word32)var2;\n    var_out = saturate(L_sum);\n\n    return (var_out);\n}\n#endif\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : sub                                                     |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |    Performs the subtraction (var1+var2) with overflow control and satu-   |\n |    ration; the 16 bit result is set at +32767 when overflow occurs or at  |\n |    -32768 when underflow occurs.                                          |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\n#if (!SUB_IS_INLINE)\nWord16 sub(Word16 var1, Word16 var2)\n{\n    Word16 var_out;\n    Word32 L_diff;\n\n    L_diff = (Word32) var1 - var2;\n    var_out = saturate(L_diff);\n\n    return (var_out);\n}\n#endif\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : abs_s                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |    Absolute value of var1; abs_s(-32768) = 32767.                         |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0x0000 0000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\n//Word16 abs_s (Word16 var1)\n//{\n//    Word16 var_out;\n//\n//    if (var1 == MIN_16)\n//    {\n//        var_out = MAX_16;\n//    }\n//    else\n//    {\n//        if (var1 < 0)\n//        {\n//            var_out = (Word16)-var1;\n//        }\n//        else\n//        {\n//            var_out = var1;\n//        }\n//    }\n//\n//    return (var_out);\n//}\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : shl                                                     |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Arithmetically shift the 16 bit input var1 left var2 positions.Zero fill|\n |   the var2 LSB of the result. If var2 is negative, arithmetically shift   |\n |   var1 right by -var2 with sign extension. Saturate the result in case of |\n |   underflows or overflows.                                                |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\n\n#if (!SHL_IS_INLINE)\nWord16 shl (Word16 var1, Word16 var2)\n{\n    Word16 var_out;\n    Word32 result;\n\n    if (var2 < 0)\n    {\n        if (var2 < -16)\n            var2 = -16;\n        var_out = shr (var1, (Word16)-var2);\n    }\n    else\n    {\n        result = (Word32) var1 *((Word32) 1 << var2);\n\n        if ((var2 > 15 && var1 != 0) || (result != (Word32) ((Word16) result)))\n        {\n            //Overflow = 1;\n            var_out = (Word16)((var1 > 0) ? MAX_16 : MIN_16);\n        }\n        else\n        {\n            var_out = extract_l(result);\n        }\n    }\n\n    return (var_out);\n}\n#endif\n// end\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : shr                                                     |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Arithmetically shift the 16 bit input var1 right var2 positions with    |\n |   sign extension. If var2 is negative, arithmetically shift var1 left by  |\n |   -var2 with sign extension. Saturate the result in case of underflows or |\n |   overflows.                                                              |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\n\n#if (!SHR_IS_INLINE)\nWord16 shr (Word16 var1, Word16 var2)\n{\n    Word16 var_out;\n\n    if (var2 < 0)\n    {\n        if (var2 < -16)\n            var2 = -16;\n        var_out = shl (var1, (Word16)-var2);\n    }\n    else\n    {\n        if (var2 >= 15)\n        {\n            var_out = (Word16)((var1 < 0) ? -1 : 0);\n        }\n        else\n        {\n            if (var1 < 0)\n            {\n                var_out = (Word16)(~((~var1) >> var2));\n            }\n            else\n            {\n                var_out = (Word16)(var1 >> var2);\n            }\n        }\n    }\n\n    return (var_out);\n}\n#endif\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : mult                                                    |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |    Performs the multiplication of var1 by var2 and gives a 16 bit result  |\n |    which is scaled i.e.:                                                  |\n |             mult(var1,var2) = extract_l(L_shr((var1 times var2),15)) and  |\n |             mult(-32768,-32768) = 32767.                                  |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\n#if (!MULT_IS_INLINE)\nWord16 mult (Word16 var1, Word16 var2)\n{\n    Word16 var_out;\n    Word32 L_product;\n\n    L_product = (Word32) var1 *(Word32) var2;\n\n    L_product = (L_product & (Word32) 0xffff8000L) >> 15;\n\n    if (L_product & (Word32) 0x00010000L)\n        L_product = L_product | (Word32) 0xffff0000L;\n\n    var_out = saturate(L_product);\n\n    return (var_out);\n}\n#endif\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_mult                                                  |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   L_mult is the 32 bit result of the multiplication of var1 times var2    |\n |   with one shift left i.e.:                                               |\n |        L_mult(var1,var2) = L_shl((var1 times var2),1) and                 |\n |        L_mult(-32768,-32768) = 2147483647.                                |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |\n |___________________________________________________________________________|\n*/\n\n#if (!L_MULT_IS_INLINE)\nWord32 L_mult(Word16 var1, Word16 var2)\n{\n    Word32 L_var_out;\n\n    L_var_out = (Word32) var1 *(Word32) var2;\n\n    if (L_var_out != (Word32) 0x40000000L)\n    {\n        L_var_out <<= 1;\n    }\n    else\n    {\n        L_var_out = MAX_32;\n    }\n\n    return (L_var_out);\n}\n#endif\n// end\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : negate                                                  |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Negate var1 with saturation, saturate in the case where input is -32768:|\n |                negate(var1) = sub(0,var1).                                |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\n//Word16 negate (Word16 var1)\n//{\n//    Word16 var_out;\n//\n//    var_out = (Word16)((var1 == MIN_16) ? MAX_16 : -var1);\n//\n//    return (var_out);\n//}\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : extract_h                                               |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Return the 16 MSB of L_var1.                                            |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1                                                                 |\n |             32 bit long signed integer (Word32 ) whose value falls in the |\n |             range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.                 |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\n#if (!EXTRACT_H_IS_INLINE)\nWord16 extract_h (Word32 L_var1)\n{\n    Word16 var_out;\n\n    var_out = (Word16) (L_var1 >> 16);\n\n    return (var_out);\n}\n#endif\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : extract_l                                               |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Return the 16 LSB of L_var1.                                            |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1                                                                 |\n |             32 bit long signed integer (Word32 ) whose value falls in the |\n |             range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.                 |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\n#if (!EXTRACT_L_IS_INLINE)\nWord16 extract_l(Word32 L_var1)\n{\n    Word16 var_out;\n\n    var_out = (Word16) L_var1;\n\n    return (var_out);\n}\n#endif\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : round                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Round the lower 16 bits of the 32 bit input number into the MS 16 bits  |\n |   with saturation. Shift the resulting bits right by 16 and return the 16 |\n |   bit number:                                                             |\n |               round(L_var1) = extract_h(L_add(L_var1,32768))              |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1                                                                 |\n |             32 bit long signed integer (Word32 ) whose value falls in the |\n |             range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.                 |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\n\n#if (!ROUND_IS_INLINE)\nWord16 round16(Word32 L_var1)\n{\n    Word16 var_out;\n    Word32 L_rounded;\n\n    L_rounded = L_add (L_var1, (Word32) 0x00008000L);\n    var_out = extract_h (L_rounded);\n\n    return (var_out);\n}\n#endif\n// end\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_mac                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Multiply var1 by var2 and shift the result left by 1. Add the 32 bit    |\n |   result to L_var3 with saturation, return a 32 bit result:               |\n |        L_mac(L_var3,var1,var2) = L_add(L_var3,L_mult(var1,var2)).         |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var3   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |\n |___________________________________________________________________________|\n*/\n#if (!L_MSU_IS_INLINE)\nWord32 L_mac (Word32 L_var3, Word16 var1, Word16 var2)\n{\n    Word32 L_var_out;\n    Word32 L_product;\n\n    L_product = L_mult(var1, var2);\n    L_var_out = L_add (L_var3, L_product);\n\n    return (L_var_out);\n}\n#endif\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_msu                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Multiply var1 by var2 and shift the result left by 1. Subtract the 32   |\n |   bit result to L_var3 with saturation, return a 32 bit result:           |\n |        L_msu(L_var3,var1,var2) = L_sub(L_var3,L_mult(var1,var2)).         |\n |                                                                           |\n |   Complexity weight : 1                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var3   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |\n |___________________________________________________________________________|\n*/\n\n#if (!L_MSU_IS_INLINE)\nWord32 L_msu (Word32 L_var3, Word16 var1, Word16 var2)\n{\n    Word32 L_var_out;\n    Word32 L_product;\n\n    L_product = L_mult(var1, var2);\n    L_var_out = L_sub (L_var3, L_product);\n\n    return (L_var_out);\n}\n#endif\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_add                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   32 bits addition of the two 32 bits variables (L_var1+L_var2) with      |\n |   overflow control and saturation; the result is set at +2147483647 when  |\n |   overflow occurs or at -2147483648 when underflow occurs.                |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |    L_var2   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |\n |___________________________________________________________________________|\n*/\n#if (!L_ADD_IS_INLINE)\nWord32 L_add (Word32 L_var1, Word32 L_var2)\n{\n    Word32 L_var_out;\n\n    L_var_out = L_var1 + L_var2;\n\n    if (((L_var1 ^ L_var2) & MIN_32) == 0)\n    {\n        if ((L_var_out ^ L_var1) & MIN_32)\n        {\n            L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;\n            //Overflow = 1;\n        }\n    }\n\n    return (L_var_out);\n}\n#endif\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_sub                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with   |\n |   overflow control and saturation; the result is set at +2147483647 when  |\n |   overflow occurs or at -2147483648 when underflow occurs.                |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |    L_var2   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |\n |___________________________________________________________________________|\n*/\n#if (!L_SUB_IS_INLINE)\nWord32 L_sub(Word32 L_var1, Word32 L_var2)\n{\n    Word32 L_var_out;\n\n    L_var_out = L_var1 - L_var2;\n\n    if (((L_var1 ^ L_var2) & MIN_32) != 0)\n    {\n        if ((L_var_out ^ L_var1) & MIN_32)\n        {\n            L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32;\n            //Overflow = 1;\n        }\n    }\n\n    return (L_var_out);\n}\n#endif\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_negate                                                |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Negate the 32 bit variable L_var1 with saturation; saturate in the case |\n |   where input is -2147483648 (0x8000 0000).                               |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |\n |___________________________________________________________________________|\n*/\n//Word32 L_negate (Word32 L_var1)\n//{\n//    Word32 L_var_out;\n//\n//    L_var_out = (L_var1 == MIN_32) ? MAX_32 : -L_var1;\n//\n//    return (L_var_out);\n//}\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : mult_r                                                  |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Same as mult with rounding, i.e.:                                       |\n |     mult_r(var1,var2) = extract_l(L_shr(((var1 * var2) + 16384),15)) and  |\n |     mult_r(-32768,-32768) = 32767.                                        |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\n#if (!MULT_R_IS_INLINE)\nWord16 mult_r (Word16 var1, Word16 var2)\n{\n    Word16 var_out;\n    Word32 L_product_arr;\n\n    L_product_arr = (Word32) var1 *(Word32) var2;       /* product */\n    L_product_arr += (Word32) 0x00004000L;      /* round */\n    L_product_arr &= (Word32) 0xffff8000L;\n    L_product_arr >>= 15;       /* shift */\n\n    if (L_product_arr & (Word32) 0x00010000L)   /* sign extend when necessary */\n    {\n        L_product_arr |= (Word32) 0xffff0000L;\n    }\n    var_out = saturate(L_product_arr);\n\n    return (var_out);\n}\n#endif\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_shl                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero  |\n |   fill the var2 LSB of the result. If var2 is negative, arithmetically    |\n |   shift L_var1 right by -var2 with sign extension. Saturate the result in |\n |   case of underflows or overflows.                                        |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |\n |___________________________________________________________________________|\n*/\n\n#if (!L_SHL_IS_INLINE)\nWord32 L_shl (Word32 L_var1, Word16 var2)\n{\n    Word32 L_var_out = 0L;\n\n    if (var2 <= 0)\n    {\n        L_var1 = L_shr(L_var1, (Word16)-var2);\n    }\n    else\n    {\n        for (; var2 > 0; var2--)\n        {\n            if (L_var1 > (Word32) 0X3fffffffL)\n            {\n                return MAX_32;\n            }\n            else\n            {\n                if (L_var1 < (Word32) 0xc0000000L)\n                {\n                    return MIN_32;\n                }\n            }\n            L_var1 <<= 1;\n        }\n    }\n    return (L_var1);\n}\n#endif\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_shr                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Arithmetically shift the 32 bit input L_var1 right var2 positions with  |\n |   sign extension. If var2 is negative, arithmetically shift L_var1 left   |\n |   by -var2 and zero fill the -var2 LSB of the result. Saturate the result |\n |   in case of underflows or overflows.                                     |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |\n |___________________________________________________________________________|\n*/\n\n#if (!L_SHR_IS_INLINE)\nWord32 L_shr (Word32 L_var1, Word16 var2)\n{\n    Word32 L_var_out;\n\n    if (var2 < 0)\n    {\n        L_var_out = L_shl (L_var1, (Word16)-var2);\n    }\n    else\n    {\n        if (var2 >= 31)\n        {\n            L_var_out = (L_var1 < 0L) ? -1 : 0;\n        }\n        else\n        {\n            if (L_var1 < 0)\n            {\n                L_var_out = ~((~L_var1) >> var2);\n            }\n            else\n            {\n                L_var_out = L_var1 >> var2;\n            }\n        }\n    }\n    return (L_var_out);\n}\n#endif\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : shr_r                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Same as shr(var1,var2) but with rounding. Saturate the result in case of|\n |   underflows or overflows :                                               |\n |    - If var2 is greater than zero :                                       |\n |          if (sub(shl(shr(var1,var2),1),shr(var1,sub(var2,1))))            |\n |          is equal to zero                                                 |\n |                     then                                                  |\n |                     shr_r(var1,var2) = shr(var1,var2)                     |\n |                     else                                                  |\n |                     shr_r(var1,var2) = add(shr(var1,var2),1)              |\n |    - If var2 is less than or equal to zero :                              |\n |                     shr_r(var1,var2) = shr(var1,var2).                    |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\n#if (!SHR_R_IS_INLINE)\nWord16 shr_r (Word16 var1, Word16 var2)\n{\n    Word16 var_out;\n\n    if (var2 > 15)\n    {\n        var_out = 0;\n    }\n    else\n    {\n        var_out = shr (var1, var2);\n\n        if (var2 > 0)\n        {\n            if ((var1 & ((Word16) 1 << (var2 - 1))) != 0)\n            {\n                var_out++;\n            }\n        }\n    }\n\n    return (var_out);\n}\n#endif\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : mac_r                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Multiply var1 by var2 and shift the result left by 1. Add the 32 bit    |\n |   result to L_var3 with saturation. Round the LS 16 bits of the result    |\n |   into the MS 16 bits with saturation and shift the result right by 16.   |\n |   Return a 16 bit result.                                                 |\n |            mac_r(L_var3,var1,var2) = round(L_mac(L_var3,var1,var2))       |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var3   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0x0000 8000 <= L_var_out <= 0x0000 7fff.              |\n |___________________________________________________________________________|\n*/\n#if (!MAC_R_IS_INLINE)\nWord16 mac_r (Word32 L_var3, Word16 var1, Word16 var2)\n{\n    Word16 var_out;\n\n    L_var3 = L_mac (L_var3, var1, var2);\n    L_var3 = L_add (L_var3, (Word32) 0x00008000L);\n    var_out = extract_h (L_var3);\n\n    return (var_out);\n}\n#endif\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : msu_r                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Multiply var1 by var2 and shift the result left by 1. Subtract the 32   |\n |   bit result to L_var3 with saturation. Round the LS 16 bits of the res-  |\n |   ult into the MS 16 bits with saturation and shift the result right by   |\n |   16. Return a 16 bit result.                                             |\n |            msu_r(L_var3,var1,var2) = round(L_msu(L_var3,var1,var2))       |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var3   32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0x0000 8000 <= L_var_out <= 0x0000 7fff.              |\n |___________________________________________________________________________|\n*/\n#if (!MSU_R_IS_INLINE)\nWord16 msu_r (Word32 L_var3, Word16 var1, Word16 var2)\n{\n    Word16 var_out;\n\n    L_var3 = L_msu (L_var3, var1, var2);\n    L_var3 = L_add (L_var3, (Word32) 0x00008000L);\n    var_out = extract_h (L_var3);\n\n    return (var_out);\n}\n#endif\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_deposit_h                                             |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Deposit the 16 bit var1 into the 16 MS bits of the 32 bit output. The   |\n |   16 LS bits of the output are zeroed.                                    |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= var_out <= 0x7fff 0000.                |\n |___________________________________________________________________________|\n*/\n//Word32 L_deposit_h (Word16 var1)\n//{\n//    Word32 L_var_out;\n//\n//    L_var_out = (Word32) var1 << 16;\n//\n//    return (L_var_out);\n//}\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_deposit_l                                             |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Deposit the 16 bit var1 into the 16 LS bits of the 32 bit output. The   |\n |   16 MS bits of the output are sign extended.                             |\n |                                                                           |\n |   Complexity weight : 2                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0xFFFF 8000 <= var_out <= 0x0000 7fff.                |\n |___________________________________________________________________________|\n*/\n//Word32 L_deposit_l (Word16 var1)\n//{\n//    Word32 L_var_out;\n//\n//    L_var_out = (Word32) var1;\n//\n//    return (L_var_out);\n//}\n\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_shr_r                                                 |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Same as L_shr(L_var1,var2) but with rounding. Saturate the result in    |\n |   case of underflows or overflows :                                       |\n |    - If var2 is greater than zero :                                       |\n |          if (L_sub(L_shl(L_shr(L_var1,var2),1),L_shr(L_var1,sub(var2,1))))|\n |          is equal to zero                                                 |\n |                     then                                                  |\n |                     L_shr_r(L_var1,var2) = L_shr(L_var1,var2)             |\n |                     else                                                  |\n |                     L_shr_r(L_var1,var2) = L_add(L_shr(L_var1,var2),1)    |\n |    - If var2 is less than or equal to zero :                              |\n |                     L_shr_r(L_var1,var2) = L_shr(L_var1,var2).            |\n |                                                                           |\n |   Complexity weight : 3                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1                                                                 |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= var1 <= 0x7fff ffff.                   |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= var_out <= 0x7fff ffff.                |\n |___________________________________________________________________________|\n*/\n#if (!L_SHR_R_IS_INLINE)\nWord32 L_shr_r (Word32 L_var1, Word16 var2)\n{\n    Word32 L_var_out;\n\n    if (var2 > 31)\n    {\n        L_var_out = 0;\n    }\n    else\n    {\n        L_var_out = L_shr (L_var1, var2);\n\n        if (var2 > 0)\n        {\n            if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0)\n            {\n                L_var_out++;\n            }\n        }\n    }\n\n    return (L_var_out);\n}\n#endif\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : L_abs                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |    Absolute value of L_var1; Saturate in case where the input is          |\n |                                                               -214783648  |\n |                                                                           |\n |   Complexity weight : 3                                                   |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1                                                                 |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= var1 <= 0x7fff ffff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    L_var_out                                                              |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x0000 0000 <= var_out <= 0x7fff ffff.                |\n |___________________________________________________________________________|\n*/\n//Word32 L_abs (Word32 L_var1)\n//{\n//    Word32 L_var_out;\n//\n//    if (L_var1 == MIN_32)\n//    {\n//        L_var_out = MAX_32;\n//    }\n//    else\n//    {\n//        if (L_var1 < 0)\n//        {\n//            L_var_out = -L_var1;\n//        }\n//        else\n//        {\n//            L_var_out = L_var1;\n//        }\n//    }\n//\n//    return (L_var_out);\n//}\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : norm_s                                                  |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Produces the number of left shift needed to normalize the 16 bit varia- |\n |   ble var1 for positive values on the interval with minimum of 16384 and  |\n |   maximum of 32767, and for negative values on the interval with minimum  |\n |   of -32768 and maximum of -16384; in order to normalize the result, the  |\n |   following operation must be done :                                      |\n |                    norm_var1 = shl(var1,norm_s(var1)).                    |\n |                                                                           |\n |   Complexity weight : 15                                                  |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0x0000 0000 <= var_out <= 0x0000 000f.                |\n |___________________________________________________________________________|\n*/\n\n#if (!NORM_S_IS_INLINE)\nWord16 norm_s (Word16 var1)\n{\n    Word16 var_out;\n\n    if (var1 == 0)\n    {\n        var_out = 0;\n    }\n    else\n    {\n        if (var1 == -1)\n        {\n            var_out = 15;\n        }\n        else\n        {\n            if (var1 < 0)\n            {\n                var1 = (Word16)~var1;\n            }\n            for (var_out = 0; var1 < 0x4000; var_out++)\n            {\n                var1 <<= 1;\n            }\n        }\n    }\n\n    return (var_out);\n}\n#endif\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : div_s                                                   |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Produces a result which is the fractional integer division of var1  by  |\n |   var2; var1 and var2 must be positive and var2 must be greater or equal  |\n |   to var1; the result is positive (leading bit equal to 0) and truncated  |\n |   to 16 bits.                                                             |\n |   If var1 = var2 then div(var1,var2) = 32767.                             |\n |                                                                           |\n |   Complexity weight : 18                                                  |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    var1                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0x0000 0000 <= var1 <= var2 and var2 != 0.            |\n |                                                                           |\n |    var2                                                                   |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : var1 <= var2 <= 0x0000 7fff and var2 != 0.            |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0x0000 0000 <= var_out <= 0x0000 7fff.                |\n |             It's a Q15 value (point between b15 and b14).                 |\n |___________________________________________________________________________|\n*/\n\n#if (!DIV_S_IS_INLINE)\nWord16 div_s (Word16 var1, Word16 var2)\n{\n    Word16 var_out = 0;\n    Word16 iteration;\n    Word32 L_num;\n    Word32 L_denom;\n\n    if (var1 == 0)\n    {\n        var_out = 0;\n    }\n    else\n    {\n        if (var1 == var2)\n        {\n            var_out = MAX_16;\n        }\n        else\n        {\n            L_num = L_deposit_l (var1);\n            L_denom = L_deposit_l (var2);\n\n            for (iteration = 0; iteration < 15; iteration++)\n            {\n                var_out <<= 1;\n                L_num <<= 1;\n\n                if (L_num >= L_denom)\n                {\n                    L_num = L_sub(L_num, L_denom);\n                    var_out = add (var_out, 1);\n                }\n            }\n        }\n    }\n\n    return (var_out);\n}\n#endif\n\n/*___________________________________________________________________________\n |                                                                           |\n |   Function Name : norm_l                                                  |\n |                                                                           |\n |   Purpose :                                                               |\n |                                                                           |\n |   Produces the number of left shifts needed to normalize the 32 bit varia-|\n |   ble L_var1 for positive values on the interval with minimum of          |\n |   1073741824 and maximum of 2147483647, and for negative values on the in-|\n |   terval with minimum of -2147483648 and maximum of -1073741824; in order |\n |   to normalize the result, the following operation must be done :         |\n |                   norm_L_var1 = L_shl(L_var1,norm_l(L_var1)).             |\n |                                                                           |\n |   Complexity weight : 30                                                  |\n |                                                                           |\n |   Inputs :                                                                |\n |                                                                           |\n |    L_var1                                                                 |\n |             32 bit long signed integer (Word32) whose value falls in the  |\n |             range : 0x8000 0000 <= var1 <= 0x7fff ffff.                   |\n |                                                                           |\n |   Outputs :                                                               |\n |                                                                           |\n |    none                                                                   |\n |                                                                           |\n |   Return Value :                                                          |\n |                                                                           |\n |    var_out                                                                |\n |             16 bit short signed integer (Word16) whose value falls in the |\n |             range : 0x0000 0000 <= var_out <= 0x0000 001f.                |\n |___________________________________________________________________________|\n*/\n\n#if (!NORM_L_IS_INLINE)\nWord16 norm_l (Word32 L_var1)\n{\n    Word16 var_out;\n\n    if (L_var1 == 0)\n    {\n        var_out = 0;\n    }\n    else\n    {\n        if (L_var1 == (Word32) 0xffffffffL)\n        {\n            var_out = 31;\n        }\n        else\n        {\n            if (L_var1 < 0)\n            {\n                L_var1 = ~L_var1;\n            }\n            for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++)\n            {\n                L_var1 <<= 1;\n            }\n        }\n    }\n\n    return (var_out);\n}\n#endif\n\n"
  },
  {
    "path": "jni/basic_op/oper_32b.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\toper_32b.c\n\n\tContent:\t  This file contains operations in double precision.\n\n*******************************************************************************/\n\n#include \"typedef.h\"\n#include \"basic_op.h\"\n#include \"oper_32b.h\"\n\n/*****************************************************************************\n *                                                                           *\n *  Function L_Extract()                                                     *\n *                                                                           *\n *  Extract from a 32 bit integer two 16 bit DPF.                            *\n *                                                                           *\n *  Arguments:                                                               *\n *                                                                           *\n *   L_32      : 32 bit integer.                                             *\n *               0x8000 0000 <= L_32 <= 0x7fff ffff.                         *\n *   hi        : b16 to b31 of L_32                                          *\n *   lo        : (L_32 - hi<<16)>>1                                          *\n *****************************************************************************\n*/\n\nvoid L_Extract (Word32 L_32, Word16 *hi, Word16 *lo)\n{\n    *hi = extract_h (L_32);\n    *lo = extract_l (L_msu (L_shr (L_32, 1), *hi, 16384));\n    return;\n}\n\n/*****************************************************************************\n *                                                                           *\n *  Function L_Comp()                                                        *\n *                                                                           *\n *  Compose from two 16 bit DPF a 32 bit integer.                            *\n *                                                                           *\n *     L_32 = hi<<16 + lo<<1                                                 *\n *                                                                           *\n *  Arguments:                                                               *\n *                                                                           *\n *   hi        msb                                                           *\n *   lo        lsf (with sign)                                               *\n *                                                                           *\n *   Return Value :                                                          *\n *                                                                           *\n *             32 bit long signed integer (Word32) whose value falls in the  *\n *             range : 0x8000 0000 <= L_32 <= 0x7fff fff0.                   *\n *                                                                           *\n *****************************************************************************\n*/\n\nWord32 L_Comp (Word16 hi, Word16 lo)\n{\n    Word32 L_32;\n\n    L_32 = L_deposit_h (hi);\n    return (L_mac (L_32, lo, 1));       /* = hi<<16 + lo<<1 */\n}\n\n/*****************************************************************************\n * Function Mpy_32()                                                         *\n *                                                                           *\n *   Multiply two 32 bit integers (DPF). The result is divided by 2**31      *\n *                                                                           *\n *   L_32 = (hi1*hi2)<<1 + ( (hi1*lo2)>>15 + (lo1*hi2)>>15 )<<1              *\n *                                                                           *\n *   This operation can also be viewed as the multiplication of two Q31      *\n *   number and the result is also in Q31.                                   *\n *                                                                           *\n * Arguments:                                                                *\n *                                                                           *\n *  hi1         hi part of first number                                      *\n *  lo1         lo part of first number                                      *\n *  hi2         hi part of second number                                     *\n *  lo2         lo part of second number                                     *\n *                                                                           *\n *****************************************************************************\n*/\n\nWord32 Mpy_32 (Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2)\n{\n    Word32 L_32;\n\n    L_32 = L_mult (hi1, hi2);\n    L_32 = L_mac (L_32, mult (hi1, lo2), 1);\n    L_32 = L_mac (L_32, mult (lo1, hi2), 1);\n\n    return (L_32);\n}\n\n/*****************************************************************************\n * Function Mpy_32_16()                                                      *\n *                                                                           *\n *   Multiply a 16 bit integer by a 32 bit (DPF). The result is divided      *\n *   by 2**15                                                                *\n *                                                                           *\n *                                                                           *\n *   L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1                                *\n *                                                                           *\n * Arguments:                                                                *\n *                                                                           *\n *  hi          hi part of 32 bit number.                                    *\n *  lo          lo part of 32 bit number.                                    *\n *  n           16 bit number.                                               *\n *                                                                           *\n *****************************************************************************\n*/\n\nWord32 Mpy_32_16 (Word16 hi, Word16 lo, Word16 n)\n{\n    Word32 L_32;\n\n    L_32 = L_mult (hi, n);\n    L_32 = L_mac (L_32, mult (lo, n), 1);\n\n    return (L_32);\n}\n\n/*****************************************************************************\n *                                                                           *\n *   Function Name : Div_32                                                  *\n *                                                                           *\n *   Purpose :                                                               *\n *             Fractional integer division of two 32 bit numbers.            *\n *             L_num / L_denom.                                              *\n *             L_num and L_denom must be positive and L_num < L_denom.       *\n *             L_denom = denom_hi<<16 + denom_lo<<1                          *\n *             denom_hi is a normalize number.                               *\n *                                                                           *\n *   Inputs :                                                                *\n *                                                                           *\n *    L_num                                                                  *\n *             32 bit long signed integer (Word32) whose value falls in the  *\n *             range : 0x0000 0000 < L_num < L_denom                         *\n *                                                                           *\n *    L_denom = denom_hi<<16 + denom_lo<<1      (DPF)                        *\n *                                                                           *\n *       denom_hi                                                            *\n *             16 bit positive normalized integer whose value falls in the   *\n *             range : 0x4000 < hi < 0x7fff                                  *\n *       denom_lo                                                            *\n *             16 bit positive integer whose value falls in the              *\n *             range : 0 < lo < 0x7fff                                       *\n *                                                                           *\n *   Return Value :                                                          *\n *                                                                           *\n *    L_div                                                                  *\n *             32 bit long signed integer (Word32) whose value falls in the  *\n *             range : 0x0000 0000 <= L_div <= 0x7fff ffff.                  *\n *                                                                           *\n *  Algorithm:                                                               *\n *                                                                           *\n *  - find = 1/L_denom.                                                      *\n *      First approximation: approx = 1 / denom_hi                           *\n *      1/L_denom = approx * (2.0 - L_denom * approx )                       *\n *                                                                           *\n *  -  result = L_num * (1/L_denom)                                          *\n *****************************************************************************\n*/\n\nWord32 Div_32 (Word32 L_num, Word32 denom)\n{\n    Word16 approx;\n    Word32 L_32;\n    /* First approximation: 1 / L_denom = 1/denom_hi */\n\n    approx = div_s ((Word16) 0x3fff, denom >> 16);\n\n    /* 1/L_denom = approx * (2.0 - L_denom * approx) */\n\n    L_32 = L_mpy_ls (denom, approx);\n\n    L_32 = L_sub ((Word32) 0x7fffffffL, L_32);\n\n\tL_32 = L_mpy_ls (L_32, approx);\n    /* L_num * (1/L_denom) */\n\n\tL_32 = MULHIGH(L_32, L_num);\n    L_32 = L_shl (L_32, 3);\n\n    return (L_32);\n}\n\n/*!\n\n  \\brief  calculates the log dualis times 4 of argument\n          iLog4(x) = (Word32)(4 * log(value)/log(2.0))\n\n  \\return ilog4 value\n\n*/\nWord16 iLog4(Word32 value)\n{\n  Word16 iLog4;\n\n  if(value != 0){\n    Word32 tmp;\n    Word16 tmp16;\n    iLog4 = norm_l(value);\n    tmp = (value << iLog4);\n    tmp16 = round16(tmp);\n    tmp = L_mult(tmp16, tmp16);\n    tmp16 = round16(tmp);\n    tmp = L_mult(tmp16, tmp16);\n    tmp16 = round16(tmp);\n\n    iLog4 = (-(iLog4 << 2) - norm_s(tmp16)) - 1;\n  }\n  else {\n    iLog4 = -128; /* -(INT_BITS*4); */\n  }\n\n  return iLog4;\n}\n\n#define step(shift) \\\n    if ((0x40000000l >> shift) + root <= value)       \\\n    {                                                 \\\n        value -= (0x40000000l >> shift) + root;       \\\n        root = (root >> 1) | (0x40000000l >> shift);  \\\n    } else {                                          \\\n        root = root >> 1;                             \\\n    }\n\nWord32 rsqrt(Word32 value,     /*!< Operand to square root (0.0 ... 1) */\n             Word32 accuracy)  /*!< Number of valid bits that will be calculated */\n{\n    Word32 root = 0;\n\tWord32 scale;\n\n\tif(value < 0)\n\t\treturn 0;\n\n\tscale = norm_l(value);\n\tif(scale & 1) scale--;\n\n\tvalue <<= scale;\n\n\tstep( 0); step( 2); step( 4); step( 6);\n    step( 8); step(10); step(12); step(14);\n    step(16); step(18); step(20); step(22);\n    step(24); step(26); step(28); step(30);\n\n    scale >>= 1;\n\tif (root < value)\n        ++root;\n\n\troot >>= scale;\n    return root* 46334;\n}\n\nstatic const Word32 pow2Table[POW2_TABLE_SIZE] = {\n0x7fffffff, 0x7fa765ad, 0x7f4f08ae, 0x7ef6e8da,\n0x7e9f0606, 0x7e476009, 0x7deff6b6, 0x7d98c9e6,\n0x7d41d96e, 0x7ceb2523, 0x7c94acde, 0x7c3e7073,\n0x7be86fb9, 0x7b92aa88, 0x7b3d20b6, 0x7ae7d21a,\n0x7a92be8b, 0x7a3de5df, 0x79e947ef, 0x7994e492,\n0x7940bb9e, 0x78ecccec, 0x78991854, 0x78459dac,\n0x77f25cce, 0x779f5591, 0x774c87cc, 0x76f9f359,\n0x76a7980f, 0x765575c8, 0x76038c5b, 0x75b1dba2,\n0x75606374, 0x750f23ab, 0x74be1c20, 0x746d4cac,\n0x741cb528, 0x73cc556d, 0x737c2d55, 0x732c3cba,\n0x72dc8374, 0x728d015d, 0x723db650, 0x71eea226,\n0x719fc4b9, 0x71511de4, 0x7102ad80, 0x70b47368,\n0x70666f76, 0x7018a185, 0x6fcb096f, 0x6f7da710,\n0x6f307a41, 0x6ee382de, 0x6e96c0c3, 0x6e4a33c9,\n0x6dfddbcc, 0x6db1b8a8, 0x6d65ca38, 0x6d1a1057,\n0x6cce8ae1, 0x6c8339b2, 0x6c381ca6, 0x6bed3398,\n0x6ba27e66, 0x6b57fce9, 0x6b0daeff, 0x6ac39485,\n0x6a79ad56, 0x6a2ff94f, 0x69e6784d, 0x699d2a2c,\n0x69540ec9, 0x690b2601, 0x68c26fb1, 0x6879ebb6,\n0x683199ed, 0x67e97a34, 0x67a18c68, 0x6759d065,\n0x6712460b, 0x66caed35, 0x6683c5c3, 0x663ccf92,\n0x65f60a80, 0x65af766a, 0x6569132f, 0x6522e0ad,\n0x64dcdec3, 0x64970d4f, 0x64516c2e, 0x640bfb41,\n0x63c6ba64, 0x6381a978, 0x633cc85b, 0x62f816eb,\n0x62b39509, 0x626f4292, 0x622b1f66, 0x61e72b65,\n0x61a3666d, 0x615fd05f, 0x611c6919, 0x60d9307b,\n0x60962665, 0x60534ab7, 0x60109d51, 0x5fce1e12,\n0x5f8bccdb, 0x5f49a98c, 0x5f07b405, 0x5ec5ec26,\n0x5e8451d0, 0x5e42e4e3, 0x5e01a540, 0x5dc092c7,\n0x5d7fad59, 0x5d3ef4d7, 0x5cfe6923, 0x5cbe0a1c,\n0x5c7dd7a4, 0x5c3dd19c, 0x5bfdf7e5, 0x5bbe4a61,\n0x5b7ec8f2, 0x5b3f7377, 0x5b0049d4, 0x5ac14bea,\n0x5a82799a, 0x5a43d2c6, 0x5a055751, 0x59c7071c,\n0x5988e209, 0x594ae7fb, 0x590d18d3, 0x58cf7474,\n0x5891fac1, 0x5854ab9b, 0x581786e6, 0x57da8c83,\n0x579dbc57, 0x57611642, 0x57249a29, 0x56e847ef,\n0x56ac1f75, 0x567020a0, 0x56344b52, 0x55f89f70,\n0x55bd1cdb, 0x5581c378, 0x55469329, 0x550b8bd4,\n0x54d0ad5b, 0x5495f7a1, 0x545b6a8b, 0x542105fd,\n0x53e6c9db, 0x53acb607, 0x5372ca68, 0x533906e0,\n0x52ff6b55, 0x52c5f7aa, 0x528cabc3, 0x52538786,\n0x521a8ad7, 0x51e1b59a, 0x51a907b4, 0x5170810b,\n0x51382182, 0x50ffe8fe, 0x50c7d765, 0x508fec9c,\n0x50582888, 0x50208b0e, 0x4fe91413, 0x4fb1c37c,\n0x4f7a9930, 0x4f439514, 0x4f0cb70c, 0x4ed5ff00,\n0x4e9f6cd4, 0x4e69006e, 0x4e32b9b4, 0x4dfc988c,\n0x4dc69cdd, 0x4d90c68b, 0x4d5b157e, 0x4d25899c,\n0x4cf022ca, 0x4cbae0ef, 0x4c85c3f1, 0x4c50cbb8,\n0x4c1bf829, 0x4be7492b, 0x4bb2bea5, 0x4b7e587d,\n0x4b4a169c, 0x4b15f8e6, 0x4ae1ff43, 0x4aae299b,\n0x4a7a77d5, 0x4a46e9d6, 0x4a137f88, 0x49e038d0,\n0x49ad1598, 0x497a15c4, 0x4947393f, 0x49147fee,\n0x48e1e9ba, 0x48af768a, 0x487d2646, 0x484af8d6,\n0x4818ee22, 0x47e70611, 0x47b5408c, 0x47839d7b,\n0x47521cc6, 0x4720be55, 0x46ef8210, 0x46be67e0,\n0x468d6fae, 0x465c9961, 0x462be4e2, 0x45fb521a,\n0x45cae0f2, 0x459a9152, 0x456a6323, 0x453a564d,\n0x450a6abb, 0x44daa054, 0x44aaf702, 0x447b6ead,\n0x444c0740, 0x441cc0a3, 0x43ed9ac0, 0x43be9580,\n0x438fb0cb, 0x4360ec8d, 0x433248ae, 0x4303c517,\n0x42d561b4, 0x42a71e6c, 0x4278fb2b, 0x424af7da,\n0x421d1462, 0x41ef50ae, 0x41c1aca8, 0x41942839,\n0x4166c34c, 0x41397dcc, 0x410c57a2, 0x40df50b8,\n0x40b268fa, 0x4085a051, 0x4058f6a8, 0x402c6be9\n};\n\n/*!\n\n  \\brief calculates 2 ^ (x/y) for x<=0, y > 0, x <= 32768 * y\n\n  avoids integer division\n\n  \\return\n*/\nWord32 pow2_xy(Word32 x, Word32 y)\n{\n  Word32 iPart;\n  Word32 fPart;\n  Word32 res;\n  Word32 tmp, tmp2;\n  Word32 shift, shift2;\n\n  tmp2 = -x;\n  iPart = tmp2 / y;\n  fPart = tmp2 - iPart*y;\n  iPart = min(iPart,INT_BITS-1);\n\n  res = pow2Table[(POW2_TABLE_SIZE*fPart)/y] >> iPart;\n\n  return(res);\n}\n"
  },
  {
    "path": "jni/inc/aac_rom.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\taac_rom.h\n\n\tContent:\tconstant tables\n\n*******************************************************************************/\n\n#ifndef ROM_H\n#define ROM_H\n\n#include \"config.h\"\n#include \"psy_const.h\"\n#include \"tns_param.h\"\n\n/*\n  mdct\n*/\nextern const int ShortWindowSine[FRAME_LEN_SHORT/2];\nextern const int LongWindowKBD[FRAME_LEN_LONG/2];\n\nextern const unsigned char bitrevTab[17 + 129];\nextern const int cossintab[128 + 1024];\n\n#if defined (ARMV5E) && !defined (ARMV7Neon)\nextern const int twidTab64[(4*6 + 16*6)/2];\nextern const int twidTab512[(8*6 + 32*6 + 128*6)/2];\n#else\nextern const int twidTab64[4*6 + 16*6];\nextern const int twidTab512[8*6 + 32*6 + 128*6];\n#endif\n\n/*\n  form factor\n*/\nextern const Word32 formfac_sqrttable[96];\n\n/*\n  quantizer\n*/\nextern const Word32 mTab_3_4[512];\nextern const Word32 mTab_4_3[512];\n/*! $2^{-\\frac{n}{16}}$ table */\nextern const Word16 pow2tominusNover16[17] ;\n\nextern Word32 specExpMantTableComb_enc[4][14];\nextern const UWord8 specExpTableComb_enc[4][14];\n\nextern const Word16 quantBorders[4][4];\n//extern const Word16 quantRecon[3][4];\nextern const Word16 quantRecon[4][3];\n\n/*\n  huffman\n*/\nextern const UWord16 huff_ltab1_2[3][3][3][3];\nextern const UWord16 huff_ltab3_4[3][3][3][3];\nextern const UWord16 huff_ltab5_6[9][9];\nextern const UWord16 huff_ltab7_8[8][8];\nextern const UWord16 huff_ltab9_10[13][13];\nextern const UWord16 huff_ltab11[17][17];\nextern const UWord16 huff_ltabscf[121];\nextern const UWord16 huff_ctab1[3][3][3][3];\nextern const UWord16 huff_ctab2[3][3][3][3];\nextern const UWord16 huff_ctab3[3][3][3][3];\nextern const UWord16 huff_ctab4[3][3][3][3];\nextern const UWord16 huff_ctab5[9][9];\nextern const UWord16 huff_ctab6[9][9];\nextern const UWord16 huff_ctab7[8][8];\nextern const UWord16 huff_ctab8[8][8];\nextern const UWord16 huff_ctab9[13][13];\nextern const UWord16 huff_ctab10[13][13];\nextern const UWord16 huff_ctab11[17][17];\nextern const UWord32 huff_ctabscf[121];\n\n\n\n/*\n  misc\n*/\nextern const int sampRateTab[NUM_SAMPLE_RATES];\nextern const int BandwithCoefTab[8][NUM_SAMPLE_RATES];\nextern const int rates[8];\nextern const UWord8 sfBandTotalShort[NUM_SAMPLE_RATES];\nextern const UWord8 sfBandTotalLong[NUM_SAMPLE_RATES];\nextern const int sfBandTabShortOffset[NUM_SAMPLE_RATES];\nextern const short sfBandTabShort[76];\nextern const int sfBandTabLongOffset[NUM_SAMPLE_RATES];\nextern const short sfBandTabLong[325];\n\nextern const Word32 m_log2_table[INT_BITS];\n\n/*\n  TNS\n*/\nextern const Word32 tnsCoeff3[8];\nextern const Word32 tnsCoeff3Borders[8];\nextern const Word32 tnsCoeff4[16];\nextern const Word32 tnsCoeff4Borders[16];\nextern const Word32 invSBF[24];\nextern const Word16 sideInfoTabLong[MAX_SFB_LONG + 1];\nextern const Word16 sideInfoTabShort[MAX_SFB_SHORT + 1];\n#endif\n"
  },
  {
    "path": "jni/inc/aacenc_core.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\taacenc_core.h\n\n\tContent:\taac encoder interface functions\n\n*******************************************************************************/\n\n#ifndef _aacenc_core_h_\n#define _aacenc_core_h_\n\n\n#include \"typedef.h\"\n#include \"config.h\"\n#include \"bitenc.h\"\n\n#include \"psy_configuration.h\"\n#include \"psy_main.h\"\n#include \"qc_main.h\"\n#include \"psy_main.h\"\n/*-------------------------- defines --------------------------------------*/\n\n\n/*-------------------- structure definitions ------------------------------*/\ntypedef  struct {\n  Word32   sampleRate;            /* audio file sample rate */\n  Word32   bitRate;               /* encoder bit rate in bits/sec */\n  Word16   nChannelsIn;           /* number of channels on input (1,2) */\n  Word16   nChannelsOut;          /* number of channels on output (1,2) */\n  Word16   bandWidth;             /* targeted audio bandwidth in Hz */\n  Word16   adtsUsed;\t\t\t  /* whether write adts header */\n} AACENC_CONFIG;\n\n\ntypedef struct {\n\n  AACENC_CONFIG config;     /* Word16 size: 8 */\n\n  ELEMENT_INFO elInfo;      /* Word16 size: 4 */\n\n  QC_STATE qcKernel;        /* Word16 size: 6 + 5(PADDING) + 7(ELEMENT_BITS) + 54(ADJ_THR_STATE) = 72 */\n  QC_OUT   qcOut;           /* Word16 size: MAX_CHANNELS*920(QC_OUT_CHANNEL) + 5(QC_OUT_ELEMENT) + 7 = 932 / 1852 */\n\n  PSY_OUT    psyOut;        /* Word16 size: MAX_CHANNELS*186 + 2 = 188 / 374 */\n  PSY_KERNEL psyKernel;     /* Word16 size:  2587 / 4491 */\n\n  struct BITSTREAMENCODER_INIT bseInit; /* Word16 size: 6 */\n  struct BIT_BUF  bitStream;            /* Word16 size: 8 */\n  HANDLE_BIT_BUF  hBitStream;\n  int\t\t\t  initOK;\n\n  short\t\t\t*intbuf;\n  short\t\t\t*encbuf;\n  short\t\t\t*inbuf;\n  int\t\t\tenclen;\n  int\t\t\tinlen;\n  int\t\t\tintlen;\n  int\t\t\tuselength;\n\n  void\t\t\t*hCheck;\n  VO_MEM_OPERATOR *voMemop;\n  VO_MEM_OPERATOR voMemoprator;\n\n}AAC_ENCODER; /* Word16 size: 3809 / 6851 */\n\n/*-----------------------------------------------------------------------------\n\nfunctionname: AacInitDefaultConfig\ndescription:  gives reasonable default configuration\nreturns:      ---\n\n------------------------------------------------------------------------------*/\nvoid AacInitDefaultConfig(AACENC_CONFIG *config);\n\n/*---------------------------------------------------------------------------\n\nfunctionname:AacEncOpen\ndescription: allocate and initialize a new encoder instance\nreturns:     AACENC_OK if success\n\n---------------------------------------------------------------------------*/\n\nWord16  AacEncOpen (AAC_ENCODER\t\t\t\t*hAacEnc,       /* pointer to an encoder handle, initialized on return */\n                    const  AACENC_CONFIG     config);        /* pre-initialized config struct */\n\nWord16 AacEncEncode(AAC_ENCODER\t\t   *hAacEnc,\n                    Word16             *timeSignal,\n                    const UWord8       *ancBytes,      /*!< pointer to ancillary data bytes */\n                    Word16             *numAncBytes,   /*!< number of ancillary Data Bytes, send as fill element  */\n                    UWord8             *outBytes,      /*!< pointer to output buffer            */\n                    VO_U32             *numOutBytes    /*!< number of bytes in output buffer */\n                    );\n\n/*---------------------------------------------------------------------------\n\nfunctionname:AacEncClose\ndescription: deallocate an encoder instance\n\n---------------------------------------------------------------------------*/\n\nvoid AacEncClose (AAC_ENCODER* hAacEnc, VO_MEM_OPERATOR *pMemOP); /* an encoder handle */\n\n#endif /* _aacenc_h_ */\n"
  },
  {
    "path": "jni/inc/adj_thr.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tadj_thr.h\n\n\tContent:\tThreshold compensation function\n\n*******************************************************************************/\n\n#ifndef __ADJ_THR_H\n#define __ADJ_THR_H\n\n#include \"adj_thr_data.h\"\n#include \"qc_data.h\"\n#include \"interface.h\"\n\nWord16 bits2pe(const Word16 bits);\n\nWord32 AdjThrNew(ADJ_THR_STATE** phAdjThr,\n                 Word32 nElements);\n\nvoid AdjThrDelete(ADJ_THR_STATE *hAdjThr);\n\nvoid AdjThrInit(ADJ_THR_STATE *hAdjThr,\n                const Word32 peMean,\n                Word32 chBitrate);\n\nvoid AdjustThresholds(ADJ_THR_STATE *adjThrState,\n                      ATS_ELEMENT* AdjThrStateElement,\n                      PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],\n                      PSY_OUT_ELEMENT *psyOutElement,\n                      Word16 *chBitDistribution,\n                      Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],\n                      Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],\n                      QC_OUT_ELEMENT* qcOE,\n\t\t\t\t\t  ELEMENT_BITS* elBits,\n\t\t\t\t\t  const Word16 nChannels,\n                      const Word16 maxBitFac);\n\nvoid AdjThrUpdate(ATS_ELEMENT *AdjThrStateElement,\n                  const Word16 dynBitsUsed);\n\n\n#endif\n"
  },
  {
    "path": "jni/inc/adj_thr_data.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tadj_thr_data.h\n\n\tContent:\tThreshold compensation parameter\n\n*******************************************************************************/\n\n#ifndef __ADJ_THR_DATA_H\n#define __ADJ_THR_DATA_H\n\n#include \"typedef.h\"\n#include \"psy_const.h\"\n#include \"line_pe.h\"\n\ntypedef struct {\n   Word16 clipSaveLow, clipSaveHigh;\n   Word16 minBitSave, maxBitSave;\n   Word16 clipSpendLow, clipSpendHigh;\n   Word16 minBitSpend, maxBitSpend;\n} BRES_PARAM;\n\ntypedef struct {\n   UWord8 modifyMinSnr;\n   Word16 startSfbL, startSfbS;\n} AH_PARAM;\n\ntypedef struct {\n  Word32 maxRed;\n  Word32 startRatio, maxRatio;\n  Word32 redRatioFac;\n  Word32 redOffs;\n} MINSNR_ADAPT_PARAM;\n\ntypedef struct {\n  /* parameters for bitreservoir control */\n  Word16 peMin, peMax;\n  /* constant offset to pe               */\n  Word16  peOffset;\n  /* avoid hole parameters               */\n  AH_PARAM ahParam;\n  /* paramters for adaptation of minSnr */\n  MINSNR_ADAPT_PARAM minSnrAdaptParam;\n  /* values for correction of pe */\n  Word16 peLast;\n  Word16 dynBitsLast;\n  Word16 peCorrectionFactor;\n} ATS_ELEMENT;\n\ntypedef struct {\n  BRES_PARAM   bresParamLong, bresParamShort; /* Word16 size: 2*8 */\n  ATS_ELEMENT  adjThrStateElem;               /* Word16 size: 19 */\n} ADJ_THR_STATE;\n\n#endif\n"
  },
  {
    "path": "jni/inc/band_nrg.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tband_nrg.h\n\n\tContent:\tBand/Line energy calculations functions\n\n*******************************************************************************/\n\n\n#ifndef _BAND_NRG_H\n#define _BAND_NRG_H\n\n#include \"typedef.h\"\n\n\nvoid CalcBandEnergy(const Word32 *mdctSpectrum,\n                    const Word16 *bandOffset,\n                    const Word16  numBands,\n                    Word32       *bandEnergy,\n                    Word32       *bandEnergySum);\n\n\nvoid CalcBandEnergyMS(const Word32 *mdctSpectrumLeft,\n                      const Word32 *mdctSpectrumRight,\n                      const Word16 *bandOffset,\n                      const Word16  numBands,\n                      Word32       *bandEnergyMid,\n                      Word32       *bandEnergyMidSum,\n                      Word32       *bandEnergySide,\n                      Word32       *bandEnergySideSum);\n\n#endif\n"
  },
  {
    "path": "jni/inc/basic_op.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tbasicop2.h\n\n\tContent:\tConstants , Globals and Basic arithmetic operators.\n\n*******************************************************************************/\n\n#ifndef __BASIC_OP_H\n#define __BASIC_OP_H\n\n#include \"typedef.h\"\n\n#define MAX_32 (Word32)0x7fffffffL\n#define MIN_32 (Word32)0x80000000L\n\n#define MAX_16 (Word16)0x7fff\n#define MIN_16 (Word16)0x8000\n#define ABS(a)\t((a) >= 0) ? (a) : (-(a))\n\n/* Short abs,           1   */\n#define abs_s(x)       (((x) != MIN_16) ? (((x) >= 0) ? (x) : (-(x))) : MAX_16)\n\n/* 16 bit var1 -> MSB,     2 */\n#define L_deposit_h(x) (((Word32)(x)) << 16)\n\n\n/* 16 bit var1 -> LSB,     2 */\n#define L_deposit_l(x) ((Word32)(x))\n\n\n/* Long abs,              3  */\n#define L_abs(x) (((x) != MIN_32) ? (((x) >= 0) ? (x) : (-(x))) : MAX_32)\n\n\n/* Short negate,        1   */\n#define negate(var1) (((var1) == MIN_16) ? MAX_16 : (-(var1)))\n\n\n/* Long negate,     2 */\n#define L_negate(L_var1) (((L_var1) == (MIN_32)) ? (MAX_32) : (-(L_var1)))\n\n\n#define MULHIGH(A,B) (int)(((Word64)(A)*(Word64)(B)) >> 32)\n#define fixmul(a, b) (int)((((Word64)(a)*(Word64)(b)) >> 32) << 1)\n\n\n#if  (SATRUATE_IS_INLINE)\n__inline Word32 saturate(Word32 L_var1);\n#else\nWord16 saturate(Word32 L_var1);\n#endif\n\n/* Short shift left,    1   */\n#if (SHL_IS_INLINE)\n__inline Word32 shl (Word32 var1, Word32 var2);\n#else\nWord16 shl (Word16 var1, Word16 var2);\n#endif\n\n/* Short shift right,   1   */\n#if (SHR_IS_INLINE)\n__inline Word32 shr (Word32 var1, Word32 var2);\n#else\nWord16 shr (Word16 var1, Word16 var2);\n#endif\n\n#if (L_MULT_IS_INLINE)\n__inline Word32 L_mult(Word32 var1, Word32 var2);\n#else\nWord32 L_mult(Word16 var1, Word16 var2);\n#endif\n\n/* Msu,  1  */\n#if (L_MSU_IS_INLINE)\n__inline Word32 L_msu (Word32 L_var3, Word32 var1, Word32 var2);\n#else\nWord32 L_msu (Word32 L_var3, Word16 var1, Word16 var2);\n#endif\n\n/* Long sub,        2 */\n#if (L_SUB_IS_INLINE)\n__inline Word32 L_sub(Word32 L_var1, Word32 L_var2);\n#else\nWord32 L_sub(Word32 L_var1, Word32 L_var2);\n#endif\n\n/* Long shift left, 2 */\n#if (L_SHL_IS_INLINE)\n__inline Word32 L_shl (Word32 L_var1, Word32 var2);\n#else\nWord32 L_shl (Word32 L_var1, Word16 var2);\n#endif\n\n/* Long shift right, 2*/\n#if (L_SHR_IS_INLINE)\n__inline Word32 L_shr (Word32 L_var1, Word32 var2);\n#else\nWord32 L_shr (Word32 L_var1, Word16 var2);\n#endif\n\n/* Short add,           1   */\n#if (ADD_IS_INLINE)\n__inline Word32 add (Word32 var1, Word32 var2);\n#else\nWord16 add (Word16 var1, Word16 var2);\n#endif\n\n/* Short sub,           1   */\n#if (SUB_IS_INLINE)\n__inline Word32 sub(Word32 var1, Word32 var2);\n#else\nWord16 sub(Word16 var1, Word16 var2);\n#endif\n\n/* Short division,       18  */\n#if (DIV_S_IS_INLINE)\n__inline Word32 div_s (Word32 var1, Word32 var2);\n#else\nWord16 div_s (Word16 var1, Word16 var2);\n#endif\n\n/* Short mult,          1   */\n#if (MULT_IS_INLINE)\n__inline Word32 mult (Word32 var1, Word32 var2);\n#else\nWord16 mult (Word16 var1, Word16 var2);\n#endif\n\n/* Short norm,           15  */\n#if (NORM_S_IS_INLINE)\n__inline Word32 norm_s (Word32 var1);\n#else\nWord16 norm_s (Word16 var1);\n#endif\n\n/* Long norm,            30  */\n#if (NORM_L_IS_INLINE)\n__inline Word32 norm_l (Word32 L_var1);\n#else\nWord16 norm_l (Word32 L_var1);\n#endif\n\n/* Round,               1   */\n#if (ROUND_IS_INLINE)\n__inline Word32 round16(Word32 L_var1);\n#else\nWord16 round16(Word32 L_var1);\n#endif\n\n/* Mac,  1  */\n#if (L_MAC_IS_INLINE)\n__inline Word32 L_mac (Word32 L_var3, Word32 var1, Word32 var2);\n#else\nWord32 L_mac (Word32 L_var3, Word16 var1, Word16 var2);\n#endif\n\n#if (L_ADD_IS_INLINE)\n__inline Word32 L_add (Word32 L_var1, Word32 L_var2);\n#else\nWord32 L_add (Word32 L_var1, Word32 L_var2);\n#endif\n\n/* Extract high,        1   */\n#if (EXTRACT_H_IS_INLINE)\n__inline Word32 extract_h (Word32 L_var1);\n#else\nWord16 extract_h (Word32 L_var1);\n#endif\n\n/* Extract low,         1   */\n#if (EXTRACT_L_IS_INLINE)\n__inline Word32 extract_l(Word32 L_var1);\n#else\nWord16 extract_l(Word32 L_var1);\n#endif\n\n/* Mult with round, 2 */\n#if (MULT_R_IS_INLINE)\n__inline Word32 mult_r(Word32 var1, Word32 var2);\n#else\nWord16 mult_r(Word16 var1, Word16 var2);\n#endif\n\n/* Shift right with round, 2           */\n#if (SHR_R_IS_INLINE)\n__inline Word32 shr_r (Word32 var1, Word32 var2);\n#else\nWord16 shr_r (Word16 var1, Word16 var2);\n#endif\n\n/* Mac with rounding,2 */\n#if (MAC_R_IS_INLINE)\n__inline Word32 mac_r (Word32 L_var3, Word32 var1, Word32 var2);\n#else\nWord16 mac_r (Word32 L_var3, Word16 var1, Word16 var2);\n#endif\n\n/* Msu with rounding,2 */\n#if (MSU_R_IS_INLINE)\n__inline Word32 msu_r (Word32 L_var3, Word32 var1, Word32 var2);\n#else\nWord16 msu_r (Word32 L_var3, Word16 var1, Word16 var2);\n#endif\n\n/* Long shift right with round,  3             */\n#if (L_SHR_R_IS_INLINE)\n__inline Word32 L_shr_r (Word32 L_var1, Word32 var2);\n#else\nWord32 L_shr_r (Word32 L_var1, Word16 var2);\n#endif\n\n#if ARMV4_INASM\n__inline Word32 ASM_L_shr(Word32 L_var1, Word32 var2)\n{\n\treturn L_var1 >> var2;\n}\n\n__inline Word32 ASM_L_shl(Word32 L_var1, Word32 var2)\n{\n\tWord32 result;\n\tasm (\n\t\t\"MOV\t%[result], %[L_var1], ASL %[var2] \\n\"\n\t\t\"TEQ\t%[L_var1], %[result], ASR %[var2]\\n\"\n\t\t\"EORNE  %[result], %[mask], %[L_var1], ASR #31\\n\"\n\t\t:[result]\"=&r\"(result)\n\t\t:[L_var1]\"r\"(L_var1), [var2]\"r\"(var2), [mask]\"r\"(0x7fffffff)\n\t\t);\n\treturn result;\n}\n\n__inline Word32 ASM_shr(Word32 L_var1, Word32 var2)\n{\n\tWord32 result;\n\tasm (\n\t\t\"CMP\t%[var2], #15\\n\"\n\t\t\"MOVLT\t%[result], %[L_var1], ASR %[var2]\\n\"\n\t\t\"MOVGE\t%[result], %[L_var1], ASR #15\\n\"\n\t\t:[result]\"=r\"(result)\n\t\t:[L_var1]\"r\"(L_var1), [var2]\"r\"(var2)\n\t\t);\n\treturn result;\n}\n\n__inline Word32 ASM_shl(Word32 L_var1, Word32 var2)\n{\n#if ARMV6_SAT\n\tWord32 result;\n\tasm (\n\t\t\"CMP\t%[var2], #16\\n\"\n\t\t\"MOVLT  %[result], %[L_var1], ASL %[var2]\\n\"\n\t\t\"MOVGE  %[result], %[L_var1], ASL #16\\n\"\n\t\t\"SSAT   %[result], #16, %[result]\\n\"\n\t\t:[result]\"=r\"(result)\n\t\t:[L_var1]\"r\"(L_var1), [var2]\"r\"(var2)\n\t\t);\n\treturn result;\n#else\n\tWord32 result;\n\tWord32 tmp;\n\tasm (\n\t\t\"CMP\t%[var2], #16\\n\"\n\t\t\"MOVLT  %[result], %[L_var1], ASL %[var2]\\n\"\n\t\t\"MOVGE  %[result], %[L_var1], ASL #16\\n\"\n        \"MOV    %[tmp], %[result], ASR #15\\n\"\n        \"TEQ    %[tmp], %[result], ASR #31 \\n\"\n        \"EORNE  %[result], %[mask], %[result],ASR #31\"\n\t\t:[result]\"=&r\"(result), [tmp]\"=&r\"(tmp)\n\t\t:[L_var1]\"r\"(L_var1), [var2]\"r\"(var2), [mask]\"r\"(0x7fff)\n\t\t);\n\treturn result;\n#endif\n}\n#endif\n\n/*___________________________________________________________________________\n |                                                                           |\n |   definitions for inline basic arithmetic operators                       |\n |___________________________________________________________________________|\n*/\n#if (SATRUATE_IS_INLINE)\n__inline Word32 saturate(Word32 L_var1)\n{\n#if ARMV6_SAT\n    Word32 result;\n\tasm (\n\t\t\"SSAT %[result], #16, %[L_var1]\"\n\t\t: [result]\"=r\"(result)\n\t\t: [L_var1]\"r\"(L_var1)\n\t\t);\n\treturn result;\n#elif ARMV5TE_SAT\n\tWord32 result;\n\tWord32 tmp;\n\tasm volatile (\n\t\t\"MOV\t%[tmp], %[L_var1],ASR#15\\n\"\n\t\t\"TEQ\t%[tmp], %[L_var1],ASR#31\\n\"\n\t\t\"EORNE\t%[result], %[mask],%[L_var1],ASR#31\\n\"\n\t\t\"MOVEQ\t%[result], %[L_var1]\\n\"\n\t\t:[result]\"=&r\"(result), [tmp]\"=&r\"(tmp)\n\t\t:[L_var1]\"r\"(L_var1), [mask]\"r\"(0x7fff)\n\t);\n\n\treturn result;\n#else\n    Word32 var_out;\n\n    //var_out = (L_var1 > (Word32)0X00007fffL) ? (MAX_16) : ((L_var1 < (Word32)0xffff8000L) ? (MIN_16) : ((Word16)L_var1));\n\n    if (L_var1 > 0X00007fffL)\n    {\n        var_out = MAX_16;\n    }\n    else if (L_var1 < (Word32) 0xffff8000L)\n    {\n        var_out = MIN_16;\n    }\n    else\n    {\n        var_out = extract_l(L_var1);\n    }\n\n    return (var_out);\n#endif\n}\n#endif\n\n/* Short shift left,    1   */\n#if (SHL_IS_INLINE)\n__inline Word32 shl (Word32 var1, Word32 var2)\n{\n#if ARMV5TE_SHL\n\tif(var2>=0)\n\t{\n\t\treturn ASM_shl( var1, var2);\n\t}\n\telse\n\t{\n\t\treturn ASM_shr( var1, -var2);\n\t}\n#else\n    Word32 var_out;\n    Word32 result;\n\n    if (var2 < 0)\n    {\n        var_out = shr (var1, (Word16)-var2);\n    }\n    else\n    {\n        result = (Word32) var1 *((Word32) 1 << var2);\n\n        if ((var2 > 15 && var1 != 0) || (result != (Word32) ((Word16) result)))\n        {\n            var_out = (Word16)((var1 > 0) ? MAX_16 : MIN_16);\n        }\n        else\n        {\n            var_out = extract_l(result);\n        }\n    }\n    return (var_out);\n#endif\n}\n#endif\n\n/* Short shift right,   1   */\n#if (SHR_IS_INLINE)\n__inline Word32 shr (Word32 var1, Word32 var2)\n{\n#if ARMV5TE_SHR\n\tif(var2>=0)\n\t{\n\t\treturn  ASM_shr( var1, var2);\n\t}\n\telse\n\t{\n\t\treturn  ASM_shl( var1, -var2);\n\t}\n#else\n    Word32 var_out;\n\n    if (var2 < 0)\n    {\n        var_out = shl (var1, (Word16)-var2);\n    }\n    else\n    {\n        if (var2 >= 15)\n        {\n            var_out = (Word16)((var1 < 0) ? -1 : 0);\n        }\n        else\n        {\n            if (var1 < 0)\n            {\n                var_out = (Word16)(~((~var1) >> var2));\n            }\n            else\n            {\n                var_out = (Word16)(var1 >> var2);\n            }\n        }\n    }\n\n    return (var_out);\n#endif\n}\n#endif\n\n\n#if (L_MULT_IS_INLINE)\n__inline Word32 L_mult(Word32 var1, Word32 var2)\n{\n#if ARMV5TE_L_MULT\n\tWord32 result;\n\tasm (\n\t\t\"SMULBB %[result], %[var1], %[var2] \\n\"\n\t\t\"QADD %[result], %[result], %[result] \\n\"\n\t\t:[result]\"=r\"(result)\n\t\t:[var1]\"r\"(var1), [var2]\"r\"(var2)\n\t\t);\n\treturn result;\n#else\n    Word32 L_var_out;\n\n    L_var_out = (Word32) var1 *(Word32) var2;\n\n    if (L_var_out != (Word32) 0x40000000L)\n    {\n        L_var_out <<= 1;\n    }\n    else\n    {\n        L_var_out = MAX_32;\n    }\n    return (L_var_out);\n#endif\n}\n#endif\n\n#if (L_MSU_IS_INLINE)\n__inline Word32 L_msu (Word32 L_var3, Word32 var1, Word32 var2)\n{\n#if ARMV5TE_L_MSU\n\tWord32 result;\n\tasm (\n\t\t\"SMULBB %[result], %[var1], %[var2] \\n\"\n\t\t\"QDSUB %[result], %[L_var3], %[result]\\n\"\n\t\t:[result]\"=&r\"(result)\n\t\t:[L_var3]\"r\"(L_var3), [var1]\"r\"(var1), [var2]\"r\"(var2)\n\t\t);\n\treturn result;\n#else\n    Word32 L_var_out;\n    Word32 L_product;\n\n    L_product = L_mult(var1, var2);\n    L_var_out = L_sub(L_var3, L_product);\n    return (L_var_out);\n#endif\n}\n#endif\n\n#if (L_SUB_IS_INLINE)\n__inline Word32 L_sub(Word32 L_var1, Word32 L_var2)\n{\n#if ARMV5TE_L_SUB\n\tWord32 result;\n\tasm (\n\t\t\"QSUB %[result], %[L_var1], %[L_var2]\\n\"\n\t\t:[result]\"=r\"(result)\n\t\t:[L_var1]\"r\"(L_var1), [L_var2]\"r\"(L_var2)\n\t\t);\n\treturn result;\n#else\n    Word32 L_var_out;\n\n    L_var_out = L_var1 - L_var2;\n\n    if (((L_var1 ^ L_var2) & MIN_32) != 0)\n    {\n        if ((L_var_out ^ L_var1) & MIN_32)\n        {\n            L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32;\n        }\n    }\n\n    return (L_var_out);\n#endif\n}\n#endif\n\n#if (L_SHL_IS_INLINE)\n__inline Word32 L_shl(Word32 L_var1, Word32 var2)\n{\n#if ARMV5TE_L_SHL\n    if(var2>=0)\n    {\n        return  ASM_L_shl( L_var1, var2);\n    }\n    else\n    {\n        return  ASM_L_shr( L_var1, -var2);\n    }\n#else\n    Word32 L_var_out = 0L;\n\n    if (var2 <= 0)\n    {\n        L_var1 = L_shr(L_var1, (Word16)-var2);\n    }\n    else\n    {\n        for (; var2 > 0; var2--)\n        {\n            if (L_var1 > (Word32) 0X3fffffffL)\n            {\n                return MAX_32;\n            }\n            else\n            {\n                if (L_var1 < (Word32) 0xc0000000L)\n                {\n                    return MIN_32;\n                }\n            }\n            L_var1 <<= 1;\n            L_var_out = L_var1;\n        }\n    }\n    return (L_var1);\n#endif\n}\n#endif\n\n#if (L_SHR_IS_INLINE)\n__inline Word32 L_shr (Word32 L_var1, Word32 var2)\n{\n#if ARMV5TE_L_SHR\n\tif(var2>=0)\n\t{\n\t\treturn ASM_L_shr( L_var1, var2);\n\t}\n\telse\n\t{\n\t\treturn ASM_L_shl( L_var1, -var2);\n\t}\n#else\n    Word32 L_var_out;\n\n    if (var2 < 0)\n    {\n        L_var_out = L_shl (L_var1, (Word16)-var2);\n    }\n    else\n    {\n        if (var2 >= 31)\n        {\n            L_var_out = (L_var1 < 0L) ? -1 : 0;\n        }\n        else\n        {\n            if (L_var1 < 0)\n            {\n                L_var_out = ~((~L_var1) >> var2);\n            }\n            else\n            {\n                L_var_out = L_var1 >> var2;\n            }\n        }\n    }\n    return (L_var_out);\n#endif\n}\n#endif\n\n/* Short add,           1   */\n#if (ADD_IS_INLINE)\n__inline Word32 add (Word32 var1, Word32 var2)\n{\n#if ARMV5TE_ADD\n\tWord32 result;\n\tWord32 tmp;\n\tasm (\n\t\t\"ADD  %[result], %[var1], %[var2] \\n\"\n\t\t\"MOV  %[tmp], %[result], ASR #15 \\n\"\n\t\t\"TEQ  %[tmp], %[result], ASR #31 \\n\"\n\t\t\"EORNE %[result], %[mask], %[result], ASR #31\"\n\t\t:[result]\"=&r\"(result), [tmp]\"=&r\"(tmp)\n\t\t:[var1]\"r\"(var1), [var2]\"r\"(var2), [mask]\"r\"(0x7fff)\n\t\t);\n\treturn result;\n#else\n    Word32 var_out;\n    Word32 L_sum;\n\n    L_sum = (Word32) var1 + var2;\n    var_out = saturate(L_sum);\n\n    return (var_out);\n#endif\n}\n#endif\n\n/* Short sub,           1   */\n#if (SUB_IS_INLINE)\n__inline Word32 sub(Word32 var1, Word32 var2)\n{\n#if ARMV5TE_SUB\n\tWord32 result;\n\tWord32 tmp;\n\tasm (\n\t\t\"SUB   %[result], %[var1], %[var2] \\n\"\n\t\t\"MOV   %[tmp], %[var1], ASR #15 \\n\"\n\t\t\"TEQ   %[tmp], %[var1], ASR #31 \\n\"\n\t\t\"EORNE %[result], %[mask], %[result], ASR #31 \\n\"\n\t\t:[result]\"=&r\"(result), [tmp]\"=&r\"(tmp)\n\t\t:[var1]\"r\"(var1), [var2]\"r\"(var2), [mask]\"r\"(0x7fff)\n\t\t);\n\treturn result;\n#else\n    Word32 var_out;\n    Word32 L_diff;\n\n    L_diff = (Word32) var1 - var2;\n    var_out = saturate(L_diff);\n\n    return (var_out);\n#endif\n}\n#endif\n\n/* Short division,       18  */\n#if (DIV_S_IS_INLINE)\n__inline Word32 div_s (Word32 var1, Word32 var2)\n{\n    Word32 var_out = 0;\n    Word32 iteration;\n    Word32 L_num;\n    Word32 L_denom;\n\n    var_out = MAX_16;\n    if (var1!= var2)//var1!= var2\n    {\n    \tvar_out = 0;\n    \tL_num = (Word32) var1;\n\n    \tL_denom = (Word32) var2;\n\n\t\t//return (L_num<<15)/var2;\n\n    \tfor (iteration = 0; iteration < 15; iteration++)\n    \t{\n    \t\tvar_out <<= 1;\n    \t\tL_num <<= 1;\n\n    \t\tif (L_num >= L_denom)\n    \t\t{\n    \t\t\tL_num -= L_denom;\n    \t\t\tvar_out++;\n    \t\t}\n    \t}\n    }\n    return (var_out);\n}\n#endif\n\n/* Short mult,          1   */\n#if (MULT_IS_INLINE)\n__inline Word32 mult (Word32 var1, Word32 var2)\n{\n#if ARMV5TE_MULT && ARMV6_SAT\n\tWord32 result;\n\tasm (\n\t\t\"SMULBB %[result], %[var1], %[var2] \\n\"\n\t\t\"SSAT   %[result], #16, %[result], ASR #15 \\n\"\n\t\t:[result]\"=r\"(result)\n\t\t:[var1]\"r\"(var1), [var2]\"r\"(var2)\n\t\t);\n\treturn result;\n#elif ARMV5TE_MULT\n\tWord32 result, tmp;\n\tasm (\n\t\t\"SMULBB %[tmp], %[var1], %[var2] \\n\"\n\t\t\"MOV\t%[result], %[tmp], ASR #15\\n\"\n\t\t\"MOV\t%[tmp], %[result], ASR #15\\n\"\n\t\t\"TEQ\t%[tmp], %[result], ASR #31\\n\"\n\t\t\"EORNE  %[result], %[mask], %[result], ASR #31 \\n\"\n\t\t:[result]\"=&r\"(result), [tmp]\"=&r\"(tmp)\n\t\t:[var1]\"r\"(var1), [var2]\"r\"(var2), [mask]\"r\"(0x7fff)\n\t\t);\n\treturn result;\n#else\n    Word32 var_out;\n    Word32 L_product;\n\n    L_product = (Word32) var1 *(Word32) var2;\n    L_product = (L_product & (Word32) 0xffff8000L) >> 15;\n    if (L_product & (Word32) 0x00010000L)\n        L_product = L_product | (Word32) 0xffff0000L;\n    var_out = saturate(L_product);\n\n    return (var_out);\n#endif\n}\n#endif\n\n\n/* Short norm,           15  */\n#if (NORM_S_IS_INLINE)\n__inline Word32 norm_s (Word32 var1)\n{\n#if ARMV5TE_NORM_S\n\tWord32 result;\n\tWord32 tmp;\n\tasm (\n\t\t\"RSBS  %[tmp], %[var1], #0 \\n\"\n\t\t\"CLZLT %[result], %[var1]\\n\"\n\t\t\"CLZGT %[result], %[tmp]\\n\"\n\t\t\"SUBNE %[result], %[result], #17\\n\"\n\t\t\"MOVEQ %[result], #0\\n\"\n\t\t\"CMP   %[var1], #-1\\n\"\n\t\t\"MOVEQ %[result], #15\\n\"\n\t\t:[result]\"=&r\"(result), [tmp]\"=&r\"(tmp)\n\t\t:[var1]\"r\"(var1)\n\t\t);\n\treturn result;\n#else\n    Word32 var_out;\n\n    if (var1 == 0)\n    {\n        var_out = 0;\n    }\n    else\n    {\n        if (var1 == -1)\n        {\n            var_out = 15;\n        }\n        else\n        {\n            if (var1 < 0)\n            {\n                var1 = (Word16)~var1;\n            }\n            for (var_out = 0; var1 < 0x4000; var_out++)\n            {\n                var1 <<= 1;\n            }\n        }\n    }\n    return (var_out);\n#endif\n}\n#endif\n\n/* Long norm,            30  */\n#if (NORM_L_IS_INLINE)\n__inline Word32 norm_l (Word32 L_var1)\n{\n#if ARMV5TE_NORM_L\n\tWord32 result;\n\tasm volatile(\n\t\t\"CMP    %[L_var1], #0\\n\"\n\t\t\"CLZNE  %[result], %[L_var1]\\n\"\n\t\t\"SUBNE  %[result], %[result], #1\\n\"\n\t\t\"MOVEQ  %[result], #0\\n\"\n\t\t:[result]\"=r\"(result)\n\t\t:[L_var1]\"r\"(L_var1)\n\t\t);\n\treturn result;\n#else\n    //Word16 var_out;\n\n    //if (L_var1 == 0)\n    //{\n    //    var_out = 0;\n    //}\n    //else\n    //{\n    //    if (L_var1 == (Word32) 0xffffffffL)\n    //    {\n    //        var_out = 31;\n    //    }\n    //    else\n    //    {\n    //        if (L_var1 < 0)\n    //        {\n    //            L_var1 = ~L_var1;\n    //        }\n    //        for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++)\n    //        {\n    //            L_var1 <<= 1;\n    //        }\n    //    }\n    //}\n    //return (var_out);\n  Word16 a16;\n  Word16 r = 0 ;\n\n\n  if ( L_var1 < 0 ) {\n    L_var1 = ~L_var1;\n  }\n\n  if (0 == (L_var1 & 0x7fff8000)) {\n    a16 = extract_l(L_var1);\n    r += 16;\n\n    if (0 == (a16 & 0x7f80)) {\n      r += 8;\n\n      if (0 == (a16 & 0x0078)) {\n        r += 4;\n\n        if (0 == (a16 & 0x0006)) {\n          r += 2;\n\n          if (0 == (a16 & 0x0001)) {\n            r += 1;\n          }\n        }\n        else {\n\n          if (0 == (a16 & 0x0004)) {\n            r += 1;\n          }\n        }\n      }\n      else {\n\n        if (0 == (a16 & 0x0060)) {\n          r += 2;\n\n          if (0 == (a16 & 0x0010)) {\n            r += 1;\n          }\n        }\n        else {\n\n          if (0 == (a16 & 0x0040)) {\n            r += 1;\n          }\n        }\n      }\n    }\n    else {\n\n      if (0 == (a16 & 0x7800)) {\n        r += 4;\n\n        if (0 == (a16 & 0x0600)) {\n          r += 2;\n\n          if (0 == (a16 & 0x0100)) {\n            r += 1;\n          }\n        }\n        else {\n\n          if (0 == (a16 & 0x0400)) {\n            r += 1;\n          }\n        }\n      }\n      else {\n\n        if (0 == (a16 & 0x6000)) {\n          r += 2;\n\n          if (0 == (a16 & 0x1000)) {\n            r += 1;\n          }\n        }\n        else {\n\n          if (0 == (a16 & 0x4000)) {\n            r += 1;\n          }\n        }\n      }\n    }\n  }\n  else {\n    a16 = extract_h(L_var1);\n\n    if (0 == (a16 & 0x7f80)) {\n      r += 8;\n\n      if (0 == (a16 & 0x0078)) {\n        r += 4 ;\n\n        if (0 == (a16 & 0x0006)) {\n          r += 2;\n\n          if (0 == (a16 & 0x0001)) {\n            r += 1;\n          }\n        }\n        else {\n\n          if (0 == (a16 & 0x0004)) {\n            r += 1;\n          }\n        }\n      }\n      else {\n\n        if (0 == (a16 & 0x0060)) {\n          r += 2;\n\n          if (0 == (a16 & 0x0010)) {\n            r += 1;\n          }\n        }\n        else {\n\n          if (0 == (a16 & 0x0040)) {\n            r += 1;\n          }\n        }\n      }\n    }\n    else {\n\n      if (0 == (a16 & 0x7800)) {\n        r += 4;\n\n        if (0 == (a16 & 0x0600)) {\n          r += 2;\n\n          if (0 == (a16 & 0x0100)) {\n            r += 1;\n          }\n        }\n        else {\n\n          if (0 == (a16 & 0x0400)) {\n            r += 1;\n          }\n        }\n      }\n      else {\n\n        if (0 == (a16 & 0x6000)) {\n          r += 2;\n\n          if (0 == (a16 & 0x1000)) {\n            r += 1;\n          }\n        }\n        else {\n\n          if (0 == (a16 & 0x4000)) {\n            return 1;\n          }\n        }\n      }\n    }\n  }\n\n  return r ;\n#endif\n}\n#endif\n\n/* Round,               1   */\n#if (ROUND_IS_INLINE)\n__inline Word32 round16(Word32 L_var1)\n{\n#if ARMV5TE_ROUND\n\tWord32 result;\n\tasm (\n\t\t\"QADD  %[result], %[L_var1], %[bias]\\n\"\n\t\t\"MOV   %[result], %[result], ASR #16 \\n\"\n\t\t:[result]\"=r\"(result)\n\t\t:[L_var1]\"r\"(L_var1), [bias]\"r\"(0x8000)\n\t\t);\n\treturn result;\n#else\n    Word32 var_out;\n    Word32 L_rounded;\n\n    L_rounded = L_add (L_var1, (Word32) 0x00008000L);\n    var_out = extract_h (L_rounded);\n    return (var_out);\n#endif\n}\n#endif\n\n/* Mac,  1  */\n#if (L_MAC_IS_INLINE)\n__inline Word32 L_mac (Word32 L_var3, Word32 var1, Word32 var2)\n{\n#if ARMV5TE_L_MAC\n\tWord32 result;\n\tasm (\n\t\t\"SMULBB %[result], %[var1], %[var2]\\n\"\n\t\t\"QDADD  %[result], %[L_var3], %[result]\\n\"\n\t\t:[result]\"=&r\"(result)\n\t\t: [L_var3]\"r\"(L_var3), [var1]\"r\"(var1), [var2]\"r\"(var2)\n\t\t);\n\treturn result;\n#else\n    Word32 L_var_out;\n    Word32 L_product;\n\n    L_product = L_mult(var1, var2);\n    L_var_out = L_add (L_var3, L_product);\n    return (L_var_out);\n#endif\n}\n#endif\n\n#if (L_ADD_IS_INLINE)\n__inline Word32 L_add (Word32 L_var1, Word32 L_var2)\n{\n#if ARMV5TE_L_ADD\n\tWord32 result;\n\tasm (\n\t\t\"QADD %[result], %[L_var1], %[L_var2]\\n\"\n\t\t:[result]\"=r\"(result)\n\t\t:[L_var1]\"r\"(L_var1), [L_var2]\"r\"(L_var2)\n\t\t);\n\treturn result;\n#else\n    Word32 L_var_out;\n\n    L_var_out = L_var1 + L_var2;\n    if (((L_var1 ^ L_var2) & MIN_32) == 0)\n    {\n        if ((L_var_out ^ L_var1) & MIN_32)\n        {\n            L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;\n        }\n    }\n    return (L_var_out);\n#endif\n}\n#endif\n\n\n\n#if (MULT_R_IS_INLINE)\n__inline Word32 mult_r (Word32 var1, Word32 var2)\n{\n    Word32 var_out;\n    Word32 L_product_arr;\n\n    L_product_arr = (Word32)var1 *(Word32)var2;       /* product */\n    L_product_arr += (Word32)0x00004000L;      /* round */\n    L_product_arr >>= 15;       /* shift */\n\n    var_out = saturate(L_product_arr);\n\n    return (var_out);\n}\n#endif\n\n#if (SHR_R_IS_INLINE)\n__inline Word32 shr_r (Word32 var1, Word32 var2)\n{\n    Word32 var_out;\n\n    if (var2 > 15)\n    {\n        var_out = 0;\n    }\n    else\n    {\n        var_out = shr(var1, var2);\n\n        if (var2 > 0)\n        {\n            if ((var1 & ((Word16) 1 << (var2 - 1))) != 0)\n            {\n                var_out++;\n            }\n        }\n    }\n\n    return (var_out);\n}\n#endif\n\n#if (MAC_R_IS_INLINE)\n__inline Word32 mac_r (Word32 L_var3, Word32 var1, Word32 var2)\n{\n    Word32 var_out;\n\n    L_var3 = L_mac (L_var3, var1, var2);\n    var_out = (Word16)((L_var3 + 0x8000L) >> 16);\n\n    return (var_out);\n}\n#endif\n\n#if (MSU_R_IS_INLINE)\n__inline Word32 msu_r (Word32 L_var3, Word32 var1, Word32 var2)\n{\n    Word32 var_out;\n\n    L_var3 = L_msu (L_var3, var1, var2);\n    var_out = (Word16)((L_var3 + 0x8000L) >> 16);\n\n    return (var_out);\n}\n#endif\n\n#if (L_SHR_R_IS_INLINE)\n__inline Word32 L_shr_r (Word32 L_var1, Word32 var2)\n{\n    Word32 L_var_out;\n\n    if (var2 > 31)\n    {\n        L_var_out = 0;\n    }\n    else\n    {\n        L_var_out = L_shr(L_var1, var2);\n\n        if (var2 > 0)\n        {\n            if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0)\n            {\n                L_var_out++;\n            }\n        }\n    }\n\n    return (L_var_out);\n}\n#endif\n\n#if (EXTRACT_H_IS_INLINE)\n__inline Word32 extract_h (Word32 L_var1)\n{\n    Word32 var_out;\n\n    var_out = (L_var1 >> 16);\n\n    return (var_out);\n}\n#endif\n\n#if (EXTRACT_L_IS_INLINE)\n__inline Word32 extract_l(Word32 L_var1)\n{\n\treturn (Word16) L_var1;\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "jni/inc/bit_cnt.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tbit_cnt.h\n\n\tContent:\tHuffman Bitcounter & coder structure and functions\n\n*******************************************************************************/\n\n#ifndef __BITCOUNT_H\n#define __BITCOUNT_H\n\n#include \"bitbuffer.h\"\n#include \"basic_op.h\"\n#define INVALID_BITCOUNT (MAX_16/4)\n\n/*\n  code book number table\n*/\n\nenum codeBookNo{\n  CODE_BOOK_ZERO_NO=               0,\n  CODE_BOOK_1_NO=                  1,\n  CODE_BOOK_2_NO=                  2,\n  CODE_BOOK_3_NO=                  3,\n  CODE_BOOK_4_NO=                  4,\n  CODE_BOOK_5_NO=                  5,\n  CODE_BOOK_6_NO=                  6,\n  CODE_BOOK_7_NO=                  7,\n  CODE_BOOK_8_NO=                  8,\n  CODE_BOOK_9_NO=                  9,\n  CODE_BOOK_10_NO=                10,\n  CODE_BOOK_ESC_NO=               11,\n  CODE_BOOK_RES_NO=               12,\n  CODE_BOOK_PNS_NO=               13\n};\n\n/*\n  code book index table\n*/\n\nenum codeBookNdx{\n  CODE_BOOK_ZERO_NDX=0,\n  CODE_BOOK_1_NDX,\n  CODE_BOOK_2_NDX,\n  CODE_BOOK_3_NDX,\n  CODE_BOOK_4_NDX,\n  CODE_BOOK_5_NDX,\n  CODE_BOOK_6_NDX,\n  CODE_BOOK_7_NDX,\n  CODE_BOOK_8_NDX,\n  CODE_BOOK_9_NDX,\n  CODE_BOOK_10_NDX,\n  CODE_BOOK_ESC_NDX,\n  CODE_BOOK_RES_NDX,\n  CODE_BOOK_PNS_NDX,\n  NUMBER_OF_CODE_BOOKS\n};\n\n/*\n  code book lav table\n*/\n\nenum codeBookLav{\n  CODE_BOOK_ZERO_LAV=0,\n  CODE_BOOK_1_LAV=1,\n  CODE_BOOK_2_LAV=1,\n  CODE_BOOK_3_LAV=2,\n  CODE_BOOK_4_LAV=2,\n  CODE_BOOK_5_LAV=4,\n  CODE_BOOK_6_LAV=4,\n  CODE_BOOK_7_LAV=7,\n  CODE_BOOK_8_LAV=7,\n  CODE_BOOK_9_LAV=12,\n  CODE_BOOK_10_LAV=12,\n  CODE_BOOK_ESC_LAV=16,\n  CODE_BOOK_SCF_LAV=60,\n  CODE_BOOK_PNS_LAV=60\n};\n\nWord16 bitCount(const Word16 *aQuantSpectrum,\n                const Word16  noOfSpecLines,\n                Word16        maxVal,\n                Word16       *bitCountLut);\n\nWord16 codeValues(Word16 *values, Word16 width, Word16 codeBook, HANDLE_BIT_BUF hBitstream);\n\nWord16 bitCountScalefactorDelta(Word16 delta);\nWord16 codeScalefactorDelta(Word16 scalefactor, HANDLE_BIT_BUF hBitstream);\n\n\n\n#endif\n"
  },
  {
    "path": "jni/inc/bitbuffer.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tbitbuffer.h\n\n\tContent:\tBit Buffer Management structure and functions\n\n*******************************************************************************/\n\n#ifndef BITBUFFER_H\n#define BITBUFFER_H\n\n#include \"typedef.h\"\n\n\nenum direction\n{\n  forwardDirection,\n  backwardDirection\n};\n\n\n/*!\n   The pointer 'pReadNext' points to the next available word, where bits can be read from. The pointer\n   'pWriteNext' points to the next available word, where bits can be written to. The pointer pBitBufBase\n   points to the start of the bitstream buffer and the pointer pBitBufEnd points to the end of the bitstream\n   buffer. The two pointers are used as lower-bound respectively upper-bound address for the modulo addressing\n   mode.\n\n   The element cntBits contains the currently available bits in the bit buffer. It will be incremented when\n   bits are written to the bitstream buffer and decremented when bits are read from the bitstream buffer.\n*/\nstruct BIT_BUF\n{\n  UWord8 *pBitBufBase;          /*!< pointer points to first position in bitstream buffer */\n  UWord8 *pBitBufEnd;           /*!< pointer points to last position in bitstream buffer */\n\n  UWord8 *pWriteNext;           /*!< pointer points to next available word in bitstream buffer to write */\n\n  UWord32 cache;\n\n  Word16  wBitPos;              /*!< 31<=wBitPos<=0*/\n  Word16  cntBits;              /*!< number of available bits in the bitstream buffer\n                                     write bits to bitstream buffer  => increment cntBits\n                                     read bits from bitstream buffer => decrement cntBits */\n  Word16  size;                 /*!< size of bitbuffer in bits */\n  Word16  isValid;              /*!< indicates whether the instance has been initialized */\n}; /* size Word16: 8 */\n\n/*! Define pointer to bit buffer structure */\ntypedef struct BIT_BUF *HANDLE_BIT_BUF;\n\n\nHANDLE_BIT_BUF CreateBitBuffer(HANDLE_BIT_BUF hBitBuf,\n                               UWord8 *pBitBufBase,\n                               Word16  bitBufSize);\n\n\nvoid DeleteBitBuffer(HANDLE_BIT_BUF *hBitBuf);\n\n\nWord16 GetBitsAvail(HANDLE_BIT_BUF hBitBuf);\n\n\nWord16 WriteBits(HANDLE_BIT_BUF hBitBuf,\n                 UWord32 writeValue,\n                 Word16 noBitsToWrite);\n\nvoid ResetBitBuf(HANDLE_BIT_BUF hBitBuf,\n                 UWord8 *pBitBufBase,\n                 Word16  bitBufSize);\n\n#define GetNrBitsAvailable(hBitBuf) ( (hBitBuf)->cntBits)\n#define GetNrBitsRead(hBitBuf)       ((hBitBuf)->size-(hBitBuf)->cntBits)\n\n#endif /* BITBUFFER_H */\n"
  },
  {
    "path": "jni/inc/bitenc.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tbitenc.h\n\n\tContent:\tBitstream encoder structure and functions\n\n*******************************************************************************/\n\n#ifndef _BITENC_H\n#define _BITENC_H\n\n#include \"qc_data.h\"\n#include \"tns.h\"\n#include \"channel_map.h\"\n#include \"interface.h\"\n\nstruct BITSTREAMENCODER_INIT\n{\n  Word16 nChannels;\n  Word32 bitrate;\n  Word32 sampleRate;\n  Word16 profile;\n};\n\n\n\nWord16 WriteBitstream (HANDLE_BIT_BUF hBitstream,\n                       ELEMENT_INFO elInfo,\n                       QC_OUT *qcOut,\n                       PSY_OUT *psyOut,\n                       Word16 *globUsedBits,\n                       const UWord8 *ancBytes,\n\t\t\t\t\t   Word16 samplerate\n                       );\n\n#endif /* _BITENC_H */\n"
  },
  {
    "path": "jni/inc/block_switch.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tblock_switch.h\n\n\tContent:\tBlock switching structure and functions\n\n*******************************************************************************/\n\n#ifndef _BLOCK_SWITCH_H\n#define _BLOCK_SWITCH_H\n\n#include \"typedef.h\"\n\n\n/****************** Defines ******************************/\n#define BLOCK_SWITCHING_IIR_LEN 2                                           /* Length of HighPass-FIR-Filter for Attack-Detection */\n#define BLOCK_SWITCH_WINDOWS TRANS_FAC                                      /* number of windows for energy calculation */\n#define BLOCK_SWITCH_WINDOW_LEN FRAME_LEN_SHORT                             /* minimal granularity of energy calculation */\n\n\n\n/****************** Structures ***************************/\ntypedef struct{\n  Word32 invAttackRatio;\n  Word16 windowSequence;\n  Word16 nextwindowSequence;\n  Flag attack;\n  Flag lastattack;\n  Word16 attackIndex;\n  Word16 lastAttackIndex;\n  Word16 noOfGroups;\n  Word16 groupLen[TRANS_FAC];\n  Word32 windowNrg[2][BLOCK_SWITCH_WINDOWS];     /* time signal energy in Subwindows (last and current) */\n  Word32 windowNrgF[2][BLOCK_SWITCH_WINDOWS];    /* filtered time signal energy in segments (last and current) */\n  Word32 iirStates[BLOCK_SWITCHING_IIR_LEN];     /* filter delay-line */\n  Word32 maxWindowNrg;                           /* max energy in subwindows */\n  Word32 accWindowNrg;                           /* recursively accumulated windowNrgF */\n}BLOCK_SWITCHING_CONTROL;\n\n\n\n\n\nWord16 InitBlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,\n                          const Word32 bitRate, const Word16 nChannels);\n\nWord16 BlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,\n                      Word16 *timeSignal,\n\t\t\t\t\t  Word32  sampleRate,\n                      Word16 chIncrement);\n\nWord16 SyncBlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControlLeft,\n                          BLOCK_SWITCHING_CONTROL *blockSwitchingControlRight,\n                          const Word16 noOfChannels);\n\n\n\n#endif  /* #ifndef _BLOCK_SWITCH_H */\n"
  },
  {
    "path": "jni/inc/channel_map.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tchannel_map.h\n\n\tContent:\tchannel mapping functions\n\n*******************************************************************************/\n\n#ifndef _CHANNEL_MAP_H\n#define _CHANNEL_MAP_H\n\n#include \"psy_const.h\"\n#include \"qc_data.h\"\n\nWord16 InitElementInfo (Word16 nChannels, ELEMENT_INFO* elInfo);\n\nWord16 InitElementBits(ELEMENT_BITS *elementBits,\n                       ELEMENT_INFO elInfo,\n                       Word32 bitrateTot,\n                       Word16 averageBitsTot,\n                       Word16 staticBitsTot);\n\n#endif /* CHANNEL_MAP_H */\n"
  },
  {
    "path": "jni/inc/cmnMemory.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tcmnMemory.h\n\n\tContent:\tmemory operator implementation header file\n\n*******************************************************************************/\n\n#ifndef __cmnMemory_H__\n#define __cmnMemory_H__\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#include \"voMem.h\"\n\n//extern VO_MEM_OPERATOR\tg_memOP;\n\n/**\n * Allocate memory\n * \\param uID [in] module ID\n * \\param uSize [in] size of memory\n * \\return value is the allocated memory address. NULL is failed.\n */\nVO_U32\tcmnMemAlloc (VO_S32 uID,  VO_MEM_INFO * pMemInfo);\n\n/**\n * Free up memory\n * \\param uID [in] module ID\n * \\param pMem [in] address of memory\n * \\return value 0, if succeeded.\n */\nVO_U32\tcmnMemFree (VO_S32 uID, VO_PTR pBuffer);\n\n/**\n * memory set function\n * \\param uID [in] module ID\n * \\param pBuff [in/out] address of memory\n * \\param uValue [in] the value to be set\n * \\param uSize [in] the size to be set\n * \\return value 0, if succeeded.\n */\nVO_U32\tcmnMemSet (VO_S32 uID, VO_PTR pBuff, VO_U8 uValue, VO_U32 uSize);\n\n/**\n * memory copy function\n * \\param uID [in] module ID\n * \\param pDest [in/out] address of destination memory\n * \\param pSource [in] address of source memory\n * \\param uSize [in] the size to be copied\n * \\return value 0, if succeeded.\n */\nVO_U32\tcmnMemCopy (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize);\n\n/**\n * memory check function\n * \\param uID [in] module ID\n * \\param pBuff [in] address of buffer to be checked\n * \\param uSize [in] the size to be checked\n * \\return value 0, if succeeded.\n */\nVO_U32\tcmnMemCheck (VO_S32 uID, VO_PTR pBuffer, VO_U32 uSize);\n\n/**\n * memory compare function\n * \\param uID [in] module ID\n * \\param pBuffer1 [in] address of buffer 1 to be compared\n * \\param pBuffer2 [in] address of buffer 2 to be compared\n * \\param uSize [in] the size to be compared\n * \\return value: same as standard C run-time memcmp() function.\n */\nVO_S32\tcmnMemCompare (VO_S32 uID, VO_PTR pBuffer1, VO_PTR pBuffer2, VO_U32 uSize);\n\n/**\n * memory move function\n * \\param uID [in] module ID\n * \\param pDest [in/out] address of destination memory\n * \\param pSource [in] address of source memory\n * \\param uSize [in] the size to be moved\n * \\return value 0, if succeeded.\n */\nVO_U32\tcmnMemMove (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize);\n\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif // __cmnMemory_H__\n\n\n"
  },
  {
    "path": "jni/inc/config.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tconfig.h\n\n\tContent:\taac encoder parameter\n\n*******************************************************************************/\n\n#ifndef _AACENC_CONFIG_H_\n#define _AACENC_CONFIG_H_\n\n#define MAX_CHANNELS        2\n\n#define AACENC_BLOCKSIZE    1024   /*! encoder only takes BLOCKSIZE samples at a time */\n#define AACENC_TRANS_FAC    8      /*! encoder short long ratio */\n\n\n#define MAXBITS_COEF\t\t6144\n#define MINBITS_COEF\t\t744\n\n\n#endif\n"
  },
  {
    "path": "jni/inc/dyn_bits.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tdyn_bits.h\n\n\tContent:\tNoiseless coder module structure and functions\n\n*******************************************************************************/\n\n#ifndef __DYN_BITS_H\n#define __DYN_BITS_H\n\n#include \"psy_const.h\"\n#include \"tns.h\"\n#include \"bit_cnt.h\"\n\n\n\n#define MAX_SECTIONS          MAX_GROUPED_SFB\n#define SECT_ESC_VAL_LONG    31\n#define SECT_ESC_VAL_SHORT    7\n#define CODE_BOOK_BITS        4\n#define SECT_BITS_LONG        5\n#define SECT_BITS_SHORT       3\n\ntypedef struct\n{\n  Word16 codeBook;\n  Word16 sfbStart;\n  Word16 sfbCnt;\n  Word16 sectionBits;\n}\nSECTION_INFO;\n\n\n\n\ntypedef struct\n{\n  Word16 blockType;\n  Word16 noOfGroups;\n  Word16 sfbCnt;\n  Word16 maxSfbPerGroup;\n  Word16 sfbPerGroup;\n  Word16 noOfSections;\n  SECTION_INFO sectionInfo[MAX_SECTIONS];\n  Word16 sideInfoBits;             /* sectioning bits       */\n  Word16 huffmanBits;              /* huffman    coded bits */\n  Word16 scalefacBits;             /* scalefac   coded bits */\n  Word16 firstScf;                 /* first scf to be coded */\n  Word16 bitLookUp[MAX_SFB_LONG*(CODE_BOOK_ESC_NDX+1)];\n  Word16 mergeGainLookUp[MAX_SFB_LONG];\n}\nSECTION_DATA; /*  Word16 size: 10 + 60(MAX_SECTIONS)*4(SECTION_INFO) + 51(MAX_SFB_LONG)*12(CODE_BOOK_ESC_NDX+1) + 51(MAX_SFB_LONG) = 913 */\n\n\nWord16 BCInit(void);\n\nWord16 dynBitCount(const Word16 *quantSpectrum,\n                   const UWord16 *maxValueInSfb,\n                   const Word16 *scalefac,\n                   const Word16 blockType,\n                   const Word16 sfbCnt,\n                   const Word16 maxSfbPerGroup,\n                   const Word16 sfbPerGroup,\n                   const Word16 *sfbOffset,\n                   SECTION_DATA *sectionData);\n\n#endif\n"
  },
  {
    "path": "jni/inc/grp_data.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tgrp_data.h\n\n\tContent:\tShort block grouping function\n\n*******************************************************************************/\n\n#ifndef __GRP_DATA_H__\n#define __GRP_DATA_H__\n#include \"psy_data.h\"\n#include \"typedefs.h\"\n\nvoid\ngroupShortData(Word32        *mdctSpectrum,\n               Word32        *tmpSpectrum,\n               SFB_THRESHOLD *sfbThreshold,\n               SFB_ENERGY    *sfbEnergy,\n               SFB_ENERGY    *sfbEnergyMS,\n               SFB_ENERGY    *sfbSpreadedEnergy,\n               const Word16   sfbCnt,\n               const Word16  *sfbOffset,\n               const Word16  *sfbMinSnr,\n               Word16        *groupedSfbOffset,\n               Word16        *maxSfbPerGroup,\n               Word16        *groupedSfbMinSnr,\n               const Word16   noOfGroups,\n               const Word16  *groupLen);\n\n#endif /* _INTERFACE_H */\n"
  },
  {
    "path": "jni/inc/interface.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tinterface.h\n\n\tContent:\tpsychoaccoustic/quantizer structures and interface\n\n*******************************************************************************/\n\n#ifndef _INTERFACE_H\n#define _INTERFACE_H\n\n#include \"config.h\"\n#include \"psy_const.h\"\n#include \"psy_data.h\"\n#include \"typedefs.h\"\n\n\nenum\n{\n  MS_NONE = 0,\n  MS_SOME = 1,\n  MS_ALL  = 2\n};\n\nenum\n{\n  MS_ON = 1\n};\n\nstruct TOOLSINFO {\n  Word16 msDigest;\n  Word16 msMask[MAX_GROUPED_SFB];\n};\n\n\ntypedef struct {\n  Word16  sfbCnt;\n  Word16  sfbPerGroup;\n  Word16  maxSfbPerGroup;\n  Word16  windowSequence;\n  Word16  windowShape;\n  Word16  groupingMask;\n  Word16  sfbOffsets[MAX_GROUPED_SFB+1];\n  Word16  mdctScale;\n  Word32 *sfbEnergy;\n  Word32 *sfbSpreadedEnergy;\n  Word32 *sfbThreshold;\n  Word32 *mdctSpectrum;\n  Word32  sfbEnSumLR;\n  Word32  sfbEnSumMS;\n  Word32 sfbDist[MAX_GROUPED_SFB];\n  Word32 sfbDistNew[MAX_GROUPED_SFB];\n  Word16  sfbMinSnr[MAX_GROUPED_SFB];\n  Word16 minSfMaxQuant[MAX_GROUPED_SFB];\n  Word16 minScfCalculated[MAX_GROUPED_SFB];\n  Word16 prevScfLast[MAX_GROUPED_SFB];\n  Word16 prevScfNext[MAX_GROUPED_SFB];\n  Word16 deltaPeLast[MAX_GROUPED_SFB];\n  TNS_INFO tnsInfo;\n} PSY_OUT_CHANNEL; /* Word16 size: 14 + 60(MAX_GROUPED_SFB) + 112(TNS_INFO) = 186 */\n\ntypedef struct {\n  struct TOOLSINFO toolsInfo;\n  Word16 groupedSfbOffset[MAX_CHANNELS][MAX_GROUPED_SFB+1];  /* plus one for last dummy offset ! */\n  Word16 groupedSfbMinSnr[MAX_CHANNELS][MAX_GROUPED_SFB];\n} PSY_OUT_ELEMENT;\n\ntypedef struct {\n  /* information shared by both channels  */\n  PSY_OUT_ELEMENT  psyOutElement;\n  /* information specific to each channel */\n  PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS];\n}PSY_OUT;\n\nvoid BuildInterface(Word32                 *mdctSpectrum,\n                    const Word16            mdctScale,\n                    SFB_THRESHOLD          *sfbThreshold,\n                    SFB_ENERGY             *sfbEnergy,\n                    SFB_ENERGY             *sfbSpreadedEnergy,\n                    const SFB_ENERGY_SUM    sfbEnergySumLR,\n                    const SFB_ENERGY_SUM    sfbEnergySumMS,\n                    const Word16            windowSequence,\n                    const Word16            windowShape,\n                    const Word16            sfbCnt,\n                    const Word16           *sfbOffset,\n                    const Word16            maxSfbPerGroup,\n                    const Word16           *groupedSfbMinSnr,\n                    const Word16            noOfGroups,\n                    const Word16           *groupLen,\n                    PSY_OUT_CHANNEL        *psyOutCh);\n\n#endif /* _INTERFACE_H */\n"
  },
  {
    "path": "jni/inc/line_pe.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tline_pe.h\n\n\tContent:\tPerceptual entropie module structure and functions\n\n*******************************************************************************/\n\n#ifndef __LINE_PE_H\n#define __LINE_PE_H\n\n\n#include \"psy_const.h\"\n#include \"interface.h\"\n\n\ntypedef struct {\n   Word16 sfbLdEnergy[MAX_GROUPED_SFB];     /* 4*log(sfbEnergy)/log(2) */\n   Word16 sfbNLines4[MAX_GROUPED_SFB];      /* 4*number of relevant lines in sfb */\n   Word16 sfbPe[MAX_GROUPED_SFB];           /* pe for each sfb */\n   Word16 sfbConstPart[MAX_GROUPED_SFB];    /* constant part for each sfb */\n   Word16 sfbNActiveLines[MAX_GROUPED_SFB]; /* number of active lines in sfb */\n   Word16 pe;                               /* sum of sfbPe */\n   Word16 constPart;                        /* sum of sfbConstPart */\n   Word16 nActiveLines;                     /* sum of sfbNActiveLines */\n} PE_CHANNEL_DATA; /* size Word16: 303 */\n\n\ntypedef struct {\n   PE_CHANNEL_DATA peChannelData[MAX_CHANNELS];\n   Word16 pe;\n   Word16 constPart;\n   Word16 nActiveLines;\n   Word16 offset;\n   Word16 ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB];\n   Word32 thrExp[MAX_CHANNELS][MAX_GROUPED_SFB];\n   Word32 sfbPeFactors[MAX_CHANNELS][MAX_GROUPED_SFB];\n} PE_DATA; /* size Word16: 303 + 4 + 120 + 240 = 667 */\n\n\n\n\nvoid prepareSfbPe(PE_DATA *peData,\n                  PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],\n                  Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],\n                  Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],\n                  const Word16 nChannels,\n                  const Word16 peOffset);\n\n\n\n\n\nvoid calcSfbPe(PE_DATA *peData,\n               PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],\n               const Word16 nChannels);\n\n\n\n\n#endif\n"
  },
  {
    "path": "jni/inc/memalign.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tmemalign.h\n\n\tContent:\tMemory alloc alignments functions\n\n*******************************************************************************/\n\n#ifndef __VO_AACENC_MEM_ALIGN_H__\n#define __VO_AACENC_MEM_ALIGN_H__\n\n#include \"voMem.h\"\n#include \"typedef.h\"\n\nextern void *mem_malloc(VO_MEM_OPERATOR *pMemop, unsigned int size, unsigned char alignment, unsigned int CodecID);\nextern void mem_free(VO_MEM_OPERATOR *pMemop, void *mem_ptr, unsigned int CodecID);\n\n#endif\t/* __VO_MEM_ALIGN_H__ */\n\n\n\n"
  },
  {
    "path": "jni/inc/ms_stereo.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tms_stereo.h\n\n\tContent:\tDeclaration MS stereo processing structure and functions\n\n*******************************************************************************/\n\n#ifndef __MS_STEREO_H__\n#define __MS_STEREO_H__\n#include \"typedef.h\"\n\nvoid MsStereoProcessing(Word32       *sfbEnergyLeft,\n                        Word32       *sfbEnergyRight,\n                        const Word32 *sfbEnergyMid,\n                        const Word32 *sfbEnergySide,\n                        Word32       *mdctSpectrumLeft,\n                        Word32       *mdctSpectrumRight,\n                        Word32       *sfbThresholdLeft,\n                        Word32       *sfbThresholdRight,\n                        Word32       *sfbSpreadedEnLeft,\n                        Word32       *sfbSpreadedEnRight,\n                        Word16       *msDigest,\n                        Word16       *msMask,\n                        const Word16  sfbCnt,\n                        const Word16  sfbPerGroup,\n                        const Word16  maxSfbPerGroup,\n                        const Word16 *sfbOffset);\n\n\n#endif\n"
  },
  {
    "path": "jni/inc/oper_32b.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\toper_32b.h\n\n\tContent:\tDouble precision operations\n\n*******************************************************************************/\n\n#ifndef __OPER_32b_H\n#define __OPER_32b_H\n\n#include \"typedef.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define POW2_TABLE_BITS 8\n#define POW2_TABLE_SIZE (1<<POW2_TABLE_BITS)\n\nvoid L_Extract (Word32 L_32, Word16 *hi, Word16 *lo);\nWord32 L_Comp (Word16 hi, Word16 lo);\nWord32 Mpy_32 (Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2);\nWord32 Mpy_32_16 (Word16 hi, Word16 lo, Word16 n);\nWord32 Div_32 (Word32 L_num, Word32 denom);\nWord16 iLog4(Word32 value);\nWord32 rsqrt(Word32 value,  Word32 accuracy);\nWord32 pow2_xy(Word32 x, Word32 y);\n\n__inline Word32 L_mpy_ls(Word32 L_var2, Word16 var1)\n{\n    unsigned short swLow1;\n    Word16 swHigh1;\n    Word32 l_var_out;\n\n    swLow1 = (unsigned short)(L_var2);\n    swHigh1 = (Word16)(L_var2 >> 16);\n\n    l_var_out = (long)swLow1 * (long)var1 >> 15;\n\n    l_var_out += swHigh1 * var1 << 1;\n\n    return(l_var_out);\n}\n\n__inline Word32 L_mpy_wx(Word32 L_var2, Word16 var1)\n{\n#if ARMV5TE_L_MPY_LS\n\tWord32 result;\n\tasm volatile(\n\t\t\"SMULWB  %[result], %[L_var2], %[var1] \\n\"\n\t\t:[result]\"=r\"(result)\n\t\t:[L_var2]\"r\"(L_var2), [var1]\"r\"(var1)\n\t\t);\n\treturn result;\n#else\n    unsigned short swLow1;\n    Word16 swHigh1;\n    Word32 l_var_out;\n\n    swLow1 = (unsigned short)(L_var2);\n    swHigh1 = (Word16)(L_var2 >> 16);\n\n    l_var_out = (long)swLow1 * (long)var1 >> 16;\n    l_var_out += swHigh1 * var1;\n\n    return(l_var_out);\n#endif\n}\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "jni/inc/pre_echo_control.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tpre_echo_control.h\n\n\tContent:\tPre echo control functions\n\n*******************************************************************************/\n\n#ifndef __PRE_ECHO_CONTROL_H\n#define __PRE_ECHO_CONTROL_H\n\n#include \"typedefs.h\"\n\nvoid InitPreEchoControl(Word32 *pbThresholdnm1,\n                        Word16  numPb,\n                        Word32 *pbThresholdQuiet);\n\n\nvoid PreEchoControl(Word32 *pbThresholdNm1,\n                    Word16  numPb,\n                    Word32  maxAllowedIncreaseFactor,\n                    Word16  minRemainingThresholdFactor,\n                    Word32 *pbThreshold,\n                    Word16  mdctScale,\n                    Word16  mdctScalenm1);\n\n#endif\n\n"
  },
  {
    "path": "jni/inc/psy_configuration.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tpsy_configuration.h\n\n\tContent:\tPsychoaccoustic configuration structure and functions\n\n*******************************************************************************/\n\n#ifndef _PSY_CONFIGURATION_H\n#define _PSY_CONFIGURATION_H\n\n#include \"typedefs.h\"\n#include \"psy_const.h\"\n#include \"tns.h\"\n\ntypedef struct{\n\n  Word16 sfbCnt;\n  Word16 sfbActive;   /* number of sf bands containing energy after lowpass */\n  const Word16 *sfbOffset;\n\n  Word32 sfbThresholdQuiet[MAX_SFB_LONG];\n\n  Word16 maxAllowedIncreaseFactor;   /* preecho control */\n  Word16 minRemainingThresholdFactor;\n\n  Word16 lowpassLine;\n  Word16 sampRateIdx;\n  Word32 clipEnergy;                 /* for level dependend tmn */\n\n  Word16 ratio;\n  Word16 sfbMaskLowFactor[MAX_SFB_LONG];\n  Word16 sfbMaskHighFactor[MAX_SFB_LONG];\n\n  Word16 sfbMaskLowFactorSprEn[MAX_SFB_LONG];\n  Word16 sfbMaskHighFactorSprEn[MAX_SFB_LONG];\n\n\n  Word16 sfbMinSnr[MAX_SFB_LONG];       /* minimum snr (formerly known as bmax) */\n\n  TNS_CONFIG tnsConf;\n\n}PSY_CONFIGURATION_LONG; /*Word16 size: 8 + 52 + 102 + 51 + 51 + 51 + 51 + 47 = 515 */\n\n\ntypedef struct{\n\n  Word16 sfbCnt;\n  Word16 sfbActive;   /* number of sf bands containing energy after lowpass */\n  const Word16 *sfbOffset;\n\n  Word32 sfbThresholdQuiet[MAX_SFB_SHORT];\n\n  Word16 maxAllowedIncreaseFactor;   /* preecho control */\n  Word16 minRemainingThresholdFactor;\n\n  Word16 lowpassLine;\n  Word16 sampRateIdx;\n  Word32 clipEnergy;                 /* for level dependend tmn */\n\n  Word16 ratio;\n  Word16 sfbMaskLowFactor[MAX_SFB_SHORT];\n  Word16 sfbMaskHighFactor[MAX_SFB_SHORT];\n\n  Word16 sfbMaskLowFactorSprEn[MAX_SFB_SHORT];\n  Word16 sfbMaskHighFactorSprEn[MAX_SFB_SHORT];\n\n\n  Word16 sfbMinSnr[MAX_SFB_SHORT];       /* minimum snr (formerly known as bmax) */\n\n  TNS_CONFIG tnsConf;\n\n}PSY_CONFIGURATION_SHORT; /*Word16 size: 8 + 16 + 16 + 16 + 16 + 16 + 16 + 16 + 47 = 167 */\n\n\n/* Returns the sample rate index */\nWord32 GetSRIndex(Word32 sampleRate);\n\n\nWord16 InitPsyConfigurationLong(Word32 bitrate,\n                                Word32 samplerate,\n                                Word16 bandwidth,\n                                PSY_CONFIGURATION_LONG *psyConf);\n\nWord16 InitPsyConfigurationShort(Word32 bitrate,\n                                 Word32 samplerate,\n                                 Word16 bandwidth,\n                                 PSY_CONFIGURATION_SHORT *psyConf);\n\n#endif /* _PSY_CONFIGURATION_H */\n\n\n\n"
  },
  {
    "path": "jni/inc/psy_const.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tpsy_const.h\n\n\tContent:\tGlobal psychoacoustic constants structures\n\n*******************************************************************************/\n\n#ifndef _PSYCONST_H\n#define _PSYCONST_H\n\n#include \"config.h\"\n\n#define TRUE  1\n#define FALSE 0\n\n#define FRAME_LEN_LONG    AACENC_BLOCKSIZE\n#define TRANS_FAC         8\n#define FRAME_LEN_SHORT   (FRAME_LEN_LONG/TRANS_FAC)\n\n\n\n/* Block types */\nenum\n{\n  LONG_WINDOW = 0,\n  START_WINDOW,\n  SHORT_WINDOW,\n  STOP_WINDOW\n};\n\n/* Window shapes */\nenum\n{\n  SINE_WINDOW = 0,\n  KBD_WINDOW  = 1\n};\n\n/*\n  MS stuff\n*/\nenum\n{\n  SI_MS_MASK_NONE = 0,\n  SI_MS_MASK_SOME = 1,\n  SI_MS_MASK_ALL  = 2\n};\n\n#define MAX_NO_OF_GROUPS 4\n#define MAX_SFB_SHORT   15  /* 15 for a memory optimized implementation, maybe 16 for convenient debugging */\n#define MAX_SFB_LONG    51  /* 51 for a memory optimized implementation, maybe 64 for convenient debugging */\n#define MAX_SFB         (MAX_SFB_SHORT > MAX_SFB_LONG ? MAX_SFB_SHORT : MAX_SFB_LONG)   /* = MAX_SFB_LONG */\n#define MAX_GROUPED_SFB (MAX_NO_OF_GROUPS*MAX_SFB_SHORT > MAX_SFB_LONG ? \\\n                         MAX_NO_OF_GROUPS*MAX_SFB_SHORT : MAX_SFB_LONG)\n\n#define BLOCK_SWITCHING_OFFSET\t\t   (1*1024+3*128+64+128)\n#define BLOCK_SWITCHING_DATA_SIZE          FRAME_LEN_LONG\n\n#define TRANSFORM_OFFSET_LONG    0\n#define TRANSFORM_OFFSET_SHORT   448\n\n#define LOG_NORM_PCM          -15\n\n#define NUM_SAMPLE_RATES\t12\n\n#endif /* _PSYCONST_H */\n"
  },
  {
    "path": "jni/inc/psy_data.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tpsy_data.h\n\n\tContent:\tPsychoacoustic data and structures\n\n*******************************************************************************/\n\n#ifndef _PSY_DATA_H\n#define _PSY_DATA_H\n\n#include \"block_switch.h\"\n#include \"tns.h\"\n\n/*\n  the structs can be implemented as unions\n*/\n\ntypedef struct{\n  Word32 sfbLong[MAX_GROUPED_SFB];\n  Word32 sfbShort[TRANS_FAC][MAX_SFB_SHORT];\n}SFB_THRESHOLD; /* Word16 size: 260 */\n\ntypedef struct{\n  Word32 sfbLong[MAX_GROUPED_SFB];\n  Word32 sfbShort[TRANS_FAC][MAX_SFB_SHORT];\n}SFB_ENERGY; /* Word16 size: 260 */\n\ntypedef struct{\n  Word32 sfbLong;\n  Word32 sfbShort[TRANS_FAC];\n}SFB_ENERGY_SUM; /* Word16 size: 18 */\n\n\ntypedef struct{\n  BLOCK_SWITCHING_CONTROL   blockSwitchingControl;          /* block switching */\n  Word16                    *mdctDelayBuffer;               /* mdct delay buffer [BLOCK_SWITCHING_OFFSET]*/\n  Word32                    sfbThresholdnm1[MAX_SFB];       /* PreEchoControl */\n  Word16                    mdctScalenm1;                   /* scale of last block's mdct (PreEchoControl) */\n\n  SFB_THRESHOLD             sfbThreshold;                   /* adapt           */\n  SFB_ENERGY                sfbEnergy;                      /* sfb Energy      */\n  SFB_ENERGY                sfbEnergyMS;\n  SFB_ENERGY_SUM            sfbEnergySum;\n  SFB_ENERGY_SUM            sfbEnergySumMS;\n  SFB_ENERGY                sfbSpreadedEnergy;\n\n  Word32                    *mdctSpectrum;                  /* mdct spectrum [FRAME_LEN_LONG] */\n  Word16                    mdctScale;                      /* scale of mdct   */\n}PSY_DATA; /* Word16 size: 4 + 87 + 102 + 360 + 360 + 360 + 18 + 18 + 360 = 1669 */\n\n#endif /* _PSY_DATA_H */\n"
  },
  {
    "path": "jni/inc/psy_main.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tpsy_main.h\n\n\tContent:\tPsychoacoustic major function block\n\n*******************************************************************************/\n\n#ifndef _PSYMAIN_H\n#define _PSYMAIN_H\n\n#include \"psy_configuration.h\"\n#include \"qc_data.h\"\n#include \"memalign.h\"\n\n/*\n  psy kernel\n*/\ntypedef struct  {\n  PSY_CONFIGURATION_LONG  psyConfLong;           /* Word16 size: 515 */\n  PSY_CONFIGURATION_SHORT psyConfShort;          /* Word16 size: 167 */\n  PSY_DATA                psyData[MAX_CHANNELS]; /* Word16 size: MAX_CHANNELS*1669*/\n  TNS_DATA                tnsData[MAX_CHANNELS]; /* Word16 size: MAX_CHANNELS*235 */\n  Word32*                 pScratchTns;\n  Word16\t\t\t\t  sampleRateIdx;\n}PSY_KERNEL; /* Word16 size: 2587 / 4491 */\n\n\nWord16 PsyNew( PSY_KERNEL  *hPsy, Word32 nChan, VO_MEM_OPERATOR *pMemOP);\nWord16 PsyDelete( PSY_KERNEL  *hPsy, VO_MEM_OPERATOR *pMemOP);\n\nWord16 PsyOutNew( PSY_OUT *hPsyOut, VO_MEM_OPERATOR *pMemOP);\nWord16 PsyOutDelete( PSY_OUT *hPsyOut, VO_MEM_OPERATOR *pMemOP);\n\nWord16 psyMainInit( PSY_KERNEL *hPsy,\n                    Word32 sampleRate,\n                    Word32 bitRate,\n                    Word16 channels,\n                    Word16 tnsMask,\n                    Word16 bandwidth);\n\n\nWord16 psyMain(Word16                   nChannels,   /*!< total number of channels */\n               ELEMENT_INFO             *elemInfo,\n               Word16                   *timeSignal, /*!< interleaved time signal */\n               PSY_DATA                 psyData[MAX_CHANNELS],\n               TNS_DATA                 tnsData[MAX_CHANNELS],\n               PSY_CONFIGURATION_LONG*  psyConfLong,\n               PSY_CONFIGURATION_SHORT* psyConfShort,\n               PSY_OUT_CHANNEL          psyOutChannel[MAX_CHANNELS],\n               PSY_OUT_ELEMENT          *psyOutElement,\n               Word32                   *pScratchTns,\n\t\t\t   Word32\t\t\t\t\tsampleRate);\n\n#endif /* _PSYMAIN_H */\n"
  },
  {
    "path": "jni/inc/qc_data.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tqc_data.h\n\n\tContent:\tQuantizing & coding structures\n\n*******************************************************************************/\n\n#ifndef _QC_DATA_H\n#define _QC_DATA_H\n\n#include \"psy_const.h\"\n#include \"dyn_bits.h\"\n#include \"adj_thr_data.h\"\n\n\n#define MAX_MODES 10\n\ntypedef enum {\n  MODE_INVALID = 0,\n  MODE_1,        /* mono      */\n  MODE_1_1,      /* dual mono */\n  MODE_2         /* stereo    */\n} ENCODER_MODE;\n\ntypedef enum {\n  ID_SCE=0,     /* Single Channel Element   */\n  ID_CPE=1,     /* Channel Pair Element     */\n  ID_CCE=2,     /* Coupling Channel Element */\n  ID_LFE=3,     /* LFE Channel Element      */\n  ID_DSE=4,     /* current one DSE element for ancillary is supported */\n  ID_PCE=5,\n  ID_FIL=6,\n  ID_END=7\n}ELEMENT_TYPE;\n\ntypedef struct {\n  ELEMENT_TYPE elType;\n  Word16 instanceTag;\n  Word16 nChannelsInEl;\n  Word16 ChannelIndex[MAX_CHANNELS];\n} ELEMENT_INFO;\n\ntypedef struct {\n  Word32 paddingRest;\n} PADDING;\n\n\n/* Quantizing & coding stage */\n\nstruct QC_INIT{\n  ELEMENT_INFO *elInfo;\n  Word16 maxBits;     /* maximum number of bits in reservoir  */\n  Word16 averageBits; /* average number of bits we should use */\n  Word16 bitRes;\n  Word16 meanPe;\n  Word32 chBitrate;\n  Word16 maxBitFac;\n  Word32 bitrate;\n\n  PADDING padding;\n};\n\ntypedef struct\n{\n  Word16          *quantSpec;       /* [FRAME_LEN_LONG];                            */\n  UWord16         *maxValueInSfb;   /* [MAX_GROUPED_SFB];                           */\n  Word16          *scf;             /* [MAX_GROUPED_SFB];                           */\n  Word16          globalGain;\n  Word16          mdctScale;\n  Word16          groupingMask;\n  SECTION_DATA    sectionData;\n  Word16          windowShape;\n} QC_OUT_CHANNEL;\n\ntypedef struct\n{\n  Word16\t\t  adtsUsed;\n  Word16          staticBitsUsed; /* for verification purposes */\n  Word16          dynBitsUsed;    /* for verification purposes */\n  Word16          pe;\n  Word16          ancBitsUsed;\n  Word16          fillBits;\n} QC_OUT_ELEMENT;\n\ntypedef struct\n{\n  QC_OUT_CHANNEL  qcChannel[MAX_CHANNELS];\n  QC_OUT_ELEMENT  qcElement;\n  Word16          totStaticBitsUsed; /* for verification purposes */\n  Word16          totDynBitsUsed;    /* for verification purposes */\n  Word16          totAncBitsUsed;    /* for verification purposes */\n  Word16          totFillBits;\n  Word16          alignBits;\n  Word16          bitResTot;\n  Word16          averageBitsTot;\n} QC_OUT;\n\ntypedef struct {\n  Word32 chBitrate;\n  Word16 averageBits;               /* brutto -> look ancillary.h */\n  Word16 maxBits;\n  Word16 bitResLevel;\n  Word16 maxBitResBits;\n  Word16 relativeBits;            /* Bits relative to total Bits scaled down by 2 */\n} ELEMENT_BITS;\n\ntypedef struct\n{\n  /* this is basically struct QC_INIT */\n  Word16 averageBitsTot;\n  Word16 maxBitsTot;\n  Word16 globStatBits;\n  Word16 nChannels;\n  Word16 bitResTot;\n\n  Word16 maxBitFac;\n\n  PADDING   padding;\n\n  ELEMENT_BITS  elementBits;\n  ADJ_THR_STATE adjThr;\n\n  Word16 logSfbFormFactor[MAX_CHANNELS][MAX_GROUPED_SFB];\n  Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB];\n  Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB];\n} QC_STATE;\n\n#endif /* _QC_DATA_H */\n"
  },
  {
    "path": "jni/inc/qc_main.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tqc_main.h\n\n\tContent:\tQuantizing & coding functions\n\n*******************************************************************************/\n\n#ifndef _QC_MAIN_H\n#define _QC_MAIN_H\n\n#include \"qc_data.h\"\n#include \"interface.h\"\n#include \"memalign.h\"\n\n/* Quantizing & coding stage */\n\nWord16 QCOutNew(QC_OUT *hQC, Word16 nChannels, VO_MEM_OPERATOR *pMemOP);\n\nvoid QCOutDelete(QC_OUT *hQC, VO_MEM_OPERATOR *pMemOP);\n\nWord16 QCNew(QC_STATE *hQC, VO_MEM_OPERATOR *pMemOP);\n\nWord16 QCInit(QC_STATE *hQC,\n              struct QC_INIT *init);\n\nvoid QCDelete(QC_STATE *hQC, VO_MEM_OPERATOR *pMemOP);\n\n\nWord16 QCMain(QC_STATE *hQC,\n              ELEMENT_BITS* elBits,\n              ATS_ELEMENT* adjThrStateElement,\n              PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS], /* may be modified in-place */\n              PSY_OUT_ELEMENT* psyOutElement,\n              QC_OUT_CHANNEL  qcOutChannel[MAX_CHANNELS],   /* out                      */\n              QC_OUT_ELEMENT* qcOutElement,\n              Word16 nChannels,\n\t\t\t  Word16 ancillaryDataBytes);     /* returns error code       */\n\nvoid updateBitres(QC_STATE* qcKernel,\n                  QC_OUT* qcOut);\n\nWord16 FinalizeBitConsumption(QC_STATE *hQC,\n                              QC_OUT* qcOut);\n\nWord16 AdjustBitrate(QC_STATE *hQC,\n                     Word32 bitRate,\n                     Word32 sampleRate);\n\n#endif /* _QC_MAIN_H */\n"
  },
  {
    "path": "jni/inc/quantize.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tquantize.h\n\n\tContent:\tQuantization functions\n\n*******************************************************************************/\n\n#ifndef _QUANTIZE_H_\n#define _QUANTIZE_H_\n#include \"typedefs.h\"\n\n/* quantizing */\n\n#define MAX_QUANT 8191\n\nvoid QuantizeSpectrum(Word16 sfbCnt,\n                      Word16 maxSfbPerGroup,\n                      Word16 sfbPerGroup,\n                      Word16 *sfbOffset, Word32 *mdctSpectrum,\n                      Word16 globalGain, Word16 *scalefactors,\n                      Word16 *quantizedSpectrum);\n\nWord32 calcSfbDist(const Word32 *spec,\n                   Word16  sfbWidth,\n                   Word16  gain);\n\n#endif /* _QUANTIZE_H_ */\n"
  },
  {
    "path": "jni/inc/sf_estim.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tsf_estim.h\n\n\tContent:\tScale factor estimation functions\n\n*******************************************************************************/\n\n#ifndef __SF_ESTIM_H__\n#define __SF_ESTIM_H__\n/*\n   Scale factor estimation\n */\n#include \"psy_const.h\"\n#include \"interface.h\"\n#include \"qc_data.h\"\n\nvoid\nCalcFormFactor(Word16          logSfbFormFactor[MAX_CHANNELS][MAX_GROUPED_SFB],\n               Word16          sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],\n               Word16          logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],\n               PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],\n               const Word16    nChannels);\n\nvoid\nEstimateScaleFactors(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],\n                     QC_OUT_CHANNEL  qcOutChannel[MAX_CHANNELS],\n                     Word16          logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],\n                     Word16          logSfbFormFactor[MAX_CHANNELS][MAX_GROUPED_SFB],\n                     Word16          sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],\n                     const Word16    nChannels);\n#endif\n"
  },
  {
    "path": "jni/inc/spreading.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tspreading.h\n\n\tContent:\tSpreading of energy functions\n\n*******************************************************************************/\n\n#ifndef _SPREADING_H\n#define _SPREADING_H\n#include \"typedefs.h\"\n\n\nvoid SpreadingMax(const Word16 pbCnt,\n                  const Word16 *maskLowFactor,\n                  const Word16 *maskHighFactor,\n                  Word32       *pbSpreadedEnergy);\n\n#endif /* #ifndef _SPREADING_H */\n"
  },
  {
    "path": "jni/inc/stat_bits.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tstat_bits.h\n\n\tContent:\tStatic bit counter functions\n\n*******************************************************************************/\n\n#ifndef __STAT_BITS_H\n#define __STAT_BITS_H\n\n#include \"psy_const.h\"\n#include \"interface.h\"\n\nWord16 countStaticBitdemand(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],\n                            PSY_OUT_ELEMENT *psyOutElement,\n                            Word16 nChannels,\n\t\t\t\t\t\t\tWord16 adtsUsed);\n\n#endif /* __STAT_BITS_H */\n"
  },
  {
    "path": "jni/inc/tns.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\ttns.h\n\n\tContent:\tTNS structures\n\n*******************************************************************************/\n\n#ifndef _TNS_H\n#define _TNS_H\n\n#include \"typedef.h\"\n#include \"psy_const.h\"\n\n\n\n#define TNS_MAX_ORDER 12\n#define TNS_MAX_ORDER_SHORT 5\n\n#define FILTER_DIRECTION    0\n\ntypedef struct{ /*stuff that is tabulated dependent on bitrate etc. */\n  Word16     threshOn;                /* min. prediction gain for using tns TABUL * 100*/\n  Word32     lpcStartFreq;            /* lowest freq for lpc TABUL*/\n  Word32     lpcStopFreq;             /* TABUL */\n  Word32     tnsTimeResolution;\n}TNS_CONFIG_TABULATED;\n\n\ntypedef struct {   /*assigned at InitTime*/\n  Word16 tnsActive;\n  Word16 tnsMaxSfb;\n\n  Word16 maxOrder;                /* max. order of tns filter */\n  Word16 tnsStartFreq;            /* lowest freq. for tns filtering */\n  Word16 coefRes;\n\n  TNS_CONFIG_TABULATED confTab;\n\n  Word32 acfWindow[TNS_MAX_ORDER+1];\n\n  Word16 tnsStartBand;\n  Word16 tnsStartLine;\n\n  Word16 tnsStopBand;\n  Word16 tnsStopLine;\n\n  Word16 lpcStartBand;\n  Word16 lpcStartLine;\n\n  Word16 lpcStopBand;\n  Word16 lpcStopLine;\n\n  Word16 tnsRatioPatchLowestCb;\n  Word16 tnsModifyBeginCb;\n\n  Word16 threshold; /* min. prediction gain for using tns TABUL * 100 */\n\n}TNS_CONFIG;\n\n\ntypedef struct {\n  Word16 tnsActive;\n  Word32 parcor[TNS_MAX_ORDER];\n  Word16 predictionGain;\n} TNS_SUBBLOCK_INFO; /* Word16 size: 26 */\n\ntypedef struct{\n  TNS_SUBBLOCK_INFO subBlockInfo[TRANS_FAC];\n} TNS_DATA_SHORT;\n\ntypedef struct{\n  TNS_SUBBLOCK_INFO subBlockInfo;\n} TNS_DATA_LONG;\n\ntypedef struct{\n  TNS_DATA_LONG tnsLong;\n  TNS_DATA_SHORT tnsShort;\n}TNS_DATA_RAW;\n\ntypedef struct{\n  Word16 numOfSubblocks;\n  TNS_DATA_RAW dataRaw;\n}TNS_DATA; /* Word16 size: 1 + 8*26 + 26 = 235 */\n\ntypedef struct{\n  Word16 tnsActive[TRANS_FAC];\n  Word16 coefRes[TRANS_FAC];\n  Word16 length[TRANS_FAC];\n  Word16 order[TRANS_FAC];\n  Word16 coef[TRANS_FAC*TNS_MAX_ORDER_SHORT];\n}TNS_INFO; /* Word16 size: 72 */\n\n#endif /* _TNS_H */\n"
  },
  {
    "path": "jni/inc/tns_func.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\ttns_func.h\n\n\tContent:\tTNS functions\n\n*******************************************************************************/\n\n/*\n   Temporal noise shaping\n */\n#ifndef _TNS_FUNC_H\n#define _TNS_FUNC_H\n#include \"typedef.h\"\n#include \"psy_configuration.h\"\n\nWord16 InitTnsConfigurationLong(Word32 bitrate,\n                                Word32 samplerate,\n                                Word16 channels,\n                                TNS_CONFIG *tnsConfig,\n                                PSY_CONFIGURATION_LONG *psyConfig,\n                                Word16 active);\n\nWord16 InitTnsConfigurationShort(Word32 bitrate,\n                                 Word32 samplerate,\n                                 Word16 channels,\n                                 TNS_CONFIG *tnsConfig,\n                                 PSY_CONFIGURATION_SHORT *psyConfig,\n                                 Word16 active);\n\nWord32 TnsDetect(TNS_DATA* tnsData,\n                 TNS_CONFIG tC,\n                 Word32* pScratchTns,\n                 const Word16 sfbOffset[],\n                 Word32* spectrum,\n                 Word16 subBlockNumber,\n                 Word16 blockType,\n                 Word32 * sfbEnergy);\n\nvoid TnsSync(TNS_DATA *tnsDataDest,\n             const TNS_DATA *tnsDataSrc,\n             const TNS_CONFIG tC,\n             const Word16 subBlockNumber,\n             const Word16 blockType);\n\nWord16 TnsEncode(TNS_INFO* tnsInfo,\n                 TNS_DATA* tnsData,\n                 Word16 numOfSfb,\n                 TNS_CONFIG tC,\n                 Word16 lowPassLine,\n                 Word32* spectrum,\n                 Word16 subBlockNumber,\n                 Word16 blockType);\n\nvoid ApplyTnsMultTableToRatios(Word16 startCb,\n                               Word16 stopCb,\n                               TNS_SUBBLOCK_INFO subInfo,\n                               Word32 *thresholds);\n\n\n#endif /* _TNS_FUNC_H */\n"
  },
  {
    "path": "jni/inc/tns_param.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\ttns_param.h\n\n\tContent:\tTNS parameters\n\n*******************************************************************************/\n\n/*\n   TNS parameters\n */\n#ifndef _TNS_PARAM_H\n#define _TNS_PARAM_H\n\n#include \"tns.h\"\n\ntypedef struct{\n  Word32 samplingRate;\n  Word16 maxBandLong;\n  Word16 maxBandShort;\n}TNS_MAX_TAB_ENTRY;\n\ntypedef struct{\n    Word32 bitRateFrom;\n    Word32 bitRateTo;\n    const TNS_CONFIG_TABULATED *paramMono_Long;  /* contains TNS parameters */\n    const TNS_CONFIG_TABULATED *paramMono_Short;\n    const TNS_CONFIG_TABULATED *paramStereo_Long;\n    const TNS_CONFIG_TABULATED *paramStereo_Short;\n}TNS_INFO_TAB;\n\n\nvoid GetTnsParam(TNS_CONFIG_TABULATED *tnsConfigTab,\n                 Word32 bitRate, Word16 channels, Word16 blockType);\n\nvoid GetTnsMaxBands(Word32 samplingRate, Word16 blockType, Word16* tnsMaxSfb);\n\n#endif /* _TNS_PARAM_H */\n"
  },
  {
    "path": "jni/inc/transform.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\ttransform.h\n\n\tContent:\tMDCT Transform functions\n\n*******************************************************************************/\n\n#ifndef  __TRANSFORM_H__\n#define __TRANSFORM_H__\n\n#include \"typedef.h\"\n\nvoid Transform_Real(Word16 *mdctDelayBuffer,\n                    Word16 *timeSignal,\n                    Word16 chIncrement,     /*! channel increment */\n                    Word32 *realOut,\n                    Word16 *mdctScale,\n                    Word16 windowSequence\n                    );\n\n#endif\n"
  },
  {
    "path": "jni/inc/typedef.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\ttypedef.h\n\n\tContent:\ttype defined for defferent paltform\n\n*******************************************************************************/\n\n#ifndef typedef_h\n#define typedef_h \"$Id $\"\n\n#undef ORIGINAL_TYPEDEF_H /* define to get \"original\" ETSI version\n                             of typedef.h                           */\n\n#ifdef ORIGINAL_TYPEDEF_H\n/*\n * this is the original code from the ETSI file typedef.h\n */\n\n#if defined(__BORLANDC__) || defined(__WATCOMC__) || defined(_MSC_VER) || defined(__ZTC__)\ntypedef signed char Word8;\ntypedef short Word16;\ntypedef long Word32;\ntypedef int Flag;\n\n#elif defined(__sun)\ntypedef signed char Word8;\ntypedef short Word16;\ntypedef long Word32;\ntypedef int Flag;\n\n#elif defined(__unix__) || defined(__unix)\ntypedef signed char Word8;\ntypedef short Word16;\ntypedef int Word32;\ntypedef int Flag;\n\n#endif\n#else /* not original typedef.h */\n\n/*\n * use (improved) type definition file typdefs.h and add a \"Flag\" type\n */\n#include \"typedefs.h\"\ntypedef int Flag;\n\n#endif\n\n#endif\n"
  },
  {
    "path": "jni/inc/typedefs.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\ttypedefs.h\n\n\tContent:\ttype defined or const defined\n\n*******************************************************************************/\n\n#ifndef typedefs_h\n#define typedefs_h \"$Id $\"\n\n#ifndef CHAR_BIT\n#define CHAR_BIT      8         /* number of bits in a char */\n#endif\n\n#ifndef VOAAC_SHRT_MAX\n#define VOAAC_SHRT_MAX    (32767)        /* maximum (signed) short value */\n#endif\n\n#ifndef VOAAC_SHRT_MIN\n#define VOAAC_SHRT_MIN    (-32768)        /* minimum (signed) short value */\n#endif\n\n/* Define NULL pointer value */\n#ifndef NULL\n#ifdef __cplusplus\n#define NULL    0\n#else\n#define NULL    ((void *)0)\n#endif\n#endif\n\n#ifndef assert\n#define assert(_Expression)     ((void)0)\n#endif\n\n#define __inline static __inline\n\n#define INT_BITS   32\n/*\n********************************************************************************\n*                         DEFINITION OF CONSTANTS\n********************************************************************************\n*/\n/*\n ********* define char type\n */\ntypedef char Char;\n\n/*\n ********* define 8 bit signed/unsigned types & constants\n */\ntypedef signed char Word8;\ntypedef unsigned char UWord8;\n/*\n ********* define 16 bit signed/unsigned types & constants\n */\ntypedef short Word16;\ntypedef unsigned short UWord16;\n\n/*\n ********* define 32 bit signed/unsigned types & constants\n */\ntypedef int Word32;\ntypedef unsigned int UWord32;\n\n\n\n#ifndef _MSC_VER\ntypedef long long Word64;\ntypedef unsigned long long UWord64;\n#else\ntypedef __int64 Word64;\ntypedef unsigned __int64 UWord64;\n#endif\n\n#ifndef min\n#define min(a,b) ( a < b ? a : b)\n#endif\n\n#ifndef max\n#define max(a,b) ( a > b ? a : b)\n#endif\n\n#ifdef ARM_INASM\n#ifdef ARMV5_INASM\n#define ARMV5E_INASM\t1\n#endif\n#define ARMV4_INASM\t\t1\n#endif\n\n#if ARMV4_INASM\n\t#define ARMV5TE_SAT           1\n    #define ARMV5TE_ADD           1\n    #define ARMV5TE_SUB           1\n\t#define ARMV5TE_SHL           1\n    #define ARMV5TE_SHR           1\n\t#define ARMV5TE_L_SHL         1\n    #define ARMV5TE_L_SHR         1\n#endif//ARMV4\n#if ARMV5E_INASM\n    #define ARMV5TE_L_ADD         1\n    #define ARMV5TE_L_SUB         1\n    #define ARMV5TE_L_MULT        1\n    #define ARMV5TE_L_MAC         1\n    #define ARMV5TE_L_MSU         1\n\n\n    #define ARMV5TE_DIV_S         1\n    #define ARMV5TE_ROUND         1\n    #define ARMV5TE_MULT          1\n\n    #define ARMV5TE_NORM_S        1\n    #define ARMV5TE_NORM_L        1\n\t#define ARMV5TE_L_MPY_LS\t  1\n#endif\n#if ARMV6_INASM\n    #undef  ARMV5TE_ADD\n    #define ARMV5TE_ADD           0\n    #undef  ARMV5TE_SUB\n    #define ARMV5TE_SUB           0\n    #define ARMV6_SAT             1\n#endif\n\n//basic operation functions optimization flags\n#define SATRUATE_IS_INLINE              1   //define saturate as inline function\n#define SHL_IS_INLINE                   1  //define shl as inline function\n#define SHR_IS_INLINE                   1   //define shr as inline function\n#define L_MULT_IS_INLINE                1   //define L_mult as inline function\n#define L_MSU_IS_INLINE                 1   //define L_msu as inline function\n#define L_SUB_IS_INLINE                 1   //define L_sub as inline function\n#define L_SHL_IS_INLINE                 1   //define L_shl as inline function\n#define L_SHR_IS_INLINE                 1   //define L_shr as inline function\n#define ADD_IS_INLINE                   1   //define add as inline function //add, inline is the best\n#define SUB_IS_INLINE                   1   //define sub as inline function //sub, inline is the best\n#define DIV_S_IS_INLINE                 1   //define div_s as inline function\n#define MULT_IS_INLINE                  1   //define mult as inline function\n#define NORM_S_IS_INLINE                1   //define norm_s as inline function\n#define NORM_L_IS_INLINE                1   //define norm_l as inline function\n#define ROUND_IS_INLINE                 1   //define round as inline function\n#define L_MAC_IS_INLINE                 1   //define L_mac as inline function\n#define L_ADD_IS_INLINE                 1   //define L_add as inline function\n#define EXTRACT_H_IS_INLINE             1   //define extract_h as inline function\n#define EXTRACT_L_IS_INLINE             1   //define extract_l as inline function        //???\n#define MULT_R_IS_INLINE                1   //define mult_r as inline function\n#define SHR_R_IS_INLINE                 1   //define shr_r as inline function\n#define MAC_R_IS_INLINE                 1   //define mac_r as inline function\n#define MSU_R_IS_INLINE                 1   //define msu_r as inline function\n#define L_SHR_R_IS_INLINE               1   //define L_shr_r as inline function\n\n#define PREFIX\t\t\t\tvoAACEnc\n#define LINK0(x, y, z)\t\tLINK1(x,y,z)\n#define LINK1(x,y,z)\t\tx##y##z\n#define ADD_PREFIX(func)\tLINK0(PREFIX, _, func)\n\n#define  L_Extract\t\tADD_PREFIX(L_Extract)\n#define  L_Comp\t\t\tADD_PREFIX(L_Comp)\n#define  Mpy_32\t\t\tADD_PREFIX(Mpy_32)\n#define  Mpy_32_16\t\tADD_PREFIX(Mpy_32_16)\n#define  Div_32\t\t\tADD_PREFIX(Div_32)\n#define  iLog4\t\t\tADD_PREFIX(iLog4)\n#define  rsqrt\t\t\tADD_PREFIX(rsqrt)\n#define  pow2_xy\t\tADD_PREFIX(pow2_xy)\n#define  L_mpy_ls\t\tADD_PREFIX(L_mpy_ls)\n#define  L_mpy_wx\t\tADD_PREFIX(L_mpy_wx)\n#define  TnsEncode\t\tADD_PREFIX(TnsEncode)\n#define  GetSRIndex\t\tADD_PREFIX(GetSRIndex)\n#define  WriteBitstream\t\tADD_PREFIX(WriteBitstream)\n\n#define mem_malloc\t\tADD_PREFIX(mem_malloc)\n#define mem_free\t\tADD_PREFIX(mem_free)\n\n#endif\n"
  },
  {
    "path": "jni/inc/voAAC.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tvoAAC.h\n\n\tContent:\tAAC codec APIs & data types\n\n*******************************************************************************/\n\n#ifndef __voAAC_H__\n#define __voAAC_H__\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#include \"voAudio.h\"\n\n/*!\n * the frame type that the decoder supports\n */\ntypedef enum {\n\tVOAAC_RAWDATA\t\t\t= 0,\t/*!<contains only raw aac data in a frame*/\n\tVOAAC_ADTS\t\t\t\t= 1,\t/*!<contains ADTS header + raw AAC data in a frame*/\n\tVOAAC_FT_MAX\t\t\t= VO_MAX_ENUM_VALUE\n} VOAACFRAMETYPE;\n\n/*!\n * the structure for AAC encoder input parameter\n */\ntypedef  struct {\n  int\t  sampleRate;          /*! audio file sample rate */\n  int\t  bitRate;             /*! encoder bit rate in bits/sec */\n  short   nChannels;\t\t   /*! number of channels on input (1,2) */\n  short   adtsUsed;\t\t\t   /*! whether write adts header */\n} AACENC_PARAM;\n\n/* AAC Param ID */\n#define VO_PID_AAC_Mdoule\t\t\t\t0x42211000\n#define VO_PID_AAC_ENCPARAM\t\t\t\tVO_PID_AAC_Mdoule | 0x0040  /*!< get/set AAC encoder parameter, the parameter is a pointer to AACENC_PARAM */\n\n/* AAC decoder error ID */\n#define VO_ERR_AAC_Mdoule\t\t\t\t0x82210000\n#define VO_ERR_AAC_UNSFILEFORMAT\t\t(VO_ERR_AAC_Mdoule | 0xF001)\n#define VO_ERR_AAC_UNSPROFILE\t\t\t(VO_ERR_AAC_Mdoule | 0xF002)\n\n/**\n * Get audio encoder API interface\n * \\param pEncHandle [out] Return the AAC Encoder handle.\n * \\retval VO_ERR_OK Succeeded.\n */\nVO_S32 VO_API voGetAACEncAPI (VO_AUDIO_CODECAPI * pEncHandle);\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif // __voAAC_H__\n\n\n\n"
  },
  {
    "path": "jni/inc/voAMRWB.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tvoAMRWB.h\n\n\tContent:\tAMR-WB codec APIs & data types\n\n*******************************************************************************/\n#ifndef  __VOAMRWB_H__\n#define  __VOAMRWB_H__\n\n#include  \"voAudio.h\"\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n#pragma pack(push, 4)\n\n/*!* the bit rate the codec supports*/\ntypedef enum {\n\tVOAMRWB_MDNONE\t\t= -1,\t/*!< Invalid mode */\n\tVOAMRWB_MD66\t\t= 0,\t/*!< 6.60kbps   */\n\tVOAMRWB_MD885\t\t= 1,    /*!< 8.85kbps   */\n\tVOAMRWB_MD1265\t\t= 2,\t/*!< 12.65kbps  */\n\tVOAMRWB_MD1425\t\t= 3,\t/*!< 14.25kbps  */\n\tVOAMRWB_MD1585\t\t= 4,\t/*!< 15.85bps   */\n\tVOAMRWB_MD1825\t\t= 5,\t/*!< 18.25bps   */\n\tVOAMRWB_MD1985\t\t= 6,\t/*!< 19.85kbps  */\n\tVOAMRWB_MD2305\t\t= 7,    /*!< 23.05kbps  */\n\tVOAMRWB_MD2385          = 8,    /*!< 23.85kbps> */\n\tVOAMRWB_N_MODES \t= 9,\t/*!< Invalid mode */\n\tVOAMRWB_MODE_MAX    = VO_MAX_ENUM_VALUE\n\n}VOAMRWBMODE;\n\n/*!* the frame format the codec supports*/\ntypedef enum {\n\tVOAMRWB_DEFAULT  \t= 0,\t/*!< the frame type is the header (defined in RFC3267) + rawdata*/\n\t/*One word (2-byte) for sync word (0x6b21)*/\n\t/*One word (2-byte) for frame length N.*/\n\t/*N words (2-byte) containing N bits (bit 0 = 0x007f, bit 1 = 0x0081).*/\n\tVOAMRWB_ITU         = 1,\n\t/*One word (2-byte) for sync word (0x6b21).*/\n\t/*One word (2-byte) to indicate the frame type.*/\n\t/*One word (2-byte) to indicate the mode.*/\n\t/*N words  (2-byte) containing N bits (bit 0 = 0xff81, bit 1 = 0x007f).*/\n\tVOAMRWB_RFC3267\t\t= 2,\t/* see RFC 3267 */\n    VOAMRWB_TMAX        = VO_MAX_ENUM_VALUE\n}VOAMRWBFRAMETYPE;\n\n\n#define    VO_PID_AMRWB_Module\t\t\t\t\t\t\t0x42261000\n#define    VO_PID_AMRWB_FORMAT                          (VO_PID_AMRWB_Module | 0x0002)\n#define    VO_PID_AMRWB_CHANNELS                        (VO_PID_AMRWB_Module | 0x0003)\n#define    VO_PID_AMRWB_SAMPLERATE                      (VO_PID_AMRWB_Module | 0x0004)\n#define    VO_PID_AMRWB_FRAMETYPE                       (VO_PID_AMRWB_Module | 0x0005)\n#define    VO_PID_AMRWB_MODE                            (VO_PID_AMRWB_Module | 0x0006)\n#define    VO_PID_AMRWB_DTX                             (VO_PID_AMRWB_Module | 0x0007)\n\n/**\n * Get audio codec API interface\n * \\param pEncHandle [out] Return the AMRWB Encoder handle.\n * \\retval VO_ERR_OK Succeeded.\n */\nVO_S32 VO_API voGetAMRWBEncAPI(VO_AUDIO_CODECAPI *pEncHandle);\n\n\n#pragma pack(pop)\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif /* __cplusplus */\n\n\n#endif   //__VOAMRWB_H__\n\n"
  },
  {
    "path": "jni/inc/voAudio.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tvoAudio.h\n\n\tContent:\tAudio types and functions\n\n*******************************************************************************/\n\n#ifndef __voAudio_H__\n#define __voAudio_H__\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#include \"voIndex.h\"\n#include \"voMem.h\"\n\n#define\tVO_PID_AUDIO_BASE\t\t\t 0x42000000\t\t\t\t\t\t\t/*!< The base param ID for AUDIO codec */\n#define\tVO_PID_AUDIO_FORMAT\t\t\t(VO_PID_AUDIO_BASE | 0X0001)\t\t/*!< The format data of audio in track */\n#define\tVO_PID_AUDIO_SAMPLEREATE\t(VO_PID_AUDIO_BASE | 0X0002)\t\t/*!< The sample rate of audio  */\n#define\tVO_PID_AUDIO_CHANNELS\t\t(VO_PID_AUDIO_BASE | 0X0003)\t\t/*!< The channel of audio */\n#define\tVO_PID_AUDIO_BITRATE\t\t(VO_PID_AUDIO_BASE | 0X0004)\t\t/*!< The bit rate of audio */\n#define VO_PID_AUDIO_CHANNELMODE\t(VO_PID_AUDIO_BASE | 0X0005)\t\t/*!< The channel mode of audio */\n\n#define\tVO_ERR_AUDIO_BASE\t\t\t0x82000000\n#define VO_ERR_AUDIO_UNSCHANNEL\t\tVO_ERR_AUDIO_BASE | 0x0001\n#define VO_ERR_AUDIO_UNSSAMPLERATE\tVO_ERR_AUDIO_BASE | 0x0002\n#define VO_ERR_AUDIO_UNSFEATURE\t\tVO_ERR_AUDIO_BASE | 0x0003\n\n\n/**\n *Enumeration used to define the possible audio coding formats.\n */\ntypedef enum VO_AUDIO_CODINGTYPE {\n\tVO_AUDIO_CodingUnused = 0,  /**< Placeholder value when coding is N/A  */\n\tVO_AUDIO_CodingPCM,         /**< Any variant of PCM coding */\n\tVO_AUDIO_CodingADPCM,       /**< Any variant of ADPCM encoded data */\n\tVO_AUDIO_CodingAMRNB,       /**< Any variant of AMR encoded data */\n\tVO_AUDIO_CodingAMRWB,       /**< Any variant of AMR encoded data */\n\tVO_AUDIO_CodingAMRWBP,      /**< Any variant of AMR encoded data */\n\tVO_AUDIO_CodingQCELP13,     /**< Any variant of QCELP 13kbps encoded data */\n\tVO_AUDIO_CodingEVRC,        /**< Any variant of EVRC encoded data */\n\tVO_AUDIO_CodingAAC,         /**< Any variant of AAC encoded data, 0xA106 - ISO/MPEG-4 AAC, 0xFF - AAC */\n\tVO_AUDIO_CodingAC3,         /**< Any variant of AC3 encoded data */\n\tVO_AUDIO_CodingFLAC,        /**< Any variant of FLAC encoded data */\n\tVO_AUDIO_CodingMP1,\t\t\t/**< Any variant of MP1 encoded data */\n\tVO_AUDIO_CodingMP3,         /**< Any variant of MP3 encoded data */\n\tVO_AUDIO_CodingOGG,         /**< Any variant of OGG encoded data */\n\tVO_AUDIO_CodingWMA,         /**< Any variant of WMA encoded data */\n\tVO_AUDIO_CodingRA,          /**< Any variant of RA encoded data */\n\tVO_AUDIO_CodingMIDI,        /**< Any variant of MIDI encoded data */\n\tVO_AUDIO_CodingDRA,         /**< Any variant of dra encoded data */\n\tVO_AUDIO_CodingG729,        /**< Any variant of dra encoded data */\n\tVO_AUDIO_Coding_MAX\t\t= VO_MAX_ENUM_VALUE\n} VO_AUDIO_CODINGTYPE;\n\n/*!\n* the channel type value\n*/\ntypedef enum {\n\tVO_CHANNEL_CENTER\t\t\t\t= 1,\t/*!<center channel*/\n\tVO_CHANNEL_FRONT_LEFT\t\t\t= 1<<1,\t/*!<front left channel*/\n\tVO_CHANNEL_FRONT_RIGHT\t\t\t= 1<<2,\t/*!<front right channel*/\n\tVO_CHANNEL_SIDE_LEFT  \t\t\t= 1<<3, /*!<side left channel*/\n\tVO_CHANNEL_SIDE_RIGHT\t\t\t= 1<<4, /*!<side right channel*/\n\tVO_CHANNEL_BACK_LEFT\t\t\t= 1<<5,\t/*!<back left channel*/\n\tVO_CHANNEL_BACK_RIGHT\t\t\t= 1<<6,\t/*!<back right channel*/\n\tVO_CHANNEL_BACK_CENTER\t\t\t= 1<<7,\t/*!<back center channel*/\n\tVO_CHANNEL_LFE_BASS\t\t\t\t= 1<<8,\t/*!<low-frequency effects bass channel*/\n\tVO_CHANNEL_ALL\t\t\t\t\t= 0xffff,/*!<[default] include all channels */\n\tVO_CHANNEL_MAX\t\t\t\t\t= VO_MAX_ENUM_VALUE\n} VO_AUDIO_CHANNELTYPE;\n\n/**\n * General audio format info\n */\ntypedef struct\n{\n\tVO_S32\tSampleRate;  /*!< Sample rate */\n\tVO_S32\tChannels;    /*!< Channel count */\n\tVO_S32\tSampleBits;  /*!< Bits per sample */\n} VO_AUDIO_FORMAT;\n\n/**\n * General audio output info\n */\ntypedef struct\n{\n\tVO_AUDIO_FORMAT\tFormat;\t\t\t/*!< Sample rate */\n\tVO_U32\t\t\tInputUsed;\t\t/*!< Channel count */\n\tVO_U32\t\t\tResever;\t\t/*!< Resevered */\n} VO_AUDIO_OUTPUTINFO;\n\n/**\n * General audio codec function set\n */\ntypedef struct VO_AUDIO_CODECAPI\n{\n\t/**\n\t * Init the audio codec module and return codec handle\n\t * \\param phCodec [OUT] Return the video codec handle\n\t * \\param vType\t[IN] The codec type if the module support multi codec.\n\t * \\param pUserData\t[IN] The init param. It is either a memory operator or an allocated memory\n\t * \\retval VO_ERR_NONE Succeeded.\n\t */\n\tVO_U32 (VO_API * Init) (VO_HANDLE * phCodec, VO_AUDIO_CODINGTYPE vType, VO_CODEC_INIT_USERDATA * pUserData );\n\n\t/**\n\t * Set input audio data.\n\t * \\param hCodec [IN]] The codec handle which was created by Init function.\n\t * \\param pInput [IN] The input buffer param.\n\t * \\retval VO_ERR_NONE Succeeded.\n\t */\n\tVO_U32 (VO_API * SetInputData) (VO_HANDLE hCodec, VO_CODECBUFFER * pInput);\n\n\t/**\n\t * Get the outut audio data\n\t * \\param hCodec [IN]] The codec handle which was created by Init function.\n\t * \\param pOutBuffer [OUT] The output audio data\n\t * \\param pOutInfo [OUT] The codec fills audio format and the input data size used in current call.\n\t *\t\t\t\t\t\t pOutInfo->InputUsed is total used input data size in byte.\n\t * \\retval  VO_ERR_NONE Succeeded.\n\t *\t\t\tVO_ERR_INPUT_BUFFER_SMALL. The input was finished or the input data was not enought. Continue to input\n\t *\t\t\t\t\t\t\t\t\t\tdata before next call.\n\t */\n\tVO_U32 (VO_API * GetOutputData) (VO_HANDLE hCodec, VO_CODECBUFFER * pOutBuffer, VO_AUDIO_OUTPUTINFO * pOutInfo);\n\n\t/**\n\t * Set the parameter for the specified param ID.\n\t * \\param hCodec [IN]] The codec handle which was created by Init function.\n\t * \\param uParamID [IN] The param ID.\n\t * \\param pData [IN] The param value.\n\t * \\retval VO_ERR_NONE Succeeded.\n\t */\n\tVO_U32 (VO_API * SetParam) (VO_HANDLE hCodec, VO_S32 uParamID, VO_PTR pData);\n\n\t/**\n\t * Get the parameter for the specified param ID.\n\t * \\param hCodec [IN]] The codec handle which was created by Init function.\n\t * \\param uParamID [IN] The param ID.\n\t * \\param pData [IN] The param value.\n\t * \\retval VO_ERR_NONE Succeeded.\n\t */\n\tVO_U32 (VO_API * GetParam) (VO_HANDLE hCodec, VO_S32 uParamID, VO_PTR pData);\n\n\t/**\n\t * Uninit the Codec.\n\t * \\param hCodec [IN]] The codec handle which was created by Init function.\n\t * \\retval VO_ERR_NONE Succeeded.\n\t */\n\tVO_U32 (VO_API * Uninit) (VO_HANDLE hCodec);\n} VO_AUDIO_CODECAPI;\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif // __voAudio_H__\n"
  },
  {
    "path": "jni/inc/voIndex.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tvoIndex.h\n\n\tContent:\tmodule and ID definition\n\n*******************************************************************************/\n\n#ifndef __voIndex_H__\n#define __voIndex_H__\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#include \"voType.h\"\n\n/* Define the module ID */\n#define _MAKE_SOURCE_ID(id, name) \\\nVO_INDEX_SRC_##name = _VO_INDEX_SOURCE | id,\n\n#define _MAKE_CODEC_ID(id, name) \\\nVO_INDEX_DEC_##name = _VO_INDEX_DEC | id, \\\nVO_INDEX_ENC_##name = _VO_INDEX_ENC | id,\n\n#define _MAKE_EFFECT_ID(id, name) \\\nVO_INDEX_EFT_##name = _VO_INDEX_EFFECT | id,\n\n#define _MAKE_SINK_ID(id, name) \\\nVO_INDEX_SNK_##name = _VO_INDEX_SINK | id,\n\n#define _MAKE_FILTER_ID(id, name) \\\nVO_INDEX_FLT_##name = _VO_INDEX_FILTER | id,\n\n#define _MAKE_OMX_ID(id, name) \\\nVO_INDEX_OMX_##name = _VO_INDEX_OMX | id,\n\n#define _MAKE_MFW_ID(id, name) \\\nVO_INDEX_MFW_##name = _VO_INDEX_MFW | id,\n\nenum\n{\n\t_VO_INDEX_SOURCE\t\t= 0x01000000,\n\t_VO_INDEX_DEC\t\t\t= 0x02000000,\n\t_VO_INDEX_ENC\t\t\t= 0x03000000,\n\t_VO_INDEX_EFFECT\t\t= 0x04000000,\n\t_VO_INDEX_SINK\t\t\t= 0x05000000,\n\t_VO_INDEX_FILTER\t\t= 0x06000000,\n\t_VO_INDEX_OMX\t\t\t= 0x07000000,\n\t_VO_INDEX_MFW\t\t\t= 0x08000000,\n\n\t// define file parser modules\n\t_MAKE_SOURCE_ID (0x010000, MP4)\n\t_MAKE_SOURCE_ID (0x020000, AVI)\n\t_MAKE_SOURCE_ID (0x030000, ASF)\n\t_MAKE_SOURCE_ID (0x040000, REAL)\n\t_MAKE_SOURCE_ID (0x050000, AUDIO)\n\t_MAKE_SOURCE_ID (0x060000, FLASH)\n\t_MAKE_SOURCE_ID (0x070000, OGG)\n\t_MAKE_SOURCE_ID (0x080000, MKV)\n\n\t// define network source modules\n\t_MAKE_SOURCE_ID (0x110000, RTSP)\n\t_MAKE_SOURCE_ID (0x120000, HTTP)\n\n\t// define CMMB source modules\n\t_MAKE_SOURCE_ID (0x200000, CMMB)\n\t_MAKE_SOURCE_ID (0x210000, CMMB_INNO)\n\t_MAKE_SOURCE_ID (0x220000, CMMB_TELE)\n\t_MAKE_SOURCE_ID (0x230000, CMMB_SIANO)\n\n\t// define DVBT source modules\n\t_MAKE_SOURCE_ID (0x300000, DVBT)\n\t_MAKE_SOURCE_ID (0x310000, DVBT_DIBCOM)\n\n\t// define other source modules\n\t_MAKE_SOURCE_ID (0x400000, ID3)\n\n\t// define video codec modules\n\t_MAKE_CODEC_ID (0x010000, H264)\n\t_MAKE_CODEC_ID (0x020000, MPEG4)\n\t_MAKE_CODEC_ID (0x030000, H263)\n\t_MAKE_CODEC_ID (0x040000, S263)\n\t_MAKE_CODEC_ID (0x050000, RV)\n\t_MAKE_CODEC_ID (0x060000, WMV)\n\t_MAKE_CODEC_ID (0x070000, DIVX3)\n\t_MAKE_CODEC_ID (0x080000, MJPEG)\n\t_MAKE_CODEC_ID (0x090000, MPEG2)\n\t_MAKE_CODEC_ID (0x0A0000, VP6)\n\n\t// define audio codec modules\n\t_MAKE_CODEC_ID (0x210000, AAC)\n\t_MAKE_CODEC_ID (0x220000, MP3)\n\t_MAKE_CODEC_ID (0x230000, WMA)\n\t_MAKE_CODEC_ID (0x240000, RA)\n\t_MAKE_CODEC_ID (0x250000, AMRNB)\n\t_MAKE_CODEC_ID (0x260000, AMRWB)\n\t_MAKE_CODEC_ID (0x270000, AMRWBP)\n\t_MAKE_CODEC_ID (0x280000, QCELP)\n\t_MAKE_CODEC_ID (0x290000, EVRC)\n\t_MAKE_CODEC_ID (0x2A0000, ADPCM)\n\t_MAKE_CODEC_ID (0x2B0000, MIDI)\n\t_MAKE_CODEC_ID (0x2C0000, AC3)\n\t_MAKE_CODEC_ID (0x2D0000, FLAC)\n\t_MAKE_CODEC_ID (0x2E0000, DRA)\n\t_MAKE_CODEC_ID (0x2F0000, OGG)\n\t_MAKE_CODEC_ID (0x300000, G729)\n\n\t// define image codec modules\n\t_MAKE_CODEC_ID (0x410000, JPEG)\n\t_MAKE_CODEC_ID (0x420000, GIF)\n\t_MAKE_CODEC_ID (0x430000, PNG)\n\t_MAKE_CODEC_ID (0x440000, TIF)\n\n\t// define effect modules\n\t_MAKE_EFFECT_ID (0x010000, EQ)\n\n\t// define sink modules\n\t_MAKE_SINK_ID (0x010000, VIDEO)\n\t_MAKE_SINK_ID (0x020000, AUDIO)\n\t_MAKE_SINK_ID (0x030000, CCRRR)\n\t_MAKE_SINK_ID (0x040000, CCRRV)\n\n\t_MAKE_SINK_ID (0x110000, MP4)\n\t_MAKE_SINK_ID (0x120000, AVI)\n\t_MAKE_SINK_ID (0x130000, AFW)\n\n\t// define media frame module ID\n\t_MAKE_MFW_ID (0x010000, VOMMPLAY)\n\t_MAKE_MFW_ID (0x020000, VOMMREC)\n\t_MAKE_MFW_ID (0x030000, VOME)\n};\n\n\n/* define the error ID */\n#define VO_ERR_NONE\t\t\t\t\t\t0x00000000\n#define VO_ERR_FINISH\t\t\t\t\t0x00000001\n#define VO_ERR_BASE\t\t\t\t\t\t0X80000000\n#define VO_ERR_FAILED\t\t\t\t\t0x80000001\n#define VO_ERR_OUTOF_MEMORY\t\t\t\t0x80000002\n#define VO_ERR_NOT_IMPLEMENT\t\t\t0x80000003\n#define VO_ERR_INVALID_ARG\t\t\t\t0x80000004\n#define VO_ERR_INPUT_BUFFER_SMALL\t\t0x80000005\n#define VO_ERR_OUTPUT_BUFFER_SMALL\t\t0x80000006\n#define VO_ERR_WRONG_STATUS\t\t\t\t0x80000007\n#define VO_ERR_WRONG_PARAM_ID\t\t\t0x80000008\n#define VO_ERR_LICENSE_ERROR\t\t\t0x80000009\n\n/* xxx is the module ID\n#define VO_ERR_FAILED\t\t\t\t\t0x8xxx0001\n#define VO_ERR_OUTOF_MEMORY\t\t\t\t0x8xxx0002\n#define VO_ERR_NOT_IMPLEMENT\t\t\t0x8xxx0003\n#define VO_ERR_INVALID_ARG\t\t\t\t0x8xxx0004\n#define VO_ERR_INPUT_BUFFER_SMALL\t\t0x8xxx0005\n#define VO_ERR_OUTPUT_BUFFER_SMALL\t\t0x8xxx0006\n#define VO_ERR_WRONG_STATUS\t\t\t\t0x8xxx0007\n#define VO_ERR_WRONG_PARAM_ID\t\t\t0x8xxx0008\n#define VO_ERR_LICENSE_ERROR\t\t\t0x8xxx0009\n// Module own error ID\n#define VO_ERR_Module\t\t\t\t\t0x8xxx0X00\n*/\n\n#define\tVO_PID_COMMON_BASE\t\t\t\t 0x40000000\t\t\t\t\t\t/*!< The base of common param ID */\n#define\tVO_PID_COMMON_QUERYMEM\t\t\t(VO_PID_COMMON_BASE | 0X0001)\t/*!< Query the memory needed; Reserved. */\n#define\tVO_PID_COMMON_INPUTTYPE\t\t\t(VO_PID_COMMON_BASE | 0X0002)\t/*!< Set or get the input buffer type. VO_INPUT_TYPE */\n#define\tVO_PID_COMMON_HASRESOURCE\t\t(VO_PID_COMMON_BASE | 0X0003)\t/*!< Query it has resource to be used. VO_U32 *, 1 have, 0 No */\n#define\tVO_PID_COMMON_HEADDATA\t\t\t(VO_PID_COMMON_BASE | 0X0004)\t/*!< Decoder track header data. VO_CODECBUFFER * */\n#define\tVO_PID_COMMON_FLUSH\t\t\t\t(VO_PID_COMMON_BASE | 0X0005)\t/*!< Flush the codec buffer. VO_U32 *, 1 Flush, 0 No * */\n\n/*\n// Module Param ID\n#define VO_ID_Mdoule\t\t\t\t\t0x0xxx1000\n*/\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif // __voIndex_H__\n"
  },
  {
    "path": "jni/inc/voMem.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tvoMem.h\n\n\tContent:\tmemory functions & data structures\n\n*******************************************************************************/\n\n#ifndef __voMem_H__\n#define __voMem_H__\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#include \"voIndex.h\"\n\ntypedef struct\n{\n\tVO_S32\t\t\t\tSize;\t\t\t\t/*!< Buffer stride */\n\tVO_S32\t\t\t\tFlag;\n\tVO_PTR\t\t\t\tVBuffer;\t\t\t/*!< user data pointer */\n\tVO_PTR\t\t\t\tPBuffer;\t\t\t/*!< user data pointer */\n}\nVO_MEM_INFO;\n\ntypedef struct VO_MEM_OPERATOR\n{\n\tVO_U32 (VO_API * Alloc) (VO_S32 uID, VO_MEM_INFO * pMemInfo);\n\tVO_U32 (VO_API * Free) (VO_S32 uID, VO_PTR pBuff);\n\tVO_U32 (VO_API * Set) (VO_S32 uID, VO_PTR pBuff, VO_U8 uValue, VO_U32 uSize);\n\tVO_U32 (VO_API * Copy) (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize);\n\tVO_U32 (VO_API * Check) (VO_S32 uID, VO_PTR pBuffer, VO_U32 uSize);\n\tVO_S32 (VO_API * Compare) (VO_S32 uID, VO_PTR pBuffer1, VO_PTR pBuffer2, VO_U32 uSize);\n\tVO_U32 (VO_API * Move) (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize);\n} VO_MEM_OPERATOR;\n\n#define voMemAlloc(pBuff, pMemOP, ID, nSize) \\\n{ \\\n\tVO_MEM_INFO voMemInfo; \\\n\tvoMemInfo.Size=nSize; \\\n\tpMemOP->Alloc(ID, &voMemInfo); \\\n\tpBuff=(VO_PBYTE)voMemInfo.VBuffer; \\\n}\n\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif // __voMem_H__\n"
  },
  {
    "path": "jni/inc/voType.h",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tvoType.h\n\n\tContent:\tdata type definition\n\n*******************************************************************************/\n#ifndef __voType_H__\n#define __voType_H__\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#ifdef _WIN32\n#\tdefine VO_API __cdecl\n#\tdefine VO_CBI __stdcall\n#else\n#\tdefine VO_API\n#\tdefine VO_CBI\n#endif //_WIN32\n\n/** VO_IN is used to identify inputs to an VO function.  This designation\n    will also be used in the case of a pointer that points to a parameter\n    that is used as an output. */\n#ifndef VO_IN\n#define VO_IN\n#endif\n\n/** VO_OUT is used to identify outputs from an VO function.  This\n    designation will also be used in the case of a pointer that points\n    to a parameter that is used as an input. */\n#ifndef VO_OUT\n#define VO_OUT\n#endif\n\n/** VO_INOUT is used to identify parameters that may be either inputs or\n    outputs from an VO function at the same time.  This designation will\n    also be used in the case of a pointer that  points to a parameter that\n    is used both as an input and an output. */\n#ifndef VO_INOUT\n#define VO_INOUT\n#endif\n\n#define VO_MAX_ENUM_VALUE\t0X7FFFFFFF\n\n/** VO_VOID */\ntypedef void VO_VOID;\n\n/** VO_U8 is an 8 bit unsigned quantity that is byte aligned */\ntypedef unsigned char VO_U8;\n\n/** VO_BYTE is an 8 bit unsigned quantity that is byte aligned */\ntypedef unsigned char VO_BYTE;\n\n/** VO_S8 is an 8 bit signed quantity that is byte aligned */\ntypedef signed char VO_S8;\n\n/** VO_CHAR is an 8 bit signed quantity that is byte aligned */\ntypedef char VO_CHAR;\n\n/** VO_U16 is a 16 bit unsigned quantity that is 16 bit word aligned */\ntypedef unsigned short VO_U16;\n\n/** VO_WCHAR is a 16 bit unsigned quantity that is 16 bit word aligned */\n#if defined _WIN32\ntypedef unsigned short VO_WCHAR;\ntypedef unsigned short* VO_PWCHAR;\n#elif defined LINUX\ntypedef unsigned char VO_WCHAR;\ntypedef unsigned char* VO_PWCHAR;\n#endif\n\n/** VO_S16 is a 16 bit signed quantity that is 16 bit word aligned */\ntypedef signed short VO_S16;\n\n/** VO_U32 is a 32 bit unsigned quantity that is 32 bit word aligned */\ntypedef unsigned long VO_U32;\n\n/** VO_S32 is a 32 bit signed quantity that is 32 bit word aligned */\ntypedef signed long VO_S32;\n\n/* Users with compilers that cannot accept the \"long long\" designation should\n   define the VO_SKIP64BIT macro.  It should be noted that this may cause\n   some components to fail to compile if the component was written to require\n   64 bit integral types.  However, these components would NOT compile anyway\n   since the compiler does not support the way the component was written.\n*/\n#ifndef VO_SKIP64BIT\n#ifdef _MSC_VER\n/** VO_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */\ntypedef unsigned __int64  VO_U64;\n/** VO_S64 is a 64 bit signed quantity that is 64 bit word aligned */\ntypedef signed   __int64  VO_S64;\n#else // WIN32\n/** VO_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */\ntypedef unsigned long long VO_U64;\n/** VO_S64 is a 64 bit signed quantity that is 64 bit word aligned */\ntypedef signed long long VO_S64;\n#endif // WIN32\n#endif // VO_SKIP64BIT\n\n/** The VO_BOOL type is intended to be used to represent a true or a false\n    value when passing parameters to and from the VO core and components.  The\n    VO_BOOL is a 32 bit quantity and is aligned on a 32 bit word boundary.\n */\ntypedef enum VO_BOOL {\n    VO_FALSE = 0,\n    VO_TRUE = !VO_FALSE,\n\tVO_BOOL_MAX = VO_MAX_ENUM_VALUE\n} VO_BOOL;\n\n/** The VO_PTR type is intended to be used to pass pointers between the VO\n    applications and the VO Core and components.  This is a 32 bit pointer and\n    is aligned on a 32 bit boundary.\n */\ntypedef void* VO_PTR;\n\n/** The VO_HANDLE type is intended to be used to pass pointers between the VO\n    applications and the VO Core and components.  This is a 32 bit pointer and\n    is aligned on a 32 bit boundary.\n */\ntypedef void* VO_HANDLE;\n\n/** The VO_STRING type is intended to be used to pass \"C\" type strings between\n    the application and the core and component.  The VO_STRING type is a 32\n    bit pointer to a zero terminated string.  The  pointer is word aligned and\n    the string is byte aligned.\n */\ntypedef char* VO_PCHAR;\n\n/** The VO_PBYTE type is intended to be used to pass arrays of bytes such as\n    buffers between the application and the component and core.  The VO_PBYTE\n    type is a 32 bit pointer to a zero terminated string.  The  pointer is word\n    aligned and the string is byte aligned.\n */\ntypedef unsigned char* VO_PBYTE;\n\n/** The VO_PTCHAR type is intended to be used to pass arrays of wchar such as\n    unicode char between the application and the component and core.  The VO_PTCHAR\n    type is a 32 bit pointer to a zero terminated string.  The  pointer is word\n    aligned and the string is byte aligned.\n */\n/*\n#if !defined LINUX\ntypedef unsigned short* VO_PTCHAR;\ntypedef unsigned short* VO_TCHAR;\n#else\ntypedef char* VO_PTCHAR;\ntypedef char VO_TCHAR;\n#endif\n*/\n\n#ifndef NULL\n#ifdef __cplusplus\n#define NULL    0\n#else\n#define NULL    ((void *)0)\n#endif\n#endif\n\n/**\n * Input stream format, Frame or Stream..\n */\ntypedef enum {\n    VO_INPUT_FRAME\t= 1,\t/*!< Input contains completely frame(s) data. */\n    VO_INPUT_STREAM,\t\t/*!< Input is stream data. */\n\tVO_INPUT_STREAM_MAX = VO_MAX_ENUM_VALUE\n} VO_INPUT_TYPE;\n\n\n/**\n * General data buffer, used as input or output.\n */\ntypedef struct {\n\tVO_PBYTE\tBuffer;\t\t/*!< Buffer pointer */\n\tVO_U32\t\tLength;\t\t/*!< Buffer size in byte */\n\tVO_S64\t\tTime;\t\t/*!< The time of the buffer */\n} VO_CODECBUFFER;\n\n\n/**\n * The init memdata flag.\n */\ntypedef enum{\n\tVO_IMF_USERMEMOPERATOR\t\t=0,\t/*!< memData is  the pointer of memoperator function*/\n\tVO_IMF_PREALLOCATEDBUFFER\t=1,\t/*!< memData is  preallocated memory*/\n\tVO_IMF_MAX = VO_MAX_ENUM_VALUE\n}VO_INIT_MEM_FlAG;\n\n\n/**\n * The init memory structure..\n */\ntypedef struct{\n\tVO_INIT_MEM_FlAG\t\t\tmemflag;\t/*!<memory flag  */\n\tVO_PTR\t\t\t\t\t\tmemData;\t/*!<a pointer to VO_MEM_OPERATOR or a preallocated buffer  */\n\tVO_U32\t\t\t\t\t\treserved1;\t/*!<reserved  */\n\tVO_U32\t\t\t\t\t\treserved2;\t/*!<reserved */\n}VO_CODEC_INIT_USERDATA;\n\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif // __voType_H__\n"
  },
  {
    "path": "jni/patent_disclaimer.txt",
    "content": "\nTHIS IS NOT A GRANT OF PATENT RIGHTS.\n\nGoogle makes no representation or warranty that the codecs for which\nsource code is made available hereunder are unencumbered by\nthird-party patents.  Those intending to use this source code in\nhardware or software products are advised that implementations of\nthese codecs, including in open source software or shareware, may\nrequire patent licenses from the relevant patent holders.\n"
  },
  {
    "path": "jni/src/aac_rom.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\taac_rom.c\n\n\tContent:\tconstant tables\n\n*******************************************************************************/\n\n#include \"aac_rom.h\"\n\n#if defined (ARMV5E) && !defined (ARMV7Neon)\n\n/*\n *  Q30 for 128 and 1024\n *\n * for (i = 0; i < num/4; i++) {\n *   angle = (i + 0.125) * M_PI / num;\n *   x = cos(angle) * (1 << 30);\n *   x = sin(angle) * (1 << 30);\n *\n *   angle = (num/2 - 1 - i + 0.125) * M_PI / num;\n *   x = cos(angle) * (1 << 30);\n *   x = sin(angle) * (1 << 30);\n * }\n */\nconst int cossintab[128 + 1024] = {\n\t/* 128 */\n\t0x3fffec43, 0x003243f1, 0x015fd4d2, 0x3ffc38d1, 0x3ff9c13a, 0x01c454f5, 0x02f1b755, 0x3feea776,\n\t0x3fe9b8a9, 0x03562038, 0x0483259d, 0x3fd73a4a, 0x3fcfd50b, 0x04e767c5, 0x0613e1c5, 0x3fb5f4ea,\n\t0x3fac1a5b, 0x0677edbb, 0x07a3adff, 0x3f8adc77, 0x3f7e8e1e, 0x08077457, 0x09324ca7, 0x3f55f796,\n\t0x3f473759, 0x0995bdfd, 0x0abf8043, 0x3f174e70, 0x3f061e95, 0x0b228d42, 0x0c4b0b94, 0x3eceeaad,\n\t0x3ebb4ddb, 0x0cada4f5, 0x0dd4b19a, 0x3e7cd778, 0x3e66d0b4, 0x0e36c82a, 0x0f5c35a3, 0x3e212179,\n\t0x3e08b42a, 0x0fbdba40, 0x10e15b4e, 0x3dbbd6d4, 0x3da106bd, 0x11423ef0, 0x1263e699, 0x3d4d0728,\n\t0x3d2fd86c, 0x12c41a4f, 0x13e39be9, 0x3cd4c38b, 0x3cb53aaa, 0x144310dd, 0x15604013, 0x3c531e88,\n\t0x3c314060, 0x15bee78c, 0x16d99864, 0x3bc82c1f, 0x3ba3fde7, 0x173763c9, 0x184f6aab, 0x3b3401bb,\n\t0x3b0d8909, 0x18ac4b87, 0x19c17d44, 0x3a96b636, 0x3a6df8f8, 0x1a1d6544, 0x1b2f971e, 0x39f061d2,\n\t0x39c5664f, 0x1b8a7815, 0x1c997fc4, 0x39411e33, 0x3913eb0e, 0x1cf34baf, 0x1dfeff67, 0x38890663,\n\t0x3859a292, 0x1e57a86d, 0x1f5fdee6, 0x37c836c2, 0x3796a996, 0x1fb7575c, 0x20bbe7d8, 0x36fecd0e,\n\t0x36cb1e2a, 0x21122240, 0x2212e492, 0x362ce855, 0x35f71fb1, 0x2267d3a0, 0x2364a02e, 0x3552a8f4,\n\t0x351acedd, 0x23b836ca, 0x24b0e699, 0x34703095, 0x34364da6, 0x250317df, 0x25f78497, 0x3385a222,\n\t0x3349bf48, 0x264843d9, 0x273847c8, 0x329321c7, 0x32554840, 0x27878893, 0x2872feb6, 0x3198d4ea,\n\t0x31590e3e, 0x28c0b4d2, 0x29a778db, 0x3096e223, 0x30553828, 0x29f3984c, 0x2ad586a3, 0x2f8d713a,\n\t0x2f49ee0f, 0x2b2003ac, 0x2bfcf97c, 0x2e7cab1c, 0x2e37592c, 0x2c45c8a0, 0x2d1da3d5, 0x2d64b9da,\n\t/* 1024 */\n\t0x3fffffb1, 0x0006487f, 0x002bfb74, 0x3ffff0e3, 0x3fffe705, 0x00388c6e, 0x005e3f4c, 0x3fffba9b,\n\t0x3fffa6de, 0x006ad03b, 0x009082ea, 0x3fff5cd8, 0x3fff3f3c, 0x009d13c5, 0x00c2c62f, 0x3ffed79b,\n\t0x3ffeb021, 0x00cf56ef, 0x00f508fc, 0x3ffe2ae5, 0x3ffdf98c, 0x01019998, 0x01274b31, 0x3ffd56b5,\n\t0x3ffd1b7e, 0x0133dba3, 0x01598cb1, 0x3ffc5b0c, 0x3ffc15f7, 0x01661cf0, 0x018bcd5b, 0x3ffb37ec,\n\t0x3ffae8f9, 0x01985d60, 0x01be0d11, 0x3ff9ed53, 0x3ff99483, 0x01ca9cd4, 0x01f04bb4, 0x3ff87b44,\n\t0x3ff81896, 0x01fcdb2e, 0x02228924, 0x3ff6e1bf, 0x3ff67534, 0x022f184d, 0x0254c544, 0x3ff520c5,\n\t0x3ff4aa5d, 0x02615414, 0x0286fff3, 0x3ff33858, 0x3ff2b813, 0x02938e62, 0x02b93914, 0x3ff12878,\n\t0x3ff09e56, 0x02c5c71a, 0x02eb7086, 0x3feef126, 0x3fee5d28, 0x02f7fe1c, 0x031da62b, 0x3fec9265,\n\t0x3febf48b, 0x032a3349, 0x034fd9e5, 0x3fea0c35, 0x3fe96480, 0x035c6682, 0x03820b93, 0x3fe75e98,\n\t0x3fe6ad08, 0x038e97a9, 0x03b43b17, 0x3fe48990, 0x3fe3ce26, 0x03c0c69e, 0x03e66852, 0x3fe18d1f,\n\t0x3fe0c7da, 0x03f2f342, 0x04189326, 0x3fde6945, 0x3fdd9a27, 0x04251d77, 0x044abb73, 0x3fdb1e06,\n\t0x3fda450f, 0x0457451d, 0x047ce11a, 0x3fd7ab64, 0x3fd6c894, 0x04896a16, 0x04af03fc, 0x3fd4115f,\n\t0x3fd324b7, 0x04bb8c42, 0x04e123fa, 0x3fd04ffc, 0x3fcf597c, 0x04edab83, 0x051340f6, 0x3fcc673b,\n\t0x3fcb66e4, 0x051fc7b9, 0x05455ad1, 0x3fc8571f, 0x3fc74cf3, 0x0551e0c7, 0x0577716b, 0x3fc41fac,\n\t0x3fc30baa, 0x0583f68c, 0x05a984a6, 0x3fbfc0e3, 0x3fbea30c, 0x05b608eb, 0x05db9463, 0x3fbb3ac7,\n\t0x3fba131b, 0x05e817c3, 0x060da083, 0x3fb68d5b, 0x3fb55bdc, 0x061a22f7, 0x063fa8e7, 0x3fb1b8a2,\n\t0x3fb07d50, 0x064c2a67, 0x0671ad71, 0x3facbc9f, 0x3fab777b, 0x067e2df5, 0x06a3ae00, 0x3fa79954,\n\t0x3fa64a5f, 0x06b02d81, 0x06d5aa77, 0x3fa24ec6, 0x3fa0f600, 0x06e228ee, 0x0707a2b7, 0x3f9cdcf7,\n\t0x3f9b7a62, 0x0714201b, 0x073996a1, 0x3f9743eb, 0x3f95d787, 0x074612eb, 0x076b8616, 0x3f9183a5,\n\t0x3f900d72, 0x0778013d, 0x079d70f7, 0x3f8b9c28, 0x3f8a1c29, 0x07a9eaf5, 0x07cf5726, 0x3f858d79,\n\t0x3f8403ae, 0x07dbcff2, 0x08013883, 0x3f7f579b, 0x3f7dc405, 0x080db016, 0x083314f1, 0x3f78fa92,\n\t0x3f775d31, 0x083f8b43, 0x0864ec4f, 0x3f727661, 0x3f70cf38, 0x08716159, 0x0896be80, 0x3f6bcb0e,\n\t0x3f6a1a1c, 0x08a3323a, 0x08c88b65, 0x3f64f89b, 0x3f633de2, 0x08d4fdc6, 0x08fa52de, 0x3f5dff0e,\n\t0x3f5c3a8f, 0x0906c3e0, 0x092c14ce, 0x3f56de6a, 0x3f551026, 0x09388469, 0x095dd116, 0x3f4f96b4,\n\t0x3f4dbeac, 0x096a3f42, 0x098f8796, 0x3f4827f0, 0x3f464626, 0x099bf44c, 0x09c13831, 0x3f409223,\n\t0x3f3ea697, 0x09cda368, 0x09f2e2c7, 0x3f38d552, 0x3f36e006, 0x09ff4c78, 0x0a24873a, 0x3f30f181,\n\t0x3f2ef276, 0x0a30ef5e, 0x0a56256c, 0x3f28e6b6, 0x3f26ddec, 0x0a628bfa, 0x0a87bd3d, 0x3f20b4f5,\n\t0x3f1ea26e, 0x0a94222f, 0x0ab94e8f, 0x3f185c43, 0x3f164001, 0x0ac5b1dc, 0x0aead944, 0x3f0fdca5,\n\t0x3f0db6a9, 0x0af73ae5, 0x0b1c5d3d, 0x3f073621, 0x3f05066d, 0x0b28bd2a, 0x0b4dda5c, 0x3efe68bc,\n\t0x3efc2f50, 0x0b5a388d, 0x0b7f5081, 0x3ef5747b, 0x3ef3315a, 0x0b8bacf0, 0x0bb0bf8f, 0x3eec5965,\n\t0x3eea0c8e, 0x0bbd1a33, 0x0be22766, 0x3ee3177e, 0x3ee0c0f4, 0x0bee8038, 0x0c1387e9, 0x3ed9aecc,\n\t0x3ed74e91, 0x0c1fdee1, 0x0c44e0f9, 0x3ed01f55, 0x3ecdb56a, 0x0c513610, 0x0c763278, 0x3ec66920,\n\t0x3ec3f585, 0x0c8285a5, 0x0ca77c47, 0x3ebc8c31, 0x3eba0ee9, 0x0cb3cd84, 0x0cd8be47, 0x3eb2888f,\n\t0x3eb0019c, 0x0ce50d8c, 0x0d09f85b, 0x3ea85e41, 0x3ea5cda3, 0x0d1645a0, 0x0d3b2a64, 0x3e9e0d4c,\n\t0x3e9b7306, 0x0d4775a1, 0x0d6c5443, 0x3e9395b7, 0x3e90f1ca, 0x0d789d71, 0x0d9d75db, 0x3e88f788,\n\t0x3e8649f5, 0x0da9bcf2, 0x0dce8f0d, 0x3e7e32c6, 0x3e7b7b90, 0x0ddad406, 0x0dff9fba, 0x3e734778,\n\t0x3e70869f, 0x0e0be28e, 0x0e30a7c5, 0x3e6835a4, 0x3e656b2b, 0x0e3ce86b, 0x0e61a70f, 0x3e5cfd51,\n\t0x3e5a2939, 0x0e6de580, 0x0e929d7a, 0x3e519e86, 0x3e4ec0d1, 0x0e9ed9af, 0x0ec38ae8, 0x3e46194a,\n\t0x3e4331fa, 0x0ecfc4d9, 0x0ef46f3b, 0x3e3a6da4, 0x3e377cbb, 0x0f00a6df, 0x0f254a53, 0x3e2e9b9c,\n\t0x3e2ba11b, 0x0f317fa5, 0x0f561c15, 0x3e22a338, 0x3e1f9f21, 0x0f624f0c, 0x0f86e460, 0x3e168480,\n\t0x3e1376d5, 0x0f9314f5, 0x0fb7a317, 0x3e0a3f7b, 0x3e07283f, 0x0fc3d143, 0x0fe8581d, 0x3dfdd432,\n\t0x3dfab365, 0x0ff483d7, 0x10190352, 0x3df142ab, 0x3dee1851, 0x10252c94, 0x1049a49a, 0x3de48aef,\n\t0x3de15708, 0x1055cb5b, 0x107a3bd5, 0x3dd7ad05, 0x3dd46f94, 0x1086600e, 0x10aac8e6, 0x3dcaa8f5,\n\t0x3dc761fc, 0x10b6ea90, 0x10db4baf, 0x3dbd7ec7, 0x3dba2e48, 0x10e76ac3, 0x110bc413, 0x3db02e84,\n\t0x3dacd481, 0x1117e088, 0x113c31f3, 0x3da2b834, 0x3d9f54af, 0x11484bc2, 0x116c9531, 0x3d951bde,\n\t0x3d91aed9, 0x1178ac53, 0x119cedaf, 0x3d87598c, 0x3d83e309, 0x11a9021d, 0x11cd3b50, 0x3d797145,\n\t0x3d75f147, 0x11d94d02, 0x11fd7df6, 0x3d6b6313, 0x3d67d99b, 0x12098ce5, 0x122db583, 0x3d5d2efe,\n\t0x3d599c0e, 0x1239c1a7, 0x125de1da, 0x3d4ed50f, 0x3d4b38aa, 0x1269eb2b, 0x128e02dc, 0x3d40554e,\n\t0x3d3caf76, 0x129a0954, 0x12be186c, 0x3d31afc5, 0x3d2e007c, 0x12ca1c03, 0x12ee226c, 0x3d22e47c,\n\t0x3d1f2bc5, 0x12fa231b, 0x131e20c0, 0x3d13f37e, 0x3d10315a, 0x132a1e7e, 0x134e1348, 0x3d04dcd2,\n\t0x3d011145, 0x135a0e0e, 0x137df9e7, 0x3cf5a082, 0x3cf1cb8e, 0x1389f1af, 0x13add481, 0x3ce63e98,\n\t0x3ce2603f, 0x13b9c943, 0x13dda2f7, 0x3cd6b71e, 0x3cd2cf62, 0x13e994ab, 0x140d652c, 0x3cc70a1c,\n\t0x3cc318ff, 0x141953cb, 0x143d1b02, 0x3cb7379c, 0x3cb33d22, 0x14490685, 0x146cc45c, 0x3ca73fa9,\n\t0x3ca33bd3, 0x1478acbc, 0x149c611d, 0x3c97224c, 0x3c93151d, 0x14a84652, 0x14cbf127, 0x3c86df8e,\n\t0x3c82c909, 0x14d7d32a, 0x14fb745e, 0x3c76777b, 0x3c7257a2, 0x15075327, 0x152aeaa3, 0x3c65ea1c,\n\t0x3c61c0f1, 0x1536c62b, 0x155a53d9, 0x3c55377b, 0x3c510501, 0x15662c18, 0x1589afe3, 0x3c445fa2,\n\t0x3c4023dd, 0x159584d3, 0x15b8fea4, 0x3c33629d, 0x3c2f1d8e, 0x15c4d03e, 0x15e83fff, 0x3c224075,\n\t0x3c1df21f, 0x15f40e3a, 0x161773d6, 0x3c10f935, 0x3c0ca19b, 0x16233eac, 0x16469a0d, 0x3bff8ce8,\n\t0x3bfb2c0c, 0x16526176, 0x1675b286, 0x3bedfb99, 0x3be9917e, 0x1681767c, 0x16a4bd25, 0x3bdc4552,\n\t0x3bd7d1fa, 0x16b07d9f, 0x16d3b9cc, 0x3bca6a1d, 0x3bc5ed8d, 0x16df76c3, 0x1702a85e, 0x3bb86a08,\n\t0x3bb3e440, 0x170e61cc, 0x173188be, 0x3ba6451b, 0x3ba1b620, 0x173d3e9b, 0x17605ad0, 0x3b93fb63,\n\t0x3b8f6337, 0x176c0d15, 0x178f1e76, 0x3b818ceb, 0x3b7ceb90, 0x179acd1c, 0x17bdd394, 0x3b6ef9be,\n\t0x3b6a4f38, 0x17c97e93, 0x17ec7a0d, 0x3b5c41e8, 0x3b578e39, 0x17f8215e, 0x181b11c4, 0x3b496574,\n\t0x3b44a8a0, 0x1826b561, 0x18499a9d, 0x3b36646e, 0x3b319e77, 0x18553a7d, 0x1878147a, 0x3b233ee1,\n\t0x3b1e6fca, 0x1883b097, 0x18a67f3f, 0x3b0ff4d9, 0x3b0b1ca6, 0x18b21791, 0x18d4dad0, 0x3afc8663,\n\t0x3af7a516, 0x18e06f50, 0x1903270f, 0x3ae8f38b, 0x3ae40926, 0x190eb7b7, 0x193163e1, 0x3ad53c5b,\n\t0x3ad048e3, 0x193cf0a9, 0x195f9128, 0x3ac160e1, 0x3abc6458, 0x196b1a09, 0x198daec8, 0x3aad6129,\n\t0x3aa85b92, 0x199933bb, 0x19bbbca6, 0x3a993d3e, 0x3a942e9d, 0x19c73da3, 0x19e9baa3, 0x3a84f52f,\n\t0x3a7fdd86, 0x19f537a4, 0x1a17a8a5, 0x3a708906, 0x3a6b6859, 0x1a2321a2, 0x1a45868e, 0x3a5bf8d1,\n\t0x3a56cf23, 0x1a50fb81, 0x1a735442, 0x3a47449c, 0x3a4211f0, 0x1a7ec524, 0x1aa111a6, 0x3a326c74,\n\t0x3a2d30cd, 0x1aac7e6f, 0x1acebe9d, 0x3a1d7066, 0x3a182bc8, 0x1ada2746, 0x1afc5b0a, 0x3a08507f,\n\t0x3a0302ed, 0x1b07bf8c, 0x1b29e6d2, 0x39f30ccc, 0x39edb649, 0x1b354727, 0x1b5761d8, 0x39dda55a,\n\t0x39d845e9, 0x1b62bdf8, 0x1b84cc01, 0x39c81a36, 0x39c2b1da, 0x1b9023e5, 0x1bb22530, 0x39b26b6d,\n\t0x39acfa2b, 0x1bbd78d2, 0x1bdf6d4a, 0x399c990d, 0x39971ee7, 0x1beabca1, 0x1c0ca432, 0x3986a324,\n\t0x3981201e, 0x1c17ef39, 0x1c39c9cd, 0x397089bf, 0x396afddc, 0x1c45107c, 0x1c66ddfe, 0x395a4ceb,\n\t0x3954b82e, 0x1c72204f, 0x1c93e0ab, 0x3943ecb6, 0x393e4f23, 0x1c9f1e96, 0x1cc0d1b6, 0x392d692f,\n\t0x3927c2c9, 0x1ccc0b35, 0x1cedb106, 0x3916c262, 0x3911132d, 0x1cf8e611, 0x1d1a7e7d, 0x38fff85e,\n\t0x38fa405e, 0x1d25af0d, 0x1d473a00, 0x38e90b31, 0x38e34a69, 0x1d52660f, 0x1d73e374, 0x38d1fae9,\n\t0x38cc315d, 0x1d7f0afb, 0x1da07abc, 0x38bac795, 0x38b4f547, 0x1dab9db5, 0x1dccffbf, 0x38a37142,\n\t0x389d9637, 0x1dd81e21, 0x1df9725f, 0x388bf7ff, 0x3886143b, 0x1e048c24, 0x1e25d282, 0x38745bdb,\n\t0x386e6f60, 0x1e30e7a4, 0x1e52200c, 0x385c9ce3, 0x3856a7b6, 0x1e5d3084, 0x1e7e5ae2, 0x3844bb28,\n\t0x383ebd4c, 0x1e8966a8, 0x1eaa82e9, 0x382cb6b7, 0x3826b030, 0x1eb589f7, 0x1ed69805, 0x38148f9f,\n\t0x380e8071, 0x1ee19a54, 0x1f029a1c, 0x37fc45ef, 0x37f62e1d, 0x1f0d97a5, 0x1f2e8911, 0x37e3d9b7,\n\t0x37ddb945, 0x1f3981ce, 0x1f5a64cb, 0x37cb4b04, 0x37c521f6, 0x1f6558b5, 0x1f862d2d, 0x37b299e7,\n\t0x37ac6841, 0x1f911c3d, 0x1fb1e21d, 0x3799c66f, 0x37938c34, 0x1fbccc4d, 0x1fdd8381, 0x3780d0aa,\n\t0x377a8ddf, 0x1fe868c8, 0x2009113c, 0x3767b8a9, 0x37616d51, 0x2013f196, 0x20348b35, 0x374e7e7b,\n\t0x37482a9a, 0x203f6699, 0x205ff14f, 0x3735222f, 0x372ec5c9, 0x206ac7b8, 0x208b4372, 0x371ba3d4,\n\t0x37153eee, 0x209614d9, 0x20b68181, 0x3702037c, 0x36fb9618, 0x20c14ddf, 0x20e1ab63, 0x36e84135,\n\t0x36e1cb58, 0x20ec72b1, 0x210cc0fc, 0x36ce5d10, 0x36c7debd, 0x21178334, 0x2137c232, 0x36b4571b,\n\t0x36add058, 0x21427f4d, 0x2162aeea, 0x369a2f69, 0x3693a038, 0x216d66e2, 0x218d870b, 0x367fe608,\n\t0x36794e6e, 0x219839d8, 0x21b84a79, 0x36657b08, 0x365edb09, 0x21c2f815, 0x21e2f91a, 0x364aee7b,\n\t0x3644461b, 0x21eda17f, 0x220d92d4, 0x36304070, 0x36298fb4, 0x221835fb, 0x2238178d, 0x361570f8,\n\t0x360eb7e3, 0x2242b56f, 0x22628729, 0x35fa8023, 0x35f3beba, 0x226d1fc1, 0x228ce191, 0x35df6e03,\n\t0x35d8a449, 0x229774d7, 0x22b726a8, 0x35c43aa7, 0x35bd68a1, 0x22c1b496, 0x22e15655, 0x35a8e621,\n\t0x35a20bd3, 0x22ebdee5, 0x230b707e, 0x358d7081, 0x35868def, 0x2315f3a8, 0x23357509, 0x3571d9d9,\n\t0x356aef08, 0x233ff2c8, 0x235f63dc, 0x35562239, 0x354f2f2c, 0x2369dc29, 0x23893cdd, 0x353a49b2,\n\t0x35334e6f, 0x2393afb2, 0x23b2fff3, 0x351e5056, 0x35174ce0, 0x23bd6d48, 0x23dcad03, 0x35023636,\n\t0x34fb2a92, 0x23e714d3, 0x240643f4, 0x34e5fb63, 0x34dee795, 0x2410a639, 0x242fc4ad, 0x34c99fef,\n\t0x34c283fb, 0x243a215f, 0x24592f13, 0x34ad23eb, 0x34a5ffd5, 0x2463862c, 0x2482830d, 0x34908768,\n\t0x34895b36, 0x248cd487, 0x24abc082, 0x3473ca79, 0x346c962f, 0x24b60c57, 0x24d4e757, 0x3456ed2f,\n\t0x344fb0d1, 0x24df2d81, 0x24fdf775, 0x3439ef9c, 0x3432ab2e, 0x250837ed, 0x2526f0c1, 0x341cd1d2,\n\t0x34158559, 0x25312b81, 0x254fd323, 0x33ff93e2, 0x33f83f62, 0x255a0823, 0x25789e80, 0x33e235df,\n\t0x33dad95e, 0x2582cdbc, 0x25a152c0, 0x33c4b7db, 0x33bd535c, 0x25ab7c30, 0x25c9efca, 0x33a719e8,\n\t0x339fad70, 0x25d41369, 0x25f27584, 0x33895c18, 0x3381e7ac, 0x25fc934b, 0x261ae3d6, 0x336b7e7e,\n\t0x33640223, 0x2624fbbf, 0x26433aa7, 0x334d812d, 0x3345fce6, 0x264d4cac, 0x266b79dd, 0x332f6435,\n\t0x3327d808, 0x267585f8, 0x2693a161, 0x331127ab, 0x3309939c, 0x269da78b, 0x26bbb119, 0x32f2cba1,\n\t0x32eb2fb5, 0x26c5b14c, 0x26e3a8ec, 0x32d45029, 0x32ccac64, 0x26eda322, 0x270b88c2, 0x32b5b557,\n\t0x32ae09be, 0x27157cf5, 0x27335082, 0x3296fb3d, 0x328f47d5, 0x273d3eac, 0x275b0014, 0x327821ee,\n\t0x327066bc, 0x2764e82f, 0x27829760, 0x3259297d, 0x32516686, 0x278c7965, 0x27aa164c, 0x323a11fe,\n\t0x32324746, 0x27b3f235, 0x27d17cc1, 0x321adb83, 0x3213090f, 0x27db5288, 0x27f8caa5, 0x31fb8620,\n\t0x31f3abf5, 0x28029a45, 0x281fffe2, 0x31dc11e8, 0x31d4300b, 0x2829c954, 0x28471c5e, 0x31bc7eee,\n\t0x31b49564, 0x2850df9d, 0x286e2002, 0x319ccd46, 0x3194dc14, 0x2877dd07, 0x28950ab6, 0x317cfd04,\n\t0x3175042e, 0x289ec17a, 0x28bbdc61, 0x315d0e3b, 0x31550dc6, 0x28c58cdf, 0x28e294eb, 0x313d00ff,\n\t0x3134f8f1, 0x28ec3f1e, 0x2909343e, 0x311cd564, 0x3114c5c0, 0x2912d81f, 0x292fba40, 0x30fc8b7d,\n\t0x30f47449, 0x293957c9, 0x295626da, 0x30dc235e, 0x30d404a0, 0x295fbe06, 0x297c79f5, 0x30bb9d1c,\n\t0x30b376d8, 0x29860abd, 0x29a2b378, 0x309af8ca, 0x3092cb05, 0x29ac3dd7, 0x29c8d34d, 0x307a367c,\n\t0x3072013c, 0x29d2573c, 0x29eed95b, 0x30595648, 0x30511991, 0x29f856d5, 0x2a14c58b, 0x30385840,\n\t0x30301418, 0x2a1e3c8a, 0x2a3a97c7, 0x30173c7a, 0x300ef0e5, 0x2a440844, 0x2a604ff5, 0x2ff6030a,\n\t0x2fedb00d, 0x2a69b9ec, 0x2a85ee00, 0x2fd4ac04, 0x2fcc51a5, 0x2a8f516b, 0x2aab71d0, 0x2fb3377c,\n\t0x2faad5c1, 0x2ab4cea9, 0x2ad0db4e, 0x2f91a589, 0x2f893c75, 0x2ada318e, 0x2af62a63, 0x2f6ff63d,\n\t0x2f6785d7, 0x2aff7a05, 0x2b1b5ef8, 0x2f4e29af, 0x2f45b1fb, 0x2b24a7f6, 0x2b4078f5, 0x2f2c3ff2,\n\t0x2f23c0f6, 0x2b49bb4a, 0x2b657844, 0x2f0a391d, 0x2f01b2de, 0x2b6eb3ea, 0x2b8a5cce, 0x2ee81543,\n\t0x2edf87c6, 0x2b9391c0, 0x2baf267d, 0x2ec5d479, 0x2ebd3fc4, 0x2bb854b4, 0x2bd3d53a, 0x2ea376d6,\n\t0x2e9adaee, 0x2bdcfcb0, 0x2bf868ed, 0x2e80fc6e, 0x2e785958, 0x2c01899e, 0x2c1ce181, 0x2e5e6556,\n\t0x2e55bb17, 0x2c25fb66, 0x2c413edf, 0x2e3bb1a4, 0x2e330042, 0x2c4a51f3, 0x2c6580f1, 0x2e18e16d,\n\t0x2e1028ed, 0x2c6e8d2e, 0x2c89a79f, 0x2df5f4c7, 0x2ded352f, 0x2c92ad01, 0x2cadb2d5, 0x2dd2ebc7,\n\t0x2dca251c, 0x2cb6b155, 0x2cd1a27b, 0x2dafc683, 0x2da6f8ca, 0x2cda9a14, 0x2cf5767c, 0x2d8c8510,\n\t0x2d83b04f, 0x2cfe6728, 0x2d192ec1, 0x2d692784, 0x2d604bc0, 0x2d22187a, 0x2d3ccb34, 0x2d45adf6\n};\n\n\nconst int twidTab512[(8*6 + 32*6 + 128*6)/2] = {\n\t0x40000000, 0x40000000, 0x40000000, 0x3b20187d,\n\t0x3ec50c7c, 0x3536238e, 0x2d412d41, 0x3b20187d,\n\t0x187d3b20, 0x187d3b20, 0x3536238e, 0xf3843ec5,\n\t0x00004000, 0x2d412d41, 0xd2bf2d41, 0xe7833b20,\n\t0x238e3536, 0xc13b0c7c, 0xd2bf2d41, 0x187d3b20,\n\t0xc4e0e783, 0xc4e0187d, 0x0c7c3ec5, 0xdc72caca,\n\n\t0x40000000, 0x40000000, 0x40000000, 0x3fb10645,\n\t0x3fec0323, 0x3f4e0964, 0x3ec50c7c, 0x3fb10645,\n\t0x3d3e1294, 0x3d3e1294, 0x3f4e0964, 0x39da1b5d,\n\t0x3b20187d, 0x3ec50c7c, 0x3536238e, 0x38711e2b,\n\t0x3e140f8c, 0x2f6b2afa, 0x3536238e, 0x3d3e1294,\n\t0x28993179, 0x31792899, 0x3c42158f, 0x20e736e5,\n\t0x2d412d41, 0x3b20187d, 0x187d3b20, 0x28993179,\n\t0x39da1b5d, 0x0f8c3e14, 0x238e3536, 0x38711e2b,\n\t0x06453fb1, 0x1e2b3871, 0x36e520e7, 0xfcdd3fec,\n\t0x187d3b20, 0x3536238e, 0xf3843ec5, 0x12943d3e,\n\t0x3367261f, 0xea713c42, 0x0c7c3ec5, 0x31792899,\n\t0xe1d53871, 0x06453fb1, 0x2f6b2afa, 0xd9e13367,\n\t0x00004000, 0x2d412d41, 0xd2bf2d41, 0xf9bb3fb1,\n\t0x2afa2f6b, 0xcc99261f, 0xf3843ec5, 0x28993179,\n\t0xc78f1e2b, 0xed6c3d3e, 0x261f3367, 0xc3be158f,\n\t0xe7833b20, 0x238e3536, 0xc13b0c7c, 0xe1d53871,\n\t0x20e736e5, 0xc0140323, 0xdc723536, 0x1e2b3871,\n\t0xc04ff9bb, 0xd7673179, 0x1b5d39da, 0xc1ecf074,\n\t0xd2bf2d41, 0x187d3b20, 0xc4e0e783, 0xce872899,\n\t0x158f3c42, 0xc91bdf19, 0xcaca238e, 0x12943d3e,\n\t0xce87d767, 0xc78f1e2b, 0x0f8c3e14, 0xd506d095,\n\t0xc4e0187d, 0x0c7c3ec5, 0xdc72caca, 0xc2c21294,\n\t0x09643f4e, 0xe4a3c626, 0xc13b0c7c, 0x06453fb1,\n\t0xed6cc2c2, 0xc04f0645, 0x03233fec, 0xf69cc0b2,\n\n\t0x40000000, 0x40000000, 0x40000000, 0x3ffb0192,\n\t0x3ffe00c9, 0x3ff4025b, 0x3fec0323, 0x3ffb0192,\n\t0x3fd304b5, 0x3fd304b5, 0x3ff4025b, 0x3f9c070d,\n\t0x3fb10645, 0x3fec0323, 0x3f4e0964, 0x3f8407d5,\n\t0x3fe103ec, 0x3eeb0bb6, 0x3f4e0964, 0x3fd304b5,\n\t0x3e710e05, 0x3f0e0af1, 0x3fc3057d, 0x3de2104f,\n\t0x3ec50c7c, 0x3fb10645, 0x3d3e1294, 0x3e710e05,\n\t0x3f9c070d, 0x3c8414d1, 0x3e140f8c, 0x3f8407d5,\n\t0x3bb61708, 0x3dae1111, 0x3f6a089c, 0x3ad21937,\n\t0x3d3e1294, 0x3f4e0964, 0x39da1b5d, 0x3cc51413,\n\t0x3f2f0a2a, 0x38cf1d79, 0x3c42158f, 0x3f0e0af1,\n\t0x37af1f8b, 0x3bb61708, 0x3eeb0bb6, 0x367c2192,\n\t0x3b20187d, 0x3ec50c7c, 0x3536238e, 0x3a8219ef,\n\t0x3e9c0d41, 0x33de257d, 0x39da1b5d, 0x3e710e05,\n\t0x3274275f, 0x392a1cc6, 0x3e440ec9, 0x30f82934,\n\t0x38711e2b, 0x3e140f8c, 0x2f6b2afa, 0x37af1f8b,\n\t0x3de2104f, 0x2dce2cb2, 0x36e520e7, 0x3dae1111,\n\t0x2c212e5a, 0x3612223d, 0x3d7711d3, 0x2a652ff1,\n\t0x3536238e, 0x3d3e1294, 0x28993179, 0x345324da,\n\t0x3d021354, 0x26c032ee, 0x3367261f, 0x3cc51413,\n\t0x24da3453, 0x3274275f, 0x3c8414d1, 0x22e635a5,\n\t0x31792899, 0x3c42158f, 0x20e736e5, 0x307629cd,\n\t0x3bfd164c, 0x1edc3811, 0x2f6b2afa, 0x3bb61708,\n\t0x1cc6392a, 0x2e5a2c21, 0x3b6c17c3, 0x1aa63a2f,\n\t0x2d412d41, 0x3b20187d, 0x187d3b20, 0x2c212e5a,\n\t0x3ad21937, 0x164c3bfd, 0x2afa2f6b, 0x3a8219ef,\n\t0x14133cc5, 0x29cd3076, 0x3a2f1aa6, 0x11d33d77,\n\t0x28993179, 0x39da1b5d, 0x0f8c3e14, 0x275f3274,\n\t0x39831c12, 0x0d413e9c, 0x261f3367, 0x392a1cc6,\n\t0x0af13f0e, 0x24da3453, 0x38cf1d79, 0x089c3f6a,\n\t0x238e3536, 0x38711e2b, 0x06453fb1, 0x223d3612,\n\t0x38111edc, 0x03ec3fe1, 0x20e736e5, 0x37af1f8b,\n\t0x01923ffb, 0x1f8b37af, 0x374b2039, 0xff373ffe,\n\t0x1e2b3871, 0x36e520e7, 0xfcdd3fec, 0x1cc6392a,\n\t0x367c2192, 0xfa833fc3, 0x1b5d39da, 0x3612223d,\n\t0xf82b3f84, 0x19ef3a82, 0x35a522e6, 0xf5d63f2f,\n\t0x187d3b20, 0x3536238e, 0xf3843ec5, 0x17083bb6,\n\t0x34c62434, 0xf1373e44, 0x158f3c42, 0x345324da,\n\t0xeeef3dae, 0x14133cc5, 0x33de257d, 0xecac3d02,\n\t0x12943d3e, 0x3367261f, 0xea713c42, 0x11113dae,\n\t0x32ee26c0, 0xe83d3b6c, 0x0f8c3e14, 0x3274275f,\n\t0xe6113a82, 0x0e053e71, 0x31f727fd, 0xe3ee3983,\n\t0x0c7c3ec5, 0x31792899, 0xe1d53871, 0x0af13f0e,\n\t0x30f82934, 0xdfc7374b, 0x09643f4e, 0x307629cd,\n\t0xddc33612, 0x07d53f84, 0x2ff12a65, 0xdbcc34c6,\n\t0x06453fb1, 0x2f6b2afa, 0xd9e13367, 0x04b53fd3,\n\t0x2ee32b8e, 0xd80331f7, 0x03233fec, 0x2e5a2c21,\n\t0xd6333076, 0x01923ffb, 0x2dce2cb2, 0xd4722ee3,\n\t0x00004000, 0x2d412d41, 0xd2bf2d41, 0xfe6e3ffb,\n\t0x2cb22dce, 0xd11d2b8e, 0xfcdd3fec, 0x2c212e5a,\n\t0xcf8a29cd, 0xfb4b3fd3, 0x2b8e2ee3, 0xce0927fd,\n\t0xf9bb3fb1, 0x2afa2f6b, 0xcc99261f, 0xf82b3f84,\n\t0x2a652ff1, 0xcb3a2434, 0xf69c3f4e, 0x29cd3076,\n\t0xc9ee223d, 0xf50f3f0e, 0x293430f8, 0xc8b52039,\n\t0xf3843ec5, 0x28993179, 0xc78f1e2b, 0xf1fb3e71,\n\t0x27fd31f7, 0xc67d1c12, 0xf0743e14, 0x275f3274,\n\t0xc57e19ef, 0xeeef3dae, 0x26c032ee, 0xc49417c3,\n\t0xed6c3d3e, 0x261f3367, 0xc3be158f, 0xebed3cc5,\n\t0x257d33de, 0xc2fe1354, 0xea713c42, 0x24da3453,\n\t0xc2521111, 0xe8f83bb6, 0x243434c6, 0xc1bc0ec9,\n\t0xe7833b20, 0x238e3536, 0xc13b0c7c, 0xe6113a82,\n\t0x22e635a5, 0xc0d10a2a, 0xe4a339da, 0x223d3612,\n\t0xc07c07d5, 0xe33a392a, 0x2192367c, 0xc03d057d,\n\t0xe1d53871, 0x20e736e5, 0xc0140323, 0xe07537af,\n\t0x2039374b, 0xc00200c9, 0xdf1936e5, 0x1f8b37af,\n\t0xc005fe6e, 0xddc33612, 0x1edc3811, 0xc01ffc14,\n\t0xdc723536, 0x1e2b3871, 0xc04ff9bb, 0xdb263453,\n\t0x1d7938cf, 0xc096f764, 0xd9e13367, 0x1cc6392a,\n\t0xc0f2f50f, 0xd8a13274, 0x1c123983, 0xc164f2bf,\n\t0xd7673179, 0x1b5d39da, 0xc1ecf074, 0xd6333076,\n\t0x1aa63a2f, 0xc289ee2d, 0xd5062f6b, 0x19ef3a82,\n\t0xc33bebed, 0xd3df2e5a, 0x19373ad2, 0xc403e9b4,\n\t0xd2bf2d41, 0x187d3b20, 0xc4e0e783, 0xd1a62c21,\n\t0x17c33b6c, 0xc5d1e55a, 0xd0952afa, 0x17083bb6,\n\t0xc6d6e33a, 0xcf8a29cd, 0x164c3bfd, 0xc7efe124,\n\t0xce872899, 0x158f3c42, 0xc91bdf19, 0xcd8c275f,\n\t0x14d13c84, 0xca5bdd1a, 0xcc99261f, 0x14133cc5,\n\t0xcbaddb26, 0xcbad24da, 0x13543d02, 0xcd12d940,\n\t0xcaca238e, 0x12943d3e, 0xce87d767, 0xc9ee223d,\n\t0x11d33d77, 0xd00fd59b, 0xc91b20e7, 0x11113dae,\n\t0xd1a6d3df, 0xc8511f8b, 0x104f3de2, 0xd34ed232,\n\t0xc78f1e2b, 0x0f8c3e14, 0xd506d095, 0xc6d61cc6,\n\t0x0ec93e44, 0xd6cccf08, 0xc6261b5d, 0x0e053e71,\n\t0xd8a1cd8c, 0xc57e19ef, 0x0d413e9c, 0xda83cc22,\n\t0xc4e0187d, 0x0c7c3ec5, 0xdc72caca, 0xc44a1708,\n\t0x0bb63eeb, 0xde6ec984, 0xc3be158f, 0x0af13f0e,\n\t0xe075c851, 0xc33b1413, 0x0a2a3f2f, 0xe287c731,\n\t0xc2c21294, 0x09643f4e, 0xe4a3c626, 0xc2521111,\n\t0x089c3f6a, 0xe6c9c52e, 0xc1ec0f8c, 0x07d53f84,\n\t0xe8f8c44a, 0xc18f0e05, 0x070d3f9c, 0xeb2fc37c,\n\t0xc13b0c7c, 0x06453fb1, 0xed6cc2c2, 0xc0f20af1,\n\t0x057d3fc3, 0xefb1c21e, 0xc0b20964, 0x04b53fd3,\n\t0xf1fbc18f, 0xc07c07d5, 0x03ec3fe1, 0xf44ac115,\n\t0xc04f0645, 0x03233fec, 0xf69cc0b2, 0xc02d04b5,\n\t0x025b3ff4, 0xf8f3c064, 0xc0140323, 0x01923ffb,\n\t0xfb4bc02d, 0xc0050192, 0x00c93ffe, 0xfda5c00c\n};\n\nconst int twidTab64[(4*6 + 16*6)/2] = {\n\t0x40000000, 0x40000000, 0x40000000, 0x2d412d41,\n\t0x3b20187d, 0x187d3b20, 0x00004000, 0x2d412d41,\n\t0xd2bf2d41, 0xd2bf2d41, 0x187d3b20, 0xc4e0e783,\n\n\t0x40000000, 0x40000000, 0x40000000, 0x3ec50c7c,\n\t0x3fb10645, 0x3d3e1294, 0x3b20187d, 0x3ec50c7c,\n\t0x3536238e, 0x3536238e, 0x3d3e1294, 0x28993179,\n\t0x2d412d41, 0x3b20187d, 0x187d3b20, 0x238e3536,\n\t0x38711e2b, 0x06453fb1, 0x187d3b20, 0x3536238e,\n\t0xf3843ec5, 0x0c7c3ec5, 0x31792899, 0xe1d53871,\n\t0x00004000, 0x2d412d41, 0xd2bf2d41, 0xf3843ec5,\n\t0x28993179, 0xc78f1e2b, 0xe7833b20, 0x238e3536,\n\t0xc13b0c7c, 0xdc723536, 0x1e2b3871, 0xc04ff9bb,\n\t0xd2bf2d41, 0x187d3b20, 0xc4e0e783, 0xcaca238e,\n\t0x12943d3e, 0xce87d767, 0xc4e0187d, 0x0c7c3ec5,\n\t0xdc72caca, 0xc13b0c7c, 0x06453fb1, 0xed6cc2c2\n};\n\n#elif defined ARMV7Neon\n/*\n *  Q29 for 128 and 1024\n *\n * for (i = 0; i < num/4; i++) {\n *   angle = (i + 0.125) * M_PI / num;\n *   x = cos(angle) * (1 << 29);\n *   x = sin(angle) * (1 << 29);\n *\n *   angle = (num/2 - 1 - i + 0.125) * M_PI / num;\n *   x = cos(angle) * (1 << 29);\n *   x = sin(angle) * (1 << 29);\n * }\n */\nconst int cossintab[128 + 1024] = {\n\t/* 128 */\n\t0x1ffff621, 0x001921f9, 0x00afea69, 0x1ffe1c68, 0x1ffce09d, 0x00e22a7a, 0x0178dbaa, 0x1ff753bb,\n\t0x1ff4dc55, 0x01ab101c, 0x024192cf, 0x1feb9d25, 0x1fe7ea85, 0x0273b3e2, 0x0309f0e2, 0x1fdafa75,\n\t0x1fd60d2e, 0x033bf6dd, 0x03d1d700, 0x1fc56e3b, 0x1fbf470f, 0x0403ba2b, 0x04992653, 0x1faafbcb,\n\t0x1fa39bac, 0x04cadefe, 0x055fc022, 0x1f8ba738, 0x1f830f4a, 0x059146a1, 0x062585ca, 0x1f677557,\n\t0x1f5da6ed, 0x0656d27a, 0x06ea58cd, 0x1f3e6bbc, 0x1f33685a, 0x071b6415, 0x07ae1ad2, 0x1f1090bd,\n\t0x1f045a15, 0x07dedd20, 0x0870ada7, 0x1eddeb6a, 0x1ed0835f, 0x08a11f78, 0x0931f34d, 0x1ea68394,\n\t0x1e97ec36, 0x09620d27, 0x09f1cdf5, 0x1e6a61c5, 0x1e5a9d55, 0x0a21886e, 0x0ab02009, 0x1e298f44,\n\t0x1e18a030, 0x0adf73c6, 0x0b6ccc32, 0x1de4160f, 0x1dd1fef4, 0x0b9bb1e5, 0x0c27b555, 0x1d9a00de,\n\t0x1d86c484, 0x0c5625c3, 0x0ce0bea2, 0x1d4b5b1b, 0x1d36fc7c, 0x0d0eb2a2, 0x0d97cb8f, 0x1cf830e9,\n\t0x1ce2b328, 0x0dc53c0a, 0x0e4cbfe2, 0x1ca08f1a, 0x1c89f587, 0x0e79a5d7, 0x0eff7fb3, 0x1c448331,\n\t0x1c2cd149, 0x0f2bd437, 0x0fafef73, 0x1be41b61, 0x1bcb54cb, 0x0fdbabae, 0x105df3ec, 0x1b7f6687,\n\t0x1b658f15, 0x10891120, 0x11097249, 0x1b16742a, 0x1afb8fd9, 0x1133e9d0, 0x11b25017, 0x1aa9547a,\n\t0x1a8d676e, 0x11dc1b65, 0x1258734d, 0x1a38184a, 0x1a1b26d3, 0x12818bef, 0x12fbc24b, 0x19c2d111,\n\t0x19a4dfa4, 0x132421ec, 0x139c23e4, 0x194990e4, 0x192aa420, 0x13c3c44a, 0x14397f5b, 0x18cc6a75,\n\t0x18ac871f, 0x14605a69, 0x14d3bc6d, 0x184b7112, 0x182a9c14, 0x14f9cc26, 0x156ac352, 0x17c6b89d,\n\t0x17a4f708, 0x159001d6, 0x15fe7cbe, 0x173e558e, 0x171bac96, 0x1622e450, 0x168ed1eb, 0x16b25ced,\n\t/* 1024 */\n\t0x1fffffd9, 0x0003243f, 0x0015fdba, 0x1ffff872, 0x1ffff382, 0x001c4637, 0x002f1fa6, 0x1fffdd4d,\n\t0x1fffd36f, 0x0035681d, 0x00484175, 0x1fffae6c, 0x1fff9f9e, 0x004e89e3, 0x00616318, 0x1fff6bce,\n\t0x1fff5811, 0x0067ab77, 0x007a847e, 0x1fff1572, 0x1ffefcc6, 0x0080cccc, 0x0093a599, 0x1ffeab5b,\n\t0x1ffe8dbf, 0x0099edd2, 0x00acc658, 0x1ffe2d86, 0x1ffe0afc, 0x00b30e78, 0x00c5e6ad, 0x1ffd9bf6,\n\t0x1ffd747c, 0x00cc2eb0, 0x00df0688, 0x1ffcf6aa, 0x1ffcca41, 0x00e54e6a, 0x00f825da, 0x1ffc3da2,\n\t0x1ffc0c4b, 0x00fe6d97, 0x01114492, 0x1ffb70e0, 0x1ffb3a9a, 0x01178c27, 0x012a62a2, 0x1ffa9063,\n\t0x1ffa552e, 0x0130aa0a, 0x01437ffa, 0x1ff99c2c, 0x1ff95c09, 0x0149c731, 0x015c9c8a, 0x1ff8943c,\n\t0x1ff84f2b, 0x0162e38d, 0x0175b843, 0x1ff77893, 0x1ff72e94, 0x017bff0e, 0x018ed316, 0x1ff64932,\n\t0x1ff5fa46, 0x019519a5, 0x01a7ecf2, 0x1ff5061b, 0x1ff4b240, 0x01ae3341, 0x01c105c9, 0x1ff3af4c,\n\t0x1ff35684, 0x01c74bd5, 0x01da1d8c, 0x1ff244c8, 0x1ff1e713, 0x01e0634f, 0x01f33429, 0x1ff0c68f,\n\t0x1ff063ed, 0x01f979a1, 0x020c4993, 0x1fef34a3, 0x1feecd14, 0x02128ebb, 0x02255db9, 0x1fed8f03,\n\t0x1fed2287, 0x022ba28f, 0x023e708d, 0x1febd5b2, 0x1feb644a, 0x0244b50b, 0x025781fe, 0x1fea08b0,\n\t0x1fe9925c, 0x025dc621, 0x027091fd, 0x1fe827fe, 0x1fe7acbe, 0x0276d5c1, 0x0289a07b, 0x1fe6339d,\n\t0x1fe5b372, 0x028fe3dd, 0x02a2ad69, 0x1fe42b90, 0x1fe3a679, 0x02a8f063, 0x02bbb8b6, 0x1fe20fd6,\n\t0x1fe185d5, 0x02c1fb46, 0x02d4c253, 0x1fdfe071, 0x1fdf5186, 0x02db0475, 0x02edca32, 0x1fdd9d64,\n\t0x1fdd098e, 0x02f40be2, 0x0306d042, 0x1fdb46ae, 0x1fdaadee, 0x030d117c, 0x031fd474, 0x1fd8dc51,\n\t0x1fd83ea8, 0x03261534, 0x0338d6b8, 0x1fd65e4f, 0x1fd5bbbd, 0x033f16fb, 0x0351d700, 0x1fd3ccaa,\n\t0x1fd32530, 0x035816c1, 0x036ad53c, 0x1fd12763, 0x1fd07b00, 0x03711477, 0x0383d15c, 0x1fce6e7c,\n\t0x1fcdbd31, 0x038a100e, 0x039ccb51, 0x1fcba1f5, 0x1fcaebc3, 0x03a30975, 0x03b5c30b, 0x1fc8c1d2,\n\t0x1fc806b9, 0x03bc009f, 0x03ceb87c, 0x1fc5ce14, 0x1fc50e14, 0x03d4f57a, 0x03e7ab93, 0x1fc2c6bd,\n\t0x1fc201d7, 0x03ede7f9, 0x04009c42, 0x1fbfabcd, 0x1fbee202, 0x0406d80b, 0x04198a78, 0x1fbc7d49,\n\t0x1fbbae99, 0x041fc5a1, 0x04327628, 0x1fb93b31, 0x1fb8679c, 0x0438b0ac, 0x044b5f40, 0x1fb5e587,\n\t0x1fb50d0e, 0x0451991d, 0x046445b2, 0x1fb27c4e, 0x1fb19ef1, 0x046a7ee3, 0x047d296f, 0x1faeff87,\n\t0x1fae1d47, 0x048361f0, 0x04960a67, 0x1fab6f35, 0x1faa8813, 0x049c4235, 0x04aee88b, 0x1fa7cb5a,\n\t0x1fa6df56, 0x04b51fa1, 0x04c7c3cb, 0x1fa413f8, 0x1fa32313, 0x04cdfa26, 0x04e09c18, 0x1fa04912,\n\t0x1f9f534c, 0x04e6d1b4, 0x04f97163, 0x1f9c6aa9, 0x1f9b7003, 0x04ffa63c, 0x0512439d, 0x1f9878c1,\n\t0x1f97793b, 0x051877af, 0x052b12b6, 0x1f94735b, 0x1f936ef6, 0x053145fd, 0x0543de9e, 0x1f905a7a,\n\t0x1f8f5137, 0x054a1117, 0x055ca748, 0x1f8c2e21, 0x1f8b2000, 0x0562d8ee, 0x05756ca2, 0x1f87ee52,\n\t0x1f86db55, 0x057b9d73, 0x058e2e9f, 0x1f839b10, 0x1f828336, 0x05945e95, 0x05a6ed2e, 0x1f7f345e,\n\t0x1f7e17a8, 0x05ad1c47, 0x05bfa840, 0x1f7aba3e, 0x1f7998ad, 0x05c5d678, 0x05d85fc7, 0x1f762cb2,\n\t0x1f750647, 0x05de8d19, 0x05f113b3, 0x1f718bbf, 0x1f70607a, 0x05f7401c, 0x0609c3f5, 0x1f6cd766,\n\t0x1f6ba748, 0x060fef71, 0x0622707d, 0x1f680fab, 0x1f66dab5, 0x06289b08, 0x063b193c, 0x1f633490,\n\t0x1f61fac3, 0x064142d3, 0x0653be23, 0x1f5e4619, 0x1f5d0775, 0x0659e6c2, 0x066c5f24, 0x1f594448,\n\t0x1f5800ce, 0x067286c6, 0x0684fc2e, 0x1f542f21, 0x1f52e6d2, 0x068b22d0, 0x069d9532, 0x1f4f06a6,\n\t0x1f4db983, 0x06a3bad0, 0x06b62a22, 0x1f49cadc, 0x1f4878e5, 0x06bc4eb9, 0x06cebaee, 0x1f447bc4,\n\t0x1f4324fb, 0x06d4de79, 0x06e74786, 0x1f3f1963, 0x1f3dbdc8, 0x06ed6a03, 0x06ffcfdd, 0x1f39a3bc,\n\t0x1f384350, 0x0705f147, 0x071853e3, 0x1f341ad2, 0x1f32b595, 0x071e7436, 0x0730d388, 0x1f2e7ea9,\n\t0x1f2d149d, 0x0736f2c0, 0x07494ebd, 0x1f28cf43, 0x1f276069, 0x074f6cd7, 0x0761c574, 0x1f230ca5,\n\t0x1f2198fd, 0x0767e26c, 0x077a379d, 0x1f1d36d2, 0x1f1bbe5d, 0x07805370, 0x0792a52a, 0x1f174dce,\n\t0x1f15d08d, 0x0798bfd3, 0x07ab0e0a, 0x1f11519c, 0x1f0fcf91, 0x07b12786, 0x07c37230, 0x1f0b4240,\n\t0x1f09bb6b, 0x07c98a7a, 0x07dbd18c, 0x1f051fbe, 0x1f03941f, 0x07e1e8a1, 0x07f42c0e, 0x1efeea19,\n\t0x1efd59b3, 0x07fa41eb, 0x080c81a9, 0x1ef8a155, 0x1ef70c28, 0x0812964a, 0x0824d24d, 0x1ef24577,\n\t0x1ef0ab84, 0x082ae5ad, 0x083d1dea, 0x1eebd682, 0x1eea37ca, 0x08433007, 0x08556473, 0x1ee5547a,\n\t0x1ee3b0fe, 0x085b7548, 0x086da5d8, 0x1edebf64, 0x1edd1724, 0x0873b562, 0x0885e209, 0x1ed81742,\n\t0x1ed66a41, 0x088bf044, 0x089e18f9, 0x1ed15c1a, 0x1ecfaa57, 0x08a425e1, 0x08b64a98, 0x1eca8def,\n\t0x1ec8d76c, 0x08bc562a, 0x08ce76d8, 0x1ec3acc6, 0x1ec1f184, 0x08d4810f, 0x08e69da8, 0x1ebcb8a3,\n\t0x1ebaf8a3, 0x08eca681, 0x08febefb, 0x1eb5b18a, 0x1eb3eccd, 0x0904c673, 0x0916dac2, 0x1eae977f,\n\t0x1eacce07, 0x091ce0d4, 0x092ef0ed, 0x1ea76a87, 0x1ea59c55, 0x0934f596, 0x0947016e, 0x1ea02aa7,\n\t0x1e9e57bb, 0x094d04aa, 0x095f0c36, 0x1e98d7e2, 0x1e97003e, 0x09650e01, 0x09771136, 0x1e91723e,\n\t0x1e8f95e3, 0x097d118d, 0x098f1060, 0x1e89f9bf, 0x1e8818ad, 0x09950f3f, 0x09a709a4, 0x1e826e69,\n\t0x1e8088a2, 0x09ad0707, 0x09befcf4, 0x1e7ad041, 0x1e78e5c7, 0x09c4f8d8, 0x09d6ea40, 0x1e731f4c,\n\t0x1e71301f, 0x09dce4a1, 0x09eed17b, 0x1e6b5b8f, 0x1e6967b1, 0x09f4ca56, 0x0a06b296, 0x1e63850e,\n\t0x1e618c80, 0x0a0ca9e6, 0x0a1e8d81, 0x1e5b9bce, 0x1e599e91, 0x0a248343, 0x0a36622e, 0x1e539fd4,\n\t0x1e519dea, 0x0a3c565e, 0x0a4e308f, 0x1e4b9126, 0x1e498a8e, 0x0a542329, 0x0a65f894, 0x1e436fc7,\n\t0x1e416485, 0x0a6be995, 0x0a7dba2f, 0x1e3b3bbd, 0x1e392bd1, 0x0a83a993, 0x0a957551, 0x1e32f50e,\n\t0x1e30e079, 0x0a9b6315, 0x0aad29ec, 0x1e2a9bbd, 0x1e288281, 0x0ab3160c, 0x0ac4d7f1, 0x1e222fd1,\n\t0x1e2011ee, 0x0acac26a, 0x0adc7f52, 0x1e19b14f, 0x1e178ec7, 0x0ae2681f, 0x0af41fff, 0x1e11203b,\n\t0x1e0ef910, 0x0afa071d, 0x0b0bb9eb, 0x1e087c9b, 0x1e0650ce, 0x0b119f56, 0x0b234d07, 0x1dffc674,\n\t0x1dfd9606, 0x0b2930bb, 0x0b3ad943, 0x1df6fdcc, 0x1df4c8bf, 0x0b40bb3e, 0x0b525e92, 0x1dee22a9,\n\t0x1debe8fd, 0x0b583ecf, 0x0b69dce6, 0x1de5350f, 0x1de2f6c6, 0x0b6fbb62, 0x0b81542f, 0x1ddc3504,\n\t0x1dd9f220, 0x0b8730e6, 0x0b98c45f, 0x1dd3228e, 0x1dd0db10, 0x0b9e9f4d, 0x0bb02d68, 0x1dc9fdb2,\n\t0x1dc7b19b, 0x0bb6068a, 0x0bc78f3b, 0x1dc0c676, 0x1dbe75c8, 0x0bcd668e, 0x0bdee9ca, 0x1db77cdf,\n\t0x1db5279c, 0x0be4bf4a, 0x0bf63d07, 0x1dae20f4, 0x1dabc71d, 0x0bfc10af, 0x0c0d88e2, 0x1da4b2ba,\n\t0x1da25450, 0x0c135ab0, 0x0c24cd4e, 0x1d9b3237, 0x1d98cf3b, 0x0c2a9d3e, 0x0c3c0a3d, 0x1d919f70,\n\t0x1d8f37e5, 0x0c41d84b, 0x0c533fa0, 0x1d87fa6d, 0x1d858e53, 0x0c590bc9, 0x0c6a6d68, 0x1d7e4332,\n\t0x1d7bd28b, 0x0c7037a8, 0x0c819388, 0x1d7479c5, 0x1d720493, 0x0c875bdb, 0x0c98b1f0, 0x1d6a9e2e,\n\t0x1d682472, 0x0c9e7854, 0x0cafc894, 0x1d60b070, 0x1d5e322c, 0x0cb58d04, 0x0cc6d764, 0x1d56b094,\n\t0x1d542dc9, 0x0ccc99de, 0x0cddde53, 0x1d4c9e9f, 0x1d4a174f, 0x0ce39ed2, 0x0cf4dd52, 0x1d427a97,\n\t0x1d3feec3, 0x0cfa9bd2, 0x0d0bd452, 0x1d384483, 0x1d35b42d, 0x0d1190d1, 0x0d22c347, 0x1d2dfc68,\n\t0x1d2b6791, 0x0d287dc1, 0x0d39aa21, 0x1d23a24e, 0x1d2108f8, 0x0d3f6292, 0x0d5088d3, 0x1d19363a,\n\t0x1d169867, 0x0d563f38, 0x0d675f4e, 0x1d0eb833, 0x1d0c15e4, 0x0d6d13a3, 0x0d7e2d85, 0x1d04283f,\n\t0x1d018176, 0x0d83dfc6, 0x0d94f369, 0x1cf98666, 0x1cf6db24, 0x0d9aa393, 0x0dabb0ec, 0x1ceed2ad,\n\t0x1cec22f4, 0x0db15efc, 0x0dc26600, 0x1ce40d1b, 0x1ce158ed, 0x0dc811f3, 0x0dd91298, 0x1cd935b7,\n\t0x1cd67d15, 0x0ddebc69, 0x0defb6a5, 0x1cce4c87, 0x1ccb8f74, 0x0df55e51, 0x0e065219, 0x1cc35192,\n\t0x1cc0900f, 0x0e0bf79c, 0x0e1ce4e6, 0x1cb844df, 0x1cb57eee, 0x0e22883e, 0x0e336eff, 0x1cad2675,\n\t0x1caa5c17, 0x0e391027, 0x0e49f055, 0x1ca1f65b, 0x1c9f2792, 0x0e4f8f4b, 0x0e6068db, 0x1c96b497,\n\t0x1c93e165, 0x0e66059a, 0x0e76d883, 0x1c8b6131, 0x1c888997, 0x0e7c7308, 0x0e8d3f3e, 0x1c7ffc2f,\n\t0x1c7d202f, 0x0e92d787, 0x0ea39d00, 0x1c748599, 0x1c71a535, 0x0ea93308, 0x0eb9f1ba, 0x1c68fd75,\n\t0x1c6618ae, 0x0ebf857d, 0x0ed03d5e, 0x1c5d63ca, 0x1c5a7aa4, 0x0ed5ceda, 0x0ee67fdf, 0x1c51b8a1,\n\t0x1c4ecb1c, 0x0eec0f10, 0x0efcb92f, 0x1c45fc00, 0x1c430a1d, 0x0f024612, 0x0f12e941, 0x1c3a2ded,\n\t0x1c3737b0, 0x0f1873d2, 0x0f291006, 0x1c2e4e72, 0x1c2b53db, 0x0f2e9842, 0x0f3f2d71, 0x1c225d94,\n\t0x1c1f5ea6, 0x0f44b354, 0x0f554175, 0x1c165b5b, 0x1c135818, 0x0f5ac4fc, 0x0f6b4c03, 0x1c0a47cf,\n\t0x1c074038, 0x0f70cd2a, 0x0f814d0e, 0x1bfe22f8, 0x1bfb170f, 0x0f86cbd3, 0x0f974489, 0x1bf1ecdb,\n\t0x1beedca2, 0x0f9cc0e7, 0x0fad3265, 0x1be5a582, 0x1be290fb, 0x0fb2ac5a, 0x0fc31697, 0x1bd94cf4,\n\t0x1bd63421, 0x0fc88e1e, 0x0fd8f10f, 0x1bcce337, 0x1bc9c61a, 0x0fde6626, 0x0feec1c0, 0x1bc06855,\n\t0x1bbd46f0, 0x0ff43464, 0x1004889e, 0x1bb3dc55, 0x1bb0b6a9, 0x1009f8cb, 0x101a459a, 0x1ba73f3d,\n\t0x1ba4154d, 0x101fb34d, 0x102ff8a8, 0x1b9a9117, 0x1b9762e4, 0x103563dc, 0x1045a1b9, 0x1b8dd1ea,\n\t0x1b8a9f77, 0x104b0a6c, 0x105b40c1, 0x1b8101be, 0x1b7dcb0c, 0x1060a6ef, 0x1070d5b1, 0x1b74209b,\n\t0x1b70e5ac, 0x10763958, 0x1086607e, 0x1b672e88, 0x1b63ef5f, 0x108bc19a, 0x109be119, 0x1b5a2b8e,\n\t0x1b56e82c, 0x10a13fa6, 0x10b15775, 0x1b4d17b4, 0x1b49d01c, 0x10b6b371, 0x10c6c385, 0x1b3ff304,\n\t0x1b3ca737, 0x10cc1cec, 0x10dc253c, 0x1b32bd84, 0x1b2f6d85, 0x10e17c0b, 0x10f17c8d, 0x1b25773d,\n\t0x1b22230e, 0x10f6d0c0, 0x1106c96a, 0x1b182038, 0x1b14c7da, 0x110c1afe, 0x111c0bc6, 0x1b0ab87c,\n\t0x1b075bf1, 0x11215ab8, 0x11314395, 0x1afd4012, 0x1af9df5d, 0x11368fe1, 0x114670c8, 0x1aefb702,\n\t0x1aec5225, 0x114bba6b, 0x115b9354, 0x1ae21d54, 0x1adeb451, 0x1160da4b, 0x1170ab2a, 0x1ad47311,\n\t0x1ad105e9, 0x1175ef72, 0x1185b83f, 0x1ac6b841, 0x1ac346f8, 0x118af9d4, 0x119aba84, 0x1ab8ecec,\n\t0x1ab57784, 0x119ff964, 0x11afb1ee, 0x1aab111c, 0x1aa79796, 0x11b4ee14, 0x11c49e6f, 0x1a9d24d9,\n\t0x1a99a737, 0x11c9d7d9, 0x11d97ff9, 0x1a8f282b, 0x1a8ba670, 0x11deb6a4, 0x11ee5682, 0x1a811b1b,\n\t0x1a7d9549, 0x11f38a6a, 0x120321fa, 0x1a72fdb2, 0x1a6f73ca, 0x1208531c, 0x1217e256, 0x1a64cff8,\n\t0x1a6141fd, 0x121d10af, 0x122c9789, 0x1a5691f5, 0x1a52ffeb, 0x1231c316, 0x12414186, 0x1a4843b4,\n\t0x1a44ad9b, 0x12466a44, 0x1255e041, 0x1a39e53d, 0x1a364b17, 0x125b062b, 0x126a73ac, 0x1a2b7698,\n\t0x1a27d868, 0x126f96c1, 0x127efbbb, 0x1a1cf7ce, 0x1a195597, 0x12841bf6, 0x12937861, 0x1a0e68e9,\n\t0x1a0ac2ac, 0x129895c0, 0x12a7e991, 0x19ffc9f1, 0x19fc1fb1, 0x12ad0412, 0x12bc4f40, 0x19f11af0,\n\t0x19ed6caf, 0x12c166de, 0x12d0a960, 0x19e25bee, 0x19dea9ae, 0x12d5be18, 0x12e4f7e5, 0x19d38cf4,\n\t0x19cfd6b8, 0x12ea09b4, 0x12f93ac2, 0x19c4ae0c, 0x19c0f3d6, 0x12fe49a6, 0x130d71eb, 0x19b5bf3f,\n\t0x19b20111, 0x13127de0, 0x13219d53, 0x19a6c096, 0x19a2fe73, 0x1326a656, 0x1335bcef, 0x1997b21b,\n\t0x1993ec04, 0x133ac2fc, 0x1349d0b0, 0x198893d6, 0x1984c9ce, 0x134ed3c5, 0x135dd88c, 0x197965d0,\n\t0x197597da, 0x1362d8a6, 0x1371d476, 0x196a2815, 0x19665632, 0x1376d191, 0x1385c461, 0x195adaab,\n\t0x195704df, 0x138abe7b, 0x1399a841, 0x194b7d9e, 0x1947a3eb, 0x139e9f56, 0x13ad800a, 0x193c10f7,\n\t0x1938335e, 0x13b27417, 0x13c14bb0, 0x192c94bf, 0x1928b343, 0x13c63cb2, 0x13d50b26, 0x191d08ff,\n\t0x191923a3, 0x13d9f91b, 0x13e8be60, 0x190d6dc1, 0x19098488, 0x13eda944, 0x13fc6553, 0x18fdc310,\n\t0x18f9d5fa, 0x14014d23, 0x140ffff1, 0x18ee08f4, 0x18ea1805, 0x1414e4aa, 0x14238e2f, 0x18de3f77,\n\t0x18da4ab2, 0x14286fce, 0x14371001, 0x18ce66a3, 0x18ca6e0a, 0x143bee83, 0x144a855b, 0x18be7e82,\n\t0x18ba8217, 0x144f60bd, 0x145dee30, 0x18ae871e, 0x18aa86e3, 0x1462c670, 0x14714a76, 0x189e8080,\n\t0x189a7c78, 0x14761f8f, 0x14849a1f, 0x188e6ab2, 0x188a62e0, 0x14896c0f, 0x1497dd20, 0x187e45be,\n\t0x187a3a25, 0x149cabe4, 0x14ab136d, 0x186e11af, 0x186a0250, 0x14afdf03, 0x14be3cfa, 0x185dce8e,\n\t0x1859bb6c, 0x14c3055e, 0x14d159bc, 0x184d7c65, 0x18496583, 0x14d61eeb, 0x14e469a6, 0x183d1b3e,\n\t0x1839009e, 0x14e92b9e, 0x14f76cad, 0x182cab24, 0x18288cc8, 0x14fc2b6a, 0x150a62c6, 0x181c2c20,\n\t0x18180a0c, 0x150f1e45, 0x151d4be3, 0x180b9e3d, 0x18077873, 0x15220422, 0x153027fb, 0x17fb0185,\n\t0x17f6d807, 0x1534dcf6, 0x1542f700, 0x17ea5602, 0x17e628d3, 0x1547a8b5, 0x1555b8e8, 0x17d99bbe,\n\t0x17d56ae0, 0x155a6754, 0x15686da7, 0x17c8d2c4, 0x17c49e3b, 0x156d18c7, 0x157b1532, 0x17b7fb1f,\n\t0x17b3c2ec, 0x157fbd03, 0x158daf7c, 0x17a714d7, 0x17a2d8fe, 0x159253fb, 0x15a03c7a, 0x17961ff9,\n\t0x1791e07b, 0x15a4dda5, 0x15b2bc22, 0x17851c8e, 0x1780d96f, 0x15b759f5, 0x15c52e67, 0x17740aa1,\n\t0x176fc3e3, 0x15c9c8e0, 0x15d7933f, 0x1762ea3d, 0x175e9fe2, 0x15dc2a5a, 0x15e9ea9d, 0x1751bb6b,\n\t0x174d6d77, 0x15ee7e58, 0x15fc3477, 0x17407e37, 0x173c2cac, 0x1600c4cf, 0x160e70c1, 0x172f32ab,\n\t0x172add8c, 0x1612fdb3, 0x16209f70, 0x171dd8d2, 0x17198021, 0x162528fa, 0x1632c078, 0x170c70b7,\n\t0x17081477, 0x16374697, 0x1644d3d0, 0x16fafa64, 0x16f69a97, 0x16495680, 0x1656d96a, 0x16e975e4,\n\t0x16e5128e, 0x165b58aa, 0x1668d13e, 0x16d7e341, 0x16d37c65, 0x166d4d0a, 0x167abb3e, 0x16c64288,\n\t0x16c1d827, 0x167f3394, 0x168c9760, 0x16b493c2, 0x16b025e0, 0x16910c3d, 0x169e659a, 0x16a2d6fb\n};\n\nconst int twidTab512[8*6 + 32*6 + 128*6] = {\n\t0x20000000, 0x00000000, 0x1d906bcf, 0x0c3ef153, 0x16a09e66, 0x16a09e66, 0x0c3ef153, 0x1d906bcf,\n\t0x20000000, 0x00000000, 0x1f6297d0, 0x063e2e0f, 0x1d906bcf, 0x0c3ef153, 0x1a9b6629, 0x11c73b3a,\n\t0x20000000, 0x00000000, 0x1a9b6629, 0x11c73b3a, 0x0c3ef153, 0x1d906bcf, 0xf9c1d1f1, 0x1f6297d0,\n\t0x00000000, 0x20000000, 0xf3c10ead, 0x1d906bcf, 0xe95f619a, 0x16a09e66, 0xe26f9431, 0x0c3ef153,\n\t0x16a09e66, 0x16a09e66, 0x11c73b3a, 0x1a9b6629, 0x0c3ef153, 0x1d906bcf, 0x063e2e0f, 0x1f6297d0,\n\t0xe95f619a, 0x16a09e66, 0xe09d6830, 0x063e2e0f, 0xe26f9431, 0xf3c10ead, 0xee38c4c6, 0xe56499d7,\n\n\t0x20000000, 0x00000000, 0x1fd88da4, 0x0322f4d8, 0x1f6297d0, 0x063e2e0f, 0x1e9f4157, 0x094a0317,\n\t0x20000000, 0x00000000, 0x1ff621e3, 0x0191f65f, 0x1fd88da4, 0x0322f4d8, 0x1fa7557f, 0x04b2041c,\n\t0x20000000, 0x00000000, 0x1fa7557f, 0x04b2041c, 0x1e9f4157, 0x094a0317, 0x1ced7af4, 0x0dae8805,\n\t0x1d906bcf, 0x0c3ef153, 0x1c38b2f2, 0x0f15ae9c, 0x1a9b6629, 0x11c73b3a, 0x18bc806b, 0x144cf325,\n\t0x1f6297d0, 0x063e2e0f, 0x1f0a7efc, 0x07c67e5f, 0x1e9f4157, 0x094a0317, 0x1e212105, 0x0ac7cd3b,\n\t0x1a9b6629, 0x11c73b3a, 0x17b5df22, 0x157d6935, 0x144cf325, 0x18bc806b, 0x10738799, 0x1b728345,\n\t0x16a09e66, 0x16a09e66, 0x144cf325, 0x18bc806b, 0x11c73b3a, 0x1a9b6629, 0x0f15ae9c, 0x1c38b2f2,\n\t0x1d906bcf, 0x0c3ef153, 0x1ced7af4, 0x0dae8805, 0x1c38b2f2, 0x0f15ae9c, 0x1b728345, 0x10738799,\n\t0x0c3ef153, 0x1d906bcf, 0x07c67e5f, 0x1f0a7efc, 0x0322f4d8, 0x1fd88da4, 0xfe6e09a1, 0x1ff621e3,\n\t0x0c3ef153, 0x1d906bcf, 0x094a0317, 0x1e9f4157, 0x063e2e0f, 0x1f6297d0, 0x0322f4d8, 0x1fd88da4,\n\t0x1a9b6629, 0x11c73b3a, 0x19b3e048, 0x130ff7fd, 0x18bc806b, 0x144cf325, 0x17b5df22, 0x157d6935,\n\t0xf9c1d1f1, 0x1f6297d0, 0xf53832c5, 0x1e212105, 0xf0ea5164, 0x1c38b2f2, 0xecf00803, 0x19b3e048,\n\t0x00000000, 0x20000000, 0xfcdd0b28, 0x1fd88da4, 0xf9c1d1f1, 0x1f6297d0, 0xf6b5fce9, 0x1e9f4157,\n\t0x16a09e66, 0x16a09e66, 0x157d6935, 0x17b5df22, 0x144cf325, 0x18bc806b, 0x130ff7fd, 0x19b3e048,\n\t0xe95f619a, 0x16a09e66, 0xe64c1fb8, 0x130ff7fd, 0xe3c74d0e, 0x0f15ae9c, 0xe1dedefb, 0x0ac7cd3b,\n\t0xf3c10ead, 0x1d906bcf, 0xf0ea5164, 0x1c38b2f2, 0xee38c4c6, 0x1a9b6629, 0xebb30cdb, 0x18bc806b,\n\t0x11c73b3a, 0x1a9b6629, 0x10738799, 0x1b728345, 0x0f15ae9c, 0x1c38b2f2, 0x0dae8805, 0x1ced7af4,\n\t0xe09d6830, 0x063e2e0f, 0xe009de1d, 0x0191f65f, 0xe027725c, 0xfcdd0b28, 0xe0f58104, 0xf83981a1,\n\t0xe95f619a, 0x16a09e66, 0xe7437f95, 0x144cf325, 0xe56499d7, 0x11c73b3a, 0xe3c74d0e, 0x0f15ae9c,\n\t0x0c3ef153, 0x1d906bcf, 0x0ac7cd3b, 0x1e212105, 0x094a0317, 0x1e9f4157, 0x07c67e5f, 0x1f0a7efc,\n\t0xe26f9431, 0xf3c10ead, 0xe48d7cbb, 0xef8c7867, 0xe7437f95, 0xebb30cdb, 0xea8296cb, 0xe84a20de,\n\t0xe26f9431, 0x0c3ef153, 0xe160bea9, 0x094a0317, 0xe09d6830, 0x063e2e0f, 0xe027725c, 0x0322f4d8,\n\t0x063e2e0f, 0x1f6297d0, 0x04b2041c, 0x1fa7557f, 0x0322f4d8, 0x1fd88da4, 0x0191f65f, 0x1ff621e3,\n\t0xee38c4c6, 0xe56499d7, 0xf25177fb, 0xe312850c, 0xf6b5fce9, 0xe160bea9, 0xfb4dfbe4, 0xe058aa81,\n\n\t0x20000000, 0x00000000, 0x1ffd8861, 0x00c90ab0, 0x1ff621e3, 0x0191f65f, 0x1fe9cdad, 0x025aa412,\n\t0x20000000, 0x00000000, 0x1fff6217, 0x00648748, 0x1ffd8861, 0x00c90ab0, 0x1ffa72f0, 0x012d8657,\n\t0x20000000, 0x00000000, 0x1ffa72f0, 0x012d8657, 0x1fe9cdad, 0x025aa412, 0x1fce15fd, 0x0386f0b9,\n\t0x1fd88da4, 0x0322f4d8, 0x1fc26471, 0x03eac9cb, 0x1fa7557f, 0x04b2041c, 0x1f8764fa, 0x05788511,\n\t0x1ff621e3, 0x0191f65f, 0x1ff09566, 0x01f656e8, 0x1fe9cdad, 0x025aa412, 0x1fe1cafd, 0x02beda01,\n\t0x1fa7557f, 0x04b2041c, 0x1f7599a4, 0x05db7678, 0x1f38f3ac, 0x0702e09b, 0x1ef178a4, 0x0827dc07,\n\t0x1f6297d0, 0x063e2e0f, 0x1f38f3ac, 0x0702e09b, 0x1f0a7efc, 0x07c67e5f, 0x1ed740e7, 0x0888e931,\n\t0x1fd88da4, 0x0322f4d8, 0x1fce15fd, 0x0386f0b9, 0x1fc26471, 0x03eac9cb, 0x1fb57972, 0x044e7c34,\n\t0x1e9f4157, 0x094a0317, 0x1e426a4b, 0x0a68f121, 0x1ddb13b7, 0x0b844298, 0x1d696174, 0x0c9b9532,\n\t0x1e9f4157, 0x094a0317, 0x1e6288ec, 0x0a09ae4a, 0x1e212105, 0x0ac7cd3b, 0x1ddb13b7, 0x0b844298,\n\t0x1fa7557f, 0x04b2041c, 0x1f97f925, 0x05155dac, 0x1f8764fa, 0x05788511, 0x1f7599a4, 0x05db7678,\n\t0x1ced7af4, 0x0dae8805, 0x1c678b35, 0x0ebcbbae, 0x1bd7c0ac, 0x0fc5d26e, 0x1b3e4d3f, 0x10c9704d,\n\t0x1d906bcf, 0x0c3ef153, 0x1d4134d1, 0x0cf7bca2, 0x1ced7af4, 0x0dae8805, 0x1c954b21, 0x0e63374d,\n\t0x1f6297d0, 0x063e2e0f, 0x1f4e603b, 0x06a0a809, 0x1f38f3ac, 0x0702e09b, 0x1f2252f7, 0x0764d3f9,\n\t0x1a9b6629, 0x11c73b3a, 0x19ef43ef, 0x12bedb26, 0x193a224a, 0x13affa29, 0x187c4010, 0x149a449c,\n\t0x1c38b2f2, 0x0f15ae9c, 0x1bd7c0ac, 0x0fc5d26e, 0x1b728345, 0x10738799, 0x1b090a58, 0x111eb354,\n\t0x1f0a7efc, 0x07c67e5f, 0x1ef178a4, 0x0827dc07, 0x1ed740e7, 0x0888e931, 0x1ebbd8c9, 0x08e9a220,\n\t0x17b5df22, 0x157d6935, 0x16e74455, 0x16591926, 0x1610b755, 0x172d0838, 0x15328293, 0x17f8ece3,\n\t0x1a9b6629, 0x11c73b3a, 0x1a29a7a0, 0x126d054d, 0x19b3e048, 0x130ff7fd, 0x193a224a, 0x13affa29,\n\t0x1e9f4157, 0x094a0317, 0x1e817bab, 0x09aa0861, 0x1e6288ec, 0x0a09ae4a, 0x1e426a4b, 0x0a68f121,\n\t0x144cf325, 0x18bc806b, 0x136058b1, 0x19777ef5, 0x126d054d, 0x1a29a7a0, 0x11734d64, 0x1ad2bc9e,\n\t0x18bc806b, 0x144cf325, 0x183b0e0c, 0x14e6cabc, 0x17b5df22, 0x157d6935, 0x172d0838, 0x1610b755,\n\t0x1e212105, 0x0ac7cd3b, 0x1dfeae62, 0x0b263eef, 0x1ddb13b7, 0x0b844298, 0x1db65262, 0x0be1d499,\n\t0x10738799, 0x1b728345, 0x0f6e0ca9, 0x1c08c426, 0x0e63374d, 0x1c954b21, 0x0d536416, 0x1d17e774,\n\t0x16a09e66, 0x16a09e66, 0x1610b755, 0x172d0838, 0x157d6935, 0x17b5df22, 0x14e6cabc, 0x183b0e0c,\n\t0x1d906bcf, 0x0c3ef153, 0x1d696174, 0x0c9b9532, 0x1d4134d1, 0x0cf7bca2, 0x1d17e774, 0x0d536416,\n\t0x0c3ef153, 0x1d906bcf, 0x0b263eef, 0x1dfeae62, 0x0a09ae4a, 0x1e6288ec, 0x08e9a220, 0x1ebbd8c9,\n\t0x144cf325, 0x18bc806b, 0x13affa29, 0x193a224a, 0x130ff7fd, 0x19b3e048, 0x126d054d, 0x1a29a7a0,\n\t0x1ced7af4, 0x0dae8805, 0x1cc1f0f4, 0x0e0924ec, 0x1c954b21, 0x0e63374d, 0x1c678b35, 0x0ebcbbae,\n\t0x07c67e5f, 0x1f0a7efc, 0x06a0a809, 0x1f4e603b, 0x05788511, 0x1f8764fa, 0x044e7c34, 0x1fb57972,\n\t0x11c73b3a, 0x1a9b6629, 0x111eb354, 0x1b090a58, 0x10738799, 0x1b728345, 0x0fc5d26e, 0x1bd7c0ac,\n\t0x1c38b2f2, 0x0f15ae9c, 0x1c08c426, 0x0f6e0ca9, 0x1bd7c0ac, 0x0fc5d26e, 0x1ba5aa67, 0x101cfc87,\n\t0x0322f4d8, 0x1fd88da4, 0x01f656e8, 0x1ff09566, 0x00c90ab0, 0x1ffd8861, 0xff9b78b8, 0x1fff6217,\n\t0x0f15ae9c, 0x1c38b2f2, 0x0e63374d, 0x1c954b21, 0x0dae8805, 0x1ced7af4, 0x0cf7bca2, 0x1d4134d1,\n\t0x1b728345, 0x10738799, 0x1b3e4d3f, 0x10c9704d, 0x1b090a58, 0x111eb354, 0x1ad2bc9e, 0x11734d64,\n\t0xfe6e09a1, 0x1ff621e3, 0xfd4125ff, 0x1fe1cafd, 0xfc153635, 0x1fc26471, 0xfaeaa254, 0x1f97f925,\n\t0x0c3ef153, 0x1d906bcf, 0x0b844298, 0x1ddb13b7, 0x0ac7cd3b, 0x1e212105, 0x0a09ae4a, 0x1e6288ec,\n\t0x1a9b6629, 0x11c73b3a, 0x1a63091b, 0x121a7999, 0x1a29a7a0, 0x126d054d, 0x19ef43ef, 0x12bedb26,\n\t0xf9c1d1f1, 0x1f6297d0, 0xf89b2c07, 0x1f2252f7, 0xf77716cf, 0x1ed740e7, 0xf655f79f, 0x1e817bab,\n\t0x094a0317, 0x1e9f4157, 0x0888e931, 0x1ed740e7, 0x07c67e5f, 0x1f0a7efc, 0x0702e09b, 0x1f38f3ac,\n\t0x19b3e048, 0x130ff7fd, 0x19777ef5, 0x136058b1, 0x193a224a, 0x13affa29, 0x18fbcca4, 0x13fed953,\n\t0xf53832c5, 0x1e212105, 0xf41e2b67, 0x1db65262, 0xf308435e, 0x1d4134d1, 0xf1f6db14, 0x1cc1f0f4,\n\t0x063e2e0f, 0x1f6297d0, 0x05788511, 0x1f8764fa, 0x04b2041c, 0x1fa7557f, 0x03eac9cb, 0x1fc26471,\n\t0x18bc806b, 0x144cf325, 0x187c4010, 0x149a449c, 0x183b0e0c, 0x14e6cabc, 0x17f8ece3, 0x15328293,\n\t0xf0ea5164, 0x1c38b2f2, 0xefe30379, 0x1ba5aa67, 0xeee14cac, 0x1b090a58, 0xede58667, 0x1a63091b,\n\t0x0322f4d8, 0x1fd88da4, 0x025aa412, 0x1fe9cdad, 0x0191f65f, 0x1ff621e3, 0x00c90ab0, 0x1ffd8861,\n\t0x17b5df22, 0x157d6935, 0x1771e75f, 0x15c77bbe, 0x172d0838, 0x1610b755, 0x16e74455, 0x16591926,\n\t0xecf00803, 0x19b3e048, 0xec0126ad, 0x18fbcca4, 0xeb193544, 0x183b0e0c, 0xea388442, 0x1771e75f,\n\t0x00000000, 0x20000000, 0xff36f550, 0x1ffd8861, 0xfe6e09a1, 0x1ff621e3, 0xfda55bee, 0x1fe9cdad,\n\t0x16a09e66, 0x16a09e66, 0x16591926, 0x16e74455, 0x1610b755, 0x172d0838, 0x15c77bbe, 0x1771e75f,\n\t0xe95f619a, 0x16a09e66, 0xe88e18a1, 0x15c77bbe, 0xe7c4f1f4, 0x14e6cabc, 0xe704335c, 0x13fed953,\n\t0xfcdd0b28, 0x1fd88da4, 0xfc153635, 0x1fc26471, 0xfb4dfbe4, 0x1fa7557f, 0xfa877aef, 0x1f8764fa,\n\t0x157d6935, 0x17b5df22, 0x15328293, 0x17f8ece3, 0x14e6cabc, 0x183b0e0c, 0x149a449c, 0x187c4010,\n\t0xe64c1fb8, 0x130ff7fd, 0xe59cf6e5, 0x121a7999, 0xe4f6f5a8, 0x111eb354, 0xe45a5599, 0x101cfc87,\n\t0xf9c1d1f1, 0x1f6297d0, 0xf8fd1f65, 0x1f38f3ac, 0xf83981a1, 0x1f0a7efc, 0xf77716cf, 0x1ed740e7,\n\t0x144cf325, 0x18bc806b, 0x13fed953, 0x18fbcca4, 0x13affa29, 0x193a224a, 0x136058b1, 0x19777ef5,\n\t0xe3c74d0e, 0x0f15ae9c, 0xe33e0f0c, 0x0e0924ec, 0xe2becb2f, 0x0cf7bca2, 0xe249ad9e, 0x0be1d499,\n\t0xf6b5fce9, 0x1e9f4157, 0xf5f651b6, 0x1e6288ec, 0xf53832c5, 0x1e212105, 0xf47bbd68, 0x1ddb13b7,\n\t0x130ff7fd, 0x19b3e048, 0x12bedb26, 0x19ef43ef, 0x126d054d, 0x1a29a7a0, 0x121a7999, 0x1a63091b,\n\t0xe1dedefb, 0x0ac7cd3b, 0xe17e8455, 0x09aa0861, 0xe128bf19, 0x0888e931, 0xe0ddad09, 0x0764d3f9,\n\t0xf3c10ead, 0x1d906bcf, 0xf308435e, 0x1d4134d1, 0xf25177fb, 0x1ced7af4, 0xf19cc8b3, 0x1c954b21,\n\t0x11c73b3a, 0x1a9b6629, 0x11734d64, 0x1ad2bc9e, 0x111eb354, 0x1b090a58, 0x10c9704d, 0x1b3e4d3f,\n\t0xe09d6830, 0x063e2e0f, 0xe06806db, 0x05155dac, 0xe03d9b8f, 0x03eac9cb, 0xe01e3503, 0x02beda01,\n\t0xf0ea5164, 0x1c38b2f2, 0xf03a2d92, 0x1bd7c0ac, 0xef8c7867, 0x1b728345, 0xeee14cac, 0x1b090a58,\n\t0x10738799, 0x1b728345, 0x101cfc87, 0x1ba5aa67, 0x0fc5d26e, 0x1bd7c0ac, 0x0f6e0ca9, 0x1c08c426,\n\t0xe009de1d, 0x0191f65f, 0xe0009de9, 0x00648748, 0xe002779f, 0xff36f550, 0xe00f6a9a, 0xfe09a918,\n\t0xee38c4c6, 0x1a9b6629, 0xed92fab3, 0x1a29a7a0, 0xecf00803, 0x19b3e048, 0xec5005d7, 0x193a224a,\n\t0x0f15ae9c, 0x1c38b2f2, 0x0ebcbbae, 0x1c678b35, 0x0e63374d, 0x1c954b21, 0x0e0924ec, 0x1cc1f0f4,\n\t0xe027725c, 0xfcdd0b28, 0xe04a868e, 0xfbb183cc, 0xe0789b06, 0xfa877aef, 0xe0b19fc5, 0xf95f57f7,\n\t0xebb30cdb, 0x18bc806b, 0xeb193544, 0x183b0e0c, 0xea8296cb, 0x17b5df22, 0xe9ef48ab, 0x172d0838,\n\t0x0dae8805, 0x1ced7af4, 0x0d536416, 0x1d17e774, 0x0cf7bca2, 0x1d4134d1, 0x0c9b9532, 0x1d696174,\n\t0xe0f58104, 0xf83981a1, 0xe1442737, 0xf7165de0, 0xe19d7714, 0xf5f651b6, 0xe201519e, 0xf4d9c111,\n\t0xe95f619a, 0x16a09e66, 0xe8d2f7c8, 0x1610b755, 0xe84a20de, 0x157d6935, 0xe7c4f1f4, 0x14e6cabc,\n\t0x0c3ef153, 0x1d906bcf, 0x0be1d499, 0x1db65262, 0x0b844298, 0x1ddb13b7, 0x0b263eef, 0x1dfeae62,\n\t0xe26f9431, 0xf3c10ead, 0xe2e8188c, 0xf2ac9bea, 0xe36ab4df, 0xf19cc8b3, 0xe3f73bda, 0xf091f357,\n\t0xe7437f95, 0x144cf325, 0xe6c5ddb6, 0x13affa29, 0xe64c1fb8, 0x130ff7fd, 0xe5d65860, 0x126d054d,\n\t0x0ac7cd3b, 0x1e212105, 0x0a68f121, 0x1e426a4b, 0x0a09ae4a, 0x1e6288ec, 0x09aa0861, 0x1e817bab,\n\t0xe48d7cbb, 0xef8c7867, 0xe52d4362, 0xee8cb29c, 0xe5d65860, 0xed92fab3, 0xe688810b, 0xec9fa74f,\n\t0xe56499d7, 0x11c73b3a, 0xe4f6f5a8, 0x111eb354, 0xe48d7cbb, 0x10738799, 0xe4283f54, 0x0fc5d26e,\n\t0x094a0317, 0x1e9f4157, 0x08e9a220, 0x1ebbd8c9, 0x0888e931, 0x1ed740e7, 0x0827dc07, 0x1ef178a4,\n\t0xe7437f95, 0xebb30cdb, 0xe807131d, 0xeacd7d6d, 0xe8d2f7c8, 0xe9ef48ab, 0xe9a6e6da, 0xe918bbab,\n\t0xe3c74d0e, 0x0f15ae9c, 0xe36ab4df, 0x0e63374d, 0xe312850c, 0x0dae8805, 0xe2becb2f, 0x0cf7bca2,\n\t0x07c67e5f, 0x1f0a7efc, 0x0764d3f9, 0x1f2252f7, 0x0702e09b, 0x1f38f3ac, 0x06a0a809, 0x1f4e603b,\n\t0xea8296cb, 0xe84a20de, 0xeb65bb64, 0xe783bff0, 0xec5005d7, 0xe6c5ddb6, 0xed4124da, 0xe610bc11,\n\t0xe26f9431, 0x0c3ef153, 0xe224ec49, 0x0b844298, 0xe1dedefb, 0x0ac7cd3b, 0xe19d7714, 0x0a09ae4a,\n\t0x063e2e0f, 0x1f6297d0, 0x05db7678, 0x1f7599a4, 0x05788511, 0x1f8764fa, 0x05155dac, 0x1f97f925,\n\t0xee38c4c6, 0xe56499d7, 0xef368fb3, 0xe4c1b2c1, 0xf03a2d92, 0xe4283f54, 0xf1434452, 0xe39874cb,\n\t0xe160bea9, 0x094a0317, 0xe128bf19, 0x0888e931, 0xe0f58104, 0x07c67e5f, 0xe0c70c54, 0x0702e09b,\n\t0x04b2041c, 0x1fa7557f, 0x044e7c34, 0x1fb57972, 0x03eac9cb, 0x1fc26471, 0x0386f0b9, 0x1fce15fd,\n\t0xf25177fb, 0xe312850c, 0xf3646ace, 0xe2969e8c, 0xf47bbd68, 0xe224ec49, 0xf5970edf, 0xe1bd95b5,\n\t0xe09d6830, 0x063e2e0f, 0xe0789b06, 0x05788511, 0xe058aa81, 0x04b2041c, 0xe03d9b8f, 0x03eac9cb,\n\t0x0322f4d8, 0x1fd88da4, 0x02beda01, 0x1fe1cafd, 0x025aa412, 0x1fe9cdad, 0x01f656e8, 0x1ff09566,\n\t0xf6b5fce9, 0xe160bea9, 0xf7d823f9, 0xe10e875c, 0xf8fd1f65, 0xe0c70c54, 0xfa248988, 0xe08a665c,\n\t0xe027725c, 0x0322f4d8, 0xe0163253, 0x025aa412, 0xe009de1d, 0x0191f65f, 0xe002779f, 0x00c90ab0,\n\t0x0191f65f, 0x1ff621e3, 0x012d8657, 0x1ffa72f0, 0x00c90ab0, 0x1ffd8861, 0x00648748, 0x1fff6217,\n\t0xfb4dfbe4, 0xe058aa81, 0xfc790f47, 0xe031ea03, 0xfda55bee, 0xe0163253, 0xfed279a9, 0xe0058d10\n};\n\nconst int twidTab64[4*6 + 16*6] = {\n\t0x20000000, 0x00000000, 0x16a09e66, 0x16a09e66, 0x00000000, 0x20000000, 0xe95f619a, 0x16a09e66,\n\t0x20000000, 0x00000000, 0x1d906bcf, 0x0c3ef153, 0x16a09e66, 0x16a09e66, 0x0c3ef153, 0x1d906bcf,\n\t0x20000000, 0x00000000, 0x0c3ef153, 0x1d906bcf, 0xe95f619a, 0x16a09e66, 0xe26f9431, 0xf3c10ead,\n\n\t0x20000000, 0x00000000, 0x1f6297d0, 0x063e2e0f, 0x1d906bcf, 0x0c3ef153, 0x1a9b6629, 0x11c73b3a,\n\t0x20000000, 0x00000000, 0x1fd88da4, 0x0322f4d8, 0x1f6297d0, 0x063e2e0f, 0x1e9f4157, 0x094a0317,\n\t0x20000000, 0x00000000, 0x1e9f4157, 0x094a0317, 0x1a9b6629, 0x11c73b3a, 0x144cf325, 0x18bc806b,\n\t0x16a09e66, 0x16a09e66, 0x11c73b3a, 0x1a9b6629, 0x0c3ef153, 0x1d906bcf, 0x063e2e0f, 0x1f6297d0,\n\t0x1d906bcf, 0x0c3ef153, 0x1c38b2f2, 0x0f15ae9c, 0x1a9b6629, 0x11c73b3a, 0x18bc806b, 0x144cf325,\n\t0x0c3ef153, 0x1d906bcf, 0x0322f4d8, 0x1fd88da4, 0xf9c1d1f1, 0x1f6297d0, 0xf0ea5164, 0x1c38b2f2,\n\t0x00000000, 0x20000000, 0xf9c1d1f1, 0x1f6297d0, 0xf3c10ead, 0x1d906bcf, 0xee38c4c6, 0x1a9b6629,\n\t0x16a09e66, 0x16a09e66, 0x144cf325, 0x18bc806b, 0x11c73b3a, 0x1a9b6629, 0x0f15ae9c, 0x1c38b2f2,\n\t0xe95f619a, 0x16a09e66, 0xe3c74d0e, 0x0f15ae9c, 0xe09d6830, 0x063e2e0f, 0xe027725c, 0xfcdd0b28,\n\t0xe95f619a, 0x16a09e66, 0xe56499d7, 0x11c73b3a, 0xe26f9431, 0x0c3ef153, 0xe09d6830, 0x063e2e0f,\n\t0x0c3ef153, 0x1d906bcf, 0x094a0317, 0x1e9f4157, 0x063e2e0f, 0x1f6297d0, 0x0322f4d8, 0x1fd88da4,\n\t0xe26f9431, 0xf3c10ead, 0xe7437f95, 0xebb30cdb, 0xee38c4c6, 0xe56499d7, 0xf6b5fce9, 0xe160bea9\n};\n\n#else\n\n/*\n *  Q30 for 128 and 1024\n *\n * for (i = 0; i < num/4; i++) {\n *   angle = (i + 0.125) * M_PI / num;\n *   x = cos(angle) * (1 << 30);\n *   x = sin(angle) * (1 << 30);\n *\n *   angle = (num/2 - 1 - i + 0.125) * M_PI / num;\n *   x = cos(angle) * (1 << 30);\n *   x = sin(angle) * (1 << 30);\n * }\n */\nconst int cossintab[128 + 1024] = {\n\t/* 128 */\n\t0x3fffec43, 0x003243f1, 0x015fd4d2, 0x3ffc38d1, 0x3ff9c13a, 0x01c454f5, 0x02f1b755, 0x3feea776,\n\t0x3fe9b8a9, 0x03562038, 0x0483259d, 0x3fd73a4a, 0x3fcfd50b, 0x04e767c5, 0x0613e1c5, 0x3fb5f4ea,\n\t0x3fac1a5b, 0x0677edbb, 0x07a3adff, 0x3f8adc77, 0x3f7e8e1e, 0x08077457, 0x09324ca7, 0x3f55f796,\n\t0x3f473759, 0x0995bdfd, 0x0abf8043, 0x3f174e70, 0x3f061e95, 0x0b228d42, 0x0c4b0b94, 0x3eceeaad,\n\t0x3ebb4ddb, 0x0cada4f5, 0x0dd4b19a, 0x3e7cd778, 0x3e66d0b4, 0x0e36c82a, 0x0f5c35a3, 0x3e212179,\n\t0x3e08b42a, 0x0fbdba40, 0x10e15b4e, 0x3dbbd6d4, 0x3da106bd, 0x11423ef0, 0x1263e699, 0x3d4d0728,\n\t0x3d2fd86c, 0x12c41a4f, 0x13e39be9, 0x3cd4c38b, 0x3cb53aaa, 0x144310dd, 0x15604013, 0x3c531e88,\n\t0x3c314060, 0x15bee78c, 0x16d99864, 0x3bc82c1f, 0x3ba3fde7, 0x173763c9, 0x184f6aab, 0x3b3401bb,\n\t0x3b0d8909, 0x18ac4b87, 0x19c17d44, 0x3a96b636, 0x3a6df8f8, 0x1a1d6544, 0x1b2f971e, 0x39f061d2,\n\t0x39c5664f, 0x1b8a7815, 0x1c997fc4, 0x39411e33, 0x3913eb0e, 0x1cf34baf, 0x1dfeff67, 0x38890663,\n\t0x3859a292, 0x1e57a86d, 0x1f5fdee6, 0x37c836c2, 0x3796a996, 0x1fb7575c, 0x20bbe7d8, 0x36fecd0e,\n\t0x36cb1e2a, 0x21122240, 0x2212e492, 0x362ce855, 0x35f71fb1, 0x2267d3a0, 0x2364a02e, 0x3552a8f4,\n\t0x351acedd, 0x23b836ca, 0x24b0e699, 0x34703095, 0x34364da6, 0x250317df, 0x25f78497, 0x3385a222,\n\t0x3349bf48, 0x264843d9, 0x273847c8, 0x329321c7, 0x32554840, 0x27878893, 0x2872feb6, 0x3198d4ea,\n\t0x31590e3e, 0x28c0b4d2, 0x29a778db, 0x3096e223, 0x30553828, 0x29f3984c, 0x2ad586a3, 0x2f8d713a,\n\t0x2f49ee0f, 0x2b2003ac, 0x2bfcf97c, 0x2e7cab1c, 0x2e37592c, 0x2c45c8a0, 0x2d1da3d5, 0x2d64b9da,\n\t/* 1024 */\n\t0x3fffffb1, 0x0006487f, 0x002bfb74, 0x3ffff0e3, 0x3fffe705, 0x00388c6e, 0x005e3f4c, 0x3fffba9b,\n\t0x3fffa6de, 0x006ad03b, 0x009082ea, 0x3fff5cd8, 0x3fff3f3c, 0x009d13c5, 0x00c2c62f, 0x3ffed79b,\n\t0x3ffeb021, 0x00cf56ef, 0x00f508fc, 0x3ffe2ae5, 0x3ffdf98c, 0x01019998, 0x01274b31, 0x3ffd56b5,\n\t0x3ffd1b7e, 0x0133dba3, 0x01598cb1, 0x3ffc5b0c, 0x3ffc15f7, 0x01661cf0, 0x018bcd5b, 0x3ffb37ec,\n\t0x3ffae8f9, 0x01985d60, 0x01be0d11, 0x3ff9ed53, 0x3ff99483, 0x01ca9cd4, 0x01f04bb4, 0x3ff87b44,\n\t0x3ff81896, 0x01fcdb2e, 0x02228924, 0x3ff6e1bf, 0x3ff67534, 0x022f184d, 0x0254c544, 0x3ff520c5,\n\t0x3ff4aa5d, 0x02615414, 0x0286fff3, 0x3ff33858, 0x3ff2b813, 0x02938e62, 0x02b93914, 0x3ff12878,\n\t0x3ff09e56, 0x02c5c71a, 0x02eb7086, 0x3feef126, 0x3fee5d28, 0x02f7fe1c, 0x031da62b, 0x3fec9265,\n\t0x3febf48b, 0x032a3349, 0x034fd9e5, 0x3fea0c35, 0x3fe96480, 0x035c6682, 0x03820b93, 0x3fe75e98,\n\t0x3fe6ad08, 0x038e97a9, 0x03b43b17, 0x3fe48990, 0x3fe3ce26, 0x03c0c69e, 0x03e66852, 0x3fe18d1f,\n\t0x3fe0c7da, 0x03f2f342, 0x04189326, 0x3fde6945, 0x3fdd9a27, 0x04251d77, 0x044abb73, 0x3fdb1e06,\n\t0x3fda450f, 0x0457451d, 0x047ce11a, 0x3fd7ab64, 0x3fd6c894, 0x04896a16, 0x04af03fc, 0x3fd4115f,\n\t0x3fd324b7, 0x04bb8c42, 0x04e123fa, 0x3fd04ffc, 0x3fcf597c, 0x04edab83, 0x051340f6, 0x3fcc673b,\n\t0x3fcb66e4, 0x051fc7b9, 0x05455ad1, 0x3fc8571f, 0x3fc74cf3, 0x0551e0c7, 0x0577716b, 0x3fc41fac,\n\t0x3fc30baa, 0x0583f68c, 0x05a984a6, 0x3fbfc0e3, 0x3fbea30c, 0x05b608eb, 0x05db9463, 0x3fbb3ac7,\n\t0x3fba131b, 0x05e817c3, 0x060da083, 0x3fb68d5b, 0x3fb55bdc, 0x061a22f7, 0x063fa8e7, 0x3fb1b8a2,\n\t0x3fb07d50, 0x064c2a67, 0x0671ad71, 0x3facbc9f, 0x3fab777b, 0x067e2df5, 0x06a3ae00, 0x3fa79954,\n\t0x3fa64a5f, 0x06b02d81, 0x06d5aa77, 0x3fa24ec6, 0x3fa0f600, 0x06e228ee, 0x0707a2b7, 0x3f9cdcf7,\n\t0x3f9b7a62, 0x0714201b, 0x073996a1, 0x3f9743eb, 0x3f95d787, 0x074612eb, 0x076b8616, 0x3f9183a5,\n\t0x3f900d72, 0x0778013d, 0x079d70f7, 0x3f8b9c28, 0x3f8a1c29, 0x07a9eaf5, 0x07cf5726, 0x3f858d79,\n\t0x3f8403ae, 0x07dbcff2, 0x08013883, 0x3f7f579b, 0x3f7dc405, 0x080db016, 0x083314f1, 0x3f78fa92,\n\t0x3f775d31, 0x083f8b43, 0x0864ec4f, 0x3f727661, 0x3f70cf38, 0x08716159, 0x0896be80, 0x3f6bcb0e,\n\t0x3f6a1a1c, 0x08a3323a, 0x08c88b65, 0x3f64f89b, 0x3f633de2, 0x08d4fdc6, 0x08fa52de, 0x3f5dff0e,\n\t0x3f5c3a8f, 0x0906c3e0, 0x092c14ce, 0x3f56de6a, 0x3f551026, 0x09388469, 0x095dd116, 0x3f4f96b4,\n\t0x3f4dbeac, 0x096a3f42, 0x098f8796, 0x3f4827f0, 0x3f464626, 0x099bf44c, 0x09c13831, 0x3f409223,\n\t0x3f3ea697, 0x09cda368, 0x09f2e2c7, 0x3f38d552, 0x3f36e006, 0x09ff4c78, 0x0a24873a, 0x3f30f181,\n\t0x3f2ef276, 0x0a30ef5e, 0x0a56256c, 0x3f28e6b6, 0x3f26ddec, 0x0a628bfa, 0x0a87bd3d, 0x3f20b4f5,\n\t0x3f1ea26e, 0x0a94222f, 0x0ab94e8f, 0x3f185c43, 0x3f164001, 0x0ac5b1dc, 0x0aead944, 0x3f0fdca5,\n\t0x3f0db6a9, 0x0af73ae5, 0x0b1c5d3d, 0x3f073621, 0x3f05066d, 0x0b28bd2a, 0x0b4dda5c, 0x3efe68bc,\n\t0x3efc2f50, 0x0b5a388d, 0x0b7f5081, 0x3ef5747b, 0x3ef3315a, 0x0b8bacf0, 0x0bb0bf8f, 0x3eec5965,\n\t0x3eea0c8e, 0x0bbd1a33, 0x0be22766, 0x3ee3177e, 0x3ee0c0f4, 0x0bee8038, 0x0c1387e9, 0x3ed9aecc,\n\t0x3ed74e91, 0x0c1fdee1, 0x0c44e0f9, 0x3ed01f55, 0x3ecdb56a, 0x0c513610, 0x0c763278, 0x3ec66920,\n\t0x3ec3f585, 0x0c8285a5, 0x0ca77c47, 0x3ebc8c31, 0x3eba0ee9, 0x0cb3cd84, 0x0cd8be47, 0x3eb2888f,\n\t0x3eb0019c, 0x0ce50d8c, 0x0d09f85b, 0x3ea85e41, 0x3ea5cda3, 0x0d1645a0, 0x0d3b2a64, 0x3e9e0d4c,\n\t0x3e9b7306, 0x0d4775a1, 0x0d6c5443, 0x3e9395b7, 0x3e90f1ca, 0x0d789d71, 0x0d9d75db, 0x3e88f788,\n\t0x3e8649f5, 0x0da9bcf2, 0x0dce8f0d, 0x3e7e32c6, 0x3e7b7b90, 0x0ddad406, 0x0dff9fba, 0x3e734778,\n\t0x3e70869f, 0x0e0be28e, 0x0e30a7c5, 0x3e6835a4, 0x3e656b2b, 0x0e3ce86b, 0x0e61a70f, 0x3e5cfd51,\n\t0x3e5a2939, 0x0e6de580, 0x0e929d7a, 0x3e519e86, 0x3e4ec0d1, 0x0e9ed9af, 0x0ec38ae8, 0x3e46194a,\n\t0x3e4331fa, 0x0ecfc4d9, 0x0ef46f3b, 0x3e3a6da4, 0x3e377cbb, 0x0f00a6df, 0x0f254a53, 0x3e2e9b9c,\n\t0x3e2ba11b, 0x0f317fa5, 0x0f561c15, 0x3e22a338, 0x3e1f9f21, 0x0f624f0c, 0x0f86e460, 0x3e168480,\n\t0x3e1376d5, 0x0f9314f5, 0x0fb7a317, 0x3e0a3f7b, 0x3e07283f, 0x0fc3d143, 0x0fe8581d, 0x3dfdd432,\n\t0x3dfab365, 0x0ff483d7, 0x10190352, 0x3df142ab, 0x3dee1851, 0x10252c94, 0x1049a49a, 0x3de48aef,\n\t0x3de15708, 0x1055cb5b, 0x107a3bd5, 0x3dd7ad05, 0x3dd46f94, 0x1086600e, 0x10aac8e6, 0x3dcaa8f5,\n\t0x3dc761fc, 0x10b6ea90, 0x10db4baf, 0x3dbd7ec7, 0x3dba2e48, 0x10e76ac3, 0x110bc413, 0x3db02e84,\n\t0x3dacd481, 0x1117e088, 0x113c31f3, 0x3da2b834, 0x3d9f54af, 0x11484bc2, 0x116c9531, 0x3d951bde,\n\t0x3d91aed9, 0x1178ac53, 0x119cedaf, 0x3d87598c, 0x3d83e309, 0x11a9021d, 0x11cd3b50, 0x3d797145,\n\t0x3d75f147, 0x11d94d02, 0x11fd7df6, 0x3d6b6313, 0x3d67d99b, 0x12098ce5, 0x122db583, 0x3d5d2efe,\n\t0x3d599c0e, 0x1239c1a7, 0x125de1da, 0x3d4ed50f, 0x3d4b38aa, 0x1269eb2b, 0x128e02dc, 0x3d40554e,\n\t0x3d3caf76, 0x129a0954, 0x12be186c, 0x3d31afc5, 0x3d2e007c, 0x12ca1c03, 0x12ee226c, 0x3d22e47c,\n\t0x3d1f2bc5, 0x12fa231b, 0x131e20c0, 0x3d13f37e, 0x3d10315a, 0x132a1e7e, 0x134e1348, 0x3d04dcd2,\n\t0x3d011145, 0x135a0e0e, 0x137df9e7, 0x3cf5a082, 0x3cf1cb8e, 0x1389f1af, 0x13add481, 0x3ce63e98,\n\t0x3ce2603f, 0x13b9c943, 0x13dda2f7, 0x3cd6b71e, 0x3cd2cf62, 0x13e994ab, 0x140d652c, 0x3cc70a1c,\n\t0x3cc318ff, 0x141953cb, 0x143d1b02, 0x3cb7379c, 0x3cb33d22, 0x14490685, 0x146cc45c, 0x3ca73fa9,\n\t0x3ca33bd3, 0x1478acbc, 0x149c611d, 0x3c97224c, 0x3c93151d, 0x14a84652, 0x14cbf127, 0x3c86df8e,\n\t0x3c82c909, 0x14d7d32a, 0x14fb745e, 0x3c76777b, 0x3c7257a2, 0x15075327, 0x152aeaa3, 0x3c65ea1c,\n\t0x3c61c0f1, 0x1536c62b, 0x155a53d9, 0x3c55377b, 0x3c510501, 0x15662c18, 0x1589afe3, 0x3c445fa2,\n\t0x3c4023dd, 0x159584d3, 0x15b8fea4, 0x3c33629d, 0x3c2f1d8e, 0x15c4d03e, 0x15e83fff, 0x3c224075,\n\t0x3c1df21f, 0x15f40e3a, 0x161773d6, 0x3c10f935, 0x3c0ca19b, 0x16233eac, 0x16469a0d, 0x3bff8ce8,\n\t0x3bfb2c0c, 0x16526176, 0x1675b286, 0x3bedfb99, 0x3be9917e, 0x1681767c, 0x16a4bd25, 0x3bdc4552,\n\t0x3bd7d1fa, 0x16b07d9f, 0x16d3b9cc, 0x3bca6a1d, 0x3bc5ed8d, 0x16df76c3, 0x1702a85e, 0x3bb86a08,\n\t0x3bb3e440, 0x170e61cc, 0x173188be, 0x3ba6451b, 0x3ba1b620, 0x173d3e9b, 0x17605ad0, 0x3b93fb63,\n\t0x3b8f6337, 0x176c0d15, 0x178f1e76, 0x3b818ceb, 0x3b7ceb90, 0x179acd1c, 0x17bdd394, 0x3b6ef9be,\n\t0x3b6a4f38, 0x17c97e93, 0x17ec7a0d, 0x3b5c41e8, 0x3b578e39, 0x17f8215e, 0x181b11c4, 0x3b496574,\n\t0x3b44a8a0, 0x1826b561, 0x18499a9d, 0x3b36646e, 0x3b319e77, 0x18553a7d, 0x1878147a, 0x3b233ee1,\n\t0x3b1e6fca, 0x1883b097, 0x18a67f3f, 0x3b0ff4d9, 0x3b0b1ca6, 0x18b21791, 0x18d4dad0, 0x3afc8663,\n\t0x3af7a516, 0x18e06f50, 0x1903270f, 0x3ae8f38b, 0x3ae40926, 0x190eb7b7, 0x193163e1, 0x3ad53c5b,\n\t0x3ad048e3, 0x193cf0a9, 0x195f9128, 0x3ac160e1, 0x3abc6458, 0x196b1a09, 0x198daec8, 0x3aad6129,\n\t0x3aa85b92, 0x199933bb, 0x19bbbca6, 0x3a993d3e, 0x3a942e9d, 0x19c73da3, 0x19e9baa3, 0x3a84f52f,\n\t0x3a7fdd86, 0x19f537a4, 0x1a17a8a5, 0x3a708906, 0x3a6b6859, 0x1a2321a2, 0x1a45868e, 0x3a5bf8d1,\n\t0x3a56cf23, 0x1a50fb81, 0x1a735442, 0x3a47449c, 0x3a4211f0, 0x1a7ec524, 0x1aa111a6, 0x3a326c74,\n\t0x3a2d30cd, 0x1aac7e6f, 0x1acebe9d, 0x3a1d7066, 0x3a182bc8, 0x1ada2746, 0x1afc5b0a, 0x3a08507f,\n\t0x3a0302ed, 0x1b07bf8c, 0x1b29e6d2, 0x39f30ccc, 0x39edb649, 0x1b354727, 0x1b5761d8, 0x39dda55a,\n\t0x39d845e9, 0x1b62bdf8, 0x1b84cc01, 0x39c81a36, 0x39c2b1da, 0x1b9023e5, 0x1bb22530, 0x39b26b6d,\n\t0x39acfa2b, 0x1bbd78d2, 0x1bdf6d4a, 0x399c990d, 0x39971ee7, 0x1beabca1, 0x1c0ca432, 0x3986a324,\n\t0x3981201e, 0x1c17ef39, 0x1c39c9cd, 0x397089bf, 0x396afddc, 0x1c45107c, 0x1c66ddfe, 0x395a4ceb,\n\t0x3954b82e, 0x1c72204f, 0x1c93e0ab, 0x3943ecb6, 0x393e4f23, 0x1c9f1e96, 0x1cc0d1b6, 0x392d692f,\n\t0x3927c2c9, 0x1ccc0b35, 0x1cedb106, 0x3916c262, 0x3911132d, 0x1cf8e611, 0x1d1a7e7d, 0x38fff85e,\n\t0x38fa405e, 0x1d25af0d, 0x1d473a00, 0x38e90b31, 0x38e34a69, 0x1d52660f, 0x1d73e374, 0x38d1fae9,\n\t0x38cc315d, 0x1d7f0afb, 0x1da07abc, 0x38bac795, 0x38b4f547, 0x1dab9db5, 0x1dccffbf, 0x38a37142,\n\t0x389d9637, 0x1dd81e21, 0x1df9725f, 0x388bf7ff, 0x3886143b, 0x1e048c24, 0x1e25d282, 0x38745bdb,\n\t0x386e6f60, 0x1e30e7a4, 0x1e52200c, 0x385c9ce3, 0x3856a7b6, 0x1e5d3084, 0x1e7e5ae2, 0x3844bb28,\n\t0x383ebd4c, 0x1e8966a8, 0x1eaa82e9, 0x382cb6b7, 0x3826b030, 0x1eb589f7, 0x1ed69805, 0x38148f9f,\n\t0x380e8071, 0x1ee19a54, 0x1f029a1c, 0x37fc45ef, 0x37f62e1d, 0x1f0d97a5, 0x1f2e8911, 0x37e3d9b7,\n\t0x37ddb945, 0x1f3981ce, 0x1f5a64cb, 0x37cb4b04, 0x37c521f6, 0x1f6558b5, 0x1f862d2d, 0x37b299e7,\n\t0x37ac6841, 0x1f911c3d, 0x1fb1e21d, 0x3799c66f, 0x37938c34, 0x1fbccc4d, 0x1fdd8381, 0x3780d0aa,\n\t0x377a8ddf, 0x1fe868c8, 0x2009113c, 0x3767b8a9, 0x37616d51, 0x2013f196, 0x20348b35, 0x374e7e7b,\n\t0x37482a9a, 0x203f6699, 0x205ff14f, 0x3735222f, 0x372ec5c9, 0x206ac7b8, 0x208b4372, 0x371ba3d4,\n\t0x37153eee, 0x209614d9, 0x20b68181, 0x3702037c, 0x36fb9618, 0x20c14ddf, 0x20e1ab63, 0x36e84135,\n\t0x36e1cb58, 0x20ec72b1, 0x210cc0fc, 0x36ce5d10, 0x36c7debd, 0x21178334, 0x2137c232, 0x36b4571b,\n\t0x36add058, 0x21427f4d, 0x2162aeea, 0x369a2f69, 0x3693a038, 0x216d66e2, 0x218d870b, 0x367fe608,\n\t0x36794e6e, 0x219839d8, 0x21b84a79, 0x36657b08, 0x365edb09, 0x21c2f815, 0x21e2f91a, 0x364aee7b,\n\t0x3644461b, 0x21eda17f, 0x220d92d4, 0x36304070, 0x36298fb4, 0x221835fb, 0x2238178d, 0x361570f8,\n\t0x360eb7e3, 0x2242b56f, 0x22628729, 0x35fa8023, 0x35f3beba, 0x226d1fc1, 0x228ce191, 0x35df6e03,\n\t0x35d8a449, 0x229774d7, 0x22b726a8, 0x35c43aa7, 0x35bd68a1, 0x22c1b496, 0x22e15655, 0x35a8e621,\n\t0x35a20bd3, 0x22ebdee5, 0x230b707e, 0x358d7081, 0x35868def, 0x2315f3a8, 0x23357509, 0x3571d9d9,\n\t0x356aef08, 0x233ff2c8, 0x235f63dc, 0x35562239, 0x354f2f2c, 0x2369dc29, 0x23893cdd, 0x353a49b2,\n\t0x35334e6f, 0x2393afb2, 0x23b2fff3, 0x351e5056, 0x35174ce0, 0x23bd6d48, 0x23dcad03, 0x35023636,\n\t0x34fb2a92, 0x23e714d3, 0x240643f4, 0x34e5fb63, 0x34dee795, 0x2410a639, 0x242fc4ad, 0x34c99fef,\n\t0x34c283fb, 0x243a215f, 0x24592f13, 0x34ad23eb, 0x34a5ffd5, 0x2463862c, 0x2482830d, 0x34908768,\n\t0x34895b36, 0x248cd487, 0x24abc082, 0x3473ca79, 0x346c962f, 0x24b60c57, 0x24d4e757, 0x3456ed2f,\n\t0x344fb0d1, 0x24df2d81, 0x24fdf775, 0x3439ef9c, 0x3432ab2e, 0x250837ed, 0x2526f0c1, 0x341cd1d2,\n\t0x34158559, 0x25312b81, 0x254fd323, 0x33ff93e2, 0x33f83f62, 0x255a0823, 0x25789e80, 0x33e235df,\n\t0x33dad95e, 0x2582cdbc, 0x25a152c0, 0x33c4b7db, 0x33bd535c, 0x25ab7c30, 0x25c9efca, 0x33a719e8,\n\t0x339fad70, 0x25d41369, 0x25f27584, 0x33895c18, 0x3381e7ac, 0x25fc934b, 0x261ae3d6, 0x336b7e7e,\n\t0x33640223, 0x2624fbbf, 0x26433aa7, 0x334d812d, 0x3345fce6, 0x264d4cac, 0x266b79dd, 0x332f6435,\n\t0x3327d808, 0x267585f8, 0x2693a161, 0x331127ab, 0x3309939c, 0x269da78b, 0x26bbb119, 0x32f2cba1,\n\t0x32eb2fb5, 0x26c5b14c, 0x26e3a8ec, 0x32d45029, 0x32ccac64, 0x26eda322, 0x270b88c2, 0x32b5b557,\n\t0x32ae09be, 0x27157cf5, 0x27335082, 0x3296fb3d, 0x328f47d5, 0x273d3eac, 0x275b0014, 0x327821ee,\n\t0x327066bc, 0x2764e82f, 0x27829760, 0x3259297d, 0x32516686, 0x278c7965, 0x27aa164c, 0x323a11fe,\n\t0x32324746, 0x27b3f235, 0x27d17cc1, 0x321adb83, 0x3213090f, 0x27db5288, 0x27f8caa5, 0x31fb8620,\n\t0x31f3abf5, 0x28029a45, 0x281fffe2, 0x31dc11e8, 0x31d4300b, 0x2829c954, 0x28471c5e, 0x31bc7eee,\n\t0x31b49564, 0x2850df9d, 0x286e2002, 0x319ccd46, 0x3194dc14, 0x2877dd07, 0x28950ab6, 0x317cfd04,\n\t0x3175042e, 0x289ec17a, 0x28bbdc61, 0x315d0e3b, 0x31550dc6, 0x28c58cdf, 0x28e294eb, 0x313d00ff,\n\t0x3134f8f1, 0x28ec3f1e, 0x2909343e, 0x311cd564, 0x3114c5c0, 0x2912d81f, 0x292fba40, 0x30fc8b7d,\n\t0x30f47449, 0x293957c9, 0x295626da, 0x30dc235e, 0x30d404a0, 0x295fbe06, 0x297c79f5, 0x30bb9d1c,\n\t0x30b376d8, 0x29860abd, 0x29a2b378, 0x309af8ca, 0x3092cb05, 0x29ac3dd7, 0x29c8d34d, 0x307a367c,\n\t0x3072013c, 0x29d2573c, 0x29eed95b, 0x30595648, 0x30511991, 0x29f856d5, 0x2a14c58b, 0x30385840,\n\t0x30301418, 0x2a1e3c8a, 0x2a3a97c7, 0x30173c7a, 0x300ef0e5, 0x2a440844, 0x2a604ff5, 0x2ff6030a,\n\t0x2fedb00d, 0x2a69b9ec, 0x2a85ee00, 0x2fd4ac04, 0x2fcc51a5, 0x2a8f516b, 0x2aab71d0, 0x2fb3377c,\n\t0x2faad5c1, 0x2ab4cea9, 0x2ad0db4e, 0x2f91a589, 0x2f893c75, 0x2ada318e, 0x2af62a63, 0x2f6ff63d,\n\t0x2f6785d7, 0x2aff7a05, 0x2b1b5ef8, 0x2f4e29af, 0x2f45b1fb, 0x2b24a7f6, 0x2b4078f5, 0x2f2c3ff2,\n\t0x2f23c0f6, 0x2b49bb4a, 0x2b657844, 0x2f0a391d, 0x2f01b2de, 0x2b6eb3ea, 0x2b8a5cce, 0x2ee81543,\n\t0x2edf87c6, 0x2b9391c0, 0x2baf267d, 0x2ec5d479, 0x2ebd3fc4, 0x2bb854b4, 0x2bd3d53a, 0x2ea376d6,\n\t0x2e9adaee, 0x2bdcfcb0, 0x2bf868ed, 0x2e80fc6e, 0x2e785958, 0x2c01899e, 0x2c1ce181, 0x2e5e6556,\n\t0x2e55bb17, 0x2c25fb66, 0x2c413edf, 0x2e3bb1a4, 0x2e330042, 0x2c4a51f3, 0x2c6580f1, 0x2e18e16d,\n\t0x2e1028ed, 0x2c6e8d2e, 0x2c89a79f, 0x2df5f4c7, 0x2ded352f, 0x2c92ad01, 0x2cadb2d5, 0x2dd2ebc7,\n\t0x2dca251c, 0x2cb6b155, 0x2cd1a27b, 0x2dafc683, 0x2da6f8ca, 0x2cda9a14, 0x2cf5767c, 0x2d8c8510,\n\t0x2d83b04f, 0x2cfe6728, 0x2d192ec1, 0x2d692784, 0x2d604bc0, 0x2d22187a, 0x2d3ccb34, 0x2d45adf6\n};\n\nconst int twidTab512[8*6 + 32*6 + 128*6] = {\n\t0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x3b20d79e, 0x187de2a6,\n\t0x3ec52f9f, 0x0c7c5c1e, 0x3536cc52, 0x238e7673, 0x2d413ccc, 0x2d413ccc, 0x3b20d79e, 0x187de2a6,\n\t0x187de2a6, 0x3b20d79e, 0x187de2a6, 0x3b20d79e, 0x3536cc52, 0x238e7673, 0xf383a3e2, 0x3ec52f9f,\n\t0x00000000, 0x40000000, 0x2d413ccc, 0x2d413ccc, 0xd2bec334, 0x2d413ccc, 0xe7821d5a, 0x3b20d79e,\n\t0x238e7673, 0x3536cc52, 0xc13ad061, 0x0c7c5c1e, 0xd2bec334, 0x2d413ccc, 0x187de2a6, 0x3b20d79e,\n\t0xc4df2862, 0xe7821d5a, 0xc4df2862, 0x187de2a6, 0x0c7c5c1e, 0x3ec52f9f, 0xdc71898d, 0xcac933ae,\n\n\t0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x3fb11b47, 0x0645e9af,\n\t0x3fec43c6, 0x0323ecbe, 0x3f4eaafe, 0x09640837, 0x3ec52f9f, 0x0c7c5c1e, 0x3fb11b47, 0x0645e9af,\n\t0x3d3e82ad, 0x1294062e, 0x3d3e82ad, 0x1294062e, 0x3f4eaafe, 0x09640837, 0x39daf5e8, 0x1b5d1009,\n\t0x3b20d79e, 0x187de2a6, 0x3ec52f9f, 0x0c7c5c1e, 0x3536cc52, 0x238e7673, 0x387165e3, 0x1e2b5d38,\n\t0x3e14fdf7, 0x0f8cfcbd, 0x2f6bbe44, 0x2afad269, 0x3536cc52, 0x238e7673, 0x3d3e82ad, 0x1294062e,\n\t0x2899e64a, 0x317900d6, 0x317900d6, 0x2899e64a, 0x3c424209, 0x158f9a75, 0x20e70f32, 0x36e5068a,\n\t0x2d413ccc, 0x2d413ccc, 0x3b20d79e, 0x187de2a6, 0x187de2a6, 0x3b20d79e, 0x2899e64a, 0x317900d6,\n\t0x39daf5e8, 0x1b5d1009, 0x0f8cfcbd, 0x3e14fdf7, 0x238e7673, 0x3536cc52, 0x387165e3, 0x1e2b5d38,\n\t0x0645e9af, 0x3fb11b47, 0x1e2b5d38, 0x387165e3, 0x36e5068a, 0x20e70f32, 0xfcdc1342, 0x3fec43c6,\n\t0x187de2a6, 0x3b20d79e, 0x3536cc52, 0x238e7673, 0xf383a3e2, 0x3ec52f9f, 0x1294062e, 0x3d3e82ad,\n\t0x3367c08f, 0x261feff9, 0xea70658b, 0x3c424209, 0x0c7c5c1e, 0x3ec52f9f, 0x317900d6, 0x2899e64a,\n\t0xe1d4a2c8, 0x387165e3, 0x0645e9af, 0x3fb11b47, 0x2f6bbe44, 0x2afad269, 0xd9e01007, 0x3367c08f,\n\t0x00000000, 0x40000000, 0x2d413ccc, 0x2d413ccc, 0xd2bec334, 0x2d413ccc, 0xf9ba1651, 0x3fb11b47,\n\t0x2afad269, 0x2f6bbe44, 0xcc983f71, 0x261feff9, 0xf383a3e2, 0x3ec52f9f, 0x2899e64a, 0x317900d6,\n\t0xc78e9a1d, 0x1e2b5d38, 0xed6bf9d2, 0x3d3e82ad, 0x261feff9, 0x3367c08f, 0xc3bdbdf7, 0x158f9a75,\n\t0xe7821d5a, 0x3b20d79e, 0x238e7673, 0x3536cc52, 0xc13ad061, 0x0c7c5c1e, 0xe1d4a2c8, 0x387165e3,\n\t0x20e70f32, 0x36e5068a, 0xc013bc3a, 0x0323ecbe, 0xdc71898d, 0x3536cc52, 0x1e2b5d38, 0x387165e3,\n\t0xc04ee4b9, 0xf9ba1651, 0xd76619b6, 0x317900d6, 0x1b5d1009, 0x39daf5e8, 0xc1eb0209, 0xf0730343,\n\t0xd2bec334, 0x2d413ccc, 0x187de2a6, 0x3b20d79e, 0xc4df2862, 0xe7821d5a, 0xce86ff2a, 0x2899e64a,\n\t0x158f9a75, 0x3c424209, 0xc91af976, 0xdf18f0ce, 0xcac933ae, 0x238e7673, 0x1294062e, 0x3d3e82ad,\n\t0xce86ff2a, 0xd76619b6, 0xc78e9a1d, 0x1e2b5d38, 0x0f8cfcbd, 0x3e14fdf7, 0xd5052d97, 0xd09441bc,\n\t0xc4df2862, 0x187de2a6, 0x0c7c5c1e, 0x3ec52f9f, 0xdc71898d, 0xcac933ae, 0xc2c17d53, 0x1294062e,\n\t0x09640837, 0x3f4eaafe, 0xe4a2eff7, 0xc6250a18, 0xc13ad061, 0x0c7c5c1e, 0x0645e9af, 0x3fb11b47,\n\t0xed6bf9d2, 0xc2c17d53, 0xc04ee4b9, 0x0645e9af, 0x0323ecbe, 0x3fec43c6, 0xf69bf7c9, 0xc0b15502,\n\n\t0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x3ffb10c1, 0x0192155f,\n\t0x3ffec42d, 0x00c90e8f, 0x3ff4e5df, 0x025b0cae, 0x3fec43c6, 0x0323ecbe, 0x3ffb10c1, 0x0192155f,\n\t0x3fd39b5a, 0x04b54824, 0x3fd39b5a, 0x04b54824, 0x3ff4e5df, 0x025b0cae, 0x3f9c2bfa, 0x070de171,\n\t0x3fb11b47, 0x0645e9af, 0x3fec43c6, 0x0323ecbe, 0x3f4eaafe, 0x09640837, 0x3f84c8e1, 0x07d59395,\n\t0x3fe12acb, 0x03ecadcf, 0x3eeb3347, 0x0bb6ecef, 0x3f4eaafe, 0x09640837, 0x3fd39b5a, 0x04b54824,\n\t0x3e71e758, 0x0e05c135, 0x3f0ec9f4, 0x0af10a22, 0x3fc395f9, 0x057db402, 0x3de2f147, 0x104fb80e,\n\t0x3ec52f9f, 0x0c7c5c1e, 0x3fb11b47, 0x0645e9af, 0x3d3e82ad, 0x1294062e, 0x3e71e758, 0x0e05c135,\n\t0x3f9c2bfa, 0x070de171, 0x3c84d496, 0x14d1e242, 0x3e14fdf7, 0x0f8cfcbd, 0x3f84c8e1, 0x07d59395,\n\t0x3bb6276d, 0x17088530, 0x3dae81ce, 0x1111d262, 0x3f6af2e3, 0x089cf867, 0x3ad2c2e7, 0x19372a63,\n\t0x3d3e82ad, 0x1294062e, 0x3f4eaafe, 0x09640837, 0x39daf5e8, 0x1b5d1009, 0x3cc511d8, 0x14135c94,\n\t0x3f2ff249, 0x0a2abb58, 0x38cf1669, 0x1d79775b, 0x3c424209, 0x158f9a75, 0x3f0ec9f4, 0x0af10a22,\n\t0x37af8158, 0x1f8ba4db, 0x3bb6276d, 0x17088530, 0x3eeb3347, 0x0bb6ecef, 0x367c9a7d, 0x2192e09a,\n\t0x3b20d79e, 0x187de2a6, 0x3ec52f9f, 0x0c7c5c1e, 0x3536cc52, 0x238e7673, 0x3a8269a2, 0x19ef7943,\n\t0x3e9cc076, 0x0d415012, 0x33de87de, 0x257db64b, 0x39daf5e8, 0x1b5d1009, 0x3e71e758, 0x0e05c135,\n\t0x32744493, 0x275ff452, 0x392a9642, 0x1cc66e99, 0x3e44a5ee, 0x0ec9a7f2, 0x30f8801f, 0x29348937,\n\t0x387165e3, 0x1e2b5d38, 0x3e14fdf7, 0x0f8cfcbd, 0x2f6bbe44, 0x2afad269, 0x37af8158, 0x1f8ba4db,\n\t0x3de2f147, 0x104fb80e, 0x2dce88a9, 0x2cb2324b, 0x36e5068a, 0x20e70f32, 0x3dae81ce, 0x1111d262,\n\t0x2c216eaa, 0x2e5a106f, 0x361214b0, 0x223d66a8, 0x3d77b191, 0x11d3443f, 0x2a650525, 0x2ff1d9c6,\n\t0x3536cc52, 0x238e7673, 0x3d3e82ad, 0x1294062e, 0x2899e64a, 0x317900d6, 0x34534f40, 0x24da0a99,\n\t0x3d02f756, 0x135410c2, 0x26c0b162, 0x32eefde9, 0x3367c08f, 0x261feff9, 0x3cc511d8, 0x14135c94,\n\t0x24da0a99, 0x34534f40, 0x32744493, 0x275ff452, 0x3c84d496, 0x14d1e242, 0x22e69ac7, 0x35a5793c,\n\t0x317900d6, 0x2899e64a, 0x3c424209, 0x158f9a75, 0x20e70f32, 0x36e5068a, 0x30761c17, 0x29cd9577,\n\t0x3bfd5cc4, 0x164c7ddd, 0x1edc1952, 0x3811884c, 0x2f6bbe44, 0x2afad269, 0x3bb6276d, 0x17088530,\n\t0x1cc66e99, 0x392a9642, 0x2e5a106f, 0x2c216eaa, 0x3b6ca4c4, 0x17c3a931, 0x1aa6c82b, 0x3a2fcee8,\n\t0x2d413ccc, 0x2d413ccc, 0x3b20d79e, 0x187de2a6, 0x187de2a6, 0x3b20d79e, 0x2c216eaa, 0x2e5a106f,\n\t0x3ad2c2e7, 0x19372a63, 0x164c7ddd, 0x3bfd5cc4, 0x2afad269, 0x2f6bbe44, 0x3a8269a2, 0x19ef7943,\n\t0x14135c94, 0x3cc511d8, 0x29cd9577, 0x30761c17, 0x3a2fcee8, 0x1aa6c82b, 0x11d3443f, 0x3d77b191,\n\t0x2899e64a, 0x317900d6, 0x39daf5e8, 0x1b5d1009, 0x0f8cfcbd, 0x3e14fdf7, 0x275ff452, 0x32744493,\n\t0x3983e1e7, 0x1c1249d8, 0x0d415012, 0x3e9cc076, 0x261feff9, 0x3367c08f, 0x392a9642, 0x1cc66e99,\n\t0x0af10a22, 0x3f0ec9f4, 0x24da0a99, 0x34534f40, 0x38cf1669, 0x1d79775b, 0x089cf867, 0x3f6af2e3,\n\t0x238e7673, 0x3536cc52, 0x387165e3, 0x1e2b5d38, 0x0645e9af, 0x3fb11b47, 0x223d66a8, 0x361214b0,\n\t0x3811884c, 0x1edc1952, 0x03ecadcf, 0x3fe12acb, 0x20e70f32, 0x36e5068a, 0x37af8158, 0x1f8ba4db,\n\t0x0192155f, 0x3ffb10c1, 0x1f8ba4db, 0x37af8158, 0x374b54ce, 0x2039f90e, 0xff36f171, 0x3ffec42d,\n\t0x1e2b5d38, 0x387165e3, 0x36e5068a, 0x20e70f32, 0xfcdc1342, 0x3fec43c6, 0x1cc66e99, 0x392a9642,\n\t0x367c9a7d, 0x2192e09a, 0xfa824bfe, 0x3fc395f9, 0x1b5d1009, 0x39daf5e8, 0x361214b0, 0x223d66a8,\n\t0xf82a6c6b, 0x3f84c8e1, 0x19ef7943, 0x3a8269a2, 0x35a5793c, 0x22e69ac7, 0xf5d544a8, 0x3f2ff249,\n\t0x187de2a6, 0x3b20d79e, 0x3536cc52, 0x238e7673, 0xf383a3e2, 0x3ec52f9f, 0x17088530, 0x3bb6276d,\n\t0x34c61236, 0x2434f332, 0xf136580e, 0x3e44a5ee, 0x158f9a75, 0x3c424209, 0x34534f40, 0x24da0a99,\n\t0xeeee2d9e, 0x3dae81ce, 0x14135c94, 0x3cc511d8, 0x33de87de, 0x257db64b, 0xecabef3e, 0x3d02f756,\n\t0x1294062e, 0x3d3e82ad, 0x3367c08f, 0x261feff9, 0xea70658b, 0x3c424209, 0x1111d262, 0x3dae81ce,\n\t0x32eefde9, 0x26c0b162, 0xe83c56cf, 0x3b6ca4c4, 0x0f8cfcbd, 0x3e14fdf7, 0x32744493, 0x275ff452,\n\t0xe61086bd, 0x3a8269a2, 0x0e05c135, 0x3e71e758, 0x31f79947, 0x27fdb2a6, 0xe3edb628, 0x3983e1e7,\n\t0x0c7c5c1e, 0x3ec52f9f, 0x317900d6, 0x2899e64a, 0xe1d4a2c8, 0x387165e3, 0x0af10a22, 0x3f0ec9f4,\n\t0x30f8801f, 0x29348937, 0xdfc606f2, 0x374b54ce, 0x09640837, 0x3f4eaafe, 0x30761c17, 0x29cd9577,\n\t0xddc29958, 0x361214b0, 0x07d59395, 0x3f84c8e1, 0x2ff1d9c6, 0x2a650525, 0xdbcb0cce, 0x34c61236,\n\t0x0645e9af, 0x3fb11b47, 0x2f6bbe44, 0x2afad269, 0xd9e01007, 0x3367c08f, 0x04b54824, 0x3fd39b5a,\n\t0x2ee3cebe, 0x2b8ef77c, 0xd8024d5a, 0x31f79947, 0x0323ecbe, 0x3fec43c6, 0x2e5a106f, 0x2c216eaa,\n\t0xd6326a89, 0x30761c17, 0x0192155f, 0x3ffb10c1, 0x2dce88a9, 0x2cb2324b, 0xd4710884, 0x2ee3cebe,\n\t0x00000000, 0x40000000, 0x2d413ccc, 0x2d413ccc, 0xd2bec334, 0x2d413ccc, 0xfe6deaa1, 0x3ffb10c1,\n\t0x2cb2324b, 0x2dce88a9, 0xd11c3142, 0x2b8ef77c, 0xfcdc1342, 0x3fec43c6, 0x2c216eaa, 0x2e5a106f,\n\t0xcf89e3e9, 0x29cd9577, 0xfb4ab7dc, 0x3fd39b5a, 0x2b8ef77c, 0x2ee3cebe, 0xce0866b9, 0x27fdb2a6,\n\t0xf9ba1651, 0x3fb11b47, 0x2afad269, 0x2f6bbe44, 0xcc983f71, 0x261feff9, 0xf82a6c6b, 0x3f84c8e1,\n\t0x2a650525, 0x2ff1d9c6, 0xcb39edca, 0x2434f332, 0xf69bf7c9, 0x3f4eaafe, 0x29cd9577, 0x30761c17,\n\t0xc9edeb50, 0x223d66a8, 0xf50ef5de, 0x3f0ec9f4, 0x29348937, 0x30f8801f, 0xc8b4ab32, 0x2039f90e,\n\t0xf383a3e2, 0x3ec52f9f, 0x2899e64a, 0x317900d6, 0xc78e9a1d, 0x1e2b5d38, 0xf1fa3ecb, 0x3e71e758,\n\t0x27fdb2a6, 0x31f79947, 0xc67c1e19, 0x1c1249d8, 0xf0730343, 0x3e14fdf7, 0x275ff452, 0x32744493,\n\t0xc57d965e, 0x19ef7943, 0xeeee2d9e, 0x3dae81ce, 0x26c0b162, 0x32eefde9, 0xc4935b3c, 0x17c3a931,\n\t0xed6bf9d2, 0x3d3e82ad, 0x261feff9, 0x3367c08f, 0xc3bdbdf7, 0x158f9a75, 0xebeca36c, 0x3cc511d8,\n\t0x257db64b, 0x33de87de, 0xc2fd08aa, 0x135410c2, 0xea70658b, 0x3c424209, 0x24da0a99, 0x34534f40,\n\t0xc2517e32, 0x1111d262, 0xe8f77ad0, 0x3bb6276d, 0x2434f332, 0x34c61236, 0xc1bb5a12, 0x0ec9a7f2,\n\t0xe7821d5a, 0x3b20d79e, 0x238e7673, 0x3536cc52, 0xc13ad061, 0x0c7c5c1e, 0xe61086bd, 0x3a8269a2,\n\t0x22e69ac7, 0x35a5793c, 0xc0d00db7, 0x0a2abb58, 0xe4a2eff7, 0x39daf5e8, 0x223d66a8, 0x361214b0,\n\t0xc07b371f, 0x07d59395, 0xe3399167, 0x392a9642, 0x2192e09a, 0x367c9a7d, 0xc03c6a07, 0x057db402,\n\t0xe1d4a2c8, 0x387165e3, 0x20e70f32, 0x36e5068a, 0xc013bc3a, 0x0323ecbe, 0xe0745b25, 0x37af8158,\n\t0x2039f90e, 0x374b54ce, 0xc0013bd3, 0x00c90e8f, 0xdf18f0ce, 0x36e5068a, 0x1f8ba4db, 0x37af8158,\n\t0xc004ef3f, 0xfe6deaa1, 0xddc29958, 0x361214b0, 0x1edc1952, 0x3811884c, 0xc01ed535, 0xfc135231,\n\t0xdc71898d, 0x3536cc52, 0x1e2b5d38, 0x387165e3, 0xc04ee4b9, 0xf9ba1651, 0xdb25f567, 0x34534f40,\n\t0x1d79775b, 0x38cf1669, 0xc0950d1d, 0xf7630799, 0xd9e01007, 0x3367c08f, 0x1cc66e99, 0x392a9642,\n\t0xc0f1360c, 0xf50ef5de, 0xd8a00bae, 0x32744493, 0x1c1249d8, 0x3983e1e7, 0xc1633f8a, 0xf2beafee,\n\t0xd76619b6, 0x317900d6, 0x1b5d1009, 0x39daf5e8, 0xc1eb0209, 0xf0730343, 0xd6326a89, 0x30761c17,\n\t0x1aa6c82b, 0x3a2fcee8, 0xc2884e6f, 0xee2cbbc1, 0xd5052d97, 0x2f6bbe44, 0x19ef7943, 0x3a8269a2,\n\t0xc33aee28, 0xebeca36c, 0xd3de9156, 0x2e5a106f, 0x19372a63, 0x3ad2c2e7, 0xc402a33c, 0xe9b38223,\n\t0xd2bec334, 0x2d413ccc, 0x187de2a6, 0x3b20d79e, 0xc4df2862, 0xe7821d5a, 0xd1a5ef91, 0x2c216eaa,\n\t0x17c3a931, 0x3b6ca4c4, 0xc5d03118, 0xe55937d5, 0xd09441bc, 0x2afad269, 0x17088530, 0x3bb6276d,\n\t0xc6d569be, 0xe3399167, 0xcf89e3e9, 0x29cd9577, 0x164c7ddd, 0x3bfd5cc4, 0xc7ee77b4, 0xe123e6ae,\n\t0xce86ff2a, 0x2899e64a, 0x158f9a75, 0x3c424209, 0xc91af976, 0xdf18f0ce, 0xcd8bbb6d, 0x275ff452,\n\t0x14d1e242, 0x3c84d496, 0xca5a86c4, 0xdd196539, 0xcc983f71, 0x261feff9, 0x14135c94, 0x3cc511d8,\n\t0xcbacb0c0, 0xdb25f567, 0xcbacb0c0, 0x24da0a99, 0x135410c2, 0x3d02f756, 0xcd110217, 0xd93f4e9e,\n\t0xcac933ae, 0x238e7673, 0x1294062e, 0x3d3e82ad, 0xce86ff2a, 0xd76619b6, 0xc9edeb50, 0x223d66a8,\n\t0x11d3443f, 0x3d77b191, 0xd00e263a, 0xd59afadb, 0xc91af976, 0x20e70f32, 0x1111d262, 0x3dae81ce,\n\t0xd1a5ef91, 0xd3de9156, 0xc8507ea8, 0x1f8ba4db, 0x104fb80e, 0x3de2f147, 0xd34dcdb5, 0xd2317757,\n\t0xc78e9a1d, 0x1e2b5d38, 0x0f8cfcbd, 0x3e14fdf7, 0xd5052d97, 0xd09441bc, 0xc6d569be, 0x1cc66e99,\n\t0x0ec9a7f2, 0x3e44a5ee, 0xd6cb76c9, 0xcf077fe1, 0xc6250a18, 0x1b5d1009, 0x0e05c135, 0x3e71e758,\n\t0xd8a00bae, 0xcd8bbb6d, 0xc57d965e, 0x19ef7943, 0x0d415012, 0x3e9cc076, 0xda8249b5, 0xcc217822,\n\t0xc4df2862, 0x187de2a6, 0x0c7c5c1e, 0x3ec52f9f, 0xdc71898d, 0xcac933ae, 0xc449d893, 0x17088530,\n\t0x0bb6ecef, 0x3eeb3347, 0xde6d1f66, 0xc9836583, 0xc3bdbdf7, 0x158f9a75, 0x0af10a22, 0x3f0ec9f4,\n\t0xe0745b25, 0xc8507ea8, 0xc33aee28, 0x14135c94, 0x0a2abb58, 0x3f2ff249, 0xe28688a5, 0xc730e997,\n\t0xc2c17d53, 0x1294062e, 0x09640837, 0x3f4eaafe, 0xe4a2eff7, 0xc6250a18, 0xc2517e32, 0x1111d262,\n\t0x089cf867, 0x3f6af2e3, 0xe6c8d59d, 0xc52d3d19, 0xc1eb0209, 0x0f8cfcbd, 0x07d59395, 0x3f84c8e1,\n\t0xe8f77ad0, 0xc449d893, 0xc18e18a8, 0x0e05c135, 0x070de171, 0x3f9c2bfa, 0xeb2e1dbe, 0xc37b2b6a,\n\t0xc13ad061, 0x0c7c5c1e, 0x0645e9af, 0x3fb11b47, 0xed6bf9d2, 0xc2c17d53, 0xc0f1360c, 0x0af10a22,\n\t0x057db402, 0x3fc395f9, 0xefb047f2, 0xc21d0eb9, 0xc0b15502, 0x09640837, 0x04b54824, 0x3fd39b5a,\n\t0xf1fa3ecb, 0xc18e18a8, 0xc07b371f, 0x07d59395, 0x03ecadcf, 0x3fe12acb, 0xf4491311, 0xc114ccb9,\n\t0xc04ee4b9, 0x0645e9af, 0x0323ecbe, 0x3fec43c6, 0xf69bf7c9, 0xc0b15502, 0xc02c64a6, 0x04b54824,\n\t0x025b0cae, 0x3ff4e5df, 0xf8f21e8f, 0xc063d406, 0xc013bc3a, 0x0323ecbe, 0x0192155f, 0x3ffb10c1,\n\t0xfb4ab7dc, 0xc02c64a6, 0xc004ef3f, 0x0192155f, 0x00c90e8f, 0x3ffec42d, 0xfda4f352, 0xc00b1a21\n};\n\nconst int twidTab64[4*6 + 16*6] = {\n\t0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x2d413ccc, 0x2d413ccc,\n\t0x3b20d79e, 0x187de2a6, 0x187de2a6, 0x3b20d79e, 0x00000000, 0x40000000, 0x2d413ccc, 0x2d413ccc,\n\t0xd2bec334, 0x2d413ccc, 0xd2bec334, 0x2d413ccc, 0x187de2a6, 0x3b20d79e, 0xc4df2862, 0xe7821d5a,\n\n\t0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x3ec52f9f, 0x0c7c5c1e,\n\t0x3fb11b47, 0x0645e9af, 0x3d3e82ad, 0x1294062e, 0x3b20d79e, 0x187de2a6, 0x3ec52f9f, 0x0c7c5c1e,\n\t0x3536cc52, 0x238e7673, 0x3536cc52, 0x238e7673, 0x3d3e82ad, 0x1294062e, 0x2899e64a, 0x317900d6,\n\t0x2d413ccc, 0x2d413ccc, 0x3b20d79e, 0x187de2a6, 0x187de2a6, 0x3b20d79e, 0x238e7673, 0x3536cc52,\n\t0x387165e3, 0x1e2b5d38, 0x0645e9af, 0x3fb11b47, 0x187de2a6, 0x3b20d79e, 0x3536cc52, 0x238e7673,\n\t0xf383a3e2, 0x3ec52f9f, 0x0c7c5c1e, 0x3ec52f9f, 0x317900d6, 0x2899e64a, 0xe1d4a2c8, 0x387165e3,\n\t0x00000000, 0x40000000, 0x2d413ccc, 0x2d413ccc, 0xd2bec334, 0x2d413ccc, 0xf383a3e2, 0x3ec52f9f,\n\t0x2899e64a, 0x317900d6, 0xc78e9a1d, 0x1e2b5d38, 0xe7821d5a, 0x3b20d79e, 0x238e7673, 0x3536cc52,\n\t0xc13ad061, 0x0c7c5c1e, 0xdc71898d, 0x3536cc52, 0x1e2b5d38, 0x387165e3, 0xc04ee4b9, 0xf9ba1651,\n\t0xd2bec334, 0x2d413ccc, 0x187de2a6, 0x3b20d79e, 0xc4df2862, 0xe7821d5a, 0xcac933ae, 0x238e7673,\n\t0x1294062e, 0x3d3e82ad, 0xce86ff2a, 0xd76619b6, 0xc4df2862, 0x187de2a6, 0x0c7c5c1e, 0x3ec52f9f,\n\t0xdc71898d, 0xcac933ae, 0xc13ad061, 0x0c7c5c1e, 0x0645e9af, 0x3fb11b47, 0xed6bf9d2, 0xc2c17d53\n};\n#endif  //ARMV5E\n\nconst int ShortWindowSine[FRAME_LEN_SHORT/2] ={\n\t0x00c97fff, 0x025b7ffa, 0x03ed7ff1, 0x057f7fe2, 0x07117fce, 0x08a27fb5, 0x0a337f98, 0x0bc47f75,\n\t0x0d547f4e, 0x0ee47f22, 0x10737ef0, 0x12017eba, 0x138f7e7f, 0x151c7e3f, 0x16a87dfb, 0x18337db1,\n\t0x19be7d63, 0x1b477d0f, 0x1cd07cb7, 0x1e577c5a, 0x1fdd7bf9, 0x21627b92, 0x22e57b27, 0x24677ab7,\n\t0x25e87a42, 0x276879c9, 0x28e5794a, 0x2a6278c8, 0x2bdc7840, 0x2d5577b4, 0x2ecc7723, 0x3042768e,\n\t0x31b575f4, 0x33277556, 0x349774b3, 0x3604740b, 0x3770735f, 0x38d972af, 0x3a4071fa, 0x3ba57141,\n\t0x3d087083, 0x3e686fc2, 0x3fc66efb, 0x41216e31, 0x427a6d62, 0x43d16c8f, 0x45246bb8, 0x46756add,\n\t0x47c469fd, 0x490f691a, 0x4a586832, 0x4b9e6747, 0x4ce16657, 0x4e216564, 0x4f5e646c, 0x50986371,\n\t0x51cf6272, 0x5303616f, 0x54336068, 0x55605f5e, 0x568a5e50, 0x57b15d3e, 0x58d45c29, 0x59f45b10\n};\n\nconst int LongWindowKBD[FRAME_LEN_LONG/2]={\n\t0x000a7fff, 0x000e7fff, 0x00127fff, 0x00157fff, 0x00197fff, 0x001c7fff, 0x00207fff, 0x00237fff,\n\t0x00267fff, 0x002a7fff, 0x002d7fff, 0x00307fff, 0x00347fff, 0x00387fff, 0x003b7fff, 0x003f7fff,\n\t0x00437fff, 0x00477fff, 0x004b7fff, 0x004f7fff, 0x00537fff, 0x00577fff, 0x005b7fff, 0x00607fff,\n\t0x00647fff, 0x00697fff, 0x006d7fff, 0x00727fff, 0x00777fff, 0x007c7fff, 0x00817fff, 0x00867fff,\n\t0x008b7fff, 0x00917fff, 0x00967fff, 0x009c7fff, 0x00a17fff, 0x00a77fff, 0x00ad7fff, 0x00b37fff,\n\t0x00b97fff, 0x00bf7fff, 0x00c67fff, 0x00cc7fff, 0x00d37fff, 0x00da7fff, 0x00e07fff, 0x00e77fff,\n\t0x00ee7fff, 0x00f57fff, 0x00fd7fff, 0x01047fff, 0x010c7fff, 0x01137fff, 0x011b7fff, 0x01237fff,\n\t0x012b7fff, 0x01337fff, 0x013c7ffe, 0x01447ffe, 0x014d7ffe, 0x01567ffe, 0x015f7ffe, 0x01687ffe,\n\t0x01717ffe, 0x017a7ffe, 0x01837ffe, 0x018d7ffe, 0x01977ffd, 0x01a17ffd, 0x01ab7ffd, 0x01b57ffd,\n\t0x01bf7ffd, 0x01ca7ffd, 0x01d47ffd, 0x01df7ffc, 0x01ea7ffc, 0x01f57ffc, 0x02007ffc, 0x020c7ffc,\n\t0x02177ffc, 0x02237ffb, 0x022f7ffb, 0x023b7ffb, 0x02477ffb, 0x02537ffb, 0x02607ffa, 0x026d7ffa,\n\t0x027a7ffa, 0x02877ffa, 0x02947ff9, 0x02a17ff9, 0x02af7ff9, 0x02bc7ff9, 0x02ca7ff8, 0x02d87ff8,\n\t0x02e77ff8, 0x02f57ff7, 0x03047ff7, 0x03127ff7, 0x03217ff6, 0x03317ff6, 0x03407ff5, 0x034f7ff5,\n\t0x035f7ff5, 0x036f7ff4, 0x037f7ff4, 0x038f7ff3, 0x03a07ff3, 0x03b07ff2, 0x03c17ff2, 0x03d27ff1,\n\t0x03e37ff1, 0x03f57ff0, 0x04067ff0, 0x04187fef, 0x042a7fef, 0x043c7fee, 0x044f7fed, 0x04617fed,\n\t0x04747fec, 0x04877feb, 0x049a7feb, 0x04ae7fea, 0x04c17fe9, 0x04d57fe9, 0x04e97fe8, 0x04fd7fe7,\n\t0x05127fe6, 0x05277fe5, 0x053b7fe5, 0x05507fe4, 0x05667fe3, 0x057b7fe2, 0x05917fe1, 0x05a77fe0,\n\t0x05bd7fdf, 0x05d37fde, 0x05ea7fdd, 0x06017fdc, 0x06187fdb, 0x062f7fda, 0x06467fd9, 0x065e7fd7,\n\t0x06767fd6, 0x068e7fd5, 0x06a67fd4, 0x06bf7fd2, 0x06d87fd1, 0x06f17fd0, 0x070a7fce, 0x07237fcd,\n\t0x073d7fcc, 0x07577fca, 0x07717fc9, 0x078c7fc7, 0x07a67fc5, 0x07c17fc4, 0x07dc7fc2, 0x07f77fc0,\n\t0x08137fbf, 0x082f7fbd, 0x084b7fbb, 0x08677fb9, 0x08847fb7, 0x08a07fb6, 0x08bd7fb4, 0x08da7fb2,\n\t0x08f87faf, 0x09167fad, 0x09347fab, 0x09527fa9, 0x09707fa7, 0x098f7fa5, 0x09ae7fa2, 0x09cd7fa0,\n\t0x09ec7f9d, 0x0a0c7f9b, 0x0a2c7f98, 0x0a4c7f96, 0x0a6c7f93, 0x0a8d7f91, 0x0aae7f8e, 0x0acf7f8b,\n\t0x0af07f88, 0x0b127f85, 0x0b337f82, 0x0b557f7f, 0x0b787f7c, 0x0b9a7f79, 0x0bbd7f76, 0x0be07f73,\n\t0x0c047f6f, 0x0c277f6c, 0x0c4b7f69, 0x0c6f7f65, 0x0c937f61, 0x0cb87f5e, 0x0cdd7f5a, 0x0d027f56,\n\t0x0d277f53, 0x0d4d7f4f, 0x0d737f4b, 0x0d997f47, 0x0dbf7f43, 0x0de67f3e, 0x0e0c7f3a, 0x0e347f36,\n\t0x0e5b7f31, 0x0e837f2d, 0x0eaa7f28, 0x0ed37f24, 0x0efb7f1f, 0x0f237f1a, 0x0f4c7f15, 0x0f757f10,\n\t0x0f9f7f0b, 0x0fc87f06, 0x0ff27f01, 0x101c7efb, 0x10477ef6, 0x10717ef0, 0x109c7eeb, 0x10c87ee5,\n\t0x10f37edf, 0x111f7eda, 0x114a7ed4, 0x11777ece, 0x11a37ec7, 0x11d07ec1, 0x11fd7ebb, 0x122a7eb4,\n\t0x12577eae, 0x12857ea7, 0x12b37ea0, 0x12e17e9a, 0x130f7e93, 0x133e7e8c, 0x136d7e84, 0x139c7e7d,\n\t0x13cc7e76, 0x13fb7e6e, 0x142b7e67, 0x145b7e5f, 0x148c7e57, 0x14bc7e4f, 0x14ed7e47, 0x151e7e3f,\n\t0x15507e37, 0x15817e2e, 0x15b37e26, 0x15e57e1d, 0x16187e14, 0x164a7e0b, 0x167d7e02, 0x16b07df9,\n\t0x16e47df0, 0x17177de6, 0x174b7ddd, 0x177f7dd3, 0x17b37dc9, 0x17e87dbf, 0x181d7db5, 0x18527dab,\n\t0x18877da1, 0x18bc7d96, 0x18f27d8c, 0x19287d81, 0x195e7d76, 0x19957d6b, 0x19cb7d60, 0x1a027d54,\n\t0x1a397d49, 0x1a717d3d, 0x1aa87d31, 0x1ae07d26, 0x1b187d19, 0x1b507d0d, 0x1b897d01, 0x1bc27cf4,\n\t0x1bfb7ce8, 0x1c347cdb, 0x1c6d7cce, 0x1ca77cc1, 0x1ce17cb3, 0x1d1b7ca6, 0x1d557c98, 0x1d8f7c8a,\n\t0x1dca7c7c, 0x1e057c6e, 0x1e407c60, 0x1e7b7c51, 0x1eb77c43, 0x1ef37c34, 0x1f2f7c25, 0x1f6b7c16,\n\t0x1fa77c06, 0x1fe47bf7, 0x20217be7, 0x205e7bd7, 0x209b7bc7, 0x20d87bb7, 0x21167ba6, 0x21547b96,\n\t0x21927b85, 0x21d07b74, 0x220e7b63, 0x224d7b52, 0x228c7b40, 0x22cb7b2e, 0x230a7b1c, 0x23497b0a,\n\t0x23897af8, 0x23c87ae6, 0x24087ad3, 0x24487ac0, 0x24897aad, 0x24c97a9a, 0x250a7a86, 0x254b7a73,\n\t0x258c7a5f, 0x25cd7a4b, 0x260e7a36, 0x26507a22, 0x26917a0d, 0x26d379f8, 0x271579e3, 0x275779ce,\n\t0x279a79b8, 0x27dc79a3, 0x281f798d, 0x28627977, 0x28a57960, 0x28e8794a, 0x292b7933, 0x296f791c,\n\t0x29b27905, 0x29f678ed, 0x2a3a78d6, 0x2a7e78be, 0x2ac278a6, 0x2b07788d, 0x2b4b7875, 0x2b90785c,\n\t0x2bd47843, 0x2c19782a, 0x2c5e7810, 0x2ca477f7, 0x2ce977dd, 0x2d2e77c3, 0x2d7477a8, 0x2dba778e,\n\t0x2dff7773, 0x2e457758, 0x2e8b773d, 0x2ed27721, 0x2f187706, 0x2f5e76ea, 0x2fa576cd, 0x2fec76b1,\n\t0x30327694, 0x30797677, 0x30c0765a, 0x3107763d, 0x314e761f, 0x31967601, 0x31dd75e3, 0x322575c5,\n\t0x326c75a6, 0x32b47588, 0x32fc7569, 0x33447549, 0x338c752a, 0x33d4750a, 0x341c74ea, 0x346474ca,\n\t0x34ac74a9, 0x34f57488, 0x353d7467, 0x35857446, 0x35ce7424, 0x36177403, 0x365f73e1, 0x36a873be,\n\t0x36f1739c, 0x373a7379, 0x37837356, 0x37cc7333, 0x3815730f, 0x385e72ec, 0x38a772c8, 0x38f172a3,\n\t0x393a727f, 0x3983725a, 0x39cd7235, 0x3a167210, 0x3a6071ea, 0x3aa971c4, 0x3af3719e, 0x3b3c7178,\n\t0x3b867151, 0x3bd0712b, 0x3c197104, 0x3c6370dc, 0x3cad70b5, 0x3cf7708d, 0x3d407065, 0x3d8a703c,\n\t0x3dd47014, 0x3e1e6feb, 0x3e686fc2, 0x3eb16f98, 0x3efb6f6f, 0x3f456f45, 0x3f8f6f1b, 0x3fd96ef0,\n\t0x40236ec6, 0x406d6e9b, 0x40b66e70, 0x41006e44, 0x414a6e19, 0x41946ded, 0x41de6dc1, 0x42286d94,\n\t0x42716d68, 0x42bb6d3b, 0x43056d0d, 0x434f6ce0, 0x43986cb2, 0x43e26c84, 0x442c6c56, 0x44756c28,\n\t0x44bf6bf9, 0x45086bca, 0x45526b9b, 0x459b6b6b, 0x45e56b3c, 0x462e6b0c, 0x46786adb, 0x46c16aab,\n\t0x470a6a7a, 0x47536a49, 0x479c6a18, 0x47e569e7, 0x482e69b5, 0x48776983, 0x48c06951, 0x4909691e,\n\t0x495268ec, 0x499b68b9, 0x49e36885, 0x4a2c6852, 0x4a74681e, 0x4abd67ea, 0x4b0567b6, 0x4b4d6782,\n\t0x4b95674d, 0x4bde6718, 0x4c2666e3, 0x4c6d66ae, 0x4cb56678, 0x4cfd6642, 0x4d45660c, 0x4d8c65d6,\n\t0x4dd4659f, 0x4e1b6568, 0x4e626531, 0x4ea964fa, 0x4ef064c3, 0x4f37648b, 0x4f7e6453, 0x4fc5641b,\n\t0x500b63e2, 0x505263aa, 0x50986371, 0x50df6338, 0x512562fe, 0x516b62c5, 0x51b1628b, 0x51f66251,\n\t0x523c6217, 0x528161dc, 0x52c761a2, 0x530c6167, 0x5351612c, 0x539660f1, 0x53db60b5, 0x54206079,\n\t0x5464603d, 0x54a96001, 0x54ed5fc5, 0x55315f88, 0x55755f4b, 0x55b95f0e, 0x55fc5ed1, 0x56405e94,\n\t0x56835e56, 0x56c75e18, 0x570a5dda, 0x574d5d9c, 0x578f5d5e, 0x57d25d1f, 0x58145ce0, 0x58565ca1,\n\t0x58995c62, 0x58da5c23, 0x591c5be3, 0x595e5ba4, 0x599f5b64, 0x59e05b24, 0x5a215ae3, 0x5a625aa3\n};\n\n\n/*\n  form factor\n*/\n/* sqrt(((i+(1<<(FF_SQRT_BITS-2)+0.5)/2^31) */\nconst Word32 formfac_sqrttable[96] = {\n  0x000407f8, 0x000417b9, 0x0004273f, 0x0004368c, 0x000445a1, 0x00045483, 0x00046332, 0x000471b0,\n  0x00048000, 0x00048e22, 0x00049c1a, 0x0004a9e7, 0x0004b78c, 0x0004c50a, 0x0004d263, 0x0004df96,\n  0x0004eca7, 0x0004f995, 0x00050662, 0x0005130e, 0x00051f9c, 0x00052c0a, 0x0005385b, 0x00054490,\n  0x000550a8, 0x00055ca5, 0x00056888, 0x00057450, 0x00058000, 0x00058b96, 0x00059715, 0x0005a27c,\n  0x0005adcc, 0x0005b906, 0x0005c42b, 0x0005cf39, 0x0005da33, 0x0005e519, 0x0005efea, 0x0005faa8,\n  0x00060552, 0x00060fea, 0x00061a70, 0x000624e3, 0x00062f45, 0x00063996, 0x000643d5, 0x00064e04,\n  0x00065823, 0x00066231, 0x00066c30, 0x0006761f, 0x00068000, 0x000689d1, 0x00069393, 0x00069d47,\n  0x0006a6ed, 0x0006b085, 0x0006ba10, 0x0006c38d, 0x0006ccfc, 0x0006d65f, 0x0006dfb5, 0x0006e8fe,\n  0x0006f23b, 0x0006fb6c, 0x00070490, 0x00070da9, 0x000716b6, 0x00071fb8, 0x000728ae, 0x00073199,\n  0x00073a79, 0x0007434e, 0x00074c19, 0x000754d9, 0x00075d8e, 0x0007663a, 0x00076edb, 0x00077772,\n  0x00078000, 0x00078883, 0x000790fd, 0x0007996e, 0x0007a1d5, 0x0007aa33, 0x0007b288, 0x0007bad4,\n  0x0007c318, 0x0007cb52, 0x0007d384, 0x0007dbad, 0x0007e3ce, 0x0007ebe6, 0x0007f3f6, 0x0007fbfe\n};\n\n\n\n/*!\n  \\name    quantizer and inverse quantizer tables\n\n  \\brief   these tables are used for the non\n           linear quantizer and inverse quantizer\n\n*/\nconst Word32 mTab_3_4[512] = {\n\t0x4c1bf829, 0x4c3880de, 0x4c550603, 0x4c71879c,\n\t0x4c8e05aa, 0x4caa8030, 0x4cc6f72f, 0x4ce36aab,\n\t0x4cffdaa4, 0x4d1c471d, 0x4d38b019, 0x4d55159a,\n\t0x4d7177a1, 0x4d8dd631, 0x4daa314b, 0x4dc688f3,\n\t0x4de2dd2a, 0x4dff2df2, 0x4e1b7b4d, 0x4e37c53d,\n\t0x4e540bc5, 0x4e704ee6, 0x4e8c8ea3, 0x4ea8cafd,\n\t0x4ec503f7, 0x4ee13992, 0x4efd6bd0, 0x4f199ab4,\n\t0x4f35c640, 0x4f51ee75, 0x4f6e1356, 0x4f8a34e4,\n\t0x4fa65321, 0x4fc26e10, 0x4fde85b2, 0x4ffa9a0a,\n\t0x5016ab18, 0x5032b8e0, 0x504ec362, 0x506acaa1,\n\t0x5086cea0, 0x50a2cf5e, 0x50becce0, 0x50dac725,\n\t0x50f6be31, 0x5112b205, 0x512ea2a3, 0x514a900d,\n\t0x51667a45, 0x5182614c, 0x519e4524, 0x51ba25cf,\n\t0x51d60350, 0x51f1dda7, 0x520db4d6, 0x522988e0,\n\t0x524559c6, 0x52612789, 0x527cf22d, 0x5298b9b1,\n\t0x52b47e19, 0x52d03f65, 0x52ebfd98, 0x5307b8b4,\n\t0x532370b9, 0x533f25aa, 0x535ad789, 0x53768656,\n\t0x53923215, 0x53addac6, 0x53c9806b, 0x53e52306,\n\t0x5400c298, 0x541c5f24, 0x5437f8ab, 0x54538f2e,\n\t0x546f22af, 0x548ab330, 0x54a640b3, 0x54c1cb38,\n\t0x54dd52c2, 0x54f8d753, 0x551458eb, 0x552fd78d,\n\t0x554b5339, 0x5566cbf3, 0x558241bb, 0x559db492,\n\t0x55b9247b, 0x55d49177, 0x55effb87, 0x560b62ad,\n\t0x5626c6eb, 0x56422842, 0x565d86b4, 0x5678e242,\n\t0x56943aee, 0x56af90b9, 0x56cae3a4, 0x56e633b2,\n\t0x570180e4, 0x571ccb3b, 0x573812b8, 0x5753575e,\n\t0x576e992e, 0x5789d829, 0x57a51450, 0x57c04da6,\n\t0x57db842b, 0x57f6b7e1, 0x5811e8c9, 0x582d16e6,\n\t0x58484238, 0x58636ac0, 0x587e9081, 0x5899b37c,\n\t0x58b4d3b1, 0x58cff123, 0x58eb0bd3, 0x590623c2,\n\t0x592138f2, 0x593c4b63, 0x59575b19, 0x59726812,\n\t0x598d7253, 0x59a879da, 0x59c37eab, 0x59de80c6,\n\t0x59f9802d, 0x5a147ce0, 0x5a2f76e2, 0x5a4a6e34,\n\t0x5a6562d6, 0x5a8054cb, 0x5a9b4414, 0x5ab630b2,\n\t0x5ad11aa6, 0x5aec01f1, 0x5b06e696, 0x5b21c895,\n\t0x5b3ca7ef, 0x5b5784a6, 0x5b725ebc, 0x5b8d3631,\n\t0x5ba80b06, 0x5bc2dd3e, 0x5bddacd9, 0x5bf879d8,\n\t0x5c13443d, 0x5c2e0c09, 0x5c48d13e, 0x5c6393dc,\n\t0x5c7e53e5, 0x5c99115a, 0x5cb3cc3c, 0x5cce848d,\n\t0x5ce93a4e, 0x5d03ed80, 0x5d1e9e24, 0x5d394c3b,\n\t0x5d53f7c7, 0x5d6ea0c9, 0x5d894742, 0x5da3eb33,\n\t0x5dbe8c9e, 0x5dd92b84, 0x5df3c7e5, 0x5e0e61c3,\n\t0x5e28f920, 0x5e438dfc, 0x5e5e2059, 0x5e78b037,\n\t0x5e933d99, 0x5eadc87e, 0x5ec850e9, 0x5ee2d6da,\n\t0x5efd5a53, 0x5f17db54, 0x5f3259e0, 0x5f4cd5f6,\n\t0x5f674f99, 0x5f81c6c8, 0x5f9c3b87, 0x5fb6add4,\n\t0x5fd11db3, 0x5feb8b23, 0x6005f626, 0x60205ebd,\n\t0x603ac4e9, 0x605528ac, 0x606f8a05, 0x6089e8f7,\n\t0x60a44583, 0x60be9fa9, 0x60d8f76b, 0x60f34cca,\n\t0x610d9fc7, 0x6127f062, 0x61423e9e, 0x615c8a7a,\n\t0x6176d3f9, 0x61911b1b, 0x61ab5fe1, 0x61c5a24d,\n\t0x61dfe25f, 0x61fa2018, 0x62145b7a, 0x622e9485,\n\t0x6248cb3b, 0x6262ff9d, 0x627d31ab, 0x62976167,\n\t0x62b18ed1, 0x62cbb9eb, 0x62e5e2b6, 0x63000933,\n\t0x631a2d62, 0x63344f45, 0x634e6edd, 0x63688c2b,\n\t0x6382a730, 0x639cbfec, 0x63b6d661, 0x63d0ea90,\n\t0x63eafc7a, 0x64050c1f, 0x641f1982, 0x643924a2,\n\t0x64532d80, 0x646d341f, 0x6487387e, 0x64a13a9e,\n\t0x64bb3a81, 0x64d53828, 0x64ef3393, 0x65092cc4,\n\t0x652323bb, 0x653d1879, 0x65570b00, 0x6570fb50,\n\t0x658ae96b, 0x65a4d550, 0x65bebf01, 0x65d8a680,\n\t0x65f28bcc, 0x660c6ee8, 0x66264fd3, 0x66402e8f,\n\t0x665a0b1c, 0x6673e57d, 0x668dbdb0, 0x66a793b8,\n\t0x66c16795, 0x66db3949, 0x66f508d4, 0x670ed636,\n\t0x6728a172, 0x67426a87, 0x675c3177, 0x6775f643,\n\t0x678fb8eb, 0x67a97971, 0x67c337d5, 0x67dcf418,\n\t0x67f6ae3b, 0x6810663f, 0x682a1c25, 0x6843cfed,\n\t0x685d8199, 0x68773129, 0x6890de9f, 0x68aa89fa,\n\t0x68c4333d, 0x68ddda67, 0x68f77f7a, 0x69112277,\n\t0x692ac35e, 0x69446230, 0x695dfeee, 0x6977999a,\n\t0x69913232, 0x69aac8ba, 0x69c45d31, 0x69ddef98,\n\t0x69f77ff0, 0x6a110e3a, 0x6a2a9a77, 0x6a4424a8,\n\t0x6a5daccc, 0x6a7732e6, 0x6a90b6f6, 0x6aaa38fd,\n\t0x6ac3b8fb, 0x6add36f2, 0x6af6b2e2, 0x6b102ccd,\n\t0x6b29a4b2, 0x6b431a92, 0x6b5c8e6f, 0x6b76004a,\n\t0x6b8f7022, 0x6ba8ddf9, 0x6bc249d0, 0x6bdbb3a7,\n\t0x6bf51b80, 0x6c0e815a, 0x6c27e537, 0x6c414718,\n\t0x6c5aa6fd, 0x6c7404e7, 0x6c8d60d7, 0x6ca6bace,\n\t0x6cc012cc, 0x6cd968d2, 0x6cf2bce1, 0x6d0c0ef9,\n\t0x6d255f1d, 0x6d3ead4b, 0x6d57f985, 0x6d7143cc,\n\t0x6d8a8c21, 0x6da3d283, 0x6dbd16f5, 0x6dd65976,\n\t0x6def9a08, 0x6e08d8ab, 0x6e221560, 0x6e3b5027,\n\t0x6e548902, 0x6e6dbff1, 0x6e86f4f5, 0x6ea0280e,\n\t0x6eb9593e, 0x6ed28885, 0x6eebb5e3, 0x6f04e15a,\n\t0x6f1e0aea, 0x6f373294, 0x6f505859, 0x6f697c39,\n\t0x6f829e35, 0x6f9bbe4e, 0x6fb4dc85, 0x6fcdf8d9,\n\t0x6fe7134d, 0x70002be0, 0x70194293, 0x70325767,\n\t0x704b6a5d, 0x70647b76, 0x707d8ab1, 0x70969811,\n\t0x70afa394, 0x70c8ad3d, 0x70e1b50c, 0x70fabb01,\n\t0x7113bf1d, 0x712cc161, 0x7145c1ce, 0x715ec064,\n\t0x7177bd24, 0x7190b80f, 0x71a9b124, 0x71c2a866,\n\t0x71db9dd4, 0x71f49170, 0x720d8339, 0x72267331,\n\t0x723f6159, 0x72584db0, 0x72713838, 0x728a20f1,\n\t0x72a307db, 0x72bbecf9, 0x72d4d049, 0x72edb1ce,\n\t0x73069187, 0x731f6f75, 0x73384b98, 0x735125f3,\n\t0x7369fe84, 0x7382d54d, 0x739baa4e, 0x73b47d89,\n\t0x73cd4efd, 0x73e61eab, 0x73feec94, 0x7417b8b8,\n\t0x74308319, 0x74494bb6, 0x74621291, 0x747ad7aa,\n\t0x74939b02, 0x74ac5c98, 0x74c51c6f, 0x74ddda86,\n\t0x74f696de, 0x750f5178, 0x75280a54, 0x7540c174,\n\t0x755976d7, 0x75722a7e, 0x758adc69, 0x75a38c9b,\n\t0x75bc3b12, 0x75d4e7cf, 0x75ed92d4, 0x76063c21,\n\t0x761ee3b6, 0x76378994, 0x76502dbc, 0x7668d02e,\n\t0x768170eb, 0x769a0ff3, 0x76b2ad47, 0x76cb48e7,\n\t0x76e3e2d5, 0x76fc7b10, 0x7715119a, 0x772da673,\n\t0x7746399b, 0x775ecb13, 0x77775adc, 0x778fe8f6,\n\t0x77a87561, 0x77c1001f, 0x77d98930, 0x77f21095,\n\t0x780a964d, 0x78231a5b, 0x783b9cbd, 0x78541d75,\n\t0x786c9c84, 0x788519e9, 0x789d95a6, 0x78b60fbb,\n\t0x78ce8828, 0x78e6feef, 0x78ff740f, 0x7917e78a,\n\t0x7930595f, 0x7948c990, 0x7961381d, 0x7979a506,\n\t0x7992104c, 0x79aa79f0, 0x79c2e1f1, 0x79db4852,\n\t0x79f3ad11, 0x7a0c1031, 0x7a2471b0, 0x7a3cd191,\n\t0x7a552fd3, 0x7a6d8c76, 0x7a85e77d, 0x7a9e40e6,\n\t0x7ab698b2, 0x7aceeee3, 0x7ae74378, 0x7aff9673,\n\t0x7b17e7d2, 0x7b303799, 0x7b4885c5, 0x7b60d259,\n\t0x7b791d55, 0x7b9166b9, 0x7ba9ae86, 0x7bc1f4bc,\n\t0x7bda395c, 0x7bf27c66, 0x7c0abddb, 0x7c22fdbb,\n\t0x7c3b3c07, 0x7c5378c0, 0x7c6bb3e5, 0x7c83ed78,\n\t0x7c9c2579, 0x7cb45be9, 0x7ccc90c7, 0x7ce4c414,\n\t0x7cfcf5d2, 0x7d152600, 0x7d2d549f, 0x7d4581b0,\n\t0x7d5dad32, 0x7d75d727, 0x7d8dff8f, 0x7da6266a,\n\t0x7dbe4bba, 0x7dd66f7d, 0x7dee91b6, 0x7e06b264,\n\t0x7e1ed188, 0x7e36ef22, 0x7e4f0b34, 0x7e6725bd,\n\t0x7e7f3ebd, 0x7e975636, 0x7eaf6c28, 0x7ec78093,\n\t0x7edf9378, 0x7ef7a4d7, 0x7f0fb4b1, 0x7f27c307,\n\t0x7f3fcfd8, 0x7f57db25, 0x7f6fe4ef, 0x7f87ed36,\n\t0x7f9ff3fb, 0x7fb7f93e, 0x7fcffcff, 0x7fe7ff40\n};\n\nconst Word32 mTab_4_3[512]={\n\t0x32cbfd4a, 0x32eddd70, 0x330fc339, 0x3331aea3,\n\t0x33539fac, 0x33759652, 0x33979294, 0x33b99470,\n\t0x33db9be4, 0x33fda8ed, 0x341fbb8b, 0x3441d3bb,\n\t0x3463f17c, 0x348614cc, 0x34a83da8, 0x34ca6c10,\n\t0x34eca001, 0x350ed979, 0x35311877, 0x35535cfa,\n\t0x3575a6fe, 0x3597f683, 0x35ba4b87, 0x35dca607,\n\t0x35ff0603, 0x36216b78, 0x3643d665, 0x366646c7,\n\t0x3688bc9e, 0x36ab37e8, 0x36cdb8a2, 0x36f03ecb,\n\t0x3712ca62, 0x37355b64, 0x3757f1d1, 0x377a8da5,\n\t0x379d2ee0, 0x37bfd580, 0x37e28184, 0x380532e8,\n\t0x3827e9ad, 0x384aa5d0, 0x386d674f, 0x38902e2a,\n\t0x38b2fa5d, 0x38d5cbe9, 0x38f8a2ca, 0x391b7eff,\n\t0x393e6088, 0x39614761, 0x3984338a, 0x39a72501,\n\t0x39ca1bc4, 0x39ed17d1, 0x3a101928, 0x3a331fc6,\n\t0x3a562baa, 0x3a793cd2, 0x3a9c533d, 0x3abf6ee9,\n\t0x3ae28fd5, 0x3b05b5ff, 0x3b28e165, 0x3b4c1206,\n\t0x3b6f47e0, 0x3b9282f2, 0x3bb5c33a, 0x3bd908b7,\n\t0x3bfc5368, 0x3c1fa349, 0x3c42f85b, 0x3c66529c,\n\t0x3c89b209, 0x3cad16a2, 0x3cd08065, 0x3cf3ef51,\n\t0x3d176364, 0x3d3adc9c, 0x3d5e5af8, 0x3d81de77,\n\t0x3da56717, 0x3dc8f4d6, 0x3dec87b4, 0x3e101fae,\n\t0x3e33bcc3, 0x3e575ef2, 0x3e7b063a, 0x3e9eb298,\n\t0x3ec2640c, 0x3ee61a93, 0x3f09d62d, 0x3f2d96d8,\n\t0x3f515c93, 0x3f75275b, 0x3f98f731, 0x3fbccc11,\n\t0x3fe0a5fc, 0x400484ef, 0x402868ea, 0x404c51e9,\n\t0x40703fee, 0x409432f5, 0x40b82afd, 0x40dc2806,\n\t0x41002a0d, 0x41243111, 0x41483d12, 0x416c4e0d,\n\t0x41906401, 0x41b47eed, 0x41d89ecf, 0x41fcc3a7,\n\t0x4220ed72, 0x42451c30, 0x42694fde, 0x428d887d,\n\t0x42b1c609, 0x42d60883, 0x42fa4fe8, 0x431e9c37,\n\t0x4342ed70, 0x43674390, 0x438b9e96, 0x43affe82,\n\t0x43d46351, 0x43f8cd03, 0x441d3b95, 0x4441af08,\n\t0x44662758, 0x448aa487, 0x44af2690, 0x44d3ad75,\n\t0x44f83933, 0x451cc9c8, 0x45415f35, 0x4565f977,\n\t0x458a988d, 0x45af3c76, 0x45d3e531, 0x45f892bc,\n\t0x461d4516, 0x4641fc3e, 0x4666b832, 0x468b78f2,\n\t0x46b03e7c, 0x46d508cf, 0x46f9d7e9, 0x471eabca,\n\t0x47438470, 0x476861d9, 0x478d4406, 0x47b22af3,\n\t0x47d716a1, 0x47fc070e, 0x4820fc39, 0x4845f620,\n\t0x486af4c3, 0x488ff820, 0x48b50035, 0x48da0d03,\n\t0x48ff1e87, 0x492434c0, 0x49494fad, 0x496e6f4d,\n\t0x4993939f, 0x49b8bca2, 0x49ddea54, 0x4a031cb4,\n\t0x4a2853c1, 0x4a4d8f7a, 0x4a72cfde, 0x4a9814eb,\n\t0x4abd5ea1, 0x4ae2acfd, 0x4b080000, 0x4b2d57a8,\n\t0x4b52b3f3, 0x4b7814e1, 0x4b9d7a70, 0x4bc2e49f,\n\t0x4be8536e, 0x4c0dc6db, 0x4c333ee4, 0x4c58bb89,\n\t0x4c7e3cc9, 0x4ca3c2a2, 0x4cc94d14, 0x4ceedc1c,\n\t0x4d146fbb, 0x4d3a07ef, 0x4d5fa4b6, 0x4d854611,\n\t0x4daaebfd, 0x4dd09679, 0x4df64585, 0x4e1bf91f,\n\t0x4e41b146, 0x4e676dfa, 0x4e8d2f38, 0x4eb2f501,\n\t0x4ed8bf52, 0x4efe8e2b, 0x4f24618a, 0x4f4a3970,\n\t0x4f7015d9, 0x4f95f6c6, 0x4fbbdc36, 0x4fe1c626,\n\t0x5007b497, 0x502da787, 0x50539ef5, 0x50799ae1,\n\t0x509f9b48, 0x50c5a02a, 0x50eba985, 0x5111b75a,\n\t0x5137c9a6, 0x515de069, 0x5183fba2, 0x51aa1b4f,\n\t0x51d03f70, 0x51f66803, 0x521c9508, 0x5242c67d,\n\t0x5268fc62, 0x528f36b5, 0x52b57575, 0x52dbb8a2,\n\t0x5302003a, 0x53284c3c, 0x534e9ca8, 0x5374f17c,\n\t0x539b4ab7, 0x53c1a858, 0x53e80a5f, 0x540e70ca,\n\t0x5434db98, 0x545b4ac8, 0x5481be5a, 0x54a8364b,\n\t0x54ceb29c, 0x54f5334c, 0x551bb858, 0x554241c1,\n\t0x5568cf85, 0x558f61a3, 0x55b5f81b, 0x55dc92eb,\n\t0x56033212, 0x5629d590, 0x56507d63, 0x5677298a,\n\t0x569dda05, 0x56c48ed3, 0x56eb47f2, 0x57120562,\n\t0x5738c721, 0x575f8d2f, 0x5786578a, 0x57ad2633,\n\t0x57d3f927, 0x57fad066, 0x5821abef, 0x58488bc0,\n\t0x586f6fda, 0x5896583b, 0x58bd44e2, 0x58e435ce,\n\t0x590b2aff, 0x59322473, 0x59592229, 0x59802420,\n\t0x59a72a59, 0x59ce34d0, 0x59f54387, 0x5a1c567b,\n\t0x5a436dac, 0x5a6a8919, 0x5a91a8c1, 0x5ab8cca3,\n\t0x5adff4be, 0x5b072111, 0x5b2e519c, 0x5b55865e,\n\t0x5b7cbf54, 0x5ba3fc80, 0x5bcb3ddf, 0x5bf28371,\n\t0x5c19cd35, 0x5c411b2a, 0x5c686d4f, 0x5c8fc3a4,\n\t0x5cb71e27, 0x5cde7cd7, 0x5d05dfb4, 0x5d2d46bd,\n\t0x5d54b1f0, 0x5d7c214e, 0x5da394d4, 0x5dcb0c83,\n\t0x5df28859, 0x5e1a0856, 0x5e418c78, 0x5e6914be,\n\t0x5e90a129, 0x5eb831b7, 0x5edfc667, 0x5f075f38,\n\t0x5f2efc29, 0x5f569d3a, 0x5f7e426a, 0x5fa5ebb7,\n\t0x5fcd9921, 0x5ff54aa8, 0x601d004a, 0x6044ba06,\n\t0x606c77dc, 0x609439ca, 0x60bbffd0, 0x60e3c9ee,\n\t0x610b9821, 0x61336a6a, 0x615b40c8, 0x61831b39,\n\t0x61aaf9bd, 0x61d2dc53, 0x61fac2fa, 0x6222adb2,\n\t0x624a9c79, 0x62728f4f, 0x629a8633, 0x62c28123,\n\t0x62ea8020, 0x63128329, 0x633a8a3c, 0x63629559,\n\t0x638aa47f, 0x63b2b7ad, 0x63dacee2, 0x6402ea1e,\n\t0x642b0960, 0x64532ca6, 0x647b53f1, 0x64a37f3f,\n\t0x64cbae8f, 0x64f3e1e2, 0x651c1935, 0x65445488,\n\t0x656c93db, 0x6594d72c, 0x65bd1e7b, 0x65e569c7,\n\t0x660db90f, 0x66360c53, 0x665e6391, 0x6686bec9,\n\t0x66af1dfa, 0x66d78123, 0x66ffe844, 0x6728535b,\n\t0x6750c268, 0x6779356b, 0x67a1ac62, 0x67ca274c,\n\t0x67f2a629, 0x681b28f9, 0x6843afb9, 0x686c3a6a,\n\t0x6894c90b, 0x68bd5b9b, 0x68e5f219, 0x690e8c84,\n\t0x69372add, 0x695fcd21, 0x69887350, 0x69b11d6a,\n\t0x69d9cb6d, 0x6a027d5a, 0x6a2b332f, 0x6a53eceb,\n\t0x6a7caa8d, 0x6aa56c16, 0x6ace3184, 0x6af6fad6,\n\t0x6b1fc80c, 0x6b489925, 0x6b716e20, 0x6b9a46fd,\n\t0x6bc323bb, 0x6bec0458, 0x6c14e8d5, 0x6c3dd130,\n\t0x6c66bd69, 0x6c8fad80, 0x6cb8a172, 0x6ce19940,\n\t0x6d0a94e9, 0x6d33946d, 0x6d5c97ca, 0x6d859eff,\n\t0x6daeaa0d, 0x6dd7b8f1, 0x6e00cbad, 0x6e29e23e,\n\t0x6e52fca4, 0x6e7c1adf, 0x6ea53cee, 0x6ece62cf,\n\t0x6ef78c83, 0x6f20ba09, 0x6f49eb5f, 0x6f732085,\n\t0x6f9c597b, 0x6fc59640, 0x6feed6d3, 0x70181b33,\n\t0x70416360, 0x706aaf59, 0x7093ff1d, 0x70bd52ab,\n\t0x70e6aa04, 0x71100525, 0x7139640f, 0x7162c6c1,\n\t0x718c2d3a, 0x71b5977a, 0x71df057f, 0x72087749,\n\t0x7231ecd8, 0x725b662a, 0x7284e33f, 0x72ae6417,\n\t0x72d7e8b0, 0x7301710a, 0x732afd24, 0x73548cfe,\n\t0x737e2097, 0x73a7b7ee, 0x73d15303, 0x73faf1d5,\n\t0x74249462, 0x744e3aac, 0x7477e4b0, 0x74a1926e,\n\t0x74cb43e6, 0x74f4f917, 0x751eb201, 0x75486ea1,\n\t0x75722ef9, 0x759bf307, 0x75c5baca, 0x75ef8642,\n\t0x7619556f, 0x7643284f, 0x766cfee2, 0x7696d928,\n\t0x76c0b71f, 0x76ea98c7, 0x77147e20, 0x773e6728,\n\t0x776853df, 0x77924445, 0x77bc3858, 0x77e63019,\n\t0x78102b85, 0x783a2a9e, 0x78642d62, 0x788e33d1,\n\t0x78b83de9, 0x78e24bab, 0x790c5d15, 0x79367228,\n\t0x79608ae1, 0x798aa742, 0x79b4c748, 0x79deeaf4,\n\t0x7a091245, 0x7a333d3a, 0x7a5d6bd2, 0x7a879e0e,\n\t0x7ab1d3ec, 0x7adc0d6b, 0x7b064a8c, 0x7b308b4d,\n\t0x7b5acfae, 0x7b8517ae, 0x7baf634c, 0x7bd9b289,\n\t0x7c040563, 0x7c2e5bda, 0x7c58b5ec, 0x7c83139b,\n\t0x7cad74e4, 0x7cd7d9c7, 0x7d024244, 0x7d2cae5a,\n\t0x7d571e09, 0x7d81914f, 0x7dac082d, 0x7dd682a1,\n\t0x7e0100ac, 0x7e2b824b, 0x7e560780, 0x7e809048,\n\t0x7eab1ca5, 0x7ed5ac94, 0x7f004015, 0x7f2ad729,\n\t0x7f5571cd, 0x7f801003, 0x7faab1c8, 0x7fd5571d\n};\n\n\nconst Word32 invSBF[24] = {\n  0x3FFD34FC, 0x2D3F8000, 0x24F18C7E, 0x1FFE9A7E,\n  0x1C9DF10C, 0x1A1F851A, 0x182FE994, 0x169FC000,\n  0x15542AAA, 0x143C31C2, 0x134B1B6C, 0x127920BE,\n  0x11BF2FCC, 0x111A749E, 0x1085FC42, 0x0FFFA7BE,\n  0x0F855818, 0x0F14EE56, 0x0EAE6A78, 0x0E4EF886,\n  0x0DF69880, 0x0DA49568, 0x0D578542, 0x0D101D0C\n};\n\nconst Word16 pow2tominusNover16[17] = {\n  0x7fff, 0x7a93, 0x7560, 0x7066,\n  0x6ba2, 0x6712, 0x62b4, 0x5e84,\n  0x5a82, 0x56ac, 0x52ff, 0x4f7b,\n  0x4c1c, 0x48e2, 0x45cb, 0x42d5,\n  0x4000\n};\n\nconst Word16 sideInfoTabLong[MAX_SFB_LONG + 1] = {\n  9, 9, 9, 9, 9, 9, 9, 9, 9,\n  9, 9, 9, 9, 9, 9, 9, 9, 9,\n  9, 9, 9, 9, 9, 9, 9, 9, 9,\n  9, 9, 9, 9, 14, 14, 14, 14,\n  14, 14, 14, 14, 14, 14, 14,\n  14, 14, 14, 14, 14, 14, 14,\n  14, 14, 14\n};\n\nconst Word16 sideInfoTabShort[MAX_SFB_SHORT + 1] = {\n  7, 7, 7, 7, 7, 7, 7, 10, 10,\n  10, 10, 10, 10, 10, 13, 13\n};\n\nWord32 specExpMantTableComb_enc[4][14] =\n{\n  {0x40000000,  0x50a28be6,  0x6597fa95,  0x40000000,\n   0x50a28be6,  0x6597fa95,  0x40000000,  0x50a28be6,\n   0x6597fa95,  0x40000000,  0x50a28be6,  0x6597fa95,\n   0x40000000,  0x50a28be6},\n\n  {0x4c1bf829,  0x5fe4435e,  0x78d0df9c,  0x4c1bf829,\n   0x5fe4435e,  0x78d0df9c,  0x4c1bf829,  0x5fe4435e,\n   0x78d0df9c,  0x4c1bf829,  0x5fe4435e,  0x78d0df9c,\n   0x4c1bf829,  0x5fe4435e},\n\n  {0x5a82799a,  0x7208f81d,  0x47d66b0f,  0x5a82799a,\n   0x7208f81d,  0x47d66b0f,  0x5a82799a,  0x7208f81d,\n   0x47d66b0f,  0x5a82799a,  0x7208f81d,  0x47d66b0f,\n   0x5a82799a,  0x7208f81d},\n\n  {0x6ba27e65,  0x43ce3e4b,  0x556e0424,  0x6ba27e65,\n   0x43ce3e4b,  0x556e0424,  0x6ba27e65,  0x43ce3e4b,\n   0x556e0424,  0x6ba27e65,  0x43ce3e4b,  0x556e0424,\n   0x6ba27e65,  0x43ce3e4b}\n};\n\nconst  UWord8 specExpTableComb_enc[4][14] =\n{\n  {1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18},\n  {1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18},\n  {1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 16, 17, 18},\n  {1, 3, 4, 5, 7, 8, 9, 11, 12, 13, 15, 16, 17, 19}\n};\n\nconst Word16 quantBorders[4][4] = {\n  /* pow(1.0-0.4054, 4/3)/16 * pow(2, (0..3)/4) */\n  {0x0400, 0x0ee7, 0x1c86, 0x2c0d},\n  /* pow(2.0-0.4054, 4/3)/16 * pow(2, (0..3)/4) */\n  {0x04c2, 0x11b9, 0x21eb, 0x3463},\n  /* pow(3.0-0.4054, 4/3)/16 * pow(2, (0..3)/4) */\n  {0x05a8, 0x1514, 0x2856, 0x3e4c},\n  /* pow(4.0-0.4054, 4/3)/16 * pow(2, (0..3)/4) */\n  {0x06ba, 0x1911, 0x2ff8, 0x4a16},\n};\n\nconst Word16 quantRecon[4][3] = {\n  {0x0800, 0x1429, 0x229d},\n  {0x0983, 0x17f9, 0x292a},\n  {0x0b50, 0x1c82, 0x30f4},\n  {0x0d74, 0x21e7, 0x3a37},\n};\n\nconst int sampRateTab[NUM_SAMPLE_RATES] = {\n    96000, 88200, 64000, 48000, 44100, 32000,\n\t24000, 22050, 16000, 12000, 11025,  8000\n};\n\n\nconst int\trates[8] = {\n\t160, 240, 320, 400, 480, 560, 640, 0\n};\n\nconst int BandwithCoefTab[8][NUM_SAMPLE_RATES] = {\n\t{ 7000,  7000,  4666,  3500,  3500,  2800,  2800,  2800,  2800,  2000,  2000,  2000},\n\t{12000, 12000,  8000,  6000,  6000,  6000,  4000,  4000,  4000,  3000,  3000,  3000},\n\t{18000, 18000, 12000,  9000,  9000,  9000,  7000,  7000,  7000,  5000,  5000,  5000},\n\t{20000, 20000, 16000, 12000, 12000, 12000,  9000,  9000,  9000,  6000,  6000,  6000},\n\t{20000, 20000, 18666, 14000, 14000, 14000, 10000, 10000, 10000,  7000,  7000,  7000},\n\t{20000, 20000, 20000, 16000, 16000, 16000, 12000, 12000, 12000,  8000,  8000,  8000},\n\t{20000, 20000, 20000, 20000, 20000, 20000, 15000, 15000, 15000, 10000, 10000, 10000},\n\t{20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000}\n};\n\n\n/* total number of scale factor bands in one window */\nconst UWord8 sfBandTotalShort[NUM_SAMPLE_RATES] = {\n    12, 12, 12, 14, 14, 14, 15, 15, 15, 15, 15, 15\n};\n\nconst UWord8 sfBandTotalLong[NUM_SAMPLE_RATES] = {\n    41, 41, 47, 49, 49, 51, 47, 47, 43, 43, 43, 40\n};\n\n/* scale factor band tables */\nconst int sfBandTabShortOffset[NUM_SAMPLE_RATES] = {0, 0, 0, 13, 13, 13, 28, 28, 44, 44, 44, 60};\n\nconst short sfBandTabShort[76] = {\n\t/* short block 64, 88, 96 kHz [13]  */\n\t0,   4,   8,  12,  16,  20,  24,  32,  40,  48,  64,  92, 128,\n\n\t/* short block 32, 44, 48 kHz [15]  */\n\t0,   4,   8,  12,  16,  20,  28,  36,  44,  56,  68,  80,  96, 112, 128,\n\n\t/* short block 22, 24 kHz [16]  */\n\t0,   4,   8,  12,  16,  20,  24,  28,  36,  44,  52,  64,  76,  92, 108, 128,\n\n\t/* short block 11, 12, 16 kHz [16] */\n\t0,   4,   8,  12,  16,  20,  24,  28,  32,  40,  48,  60,  72,  88, 108, 128,\n\n\t/* short block 8 kHz [16] */\n\t0,   4,   8,  12,  16,  20,  24,  28,  36,  44,  52,  60,  72,  88, 108, 128\n};\n\nconst int sfBandTabLongOffset[NUM_SAMPLE_RATES] = {0, 0, 42, 90, 90, 140, 192, 192, 240, 240, 240, 284};\n\nconst short sfBandTabLong[325] = {\n\t/* long block 88, 96 kHz [42]  */\n\t  0,   4,   8,  12,  16,  20,  24,  28,  32,  36,  40,  44,  48,   52,\n\t 56,  64,  72,  80,  88,  96, 108, 120, 132, 144, 156, 172, 188,  212,\n\t240, 276, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024,\n\n\t/* long block 64 kHz [48]  */\n\t  0,   4,   8,  12,  16,  20,  24,  28,  32,  36,  40,  44,  48,  52,  56,   64,\n\t 72,  80,  88, 100, 112, 124, 140, 156, 172, 192, 216, 240, 268, 304, 344,  384,\n\t424, 464, 504, 544, 584, 624, 664, 704, 744, 784, 824, 864, 904, 944, 984, 1024,\n\n\t/* long block 44, 48 kHz [50] */\n\t  0,   4,   8,  12,  16,  20,  24,  28,  32,  36,  40,  48,  56,  64,  72,   80,  88,\n\t 96, 108, 120, 132, 144, 160, 176, 196, 216, 240, 264, 292, 320, 352, 384,  416, 448,\n\t480, 512, 544, 576, 608, 640, 672, 704, 736, 768, 800, 832, 864, 896, 928, 1024,\n\n\t/* long block 32 kHz [52] */\n\t  0,   4,   8,  12,  16,  20,  24,  28,  32,  36,  40,  48,  56,  64,  72,   80,  88,  96,\n\t108, 120, 132, 144, 160, 176, 196, 216, 240, 264, 292, 320, 352, 384, 416,  448, 480, 512,\n\t544, 576, 608, 640, 672, 704, 736, 768, 800, 832, 864, 896, 928, 960, 992, 1024,\n\n\t/* long block 22, 24 kHz [48] */\n\t  0,   4,   8,  12,  16,  20,  24,  28,  32,  36,  40,  44,  52,  60,  68,   76,\n\t 84,  92, 100, 108, 116, 124, 136, 148, 160, 172, 188, 204, 220, 240, 260,  284,\n\t308, 336, 364, 396, 432, 468, 508, 552, 600, 652, 704, 768, 832, 896, 960, 1024,\n\n\t/* long block 11, 12, 16 kHz [44] */\n\t  0,   8,  16,  24,  32,  40,  48,  56,  64,  72,  80,  88, 100,  112, 124,\n\t136, 148, 160, 172, 184, 196, 212, 228, 244, 260, 280, 300, 320,  344, 368,\n\t396, 424, 456, 492, 532, 572, 616, 664, 716, 772, 832, 896, 960, 1024,\n\n\t/* long block 8 kHz [41]  */\n\t  0,  12,  24,  36,  48,  60,  72,  84,  96, 108, 120, 132,  144, 156,\n\t172, 188, 204, 220, 236, 252, 268, 288, 308, 328, 348, 372,  396, 420,\n\t448, 476, 508, 544, 580, 620, 664, 712, 764, 820, 880, 944, 1024\n};\n\n/*\n  these tables are used only for counting and\n  are stored in packed format\n*/\nconst UWord16 huff_ltab1_2[3][3][3][3]=\n{\n  {\n    {\n      {0x0b09,0x0907,0x0b09},\n      {0x0a08,0x0706,0x0a08},\n      {0x0b09,0x0908,0x0b09}\n    },\n    {\n      {0x0a08,0x0706,0x0a07},\n      {0x0706,0x0505,0x0706},\n      {0x0907,0x0706,0x0a08}\n    },\n    {\n      {0x0b09,0x0907,0x0b08},\n      {0x0908,0x0706,0x0908},\n      {0x0b09,0x0907,0x0b09}\n    }\n  },\n  {\n    {\n      {0x0908,0x0706,0x0907},\n      {0x0706,0x0505,0x0706},\n      {0x0907,0x0706,0x0908}\n    },\n    {\n      {0x0706,0x0505,0x0706},\n      {0x0505,0x0103,0x0505},\n      {0x0706,0x0505,0x0706}\n    },\n    {\n      {0x0908,0x0706,0x0907},\n      {0x0706,0x0505,0x0706},\n      {0x0908,0x0706,0x0908}\n    }\n  },\n  {\n    {\n      {0x0b09,0x0907,0x0b09},\n      {0x0908,0x0706,0x0908},\n      {0x0b08,0x0907,0x0b09}\n    },\n    {\n      {0x0a08,0x0706,0x0907},\n      {0x0706,0x0504,0x0706},\n      {0x0908,0x0706,0x0a07}\n    },\n    {\n      {0x0b09,0x0907,0x0b09},\n      {0x0a07,0x0706,0x0908},\n      {0x0b09,0x0907,0x0b09}\n    }\n  }\n};\n\n\nconst UWord16 huff_ltab3_4[3][3][3][3]=\n{\n  {\n    {\n      {0x0104,0x0405,0x0808},\n      {0x0405,0x0504,0x0808},\n      {0x0909,0x0908,0x0a0b}\n    },\n    {\n      {0x0405,0x0605,0x0908},\n      {0x0605,0x0604,0x0908},\n      {0x0908,0x0907,0x0a0a}\n    },\n    {\n      {0x0909,0x0a08,0x0d0b},\n      {0x0908,0x0908,0x0b0a},\n      {0x0b0b,0x0a0a,0x0c0b}\n    }\n  },\n  {\n    {\n      {0x0404,0x0605,0x0a08},\n      {0x0604,0x0704,0x0a08},\n      {0x0a08,0x0a08,0x0c0a}\n    },\n    {\n      {0x0504,0x0704,0x0b08},\n      {0x0604,0x0704,0x0a07},\n      {0x0908,0x0907,0x0b09}\n    },\n    {\n      {0x0908,0x0a08,0x0d0a},\n      {0x0807,0x0907,0x0c09},\n      {0x0a0a,0x0b09,0x0c0a}\n    }\n  },\n  {\n    {\n      {0x0808,0x0a08,0x0f0b},\n      {0x0908,0x0b07,0x0f0a},\n      {0x0d0b,0x0e0a,0x100c}\n    },\n    {\n      {0x0808,0x0a07,0x0e0a},\n      {0x0907,0x0a07,0x0e09},\n      {0x0c0a,0x0c09,0x0f0b}\n    },\n    {\n      {0x0b0b,0x0c0a,0x100c},\n      {0x0a0a,0x0b09,0x0f0b},\n      {0x0c0b,0x0c0a,0x0f0b}\n    }\n  }\n};\n\nconst UWord16 huff_ltab5_6[9][9]=\n{\n  {0x0d0b,0x0c0a,0x0b09,0x0b09,0x0a09,0x0b09,0x0b09,0x0c0a,0x0d0b},\n  {0x0c0a,0x0b09,0x0a08,0x0907,0x0807,0x0907,0x0a08,0x0b09,0x0c0a},\n  {0x0c09,0x0a08,0x0906,0x0806,0x0706,0x0806,0x0906,0x0a08,0x0b09},\n  {0x0b09,0x0907,0x0806,0x0504,0x0404,0x0504,0x0806,0x0907,0x0b09},\n  {0x0a09,0x0807,0x0706,0x0404,0x0104,0x0404,0x0706,0x0807,0x0b09},\n  {0x0b09,0x0907,0x0806,0x0504,0x0404,0x0504,0x0806,0x0907,0x0b09},\n  {0x0b09,0x0a08,0x0906,0x0806,0x0706,0x0806,0x0906,0x0a08,0x0b09},\n  {0x0c0a,0x0b09,0x0a08,0x0907,0x0807,0x0907,0x0a07,0x0b08,0x0c0a},\n  {0x0d0b,0x0c0a,0x0c09,0x0b09,0x0a09,0x0a09,0x0b09,0x0c0a,0x0d0b}\n};\n\nconst UWord16 huff_ltab7_8[8][8]=\n{\n  {0x0105,0x0304,0x0605,0x0706,0x0807,0x0908,0x0a09,0x0b0a},\n  {0x0304,0x0403,0x0604,0x0705,0x0806,0x0807,0x0907,0x0908},\n  {0x0605,0x0604,0x0704,0x0805,0x0806,0x0907,0x0907,0x0a08},\n  {0x0706,0x0705,0x0805,0x0806,0x0906,0x0907,0x0a08,0x0a08},\n  {0x0807,0x0806,0x0906,0x0906,0x0a07,0x0a07,0x0a08,0x0b09},\n  {0x0908,0x0807,0x0906,0x0907,0x0a07,0x0a08,0x0b08,0x0b0a},\n  {0x0a09,0x0907,0x0907,0x0a08,0x0a08,0x0b08,0x0c09,0x0c09},\n  {0x0b0a,0x0a08,0x0a08,0x0a08,0x0b09,0x0b09,0x0c09,0x0c0a}\n};\n\nconst UWord16 huff_ltab9_10[13][13]=\n{\n  {0x0106,0x0305,0x0606,0x0806,0x0907,0x0a08,0x0a09,0x0b0a,0x0b0a,0x0c0a,0x0c0b,0x0d0b,0x0d0c},\n  {0x0305,0x0404,0x0604,0x0705,0x0806,0x0807,0x0907,0x0a08,0x0a08,0x0a09,0x0b0a,0x0c0a,0x0c0b},\n  {0x0606,0x0604,0x0705,0x0805,0x0806,0x0906,0x0a07,0x0a08,0x0a08,0x0b09,0x0c09,0x0c0a,0x0c0a},\n  {0x0806,0x0705,0x0805,0x0905,0x0906,0x0a07,0x0a07,0x0b08,0x0b08,0x0b09,0x0c09,0x0c0a,0x0d0a},\n  {0x0907,0x0806,0x0906,0x0906,0x0a06,0x0a07,0x0b07,0x0b08,0x0b08,0x0c09,0x0c09,0x0c0a,0x0d0a},\n  {0x0a08,0x0907,0x0906,0x0a07,0x0b07,0x0b07,0x0b08,0x0c08,0x0b08,0x0c09,0x0c0a,0x0d0a,0x0d0b},\n  {0x0b09,0x0907,0x0a07,0x0b07,0x0b07,0x0b08,0x0c08,0x0c09,0x0c09,0x0c09,0x0d0a,0x0d0a,0x0d0b},\n  {0x0b09,0x0a08,0x0a08,0x0b08,0x0b08,0x0c08,0x0c09,0x0d09,0x0d09,0x0d0a,0x0d0a,0x0d0b,0x0d0b},\n  {0x0b09,0x0a08,0x0a08,0x0b08,0x0b08,0x0b08,0x0c09,0x0c09,0x0d0a,0x0d0a,0x0e0a,0x0d0b,0x0e0b},\n  {0x0b0a,0x0a09,0x0b09,0x0b09,0x0c09,0x0c09,0x0c09,0x0c0a,0x0d0a,0x0d0a,0x0e0b,0x0e0b,0x0e0c},\n  {0x0c0a,0x0b09,0x0b09,0x0c09,0x0c09,0x0c0a,0x0d0a,0x0d0a,0x0d0a,0x0e0b,0x0e0b,0x0e0b,0x0f0c},\n  {0x0c0b,0x0b0a,0x0c09,0x0c0a,0x0c0a,0x0d0a,0x0d0a,0x0d0a,0x0d0b,0x0e0b,0x0e0b,0x0f0b,0x0f0c},\n  {0x0d0b,0x0c0a,0x0c0a,0x0c0a,0x0d0a,0x0d0a,0x0d0a,0x0d0b,0x0e0b,0x0e0c,0x0e0c,0x0e0c,0x0f0c}\n};\n\nconst UWord16 huff_ltab11[17][17]=\n{\n  {0x0004,0x0005,0x0006,0x0007,0x0008,0x0008,0x0009,0x000a,0x000a,0x000a,0x000b,0x000b,0x000c,0x000b,0x000c,0x000c,0x000a},\n  {0x0005,0x0004,0x0005,0x0006,0x0007,0x0007,0x0008,0x0008,0x0009,0x0009,0x0009,0x000a,0x000a,0x000a,0x000a,0x000b,0x0008},\n  {0x0006,0x0005,0x0005,0x0006,0x0007,0x0007,0x0008,0x0008,0x0008,0x0009,0x0009,0x0009,0x000a,0x000a,0x000a,0x000a,0x0008},\n  {0x0007,0x0006,0x0006,0x0006,0x0007,0x0007,0x0008,0x0008,0x0008,0x0009,0x0009,0x0009,0x000a,0x000a,0x000a,0x000a,0x0008},\n  {0x0008,0x0007,0x0007,0x0007,0x0007,0x0008,0x0008,0x0008,0x0008,0x0009,0x0009,0x0009,0x000a,0x000a,0x000a,0x000a,0x0008},\n  {0x0008,0x0007,0x0007,0x0007,0x0007,0x0008,0x0008,0x0008,0x0009,0x0009,0x0009,0x0009,0x000a,0x000a,0x000a,0x000a,0x0008},\n  {0x0009,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0009,0x0009,0x0009,0x000a,0x000a,0x000a,0x000a,0x000a,0x0008},\n  {0x0009,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0009,0x0009,0x0009,0x000a,0x000a,0x000a,0x000a,0x000a,0x000a,0x0008},\n  {0x000a,0x0009,0x0008,0x0008,0x0009,0x0009,0x0009,0x0009,0x0009,0x000a,0x000a,0x000a,0x000a,0x000a,0x000a,0x000b,0x0008},\n  {0x000a,0x0009,0x0009,0x0009,0x0009,0x0009,0x0009,0x0009,0x000a,0x000a,0x000a,0x000a,0x000a,0x000a,0x000b,0x000b,0x0008},\n  {0x000b,0x0009,0x0009,0x0009,0x0009,0x0009,0x0009,0x000a,0x000a,0x000a,0x000a,0x000a,0x000b,0x000a,0x000b,0x000b,0x0008},\n  {0x000b,0x000a,0x0009,0x0009,0x000a,0x0009,0x000a,0x000a,0x000a,0x000a,0x000a,0x000b,0x000b,0x000b,0x000b,0x000b,0x0008},\n  {0x000b,0x000a,0x000a,0x000a,0x000a,0x000a,0x000a,0x000a,0x000a,0x000a,0x000a,0x000b,0x000b,0x000b,0x000b,0x000b,0x0009},\n  {0x000b,0x000a,0x0009,0x0009,0x000a,0x000a,0x000a,0x000a,0x000a,0x000a,0x000b,0x000b,0x000b,0x000b,0x000b,0x000b,0x0009},\n  {0x000b,0x000a,0x000a,0x000a,0x000a,0x000a,0x000a,0x000a,0x000a,0x000a,0x000b,0x000b,0x000b,0x000b,0x000b,0x000b,0x0009},\n  {0x000c,0x000a,0x000a,0x000a,0x000a,0x000a,0x000a,0x000a,0x000b,0x000b,0x000b,0x000b,0x000b,0x000b,0x000c,0x000c,0x0009},\n  {0x0009,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0009,0x0005}\n};\n\nconst UWord16 huff_ltabscf[121]=\n{\n  0x0012,\n  0x0012,\n  0x0012,\n  0x0012,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0012,\n  0x0013,\n  0x0012,\n  0x0011,\n  0x0011,\n  0x0010,\n  0x0011,\n  0x0010,\n  0x0010,\n  0x0010,\n  0x0010,\n  0x000f,\n  0x000f,\n  0x000e,\n  0x000e,\n  0x000e,\n  0x000e,\n  0x000e,\n  0x000e,\n  0x000d,\n  0x000d,\n  0x000c,\n  0x000c,\n  0x000c,\n  0x000b,\n  0x000c,\n  0x000b,\n  0x000a,\n  0x000a,\n  0x000a,\n  0x0009,\n  0x0009,\n  0x0008,\n  0x0008,\n  0x0008,\n  0x0007,\n  0x0006,\n  0x0006,\n  0x0005,\n  0x0004,\n  0x0003,\n  0x0001,\n  0x0004,\n  0x0004,\n  0x0005,\n  0x0006,\n  0x0006,\n  0x0007,\n  0x0007,\n  0x0008,\n  0x0008,\n  0x0009,\n  0x0009,\n  0x000a,\n  0x000a,\n  0x000a,\n  0x000b,\n  0x000b,\n  0x000b,\n  0x000b,\n  0x000c,\n  0x000c,\n  0x000d,\n  0x000d,\n  0x000d,\n  0x000e,\n  0x000e,\n  0x0010,\n  0x000f,\n  0x0010,\n  0x000f,\n  0x0012,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013,\n  0x0013\n};\n\n\nconst UWord16 huff_ctab1[3][3][3][3]=\n{\n  {\n    {\n      {0x07f8,0x01f1,0x07fd},\n      {0x03f5,0x0068,0x03f0},\n      {0x07f7,0x01ec,0x07f5}\n    },\n    {\n      {0x03f1,0x0072,0x03f4},\n      {0x0074,0x0011,0x0076},\n      {0x01eb,0x006c,0x03f6}\n    },\n    {\n      {0x07fc,0x01e1,0x07f1},\n      {0x01f0,0x0061,0x01f6},\n      {0x07f2,0x01ea,0x07fb}\n    }\n  },\n  {\n    {\n      {0x01f2,0x0069,0x01ed},\n      {0x0077,0x0017,0x006f},\n      {0x01e6,0x0064,0x01e5}\n    },\n    {\n      {0x0067,0x0015,0x0062},\n      {0x0012,0x0000,0x0014},\n      {0x0065,0x0016,0x006d}\n    },\n    {\n      {0x01e9,0x0063,0x01e4},\n      {0x006b,0x0013,0x0071},\n      {0x01e3,0x0070,0x01f3}\n    }\n  },\n  {\n    {\n      {0x07fe,0x01e7,0x07f3},\n      {0x01ef,0x0060,0x01ee},\n      {0x07f0,0x01e2,0x07fa}\n    },\n    {\n      {0x03f3,0x006a,0x01e8},\n      {0x0075,0x0010,0x0073},\n      {0x01f4,0x006e,0x03f7}\n    },\n    {\n      {0x07f6,0x01e0,0x07f9},\n      {0x03f2,0x0066,0x01f5},\n      {0x07ff,0x01f7,0x07f4}\n    }\n  }\n};\n\nconst UWord16 huff_ctab2[3][3][3][3]=\n{\n  {\n    {\n      {0x01f3,0x006f,0x01fd},\n      {0x00eb,0x0023,0x00ea},\n      {0x01f7,0x00e8,0x01fa}\n    },\n    {\n      {0x00f2,0x002d,0x0070},\n      {0x0020,0x0006,0x002b},\n      {0x006e,0x0028,0x00e9}\n    },\n    {\n      {0x01f9,0x0066,0x00f8},\n      {0x00e7,0x001b,0x00f1},\n      {0x01f4,0x006b,0x01f5}\n    }\n  },\n  {\n    {\n      {0x00ec,0x002a,0x006c},\n      {0x002c,0x000a,0x0027},\n      {0x0067,0x001a,0x00f5}\n    },\n    {\n      {0x0024,0x0008,0x001f},\n      {0x0009,0x0000,0x0007},\n      {0x001d,0x000b,0x0030}\n    },\n    {\n      {0x00ef,0x001c,0x0064},\n      {0x001e,0x000c,0x0029},\n      {0x00f3,0x002f,0x00f0}\n    }\n  },\n  {\n    {\n      {0x01fc,0x0071,0x01f2},\n      {0x00f4,0x0021,0x00e6},\n      {0x00f7,0x0068,0x01f8}\n    },\n    {\n      {0x00ee,0x0022,0x0065},\n      {0x0031,0x0002,0x0026},\n      {0x00ed,0x0025,0x006a}\n    },\n    {\n      {0x01fb,0x0072,0x01fe},\n      {0x0069,0x002e,0x00f6},\n      {0x01ff,0x006d,0x01f6}\n    }\n  }\n};\n\nconst UWord16 huff_ctab3[3][3][3][3]=\n{\n  {\n    {\n      {0x0000,0x0009,0x00ef},\n      {0x000b,0x0019,0x00f0},\n      {0x01eb,0x01e6,0x03f2}\n    },\n    {\n      {0x000a,0x0035,0x01ef},\n      {0x0034,0x0037,0x01e9},\n      {0x01ed,0x01e7,0x03f3}\n    },\n    {\n      {0x01ee,0x03ed,0x1ffa},\n      {0x01ec,0x01f2,0x07f9},\n      {0x07f8,0x03f8,0x0ff8}\n    }\n  },\n  {\n    {\n      {0x0008,0x0038,0x03f6},\n      {0x0036,0x0075,0x03f1},\n      {0x03eb,0x03ec,0x0ff4}\n    },\n    {\n      {0x0018,0x0076,0x07f4},\n      {0x0039,0x0074,0x03ef},\n      {0x01f3,0x01f4,0x07f6}\n    },\n    {\n      {0x01e8,0x03ea,0x1ffc},\n      {0x00f2,0x01f1,0x0ffb},\n      {0x03f5,0x07f3,0x0ffc}\n    }\n  },\n  {\n    {\n      {0x00ee,0x03f7,0x7ffe},\n      {0x01f0,0x07f5,0x7ffd},\n      {0x1ffb,0x3ffa,0xffff}\n    },\n    {\n      {0x00f1,0x03f0,0x3ffc},\n      {0x01ea,0x03ee,0x3ffb},\n      {0x0ff6,0x0ffa,0x7ffc}\n    },\n    {\n      {0x07f2,0x0ff5,0xfffe},\n      {0x03f4,0x07f7,0x7ffb},\n      {0x0ff7,0x0ff9,0x7ffa}\n    }\n  }\n};\n\nconst UWord16 huff_ctab4[3][3][3][3]=\n{\n  {\n    {\n      {0x0007,0x0016,0x00f6},\n      {0x0018,0x0008,0x00ef},\n      {0x01ef,0x00f3,0x07f8}\n    },\n    {\n      {0x0019,0x0017,0x00ed},\n      {0x0015,0x0001,0x00e2},\n      {0x00f0,0x0070,0x03f0}\n    },\n    {\n      {0x01ee,0x00f1,0x07fa},\n      {0x00ee,0x00e4,0x03f2},\n      {0x07f6,0x03ef,0x07fd}\n    }\n  },\n  {\n    {\n      {0x0005,0x0014,0x00f2},\n      {0x0009,0x0004,0x00e5},\n      {0x00f4,0x00e8,0x03f4}\n    },\n    {\n      {0x0006,0x0002,0x00e7},\n      {0x0003,0x0000,0x006b},\n      {0x00e3,0x0069,0x01f3}\n    },\n    {\n      {0x00eb,0x00e6,0x03f6},\n      {0x006e,0x006a,0x01f4},\n      {0x03ec,0x01f0,0x03f9}\n    }\n  },\n  {\n    {\n      {0x00f5,0x00ec,0x07fb},\n      {0x00ea,0x006f,0x03f7},\n      {0x07f9,0x03f3,0x0fff}\n    },\n    {\n      {0x00e9,0x006d,0x03f8},\n      {0x006c,0x0068,0x01f5},\n      {0x03ee,0x01f2,0x07f4}\n    },\n    {\n      {0x07f7,0x03f1,0x0ffe},\n      {0x03ed,0x01f1,0x07f5},\n      {0x07fe,0x03f5,0x07fc}\n    }\n  }\n};\nconst UWord16 huff_ctab5[9][9]=\n{\n  {0x1fff,0x0ff7,0x07f4,0x07e8,0x03f1,0x07ee,0x07f9,0x0ff8,0x1ffd},\n  {0x0ffd,0x07f1,0x03e8,0x01e8,0x00f0,0x01ec,0x03ee,0x07f2,0x0ffa},\n  {0x0ff4,0x03ef,0x01f2,0x00e8,0x0070,0x00ec,0x01f0,0x03ea,0x07f3},\n  {0x07eb,0x01eb,0x00ea,0x001a,0x0008,0x0019,0x00ee,0x01ef,0x07ed},\n  {0x03f0,0x00f2,0x0073,0x000b,0x0000,0x000a,0x0071,0x00f3,0x07e9},\n  {0x07ef,0x01ee,0x00ef,0x0018,0x0009,0x001b,0x00eb,0x01e9,0x07ec},\n  {0x07f6,0x03eb,0x01f3,0x00ed,0x0072,0x00e9,0x01f1,0x03ed,0x07f7},\n  {0x0ff6,0x07f0,0x03e9,0x01ed,0x00f1,0x01ea,0x03ec,0x07f8,0x0ff9},\n  {0x1ffc,0x0ffc,0x0ff5,0x07ea,0x03f3,0x03f2,0x07f5,0x0ffb,0x1ffe}\n};\n\nconst UWord16 huff_ctab6[9][9]=\n{\n  {0x07fe,0x03fd,0x01f1,0x01eb,0x01f4,0x01ea,0x01f0,0x03fc,0x07fd},\n  {0x03f6,0x01e5,0x00ea,0x006c,0x0071,0x0068,0x00f0,0x01e6,0x03f7},\n  {0x01f3,0x00ef,0x0032,0x0027,0x0028,0x0026,0x0031,0x00eb,0x01f7},\n  {0x01e8,0x006f,0x002e,0x0008,0x0004,0x0006,0x0029,0x006b,0x01ee},\n  {0x01ef,0x0072,0x002d,0x0002,0x0000,0x0003,0x002f,0x0073,0x01fa},\n  {0x01e7,0x006e,0x002b,0x0007,0x0001,0x0005,0x002c,0x006d,0x01ec},\n  {0x01f9,0x00ee,0x0030,0x0024,0x002a,0x0025,0x0033,0x00ec,0x01f2},\n  {0x03f8,0x01e4,0x00ed,0x006a,0x0070,0x0069,0x0074,0x00f1,0x03fa},\n  {0x07ff,0x03f9,0x01f6,0x01ed,0x01f8,0x01e9,0x01f5,0x03fb,0x07fc}\n};\n\nconst UWord16 huff_ctab7[8][8]=\n{\n  {0x0000,0x0005,0x0037,0x0074,0x00f2,0x01eb,0x03ed,0x07f7},\n  {0x0004,0x000c,0x0035,0x0071,0x00ec,0x00ee,0x01ee,0x01f5},\n  {0x0036,0x0034,0x0072,0x00ea,0x00f1,0x01e9,0x01f3,0x03f5},\n  {0x0073,0x0070,0x00eb,0x00f0,0x01f1,0x01f0,0x03ec,0x03fa},\n  {0x00f3,0x00ed,0x01e8,0x01ef,0x03ef,0x03f1,0x03f9,0x07fb},\n  {0x01ed,0x00ef,0x01ea,0x01f2,0x03f3,0x03f8,0x07f9,0x07fc},\n  {0x03ee,0x01ec,0x01f4,0x03f4,0x03f7,0x07f8,0x0ffd,0x0ffe},\n  {0x07f6,0x03f0,0x03f2,0x03f6,0x07fa,0x07fd,0x0ffc,0x0fff}\n};\n\nconst UWord16 huff_ctab8[8][8]=\n{\n  {0x000e,0x0005,0x0010,0x0030,0x006f,0x00f1,0x01fa,0x03fe},\n  {0x0003,0x0000,0x0004,0x0012,0x002c,0x006a,0x0075,0x00f8},\n  {0x000f,0x0002,0x0006,0x0014,0x002e,0x0069,0x0072,0x00f5},\n  {0x002f,0x0011,0x0013,0x002a,0x0032,0x006c,0x00ec,0x00fa},\n  {0x0071,0x002b,0x002d,0x0031,0x006d,0x0070,0x00f2,0x01f9},\n  {0x00ef,0x0068,0x0033,0x006b,0x006e,0x00ee,0x00f9,0x03fc},\n  {0x01f8,0x0074,0x0073,0x00ed,0x00f0,0x00f6,0x01f6,0x01fd},\n  {0x03fd,0x00f3,0x00f4,0x00f7,0x01f7,0x01fb,0x01fc,0x03ff}\n};\n\nconst UWord16 huff_ctab9[13][13]=\n{\n  {0x0000,0x0005,0x0037,0x00e7,0x01de,0x03ce,0x03d9,0x07c8,0x07cd,0x0fc8,0x0fdd,0x1fe4,0x1fec},\n  {0x0004,0x000c,0x0035,0x0072,0x00ea,0x00ed,0x01e2,0x03d1,0x03d3,0x03e0,0x07d8,0x0fcf,0x0fd5},\n  {0x0036,0x0034,0x0071,0x00e8,0x00ec,0x01e1,0x03cf,0x03dd,0x03db,0x07d0,0x0fc7,0x0fd4,0x0fe4},\n  {0x00e6,0x0070,0x00e9,0x01dd,0x01e3,0x03d2,0x03dc,0x07cc,0x07ca,0x07de,0x0fd8,0x0fea,0x1fdb},\n  {0x01df,0x00eb,0x01dc,0x01e6,0x03d5,0x03de,0x07cb,0x07dd,0x07dc,0x0fcd,0x0fe2,0x0fe7,0x1fe1},\n  {0x03d0,0x01e0,0x01e4,0x03d6,0x07c5,0x07d1,0x07db,0x0fd2,0x07e0,0x0fd9,0x0feb,0x1fe3,0x1fe9},\n  {0x07c4,0x01e5,0x03d7,0x07c6,0x07cf,0x07da,0x0fcb,0x0fda,0x0fe3,0x0fe9,0x1fe6,0x1ff3,0x1ff7},\n  {0x07d3,0x03d8,0x03e1,0x07d4,0x07d9,0x0fd3,0x0fde,0x1fdd,0x1fd9,0x1fe2,0x1fea,0x1ff1,0x1ff6},\n  {0x07d2,0x03d4,0x03da,0x07c7,0x07d7,0x07e2,0x0fce,0x0fdb,0x1fd8,0x1fee,0x3ff0,0x1ff4,0x3ff2},\n  {0x07e1,0x03df,0x07c9,0x07d6,0x0fca,0x0fd0,0x0fe5,0x0fe6,0x1feb,0x1fef,0x3ff3,0x3ff4,0x3ff5},\n  {0x0fe0,0x07ce,0x07d5,0x0fc6,0x0fd1,0x0fe1,0x1fe0,0x1fe8,0x1ff0,0x3ff1,0x3ff8,0x3ff6,0x7ffc},\n  {0x0fe8,0x07df,0x0fc9,0x0fd7,0x0fdc,0x1fdc,0x1fdf,0x1fed,0x1ff5,0x3ff9,0x3ffb,0x7ffd,0x7ffe},\n  {0x1fe7,0x0fcc,0x0fd6,0x0fdf,0x1fde,0x1fda,0x1fe5,0x1ff2,0x3ffa,0x3ff7,0x3ffc,0x3ffd,0x7fff}\n};\n\nconst UWord16 huff_ctab10[13][13]=\n{\n  {0x0022,0x0008,0x001d,0x0026,0x005f,0x00d3,0x01cf,0x03d0,0x03d7,0x03ed,0x07f0,0x07f6,0x0ffd},\n  {0x0007,0x0000,0x0001,0x0009,0x0020,0x0054,0x0060,0x00d5,0x00dc,0x01d4,0x03cd,0x03de,0x07e7},\n  {0x001c,0x0002,0x0006,0x000c,0x001e,0x0028,0x005b,0x00cd,0x00d9,0x01ce,0x01dc,0x03d9,0x03f1},\n  {0x0025,0x000b,0x000a,0x000d,0x0024,0x0057,0x0061,0x00cc,0x00dd,0x01cc,0x01de,0x03d3,0x03e7},\n  {0x005d,0x0021,0x001f,0x0023,0x0027,0x0059,0x0064,0x00d8,0x00df,0x01d2,0x01e2,0x03dd,0x03ee},\n  {0x00d1,0x0055,0x0029,0x0056,0x0058,0x0062,0x00ce,0x00e0,0x00e2,0x01da,0x03d4,0x03e3,0x07eb},\n  {0x01c9,0x005e,0x005a,0x005c,0x0063,0x00ca,0x00da,0x01c7,0x01ca,0x01e0,0x03db,0x03e8,0x07ec},\n  {0x01e3,0x00d2,0x00cb,0x00d0,0x00d7,0x00db,0x01c6,0x01d5,0x01d8,0x03ca,0x03da,0x07ea,0x07f1},\n  {0x01e1,0x00d4,0x00cf,0x00d6,0x00de,0x00e1,0x01d0,0x01d6,0x03d1,0x03d5,0x03f2,0x07ee,0x07fb},\n  {0x03e9,0x01cd,0x01c8,0x01cb,0x01d1,0x01d7,0x01df,0x03cf,0x03e0,0x03ef,0x07e6,0x07f8,0x0ffa},\n  {0x03eb,0x01dd,0x01d3,0x01d9,0x01db,0x03d2,0x03cc,0x03dc,0x03ea,0x07ed,0x07f3,0x07f9,0x0ff9},\n  {0x07f2,0x03ce,0x01e4,0x03cb,0x03d8,0x03d6,0x03e2,0x03e5,0x07e8,0x07f4,0x07f5,0x07f7,0x0ffb},\n  {0x07fa,0x03ec,0x03df,0x03e1,0x03e4,0x03e6,0x03f0,0x07e9,0x07ef,0x0ff8,0x0ffe,0x0ffc,0x0fff}\n};\n\nconst UWord16 huff_ctab11[17][17]=\n{\n  {0x0000,0x0006,0x0019,0x003d,0x009c,0x00c6,0x01a7,0x0390,0x03c2,0x03df,0x07e6,0x07f3,0x0ffb,0x07ec,0x0ffa,0x0ffe,0x038e},\n  {0x0005,0x0001,0x0008,0x0014,0x0037,0x0042,0x0092,0x00af,0x0191,0x01a5,0x01b5,0x039e,0x03c0,0x03a2,0x03cd,0x07d6,0x00ae},\n  {0x0017,0x0007,0x0009,0x0018,0x0039,0x0040,0x008e,0x00a3,0x00b8,0x0199,0x01ac,0x01c1,0x03b1,0x0396,0x03be,0x03ca,0x009d},\n  {0x003c,0x0015,0x0016,0x001a,0x003b,0x0044,0x0091,0x00a5,0x00be,0x0196,0x01ae,0x01b9,0x03a1,0x0391,0x03a5,0x03d5,0x0094},\n  {0x009a,0x0036,0x0038,0x003a,0x0041,0x008c,0x009b,0x00b0,0x00c3,0x019e,0x01ab,0x01bc,0x039f,0x038f,0x03a9,0x03cf,0x0093},\n  {0x00bf,0x003e,0x003f,0x0043,0x0045,0x009e,0x00a7,0x00b9,0x0194,0x01a2,0x01ba,0x01c3,0x03a6,0x03a7,0x03bb,0x03d4,0x009f},\n  {0x01a0,0x008f,0x008d,0x0090,0x0098,0x00a6,0x00b6,0x00c4,0x019f,0x01af,0x01bf,0x0399,0x03bf,0x03b4,0x03c9,0x03e7,0x00a8},\n  {0x01b6,0x00ab,0x00a4,0x00aa,0x00b2,0x00c2,0x00c5,0x0198,0x01a4,0x01b8,0x038c,0x03a4,0x03c4,0x03c6,0x03dd,0x03e8,0x00ad},\n  {0x03af,0x0192,0x00bd,0x00bc,0x018e,0x0197,0x019a,0x01a3,0x01b1,0x038d,0x0398,0x03b7,0x03d3,0x03d1,0x03db,0x07dd,0x00b4},\n  {0x03de,0x01a9,0x019b,0x019c,0x01a1,0x01aa,0x01ad,0x01b3,0x038b,0x03b2,0x03b8,0x03ce,0x03e1,0x03e0,0x07d2,0x07e5,0x00b7},\n  {0x07e3,0x01bb,0x01a8,0x01a6,0x01b0,0x01b2,0x01b7,0x039b,0x039a,0x03ba,0x03b5,0x03d6,0x07d7,0x03e4,0x07d8,0x07ea,0x00ba},\n  {0x07e8,0x03a0,0x01bd,0x01b4,0x038a,0x01c4,0x0392,0x03aa,0x03b0,0x03bc,0x03d7,0x07d4,0x07dc,0x07db,0x07d5,0x07f0,0x00c1},\n  {0x07fb,0x03c8,0x03a3,0x0395,0x039d,0x03ac,0x03ae,0x03c5,0x03d8,0x03e2,0x03e6,0x07e4,0x07e7,0x07e0,0x07e9,0x07f7,0x0190},\n  {0x07f2,0x0393,0x01be,0x01c0,0x0394,0x0397,0x03ad,0x03c3,0x03c1,0x03d2,0x07da,0x07d9,0x07df,0x07eb,0x07f4,0x07fa,0x0195},\n  {0x07f8,0x03bd,0x039c,0x03ab,0x03a8,0x03b3,0x03b9,0x03d0,0x03e3,0x03e5,0x07e2,0x07de,0x07ed,0x07f1,0x07f9,0x07fc,0x0193},\n  {0x0ffd,0x03dc,0x03b6,0x03c7,0x03cc,0x03cb,0x03d9,0x03da,0x07d3,0x07e1,0x07ee,0x07ef,0x07f5,0x07f6,0x0ffc,0x0fff,0x019d},\n  {0x01c2,0x00b5,0x00a1,0x0096,0x0097,0x0095,0x0099,0x00a0,0x00a2,0x00ac,0x00a9,0x00b1,0x00b3,0x00bb,0x00c0,0x018f,0x0004}\n};\n\nconst UWord32 huff_ctabscf[121]=\n{\n  0x0003ffe8,\n  0x0003ffe6,\n  0x0003ffe7,\n  0x0003ffe5,\n  0x0007fff5,\n  0x0007fff1,\n  0x0007ffed,\n  0x0007fff6,\n  0x0007ffee,\n  0x0007ffef,\n  0x0007fff0,\n  0x0007fffc,\n  0x0007fffd,\n  0x0007ffff,\n  0x0007fffe,\n  0x0007fff7,\n  0x0007fff8,\n  0x0007fffb,\n  0x0007fff9,\n  0x0003ffe4,\n  0x0007fffa,\n  0x0003ffe3,\n  0x0001ffef,\n  0x0001fff0,\n  0x0000fff5,\n  0x0001ffee,\n  0x0000fff2,\n  0x0000fff3,\n  0x0000fff4,\n  0x0000fff1,\n  0x00007ff6,\n  0x00007ff7,\n  0x00003ff9,\n  0x00003ff5,\n  0x00003ff7,\n  0x00003ff3,\n  0x00003ff6,\n  0x00003ff2,\n  0x00001ff7,\n  0x00001ff5,\n  0x00000ff9,\n  0x00000ff7,\n  0x00000ff6,\n  0x000007f9,\n  0x00000ff4,\n  0x000007f8,\n  0x000003f9,\n  0x000003f7,\n  0x000003f5,\n  0x000001f8,\n  0x000001f7,\n  0x000000fa,\n  0x000000f8,\n  0x000000f6,\n  0x00000079,\n  0x0000003a,\n  0x00000038,\n  0x0000001a,\n  0x0000000b,\n  0x00000004,\n  0x00000000,\n  0x0000000a,\n  0x0000000c,\n  0x0000001b,\n  0x00000039,\n  0x0000003b,\n  0x00000078,\n  0x0000007a,\n  0x000000f7,\n  0x000000f9,\n  0x000001f6,\n  0x000001f9,\n  0x000003f4,\n  0x000003f6,\n  0x000003f8,\n  0x000007f5,\n  0x000007f4,\n  0x000007f6,\n  0x000007f7,\n  0x00000ff5,\n  0x00000ff8,\n  0x00001ff4,\n  0x00001ff6,\n  0x00001ff8,\n  0x00003ff8,\n  0x00003ff4,\n  0x0000fff0,\n  0x00007ff4,\n  0x0000fff6,\n  0x00007ff5,\n  0x0003ffe2,\n  0x0007ffd9,\n  0x0007ffda,\n  0x0007ffdb,\n  0x0007ffdc,\n  0x0007ffdd,\n  0x0007ffde,\n  0x0007ffd8,\n  0x0007ffd2,\n  0x0007ffd3,\n  0x0007ffd4,\n  0x0007ffd5,\n  0x0007ffd6,\n  0x0007fff2,\n  0x0007ffdf,\n  0x0007ffe7,\n  0x0007ffe8,\n  0x0007ffe9,\n  0x0007ffea,\n  0x0007ffeb,\n  0x0007ffe6,\n  0x0007ffe0,\n  0x0007ffe1,\n  0x0007ffe2,\n  0x0007ffe3,\n  0x0007ffe4,\n  0x0007ffe5,\n  0x0007ffd7,\n  0x0007ffec,\n  0x0007fff4,\n  0x0007fff3\n};\n\nconst Word32 m_log2_table[INT_BITS] = {\n  0x00000000,0x4ae00d00,0x2934f080,0x15c01a3f,\n  0x0b31fb80,0x05aeb4e0,0x02dcf2d0,0x016fe50c,\n  0x00b84e23,0x005c3e10,0x002e24ca,0x001713d6,\n  0x000b8a47,0x0005c53b,0x0002e2a3,0x00017153,\n  0x0000b8aa,0x00005c55,0x00002e2b,0x00001715,\n  0x00000b8b,0x000005c5,0x000002e3,0x00000171,\n  0x000000b9,0x0000005c,0x0000002e,0x00000017,\n  0x0000000c,0x00000006,0x00000003,0x00000001\n};\n\n\n/*\n  3 bit resolution\n*/\nconst Word32 tnsCoeff3[8] =\n{\n  0x81f1d1d4,\n  0x9126147c,\n  0xadb922f7,\n  0xd438af09,\n  0x00000000,\n  0x37898087,\n  0x64130dfa,\n  0x7cca6ffb,\n};\n\nconst Word32 tnsCoeff3Borders[8] =\n{\n  0x80000000,  /* -4 */\n  0x87b826de,  /* -3 */\n  0x9df24153,  /* -2 */\n  0xbfffffe5,  /* -1 */\n  0xe9c5e578,  /*  0 */\n  0x1c7b90f0,  /*  1 */\n  0x4fce83aa,  /*  2 */\n  0x7352f2c4,  /*  3 */\n};\n\n\n/*\n  4 bit resolution\n*/\n\nconst Word32 tnsCoeff4[16] =\n{\n  0x808bc84b,\n  0x84e2e57d,\n  0x8d6b49fb,\n  0x99da9207,\n  0xa9c45707,\n  0xbc9dde78,\n  0xd1c2d4fc,\n  0xe87ae539,\n  0x00000000,\n  0x1a9cd9c0,\n  0x340ff23b,\n  0x4b3c8bf7,\n  0x5f1f5e80,\n  0x6ed9eb84,\n  0x79bc3880,\n  0x7f4c7e89\n};\n\nconst Word32 tnsCoeff4Borders[16]=\n{\n  0x80000000,  /* -8 */\n  0x822defef,  /* -7 */\n  0x88a4bfe5,  /* -6 */\n  0x932c159c,  /* -5 */\n  0xa16827c1,  /* -4 */\n  0xb2dcde26,  /* -3 */\n  0xc6f20b91,  /* -2 */\n  0xdcf89c64,  /* -1 */\n  0xf4308ce1,  /*  0 */\n  0x0d613054,  /*  1 */\n  0x278dde80,  /*  2 */\n  0x4000001b,  /*  3 */\n  0x55a6127c,  /*  4 */\n  0x678dde8f,  /*  5 */\n  0x74ef0ed8,  /*  6 */\n  0x7d33f0db   /*  7 */\n};\n\n\nconst unsigned char bitrevTab[17 + 129] =\n{\n/* 64 */\n0x01, 0x08, 0x02, 0x04, 0x03, 0x0c, 0x05, 0x0a, 0x07, 0x0e, 0x0b, 0x0d, 0x00, 0x06, 0x09, 0x0f,\n0x00,\n\n/* 512 */\n0x01, 0x40, 0x02, 0x20, 0x03, 0x60, 0x04, 0x10, 0x05, 0x50, 0x06, 0x30, 0x07, 0x70, 0x09, 0x48,\n0x0a, 0x28, 0x0b, 0x68, 0x0c, 0x18, 0x0d, 0x58, 0x0e, 0x38, 0x0f, 0x78, 0x11, 0x44, 0x12, 0x24,\n0x13, 0x64, 0x15, 0x54, 0x16, 0x34, 0x17, 0x74, 0x19, 0x4c, 0x1a, 0x2c, 0x1b, 0x6c, 0x1d, 0x5c,\n0x1e, 0x3c, 0x1f, 0x7c, 0x21, 0x42, 0x23, 0x62, 0x25, 0x52, 0x26, 0x32, 0x27, 0x72, 0x29, 0x4a,\n0x2b, 0x6a, 0x2d, 0x5a, 0x2e, 0x3a, 0x2f, 0x7a, 0x31, 0x46, 0x33, 0x66, 0x35, 0x56, 0x37, 0x76,\n0x39, 0x4e, 0x3b, 0x6e, 0x3d, 0x5e, 0x3f, 0x7e, 0x43, 0x61, 0x45, 0x51, 0x47, 0x71, 0x4b, 0x69,\n0x4d, 0x59, 0x4f, 0x79, 0x53, 0x65, 0x57, 0x75, 0x5b, 0x6d, 0x5f, 0x7d, 0x67, 0x73, 0x6f, 0x7b,\n0x00, 0x08, 0x14, 0x1c, 0x22, 0x2a, 0x36, 0x3e, 0x41, 0x49, 0x55, 0x5d, 0x63, 0x6b, 0x77, 0x7f,\n0x00,\n};\n"
  },
  {
    "path": "jni/src/aacenc.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\taacenc.c\n\n\tContent:\taac encoder interface functions\n\n*******************************************************************************/\n\n#include \"voAAC.h\"\n#include \"typedef.h\"\n#include \"aacenc_core.h\"\n#include \"aac_rom.h\"\n#include \"cmnMemory.h\"\n#include \"memalign.h\"\n\n/**\n* Init the audio codec module and return codec handle\n* \\param phCodec [OUT] Return the video codec handle\n* \\param vType\t[IN] The codec type if the module support multi codec.\n* \\param pUserData\t[IN] The init param. It is memory operator or alloced memory\n* \\retval VO_ERR_NONE Succeeded.\n*/\nVO_U32 VO_API voAACEncInit(VO_HANDLE * phCodec,VO_AUDIO_CODINGTYPE vType, VO_CODEC_INIT_USERDATA *pUserData)\n{\n\tAAC_ENCODER*hAacEnc;\n\tAACENC_CONFIG config;\n\tint error;\n\n#ifdef USE_DEAULT_MEM\n\tVO_MEM_OPERATOR voMemoprator;\n#endif\n\tVO_MEM_OPERATOR *pMemOP;\n\tint interMem;\n\n\tinterMem = 0;\n\terror = 0;\n\n\t/* init the memory operator */\n\tif(pUserData == NULL || pUserData->memflag != VO_IMF_USERMEMOPERATOR || pUserData->memData == NULL )\n\t{\n#ifdef USE_DEAULT_MEM\n\t\tvoMemoprator.Alloc = cmnMemAlloc;\n\t\tvoMemoprator.Copy = cmnMemCopy;\n\t\tvoMemoprator.Free = cmnMemFree;\n\t\tvoMemoprator.Set = cmnMemSet;\n\t\tvoMemoprator.Check = cmnMemCheck;\n\n\t\tinterMem = 1;\n\n\t\tpMemOP = &voMemoprator;\n#else\n\t\t*phCodec = NULL;\n\t\treturn VO_ERR_INVALID_ARG;\n#endif\n\t}\n\telse\n\t{\n\t\tpMemOP = (VO_MEM_OPERATOR *)pUserData->memData;\n\t}\n\n\t/* init the aac encoder handle */\n\thAacEnc = (AAC_ENCODER*)mem_malloc(pMemOP, sizeof(AAC_ENCODER), 32, VO_INDEX_ENC_AAC);\n\tif(NULL == hAacEnc)\n\t{\n\t\terror = 1;\n\t}\n\n\tif(!error)\n\t{\n\t\t/* init the aac encoder intra memory */\n\t\thAacEnc->intbuf = (short *)mem_malloc(pMemOP, AACENC_BLOCKSIZE*MAX_CHANNELS*sizeof(short), 32, VO_INDEX_ENC_AAC);\n\t\tif(NULL == hAacEnc->intbuf)\n\t\t{\n\t\t\terror = 1;\n\t\t}\n\t}\n\n\tif (!error) {\n\t\t/* init the aac encoder psychoacoustic */\n\t\terror = (PsyNew(&hAacEnc->psyKernel, MAX_CHANNELS, pMemOP) ||\n\t\t\tPsyOutNew(&hAacEnc->psyOut, pMemOP));\n\t}\n\n\tif (!error) {\n\t\t/* init the aac encoder quantization elements */\n\t\terror = QCOutNew(&hAacEnc->qcOut,MAX_CHANNELS, pMemOP);\n\t}\n\n\tif (!error) {\n\t\t/* init the aac encoder quantization state */\n\t\terror = QCNew(&hAacEnc->qcKernel, pMemOP);\n\t}\n\n\t/* uninit the aac encoder if error is nozero */\n\tif(error)\n\t{\n\t\tAacEncClose(hAacEnc, pMemOP);\n\t\tif(hAacEnc)\n\t\t{\n\t\t\tmem_free(pMemOP, hAacEnc, VO_INDEX_ENC_AAC);\n\t\t\thAacEnc = NULL;\n\t\t}\n\t\t*phCodec = NULL;\n\t\treturn VO_ERR_OUTOF_MEMORY;\n\t}\n\n\t/* init the aac encoder memory operator  */\n#ifdef USE_DEAULT_MEM\n\tif(interMem)\n\t{\n\t\thAacEnc->voMemoprator.Alloc = cmnMemAlloc;\n\t\thAacEnc->voMemoprator.Copy = cmnMemCopy;\n\t\thAacEnc->voMemoprator.Free = cmnMemFree;\n\t\thAacEnc->voMemoprator.Set = cmnMemSet;\n\t\thAacEnc->voMemoprator.Check = cmnMemCheck;\n\n\t\tpMemOP = &hAacEnc->voMemoprator;\n\t}\n#endif\n\t/* init the aac encoder default parameter  */\n\tif(hAacEnc->initOK == 0)\n\t{\n\t\t AACENC_CONFIG config;\n\t\t config.adtsUsed = 1;\n\t\t config.bitRate = 128000;\n\t\t config.nChannelsIn = 2;\n\t\t config.nChannelsOut = 2;\n\t\t config.sampleRate = 44100;\n\t\t config.bandWidth = 20000;\n\n\t\t AacEncOpen(hAacEnc, config);\n\t}\n\n\thAacEnc->voMemop = pMemOP;\n\n\t*phCodec = hAacEnc;\n\n\treturn VO_ERR_NONE;\n}\n\n/**\n* Set input audio data.\n* \\param hCodec [IN]] The Codec Handle which was created by Init function.\n* \\param pInput [IN] The input buffer param.\n* \\param pOutBuffer [OUT] The output buffer info.\n* \\retval VO_ERR_NONE Succeeded.\n*/\nVO_U32 VO_API voAACEncSetInputData(VO_HANDLE hCodec, VO_CODECBUFFER * pInput)\n{\n\tAAC_ENCODER *hAacEnc;\n\tint  length;\n\n\tif(NULL == hCodec || NULL == pInput || NULL == pInput->Buffer)\n\t{\n\t\treturn VO_ERR_INVALID_ARG;\n\t}\n\n\thAacEnc = (AAC_ENCODER *)hCodec;\n\n\t/* init input pcm buffer and length*/\n\thAacEnc->inbuf = (short *)pInput->Buffer;\n\thAacEnc->inlen = pInput->Length / sizeof(short);\n\thAacEnc->uselength = 0;\n\n\thAacEnc->encbuf = hAacEnc->inbuf;\n\thAacEnc->enclen = hAacEnc->inlen;\n\n\t/* rebuild intra pcm buffer and length*/\n\tif(hAacEnc->intlen)\n\t{\n\t\tlength = min(hAacEnc->config.nChannelsIn*AACENC_BLOCKSIZE - hAacEnc->intlen, hAacEnc->inlen);\n\t\thAacEnc->voMemop->Copy(VO_INDEX_ENC_AAC, hAacEnc->intbuf + hAacEnc->intlen,\n\t\t\thAacEnc->inbuf, length*sizeof(short));\n\n\t\thAacEnc->encbuf = hAacEnc->intbuf;\n\t\thAacEnc->enclen = hAacEnc->intlen + length;\n\n\t\thAacEnc->inbuf += length;\n\t\thAacEnc->inlen -= length;\n\t}\n\n\treturn VO_ERR_NONE;\n}\n\n/**\n* Get the outut audio data\n* \\param hCodec [IN]] The Codec Handle which was created by Init function.\n* \\param pOutBuffer [OUT] The output audio data\n* \\param pOutInfo [OUT] The dec module filled audio format and used the input size.\n*\t\t\t\t\t\t pOutInfo->InputUsed is total used the input size.\n* \\retval  VO_ERR_NONE Succeeded.\n*\t\t\tVO_ERR_INPUT_BUFFER_SMALL. The input was finished or the input data was not enought.\n*/\nVO_U32 VO_API voAACEncGetOutputData(VO_HANDLE hCodec, VO_CODECBUFFER * pOutput, VO_AUDIO_OUTPUTINFO * pOutInfo)\n{\n\tAAC_ENCODER* hAacEnc = (AAC_ENCODER*)hCodec;\n\tWord16 numAncDataBytes=0;\n\tWord32  inbuflen;\n\tint ret, length;\n\tif(NULL == hAacEnc)\n\t\treturn VO_ERR_INVALID_ARG;\n\n\t inbuflen = AACENC_BLOCKSIZE*hAacEnc->config.nChannelsIn;\n\n\t /* check the input pcm buffer and length*/\n\t if(NULL == hAacEnc->encbuf || hAacEnc->enclen < inbuflen)\n\t {\n\t\tlength = hAacEnc->enclen;\n\t\tif(hAacEnc->intlen == 0)\n\t\t{\n\t\t\thAacEnc->voMemop->Copy(VO_INDEX_ENC_AAC, hAacEnc->intbuf,\n\t\t\t\thAacEnc->encbuf, length*sizeof(short));\n\t\t\thAacEnc->uselength += length*sizeof(short);\n\t\t}\n\t\telse\n\t\t{\n\t\t\thAacEnc->uselength += (length - hAacEnc->intlen)*sizeof(short);\n\t\t}\n\n\t\thAacEnc->intlen = length;\n\n\t\tpOutput->Length = 0;\n\t\tif(pOutInfo)\n\t\t\tpOutInfo->InputUsed = hAacEnc->uselength;\n\t\treturn VO_ERR_INPUT_BUFFER_SMALL;\n\t }\n\n\t /* check the output aac buffer and length*/\n\t if(NULL == pOutput || NULL == pOutput->Buffer || pOutput->Length < (6144/8)*hAacEnc->config.nChannelsOut/(sizeof(Word32)))\n\t\t return VO_ERR_OUTPUT_BUFFER_SMALL;\n\n\t /* aac encoder core function */\n\t AacEncEncode( hAacEnc,\n\t\t\t(Word16*)hAacEnc->encbuf,\n\t\t\tNULL,\n\t\t\t&numAncDataBytes,\n\t\t\tpOutput->Buffer,\n\t\t\t&pOutput->Length);\n\n\t /* update the input pcm buffer and length*/\n\t if(hAacEnc->intlen)\n\t {\n\t\tlength = inbuflen - hAacEnc->intlen;\n\t\thAacEnc->encbuf = hAacEnc->inbuf;\n\t\thAacEnc->enclen = hAacEnc->inlen;\n\t\thAacEnc->uselength += length*sizeof(short);\n\t\thAacEnc->intlen = 0;\n\t }\n\t else\n\t {\n\t\t hAacEnc->encbuf = hAacEnc->encbuf + inbuflen;\n\t\t hAacEnc->enclen = hAacEnc->enclen - inbuflen;\n\t\t hAacEnc->uselength += inbuflen*sizeof(short);\n\t }\n\n\t /* update the output aac information */\n\tif(pOutInfo)\n\t{\n\t\tpOutInfo->Format.Channels = hAacEnc->config.nChannelsOut;\n\t\tpOutInfo->Format.SampleRate = hAacEnc->config.sampleRate;\n\t\tpOutInfo->Format.SampleBits = 16;\n\t\tpOutInfo->InputUsed = hAacEnc->uselength;\n\t}\n\n\t return VO_ERR_NONE;\n}\n\n/**\n* Uninit the Codec.\n* \\param hCodec [IN]] The Codec Handle which was created by Init function.\n* \\retval VO_ERR_NONE Succeeded.\n*/\nVO_U32 VO_API voAACEncUninit(VO_HANDLE hCodec)\n{\n\tAAC_ENCODER* hAacEnc = (AAC_ENCODER*)hCodec;\n\n\tif(NULL != hAacEnc)\n\t{\n\t\t/* close the aac encoder */\n\t\tAacEncClose(hAacEnc, hAacEnc->voMemop);\n\n\t\t/* free the aac encoder handle*/\n\t\tmem_free(hAacEnc->voMemop, hAacEnc, VO_INDEX_ENC_AAC);\n\t\thAacEnc = NULL;\n\t}\n\n\treturn VO_ERR_NONE;\n}\n\n/**\n* Set the param for special target.\n* \\param hCodec [IN]] The Codec Handle which was created by Init function.\n* \\param uParamID [IN] The param ID.\n* \\param pData [IN] The param value depend on the ID>\n* \\retval VO_ERR_NONE Succeeded.\n*/\nVO_U32 VO_API voAACEncSetParam(VO_HANDLE hCodec, VO_S32 uParamID, VO_PTR pData)\n{\n\tAACENC_CONFIG config;\n\tAACENC_PARAM* pAAC_param;\n\tVO_AUDIO_FORMAT *pWAV_Format;\n\tAAC_ENCODER* hAacEnc = (AAC_ENCODER*)hCodec;\n\tint ret, i, bitrate, tmp;\n\tint SampleRateIdx;\n\n\tif(NULL == hAacEnc)\n\t\treturn VO_ERR_INVALID_ARG;\n\n\tswitch(uParamID)\n\t{\n\tcase VO_PID_AAC_ENCPARAM:  /* init aac encoder parameter*/\n\t\tAacInitDefaultConfig(&config);\n\t\tif(pData == NULL)\n\t\t\treturn VO_ERR_INVALID_ARG;\n\t\tpAAC_param = (AACENC_PARAM*)pData;\n\t\tconfig.adtsUsed = pAAC_param->adtsUsed;\n\t\tconfig.bitRate = pAAC_param->bitRate;\n\t\tconfig.nChannelsIn = pAAC_param->nChannels;\n\t\tconfig.nChannelsOut = pAAC_param->nChannels;\n\t\tconfig.sampleRate = pAAC_param->sampleRate;\n\n\t\t/* check the channel */\n\t\tif(config.nChannelsIn< 1  || config.nChannelsIn > MAX_CHANNELS  ||\n             config.nChannelsOut < 1 || config.nChannelsOut > MAX_CHANNELS || config.nChannelsIn < config.nChannelsOut)\n\t\t\t return VO_ERR_AUDIO_UNSCHANNEL;\n\n\t\t/* check the samplerate */\n\t\tret = -1;\n\t\tfor(i = 0; i < NUM_SAMPLE_RATES; i++)\n\t\t{\n\t\t\tif(config.sampleRate == sampRateTab[i])\n\t\t\t{\n\t\t\t\tret = 0;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif(ret < 0)\n\t\t\treturn VO_ERR_AUDIO_UNSSAMPLERATE;\n\n\t\tSampleRateIdx = i;\n\n\t\ttmp = 441;\n\t\tif(config.sampleRate%8000 == 0)\n\t\t\ttmp =480;\n\t\t/* check the bitrate */\n\t\tif(config.bitRate!=0 && (config.bitRate/config.nChannelsOut < 4000) ||\n           (config.bitRate/config.nChannelsOut > 160000) ||\n\t\t   (config.bitRate > config.sampleRate*6*config.nChannelsOut))\n\t\t{\n\t\t\tconfig.bitRate = 640*config.sampleRate/tmp*config.nChannelsOut;\n\n\t\t\tif(config.bitRate/config.nChannelsOut < 4000)\n\t\t\t\tconfig.bitRate = 4000 * config.nChannelsOut;\n\t\t\telse if(config.bitRate > config.sampleRate*6*config.nChannelsOut)\n\t\t\t\tconfig.bitRate = config.sampleRate*6*config.nChannelsOut;\n\t\t\telse if(config.bitRate/config.nChannelsOut > 160000)\n\t\t\t\tconfig.bitRate = config.nChannelsOut*160000;\n\t\t}\n\n\t\t/* check the bandwidth */\n\t\tbitrate = config.bitRate / config.nChannelsOut;\n\t\tbitrate = bitrate * tmp / config.sampleRate;\n\n\t\tfor (i = 0; rates[i]; i++)\n\t\t{\n\t\t\tif (rates[i] >= bitrate)\n\t\t\t\tbreak;\n\t\t}\n\n\t\tconfig.bandWidth = BandwithCoefTab[i][SampleRateIdx];\n\n\t\t/* init aac encoder core */\n\t\tret = AacEncOpen(hAacEnc, config);\n\t\tif(ret)\n\t\t\treturn VO_ERR_AUDIO_UNSFEATURE;\n\t\tbreak;\n\tcase VO_PID_AUDIO_FORMAT:\t/* init pcm channel and samplerate*/\n\t\tAacInitDefaultConfig(&config);\n\t\tif(pData == NULL)\n\t\t\treturn VO_ERR_INVALID_ARG;\n\t\tpWAV_Format = (VO_AUDIO_FORMAT*)pData;\n\t\tconfig.adtsUsed = 1;\n\t\tconfig.nChannelsIn = pWAV_Format->Channels;\n\t\tconfig.nChannelsOut = pWAV_Format->Channels;\n\t\tconfig.sampleRate = pWAV_Format->SampleRate;\n\n\t\t/* check the channel */\n\t\tif(config.nChannelsIn< 1  || config.nChannelsIn > MAX_CHANNELS  ||\n             config.nChannelsOut < 1 || config.nChannelsOut > MAX_CHANNELS || config.nChannelsIn < config.nChannelsOut)\n\t\t\t return VO_ERR_AUDIO_UNSCHANNEL;\n\n\t\t/* check the samplebits */\n\t\tif(pWAV_Format->SampleBits != 16)\n\t\t{\n\t\t\treturn VO_ERR_AUDIO_UNSFEATURE;\n\t\t}\n\n\t\t/* check the samplerate */\n\t\tret = -1;\n\t\tfor(i = 0; i < NUM_SAMPLE_RATES; i++)\n\t\t{\n\t\t\tif(config.sampleRate == sampRateTab[i])\n\t\t\t{\n\t\t\t\tret = 0;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif(ret < 0)\n\t\t\treturn VO_ERR_AUDIO_UNSSAMPLERATE;\n\n\t\tSampleRateIdx = i;\n\n\t\t/* update the bitrates */\n\t\ttmp = 441;\n\t\tif(config.sampleRate%8000 == 0)\n\t\t\ttmp =480;\n\n\t\tconfig.bitRate = 640*config.sampleRate/tmp*config.nChannelsOut;\n\n\t\tif(config.bitRate/config.nChannelsOut < 4000)\n\t\t\tconfig.bitRate = 4000 * config.nChannelsOut;\n\t\telse if(config.bitRate > config.sampleRate*6*config.nChannelsOut)\n\t\t\tconfig.bitRate = config.sampleRate*6*config.nChannelsOut;\n\t\telse if(config.bitRate/config.nChannelsOut > 160000)\n\t\t\tconfig.bitRate = config.nChannelsOut*160000;\n\n\t\t/* check the bandwidth */\n\t\tbitrate = config.bitRate / config.nChannelsOut;\n\t\tbitrate = bitrate * tmp / config.sampleRate;\n\n\t\tfor (i = 0; rates[i]; i++)\n\t\t{\n\t\t\tif (rates[i] >= bitrate)\n\t\t\t\tbreak;\n\t\t}\n\n\t\tconfig.bandWidth = BandwithCoefTab[i][SampleRateIdx];\n\n\t\t/* init aac encoder core */\n\t\tret = AacEncOpen(hAacEnc, config);\n\t\tif(ret)\n\t\t\treturn VO_ERR_AUDIO_UNSFEATURE;\n\t\tbreak;\n\tdefault:\n\t\treturn VO_ERR_WRONG_PARAM_ID;\n\t}\n\n\treturn VO_ERR_NONE;\n}\n\n/**\n* Get the param for special target.\n* \\param hCodec [IN]] The Codec Handle which was created by Init function.\n* \\param uParamID [IN] The param ID.\n* \\param pData [IN] The param value depend on the ID>\n* \\retval VO_ERR_NONE Succeeded.\n*/\nVO_U32 VO_API voAACEncGetParam(VO_HANDLE hCodec, VO_S32 uParamID, VO_PTR pData)\n{\n\treturn VO_ERR_NONE;\n}\n\n/**\n * Get audio codec API interface\n * \\param pEncHandle [out] Return the AAC Encoder handle.\n * \\retval VO_ERR_OK Succeeded.\n */\nVO_S32 VO_API voGetAACEncAPI(VO_AUDIO_CODECAPI * pDecHandle)\n{\n\tif(pDecHandle == NULL)\n\t\treturn VO_ERR_INVALID_ARG;\n\n\tpDecHandle->Init = voAACEncInit;\n\tpDecHandle->SetInputData = voAACEncSetInputData;\n\tpDecHandle->GetOutputData = voAACEncGetOutputData;\n\tpDecHandle->SetParam = voAACEncSetParam;\n\tpDecHandle->GetParam = voAACEncGetParam;\n\tpDecHandle->Uninit = voAACEncUninit;\n\n\treturn VO_ERR_NONE;\n}\n"
  },
  {
    "path": "jni/src/aacenc_core.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\taacenc_core.c\n\n\tContent:\taac encoder core functions\n\n*******************************************************************************/\n\n#include \"typedef.h\"\n#include \"aacenc_core.h\"\n#include \"bitenc.h\"\n\n#include \"psy_configuration.h\"\n#include \"psy_main.h\"\n#include \"qc_main.h\"\n#include \"psy_main.h\"\n#include \"channel_map.h\"\n#include \"aac_rom.h\"\n\n/********************************************************************************\n*\n* function name: AacInitDefaultConfig\n* description:  gives reasonable default configuration\n*\n**********************************************************************************/\nvoid AacInitDefaultConfig(AACENC_CONFIG *config)\n{\n  /* default configurations */\n  config->adtsUsed        = 1;\n  config->nChannelsIn     = 2;\n  config->nChannelsOut    = 2;\n  config->bitRate         = 128000;\n  config->bandWidth       = 0;\n}\n\n/********************************************************************************\n*\n* function name: AacEncOpen\n* description:  allocate and initialize a new encoder instance\n* returns:      0 if success\n*\n**********************************************************************************/\nWord16  AacEncOpen(  AAC_ENCODER*      hAacEnc,        /* pointer to an encoder handle, initialized on return */\n                     const  AACENC_CONFIG     config   /* pre-initialized config struct */\n                     )\n{\n  Word32 i;\n  Word32 error = 0;\n  Word16 profile = 1;\n\n  ELEMENT_INFO *elInfo = NULL;\n\n  if (hAacEnc==0) {\n    error=1;\n  }\n\n  if (!error) {\n    hAacEnc->config = config;\n  }\n\n  if (!error) {\n    error = InitElementInfo (config.nChannelsOut,\n                             &hAacEnc->elInfo);\n  }\n\n  if (!error) {\n    elInfo = &hAacEnc->elInfo;\n  }\n\n  if (!error) {\n    /* use or not tns tool for long and short block */\n\t Word16 tnsMask=3;\n\n\t/* init encoder psychoacoustic */\n    error = psyMainInit(&hAacEnc->psyKernel,\n                        config.sampleRate,\n                        config.bitRate,\n                        elInfo->nChannelsInEl,\n                        tnsMask,\n                        hAacEnc->config.bandWidth);\n  }\n\n /* use or not adts header */\n  if(!error) {\n\t  hAacEnc->qcOut.qcElement.adtsUsed = config.adtsUsed;\n  }\n\n  /* init encoder quantization */\n  if (!error) {\n    struct QC_INIT qcInit;\n\n    /*qcInit.channelMapping = &hAacEnc->channelMapping;*/\n    qcInit.elInfo = &hAacEnc->elInfo;\n\n    qcInit.maxBits = (Word16) (MAXBITS_COEF*elInfo->nChannelsInEl);\n    qcInit.bitRes = qcInit.maxBits;\n    qcInit.averageBits = (Word16) ((config.bitRate * FRAME_LEN_LONG) / config.sampleRate);\n\n    qcInit.padding.paddingRest = config.sampleRate;\n\n    qcInit.meanPe = (Word16) ((10 * FRAME_LEN_LONG * hAacEnc->config.bandWidth) /\n                                              (config.sampleRate>>1));\n\n    qcInit.maxBitFac = (Word16) ((100 * (MAXBITS_COEF-MINBITS_COEF)* elInfo->nChannelsInEl)/\n                                                 (qcInit.averageBits?qcInit.averageBits:1));\n\n    qcInit.bitrate = config.bitRate;\n\n    error = QCInit(&hAacEnc->qcKernel, &qcInit);\n  }\n\n  /* init bitstream encoder */\n  if (!error) {\n    hAacEnc->bseInit.nChannels   = elInfo->nChannelsInEl;\n    hAacEnc->bseInit.bitrate     = config.bitRate;\n    hAacEnc->bseInit.sampleRate  = config.sampleRate;\n    hAacEnc->bseInit.profile     = profile;\n  }\n\n  return error;\n}\n\n/********************************************************************************\n*\n* function name: AacEncEncode\n* description:  encode pcm to aac data core function\n* returns:      0 if success\n*\n**********************************************************************************/\nWord16 AacEncEncode(AAC_ENCODER *aacEnc,\t\t/*!< an encoder handle */\n                    Word16 *timeSignal,         /*!< BLOCKSIZE*nChannels audio samples, interleaved */\n                    const UWord8 *ancBytes,     /*!< pointer to ancillary data bytes */\n                    Word16 *numAncBytes,\t\t/*!< number of ancillary Data Bytes */\n                    UWord8 *outBytes,           /*!< pointer to output buffer (must be large MINBITS_COEF/8*MAX_CHANNELS bytes) */\n                    VO_U32 *numOutBytes         /*!< number of bytes in output buffer after processing */\n                    )\n{\n  ELEMENT_INFO *elInfo = &aacEnc->elInfo;\n  Word16 globUsedBits;\n  Word16 ancDataBytes, ancDataBytesLeft;\n\n  ancDataBytes = ancDataBytesLeft = *numAncBytes;\n\n  /* init output aac data buffer and length */\n  aacEnc->hBitStream = CreateBitBuffer(&aacEnc->bitStream, outBytes, *numOutBytes);\n\n  /* psychoacoustic process */\n  psyMain(aacEnc->config.nChannelsOut,\n          elInfo,\n          timeSignal,\n          &aacEnc->psyKernel.psyData[elInfo->ChannelIndex[0]],\n          &aacEnc->psyKernel.tnsData[elInfo->ChannelIndex[0]],\n          &aacEnc->psyKernel.psyConfLong,\n          &aacEnc->psyKernel.psyConfShort,\n          &aacEnc->psyOut.psyOutChannel[elInfo->ChannelIndex[0]],\n          &aacEnc->psyOut.psyOutElement,\n          aacEnc->psyKernel.pScratchTns,\n\t\t  aacEnc->config.sampleRate);\n\n  /* adjust bitrate and frame length */\n  AdjustBitrate(&aacEnc->qcKernel,\n                aacEnc->config.bitRate,\n                aacEnc->config.sampleRate);\n\n  /* quantization and coding process */\n  QCMain(&aacEnc->qcKernel,\n         &aacEnc->qcKernel.elementBits,\n         &aacEnc->qcKernel.adjThr.adjThrStateElem,\n         &aacEnc->psyOut.psyOutChannel[elInfo->ChannelIndex[0]],\n         &aacEnc->psyOut.psyOutElement,\n         &aacEnc->qcOut.qcChannel[elInfo->ChannelIndex[0]],\n         &aacEnc->qcOut.qcElement,\n         elInfo->nChannelsInEl,\n\t\t min(ancDataBytesLeft,ancDataBytes));\n\n  ancDataBytesLeft = ancDataBytesLeft - ancDataBytes;\n\n  globUsedBits = FinalizeBitConsumption(&aacEnc->qcKernel,\n                         &aacEnc->qcOut);\n\n  /* write bitstream process */\n  WriteBitstream(aacEnc->hBitStream,\n                 *elInfo,\n                 &aacEnc->qcOut,\n                 &aacEnc->psyOut,\n                 &globUsedBits,\n                 ancBytes,\n\t\t\t\t aacEnc->psyKernel.sampleRateIdx);\n\n  updateBitres(&aacEnc->qcKernel,\n               &aacEnc->qcOut);\n\n  /* write out the bitstream */\n  *numOutBytes = GetBitsAvail(aacEnc->hBitStream) >> 3;\n\n  return 0;\n}\n\n\n/********************************************************************************\n*\n* function name:AacEncClose\n* description: deallocate an encoder instance\n*\n**********************************************************************************/\nvoid AacEncClose (AAC_ENCODER* hAacEnc, VO_MEM_OPERATOR *pMemOP)\n{\n  if (hAacEnc) {\n    QCDelete(&hAacEnc->qcKernel, pMemOP);\n\n    QCOutDelete(&hAacEnc->qcOut, pMemOP);\n\n    PsyDelete(&hAacEnc->psyKernel, pMemOP);\n\n    PsyOutDelete(&hAacEnc->psyOut, pMemOP);\n\n    DeleteBitBuffer(&hAacEnc->hBitStream);\n\n\tif(hAacEnc->intbuf)\n\t{\n\t\tmem_free(pMemOP, hAacEnc->intbuf, VO_INDEX_ENC_AAC);\n\t\thAacEnc->intbuf = NULL;\n\t}\n  }\n}\n"
  },
  {
    "path": "jni/src/adj_thr.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tadj_thr.c\n\n\tContent:\tThreshold compensation functions\n\n*******************************************************************************/\n\n#include \"basic_op.h\"\n#include \"oper_32b.h\"\n#include \"adj_thr_data.h\"\n#include \"adj_thr.h\"\n#include \"qc_data.h\"\n#include \"line_pe.h\"\n#include <string.h>\n\n\n#define  minSnrLimit    0x6666 /* 1 dB */\n#define  PEBITS_COEF\t0x170a /* 0.18*(1 << 15)*/\n\n#define  HOLE_THR_LONG\t0x2873\t/* 0.316*(1 << 15) */\n#define  HOLE_THR_SHORT 0x4000  /* 0.5  *(1 << 15) */\n\n#define  MS_THRSPREAD_COEF 0x7333  /* 0.9 * (1 << 15) */\n\n#define\t MIN_SNR_COEF\t   0x651f  /* 3.16* (1 << (15 - 2)) */\n\n/* values for avoid hole flag */\nenum _avoid_hole_state {\n  NO_AH              =0,\n  AH_INACTIVE        =1,\n  AH_ACTIVE          =2\n};\n\n/********************************************************************************\n*\n* function name:bits2pe\n* description: convert from bits to pe\n*\t\t\t   pe = 1.18*desiredBits\n*\n**********************************************************************************/\nWord16 bits2pe(const Word16 bits) {\n  return (bits + ((PEBITS_COEF * bits) >> 15));\n}\n\n/********************************************************************************\n*\n* function name:calcThreshExp\n* description: loudness calculation (threshold to the power of redExp)\n*\t\t\t   thr(n)^0.25\n*\n**********************************************************************************/\nstatic void calcThreshExp(Word32 thrExp[MAX_CHANNELS][MAX_GROUPED_SFB],\n                          PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],\n                          const Word16 nChannels)\n{\n  Word16 ch, sfb, sfbGrp;\n  Word32 *pthrExp, *psfbThre;\n  for (ch=0; ch<nChannels; ch++) {\n    PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];\n\t for(sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt; sfbGrp+= psyOutChan->sfbPerGroup)\n\t  pthrExp = &(thrExp[ch][sfbGrp]);\n\t  psfbThre = psyOutChan->sfbThreshold + sfbGrp;\n\t  for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {\n\t\t*pthrExp = rsqrt(rsqrt(*psfbThre,INT_BITS),INT_BITS);\n\t\tpthrExp++; psfbThre++;\n      }\n  }\n}\n\n/********************************************************************************\n*\n* function name:adaptMinSnr\n* description: reduce minSnr requirements for bands with relative low energies\n*\n**********************************************************************************/\nstatic void adaptMinSnr(PSY_OUT_CHANNEL     psyOutChannel[MAX_CHANNELS],\n                        Word16              logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],\n                        MINSNR_ADAPT_PARAM *msaParam,\n                        const Word16        nChannels)\n{\n  Word16 ch, sfb, sfbOffs, shift;\n  Word32 nSfb, avgEn;\n  Word16 log_avgEn = 0;\n  Word32 startRatio_x_avgEn = 0;\n\n\n  for (ch=0; ch<nChannels; ch++) {\n    PSY_OUT_CHANNEL* psyOutChan = &psyOutChannel[ch];\n\n    /* calc average energy per scalefactor band */\n    avgEn = 0;\n    nSfb = 0;\n    for (sfbOffs=0; sfbOffs<psyOutChan->sfbCnt; sfbOffs+=psyOutChan->sfbPerGroup) {\n      for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {\n        avgEn = L_add(avgEn, psyOutChan->sfbEnergy[sfbOffs+sfb]);\n        nSfb = nSfb + 1;\n      }\n    }\n\n    if (nSfb > 0) {\n\t  avgEn = avgEn / nSfb;\n\n      log_avgEn = iLog4(avgEn);\n      startRatio_x_avgEn = fixmul(msaParam->startRatio, avgEn);\n    }\n\n\n    /* reduce minSnr requirement by minSnr^minSnrRed dependent on avgEn/sfbEn */\n    for (sfbOffs=0; sfbOffs<psyOutChan->sfbCnt; sfbOffs+=psyOutChan->sfbPerGroup) {\n      for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {\n        if (psyOutChan->sfbEnergy[sfbOffs+sfb] < startRatio_x_avgEn) {\n          Word16 dbRatio, minSnrRed;\n          Word32 snrRed;\n          Word16 newMinSnr;\n\n          dbRatio = log_avgEn - logSfbEnergy[ch][sfbOffs+sfb];\n          dbRatio = dbRatio + (dbRatio << 1);\n\n          minSnrRed = 110 - ((dbRatio + (dbRatio << 1)) >> 2);\n          minSnrRed = max(minSnrRed, 20); /* 110: (0.375(redOffs)+1)*80,\n                                               3: 0.00375(redRatioFac)*80\n                                               20: 0.25(maxRed) * 80 */\n\n          snrRed = minSnrRed * iLog4((psyOutChan->sfbMinSnr[sfbOffs+sfb] << 16));\n          /*\n             snrRedI si now scaled by 80 (minSnrRed) and 4 (ffr_iLog4)\n          */\n\n          newMinSnr = round16(pow2_xy(snrRed,80*4));\n\n          psyOutChan->sfbMinSnr[sfbOffs+sfb] = min(newMinSnr, minSnrLimit);\n        }\n      }\n    }\n  }\n\n}\n\n\n/********************************************************************************\n*\n* function name:initAvoidHoleFlag\n* description: determine bands where avoid hole is not necessary resp. possible\n*\n**********************************************************************************/\nstatic void initAvoidHoleFlag(Word16 ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],\n                              PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],\n                              PSY_OUT_ELEMENT* psyOutElement,\n                              const Word16 nChannels,\n                              AH_PARAM *ahParam)\n{\n  Word16 ch, sfb, sfbGrp, shift;\n  Word32 threshold;\n  Word32* psfbSpreadEn;\n\n  for (ch=0; ch<nChannels; ch++) {\n    PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];\n\n    if (psyOutChan->windowSequence != SHORT_WINDOW) {\n      for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){\n         psfbSpreadEn = psyOutChan->sfbSpreadedEnergy + sfbGrp;\n\t\t for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {\n\t\t\t*psfbSpreadEn = *psfbSpreadEn >> 1;  /* 0.5 */\n\t\t\t++psfbSpreadEn;\n        }\n      }\n    }\n    else {\n      for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){\n\t\tpsfbSpreadEn = psyOutChan->sfbSpreadedEnergy + sfbGrp;\n        for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {\n          *psfbSpreadEn = (*psfbSpreadEn >> 1) + (*psfbSpreadEn >> 3);  /* 0.63 */\n\t\t  ++psfbSpreadEn;\n        }\n      }\n    }\n  }\n\n  /* increase minSnr for local peaks, decrease it for valleys */\n  if (ahParam->modifyMinSnr) {\n    for(ch=0; ch<nChannels; ch++) {\n      PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];\n\n      if (psyOutChan->windowSequence != SHORT_WINDOW)\n        threshold = HOLE_THR_LONG;\n      else\n        threshold = HOLE_THR_SHORT;\n\n      for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){\n        Word16 *psfbMinSnr = psyOutChan->sfbMinSnr + sfbGrp;\n\t\tfor (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {\n          Word32 sfbEn, sfbEnm1, sfbEnp1, avgEn;\n\n          if (sfb > 0)\n            sfbEnm1 = psyOutChan->sfbEnergy[sfbGrp+sfb-1];\n          else\n            sfbEnm1 = psyOutChan->sfbEnergy[sfbGrp];\n\n          if (sfb < (psyOutChan->maxSfbPerGroup-1))\n            sfbEnp1 = psyOutChan->sfbEnergy[sfbGrp+sfb+1];\n          else\n            sfbEnp1 = psyOutChan->sfbEnergy[sfbGrp+sfb];\n          avgEn = (sfbEnm1 + sfbEnp1) >> 1;\n          sfbEn = psyOutChan->sfbEnergy[sfbGrp+sfb];\n\n          if (sfbEn > avgEn && avgEn > 0) {\n            Word32 tmpMinSnr;\n            shift = norm_l(sfbEn);\n\t\t\ttmpMinSnr = Div_32(L_mpy_ls(avgEn, minSnrLimit) << shift, sfbEn << shift );\n            tmpMinSnr = max(tmpMinSnr, HOLE_THR_LONG);\n            tmpMinSnr = max(tmpMinSnr, threshold);\n            *psfbMinSnr = min(*psfbMinSnr, tmpMinSnr);\n          }\n          /* valley ? */\n\n          if ((sfbEn < (avgEn >> 1)) && (sfbEn > 0)) {\n            Word32 tmpMinSnr;\n            Word32 minSnrEn = L_mpy_wx(avgEn, *psfbMinSnr);\n\n            if(minSnrEn < sfbEn) {\n\t\t\t  shift = norm_l(sfbEn);\n              tmpMinSnr = Div_32( minSnrEn << shift, sfbEn<<shift);\n            }\n            else {\n              tmpMinSnr = MAX_16;\n            }\n            tmpMinSnr = min(minSnrLimit, tmpMinSnr);\n\n            *psfbMinSnr =\n              (min((tmpMinSnr >>  2), mult(*psfbMinSnr, MIN_SNR_COEF)) << 2);\n          }\n\t\t  psfbMinSnr++;\n        }\n      }\n    }\n  }\n\n  /* stereo: adapt the minimum requirements sfbMinSnr of mid and\n     side channels */\n\n  if (nChannels == 2) {\n    PSY_OUT_CHANNEL *psyOutChanM = &psyOutChannel[0];\n    PSY_OUT_CHANNEL *psyOutChanS = &psyOutChannel[1];\n    for (sfb=0; sfb<psyOutChanM->sfbCnt; sfb++) {\n      if (psyOutElement->toolsInfo.msMask[sfb]) {\n        Word32 sfbEnM = psyOutChanM->sfbEnergy[sfb];\n        Word32 sfbEnS = psyOutChanS->sfbEnergy[sfb];\n        Word32 maxSfbEn = max(sfbEnM, sfbEnS);\n        Word32 maxThr = L_mpy_wx(maxSfbEn, psyOutChanM->sfbMinSnr[sfb]) >> 1;\n\n        if(maxThr >= sfbEnM) {\n          psyOutChanM->sfbMinSnr[sfb] = MAX_16;\n        }\n        else {\n          shift = norm_l(sfbEnM);\n\t\t  psyOutChanM->sfbMinSnr[sfb] = min(max(psyOutChanM->sfbMinSnr[sfb],\n\t\t\t  round16(Div_32(maxThr<<shift, sfbEnM << shift))), minSnrLimit);\n        }\n\n        if(maxThr >= sfbEnS) {\n          psyOutChanS->sfbMinSnr[sfb] = MAX_16;\n        }\n        else {\n\t\t  shift = norm_l(sfbEnS);\n          psyOutChanS->sfbMinSnr[sfb] = min(max(psyOutChanS->sfbMinSnr[sfb],\n\t\t\t  round16(Div_32(maxThr << shift, sfbEnS << shift))), minSnrLimit);\n        }\n\n\n        if (sfbEnM > psyOutChanM->sfbSpreadedEnergy[sfb])\n          psyOutChanS->sfbSpreadedEnergy[sfb] = L_mpy_ls(sfbEnS, MS_THRSPREAD_COEF);\n\n        if (sfbEnS > psyOutChanS->sfbSpreadedEnergy[sfb])\n          psyOutChanM->sfbSpreadedEnergy[sfb] = L_mpy_ls(sfbEnM, MS_THRSPREAD_COEF);\n      }\n    }\n  }\n\n\n  /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */\n  for(ch=0; ch<nChannels; ch++) {\n    PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];\n    for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){\n      Word16 *pahFlag = ahFlag[ch] + sfbGrp;\n\t  for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {\n\n        if ((psyOutChan->sfbSpreadedEnergy[sfbGrp+sfb] > psyOutChan->sfbEnergy[sfbGrp+sfb]) ||\n            (psyOutChan->sfbEnergy[sfbGrp+sfb] <= psyOutChan->sfbThreshold[sfbGrp+sfb]) ||\n            (psyOutChan->sfbMinSnr[sfbGrp+sfb] == MAX_16)) {\n          *pahFlag++ = NO_AH;\n        }\n        else {\n          *pahFlag++ = AH_INACTIVE;\n        }\n      }\n      for (sfb=psyOutChan->maxSfbPerGroup; sfb<psyOutChan->sfbPerGroup; sfb++) {\n        *pahFlag++ = NO_AH;\n      }\n    }\n  }\n}\n\n/********************************************************************************\n*\n* function name:calcPeNoAH\n* description: sum the pe data only for bands where avoid hole is inactive\n*\n**********************************************************************************/\nstatic void calcPeNoAH(Word16          *pe,\n                       Word16          *constPart,\n                       Word16          *nActiveLines,\n                       PE_DATA         *peData,\n                       Word16           ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],\n                       PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],\n                       const Word16     nChannels)\n{\n  Word16 ch, sfb, sfbGrp;\n  int ipe, iconstPart, inActiveLines;\n\n  ipe = 0;\n  iconstPart = 0;\n  inActiveLines = 0;\n  for(ch=0; ch<nChannels; ch++) {\n    PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];\n    PE_CHANNEL_DATA *peChanData = &peData->peChannelData[ch];\n    for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){\n      for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {\n\n        if (ahFlag[ch][sfbGrp+sfb] < AH_ACTIVE) {\n          ipe = ipe + peChanData->sfbPe[sfbGrp+sfb];\n          iconstPart = iconstPart + peChanData->sfbConstPart[sfbGrp+sfb];\n          inActiveLines = inActiveLines + peChanData->sfbNActiveLines[sfbGrp+sfb];\n        }\n      }\n    }\n  }\n\n  *pe = saturate(ipe);\n  *constPart = saturate(iconstPart);\n  *nActiveLines = saturate(inActiveLines);\n}\n\n/********************************************************************************\n*\n* function name:reduceThresholds\n* description: apply reduction formula\n*\n**********************************************************************************/\nstatic void reduceThresholds(PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],\n                             Word16           ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],\n                             Word32           thrExp[MAX_CHANNELS][MAX_GROUPED_SFB],\n                             const Word16     nChannels,\n                             const Word32     redVal)\n{\n  Word32 sfbThrReduced;\n  Word32 *psfbEn, *psfbThr;\n  Word16 ch, sfb, sfbGrp;\n\n  for(ch=0; ch<nChannels; ch++) {\n    PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];\n    for(sfbGrp=0; sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup) {\n \t  psfbEn  = psyOutChan->sfbEnergy + sfbGrp;\n      psfbThr = psyOutChan->sfbThreshold + sfbGrp;\n\t  for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {\n\n        if (*psfbEn > *psfbThr) {\n          /* threshold reduction formula */\n          Word32 tmp = thrExp[ch][sfbGrp+sfb] + redVal;\n          tmp = fixmul(tmp, tmp);\n          sfbThrReduced = fixmul(tmp, tmp);\n          /* avoid holes */\n          tmp = L_mpy_ls(*psfbEn, psyOutChan->sfbMinSnr[sfbGrp+sfb]);\n\n          if ((sfbThrReduced > tmp) &&\n              (ahFlag[ch][sfbGrp+sfb] != NO_AH)){\n            sfbThrReduced = max(tmp, *psfbThr);\n            ahFlag[ch][sfbGrp+sfb] = AH_ACTIVE;\n          }\n\t\t  *psfbThr = sfbThrReduced;\n        }\n\n\t\tpsfbEn++;  psfbThr++;\n      }\n    }\n  }\n}\n\n\n/********************************************************************************\n*\n* function name:correctThresh\n* description: if pe difference deltaPe between desired pe and real pe is small enough,\n*             the difference can be distributed among the scale factor bands.\n*\n**********************************************************************************/\nstatic void correctThresh(PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],\n                          Word16           ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],\n                          PE_DATA          *peData,\n                          Word32           thrExp[MAX_CHANNELS][MAX_GROUPED_SFB],\n                          const Word32     redVal,\n                          const Word16     nChannels,\n                          const Word32     deltaPe)\n{\n  Word16 ch, sfb, sfbGrp,shift;\n  PSY_OUT_CHANNEL *psyOutChan;\n  PE_CHANNEL_DATA *peChanData;\n  Word32 deltaSfbPe;\n  Word32 normFactor;\n  Word32 *psfbPeFactors;\n  Word16 *psfbNActiveLines, *pahFlag;\n  Word32 sfbEn, sfbThr;\n  Word32 sfbThrReduced;\n\n  /* for each sfb calc relative factors for pe changes */\n  normFactor = 1;\n  for(ch=0; ch<nChannels; ch++) {\n    psyOutChan = &psyOutChannel[ch];\n    peChanData = &peData->peChannelData[ch];\n    for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){\n      psfbPeFactors = peData->sfbPeFactors[ch] + sfbGrp;\n\t  psfbNActiveLines = peChanData->sfbNActiveLines + sfbGrp;\n\t  pahFlag = ahFlag[ch] + sfbGrp;\n\t  for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {\n        Word32 redThrExp = thrExp[ch][sfbGrp+sfb] + redVal;\n\n        if (((*pahFlag < AH_ACTIVE) || (deltaPe > 0)) && (redThrExp > 0) && (redThrExp >= *psfbNActiveLines)) {\n\n          *psfbPeFactors = (*psfbNActiveLines) * (0x7fffffff / redThrExp);\n          normFactor = L_add(normFactor, *psfbPeFactors);\n        }\n        else {\n          *psfbPeFactors = 0;\n        }\n\t\tpsfbPeFactors++;\n\t\tpahFlag++; psfbNActiveLines++;\n      }\n    }\n  }\n\n\n  /* calculate new thresholds */\n  for(ch=0; ch<nChannels; ch++) {\n    psyOutChan = &psyOutChannel[ch];\n    peChanData = &peData->peChannelData[ch];\n    for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){\n      psfbPeFactors = peData->sfbPeFactors[ch] + sfbGrp;\n\t  psfbNActiveLines = peChanData->sfbNActiveLines + sfbGrp;\n\t  pahFlag = ahFlag[ch] + sfbGrp;\n\t  for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {\n        /* pe difference for this sfb */\n        deltaSfbPe = *psfbPeFactors * deltaPe;\n\n\t\t/* thr3(n) = thr2(n)*2^deltaSfbPe/b(n) */\n        if (*psfbNActiveLines > 0 && (normFactor* (*psfbNActiveLines)) != 0) {\n          /* new threshold */\n          Word32 thrFactor;\n          sfbEn  = psyOutChan->sfbEnergy[sfbGrp+sfb];\n          sfbThr = psyOutChan->sfbThreshold[sfbGrp+sfb];\n\n           if(deltaSfbPe >= 0){\n            /*\n              reduce threshold\n            */\n            thrFactor = pow2_xy(L_negate(deltaSfbPe), (normFactor* (*psfbNActiveLines)));\n\n            sfbThrReduced = L_mpy_ls(sfbThr, round16(thrFactor));\n          }\n          else {\n            /*\n              increase threshold\n            */\n            thrFactor = pow2_xy(deltaSfbPe, (normFactor * (*psfbNActiveLines)));\n\n\n            if(thrFactor > sfbThr) {\n              shift = norm_l(thrFactor);\n\t\t\t  sfbThrReduced = Div_32( sfbThr << shift, thrFactor<<shift );\n            }\n            else {\n              sfbThrReduced = MAX_32;\n            }\n\n          }\n\n          /* avoid hole */\n          sfbEn = L_mpy_ls(sfbEn, psyOutChan->sfbMinSnr[sfbGrp+sfb]);\n\n          if ((sfbThrReduced > sfbEn) &&\n              (*pahFlag == AH_INACTIVE)) {\n            sfbThrReduced = max(sfbEn, sfbThr);\n            *pahFlag = AH_ACTIVE;\n          }\n\n          psyOutChan->sfbThreshold[sfbGrp+sfb] = sfbThrReduced;\n        }\n\n\t\tpahFlag++; psfbNActiveLines++; psfbPeFactors++;\n      }\n    }\n  }\n}\n\n\n/********************************************************************************\n*\n* function name:reduceMinSnr\n* description: if the desired pe can not be reached, reduce pe by reducing minSnr\n*\n**********************************************************************************/\nstatic void reduceMinSnr(PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],\n                         PE_DATA         *peData,\n                         Word16           ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],\n                         const Word16     nChannels,\n                         const Word16     desiredPe)\n{\n  Word16 ch, sfb, sfbSubWin;\n  Word16 deltaPe;\n\n  /* start at highest freq down to 0 */\n  sfbSubWin = psyOutChannel[0].maxSfbPerGroup;\n  while (peData->pe > desiredPe && sfbSubWin > 0) {\n\n    sfbSubWin = sfbSubWin - 1;\n    /* loop over all subwindows */\n    for (sfb=sfbSubWin; sfb<psyOutChannel[0].sfbCnt;\n        sfb+=psyOutChannel[0].sfbPerGroup) {\n      /* loop over all channels */\n\t\tPE_CHANNEL_DATA* peChan = peData->peChannelData;\n\t\tPSY_OUT_CHANNEL* psyOutCh = psyOutChannel;\n\t\tfor (ch=0; ch<nChannels; ch++) {\n        if (ahFlag[ch][sfb] != NO_AH &&\n            psyOutCh->sfbMinSnr[sfb] < minSnrLimit) {\n          psyOutCh->sfbMinSnr[sfb] = minSnrLimit;\n          psyOutCh->sfbThreshold[sfb] =\n            L_mpy_ls(psyOutCh->sfbEnergy[sfb], psyOutCh->sfbMinSnr[sfb]);\n\n          /* calc new pe */\n          deltaPe = ((peChan->sfbNLines4[sfb] + (peChan->sfbNLines4[sfb] >> 1)) >> 2) -\n              peChan->sfbPe[sfb];\n          peData->pe = peData->pe + deltaPe;\n          peChan->pe = peChan->pe + deltaPe;\n        }\n\t\tpeChan += 1; psyOutCh += 1;\n      }\n      /* stop if enough has been saved */\n\n      if (peData->pe <= desiredPe)\n        break;\n    }\n  }\n}\n\n/********************************************************************************\n*\n* function name:allowMoreHoles\n* description: if the desired pe can not be reached, some more scalefactor bands\n*              have to be quantized to zero\n*\n**********************************************************************************/\nstatic void allowMoreHoles(PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],\n                           PSY_OUT_ELEMENT *psyOutElement,\n                           PE_DATA         *peData,\n                           Word16           ahFlag[MAX_CHANNELS][MAX_GROUPED_SFB],\n                           const AH_PARAM  *ahParam,\n                           const Word16     nChannels,\n                           const Word16     desiredPe)\n{\n  Word16 ch, sfb;\n  Word16 actPe, shift;\n\n  actPe = peData->pe;\n\n  /* for MS allow hole in the channel with less energy */\n\n  if (nChannels==2 &&\n      psyOutChannel[0].windowSequence==psyOutChannel[1].windowSequence) {\n    PSY_OUT_CHANNEL *psyOutChanL = &psyOutChannel[0];\n    PSY_OUT_CHANNEL *psyOutChanR = &psyOutChannel[1];\n    for (sfb=0; sfb<psyOutChanL->sfbCnt; sfb++) {\n      Word32 minEn;\n\n      if (psyOutElement->toolsInfo.msMask[sfb]) {\n        /* allow hole in side channel ? */\n        minEn = L_mpy_ls(psyOutChanL->sfbEnergy[sfb], (minSnrLimit * psyOutChanL->sfbMinSnr[sfb]) >> 16);\n\n        if (ahFlag[1][sfb] != NO_AH &&\n            minEn > psyOutChanR->sfbEnergy[sfb]) {\n          ahFlag[1][sfb] = NO_AH;\n          psyOutChanR->sfbThreshold[sfb] = L_add(psyOutChanR->sfbEnergy[sfb], psyOutChanR->sfbEnergy[sfb]);\n          actPe = actPe - peData->peChannelData[1].sfbPe[sfb];\n        }\n        /* allow hole in mid channel ? */\n        else {\n        minEn = L_mpy_ls(psyOutChanR->sfbEnergy[sfb], (minSnrLimit * psyOutChanR->sfbMinSnr[sfb]) >> 16);\n\n          if (ahFlag[0][sfb]!= NO_AH &&\n              minEn > psyOutChanL->sfbEnergy[sfb]) {\n            ahFlag[0][sfb] = NO_AH;\n            psyOutChanL->sfbThreshold[sfb] = L_add(psyOutChanL->sfbEnergy[sfb], psyOutChanL->sfbEnergy[sfb]);\n            actPe = actPe - peData->peChannelData[0].sfbPe[sfb];\n          }\n        }\n\n        if (actPe < desiredPe)\n          break;\n      }\n    }\n  }\n\n  /* subsequently erase bands */\n  if (actPe > desiredPe) {\n    Word16 startSfb[2];\n    Word32 avgEn, minEn;\n    Word16 ahCnt;\n    Word16 enIdx;\n    Word16 enDiff;\n    Word32 en[4];\n    Word16 minSfb, maxSfb;\n    Flag   done;\n\n    /* do not go below startSfb */\n    for (ch=0; ch<nChannels; ch++) {\n\n      if (psyOutChannel[ch].windowSequence != SHORT_WINDOW)\n        startSfb[ch] = ahParam->startSfbL;\n      else\n        startSfb[ch] = ahParam->startSfbS;\n    }\n\n    avgEn = 0;\n    minEn = MAX_32;\n    ahCnt = 0;\n    for (ch=0; ch<nChannels; ch++) {\n      PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];\n      for (sfb=startSfb[ch]; sfb<psyOutChan->sfbCnt; sfb++) {\n\n        if ((ahFlag[ch][sfb] != NO_AH) &&\n            (psyOutChan->sfbEnergy[sfb] > psyOutChan->sfbThreshold[sfb])) {\n          minEn = min(minEn, psyOutChan->sfbEnergy[sfb]);\n          avgEn = L_add(avgEn, psyOutChan->sfbEnergy[sfb]);\n          ahCnt++;\n        }\n      }\n    }\n\n    if(ahCnt) {\n      Word32 iahCnt;\n      shift = norm_l(ahCnt);\n\t  iahCnt = Div_32( 1 << shift, ahCnt << shift );\n      avgEn = fixmul(avgEn, iahCnt);\n    }\n\n    enDiff = iLog4(avgEn) - iLog4(minEn);\n    /* calc some energy borders between minEn and avgEn */\n    for (enIdx=0; enIdx<4; enIdx++) {\n      Word32 enFac;\n      enFac = ((6-(enIdx << 1)) * enDiff);\n      en[enIdx] = fixmul(avgEn, pow2_xy(L_negate(enFac),7*4));\n    }\n\n    /* start with lowest energy border at highest sfb */\n    maxSfb = psyOutChannel[0].sfbCnt - 1;\n    minSfb = startSfb[0];\n\n    if (nChannels == 2) {\n      maxSfb = max(maxSfb, (psyOutChannel[1].sfbCnt - 1));\n      minSfb = min(minSfb, startSfb[1]);\n    }\n\n    sfb = maxSfb;\n    enIdx = 0;\n    done = 0;\n    while (!done) {\n\n      for (ch=0; ch<nChannels; ch++) {\n        PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];\n\n        if (sfb>=startSfb[ch] && sfb<psyOutChan->sfbCnt) {\n          /* sfb energy below border ? */\n\n          if (ahFlag[ch][sfb] != NO_AH && psyOutChan->sfbEnergy[sfb] < en[enIdx]){\n            /* allow hole */\n            ahFlag[ch][sfb] = NO_AH;\n            psyOutChan->sfbThreshold[sfb] = L_add(psyOutChan->sfbEnergy[sfb], psyOutChan->sfbEnergy[sfb]);\n            actPe = actPe - peData->peChannelData[ch].sfbPe[sfb];\n          }\n\n          if (actPe < desiredPe) {\n            done = 1;\n            break;\n          }\n        }\n      }\n      sfb = sfb - 1;\n\n      if (sfb < minSfb) {\n        /* restart with next energy border */\n        sfb = maxSfb;\n        enIdx = enIdx + 1;\n\n        if (enIdx - 4 >= 0)\n          done = 1;\n      }\n    }\n  }\n}\n\n/********************************************************************************\n*\n* function name:adaptThresholdsToPe\n* description: two guesses for the reduction value and one final correction of the\n*              thresholds\n*\n**********************************************************************************/\nstatic void adaptThresholdsToPe(PSY_OUT_CHANNEL     psyOutChannel[MAX_CHANNELS],\n                                PSY_OUT_ELEMENT    *psyOutElement,\n                                Word16              logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],\n                                PE_DATA            *peData,\n                                const Word16        nChannels,\n                                const Word16        desiredPe,\n                                AH_PARAM           *ahParam,\n                                MINSNR_ADAPT_PARAM *msaParam)\n{\n  Word16 noRedPe, redPe, redPeNoAH;\n  Word16 constPart, constPartNoAH;\n  Word16 nActiveLines, nActiveLinesNoAH;\n  Word16 desiredPeNoAH;\n  Word32 redVal, avgThrExp;\n  Word32 iter;\n\n  calcThreshExp(peData->thrExp, psyOutChannel, nChannels);\n\n  adaptMinSnr(psyOutChannel, logSfbEnergy, msaParam, nChannels);\n\n  initAvoidHoleFlag(peData->ahFlag, psyOutChannel, psyOutElement, nChannels, ahParam);\n\n  noRedPe = peData->pe;\n  constPart = peData->constPart;\n  nActiveLines = peData->nActiveLines;\n\n  /* first guess of reduction value t^0.25 = 2^((a-pen)/4*b) */\n  avgThrExp = pow2_xy((constPart - noRedPe), (nActiveLines << 2));\n\n  /* r1 = 2^((a-per)/4*b) - t^0.25 */\n  redVal = pow2_xy((constPart - desiredPe), (nActiveLines << 2)) - avgThrExp;\n\n  /* reduce thresholds */\n  reduceThresholds(psyOutChannel, peData->ahFlag, peData->thrExp, nChannels, redVal);\n\n  /* pe after first guess */\n  calcSfbPe(peData, psyOutChannel, nChannels);\n  redPe = peData->pe;\n\n  iter = 0;\n  do {\n    /* pe for bands where avoid hole is inactive */\n    calcPeNoAH(&redPeNoAH, &constPartNoAH, &nActiveLinesNoAH,\n               peData, peData->ahFlag, psyOutChannel, nChannels);\n\n    desiredPeNoAH = desiredPe -(redPe - redPeNoAH);\n\n    if (desiredPeNoAH < 0) {\n      desiredPeNoAH = 0;\n    }\n\n    /* second guess */\n\n    if (nActiveLinesNoAH > 0) {\n\n\t\tavgThrExp = pow2_xy((constPartNoAH - redPeNoAH), (nActiveLinesNoAH << 2));\n\n\t\tredVal = (redVal + pow2_xy((constPartNoAH - desiredPeNoAH), (nActiveLinesNoAH << 2))) - avgThrExp;\n\n\t\t/* reduce thresholds */\n\t\treduceThresholds(psyOutChannel, peData->ahFlag, peData->thrExp, nChannels, redVal);\n    }\n\n    calcSfbPe(peData, psyOutChannel, nChannels);\n    redPe = peData->pe;\n\n    iter = iter+1;\n\n  } while ((20 * abs_s(redPe - desiredPe) > desiredPe) && (iter < 2));\n\n\n  if ((100 * redPe < 115 * desiredPe)) {\n    correctThresh(psyOutChannel, peData->ahFlag, peData, peData->thrExp, redVal,\n                  nChannels, desiredPe - redPe);\n  }\n  else {\n    Word16 desiredPe105 = (105 * desiredPe) / 100;\n    reduceMinSnr(psyOutChannel, peData, peData->ahFlag,\n                 nChannels, desiredPe105);\n    allowMoreHoles(psyOutChannel, psyOutElement, peData, peData->ahFlag,\n                   ahParam, nChannels, desiredPe105);\n  }\n}\n\n\n/*****************************************************************************\n*\n* function name: calcBitSave\n* description:  Calculates percentage of bit save, see figure below\n* returns:\n* input:        parameters and bitres-fullness\n* output:       percentage of bit save\n*\n*****************************************************************************/\nstatic Word16 calcBitSave(Word16 fillLevel,\n                          const Word16 clipLow,\n                          const Word16 clipHigh,\n                          const Word16 minBitSave,\n                          const Word16 maxBitSave)\n{\n  Word16 bitsave = 0;\n\n  fillLevel = max(fillLevel, clipLow);\n  fillLevel = min(fillLevel, clipHigh);\n\n  if(clipHigh-clipLow)\n  bitsave = (maxBitSave - (((maxBitSave-minBitSave)*(fillLevel-clipLow))/\n                              (clipHigh-clipLow)));\n\n  return (bitsave);\n}\n\n\n\n/*****************************************************************************\n*\n* function name: calcBitSpend\n* description:  Calculates percentage of bit spend, see figure below\n* returns:\n* input:        parameters and bitres-fullness\n* output:       percentage of bit spend\n*\n*****************************************************************************/\nstatic Word16 calcBitSpend(Word16 fillLevel,\n                           const Word16 clipLow,\n                           const Word16 clipHigh,\n                           const Word16 minBitSpend,\n                           const Word16 maxBitSpend)\n{\n  Word16 bitspend = 1;\n\n  fillLevel = max(fillLevel, clipLow);\n  fillLevel = min(fillLevel, clipHigh);\n\n  if(clipHigh-clipLow)\n  bitspend = (minBitSpend + ((maxBitSpend - minBitSpend)*(fillLevel - clipLow) /\n                                (clipHigh-clipLow)));\n\n  return (bitspend);\n}\n\n\n/*****************************************************************************\n*\n* function name: adjustPeMinMax()\n* description:  adjusts peMin and peMax parameters over time\n* returns:\n* input:        current pe, peMin, peMax\n* output:       adjusted peMin/peMax\n*\n*****************************************************************************/\nstatic void adjustPeMinMax(const Word16 currPe,\n                           Word16      *peMin,\n                           Word16      *peMax)\n{\n  Word16 minFacHi, maxFacHi, minFacLo, maxFacLo;\n  Word16 diff;\n  Word16 minDiff = extract_l(currPe / 6);\n  minFacHi = 30;\n  maxFacHi = 100;\n  minFacLo = 14;\n  maxFacLo = 7;\n\n  diff = currPe - *peMax ;\n\n  if (diff > 0) {\n    *peMin = *peMin + ((diff * minFacHi) / 100);\n    *peMax = *peMax + ((diff * maxFacHi) / 100);\n  } else {\n    diff = *peMin - currPe;\n\n    if (diff > 0) {\n      *peMin = *peMin - ((diff * minFacLo) / 100);\n      *peMax = *peMax - ((diff * maxFacLo) / 100);\n    } else {\n      *peMin = *peMin + ((currPe - *peMin) * minFacHi / 100);\n      *peMax = *peMax - ((*peMax - currPe) * maxFacLo / 100);\n    }\n  }\n\n\n  if ((*peMax - *peMin) < minDiff) {\n    Word16 partLo, partHi;\n\n    partLo = max(0, (currPe - *peMin));\n    partHi = max(0, (*peMax - currPe));\n\n    *peMax = currPe + ((partHi * minDiff) / (partLo + partHi));\n    *peMin = currPe - ((partLo * minDiff) / (partLo + partHi));\n    *peMin = max(0, *peMin);\n  }\n}\n\n\n/*****************************************************************************\n*\n* function name: BitresCalcBitFac\n* description:  calculates factor of spending bits for one frame\n*                1.0 : take all frame dynpart bits\n*                >1.0 : take all frame dynpart bits + bitres\n*                <1.0 : put bits in bitreservoir\n*  returns:      BitFac*100\n*  input:        bitres-fullness, pe, blockType, parameter-settings\n*  output:\n*\n*****************************************************************************/\nstatic Word16 bitresCalcBitFac( const Word16   bitresBits,\n                                const Word16   maxBitresBits,\n                                const Word16   pe,\n                                const Word16   windowSequence,\n                                const Word16   avgBits,\n                                const Word16   maxBitFac,\n                                ADJ_THR_STATE *AdjThr,\n                                ATS_ELEMENT   *adjThrChan)\n{\n  BRES_PARAM *bresParam;\n  Word16 pex;\n  Word16 fillLevel;\n  Word16 bitSave, bitSpend, bitresFac;\n\n  fillLevel = extract_l((100* bitresBits) / maxBitresBits);\n\n  if (windowSequence != SHORT_WINDOW)\n    bresParam = &(AdjThr->bresParamLong);\n  else\n    bresParam = &(AdjThr->bresParamShort);\n\n  pex = max(pe, adjThrChan->peMin);\n  pex = min(pex,adjThrChan->peMax);\n\n  bitSave = calcBitSave(fillLevel,\n                        bresParam->clipSaveLow, bresParam->clipSaveHigh,\n                        bresParam->minBitSave, bresParam->maxBitSave);\n\n  bitSpend = calcBitSpend(fillLevel,\n                          bresParam->clipSpendLow, bresParam->clipSpendHigh,\n                          bresParam->minBitSpend, bresParam->maxBitSpend);\n\n  if(adjThrChan->peMax != adjThrChan->peMin)\n\tbitresFac = (100 - bitSave) + extract_l(((bitSpend + bitSave) * (pex - adjThrChan->peMin)) /\n                    (adjThrChan->peMax - adjThrChan->peMin));\n  else\n\tbitresFac = 0x7fff;\n\n  bitresFac = min(bitresFac,\n                    (100-30 + extract_l((100 * bitresBits) / avgBits)));\n\n  bitresFac = min(bitresFac, maxBitFac);\n\n  adjustPeMinMax(pe, &adjThrChan->peMin, &adjThrChan->peMax);\n\n  return bitresFac;\n}\n\n/*****************************************************************************\n*\n* function name: AdjThrInit\n* description:  init thresholds parameter\n*\n*****************************************************************************/\nvoid AdjThrInit(ADJ_THR_STATE *hAdjThr,\n                const Word32   meanPe,\n                Word32         chBitrate)\n{\n  ATS_ELEMENT* atsElem = &hAdjThr->adjThrStateElem;\n  MINSNR_ADAPT_PARAM *msaParam = &atsElem->minSnrAdaptParam;\n\n  /* common for all elements: */\n  /* parameters for bitres control */\n  hAdjThr->bresParamLong.clipSaveLow   =  20;\n  hAdjThr->bresParamLong.clipSaveHigh  =  95;\n  hAdjThr->bresParamLong.minBitSave    =  -5;\n  hAdjThr->bresParamLong.maxBitSave    =  30;\n  hAdjThr->bresParamLong.clipSpendLow  =  20;\n  hAdjThr->bresParamLong.clipSpendHigh =  95;\n  hAdjThr->bresParamLong.minBitSpend   = -10;\n  hAdjThr->bresParamLong.maxBitSpend   =  40;\n\n  hAdjThr->bresParamShort.clipSaveLow   =  20;\n  hAdjThr->bresParamShort.clipSaveHigh  =  75;\n  hAdjThr->bresParamShort.minBitSave    =   0;\n  hAdjThr->bresParamShort.maxBitSave    =  20;\n  hAdjThr->bresParamShort.clipSpendLow  =  20;\n  hAdjThr->bresParamShort.clipSpendHigh =  75;\n  hAdjThr->bresParamShort.minBitSpend   = -5;\n  hAdjThr->bresParamShort.maxBitSpend   =  50;\n\n  /* specific for each element: */\n\n  /* parameters for bitres control */\n  atsElem->peMin = extract_l(((80*meanPe) / 100));\n  atsElem->peMax = extract_l(((120*meanPe) / 100));\n\n  /* additional pe offset to correct pe2bits for low bitrates */\n  atsElem->peOffset = 0;\n  if (chBitrate < 32000) {\n    atsElem->peOffset = max(50, (100 - extract_l((100 * chBitrate) / 32000)));\n  }\n\n  /* avoid hole parameters */\n  if (chBitrate > 20000) {\n    atsElem->ahParam.modifyMinSnr = TRUE;\n    atsElem->ahParam.startSfbL = 15;\n    atsElem->ahParam.startSfbS = 3;\n  }\n  else {\n    atsElem->ahParam.modifyMinSnr = FALSE;\n    atsElem->ahParam.startSfbL = 0;\n    atsElem->ahParam.startSfbS = 0;\n  }\n\n  /* minSnr adaptation */\n  /* maximum reduction of minSnr goes down to minSnr^maxRed */\n  msaParam->maxRed = 0x20000000;     /* *0.25f */\n  /* start adaptation of minSnr for avgEn/sfbEn > startRatio */\n  msaParam->startRatio = 0x0ccccccd; /* 10 */\n  /* maximum minSnr reduction to minSnr^maxRed is reached for\n     avgEn/sfbEn >= maxRatio */\n  msaParam->maxRatio =  0x0020c49c; /* 1000 */\n  /* helper variables to interpolate minSnr reduction for\n     avgEn/sfbEn between startRatio and maxRatio */\n\n  msaParam->redRatioFac = 0xfb333333; /* -0.75/20 */\n\n  msaParam->redOffs = 0x30000000;  /* msaParam->redRatioFac * 10*log10(msaParam->startRatio) */\n\n\n  /* pe correction */\n  atsElem->peLast = 0;\n  atsElem->dynBitsLast = 0;\n  atsElem->peCorrectionFactor = 100; /* 1.0 */\n\n}\n\n/*****************************************************************************\n*\n* function name: calcPeCorrection\n* description:  calculates the desired perceptual entropy factor\n*\t\t\t\tIt is between 0.85 and 1.15\n*\n*****************************************************************************/\nstatic void calcPeCorrection(Word16 *correctionFac,\n                             const Word16 peAct,\n                             const Word16 peLast,\n                             const Word16 bitsLast)\n{\n  Word32 peAct100 = 100 * peAct;\n  Word32 peLast100 = 100 * peLast;\n  Word16 peBitsLast = bits2pe(bitsLast);\n\n  if ((bitsLast > 0) &&\n      (peAct100 < (150 * peLast)) &&  (peAct100 > (70 * peLast)) &&\n      ((120 * peBitsLast) > peLast100 ) && (( 65 * peBitsLast) < peLast100))\n    {\n      Word16 newFac = (100 * peLast) / peBitsLast;\n      /* dead zone */\n\n      if (newFac < 100) {\n        newFac = min(((110 * newFac) / 100), 100);\n        newFac = max(newFac, 85);\n      }\n      else {\n        newFac = max(((90 * newFac) / 100), 100);\n        newFac = min(newFac, 115);\n      }\n\n      if ((newFac > 100 && *correctionFac < 100) ||\n          (newFac < 100 && *correctionFac > 100)) {\n        *correctionFac = 100;\n      }\n      /* faster adaptation towards 1.0, slower in the other direction */\n\n      if ((*correctionFac < 100 && newFac < *correctionFac) ||\n          (*correctionFac > 100 && newFac > *correctionFac))\n        *correctionFac = (85 * *correctionFac + 15 * newFac) / 100;\n      else\n        *correctionFac = (70 * *correctionFac + 30 * newFac) / 100;\n      *correctionFac = min(*correctionFac, 115);\n      *correctionFac = max(*correctionFac, 85);\n    }\n  else {\n    *correctionFac = 100;\n  }\n}\n\n/********************************************************************************\n*\n* function name: AdjustThresholds\n* description:  Adjust thresholds to the desired bitrate\n*\n**********************************************************************************/\nvoid AdjustThresholds(ADJ_THR_STATE   *adjThrState,\n                      ATS_ELEMENT     *AdjThrStateElement,\n                      PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],\n                      PSY_OUT_ELEMENT *psyOutElement,\n                      Word16          *chBitDistribution,\n                      Word16           logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],\n                      Word16           sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],\n                      QC_OUT_ELEMENT  *qcOE,\n\t\t\t\t\t  ELEMENT_BITS\t  *elBits,\n\t\t\t\t\t  const Word16     nChannels,\n                      const Word16     maxBitFac)\n{\n  PE_DATA peData;\n  Word16 noRedPe, grantedPe, grantedPeCorr;\n  Word16 curWindowSequence;\n  Word16 bitFactor;\n  Word16 avgBits = (elBits->averageBits - (qcOE->staticBitsUsed + qcOE->ancBitsUsed));\n  Word16 bitresBits = elBits->bitResLevel;\n  Word16 maxBitresBits = elBits->maxBits;\n  Word16 sideInfoBits = (qcOE->staticBitsUsed + qcOE->ancBitsUsed);\n  Word16 ch;\n  memset(&peData, 0, sizeof(peData));\n\n  prepareSfbPe(&peData, psyOutChannel, logSfbEnergy, sfbNRelevantLines, nChannels, AdjThrStateElement->peOffset);\n\n  /* pe without reduction */\n  calcSfbPe(&peData, psyOutChannel, nChannels);\n  noRedPe = peData.pe;\n\n\n  curWindowSequence = LONG_WINDOW;\n\n  if (nChannels == 2) {\n\n    if ((psyOutChannel[0].windowSequence == SHORT_WINDOW) ||\n        (psyOutChannel[1].windowSequence == SHORT_WINDOW)) {\n      curWindowSequence = SHORT_WINDOW;\n    }\n  }\n  else {\n    curWindowSequence = psyOutChannel[0].windowSequence;\n  }\n\n\n  /* bit factor */\n  bitFactor = bitresCalcBitFac(bitresBits, maxBitresBits, noRedPe+5*sideInfoBits,\n                               curWindowSequence, avgBits, maxBitFac,\n                               adjThrState,\n                               AdjThrStateElement);\n\n  /* desired pe */\n  grantedPe = ((bitFactor * bits2pe(avgBits)) / 100);\n\n  /* correction of pe value */\n  calcPeCorrection(&(AdjThrStateElement->peCorrectionFactor),\n                   min(grantedPe, noRedPe),\n                   AdjThrStateElement->peLast,\n                   AdjThrStateElement->dynBitsLast);\n  grantedPeCorr = (grantedPe * AdjThrStateElement->peCorrectionFactor) / 100;\n\n\n  if (grantedPeCorr < noRedPe && noRedPe > peData.offset) {\n    /* calc threshold necessary for desired pe */\n    adaptThresholdsToPe(psyOutChannel,\n                        psyOutElement,\n                        logSfbEnergy,\n                        &peData,\n                        nChannels,\n                        grantedPeCorr,\n                        &AdjThrStateElement->ahParam,\n                        &AdjThrStateElement->minSnrAdaptParam);\n  }\n\n  /* calculate relative distribution */\n  for (ch=0; ch<nChannels; ch++) {\n    Word16 peOffsDiff = peData.pe - peData.offset;\n    chBitDistribution[ch] = 200;\n\n    if (peOffsDiff > 0) {\n      Word32 temp = 1000 - (nChannels * 200);\n      chBitDistribution[ch] = chBitDistribution[ch] +\n\t\t  (temp * peData.peChannelData[ch].pe) / peOffsDiff;\n    }\n  }\n\n  /* store pe */\n  qcOE->pe = noRedPe;\n\n  /* update last pe */\n  AdjThrStateElement->peLast = grantedPe;\n}\n\n/********************************************************************************\n*\n* function name: AdjThrUpdate\n* description:  save dynBitsUsed for correction of bits2pe relation\n*\n**********************************************************************************/\nvoid AdjThrUpdate(ATS_ELEMENT *AdjThrStateElement,\n                  const Word16 dynBitsUsed)\n{\n  AdjThrStateElement->dynBitsLast = dynBitsUsed;\n}\n\n\n"
  },
  {
    "path": "jni/src/asm/ARMV5E/AutoCorrelation_v5.s",
    "content": "@/*\n@ ** Copyright 2003-2010, VisualOn, Inc.\n@ **\n@ ** Licensed under the Apache License, Version 2.0 (the \"License\");\n@ ** you may not use this file except in compliance with the License.\n@ ** You may obtain a copy of the License at\n@ **\n@ **     http://www.apache.org/licenses/LICENSE-2.0\n@ **\n@ ** Unless required by applicable law or agreed to in writing, software\n@ ** distributed under the License is distributed on an \"AS IS\" BASIS,\n@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@ ** See the License for the specific language governing permissions and\n@ ** limitations under the License.\n@ */\n\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n@\tFile:\t\tAutoCorrelation_v5.s\n@\n@\tContent:\tAutoCorrelation function armv5 assemble\n@\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n\n\t.section .text\n\t.global\tAutoCorrelation\n\nAutoCorrelation:\n\tstmdb     sp!, {r4 - r11, lr}\n\n  sub     r13, r13, #20\n\n  mov     r5, r0\n  mov     r7, r1\n  mov     r9, r3\n  mov     r2, r2, lsl #16\n  mov     r0, #0\n  mov     r4, r2, asr #16\n  mov     r8, #0\n  cmp     r4, #0\n  ble     L136\n\n\tcmp     r4, #8\n\tmov\t\t  r2, #0\n  blt     L133\n\n\tsub     r12, r4, #8\nL132:\n  ldr     r6, [r5, r2]\n\tadd\t\t  r2, r2, #4\n\tsmulbb  r3, r6, r6\n\tldr     r1, [r5, r2]\n\tsmultt\tr10, r6, r6\n\tmov\t\t  r3, r3, asr #9\n\tsmulbb\tr6, r1, r1\n\tmov\t\t  r10, r10, asr #9\n\tqadd\t  r0, r0, r3\n\tsmultt\tr11, r1, r1\n\tadd     r2, r2, #4\n\tqadd\t  r0, r0, r10\n\tmov\t\t  r6, r6, asr #9\n\tmov\t\t  r11, r11, asr #9\n\tldr\t\t  r1, [r5, r2]\n\tqadd\t  r0, r0, r6\n\tsmulbb\tr10, r1, r1\n\tsmultt\tr6, r1, r1\n\tqadd\t  r0, r0, r11\n\tmov\t\t  r10, r10, asr #9\n\tmov\t\t  r6, r6, asr #9\n\tqadd\t  r0, r0, r10\n\tadd     r2, r2, #4\n\tadd     r8, r8, #6\n\n\tqadd\t  r0, r0, r6\n\tcmp     r8, r12\n  blt     L132\nL133:\n  ldrsh   r6, [r5, r2]\n  mul     r10, r6, r6\n\tadd     r2, r2, #2\n  mov     r1, r10, asr #9\n  qadd    r0, r0, r1\nL134:\n  add     r8, r8, #1\n  cmp     r8, r4\n  blt     L133\nL135:\nL136:\n  str     r0, [r7, #0]\n  cmp     r0, #0\n  beq     L1320\nL137:\n  mov     r2, r9, lsl #16\n\tmov     r8, #1\n  mov     r2, r2, asr #16\n  cmp     r2, #1\n  ble     L1319\nL138:\nL139:\n  sub     r4, r4, #1\n  mov     r14, #0\n  mov     r3, #0\n  cmp     r4, #0\n  ble     L1317\nL1310:\n  cmp     r4, #6\n  addlt   r6, r5, r8, lsl #1\n  blt     L1314\nL1311:\n  add     r6, r5, r8, lsl #1\n  sub     r12, r4, #6\n  str     r8, [r13, #8]\n  str     r7, [r13, #4]\nL1312:\n  mov     r1, r3, lsl #1\n  ldrsh   r7, [r6, r1]\n  ldrsh   r10, [r5, r1]\n  add     r8, r1, r6\n\tadd     r9, r5, r1\n\tmul     r7, r10, r7\n  ldrsh   r1, [r8, #2]\n\tldrsh   r10, [r8, #4]\n  add     r7, r14, r7, asr #9\n  ldrsh   r0, [r9, #2]\n  ldrsh   r11, [r9, #4]\n  mul     r1, r0, r1\n  ldrsh   r14, [r8, #6]\n  mul     r10, r11, r10\n\tadd     r7, r7, r1, asr #9\n  ldrsh   r8, [r8, #8]\n\tadd     r3, r3, #5\n\tldrsh   r11, [r9, #6]\n  ldrsh   r1, [r9, #8]\n  mul     r14, r11, r14\n  add     r7, r7, r10, asr #9\n  mul     r1, r1, r8\n  add     r14, r7, r14, asr #9\n\tcmp     r3, r12\n  add     r14, r14, r1, asr #9\n  ble     L1312\nL1313:\n  ldr     r8, [r13, #8]\n  ldr     r7, [r13, #4]\nL1314:\nL1315:\n  mov     r12, r3, lsl #1\n  ldrsh   r9, [r6, r12]\n  ldrsh   r12, [r5, r12]\n  add     r3, r3, #1\n  cmp     r3, r4\n  mul     r12, r12, r9\n  add     r14, r14, r12, asr #9\n  blt     L1315\nL1316:\nL1317:\n  str     r14, [r7, +r8, lsl #2]\n  add     r8, r8, #1\n  cmp     r8, r2\n  blt     L139\n\nL1319:\nL1320:\n\tadd     r13, r13, #20\n\tldmia   sp!, {r4 - r11, pc}\n\n\t@ENDP  @ |AutoCorrelation|\n\t.end\n"
  },
  {
    "path": "jni/src/asm/ARMV5E/CalcWindowEnergy_v5.s",
    "content": "@/*\n@ ** Copyright 2003-2010, VisualOn, Inc.\n@ **\n@ ** Licensed under the Apache License, Version 2.0 (the \"License\");\n@ ** you may not use this file except in compliance with the License.\n@ ** You may obtain a copy of the License at\n@ **\n@ **     http://www.apache.org/licenses/LICENSE-2.0\n@ **\n@ ** Unless required by applicable law or agreed to in writing, software\n@ ** distributed under the License is distributed on an \"AS IS\" BASIS,\n@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@ ** See the License for the specific language governing permissions and\n@ ** limitations under the License.\n@ */\n\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n@\tFile:\t\tCalcWindowEnergy_v5.s\n@\n@\tContent:\tCalcWindowEnergy function armv5 assemble\n@\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n\t.section .text\n\n\t.global\tCalcWindowEnergy\n\nCalcWindowEnergy:\n\tstmdb   sp!, {r4 - r11, lr}\n\tsub     r13, r13, #20\n\n  mov     r3, r3, lsl #16\n\tldr     r10, [r0, #168]                    @ states0 = blockSwitchingControl->iirStates[0];\n  mov     r3, r3, asr #16\n\tldr     r11, [r0, #172]                    @ states1 = blockSwitchingControl->iirStates[1];\n\n\tmov     r2, r2, lsl #16\n\tldr     r12, hiPassCoeff                   @ Coeff0 = hiPassCoeff[0];\n  mov     r2, r2, asr #16\n\tldr     r14, hiPassCoeff + 4\t\t\t         @ Coeff1 = hiPassCoeff[1];\n\n\tmov\t\t\tr8, #0\t\t\t\t\t\t\t               @ w=0\n\tmov\t\t\tr5, #0\t\t\t\t\t\t\t               @ wOffset = 0;\n\nBLOCK_BEGIN:\n\tmov\t\t\tr6, #0                             @ accuUE = 0;\n\tmov\t\t\tr7, #0\t\t\t\t\t\t\t\t             @ accuFE = 0;\n\tmov\t\t\tr4, #0\t\t\t\t\t\t\t               @ i=0\n\n\tstr\t\t\tr8, [r13, #4]\n\tstr\t\t\tr0, [r13, #8]\n\tstr\t\t\tr3, [r13, #12]\n\nENERGY_BEG:\n\tmov     r9, r5, lsl #1\n\tldrsh   r9, [r1, r9]\t\t\t\t\t\t\t\t\t\t\t@ tempUnfiltered = timeSignal[tidx];\n\n\tadd\t\t\tr5, r5, r2\t\t\t\t\t\t\t\t\t\t\t\t@ tidx = tidx + chIncrement;\n\n\tsmulwb\tr3, r14, r9\t\t\t\t\t\t\t\t\t\t\t\t@ accu1 = L_mpy_ls(Coeff1, tempUnfiltered);\n\tsmull\t\tr0, r8, r12, r11\t\t\t\t\t\t\t\t\t@ accu2 = fixmul( Coeff0, states1 );\n\n\tmov\t\t\tr3, r3, lsl #1\n\tmov\t\t\tr8, r8, lsl #1\n\n\tsub\t\t\tr0, r3, r10\t\t\t\t\t\t\t\t\t\t\t\t@ accu3 = accu1 - states0;\n\tsub\t\t\tr8,\tr0, r8\t\t\t\t\t\t\t\t\t\t\t\t@ out = accu3 - accu2;\n\n\tmov\t\t  r10, r3\t\t\t\t\t\t\t\t\t\t\t\t\t\t@ states0 = accu1;\n\tmov\t\t  r11, r8\t\t\t\t\t\t\t\t\t\t\t\t\t\t@ states1 = out;\n\n\tmul\t\t  r3, r9, r9\n\tmov     r8, r8, asr #16\n\n\tadd\t\t  r4, r4, #1\n\tadd     r6, r6, r3, asr #7\n\n\tmul\t\t  r9, r8, r8\n\tldr\t\t  r3, [r13, #12]\n\n\tadd\t\t  r7, r7, r9, asr #7\n\n\tcmp     r4, r3\n  blt     ENERGY_BEG\n\n\tldr\t\t  r0, [r13, #8]\n\tldr\t\t  r8, [r13, #4]\n\nENERGY_END:\n\tadd\t\t  r4, r0, r8, lsl #2\n\n\tstr     r6, [r4, #72]\n\tadd\t\t  r8, r8, #1\n  str     r7, [r4, #136]\n\n\tcmp\t\t  r8, #8\n\tblt\t\t  BLOCK_BEGIN\n\nBLOCK_END:\n\tstr     r10, [r0, #168]\n  str     r11, [r0, #172]\n  mov     r0, #1\n\n  add     r13, r13, #20\n\tldmia   sp!, {r4 - r11, pc}\n\nhiPassCoeff:\n\t.word 0xbec8b439\n\t.word\t0x609d4952\n\n\t@ENDP\n\t.end\n"
  },
  {
    "path": "jni/src/asm/ARMV5E/PrePostMDCT_v5.s",
    "content": "@/*\n@ ** Copyright 2003-2010, VisualOn, Inc.\n@ **\n@ ** Licensed under the Apache License, Version 2.0 (the \"License\");\n@ ** you may not use this file except in compliance with the License.\n@ ** You may obtain a copy of the License at\n@ **\n@ **     http://www.apache.org/licenses/LICENSE-2.0\n@ **\n@ ** Unless required by applicable law or agreed to in writing, software\n@ ** distributed under the License is distributed on an \"AS IS\" BASIS,\n@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@ ** See the License for the specific language governing permissions and\n@ ** limitations under the License.\n@ */\n\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n@\tFile:\t\tPrePostMDCT_v5.s\n@\n@\tContent:\tpremdct and postmdct function armv5 assemble\n@\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n\t.section .text\n\t.global\tPreMDCT\n\nPreMDCT:\n\tstmdb       sp!, {r4 - r11, lr}\n\n\tadd         r9, r0, r1, lsl #2\n\tsub         r3, r9, #8\n\n\tmovs        r1, r1, asr #2\n\tbeq         PreMDCT_END\n\nPreMDCT_LOOP:\n\tldr\t\t\t\t\tr8, [r2], #4\n\tldr\t\t\t\t\tr9, [r2], #4\n\n\tldrd\t\t\t\tr4, [r0]\n\tldrd\t\t\t\tr6, [r3]\n\n\tsmull\t\t\t\tr14, r11, r4, r8\t\t\t\t\t@ MULHIGH(tr1, cosa)\n\tsmull    \t\t\tr10, r12, r7, r8\t\t\t\t\t@ MULHIGH(ti1, cosa)\n\n\tsmull\t\t\t\tr14, r8, r7, r9\t\t\t\t\t\t@ MULHIGH(ti1, sina)\n\tsmull\t\t\t\tr7, r10, r4, r9\t\t\t\t\t\t@ MULHIGH(tr1, sina)\n\n\tadd\t\t\t\t\tr11, r11, r8\t\t\t\t\t\t@ MULHIGH(cosa, tr1) + MULHIGH(sina, ti1)@\n\tsub\t\t\t\t\tr7, r12, r10\t\t\t\t\t\t@ MULHIGH(ti1, cosa) - MULHIGH(tr1, sina)\n\n\tldr\t\t\t\t\tr8, [r2], #4\n\tldr\t\t\t\t\tr9, [r2], #4\n\n\tsmull\t\t\t\tr14, r4, r6, r8\t\t\t\t\t\t@ MULHIGH(tr2, cosa)\n\tsmull    \t\t\tr10, r12, r5, r8\t\t\t\t\t@ MULHIGH(ti2, cosa)\n\n\tsmull\t\t\t\tr14, r8, r5, r9\t\t\t\t\t\t@ MULHIGH(ti2, sina)\n\tsmull\t\t\t\tr5, r10, r6, r9\t\t\t\t\t\t@ MULHIGH(tr2, sina)\n\n\tadd\t\t\t\t\tr8, r8, r4\n\tsub\t\t\t\t\tr9, r12, r10\n\n\tmov\t\t\t\t\tr6, r11\n\n\tstrd\t\t\t\tr6, [r0]\n\tstrd\t\t\t\tr8, [r3]\n\n\tsubs\t\t\t\tr1, r1, #1\n\tsub\t\t\t\t\tr3, r3, #8\n\tadd \t\t\t\tr0, r0, #8\n\tbne\t\t\t\t\tPreMDCT_LOOP\n\nPreMDCT_END:\n\tldmia       sp!, {r4 - r11, pc}\n\t@ENDP  @ |PreMDCT|\n\n\t.section .text\n\t.global\tPostMDCT\n\nPostMDCT:\n\tstmdb       sp!, {r4 - r11, lr}\n\n\tadd         r9, r0, r1, lsl #2\n\tsub         r3, r9, #8\n\n\tmovs        r1, r1, asr #2\n\tbeq         PostMDCT_END\n\nPostMDCT_LOOP:\n\tldr\t\t\t\t\tr8, [r2], #4\n\tldr\t\t\t\t\tr9, [r2], #4\n\n\tldrd\t\t\t\tr4, [r0]\n\tldrd\t\t\t\tr6, [r3]\n\n\tsmull\t\t\t\tr14, r11, r4, r8\t\t\t\t\t@ MULHIGH(tr1, cosa)\n\tsmull    \t\t\tr10, r12, r5, r8\t\t\t\t\t@ MULHIGH(ti1, cosa)\n\n\tsmull\t\t\t\tr14, r8, r5, r9\t\t\t\t\t\t@ MULHIGH(ti1, sina)\n\tsmull\t\t\t\tr5, r10, r4, r9\t\t\t\t\t\t@ MULHIGH(tr1, sina)\n\n\tadd\t\t\t\t\tr4, r11, r8\t\t\t\t\t\t\t@ MULHIGH(cosa, tr1) + MULHIGH(sina, ti1)@\n\tsub\t\t\t\t\tr11, r10, r12\t\t\t\t\t\t@ MULHIGH(ti1, cosa) - MULHIGH(tr1, sina)@\n\n\tldr\t\t\t\t\tr8, [r2], #4\t\t\t\t\t\t@\n\tldr\t\t\t\t\tr9, [r2], #4\n\n\tsmull\t\t\t\tr14, r5, r6, r8\t\t\t\t\t\t@ MULHIGH(tr2, cosa)\n\tsmull    \t\t\tr10, r12, r7, r8\t\t\t\t\t@ MULHIGH(ti2, cosa)\n\n\tsmull\t\t\t\tr14, r8, r7, r9\t\t\t\t\t\t@ MULHIGH(ti2, sina)\n\tsmull\t\t\t\tr7, r10, r6, r9\t\t\t\t\t\t@ MULHIGH(tr2, sina)\n\n\tadd\t\t\t\t\tr6, r8, r5\t\t\t\t\t\t\t@ MULHIGH(cosb, tr2) + MULHIGH(sinb, ti2)@\n\tsub\t\t\t\t\tr5, r10, r12\t\t\t\t\t\t@ MULHIGH(sinb, tr2) - MULHIGH(cosb, ti2)@\n\n\tmov\t\t\t\t\tr7, r11\n\n\tstrd\t\t\t\tr4, [r0]\n\tstrd\t\t\t\tr6, [r3]\n\n\tsubs\t\t\t\tr1, r1, #1\n\tsub\t\t\t\t\tr3, r3, #8\n\tadd \t\t\t\tr0, r0, #8\n\tbne\t\t\t\t\tPostMDCT_LOOP\n\nPostMDCT_END:\n\tldmia       sp!, {r4 - r11, pc}\n\t@ENDP  @ |PostMDCT|\n\t.end\n"
  },
  {
    "path": "jni/src/asm/ARMV5E/R4R8First_v5.s",
    "content": "@/*\n@ ** Copyright 2003-2010, VisualOn, Inc.\n@ **\n@ ** Licensed under the Apache License, Version 2.0 (the \"License\");\n@ ** you may not use this file except in compliance with the License.\n@ ** You may obtain a copy of the License at\n@ **\n@ **     http://www.apache.org/licenses/LICENSE-2.0\n@ **\n@ ** Unless required by applicable law or agreed to in writing, software\n@ ** distributed under the License is distributed on an \"AS IS\" BASIS,\n@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@ ** See the License for the specific language governing permissions and\n@ ** limitations under the License.\n@ */\n\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n@\tFile:\t\tR4R8First_v5.s\n@\n@\tContent:\tRadix8First and Radix4First function armv5 assemble\n@\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n\t.section .text\n\t.global\tRadix4First\n\nRadix4First:\n\tstmdb       sp!, {r4 - r11, lr}\n\n\tmovs\t\t\t\tr10, r1\n\tmov\t\t\t\t\tr11, r0\n\tbeq\t\t\t\t\tRadix4First_END\n\nRadix4First_LOOP:\n\tldrd\t\t\t\tr0, [r11]\n\tldrd\t\t\t\tr2, [r11, #8]\n\tldrd\t\t\t\tr4, [r11, #16]\n\tldrd\t\t\t\tr6, [r11, #24]\n\n\tadd\t\t\t\t\tr8, r0, r2\n\tadd\t\t\t\t\tr9, r1, r3\n\n\tsub\t\t\t\t\tr0, r0, r2\n\tsub\t\t\t\t\tr1, r1, r3\n\n\tadd\t\t\t\t\tr2, r4, r6\n\tadd\t\t\t\t\tr3, r5, r7\n\n\tsub\t\t\t\t\tr4, r4, r6\n\tsub\t\t\t\t\tr5, r5, r7\n\n\tadd\t\t\t\t\tr6, r8, r2\n\tadd\t\t\t\t\tr7, r9, r3\n\n\tsub\t\t\t\t\tr8, r8, r2\n\tsub\t\t\t\t\tr9, r9, r3\n\n\tadd\t\t\t\t\tr2, r0, r5\n\tsub\t\t\t\t\tr3, r1, r4\n\n\tsub\t\t\t\t\tr0, r0, r5\n\tadd\t\t\t\t\tr1, r1, r4\n\n\tstrd\t\t\t\tr6, [r11]\n\tstrd\t\t\t\tr2, [r11, #8]\n\tstrd\t\t\t\tr8, [r11, #16]\n\tstrd\t\t\t\tr0, [r11, #24]\n\n\tsubs\t\t\t\tr10, r10, #1\n\tadd\t\t\t\t\tr11, r11, #32\n\tbne\t\t\t\t\tRadix4First_LOOP\n\nRadix4First_END:\n\tldmia       sp!, {r4 - r11, pc}\n\t@ENDP  @ |Radix4First|\n\n\t.section .text\n\t.global\tRadix8First\n\nRadix8First:\n\tstmdb       sp!, {r4 - r11, lr}\n\tsub         sp, sp, #0x24\n\n\tmov\t\t\t\t  r12, r1\n\tmov\t\t\t\t\tr14, r0\n\tcmp\t\t\t\t\tr12, #0\n\tbeq\t\t\t\t\tRadix8First_END\n\nRadix8First_LOOP:\n\tldrd\t\t\t\tr0, [r14]\n\tldrd\t\t\t\tr2, [r14, #8]\n\tldrd\t\t\t\tr4, [r14, #16]\n\tldrd\t\t\t\tr6, [r14, #24]\n\n\tadd\t\t\t\t\tr8, r0, r2\t\t\t\t\t@ r0 = buf[0] + buf[2]@\n\tadd\t\t\t\t\tr9, r1, r3\t\t\t\t\t@ i0 = buf[1] + buf[3]@\n\n\tsub\t\t\t\t\tr0, r0, r2\t\t\t\t\t@ r1 = buf[0] - buf[2]@\n\tsub\t\t\t\t\tr1, r1, r3\t\t\t\t\t@ i1 = buf[1] - buf[3]@\n\n\tadd\t\t\t\t\tr2, r4, r6\t\t\t\t\t@\tr2 = buf[4] + buf[6]@\n\tadd\t\t\t\t\tr3, r5, r7\t\t\t\t\t@ i2 = buf[5] + buf[7]@\n\n\tsub\t\t\t\t\tr4, r4, r6\t\t\t\t\t@\tr3 = buf[4] - buf[6]@\n\tsub\t\t\t\t\tr5, r5, r7\t\t\t\t\t@ i3 = buf[5] - buf[7]@\n\n\tadd\t\t\t\t\tr6, r8, r2\t\t\t\t\t@ r4 = (r0 + r2) >> 1@\n\tadd\t\t\t\t\tr7, r9, r3\t\t\t\t\t@ i4 = (i0 + i2) >> 1@\n\n\tsub\t\t\t\t\tr8, r8, r2\t\t\t\t\t@\tr5 = (r0 - r2) >> 1@\n\tsub\t\t\t\t\tr9, r9, r3\t\t\t\t\t@ i5 = (i0 - i2) >> 1@\n\n\tsub\t\t\t\t\tr2, r0, r5\t\t\t\t\t@ r6 = (r1 - i3) >> 1@\n\tadd\t\t\t\t\tr3, r1, r4\t\t\t\t\t@ i6 = (i1 + r3) >> 1@\n\n\tadd\t\t\t\t\tr0, r0, r5\t\t\t\t\t@ r7 = (r1 + i3) >> 1@\n\tsub\t\t\t\t\tr1, r1, r4\t\t\t\t\t@ i7 = (i1 - r3) >> 1@\n\n\tmov\t\t\t\t\tr6, r6, asr #1\t\t\t@\n\tmov\t\t\t\t\tr7, r7, asr #1\t\t\t@\n\n\tmov\t\t\t\t\tr8, r8, asr #1\n\tmov\t\t\t\t\tr9, r9, asr #1\n\n\tmov\t\t\t\t\tr2, r2, asr #1\n\tmov\t\t\t\t\tr3, r3, asr #1\n\n\tmov\t\t\t\t\tr0, r0, asr #1\n\tmov\t\t\t\t\tr1, r1, asr #1\n\n\tstr\t\t\t\t\tr6, [sp]\n\tstr\t\t\t\t\tr7, [sp, #4]\n\n\tstr\t\t\t\t\tr8, [sp, #8]\n\tstr\t\t\t\t\tr9, [sp, #12]\n\n\tstr\t\t\t\t\tr2, [sp, #16]\n\tstr\t\t\t\t\tr3, [sp, #20]\n\n\tstr\t\t\t\t\tr0, [sp, #24]\n\tstr\t\t\t\t\tr1, [sp, #28]\n\n\tldrd\t\t\t\tr2, [r14, #32]\n\tldrd\t\t\t\tr4, [r14, #40]\n\tldrd\t\t\t\tr6, [r14, #48]\n\tldrd\t\t\t\tr8, [r14, #56]\n\n\tadd\t\t\t\t\tr0, r2, r4\t\t\t\t\t@ r0 = buf[ 8] + buf[10]@\n\tadd\t\t\t\t\tr1, r3, r5\t\t\t\t\t@ i0 = buf[ 9] + buf[11]@\n\n\tsub\t\t\t\t\tr2, r2, r4\t\t\t\t\t@ r1 = buf[ 8] - buf[10]@\n\tsub\t\t\t\t\tr3, r3, r5\t\t\t\t\t@ i1 = buf[ 9] - buf[11]@\n\n\tadd\t\t\t\t\tr4, r6, r8\t\t\t\t\t@ r2 = buf[12] + buf[14]@\n\tadd\t\t\t\t\tr5, r7, r9\t\t\t\t\t@ i2 = buf[13] + buf[15]@\n\n\tsub\t\t\t\t\tr6, r6, r8\t\t\t\t\t@ r3 = buf[12] - buf[14]@\n\tsub\t\t\t\t\tr7, r7, r9\t\t\t\t\t@\ti3 = buf[13] - buf[15]@\n\n\tadd\t\t\t\t\tr8, r0, r4\t\t\t\t\t@ t0 = (r0 + r2)\n\tadd\t\t\t\t\tr9, r1, r5\t\t\t\t\t@ t1 = (i0 + i2)\n\n\tsub\t\t\t\t\tr0, r0, r4\t\t\t\t\t@ t2 = (r0 - r2)\n\tsub\t\t\t\t\tr1, r1, r5\t\t\t\t\t@ t3 = (i0 - i2)\n\n\tmov\t\t\t\t\tr8, r8, asr #1\n\tldr\t\t\t\t\tr4, [sp]\n\n\tmov\t\t\t\t\tr9, r9, asr #1\n\tldr\t\t\t\t\tr5, [sp, #4]\n\n\tmov\t\t\t\t\tr0, r0, asr #1\n\tmov\t\t\t\t\tr1, r1, asr #1\n\n\tadd\t\t\t\t\tr10, r4, r8\t\t\t\t\t@ buf[ 0] = r4 + t0@\n\tadd\t\t\t\t\tr11, r5, r9\t\t\t\t\t@ buf[ 1] = i4 + t1@\n\n\tsub\t\t\t\t\tr4,  r4, r8\t\t\t\t\t@ buf[ 8] = r4 - t0@\n\tsub\t\t\t\t\tr5,  r5, r9\t\t\t\t\t@\tbuf[ 9] = i4 - t1@\n\n \tstrd\t\t\t\tr10, [r14]\n \tstrd\t\t\t\tr4,  [r14, #32]\n\n \tldr\t\t\t\t\tr10, [sp, #8]\n \tldr\t\t\t\t\tr11, [sp, #12]\n\n \tadd\t\t\t\t\tr4, r10, r1\t\t\t\t\t@ buf[ 4] = r5 + t3@\n \tsub\t\t\t\t\tr5, r11, r0\t\t\t\t\t@\tbuf[ 5] = i5 - t2@\n\n \tsub\t\t\t\t\tr10, r10, r1\t\t\t\t@ buf[12] = r5 - t3@\n \tadd\t\t\t\t\tr11, r11, r0\t\t\t\t@ buf[13] = i5 + t2@\n\n \tstrd\t\t\t\tr4,  [r14, #16]\n \tstrd\t\t\t\tr10, [r14, #48]\n\n \tsub\t\t\t\t\tr0, r2, r7\t\t\t\t\t@ r0 = r1 - i3@\n \tadd\t\t\t\t\tr1, r3, r6\t\t\t\t\t@ i0 = i1 + r3@\n\n  ldr\t\t\t\t\tr11, DATATab\n\n \tadd\t\t\t\t\tr2, r2, r7\t\t\t\t\t@ r2 = r1 + i3@\n \tsub\t\t\t\t\tr3, r3, r6\t\t\t\t\t@ i2 = i1 - r3@\n\n\tsub\t\t\t\t\tr4, r0, r1\t\t\t\t\t@ r0 - i0\n\tadd\t\t\t\t\tr5, r0, r1\t\t\t\t\t@ r0 + i0\n\n\tsub\t\t\t\t\tr0, r2, r3\t\t\t\t\t@ r2 - i2\n\tadd\t\t\t\t\tr1, r2, r3\t\t\t\t\t@ r2 + i2\n\n\tsmull\t\t\t\tr8, r6, r4, r11\n\tsmull\t\t\t\tr9, r7, r5, r11\n\n\tldr\t\t\t\t\tr2, [sp, #16]\n\tldr\t\t\t\t\tr3, [sp, #20]\n\n\tsmull\t\t\t\tr8, r4, r0, r11\n\tsmull\t\t\t\tr9, r5, r1, r11\n\n\tldr\t\t\t\t\tr10, [sp, #24]\n\tldr\t\t\t\t\tr11, [sp, #28]\n\n\tsub\t\t\t\t\tr8, r2, r6\n\tsub\t\t\t\t\tr9, r3, r7\n\n\tadd\t\t\t\t\tr2, r2, r6\n\tadd\t\t\t\t\tr3, r3, r7\n\n\tadd\t\t\t\t\tr6, r10, r5\n\tsub\t\t\t\t\tr7, r11, r4\n\n\tsub\t\t\t\t\tr0, r10, r5\n\tadd\t\t\t\t\tr1, r11, r4\n\n\tstrd\t\t\t\tr6, [r14, #8]\n\tstrd\t\t\t\tr8, [r14, #24]\n\tstrd\t\t\t\tr0, [r14, #40]\n\tstrd\t\t\t\tr2, [r14, #56]\n\n\tsubs\t\t\t\tr12, r12, #1\n\tadd\t\t\t\t\tr14, r14, #64\n\n\tbne\t\t\t\t\tRadix8First_LOOP\n\nRadix8First_END:\n\tadd         sp, sp, #0x24\n\tldmia       sp!, {r4 - r11, pc}\n\nDATATab:\n\t.word       0x5a82799a\n\n\t@ENDP  @ |Radix8First|\n\t.end\n"
  },
  {
    "path": "jni/src/asm/ARMV5E/Radix4FFT_v5.s",
    "content": "@/*\n@ ** Copyright 2003-2010, VisualOn, Inc.\n@ **\n@ ** Licensed under the Apache License, Version 2.0 (the \"License\");\n@ ** you may not use this file except in compliance with the License.\n@ ** You may obtain a copy of the License at\n@ **\n@ **     http://www.apache.org/licenses/LICENSE-2.0\n@ **\n@ ** Unless required by applicable law or agreed to in writing, software\n@ ** distributed under the License is distributed on an \"AS IS\" BASIS,\n@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@ ** See the License for the specific language governing permissions and\n@ ** limitations under the License.\n@ */\n\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n@\tFile:\t\tRadix4FFT_v5.s\n@\n@\tContent:\tRadix4FFT armv5 assemble\n@\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\t.section .text\n\t.global\tRadix4FFT\n\nRadix4FFT:\n\tstmdb     sp!, {r4 - r11, lr}\n\tsub       sp, sp, #32\n\n\tmov\t\t\tr1, r1, asr #2\n\tcmp     r1, #0\n\tbeq     Radix4FFT_END\n\nRadix4FFT_LOOP1:\n\tmov     r14, r0          \t\t\t\t\t\t\t@ xptr = buf@\n\tmov\t\tr10, r1 \t\t\t\t\t\t\t\t\t\t\t\t@ i = num@\n\tmov     r9, r2, lsl #3  \t\t\t\t\t\t\t@ step = 2*bgn@\n\tcmp     r10, #0\n\tstr\t\tr0, [sp]\n\tstr\t\tr1, [sp, #4]\n\tstr\t\tr2, [sp, #8]\n\tstr\t\tr3, [sp, #12]\n\tbeq     Radix4FFT_LOOP1_END\n\nRadix4FFT_LOOP2:\n\tmov     r12, r3\t\t\t\t        \t\t\t\t@ csptr = twidTab@\n\tmov\t\tr11, r2\t\t\t\t\t\t\t\t\t\t\t\t@ j = bgn\n\tcmp     r11, #0\n\tstr\t\tr10, [sp, #16]\n\tbeq     Radix4FFT_LOOP2_END\n\nRadix4FFT_LOOP3:\n\tstr\t\t\tr11, [sp, #20]\n\n\tldrd\t\tr0, [r14, #0]\t\t\t\t\t\t\t\t\t@ r0 = xptr[0]@ r1 = xptr[1]@\n\tadd\t\t\tr14, r14, r9 \t \t\t\t\t\t\t\t\t@ xptr += step@\n\n\tldrd\t\tr10,\t[r14, #0]  \t\t\t\t\t \t\t\t@ r2 = xptr[0]@ r3 = xptr[1]@\n\tldr\t\t\tr8, [r12], #4\t\t\t\t\t\t\t\t\t@ cosxsinx = csptr[0]@\n\n\tsmulwt\tr4, r10, r8\t\t\t\t\t\t\t\t\t\t@ L_mpy_wx(cosx, t0)\n\tsmulwt\tr3, r11, r8\t\t\t\t\t\t\t\t\t\t@ L_mpy_wx(cosx, t1)\n\n\tsmlawb\tr2, r11, r8, r4\t\t\t\t\t\t\t\t@ r2 = L_mpy_wx(cosx, t0) + L_mpy_wx(sinx, t1)@\n\tsmulwb\tr5, r10, r8\t\t\t\t\t\t\t\t\t\t@ L_mpy_wx(sinx, t0)\n\n\tmov\t\t\tr10, r0, asr #2\t\t\t\t\t\t\t\t@ t0 = r0 >> 2@\n\tmov\t\t\tr11, r1, asr #2\t\t\t\t\t\t\t\t@\tt1 = r1 >> 2@\n\n\tsub\t\t\tr3, r3, r5\t\t\t\t\t\t\t\t\t\t@ r3 = L_mpy_wx(cosx, t1) - L_mpy_wx(sinx, t0)@\n\tadd     r14, r14, r9 \t \t\t\t\t\t\t\t\t@ xptr += step@\n\n\tsub\t\t\tr0, r10, r2\t\t\t\t\t\t\t\t\t\t@ r0 = t0 - r2@\n\tsub\t\t\tr1, r11, r3\t\t\t\t\t\t\t\t\t  @ r1 = t1 - r3@\n\n\tadd\t\t\tr2, r10, r2\t\t\t\t\t\t\t\t\t\t@ r2 = t0 + r2@\n\tadd\t\t\tr3, r11, r3\t\t\t\t\t\t\t\t\t\t@ r3 = t1 + r3@\n\n\tstr\t\t\tr2, [sp, #24]\n\tstr\t\t\tr3, [sp, #28]\n\n\tldrd\t\tr10, [r14, #0]\t\t\t\t\t\t\t\t@ r4 = xptr[0]@ r5 = xptr[1]@\n\tldr\t\t\tr8, [r12], #4\t\t\t\t\t\t\t\t\t@ cosxsinx = csptr[1]@\n\n\tsmulwt\tr6, r10, r8\t\t\t\t\t\t\t\t\t\t@ L_mpy_wx(cosx, t0)\n\tsmulwt\tr5, r11, r8\t\t\t\t\t\t\t\t\t\t@ L_mpy_wx(cosx, t1)\n\n\tsmlawb\tr4, r11, r8, r6\t\t\t\t\t\t\t\t@ r4 = L_mpy_wx(cosx, t0) + L_mpy_wx(sinx, t1)@\n\tsmulwb\tr7, r10, r8\t\t\t\t\t\t\t\t\t\t@ L_mpy_wx(sinx, t0)\n\n\tadd\t\t\tr14, r14, r9\t\t\t\t\t\t\t\t\t@ xptr += step@\n\tsub\t\t\tr5, r5, r7\t\t\t\t\t\t\t\t\t\t@ r5 = L_mpy_wx(cosx, t1) - L_mpy_wx(sinx, t0)@\n\n\tldrd\t\tr10, [r14]\t\t\t\t\t\t\t\t\t\t@ r6 = xptr[0]@ r7 = xptr[1]@\n\tldr\t\t\tr8, [r12], #4\t\t\t\t\t\t\t\t\t@ cosxsinx = csptr[1]@\n\n\tsmulwt\tr2, r10, r8\t\t\t\t\t\t\t\t\t\t@ L_mpy_wx(cosx, t0)\n\tsmulwt\tr7, r11, r8\t\t\t\t\t\t\t\t\t\t@ L_mpy_wx(cosx, t1)\n\n\tsmlawb\tr6, r11, r8, r2\t\t\t\t\t\t\t\t@ r4 = L_mpy_wx(cosx, t0) + L_mpy_wx(sinx, t1)@\n\tsmulwb\tr3, r10, r8\t\t\t\t\t\t\t\t\t\t@ L_mpy_wx(sinx, t0)\n\n\tmov\t\t\tr10, r4\t\t\t\t\t\t\t\t\t\t\t\t@ t0 = r4@\n\tmov\t\t\tr11, r5\t\t\t\t\t\t\t\t\t\t\t\t@ t1 = r5@\n\n\tsub\t\t\tr7, r7, r3\t\t\t\t\t\t\t\t\t\t@ r5 = L_mpy_wx(cosx, t1) - L_mpy_wx(sinx, t0)@\n\n\n\tadd\t\t\tr4,  r10, r6\t\t\t\t\t\t\t\t\t@\tr4 = t0 + r6@\n\tsub\t\t\tr5, r7, r11\t\t\t\t\t\t\t\t\t\t@ r5 = r7 - t1@\n\n\tsub\t\t\tr6, r10, r6\t\t\t\t\t\t\t\t\t\t@ r6 = t0 - r6@\n\tadd\t\t\tr7, r7, r11\t\t\t\t\t\t\t\t\t\t@ r7 = r7 + t1@\n\n\tldr\t\t\tr2, [sp, #24]\n\tldr\t\t\tr3, [sp, #28]\n\n\tadd\t\t\tr10, r0, r5\t\t\t\t\t\t\t\t\t\t@ xptr[0] = r0 + r5@\n\tadd\t\t\tr11, r1, r6\t\t\t\t\t\t\t\t\t\t@ xptr[0] = r1 + r6\n\n\tstrd\t\tr10, [r14]\n\tsub\t\t\tr14, r14, r9\t\t\t\t\t\t\t\t\t@ xptr -= step@\n\n\tsub\t\t\tr10, r2, r4\t\t\t\t\t\t\t\t\t\t@\txptr[0] = r2 - r4@\n\tsub\t\t\tr11, r3, r7\t\t\t\t\t\t\t\t\t\t@ xptr[1] = r3 - r7@\n\n\tstrd\t\tr10, [r14]\n\tsub\t\t\tr14, r14, r9\t\t\t\t\t\t\t\t\t@ xptr -= step@\n\n\tsub\t\t\tr10, r0, r5\t\t\t\t\t\t\t\t\t\t@ xptr[0] = r0 - r5@\n\tsub\t\t\tr11, r1, r6\t\t\t\t\t\t\t\t\t\t@ xptr[0] = r1 - r6\n\n\tstrd\t\tr10, [r14]\n\tsub\t\t\tr14, r14, r9\t\t\t\t\t\t\t\t\t@ xptr -= step@\n\n\tadd\t\t\tr10, r2, r4\t\t\t\t\t\t\t\t\t\t@\txptr[0] = r2 - r4@\n\tadd\t\t\tr11, r3, r7\t\t\t\t\t\t\t\t\t\t@ xptr[1] = r3 - r7@\n\n\tstrd\t\tr10, [r14]\n\tadd\t\t\tr14, r14, #8\t\t\t\t\t\t\t\t\t@ xptr += 2@\n\n\tldr\t\t\tr11, [sp, #20]\n\tsubs\t\tr11, r11, #1\n\tbne\t\t\tRadix4FFT_LOOP3\n\nRadix4FFT_LOOP2_END:\n\tldr\t\t\tr10, [sp, #16]\n\tldr\t\t\tr3, [sp, #12]\n\tldr\t\t\tr2, [sp, #8]\n\trsb\t\t\tr8, r9, r9, lsl #2\n\tsub\t\t\tr10, r10, #1\n\tadd\t\t\tr14, r14, r8\n\tcmp\t\t\tr10, #0\n\tbhi     Radix4FFT_LOOP2\n\nRadix4FFT_LOOP1_END:\n\tldr     r0, [sp]\n\tldr\t\tr1, [sp, #4]\n\tadd     r3, r3, r8, asr #1\n\tmov     r2, r2, lsl #2\n\tmovs    r1, r1, asr #2\n\tbne     Radix4FFT_LOOP1\n\nRadix4FFT_END:\n\tadd     sp, sp, #32\n\tldmia   sp!, {r4 - r11, pc}\n\n\t@ENDP  @ |Radix4FFT|\n\t.end\n"
  },
  {
    "path": "jni/src/asm/ARMV5E/band_nrg_v5.s",
    "content": "@/*\n@ ** Copyright 2003-2010, VisualOn, Inc.\n@ **\n@ ** Licensed under the Apache License, Version 2.0 (the \"License\");\n@ ** you may not use this file except in compliance with the License.\n@ ** You may obtain a copy of the License at\n@ **\n@ **     http://www.apache.org/licenses/LICENSE-2.0\n@ **\n@ ** Unless required by applicable law or agreed to in writing, software\n@ ** distributed under the License is distributed on an \"AS IS\" BASIS,\n@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@ ** See the License for the specific language governing permissions and\n@ ** limitations under the License.\n@ */\n\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n@\tFile:\t\tband_nrg_v5.s\n@\n@\tContent:\tCalcBandEnergy and CalcBandEnergyMS function armv5 assemble\n@\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n\t.section .text\n\n\t.global\tCalcBandEnergy\n\nCalcBandEnergy:\n\tstmdb   sp!, {r4 - r11, lr}\n\n  mov     r2, r2, lsl #16\n\tldr     r12, [r13, #36]\n\tmov\t\t\tr9, #0\n  mov     r5, r2, asr #16\n\tmov\t\t\tr4, #0\n  cmp     r5, #0\n\tble     L212\n\nL22:\n  mov     r2, r4, lsl #1\n  ldrsh   r10, [r1, r2]\n  add     r11, r1, r2\n  ldrsh   r2, [r11, #2]\n\tmov     r14, #0\n  cmp     r10, r2\n  bge     L28\n\nL23:\n\tldr     r11, [r0, +r10, lsl #2]\n  add     r10, r10, #1\n\tldr     r6, [r0, +r10, lsl #2]\n\tsmull   r11, r7, r11, r11\n\tadd     r10, r10, #1\n\tsmull\t  r6, r8, r6, r6\n\tldr     r11, [r0, +r10, lsl #2]\n\tqadd\t  r14, r14, r7\n\tadd     r10, r10, #1\n\tsmull\t  r11, r7, r11, r11\n\tldr     r6, [r0, +r10, lsl #2]\n\tqadd\t  r14, r14, r8\n\tsmull\t  r6, r8, r6, r6\n  add     r10, r10, #1\n\tqadd\t  r14, r14, r7\n\tcmp     r10, r2\n\tqadd\t  r14, r14, r8\n\tblt     L23\n\nL28:\n\tqadd\t  r14, r14, r14\n\tstr     r14, [r3, +r4, lsl #2]\n\tadd     r4, r4, #1\n\tqadd\t  r9, r9, r14\n\tcmp     r4, r5\n\n  blt     L22\n\nL212:\n\tstr     r9, [r12, #0]\n\tldmia   sp!, {r4 - r11, pc}\n\n\t@ENDP  ; |CalcBandEnergy|\n\n\t.global\tCalcBandEnergyMS\n\nCalcBandEnergyMS:\n\tstmdb   sp!, {r4 - r11, lr}\n\tsub     r13, r13, #24\n\n\tmov     r12, #0\n  mov     r3, r3, lsl #16\n  mov     r14, #0\n\tmov     r3, r3, asr #16\n\tcmp     r3, #0\n\tmov\t\t  r4, #0\n  ble     L315\n\nL32:\n\tmov\t\t  r5, r4, lsl #1\n\tmov\t\t  r6, #0\n\tldrsh   r10, [r2, r5]\n\tadd     r5, r2, r5\n\tmov\t\t  r7, #0\n\tldrsh\t  r11, [r5, #2]\n\tcmp     r10, r11\n  bge     L39\n\n\tstr\t\t  r3, [r13, #4]\n\tstr\t\t  r4, [r13, #8]\n\tstr\t\t  r12, [r13, #12]\n\tstr\t\t  r14, [r13, #16]\n\nL33:\n\tldr     r8, [r0, +r10, lsl #2]\n\tldr     r9, [r1, +r10, lsl #2]\n\tmov\t\t  r8, r8, asr #1\n\tadd\t\t  r10, r10, #1\n\tmov\t\t  r9, r9, asr #1\n\n\tldr     r12, [r0, +r10, lsl #2]\n\tadd\t\t  r5, r8, r9\n\tldr     r14, [r1, +r10, lsl #2]\n\tsub\t\t  r8, r8, r9\n\n\tsmull   r5, r3, r5, r5\n\tmov\t\t  r12, r12, asr #1\n\tsmull   r8, r4, r8, r8\n\tmov\t\t  r14, r14, asr #1\n\n\tqadd\t  r6, r6, r3\n\tadd\t\t  r5, r12, r14\n\tqadd\t  r7, r7, r4\n\tsub\t\t  r8, r12, r14\n\n\tsmull   r5, r3, r5, r5\n\tadd\t\t  r10, r10, #1\n\tsmull   r8, r4, r8, r8\n\n\tqadd\t  r6, r6, r3\n\tqadd\t  r7, r7, r4\n\n\tldr     r8, [r0, +r10, lsl #2]\n\tldr     r9, [r1, +r10, lsl #2]\n\tmov\t\t  r8, r8, asr #1\n\tadd\t\t  r10, r10, #1\n\tmov\t\t  r9, r9, asr #1\n\n\tldr     r12, [r0, +r10, lsl #2]\n\tadd\t\t  r5, r8, r9\n\tldr     r14, [r1, +r10, lsl #2]\n\tsub\t\t  r8, r8, r9\n\n\tsmull   r5, r3, r5, r5\n\tmov\t\t  r12, r12, asr #1\n\tsmull   r8, r4, r8, r8\n\tmov\t\t  r14, r14, asr #1\n\n\tqadd\t  r6, r6, r3\n\tadd\t\t  r5, r12, r14\n\tqadd\t  r7, r7, r4\n\tsub\t\t  r8, r12, r14\n\n\tsmull   r5, r3, r5, r5\n\tadd\t\t  r10, r10, #1\n\tsmull   r8, r4, r8, r8\n\n\tqadd\t  r6, r6, r3\n\tqadd\t  r7, r7, r4\n\n\tcmp     r10, r11\n\n\tblt\t\t  L33\n\n\tldr\t\t  r3, [r13, #4]\n\tldr\t\t  r4, [r13, #8]\n\tldr\t\t  r12, [r13, #12]\n\tldr\t\t  r14, [r13, #16]\nL39:\n\tqadd\t  r6, r6, r6\n\tqadd\t  r7, r7, r7\n\n\tldr\t\t  r8, [r13, #60]\n\tldr\t\t  r9, [r13, #68]\n\n\tqadd\t  r12, r12, r6\n\tqadd\t  r14, r14, r7\n\n\tstr\t\t  r6, [r8, +r4, lsl #2]\n\tstr     r7, [r9, +r4, lsl #2]\n\n\tadd\t\t  r4, r4, #1\n\tcmp\t\t  r4, r3\n\tblt     L32\n\nL315:\n\tldr\t\t  r8, [r13, #64]\n\tldr\t\t  r9, [r13, #72]\n\tstr\t\t  r12, [r8, #0]\n\tstr\t\t  r14, [r9, #0]\n\n\tadd     r13, r13, #24\n\tldmia   sp!, {r4 - r11, pc}\n\t@ENDP  ; |CalcBandEnergyMS|\n\n\t.end\n"
  },
  {
    "path": "jni/src/asm/ARMV7/PrePostMDCT_v7.s",
    "content": "@/*\n@ ** Copyright 2003-2010, VisualOn, Inc.\n@ **\n@ ** Licensed under the Apache License, Version 2.0 (the \"License\");\n@ ** you may not use this file except in compliance with the License.\n@ ** You may obtain a copy of the License at\n@ **\n@ **     http://www.apache.org/licenses/LICENSE-2.0\n@ **\n@ ** Unless required by applicable law or agreed to in writing, software\n@ ** distributed under the License is distributed on an \"AS IS\" BASIS,\n@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@ ** See the License for the specific language governing permissions and\n@ ** limitations under the License.\n@ */\n\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n@\tFile:\t\tPrePostMDCT_v7.s\n@\n@\tContent:\tpremdct and postmdct function armv7 assemble\n@\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n\t.section .text\n\t.global\tPreMDCT\n\nPreMDCT:\n\tstmdb     sp!, {r4 - r11, lr}\n\n\tadd         r9, r0, r1, lsl #2\n\tsub         r3, r9, #32\n\n\tmovs        r1, r1, asr #2\n\tbeq         PreMDCT_END\n\nPreMDCT_LOOP:\n\tVLD4.I32\t\t\t{d0, d2, d4, d6}, [r2]!\t\t\t\t@ cosa = *csptr++@ sina = *csptr++@\n\tVLD4.I32\t\t\t{d1, d3, d5, d7}, [r2]!\t\t\t\t@ cosb = *csptr++@ sinb = *csptr++@\n\tVLD2.I32\t\t\t{d8, d9, d10, d11}, [r0]\t\t\t@ tr1 = *(buf0 + 0)@ ti2 = *(buf0 + 1)@\n\tVLD2.I32\t\t\t{d13, d15}, [r3]!\t\t\t\t\t@ tr2 = *(buf1 - 1)@ ti1 = *(buf1 + 0)@\n\tVLD2.I32\t\t\t{d12, d14}, [r3]!\t\t\t\t\t@ tr2 = *(buf1 - 1)@ ti1 = *(buf1 + 0)@\n\n\tVREV64.32\t\t\tQ8, Q7\n\tVREV64.32\t\t\tQ9, Q6\n\n\n\tVQDMULH.S32\t\tQ10, Q0, Q4\t\t\t\t\t\t\t\t@ MULHIGH(cosa, tr1)\n\tVQDMULH.S32\t\tQ11, Q1, Q8\t\t\t\t\t\t\t\t@ MULHIGH(sina, ti1)\n\tVQDMULH.S32\t\tQ12, Q0, Q8\t\t\t\t\t\t\t\t@ MULHIGH(cosa, ti1)\n\tVQDMULH.S32\t\tQ13, Q1, Q4\t\t\t\t\t\t\t\t@ MULHIGH(sina, tr1)\n\n\tVADD.S32\t\t\tQ0, Q10, Q11\t\t\t\t\t\t@ *buf0++ = MULHIGH(cosa, tr1) + MULHIGH(sina, ti1)@\n\tVSUB.S32\t\t\tQ1, Q12, Q13\t\t\t\t\t\t@ *buf0++ = MULHIGH(cosa, ti1) - MULHIGH(sina, tr1)@\n\n\tVST2.I32\t\t\t{d0, d1, d2, d3}, [r0]!\n\tsub\t\t\t\t\t\tr3, r3, #32\n\n\tVQDMULH.S32\t\tQ10, Q2, Q9\t\t\t\t\t\t\t\t\t\t@ MULHIGH(cosb, tr2)\n\tVQDMULH.S32\t\tQ11, Q3, Q5\t\t\t\t\t\t\t\t\t\t@ MULHIGH(sinb, ti2)\n\tVQDMULH.S32\t\tQ12, Q2, Q5\t\t\t\t\t\t\t\t\t\t@ MULHIGH(cosb, ti2)\n\tVQDMULH.S32\t\tQ13, Q3, Q9\t\t\t\t\t\t\t\t\t\t@ MULHIGH(sinb, tr2)\n\n\tVADD.S32\t\t\tQ0, Q10, Q11\t\t\t\t\t\t\t\t\t@ MULHIGH(cosa, tr2) + MULHIGH(sina, ti2)@\n\tVSUB.S32\t\t\tQ1, Q12, Q13\t\t\t\t\t\t\t\t\t@ MULHIGH(cosa, ti2) - MULHIGH(sina, tr2)@\n\n\tVREV64.32\t\t\tQ3, Q1\n\tVREV64.32\t\t\tQ2, Q0\n\n\tVST2.I32\t\t{d5, d7}, [r3]!\n\tVST2.I32\t\t{d4, d6}, [r3]!\n\n\tsubs     \t\tr1, r1, #4\n\tsub\t\t  \t\tr3, r3, #64\n\tbne       \tPreMDCT_LOOP\n\nPreMDCT_END:\n\tldmia     sp!, {r4 - r11, pc}\n\t@ENDP  @ |PreMDCT|\n\n\t.section .text\n\t.global\tPostMDCT\n\nPostMDCT:\n\tstmdb     sp!, {r4 - r11, lr}\n\n\tadd         r9, r0, r1, lsl #2\n\tsub         r3, r9, #32\n\n\tmovs        r1, r1, asr #2\n\tbeq         PostMDCT_END\n\nPostMDCT_LOOP:\n\tVLD4.I32\t\t\t{d0, d2, d4, d6}, [r2]!\t\t\t\t@ cosa = *csptr++@ sina = *csptr++@\n\tVLD4.I32\t\t\t{d1, d3, d5, d7}, [r2]!\t\t\t\t@ cosb = *csptr++@ sinb = *csptr++@\n\tVLD2.I32\t\t\t{d8, d9, d10, d11}, [r0]\t\t\t@ tr1 = *(zbuf1 + 0)@ ti1 = *(zbuf1 + 1)@\n\tVLD2.I32\t\t\t{d13, d15}, [r3]!\t\t\t\t\t\t\t@ tr2 = *(zbuf2 - 1)@ ti2 = *(zbuf2 + 0)@\n\tVLD2.I32\t\t\t{d12, d14}, [r3]!\t\t\t\t\t\t\t@ tr2 = *(zbuf2 - 1)@ ti2 = *(zbuf2 + 0)@\n\n\tVREV64.32\t\t\tQ8, Q6\n\tVREV64.32\t\t\tQ9, Q7\n\n\tVQDMULH.S32\t\tQ10, Q0, Q4\t\t\t\t\t\t\t\t\t\t@ MULHIGH(cosa, tr1)\n\tVQDMULH.S32\t\tQ11, Q1, Q5\t\t\t\t\t\t\t\t\t\t@ MULHIGH(sina, ti1)\n\tVQDMULH.S32\t\tQ12, Q0, Q5\t\t\t\t\t\t\t\t\t\t@ MULHIGH(cosa, ti1)\n\tVQDMULH.S32\t\tQ13, Q1, Q4\t\t\t\t\t\t\t\t\t\t@ MULHIGH(sina, tr1)\n\n\tVADD.S32\t\t\tQ0, Q10, Q11\t\t\t\t\t\t\t\t\t@ *buf0++ = MULHIGH(cosa, tr1) + MULHIGH(sina, ti1)@\n\tVSUB.S32\t\t\tQ5, Q13, Q12\t\t\t\t\t\t\t\t\t@ *buf1-- = MULHIGH(sina, tr1) - MULHIGH(cosa, ti1)@\n\n\tVQDMULH.S32\t\tQ10, Q2, Q8\t\t\t\t\t\t\t\t\t\t@ MULHIGH(cosb, tr2)\n\tVQDMULH.S32\t\tQ11, Q3, Q9\t\t\t\t\t\t\t\t\t\t@ MULHIGH(sinb, ti2)\n\tVQDMULH.S32\t\tQ12, Q2, Q9\t\t\t\t\t\t\t\t\t\t@ MULHIGH(cosb, ti2)\n\tVQDMULH.S32\t\tQ13, Q3, Q8\t\t\t\t\t\t\t\t\t\t@ MULHIGH(sinb, tr2)\n\n\tVADD.S32\t\t\tQ4, Q10, Q11\t\t\t\t\t\t\t\t\t@ *buf1-- = MULHIGH(cosa, tr2) + MULHIGH(sina, ti2)@\n\tVSUB.S32\t\t\tQ1, Q13, Q12\t\t\t\t\t\t\t\t\t@ *buf0++ = MULHIGH(sina, tr2) - MULHIGH(cosa, ti2)@\n\n\tVREV64.32\t\t\tQ2, Q4\n\tVREV64.32\t\t\tQ3, Q5\n\n\tsub\t\t\t\t\t\tr3, r3, #32\n\tVST2.I32\t\t\t{d0, d1, d2, d3}, [r0]!\n\n\tVST2.I32\t\t\t{d5, d7}, [r3]!\n\tVST2.I32\t\t\t{d4, d6}, [r3]!\n\n\tsubs     \t\t\tr1, r1, #4\n\tsub\t\t  \t\t\tr3, r3, #64\n\tbne       \tPostMDCT_LOOP\n\nPostMDCT_END:\n\tldmia     sp!, {r4 - r11, pc}\n\n\t@ENDP  \t\t@ |PostMDCT|\n\t.end\n"
  },
  {
    "path": "jni/src/asm/ARMV7/R4R8First_v7.s",
    "content": "@/*\n@ ** Copyright 2003-2010, VisualOn, Inc.\n@ **\n@ ** Licensed under the Apache License, Version 2.0 (the \"License\");\n@ ** you may not use this file except in compliance with the License.\n@ ** You may obtain a copy of the License at\n@ **\n@ **     http://www.apache.org/licenses/LICENSE-2.0\n@ **\n@ ** Unless required by applicable law or agreed to in writing, software\n@ ** distributed under the License is distributed on an \"AS IS\" BASIS,\n@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@ ** See the License for the specific language governing permissions and\n@ ** limitations under the License.\n@ */\n\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n@\tFile:\t\tR4R8First_v7.s\n@\n@\tContent:\tRadix8First and Radix4First function armv7 assemble\n@\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n\t.section .text\n\t.global\tRadix8First\n\nRadix8First:\n\tstmdb     \t\tsp!, {r4 - r11, lr}\n\n\tldr       \t\tr3, SQRT1_2\n\tcmp       \t\tr1, #0\n\n\tVDUP.I32  \t\tQ15, r3\n\tbeq       \t\tRadix8First_END\n\nRadix8First_LOOP:\n\tVLD1.I32\t\t\t{d0, d1, d2, d3},\t[r0]!\n\tVLD1.I32\t\t\t{d8, d9, d10, d11},\t[r0]!\n\n\tVADD.S32\t\t\td4, d0, d1\t\t@ r0 = buf[0] + buf[2]@i0 = buf[1] + buf[3]@\n\tVSUB.S32\t\t\td5, d0, d1\t\t@ r1 = buf[0] - buf[2]@i1 = buf[1] - buf[3]@\n\tVSUB.S32\t\t\td7, d2, d3\t\t@ r2 = buf[4] - buf[6]@i2 = buf[5] - buf[7]@\n\tVADD.S32\t\t\td6, d2, d3\t\t@ r3 = buf[4] + buf[6]@i3 = buf[5] + buf[7]@\n\tVREV64.I32\t\t\td7, d7\n\n\tVADD.S32\t\t\tQ0, Q2, Q3\t\t@ r4 = (r0 + r2)@i4 = (i0 + i2)@i6 = (i1 + r3)@r7 = (r1 + i3)\n\tVSUB.S32\t\t\tQ1, Q2, Q3\t\t@ r5 = (r0 - r2)@i5 = (i0 - i2)@r6 = (r1 - i3)@i7 = (i1 - r3)@\n\n\tVREV64.I32\t\t\td3, d3\n\n\tVADD.S32\t\t\td4, d8, d9\t\t@ r0 = buf[ 8] + buf[10]@i0 = buf[ 9] + buf[11]@\n\tVSUB.S32\t\t\td7, d10, d11\t@ r1 = buf[12] - buf[14]@i1 = buf[13] - buf[15]@\n\tVADD.S32\t\t\td6, d10, d11\t@ r2 = buf[12] + buf[14]@i2 = buf[13] + buf[15]@\n\tVREV64.I32\t\t\td7, d7\n\tVSUB.S32\t\t\td5, d8, d9\t\t@ r3 = buf[ 8] - buf[10]@i3 = buf[ 9] - buf[11]@\n\n\tVTRN.32\t\t\t\td1, d3\n\n\tVADD.S32\t\t\tQ4, Q2, Q3\t\t@ t0 = (r0 + r2) >> 1@t1 = (i0 + i2) >> 1@i0 = i1 + r3@r2 = r1 + i3@\n\tVSUB.S32\t\t\tQ5, Q2, Q3\t\t@ t2 = (r0 - r2) >> 1@t3 = (i0 - i2) >> 1@r0 = r1 - i3@i2 = i1 - r3@\n\n\tVREV64.I32\t\t\td3, d3\n\n\tVSHR.S32\t\t\td8, d8, #1\n\tVSHR.S32\t\t\tQ0, Q0, #1\n\tVREV64.I32\t\t\td10, d10\n\tVTRN.32\t\t\t\td11, d9\n\tVSHR.S32\t\t\tQ1, Q1, #1\n\tVSHR.S32\t\t\td10, d10, #1\n\tVREV64.I32\t\t\td9, d9\n\n\tsub       \t\t\tr0, r0, #0x40\n\n\tVADD.S32\t\t\td12, d0, d8\n\tVSUB.S32\t\t\td16, d0, d8\n\tVADD.S32\t\t\td14, d2, d10\n\tVSUB.S32\t\t\td18, d2, d10\n\n\tVSUB.S32\t\t\td4, d11, d9\n\tVADD.S32\t\t\td5, d11, d9\n\n\tVREV64.I32\t\t\td18, d18\n\n\tVQDMULH.S32\t\t\tQ3, Q2, Q15\n\tVTRN.32\t\t\t\td14, d18\n\tVTRN.32\t\t\t\td6, d7\n\tVREV64.I32\t\t\td18, d18\n\n\tVSUB.S32\t\t\td15, d3, d6\n\tVREV64.I32\t\t\td7, d7\n\tVADD.S32\t\t\td19, d3, d6\n\tVADD.S32\t\t\td13, d1, d7\n\tVSUB.S32\t\t\td17, d1, d7\n\n\tVREV64.I32\t\t\td17, d17\n\tVTRN.32\t\t\t\td13, d17\n\tVREV64.I32\t\t\td17, d17\n\n\tsubs       \t\t\tr1, r1, #1\n\n\tVST1.I32\t\t\t{d12, d13, d14, d15}, [r0]!\n\tVST1.I32\t\t\t{d16, d17, d18, d19}, [r0]!\n\tbne       \t\t\tRadix8First_LOOP\n\nRadix8First_END:\n\tldmia     sp!, {r4 - r11, pc}\nSQRT1_2:\n\t.word      0x2d413ccd\n\n\t@ENDP  @ |Radix8First|\n\n\t.section .text\n\t.global\tRadix4First\n\nRadix4First:\n\tstmdb     \tsp!, {r4 - r11, lr}\n\n\tcmp       \tr1, #0\n\tbeq       \tRadix4First_END\n\nRadix4First_LOOP:\n\tVLD1.I32\t\t\t{d0, d1, d2, d3}, [r0]\n\n\tVADD.S32\t\t\td4, d0, d1\t\t\t\t\t\t\t@ r0 = buf[0] + buf[2]@ r1 = buf[1] + buf[3]@\n\tVSUB.S32\t\t\td5, d0, d1\t\t\t\t\t\t\t@ r2 = buf[0] - buf[2]@ r3 = buf[1] - buf[3]@\n\tVSUB.S32\t\t\td7, d2, d3\t\t\t\t\t\t\t@ r4 = buf[4] + buf[6]@ r5 = buf[5] + buf[7]@\n\tVADD.S32\t\t\td6, d2, d3\t\t\t\t\t\t\t@ r6 = buf[4] - buf[6]@ r7 = buf[5] - buf[7]@\n\n\tVREV64.I32\t\td7, d7\t\t\t\t\t\t\t\t\t@\n\n\tVADD.S32\t\t\tQ4, Q2, Q3\n\tVSUB.S32\t\t\tQ5, Q2, Q3\n\n\tVREV64.I32\t\td11, d11\n\tVTRN.32\t\t\t\td9, d11\n\tsubs       \t\tr1, r1, #1\n\tVREV64.I32\t\td11, d11\n\tVST1.I32\t\t\t{d8, d9, d10, d11}, [r0]!\n\n\tbne       \t\tRadix4First_LOOP\n\nRadix4First_END:\n\tldmia    \t\tsp!, {r4 - r11, pc}\n\n\t@ENDP  @ |Radix4First|\n\t.end\n"
  },
  {
    "path": "jni/src/asm/ARMV7/Radix4FFT_v7.s",
    "content": "@/*\n@ ** Copyright 2003-2010, VisualOn, Inc.\n@ **\n@ ** Licensed under the Apache License, Version 2.0 (the \"License\");\n@ ** you may not use this file except in compliance with the License.\n@ ** You may obtain a copy of the License at\n@ **\n@ **     http://www.apache.org/licenses/LICENSE-2.0\n@ **\n@ ** Unless required by applicable law or agreed to in writing, software\n@ ** distributed under the License is distributed on an \"AS IS\" BASIS,\n@ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@ ** See the License for the specific language governing permissions and\n@ ** limitations under the License.\n@ */\n\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n@\tFile:\t\tRadix4FFT_v7.s\n@\n@\tContent:\tRadix4FFT armv7 assemble\n@\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n\t.section .text\n\t.global\tRadix4FFT\n\nRadix4FFT:\n\tstmdb    sp!, {r4 - r11, lr}\n\n\tmov\t\t\tr1, r1, asr #2\n\tcmp     \tr1, #0\n\tbeq     \tRadix4FFT_END\n\nRadix4FFT_LOOP1:\n\tmov     \tr5, r2, lsl #1\n\tmov     \tr8, r0\n\tmov     \tr7, r1\n\tmov     \tr5, r5, lsl #2\n\tcmp     \tr1, #0\n\trsbeq   \tr12, r5, r5, lsl #2\n\tbeq     \tRadix4FFT_LOOP1_END\n\n\trsb     \tr12, r5, r5, lsl #2\n\nRadix4FFT_LOOP2:\n\tmov     \tr6, r3\n\tmov     \tr4, r2\n\tcmp     \tr2, #0\n\tbeq     \tRadix4FFT_LOOP2_END\n\nRadix4FFT_LOOP3:\n\t@r0 = xptr[0]@\n\t@r1 = xptr[1]@\n\tVLD2.I32\t\t\t{D0, D1, D2, D3}, [r8]\n\tVLD2.I32\t\t\t{D28, D29, D30, D31}, [r6]!\t\t@ cosx = csptr[0]@ sinx = csptr[1]@\n\n\tadd\t\t\t\t\tr8, r8, r5\t\t\t\t\t\t\t\t\t\t@ xptr += step@\n\tVLD2.I32\t\t\t{D4, D5, D6,D7}, [r8]\t\t\t\t\t@ r2 = xptr[0]@ r3 = xptr[1]@\n\n\tVQDMULH.S32\t\tQ10, Q2, Q14\t\t\t\t\t\t\t\t\t@ MULHIGH(cosx, t0)\n\tVQDMULH.S32\t\tQ11, Q3, Q15\t\t\t\t\t\t\t\t\t@ MULHIGH(sinx, t1)\n\tVQDMULH.S32\t\tQ12, Q3, Q14\t\t\t\t\t\t\t\t\t@ MULHIGH(cosx, t1)\n\tVQDMULH.S32\t\tQ13, Q2, Q15\t\t\t\t\t\t\t\t\t@ MULHIGH(sinx, t0)\n\n\tVADD.S32\t\t\tQ2, Q10, Q11\t\t\t\t\t\t\t\t\t@ MULHIGH(cosx, t0) + MULHIGH(sinx, t1)\n\tVSUB.S32\t\t\tQ3, Q12, Q13\t\t\t\t\t\t\t\t\t@ MULHIGH(cosx, t1) - MULHIGH(sinx, t0)\n\n\tadd\t\t\t\t\tr8, r8, r5\t\t\t\t\t\t\t\t\t\t@ xptr += step@\n\tVSHR.S32\t\t\tQ10, Q0, #2\t\t\t\t\t\t\t\t\t\t@ t0 = r0 >> 2@\n\tVSHR.S32\t\t\tQ11, Q1, #2\t\t\t\t\t\t\t\t\t\t@ t1 = r1 >> 2@\n\n\tVSUB.S32\t\t\tQ0,\tQ10, Q2\t\t\t\t\t\t\t\t\t\t@ r0 = t0 - r2@\n\tVSUB.S32\t\t\tQ1,\tQ11, Q3\t\t\t\t\t\t\t\t\t\t@ r1 = t1 - r3@\n\tVADD.S32\t\t\tQ2, Q10, Q2\t\t\t\t\t\t\t\t\t\t@ r2 = t0 + r2@\n\tVADD.S32\t\t\tQ3, Q11, Q3\t\t\t\t\t\t\t\t\t\t@ r3 = t1 + r3@\n\n\tVLD2.I32\t\t\t{D8, D9, D10, D11}, [r8]\n\tVLD2.I32\t\t\t{D28, D29, D30, D31}, [r6]!\n\tadd\t\t\t\t\t\tr8, r8, r5\n\n\tVQDMULH.S32\t\tQ10, Q4, Q14\t\t\t\t\t\t\t\t\t@ MULHIGH(cosx, t0)\n\tVQDMULH.S32\t\tQ11, Q5, Q15\t\t\t\t\t\t\t\t\t@ MULHIGH(sinx, t1)\n\tVQDMULH.S32\t\tQ12, Q5, Q14\t\t\t\t\t\t\t\t\t@ MULHIGH(cosx, t1)\n\tVQDMULH.S32\t\tQ13, Q4, Q15\t\t\t\t\t\t\t\t\t@ MULHIGH(sinx, t0)\n\n\tVADD.S32\t\t\tQ8, Q10, Q11\t\t\t\t\t\t\t\t\t@ MULHIGH(cosx, t0) + MULHIGH(sinx, t1)\n\tVSUB.S32\t\t\tQ9, Q12, Q13\t\t\t\t\t\t\t\t\t@ MULHIGH(cosx, t1) - MULHIGH(sinx, t0)\n\n\tVLD2.I32\t\t{D12, D13, D14, D15}, [r8]\n\tVLD2.I32\t\t{D28, D29, D30, D31}, [r6]!\n\n\tVQDMULH.S32\t\tQ10, Q6, Q14\t\t\t\t\t\t\t\t\t@ MULHIGH(cosx, t0)\n\tVQDMULH.S32\t\tQ11, Q7, Q15\t\t\t\t\t\t\t\t\t@ MULHIGH(sinx, t1)\n\tVQDMULH.S32\t\tQ12, Q7, Q14\t\t\t\t\t\t\t\t\t@ MULHIGH(cosx, t1)\n\tVQDMULH.S32\t\tQ13, Q6, Q15\t\t\t\t\t\t\t\t\t@ MULHIGH(sinx, t0)\n\n\tVADD.S32\t\t\tQ6, Q10, Q11\t\t\t\t\t\t\t\t\t@ MULHIGH(cosx, t0) + MULHIGH(sinx, t1)\n\tVSUB.S32\t\t\tQ7, Q12, Q13\t\t\t\t\t\t\t\t\t@ MULHIGH(cosx, t1) - MULHIGH(sinx, t0)\n\n\tVADD.S32\t\t\tQ4, Q8, Q6\t\t\t\t\t\t\t\t\t\t@ r4 = t0 + r6@\n\tVSUB.S32\t\t\tQ5, Q7, Q9\t\t\t\t\t\t\t\t\t\t@ r5 = r7 - t1@\n\tVSUB.S32\t\t\tQ6, Q8, Q6\t\t\t\t\t\t\t\t\t\t@ r6 = t0 - r6@\n\tVADD.S32\t\t\tQ7, Q7, Q9\t\t\t\t\t\t\t\t\t\t@ r7 = r7 + t1@\n\n\tVADD.S32\t\t\tQ8, Q0, Q5\t\t\t\t\t\t\t\t\t\t@ xptr[0] = r0 + r5@\n\tVADD.S32\t\t\tQ9, Q1, Q6\t\t\t\t\t\t\t\t\t\t@ xptr[1] = r1 + r6@\n\tVST2.I32\t\t\t{D16, D17, D18, D19}, [r8]\n\n\tVSUB.S32\t\t\tQ10, Q2, Q4\t\t\t\t\t\t\t\t\t\t@ xptr[0] = r2 - r4@\n\tsub\t\t\t\t\tr8, r8, r5\t\t\t\t\t\t\t\t\t\t@ xptr -= step@\n\tVSUB.S32\t\t\tQ11, Q3, Q7\t\t\t\t\t\t\t\t\t\t@ xptr[1] = r3 - r7@\n\tVST2.I32\t\t\t{D20, D21, D22, D23}, [r8]\n\n\tVSUB.S32\t\t\tQ8, Q0, Q5\t\t\t\t\t\t\t\t\t\t@ xptr[0] = r0 - r5@\n\tsub\t\t\t\t\tr8, r8, r5\t\t\t\t\t\t\t\t\t\t@ xptr -= step@\n\tVSUB.S32\t\t\tQ9, Q1, Q6\t\t\t\t\t\t\t\t\t\t@ xptr[1] = r1 - r6@\n\tVST2.I32\t\t\t{D16, D17, D18, D19}, [r8]\n\n\tVADD.S32\t\t\tQ10, Q2, Q4\t\t\t\t\t\t\t\t\t\t@ xptr[0] = r2 + r4@\n\tsub\t\t\t\t\tr8, r8, r5\t\t\t\t\t\t\t\t\t\t@ xptr -= step@\n\tVADD.S32\t\t\tQ11, Q3, Q7\t\t\t\t\t\t\t\t\t\t@ xptr[1] = r3 + r7@\n\tVST2.I32\t\t\t{D20, D21, D22, D23}, [r8]!\n\n\tsubs    \t\t\tr4, r4, #4\n\tbne     \t\t\tRadix4FFT_LOOP3\n\nRadix4FFT_LOOP2_END:\n\tadd     \t\t\tr8, r8, r12\n\tsub    \t\t\t\tr7, r7, #1\n\tcmp\t\t\t\t\tr7, #0\n\tbhi     \t\t\tRadix4FFT_LOOP2\n\nRadix4FFT_LOOP1_END:\n\tadd     \t\t\tr3, r12, r3\n\tmov     \t\t\tr2, r2, lsl #2\n\tmovs    \t\t\tr1, r1, asr #2\n\tbne     \t\t\tRadix4FFT_LOOP1\n\nRadix4FFT_END:\n\tldmia   \t\t\tsp!, {r4 - r11, pc}\n\n\t@ENDP  @ |Radix4FFT|\n\t.end\n"
  },
  {
    "path": "jni/src/band_nrg.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tband_nrg.c\n\n\tContent:\tBand/Line energy calculations functions\n\n*******************************************************************************/\n\n#include \"basic_op.h\"\n#include \"band_nrg.h\"\n\n#ifndef ARMV5E\n/********************************************************************************\n*\n* function name: CalcBandEnergy\n* description:   Calc sfb-bandwise mdct-energies for left and right channel\n*\n**********************************************************************************/\nvoid CalcBandEnergy(const Word32 *mdctSpectrum,\n                    const Word16 *bandOffset,\n                    const Word16  numBands,\n                    Word32       *bandEnergy,\n                    Word32       *bandEnergySum)\n{\n  Word32 i, j;\n  Word32 accuSum = 0;\n\n  for (i=0; i<numBands; i++) {\n    Word32 accu = 0;\n    for (j=bandOffset[i]; j<bandOffset[i+1]; j++)\n      accu = L_add(accu, MULHIGH(mdctSpectrum[j], mdctSpectrum[j]));\n\n\taccu = L_add(accu, accu);\n    accuSum = L_add(accuSum, accu);\n    bandEnergy[i] = accu;\n  }\n  *bandEnergySum = accuSum;\n}\n\n/********************************************************************************\n*\n* function name: CalcBandEnergyMS\n* description:   Calc sfb-bandwise mdct-energies for left add or minus right channel\n*\n**********************************************************************************/\nvoid CalcBandEnergyMS(const Word32 *mdctSpectrumLeft,\n                      const Word32 *mdctSpectrumRight,\n                      const Word16 *bandOffset,\n                      const Word16  numBands,\n                      Word32       *bandEnergyMid,\n                      Word32       *bandEnergyMidSum,\n                      Word32       *bandEnergySide,\n                      Word32       *bandEnergySideSum)\n{\n\n  Word32 i, j;\n  Word32 accuMidSum = 0;\n  Word32 accuSideSum = 0;\n\n\n  for(i=0; i<numBands; i++) {\n    Word32 accuMid = 0;\n    Word32 accuSide = 0;\n    for (j=bandOffset[i]; j<bandOffset[i+1]; j++) {\n      Word32 specm, specs;\n      Word32 l, r;\n\n      l = mdctSpectrumLeft[j] >> 1;\n      r = mdctSpectrumRight[j] >> 1;\n      specm = l + r;\n      specs = l - r;\n      accuMid = L_add(accuMid, MULHIGH(specm, specm));\n      accuSide = L_add(accuSide, MULHIGH(specs, specs));\n    }\n\n\taccuMid = L_add(accuMid, accuMid);\n\taccuSide = L_add(accuSide, accuSide);\n\tbandEnergyMid[i] = accuMid;\n    accuMidSum = L_add(accuMidSum, accuMid);\n    bandEnergySide[i] = accuSide;\n    accuSideSum = L_add(accuSideSum, accuSide);\n\n  }\n  *bandEnergyMidSum = accuMidSum;\n  *bandEnergySideSum = accuSideSum;\n}\n\n#endif\n"
  },
  {
    "path": "jni/src/bit_cnt.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tbit_cnt.c\n\n\tContent:\tHuffman Bitcounter & coder functions\n\n*******************************************************************************/\n\n#include \"bit_cnt.h\"\n#include \"aac_rom.h\"\n\n#define HI_LTAB(a) (a>>8)\n#define LO_LTAB(a) (a & 0xff)\n\n#define EXPAND(a)  ((((Word32)(a&0xff00)) << 8)|(Word32)(a&0xff))\n\n\n/*****************************************************************************\n*\n* function name: count1_2_3_4_5_6_7_8_9_10_11\n* description:  counts tables 1-11\n* returns:\n* input:        quantized spectrum\n* output:       bitCount for tables 1-11\n*\n*****************************************************************************/\n\nstatic void count1_2_3_4_5_6_7_8_9_10_11(const Word16 *values,\n                                         const Word16  width,\n                                         Word16       *bitCount)\n{\n  Word32 t0,t1,t2,t3,i;\n  Word32 bc1_2,bc3_4,bc5_6,bc7_8,bc9_10;\n  Word16 bc11,sc;\n\n  bc1_2=0;\n  bc3_4=0;\n  bc5_6=0;\n  bc7_8=0;\n  bc9_10=0;\n  bc11=0;\n  sc=0;\n\n  for(i=0;i<width;i+=4){\n\n    t0= values[i+0];\n    t1= values[i+1];\n    t2= values[i+2];\n    t3= values[i+3];\n\n    /* 1,2 */\n\n    bc1_2 = bc1_2 + EXPAND(huff_ltab1_2[t0+1][t1+1][t2+1][t3+1]);\n\n    /* 5,6 */\n    bc5_6 = bc5_6 + EXPAND(huff_ltab5_6[t0+4][t1+4]);\n    bc5_6 = bc5_6 + EXPAND(huff_ltab5_6[t2+4][t3+4]);\n\n    t0=ABS(t0);\n    t1=ABS(t1);\n    t2=ABS(t2);\n    t3=ABS(t3);\n\n\n    bc3_4 = bc3_4 + EXPAND(huff_ltab3_4[t0][t1][t2][t3]);\n\n    bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t0][t1]);\n    bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t2][t3]);\n\n    bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t0][t1]);\n    bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t2][t3]);\n\n    bc11 = bc11 + huff_ltab11[t0][t1];\n    bc11 = bc11 + huff_ltab11[t2][t3];\n\n\n    sc = sc + (t0>0) + (t1>0) + (t2>0) + (t3>0);\n  }\n\n  bitCount[1]=extract_h(bc1_2);\n  bitCount[2]=extract_l(bc1_2);\n  bitCount[3]=extract_h(bc3_4) + sc;\n  bitCount[4]=extract_l(bc3_4) + sc;\n  bitCount[5]=extract_h(bc5_6);\n  bitCount[6]=extract_l(bc5_6);\n  bitCount[7]=extract_h(bc7_8) + sc;\n  bitCount[8]=extract_l(bc7_8) + sc;\n  bitCount[9]=extract_h(bc9_10) + sc;\n  bitCount[10]=extract_l(bc9_10) + sc;\n  bitCount[11]=bc11 + sc;\n}\n\n\n/*****************************************************************************\n*\n* function name: count3_4_5_6_7_8_9_10_11\n* description:  counts tables 3-11\n* returns:\n* input:        quantized spectrum\n* output:       bitCount for tables 3-11\n*\n*****************************************************************************/\n\nstatic void count3_4_5_6_7_8_9_10_11(const Word16 *values,\n                                     const Word16  width,\n                                     Word16       *bitCount)\n{\n  Word32 t0,t1,t2,t3, i;\n  Word32 bc3_4,bc5_6,bc7_8,bc9_10;\n  Word16 bc11,sc;\n\n  bc3_4=0;\n  bc5_6=0;\n  bc7_8=0;\n  bc9_10=0;\n  bc11=0;\n  sc=0;\n\n  for(i=0;i<width;i+=4){\n\n    t0= values[i+0];\n    t1= values[i+1];\n    t2= values[i+2];\n    t3= values[i+3];\n\n    /*\n      5,6\n    */\n    bc5_6 = bc5_6 + EXPAND(huff_ltab5_6[t0+4][t1+4]);\n    bc5_6 = bc5_6 + EXPAND(huff_ltab5_6[t2+4][t3+4]);\n\n    t0=ABS(t0);\n    t1=ABS(t1);\n    t2=ABS(t2);\n    t3=ABS(t3);\n\n\n    bc3_4 = bc3_4 + EXPAND(huff_ltab3_4[t0][t1][t2][t3]);\n\n    bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t0][t1]);\n    bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t2][t3]);\n\n    bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t0][t1]);\n    bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t2][t3]);\n\n    bc11 = bc11 + huff_ltab11[t0][t1];\n    bc11 = bc11 + huff_ltab11[t2][t3];\n\n\n    sc = sc + (t0>0) + (t1>0) + (t2>0) + (t3>0);\n  }\n\n  bitCount[1]=INVALID_BITCOUNT;\n  bitCount[2]=INVALID_BITCOUNT;\n  bitCount[3]=extract_h(bc3_4) + sc;\n  bitCount[4]=extract_l(bc3_4) + sc;\n  bitCount[5]=extract_h(bc5_6);\n  bitCount[6]=extract_l(bc5_6);\n  bitCount[7]=extract_h(bc7_8) + sc;\n  bitCount[8]=extract_l(bc7_8) + sc;\n  bitCount[9]=extract_h(bc9_10) + sc;\n  bitCount[10]=extract_l(bc9_10) + sc;\n  bitCount[11]=bc11 + sc;\n\n}\n\n\n\n/*****************************************************************************\n*\n* function name: count5_6_7_8_9_10_11\n* description:  counts tables 5-11\n* returns:\n* input:        quantized spectrum\n* output:       bitCount for tables 5-11\n*\n*****************************************************************************/\nstatic void count5_6_7_8_9_10_11(const Word16 *values,\n                                 const Word16  width,\n                                 Word16       *bitCount)\n{\n\n  Word32 t0,t1,i;\n  Word32 bc5_6,bc7_8,bc9_10;\n  Word16 bc11,sc;\n\n  bc5_6=0;\n  bc7_8=0;\n  bc9_10=0;\n  bc11=0;\n  sc=0;\n\n  for(i=0;i<width;i+=2){\n\n    t0 = values[i+0];\n    t1 = values[i+1];\n\n    bc5_6 = bc5_6 + EXPAND(huff_ltab5_6[t0+4][t1+4]);\n\n    t0=ABS(t0);\n    t1=ABS(t1);\n\n    bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t0][t1]);\n    bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t0][t1]);\n    bc11 = bc11 + huff_ltab11[t0][t1];\n\n\n    sc = sc + (t0>0) + (t1>0);\n  }\n  bitCount[1]=INVALID_BITCOUNT;\n  bitCount[2]=INVALID_BITCOUNT;\n  bitCount[3]=INVALID_BITCOUNT;\n  bitCount[4]=INVALID_BITCOUNT;\n  bitCount[5]=extract_h(bc5_6);\n  bitCount[6]=extract_l(bc5_6);\n  bitCount[7]=extract_h(bc7_8) + sc;\n  bitCount[8]=extract_l(bc7_8) + sc;\n  bitCount[9]=extract_h(bc9_10) + sc;\n  bitCount[10]=extract_l(bc9_10) + sc;\n  bitCount[11]=bc11 + sc;\n\n}\n\n\n/*****************************************************************************\n*\n* function name: count7_8_9_10_11\n* description:  counts tables 7-11\n* returns:\n* input:        quantized spectrum\n* output:       bitCount for tables 7-11\n*\n*****************************************************************************/\n\nstatic void count7_8_9_10_11(const Word16 *values,\n                             const Word16  width,\n                             Word16       *bitCount)\n{\n  Word32 t0,t1, i;\n  Word32 bc7_8,bc9_10;\n  Word16 bc11,sc;\n\n  bc7_8=0;\n  bc9_10=0;\n  bc11=0;\n  sc=0;\n\n  for(i=0;i<width;i+=2){\n\n    t0=ABS(values[i+0]);\n    t1=ABS(values[i+1]);\n\n    bc7_8 = bc7_8 + EXPAND(huff_ltab7_8[t0][t1]);\n    bc9_10 = bc9_10 + EXPAND(huff_ltab9_10[t0][t1]);\n    bc11 = bc11 + huff_ltab11[t0][t1];\n\n\n    sc = sc + (t0>0) + (t1>0);\n  }\n  bitCount[1]=INVALID_BITCOUNT;\n  bitCount[2]=INVALID_BITCOUNT;\n  bitCount[3]=INVALID_BITCOUNT;\n  bitCount[4]=INVALID_BITCOUNT;\n  bitCount[5]=INVALID_BITCOUNT;\n  bitCount[6]=INVALID_BITCOUNT;\n  bitCount[7]=extract_h(bc7_8) + sc;\n  bitCount[8]=extract_l(bc7_8) + sc;\n  bitCount[9]=extract_h(bc9_10) + sc;\n  bitCount[10]=extract_l(bc9_10) + sc;\n  bitCount[11]=bc11 + sc;\n\n}\n\n/*****************************************************************************\n*\n* function name: count9_10_11\n* description:  counts tables 9-11\n* returns:\n* input:        quantized spectrum\n* output:       bitCount for tables 9-11\n*\n*****************************************************************************/\nstatic void count9_10_11(const Word16 *values,\n                         const Word16  width,\n                         Word16       *bitCount)\n{\n\n  Word32 t0,t1,i;\n  Word32 bc9_10;\n  Word16 bc11,sc;\n\n  bc9_10=0;\n  bc11=0;\n  sc=0;\n\n  for(i=0;i<width;i+=2){\n\n    t0=ABS(values[i+0]);\n    t1=ABS(values[i+1]);\n\n\n    bc9_10 += EXPAND(huff_ltab9_10[t0][t1]);\n    bc11 = bc11 + huff_ltab11[t0][t1];\n\n\n    sc = sc + (t0>0) + (t1>0);\n  }\n  bitCount[1]=INVALID_BITCOUNT;\n  bitCount[2]=INVALID_BITCOUNT;\n  bitCount[3]=INVALID_BITCOUNT;\n  bitCount[4]=INVALID_BITCOUNT;\n  bitCount[5]=INVALID_BITCOUNT;\n  bitCount[6]=INVALID_BITCOUNT;\n  bitCount[7]=INVALID_BITCOUNT;\n  bitCount[8]=INVALID_BITCOUNT;\n  bitCount[9]=extract_h(bc9_10) + sc;\n  bitCount[10]=extract_l(bc9_10) + sc;\n  bitCount[11]=bc11 + sc;\n\n}\n\n/*****************************************************************************\n*\n* function name: count11\n* description:  counts table 11\n* returns:\n* input:        quantized spectrum\n* output:       bitCount for table 11\n*\n*****************************************************************************/\n static void count11(const Word16 *values,\n                    const Word16  width,\n                    Word16        *bitCount)\n{\n  Word32 t0,t1,i;\n  Word16 bc11,sc;\n\n  bc11=0;\n  sc=0;\n  for(i=0;i<width;i+=2){\n    t0=ABS(values[i+0]);\n    t1=ABS(values[i+1]);\n    bc11 = bc11 + huff_ltab11[t0][t1];\n\n\n    sc = sc + (t0>0) + (t1>0);\n  }\n\n  bitCount[1]=INVALID_BITCOUNT;\n  bitCount[2]=INVALID_BITCOUNT;\n  bitCount[3]=INVALID_BITCOUNT;\n  bitCount[4]=INVALID_BITCOUNT;\n  bitCount[5]=INVALID_BITCOUNT;\n  bitCount[6]=INVALID_BITCOUNT;\n  bitCount[7]=INVALID_BITCOUNT;\n  bitCount[8]=INVALID_BITCOUNT;\n  bitCount[9]=INVALID_BITCOUNT;\n  bitCount[10]=INVALID_BITCOUNT;\n  bitCount[11]=bc11 + sc;\n}\n\n/*****************************************************************************\n*\n* function name: countEsc\n* description:  counts table 11 (with Esc)\n* returns:\n* input:        quantized spectrum\n* output:       bitCount for tables 11 (with Esc)\n*\n*****************************************************************************/\n\nstatic void countEsc(const Word16 *values,\n                     const Word16  width,\n                     Word16       *bitCount)\n{\n  Word32 t0,t1,t00,t01,i;\n  Word16 bc11,ec,sc;\n\n  bc11=0;\n  sc=0;\n  ec=0;\n  for(i=0;i<width;i+=2){\n    t0=ABS(values[i+0]);\n    t1=ABS(values[i+1]);\n\n\n    sc = sc + (t0>0) + (t1>0);\n\n    t00 = min(t0,16);\n    t01 = min(t1,16);\n    bc11 = bc11 + huff_ltab11[t00][t01];\n\n\n    if(t0 >= 16){\n      ec = ec + 5;\n      while(sub(t0=(t0 >> 1), 16) >= 0) {\n        ec = ec + 2;\n      }\n    }\n\n\n    if(t1 >= 16){\n      ec = ec + 5;\n      while(sub(t1=(t1 >> 1), 16) >= 0) {\n        ec = ec + 2;\n      }\n    }\n  }\n  bitCount[1]=INVALID_BITCOUNT;\n  bitCount[2]=INVALID_BITCOUNT;\n  bitCount[3]=INVALID_BITCOUNT;\n  bitCount[4]=INVALID_BITCOUNT;\n  bitCount[5]=INVALID_BITCOUNT;\n  bitCount[6]=INVALID_BITCOUNT;\n  bitCount[7]=INVALID_BITCOUNT;\n  bitCount[8]=INVALID_BITCOUNT;\n  bitCount[9]=INVALID_BITCOUNT;\n  bitCount[10]=INVALID_BITCOUNT;\n  bitCount[11]=bc11 + sc + ec;\n}\n\n\ntypedef void (*COUNT_FUNCTION)(const Word16 *values,\n                               const Word16  width,\n                               Word16       *bitCount);\n\nstatic COUNT_FUNCTION countFuncTable[CODE_BOOK_ESC_LAV+1] =\n  {\n\n    count1_2_3_4_5_6_7_8_9_10_11,  /* 0  */\n    count1_2_3_4_5_6_7_8_9_10_11,  /* 1  */\n    count3_4_5_6_7_8_9_10_11,      /* 2  */\n    count5_6_7_8_9_10_11,          /* 3  */\n    count5_6_7_8_9_10_11,          /* 4  */\n    count7_8_9_10_11,              /* 5  */\n    count7_8_9_10_11,              /* 6  */\n    count7_8_9_10_11,              /* 7  */\n    count9_10_11,                  /* 8  */\n    count9_10_11,                  /* 9  */\n    count9_10_11,                  /* 10 */\n    count9_10_11,                  /* 11 */\n    count9_10_11,                  /* 12 */\n    count11,                       /* 13 */\n    count11,                       /* 14 */\n    count11,                       /* 15 */\n    countEsc                       /* 16 */\n  };\n\n/*****************************************************************************\n*\n* function name: bitCount\n* description:  count bits\n*\n*****************************************************************************/\nWord16 bitCount(const Word16 *values,\n                const Word16  width,\n                Word16        maxVal,\n                Word16       *bitCount)\n{\n  /*\n    check if we can use codebook 0\n  */\n\n  if(maxVal == 0)\n    bitCount[0] = 0;\n  else\n    bitCount[0] = INVALID_BITCOUNT;\n\n  maxVal = min(maxVal, CODE_BOOK_ESC_LAV);\n  countFuncTable[maxVal](values,width,bitCount);\n\n  return(0);\n}\n\n/*****************************************************************************\n*\n* function name: codeValues\n* description:  write huffum bits\n*\n*****************************************************************************/\nWord16 codeValues(Word16 *values, Word16 width, Word16 codeBook, HANDLE_BIT_BUF hBitstream)\n{\n\n  Word32 i, t0, t1, t2, t3, t00, t01;\n  UWord16 codeWord, codeLength;\n  Word16 sign, signLength;\n\n\n  switch (codeBook) {\n    case CODE_BOOK_ZERO_NO:\n      break;\n\n    case CODE_BOOK_1_NO:\n      for(i=0; i<width; i+=4) {\n        t0         = values[i+0];\n        t1         = values[i+1];\n        t2         = values[i+2];\n        t3         = values[i+3];\n        codeWord   = huff_ctab1[t0+1][t1+1][t2+1][t3+1];\n        codeLength = HI_LTAB(huff_ltab1_2[t0+1][t1+1][t2+1][t3+1]);\n        WriteBits(hBitstream, codeWord, codeLength);\n      }\n      break;\n\n    case CODE_BOOK_2_NO:\n      for(i=0; i<width; i+=4) {\n        t0         = values[i+0];\n        t1         = values[i+1];\n        t2         = values[i+2];\n        t3         = values[i+3];\n        codeWord   = huff_ctab2[t0+1][t1+1][t2+1][t3+1];\n        codeLength = LO_LTAB(huff_ltab1_2[t0+1][t1+1][t2+1][t3+1]);\n        WriteBits(hBitstream,codeWord,codeLength);\n      }\n      break;\n\n    case CODE_BOOK_3_NO:\n      for(i=0; i<width; i+=4) {\n        sign=0;\n        signLength=0;\n        t0 = values[i+0];\n\n        if(t0 != 0){\n          signLength = signLength + 1;\n          sign = sign << 1;\n\n          if(t0 < 0){\n            sign|=1;\n            t0=-t0;\n          }\n        }\n        t1 = values[i+1];\n\n        if(t1 != 0){\n          signLength = signLength + 1;\n          sign = sign << 1;\n\n          if(t1 < 0){\n            sign|=1;\n            t1=-t1;\n          }\n        }\n        t2 = values[i+2];\n\n        if(t2 != 0){\n          signLength = signLength + 1;\n          sign = sign << 1;\n\n          if(t2 < 0){\n            sign|=1;\n            t2=-t2;\n          }\n        }\n        t3 = values[i+3];\n        if(t3 != 0){\n          signLength = signLength + 1;\n          sign = sign << 1;\n\n          if(t3 < 0){\n            sign|=1;\n            t3=-t3;\n          }\n        }\n\n        codeWord   = huff_ctab3[t0][t1][t2][t3];\n        codeLength = HI_LTAB(huff_ltab3_4[t0][t1][t2][t3]);\n        WriteBits(hBitstream,codeWord,codeLength);\n        WriteBits(hBitstream,sign,signLength);\n      }\n      break;\n\n    case CODE_BOOK_4_NO:\n      for(i=0; i<width; i+=4) {\n        sign=0;\n        signLength=0;\n        t0 = values[i+0];\n\n        if(t0 != 0){\n          signLength = signLength + 1;\n          sign = sign << 1;\n          if(t0 < 0){\n            sign|=1;\n            t0=-t0;\n          }\n        }\n        t1 = values[i+1];\n\n        if(t1 != 0){\n          signLength = signLength + 1;\n          sign = sign << 1;\n\n          if(t1 < 0){\n            sign|=1;\n            t1=-t1;\n          }\n        }\n        t2 = values[i+2];\n\n        if(t2 != 0){\n          signLength = signLength + 1;\n          sign = sign << 1;\n\n          if(t2 < 0){\n            sign|=1;\n            t2=-t2;\n          }\n        }\n        t3 = values[i+3];\n\n        if(t3 != 0){\n          signLength = signLength + 1;\n          sign = sign << 1;\n\n          if(t3 < 0){\n            sign|=1;\n            t3=-t3;\n          }\n        }\n        codeWord   = huff_ctab4[t0][t1][t2][t3];\n        codeLength = LO_LTAB(huff_ltab3_4[t0][t1][t2][t3]);\n        WriteBits(hBitstream,codeWord,codeLength);\n        WriteBits(hBitstream,sign,signLength);\n      }\n      break;\n\n    case CODE_BOOK_5_NO:\n      for(i=0; i<width; i+=2) {\n        t0         = values[i+0];\n        t1         = values[i+1];\n        codeWord   = huff_ctab5[t0+4][t1+4];\n        codeLength = HI_LTAB(huff_ltab5_6[t0+4][t1+4]);\n        WriteBits(hBitstream,codeWord,codeLength);\n      }\n      break;\n\n    case CODE_BOOK_6_NO:\n      for(i=0; i<width; i+=2) {\n        t0         = values[i+0];\n        t1         = values[i+1];\n        codeWord   = huff_ctab6[t0+4][t1+4];\n        codeLength = LO_LTAB(huff_ltab5_6[t0+4][t1+4]);\n        WriteBits(hBitstream,codeWord,codeLength);\n      }\n      break;\n\n    case CODE_BOOK_7_NO:\n      for(i=0; i<width; i+=2){\n        sign=0;\n        signLength=0;\n        t0 = values[i+0];\n\n        if(t0 != 0){\n          signLength = signLength + 1;\n          sign = sign << 1;\n\n          if(t0 < 0){\n            sign|=1;\n            t0=-t0;\n          }\n        }\n\n        t1 = values[i+1];\n\n        if(t1 != 0){\n          signLength = signLength + 1;\n          sign = sign << 1;\n\n          if(t1 < 0){\n            sign|=1;\n            t1=-t1;\n          }\n        }\n        codeWord   = huff_ctab7[t0][t1];\n        codeLength = HI_LTAB(huff_ltab7_8[t0][t1]);\n        WriteBits(hBitstream,codeWord,codeLength);\n        WriteBits(hBitstream,sign,signLength);\n      }\n      break;\n\n    case CODE_BOOK_8_NO:\n      for(i=0; i<width; i+=2) {\n        sign=0;\n        signLength=0;\n        t0 = values[i+0];\n\n        if(t0 != 0){\n          signLength = signLength + 1;\n          sign = sign << 1;\n\n          if(t0 < 0){\n            sign|=1;\n            t0=-t0;\n          }\n        }\n\n        t1 = values[i+1];\n\n        if(t1 != 0){\n          signLength = signLength + 1;\n          sign = sign << 1;\n\n          if(t1 < 0){\n            sign|=1;\n            t1=-t1;\n          }\n        }\n        codeWord   = huff_ctab8[t0][t1];\n        codeLength = LO_LTAB(huff_ltab7_8[t0][t1]);\n        WriteBits(hBitstream,codeWord,codeLength);\n        WriteBits(hBitstream,sign,signLength);\n      }\n      break;\n\n    case CODE_BOOK_9_NO:\n      for(i=0; i<width; i+=2) {\n        sign=0;\n        signLength=0;\n        t0 = values[i+0];\n\n        if(t0 != 0){\n          signLength = signLength + 1;\n          sign = sign << 1;\n\n          if(t0 < 0){\n            sign|=1;\n            t0=-t0;\n          }\n        }\n\n        t1 = values[i+1];\n\n        if(t1 != 0){\n          signLength = signLength + 1;\n          sign = sign << 1;\n\n          if(t1 < 0){\n            sign|=1;\n            t1=-t1;\n          }\n        }\n        codeWord   = huff_ctab9[t0][t1];\n        codeLength = HI_LTAB(huff_ltab9_10[t0][t1]);\n        WriteBits(hBitstream,codeWord,codeLength);\n        WriteBits(hBitstream,sign,signLength);\n      }\n      break;\n\n    case CODE_BOOK_10_NO:\n      for(i=0; i<width; i+=2) {\n        sign=0;\n        signLength=0;\n        t0 = values[i+0];\n\n        if(t0 != 0){\n          signLength = signLength + 1;\n          sign = sign << 1;\n\n          if(t0 < 0){\n            sign|=1;\n            t0=-t0;\n          }\n        }\n\n        t1 = values[i+1];\n\n        if(t1 != 0){\n          signLength = signLength + 1;\n          sign = sign << 1;\n\n          if(t1 < 0){\n            sign|=1;\n            t1=-t1;\n          }\n        }\n        codeWord   = huff_ctab10[t0][t1];\n        codeLength = LO_LTAB(huff_ltab9_10[t0][t1]);\n        WriteBits(hBitstream,codeWord,codeLength);\n        WriteBits(hBitstream,sign,signLength);\n      }\n      break;\n\n    case CODE_BOOK_ESC_NO:\n      for(i=0; i<width; i+=2) {\n        sign=0;\n        signLength=0;\n        t0 = values[i+0];\n\n        if(t0 != 0){\n          signLength = signLength + 1;\n          sign = sign << 1;\n\n          if(t0 < 0){\n            sign|=1;\n            t0=-t0;\n          }\n        }\n\n        t1 = values[i+1];\n\n        if(t1 != 0){\n          signLength = signLength + 1;\n          sign = sign << 1;\n\n          if(t1 < 0){\n            sign|=1;\n            t1=-t1;\n          }\n        }\n        t00 = min(t0,16);\n        t01 = min(t1,16);\n\n        codeWord   = huff_ctab11[t00][t01];\n        codeLength = huff_ltab11[t00][t01];\n        WriteBits(hBitstream,codeWord,codeLength);\n        WriteBits(hBitstream,sign,signLength);\n\n        if(t0 >= 16){\n          Word16 n, p;\n          n=0;\n          p=t0;\n          while(sub(p=(p >> 1), 16) >= 0){\n\n            WriteBits(hBitstream,1,1);\n            n = n + 1;\n          }\n          WriteBits(hBitstream,0,1);\n          n = n + 4;\n          WriteBits(hBitstream,(t0 - (1 << n)),n);\n        }\n\n        if(t1 >= 16){\n          Word16 n, p;\n          n=0;\n          p=t1;\n          while(sub(p=(p >> 1), 16) >= 0){\n\n            WriteBits(hBitstream,1,1);\n            n = n + 1;\n          }\n          WriteBits(hBitstream,0,1);\n          n = n + 4;\n          WriteBits(hBitstream,(t1 - (1 << n)),n);\n        }\n      }\n      break;\n\n    default:\n      break;\n  }\n  return(0);\n}\n\nWord16 bitCountScalefactorDelta(Word16 delta)\n{\n  return(huff_ltabscf[delta+CODE_BOOK_SCF_LAV]);\n}\n\nWord16 codeScalefactorDelta(Word16 delta, HANDLE_BIT_BUF hBitstream)\n{\n  Word32 codeWord;\n  Word16 codeLength;\n\n\n  if(delta > CODE_BOOK_SCF_LAV || delta < -CODE_BOOK_SCF_LAV)\n    return(1);\n\n  codeWord   = huff_ctabscf[delta + CODE_BOOK_SCF_LAV];\n  codeLength = huff_ltabscf[delta + CODE_BOOK_SCF_LAV];\n  WriteBits(hBitstream,codeWord,codeLength);\n  return(0);\n}\n"
  },
  {
    "path": "jni/src/bitbuffer.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tbitbuffer.c\n\n\tContent:\tBit Buffer Management functions\n\n*******************************************************************************/\n\n#include \"bitbuffer.h\"\n\n/*****************************************************************************\n*\n* function name: updateBitBufWordPtr\n* description:  update Bit Buffer pointer\n*\n*****************************************************************************/\nstatic void updateBitBufWordPtr(HANDLE_BIT_BUF hBitBuf,\n                                UWord8 **pBitBufWord,\n                                Word16   cnt)\n{\n  *pBitBufWord += cnt;\n\n\n  if(*pBitBufWord > hBitBuf->pBitBufEnd) {\n    *pBitBufWord -= (hBitBuf->pBitBufEnd - hBitBuf->pBitBufBase + 1);\n  }\n\n  if(*pBitBufWord < hBitBuf->pBitBufBase) {\n    *pBitBufWord += (hBitBuf->pBitBufEnd - hBitBuf->pBitBufBase + 1);\n  }\n}\n\n\n/*****************************************************************************\n*\n* function name: CreateBitBuffer\n* description:  create and init Bit Buffer Management\n*\n*****************************************************************************/\nHANDLE_BIT_BUF CreateBitBuffer(HANDLE_BIT_BUF hBitBuf,\n                               UWord8 *pBitBufBase,\n                               Word16  bitBufSize)\n{\n  assert(bitBufSize*8 <= 32768);\n\n  hBitBuf->pBitBufBase = pBitBufBase;\n  hBitBuf->pBitBufEnd  = pBitBufBase + bitBufSize - 1;\n\n  hBitBuf->pWriteNext  = pBitBufBase;\n\n  hBitBuf->cache       = 0;\n\n  hBitBuf->wBitPos     = 0;\n  hBitBuf->cntBits     = 0;\n\n  hBitBuf->size        = (bitBufSize << 3);\n  hBitBuf->isValid     = 1;\n\n  return hBitBuf;\n}\n\n/*****************************************************************************\n*\n* function name: DeleteBitBuffer\n* description:  uninit Bit Buffer Management\n*\n*****************************************************************************/\nvoid DeleteBitBuffer(HANDLE_BIT_BUF *hBitBuf)\n{\n  if(*hBitBuf)\n\t(*hBitBuf)->isValid = 0;\n  *hBitBuf = NULL;\n}\n\n/*****************************************************************************\n*\n* function name: ResetBitBuf\n* description:  reset Bit Buffer Management\n*\n*****************************************************************************/\nvoid ResetBitBuf(HANDLE_BIT_BUF hBitBuf,\n                 UWord8 *pBitBufBase,\n                 Word16  bitBufSize)\n{\n  hBitBuf->pBitBufBase = pBitBufBase;\n  hBitBuf->pBitBufEnd  = pBitBufBase + bitBufSize - 1;\n\n\n  hBitBuf->pWriteNext  = pBitBufBase;\n\n  hBitBuf->wBitPos     = 0;\n  hBitBuf->cntBits     = 0;\n\n  hBitBuf->cache\t   = 0;\n}\n\n/*****************************************************************************\n*\n* function name: CopyBitBuf\n* description:  copy Bit Buffer Management\n*\n*****************************************************************************/\nvoid CopyBitBuf(HANDLE_BIT_BUF hBitBufSrc,\n                HANDLE_BIT_BUF hBitBufDst)\n{\n  *hBitBufDst = *hBitBufSrc;\n}\n\n/*****************************************************************************\n*\n* function name: GetBitsAvail\n* description:  get available bits\n*\n*****************************************************************************/\nWord16 GetBitsAvail(HANDLE_BIT_BUF hBitBuf)\n{\n  return hBitBuf->cntBits;\n}\n\n/*****************************************************************************\n*\n* function name: WriteBits\n* description:  write bits to the buffer\n*\n*****************************************************************************/\nWord16 WriteBits(HANDLE_BIT_BUF hBitBuf,\n                 UWord32 writeValue,\n                 Word16 noBitsToWrite)\n{\n  Word16 wBitPos;\n\n  assert(noBitsToWrite <= (Word16)sizeof(Word32)*8);\n\n  if(noBitsToWrite == 0)\n\t  return noBitsToWrite;\n\n  hBitBuf->cntBits += noBitsToWrite;\n\n  wBitPos = hBitBuf->wBitPos;\n  wBitPos += noBitsToWrite;\n  writeValue &= ~(0xffffffff << noBitsToWrite); // Mask out everything except the lowest noBitsToWrite bits\n  writeValue <<= 32 - wBitPos;\n  writeValue |= hBitBuf->cache;\n\n  while (wBitPos >= 8)\n  {\n\t  UWord8 tmp;\n\t  tmp = (UWord8)((writeValue >> 24) & 0xFF);\n\n\t  *hBitBuf->pWriteNext++ = tmp;\n\t  writeValue <<= 8;\n\t  wBitPos -= 8;\n  }\n\n  hBitBuf->wBitPos = wBitPos;\n  hBitBuf->cache = writeValue;\n\n  return noBitsToWrite;\n}\n"
  },
  {
    "path": "jni/src/bitenc.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tbitenc.c\n\n\tContent:\tBitstream encoder functions\n\n*******************************************************************************/\n\n#include \"bitenc.h\"\n#include \"bit_cnt.h\"\n#include \"dyn_bits.h\"\n#include \"qc_data.h\"\n#include \"interface.h\"\n\n\nstatic const  Word16 globalGainOffset = 100;\nstatic const  Word16 icsReservedBit   = 0;\n\n\n/*****************************************************************************\n*\n* function name: encodeSpectralData\n* description:  encode spectral data\n* returns:      spectral bits used\n*\n*****************************************************************************/\nstatic Word32 encodeSpectralData(Word16             *sfbOffset,\n                                 SECTION_DATA       *sectionData,\n                                 Word16             *quantSpectrum,\n                                 HANDLE_BIT_BUF      hBitStream)\n{\n  Word16 i,sfb;\n  Word16 dbgVal;\n  SECTION_INFO* psectioninfo;\n  dbgVal = GetBitsAvail(hBitStream);\n\n  for(i=0; i<sectionData->noOfSections; i++) {\n    psectioninfo = &(sectionData->sectionInfo[i]);\n\t/*\n       huffencode spectral data for this section\n    */\n    for(sfb=psectioninfo->sfbStart;\n        sfb<psectioninfo->sfbStart+psectioninfo->sfbCnt;\n        sfb++) {\n      codeValues(quantSpectrum+sfbOffset[sfb],\n                 sfbOffset[sfb+1] - sfbOffset[sfb],\n                 psectioninfo->codeBook,\n                 hBitStream);\n    }\n  }\n\n  return(GetBitsAvail(hBitStream)-dbgVal);\n}\n\n/*****************************************************************************\n*\n* function name:encodeGlobalGain\n* description: encodes Global Gain (common scale factor)\n* returns:     none\n*\n*****************************************************************************/\nstatic void encodeGlobalGain(Word16 globalGain,\n                             Word16 logNorm,\n                             Word16 scalefac,\n                             HANDLE_BIT_BUF hBitStream)\n{\n  WriteBits(hBitStream, ((globalGain - scalefac) + globalGainOffset-(logNorm << 2)), 8);\n}\n\n\n/*****************************************************************************\n*\n* function name:encodeIcsInfo\n* description: encodes Ics Info\n* returns:     none\n*\n*****************************************************************************/\n\nstatic void encodeIcsInfo(Word16 blockType,\n                          Word16 windowShape,\n                          Word16 groupingMask,\n                          SECTION_DATA *sectionData,\n                          HANDLE_BIT_BUF  hBitStream)\n{\n  WriteBits(hBitStream,icsReservedBit,1);\n  WriteBits(hBitStream,blockType,2);\n  WriteBits(hBitStream,windowShape,1);\n\n\n  switch(blockType){\n    case LONG_WINDOW:\n    case START_WINDOW:\n    case STOP_WINDOW:\n      WriteBits(hBitStream,sectionData->maxSfbPerGroup,6);\n\n      /* No predictor data present */\n      WriteBits(hBitStream, 0, 1);\n      break;\n\n    case SHORT_WINDOW:\n      WriteBits(hBitStream,sectionData->maxSfbPerGroup,4);\n\n      /*\n      Write grouping bits\n      */\n      WriteBits(hBitStream,groupingMask,TRANS_FAC-1);\n      break;\n  }\n}\n\n/*****************************************************************************\n*\n* function name: encodeSectionData\n* description:  encode section data (common Huffman codebooks for adjacent\n*               SFB's)\n* returns:      none\n*\n*****************************************************************************/\nstatic Word32 encodeSectionData(SECTION_DATA *sectionData,\n                                HANDLE_BIT_BUF hBitStream)\n{\n  Word16 sectEscapeVal=0,sectLenBits=0;\n  Word16 sectLen;\n  Word16 i;\n  Word16 dbgVal=GetBitsAvail(hBitStream);\n\n\n\n  switch(sectionData->blockType)\n  {\n    case LONG_WINDOW:\n    case START_WINDOW:\n    case STOP_WINDOW:\n      sectEscapeVal = SECT_ESC_VAL_LONG;\n      sectLenBits   = SECT_BITS_LONG;\n      break;\n\n    case SHORT_WINDOW:\n      sectEscapeVal = SECT_ESC_VAL_SHORT;\n      sectLenBits   = SECT_BITS_SHORT;\n      break;\n  }\n\n  for(i=0;i<sectionData->noOfSections;i++) {\n    WriteBits(hBitStream,sectionData->sectionInfo[i].codeBook,4);\n    sectLen = sectionData->sectionInfo[i].sfbCnt;\n\n    while(sectLen >= sectEscapeVal) {\n\n      WriteBits(hBitStream,sectEscapeVal,sectLenBits);\n      sectLen = sectLen - sectEscapeVal;\n    }\n    WriteBits(hBitStream,sectLen,sectLenBits);\n  }\n  return(GetBitsAvail(hBitStream)-dbgVal);\n}\n\n/*****************************************************************************\n*\n* function name: encodeScaleFactorData\n* description:  encode DPCM coded scale factors\n* returns:      none\n*\n*****************************************************************************/\nstatic Word32 encodeScaleFactorData(UWord16        *maxValueInSfb,\n                                    SECTION_DATA   *sectionData,\n                                    Word16         *scalefac,\n                                    HANDLE_BIT_BUF  hBitStream)\n{\n  Word16 i,j,lastValScf,deltaScf;\n  Word16 dbgVal = GetBitsAvail(hBitStream);\n  SECTION_INFO* psectioninfo;\n\n  lastValScf=scalefac[sectionData->firstScf];\n\n  for(i=0;i<sectionData->noOfSections;i++){\n    psectioninfo = &(sectionData->sectionInfo[i]);\n    if (psectioninfo->codeBook != CODE_BOOK_ZERO_NO){\n      for (j=psectioninfo->sfbStart;\n           j<psectioninfo->sfbStart+psectioninfo->sfbCnt; j++){\n\n        if(maxValueInSfb[j] == 0) {\n          deltaScf = 0;\n        }\n        else {\n          deltaScf = lastValScf - scalefac[j];\n          lastValScf = scalefac[j];\n        }\n\n        if(codeScalefactorDelta(deltaScf,hBitStream)){\n          return(1);\n        }\n      }\n    }\n\n  }\n  return(GetBitsAvail(hBitStream)-dbgVal);\n}\n\n/*****************************************************************************\n*\n* function name:encodeMsInfo\n* description: encodes MS-Stereo Info\n* returns:     none\n*\n*****************************************************************************/\nstatic void encodeMSInfo(Word16          sfbCnt,\n                         Word16          grpSfb,\n                         Word16          maxSfb,\n                         Word16          msDigest,\n                         Word16         *jsFlags,\n                         HANDLE_BIT_BUF  hBitStream)\n{\n  Word16 sfb, sfbOff;\n\n\n  switch(msDigest)\n  {\n    case MS_NONE:\n      WriteBits(hBitStream,SI_MS_MASK_NONE,2);\n      break;\n\n    case MS_ALL:\n      WriteBits(hBitStream,SI_MS_MASK_ALL,2);\n      break;\n\n    case MS_SOME:\n      WriteBits(hBitStream,SI_MS_MASK_SOME,2);\n      for(sfbOff = 0; sfbOff < sfbCnt; sfbOff+=grpSfb) {\n        for(sfb=0; sfb<maxSfb; sfb++) {\n\n          if(jsFlags[sfbOff+sfb] & MS_ON) {\n            WriteBits(hBitStream,1,1);\n          }\n          else{\n            WriteBits(hBitStream,0,1);\n          }\n        }\n      }\n      break;\n  }\n\n}\n\n/*****************************************************************************\n*\n* function name: encodeTnsData\n* description:  encode TNS data (filter order, coeffs, ..)\n* returns:      none\n*\n*****************************************************************************/\nstatic void encodeTnsData(TNS_INFO tnsInfo,\n                          Word16 blockType,\n                          HANDLE_BIT_BUF hBitStream) {\n  Word16 i,k;\n  Flag tnsPresent;\n  Word16 numOfWindows;\n  Word16 coefBits;\n  Flag isShort;\n\n\n  if (blockType==2) {\n    isShort = 1;\n    numOfWindows = TRANS_FAC;\n  }\n  else {\n    isShort = 0;\n    numOfWindows = 1;\n  }\n\n  tnsPresent=0;\n  for (i=0; i<numOfWindows; i++) {\n\n    if (tnsInfo.tnsActive[i]) {\n      tnsPresent=1;\n    }\n  }\n\n  if (tnsPresent==0) {\n    WriteBits(hBitStream,0,1);\n  }\n  else{ /* there is data to be written*/\n    WriteBits(hBitStream,1,1); /*data_present */\n    for (i=0; i<numOfWindows; i++) {\n\n      WriteBits(hBitStream,tnsInfo.tnsActive[i],(isShort?1:2));\n\n      if (tnsInfo.tnsActive[i]) {\n\n        WriteBits(hBitStream,((tnsInfo.coefRes[i] - 4)==0?1:0),1);\n\n        WriteBits(hBitStream,tnsInfo.length[i],(isShort?4:6));\n\n        WriteBits(hBitStream,tnsInfo.order[i],(isShort?3:5));\n\n        if (tnsInfo.order[i]){\n          WriteBits(hBitStream, FILTER_DIRECTION, 1);\n\n          if(tnsInfo.coefRes[i] == 4) {\n            coefBits = 3;\n            for(k=0; k<tnsInfo.order[i]; k++) {\n\n              if (tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] > 3 ||\n                  tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] < -4) {\n                coefBits = 4;\n                break;\n              }\n            }\n          }\n          else {\n            coefBits = 2;\n            for(k=0; k<tnsInfo.order[i]; k++) {\n\n              if (tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] > 1 ||\n                  tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] < -2) {\n                coefBits = 3;\n                break;\n              }\n            }\n          }\n          WriteBits(hBitStream, tnsInfo.coefRes[i] - coefBits, 1); /*coef_compres*/\n          for (k=0; k<tnsInfo.order[i]; k++ ) {\n            static const Word16 rmask[] = {0,1,3,7,15};\n\n            WriteBits(hBitStream,tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] & rmask[coefBits],coefBits);\n          }\n        }\n      }\n    }\n  }\n\n}\n\n/*****************************************************************************\n*\n* function name: encodeGainControlData\n* description:  unsupported\n* returns:      none\n*\n*****************************************************************************/\nstatic void encodeGainControlData(HANDLE_BIT_BUF hBitStream)\n{\n  WriteBits(hBitStream,0,1);\n}\n\n/*****************************************************************************\n*\n* function name: encodePulseData\n* description:  not supported yet (dummy)\n* returns:      none\n*\n*****************************************************************************/\nstatic void encodePulseData(HANDLE_BIT_BUF hBitStream)\n{\n  WriteBits(hBitStream,0,1);\n}\n\n\n/*****************************************************************************\n*\n* function name: WriteIndividualChannelStream\n* description:  management of write process of individual channel stream\n* returns:      none\n*\n*****************************************************************************/\nstatic void\nwriteIndividualChannelStream(Flag   commonWindow,\n                             Word16 mdctScale,\n                             Word16 windowShape,\n                             Word16 groupingMask,\n                             Word16 *sfbOffset,\n                             Word16 scf[],\n                             UWord16 *maxValueInSfb,\n                             Word16 globalGain,\n                             Word16 quantSpec[],\n                             SECTION_DATA *sectionData,\n                             HANDLE_BIT_BUF hBitStream,\n                             TNS_INFO tnsInfo)\n{\n  Word16 logNorm;\n\n  logNorm = LOG_NORM_PCM - (mdctScale + 1);\n\n  encodeGlobalGain(globalGain, logNorm,scf[sectionData->firstScf], hBitStream);\n\n\n  if(!commonWindow) {\n    encodeIcsInfo(sectionData->blockType, windowShape, groupingMask, sectionData, hBitStream);\n  }\n\n  encodeSectionData(sectionData, hBitStream);\n\n  encodeScaleFactorData(maxValueInSfb,\n                        sectionData,\n                        scf,\n                        hBitStream);\n\n  encodePulseData(hBitStream);\n\n  encodeTnsData(tnsInfo, sectionData->blockType, hBitStream);\n\n  encodeGainControlData(hBitStream);\n\n  encodeSpectralData(sfbOffset,\n                     sectionData,\n                     quantSpec,\n                     hBitStream);\n\n}\n\n/*****************************************************************************\n*\n* function name: writeSingleChannelElement\n* description:  write single channel element to bitstream\n* returns:      none\n*\n*****************************************************************************/\nstatic Word16 writeSingleChannelElement(Word16 instanceTag,\n                                        Word16 *sfbOffset,\n                                        QC_OUT_CHANNEL* qcOutChannel,\n                                        HANDLE_BIT_BUF hBitStream,\n                                        TNS_INFO tnsInfo)\n{\n  WriteBits(hBitStream,ID_SCE,3);\n  WriteBits(hBitStream,instanceTag,4);\n  writeIndividualChannelStream(0,\n                               qcOutChannel->mdctScale,\n                               qcOutChannel->windowShape,\n                               qcOutChannel->groupingMask,\n                               sfbOffset,\n                               qcOutChannel->scf,\n                               qcOutChannel->maxValueInSfb,\n                               qcOutChannel->globalGain,\n                               qcOutChannel->quantSpec,\n                               &(qcOutChannel->sectionData),\n                               hBitStream,\n                               tnsInfo\n                               );\n  return(0);\n}\n\n\n\n/*****************************************************************************\n*\n* function name: writeChannelPairElement\n* description:\n* returns:      none\n*\n*****************************************************************************/\nstatic Word16 writeChannelPairElement(Word16 instanceTag,\n                                      Word16 msDigest,\n                                      Word16 msFlags[MAX_GROUPED_SFB],\n                                      Word16 *sfbOffset[2],\n                                      QC_OUT_CHANNEL qcOutChannel[2],\n                                      HANDLE_BIT_BUF hBitStream,\n                                      TNS_INFO tnsInfo[2])\n{\n  WriteBits(hBitStream,ID_CPE,3);\n  WriteBits(hBitStream,instanceTag,4);\n  WriteBits(hBitStream,1,1); /* common window */\n\n  encodeIcsInfo(qcOutChannel[0].sectionData.blockType,\n                qcOutChannel[0].windowShape,\n                qcOutChannel[0].groupingMask,\n                &(qcOutChannel[0].sectionData),\n                hBitStream);\n\n  encodeMSInfo(qcOutChannel[0].sectionData.sfbCnt,\n               qcOutChannel[0].sectionData.sfbPerGroup,\n               qcOutChannel[0].sectionData.maxSfbPerGroup,\n               msDigest,\n               msFlags,\n               hBitStream);\n\n  writeIndividualChannelStream(1,\n                               qcOutChannel[0].mdctScale,\n                               qcOutChannel[0].windowShape,\n                               qcOutChannel[0].groupingMask,\n                               sfbOffset[0],\n                               qcOutChannel[0].scf,\n                               qcOutChannel[0].maxValueInSfb,\n                               qcOutChannel[0].globalGain,\n                               qcOutChannel[0].quantSpec,\n                               &(qcOutChannel[0].sectionData),\n                               hBitStream,\n                               tnsInfo[0]);\n\n  writeIndividualChannelStream(1,\n                               qcOutChannel[1].mdctScale,\n                               qcOutChannel[1].windowShape,\n                               qcOutChannel[1].groupingMask,\n                               sfbOffset[1],\n                               qcOutChannel[1].scf,\n                               qcOutChannel[1].maxValueInSfb,\n                               qcOutChannel[1].globalGain,\n                               qcOutChannel[1].quantSpec,\n                               &(qcOutChannel[1].sectionData),\n                               hBitStream,\n                               tnsInfo[1]);\n\n  return(0);\n}\n\n\n\n/*****************************************************************************\n*\n* function name: writeFillElement\n* description:  write fill elements to bitstream\n* returns:      none\n*\n*****************************************************************************/\nstatic void writeFillElement( const UWord8 *ancBytes,\n                              Word16 totFillBits,\n                              HANDLE_BIT_BUF hBitStream)\n{\n  Word16 i;\n  Word16 cnt,esc_count;\n\n  /*\n    Write fill Element(s):\n    amount of a fill element can be 7+X*8 Bits, X element of [0..270]\n  */\n\n  while(totFillBits >= (3+4)) {\n    cnt = min(((totFillBits - (3+4)) >> 3), ((1<<4)-1));\n\n    WriteBits(hBitStream,ID_FIL,3);\n    WriteBits(hBitStream,cnt,4);\n\n    totFillBits = totFillBits - (3+4);\n\n\n    if ((cnt == (1<<4)-1)) {\n\n      esc_count = min( ((totFillBits >> 3) - ((1<<4)-1)), (1<<8)-1);\n      WriteBits(hBitStream,esc_count,8);\n      totFillBits = (totFillBits - 8);\n      cnt = cnt + (esc_count - 1);\n    }\n\n    for(i=0;i<cnt;i++) {\n\n      if(ancBytes)\n        WriteBits(hBitStream, *ancBytes++,8);\n      else\n        WriteBits(hBitStream,0,8);\n      totFillBits = totFillBits - 8;\n    }\n  }\n}\n\n/*****************************************************************************\n*\n* function name: WriteBitStream\n* description:  main function of write bitsteam process\n* returns:      0 if success\n*\n*****************************************************************************/\nWord16 WriteBitstream (HANDLE_BIT_BUF hBitStream,\n                       ELEMENT_INFO elInfo,\n                       QC_OUT *qcOut,\n                       PSY_OUT *psyOut,\n                       Word16 *globUsedBits,\n                       const UWord8 *ancBytes,\n\t\t\t\t\t   Word16 sampindex\n                       ) /* returns error code */\n{\n  Word16 bitMarkUp;\n  Word16 elementUsedBits;\n  Word16 frameBits=0;\n\n  /*   struct bitbuffer bsWriteCopy; */\n  bitMarkUp = GetBitsAvail(hBitStream);\n  if(qcOut->qcElement.adtsUsed)  /*  write adts header*/\n  {\n\t  WriteBits(hBitStream, 0xFFF, 12); /* 12 bit Syncword */\n\t  WriteBits(hBitStream, 1, 1); /* ID == 0 for MPEG4 AAC, 1 for MPEG2 AAC */\n\t  WriteBits(hBitStream, 0, 2); /* layer == 0 */\n\t  WriteBits(hBitStream, 1, 1); /* protection absent */\n\t  WriteBits(hBitStream, 1, 2); /* profile */\n\t  WriteBits(hBitStream, sampindex, 4); /* sampling rate */\n\t  WriteBits(hBitStream, 0, 1); /* private bit */\n\t  WriteBits(hBitStream, elInfo.nChannelsInEl, 3); /* ch. config (must be > 0) */\n\t\t\t\t\t\t\t\t   /* simply using numChannels only works for\n\t\t\t\t\t\t\t\t\t6 channels or less, else a channel\n\t\t\t\t\t\t\t\t\tconfiguration should be written */\n\t  WriteBits(hBitStream, 0, 1); /* original/copy */\n\t  WriteBits(hBitStream, 0, 1); /* home */\n\n\t  /* Variable ADTS header */\n\t  WriteBits(hBitStream, 0, 1); /* copyr. id. bit */\n\t  WriteBits(hBitStream, 0, 1); /* copyr. id. start */\n\t  WriteBits(hBitStream, *globUsedBits >> 3, 13);\n\t  WriteBits(hBitStream, 0x7FF, 11); /* buffer fullness (0x7FF for VBR) */\n\t  WriteBits(hBitStream, 0, 2); /* raw data blocks (0+1=1) */\n  }\n\n  *globUsedBits=0;\n\n  {\n\n    Word16 *sfbOffset[2];\n    TNS_INFO tnsInfo[2];\n    elementUsedBits = 0;\n\n    switch (elInfo.elType) {\n\n      case ID_SCE:      /* single channel */\n        sfbOffset[0] = psyOut->psyOutChannel[elInfo.ChannelIndex[0]].sfbOffsets;\n        tnsInfo[0] = psyOut->psyOutChannel[elInfo.ChannelIndex[0]].tnsInfo;\n\n        writeSingleChannelElement(elInfo.instanceTag,\n                                  sfbOffset[0],\n                                  &qcOut->qcChannel[elInfo.ChannelIndex[0]],\n                                  hBitStream,\n                                  tnsInfo[0]);\n        break;\n\n      case ID_CPE:     /* channel pair */\n        {\n          Word16 msDigest;\n          Word16 *msFlags = psyOut->psyOutElement.toolsInfo.msMask;\n          msDigest = psyOut->psyOutElement.toolsInfo.msDigest;\n          sfbOffset[0] =\n            psyOut->psyOutChannel[elInfo.ChannelIndex[0]].sfbOffsets;\n          sfbOffset[1] =\n            psyOut->psyOutChannel[elInfo.ChannelIndex[1]].sfbOffsets;\n\n          tnsInfo[0]=\n            psyOut->psyOutChannel[elInfo.ChannelIndex[0]].tnsInfo;\n          tnsInfo[1]=\n            psyOut->psyOutChannel[elInfo.ChannelIndex[1]].tnsInfo;\n          writeChannelPairElement(elInfo.instanceTag,\n                                  msDigest,\n                                  msFlags,\n                                  sfbOffset,\n                                  &qcOut->qcChannel[elInfo.ChannelIndex[0]],\n                                  hBitStream,\n                                  tnsInfo);\n        }\n        break;\n\n      default:\n        return(1);\n\n      }   /* switch */\n\n    elementUsedBits = elementUsedBits - bitMarkUp;\n    bitMarkUp = GetBitsAvail(hBitStream);\n    frameBits = frameBits + elementUsedBits + bitMarkUp;\n\n  }\n\n  writeFillElement(NULL,\n                   qcOut->totFillBits,\n                   hBitStream);\n\n  WriteBits(hBitStream,ID_END,3);\n\n  /* byte alignement */\n  WriteBits(hBitStream,0, (8 - (hBitStream->cntBits & 7)) & 7);\n\n  *globUsedBits = *globUsedBits- bitMarkUp;\n  bitMarkUp = GetBitsAvail(hBitStream);\n  *globUsedBits = *globUsedBits + bitMarkUp;\n  frameBits = frameBits + *globUsedBits;\n\n\n  if (frameBits !=  (qcOut->totStaticBitsUsed+qcOut->totDynBitsUsed + qcOut->totAncBitsUsed +\n                     qcOut->totFillBits + qcOut->alignBits)) {\n    return(-1);\n  }\n  return(0);\n}\n"
  },
  {
    "path": "jni/src/block_switch.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tblock_switch.c\n\n\tContent:\tBlock switching functions\n\n*******************************************************************************/\n\n#include \"typedef.h\"\n#include \"basic_op.h\"\n#include \"oper_32b.h\"\n#include \"psy_const.h\"\n#include \"block_switch.h\"\n\n\n#define ENERGY_SHIFT (8 - 1)\n\n/**************** internal function prototypes ***********/\nstatic Word16\nIIRFilter(const Word16 in, const Word32 coeff[], Word32 states[]);\n\nstatic Word32\nSrchMaxWithIndex(const Word32 *in, Word16 *index, Word16 n);\n\n\nWord32\nCalcWindowEnergy(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,\n                 Word16 *timeSignal,\n                 Word16 chIncrement,\n                 Word16 windowLen);\n\n\n\n/****************** Constants *****************************/\n\n\n/*\n  IIR high pass coeffs\n*/\nWord32 hiPassCoeff[BLOCK_SWITCHING_IIR_LEN] = {\n  0xbec8b439, 0x609d4952  /* -0.5095f, 0.7548f */\n};\n\nstatic const Word32 accWindowNrgFac = 0x26666666;                   /* factor for accumulating filtered window energies 0.3 */\nstatic const Word32 oneMinusAccWindowNrgFac = 0x5999999a;\t\t\t/* 0.7 */\nstatic const Word32 invAttackRatioHighBr = 0x0ccccccd;              /* inverted lower ratio limit for attacks 0.1*/\nstatic const Word32 invAttackRatioLowBr =  0x072b020c;              /* 0.056 */\nstatic const Word32 minAttackNrg = 0x00001e84;                      /* minimum energy for attacks 1e+6 */\n\n\n/****************** Routines ****************************/\n\n\n/*****************************************************************************\n*\n* function name: InitBlockSwitching\n* description:  init Block Switching parameter.\n* returns:      TRUE if success\n*\n**********************************************************************************/\nWord16 InitBlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,\n                          const Word32 bitRate, const Word16 nChannels)\n{\n  /* select attackRatio */\n\n  if ((sub(nChannels,1)==0 && L_sub(bitRate, 24000) > 0) ||\n      (sub(nChannels,1)>0 && bitRate > (nChannels * 16000))) {\n    blockSwitchingControl->invAttackRatio = invAttackRatioHighBr;\n  }\n  else  {\n    blockSwitchingControl->invAttackRatio = invAttackRatioLowBr;\n  }\n\n  return(TRUE);\n}\n\nstatic Word16 suggestedGroupingTable[TRANS_FAC][MAX_NO_OF_GROUPS] = {\n  /* Attack in Window 0 */ {1,  3,  3,  1},\n  /* Attack in Window 1 */ {1,  1,  3,  3},\n  /* Attack in Window 2 */ {2,  1,  3,  2},\n  /* Attack in Window 3 */ {3,  1,  3,  1},\n  /* Attack in Window 4 */ {3,  1,  1,  3},\n  /* Attack in Window 5 */ {3,  2,  1,  2},\n  /* Attack in Window 6 */ {3,  3,  1,  1},\n  /* Attack in Window 7 */ {3,  3,  1,  1}\n};\n\n/*****************************************************************************\n*\n* function name: BlockSwitching\n* description:  detect this frame whether there is an attack\n* returns:      TRUE if success\n*\n**********************************************************************************/\nWord16 BlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,\n                      Word16 *timeSignal,\n\t\t\t\t\t  Word32 sampleRate,\n                      Word16 chIncrement)\n{\n  Word32 i, w;\n  Word32 enM1, enMax;\n\n  /* Reset grouping info */\n  for (i=0; i<TRANS_FAC; i++) {\n    blockSwitchingControl->groupLen[i] = 0;\n  }\n\n\n  /* Search for position and amplitude of attack in last frame (1 windows delay) */\n  blockSwitchingControl->maxWindowNrg = SrchMaxWithIndex( &blockSwitchingControl->windowNrg[0][BLOCK_SWITCH_WINDOWS-1],\n                                                          &blockSwitchingControl->attackIndex,\n                                                          BLOCK_SWITCH_WINDOWS);\n\n  blockSwitchingControl->attackIndex = blockSwitchingControl->lastAttackIndex;\n\n  /* Set grouping info */\n  blockSwitchingControl->noOfGroups = MAX_NO_OF_GROUPS;\n\n  for (i=0; i<MAX_NO_OF_GROUPS; i++) {\n    blockSwitchingControl->groupLen[i] = suggestedGroupingTable[blockSwitchingControl->attackIndex][i];\n  }\n\n  /* if the samplerate is less than 16000, it should be all the short block, avoid pre&post echo */\n  if(sampleRate >= 16000) {\n\t  /* Save current window energy as last window energy */\n\t  for (w=0; w<BLOCK_SWITCH_WINDOWS; w++) {\n\t\t  blockSwitchingControl->windowNrg[0][w] = blockSwitchingControl->windowNrg[1][w];\n\t\t  blockSwitchingControl->windowNrgF[0][w] = blockSwitchingControl->windowNrgF[1][w];\n\t  }\n\n\n\t  /* Calculate unfiltered and filtered energies in subwindows and combine to segments */\n\t  CalcWindowEnergy(blockSwitchingControl, timeSignal, chIncrement, BLOCK_SWITCH_WINDOW_LEN);\n\n\t  /* reset attack */\n\t  blockSwitchingControl->attack = FALSE;\n\n\t  enMax = 0;\n\t  enM1 = blockSwitchingControl->windowNrgF[0][BLOCK_SWITCH_WINDOWS-1];\n\n\t  for (w=0; w<BLOCK_SWITCH_WINDOWS; w++) {\n\t\t  Word32 enM1_Tmp, accWindowNrg_Tmp, windowNrgF_Tmp;\n\t\t  Word16 enM1_Shf, accWindowNrg_Shf, windowNrgF_Shf;\n\n\t\t  accWindowNrg_Shf = norm_l(blockSwitchingControl->accWindowNrg);\n\t\t  enM1_Shf = norm_l(enM1);\n\t\t  windowNrgF_Shf = norm_l(blockSwitchingControl->windowNrgF[1][w]);\n\n\t\t  accWindowNrg_Tmp = blockSwitchingControl->accWindowNrg << accWindowNrg_Shf;\n\t\t  enM1_Tmp = enM1 << enM1_Shf;\n\t\t  windowNrgF_Tmp = blockSwitchingControl->windowNrgF[1][w] << windowNrgF_Shf;\n\n\t\t  /* a sliding average of the previous energies */\n\t\t  blockSwitchingControl->accWindowNrg = (fixmul(oneMinusAccWindowNrgFac, accWindowNrg_Tmp) >> accWindowNrg_Shf) +\n\t\t\t  (fixmul(accWindowNrgFac, enM1_Tmp) >> enM1_Shf);\n\n\n\t\t  /* if the energy with the ratio is bigger than the average, and the attack and short block  */\n\t\t  if ((fixmul(windowNrgF_Tmp, blockSwitchingControl->invAttackRatio) >> windowNrgF_Shf) >\n\t\t\t  blockSwitchingControl->accWindowNrg ) {\n\t\t\t\t  blockSwitchingControl->attack = TRUE;\n\t\t\t\t  blockSwitchingControl->lastAttackIndex = w;\n\t\t  }\n\t\t  enM1 = blockSwitchingControl->windowNrgF[1][w];\n\t\t  enMax = max(enMax, enM1);\n\t  }\n\n\t  if (enMax < minAttackNrg) {\n\t\t  blockSwitchingControl->attack = FALSE;\n\t  }\n  }\n  else\n  {\n\t  blockSwitchingControl->attack = TRUE;\n  }\n\n  /* Check if attack spreads over frame border */\n  if ((!blockSwitchingControl->attack) && (blockSwitchingControl->lastattack)) {\n\n    if (blockSwitchingControl->attackIndex == TRANS_FAC-1) {\n      blockSwitchingControl->attack = TRUE;\n    }\n\n    blockSwitchingControl->lastattack = FALSE;\n  }\n  else {\n    blockSwitchingControl->lastattack = blockSwitchingControl->attack;\n  }\n\n  blockSwitchingControl->windowSequence =  blockSwitchingControl->nextwindowSequence;\n\n\n  if (blockSwitchingControl->attack) {\n    blockSwitchingControl->nextwindowSequence = SHORT_WINDOW;\n  }\n  else {\n    blockSwitchingControl->nextwindowSequence = LONG_WINDOW;\n  }\n\n  /* update short block group */\n  if (blockSwitchingControl->nextwindowSequence == SHORT_WINDOW) {\n\n    if (blockSwitchingControl->windowSequence== LONG_WINDOW) {\n      blockSwitchingControl->windowSequence = START_WINDOW;\n    }\n\n    if (blockSwitchingControl->windowSequence == STOP_WINDOW) {\n      blockSwitchingControl->windowSequence = SHORT_WINDOW;\n      blockSwitchingControl->noOfGroups = 3;\n      blockSwitchingControl->groupLen[0] = 3;\n      blockSwitchingControl->groupLen[1] = 3;\n      blockSwitchingControl->groupLen[2] = 2;\n    }\n  }\n\n  /* update block type */\n  if (blockSwitchingControl->nextwindowSequence == LONG_WINDOW) {\n\n    if (blockSwitchingControl->windowSequence == SHORT_WINDOW) {\n      blockSwitchingControl->nextwindowSequence = STOP_WINDOW;\n    }\n  }\n\n  return(TRUE);\n}\n\n\n/*****************************************************************************\n*\n* function name: SrchMaxWithIndex\n* description:  search for the biggest value in an array\n* returns:      the max value\n*\n**********************************************************************************/\nstatic Word32 SrchMaxWithIndex(const Word32 in[], Word16 *index, Word16 n)\n{\n  Word32 max;\n  Word32 i, idx;\n\n  /* Search maximum value in array and return index and value */\n  max = 0;\n  idx = 0;\n\n  for (i = 0; i < n; i++) {\n\n    if (in[i+1]  > max) {\n      max = in[i+1];\n      idx = i;\n    }\n  }\n  *index = idx;\n\n  return(max);\n}\n\n/*****************************************************************************\n*\n* function name: CalcWindowEnergy\n* description:  calculate the energy before iir-filter and after irr-filter\n* returns:      TRUE if success\n*\n**********************************************************************************/\n#ifndef ARMV5E\nWord32 CalcWindowEnergy(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,\n                        Word16 *timeSignal,\n                        Word16 chIncrement,\n                        Word16 windowLen)\n{\n  Word32 w, i, wOffset, tidx, ch;\n  Word32 accuUE, accuFE;\n  Word32 tempUnfiltered;\n  Word32 tempFiltered;\n  Word32 states0, states1;\n  Word32 Coeff0, Coeff1;\n\n\n  states0 = blockSwitchingControl->iirStates[0];\n  states1 = blockSwitchingControl->iirStates[1];\n  Coeff0 = hiPassCoeff[0];\n  Coeff1 = hiPassCoeff[1];\n  tidx = 0;\n  for (w=0; w < BLOCK_SWITCH_WINDOWS; w++) {\n\n    accuUE = 0;\n    accuFE = 0;\n\n    for(i=0; i<windowLen; i++) {\n\t  Word32 accu1, accu2, accu3;\n\t  Word32 out;\n\t  tempUnfiltered = timeSignal[tidx];\n      tidx = tidx + chIncrement;\n\n\t  accu1 = L_mpy_ls(Coeff1, tempUnfiltered);\n\t  accu2 = fixmul( Coeff0, states1 );\n\t  accu3 = accu1 - states0;\n\t  out = accu3 - accu2;\n\n\t  states0 = accu1;\n\t  states1 = out;\n\n      tempFiltered = extract_h(out);\n      accuUE += (tempUnfiltered * tempUnfiltered) >> ENERGY_SHIFT;\n      accuFE += (tempFiltered * tempFiltered) >> ENERGY_SHIFT;\n    }\n\n    blockSwitchingControl->windowNrg[1][w] = accuUE;\n    blockSwitchingControl->windowNrgF[1][w] = accuFE;\n\n  }\n\n  blockSwitchingControl->iirStates[0] = states0;\n  blockSwitchingControl->iirStates[1] = states1;\n\n  return(TRUE);\n}\n#endif\n\n/*****************************************************************************\n*\n* function name: IIRFilter\n* description:  calculate the iir-filter for an array\n* returns:      the result after iir-filter\n*\n**********************************************************************************/\nstatic Word16 IIRFilter(const Word16 in, const Word32 coeff[], Word32 states[])\n{\n  Word32 accu1, accu2, accu3;\n  Word32 out;\n\n  accu1 = L_mpy_ls(coeff[1], in);\n  accu3 = accu1 - states[0];\n  accu2 = fixmul( coeff[0], states[1] );\n  out = accu3 - accu2;\n\n  states[0] = accu1;\n  states[1] = out;\n\n  return round16(out);\n}\n\n\nstatic Word16 synchronizedBlockTypeTable[4][4] = {\n  /*                 LONG_WINDOW   START_WINDOW  SHORT_WINDOW  STOP_WINDOW */\n  /* LONG_WINDOW  */{LONG_WINDOW,  START_WINDOW, SHORT_WINDOW, STOP_WINDOW},\n  /* START_WINDOW */{START_WINDOW, START_WINDOW, SHORT_WINDOW, SHORT_WINDOW},\n  /* SHORT_WINDOW */{SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW},\n  /* STOP_WINDOW  */{STOP_WINDOW,  SHORT_WINDOW, SHORT_WINDOW, STOP_WINDOW}\n};\n\n\n/*****************************************************************************\n*\n* function name: SyncBlockSwitching\n* description:  update block type and group value\n* returns:      TRUE if success\n*\n**********************************************************************************/\nWord16 SyncBlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControlLeft,\n                          BLOCK_SWITCHING_CONTROL *blockSwitchingControlRight,\n                          const Word16 nChannels)\n{\n  Word16 i;\n  Word16 patchType = LONG_WINDOW;\n\n\n  if (nChannels == 1) { /* Mono */\n    if (blockSwitchingControlLeft->windowSequence != SHORT_WINDOW) {\n      blockSwitchingControlLeft->noOfGroups = 1;\n      blockSwitchingControlLeft->groupLen[0] = 1;\n\n      for (i=1; i<TRANS_FAC; i++) {\n        blockSwitchingControlLeft->groupLen[i] = 0;\n      }\n    }\n  }\n  else { /* Stereo common Window */\n    patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlLeft->windowSequence];\n    patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlRight->windowSequence];\n\n    /* Set synchronized Blocktype */\n    blockSwitchingControlLeft->windowSequence = patchType;\n    blockSwitchingControlRight->windowSequence = patchType;\n\n    /* Synchronize grouping info */\n    if(patchType != SHORT_WINDOW) { /* Long Blocks */\n      /* Set grouping info */\n      blockSwitchingControlLeft->noOfGroups = 1;\n      blockSwitchingControlRight->noOfGroups = 1;\n      blockSwitchingControlLeft->groupLen[0] = 1;\n      blockSwitchingControlRight->groupLen[0] = 1;\n\n      for (i=1; i<TRANS_FAC; i++) {\n        blockSwitchingControlLeft->groupLen[i] = 0;\n        blockSwitchingControlRight->groupLen[i] = 0;\n      }\n    }\n    else {\n\n      if (blockSwitchingControlLeft->maxWindowNrg > blockSwitchingControlRight->maxWindowNrg) {\n        /* Left Channel wins */\n        blockSwitchingControlRight->noOfGroups = blockSwitchingControlLeft->noOfGroups;\n        for (i=0; i<TRANS_FAC; i++) {\n          blockSwitchingControlRight->groupLen[i] = blockSwitchingControlLeft->groupLen[i];\n        }\n      }\n      else {\n        /* Right Channel wins */\n        blockSwitchingControlLeft->noOfGroups = blockSwitchingControlRight->noOfGroups;\n        for (i=0; i<TRANS_FAC; i++) {\n          blockSwitchingControlLeft->groupLen[i] = blockSwitchingControlRight->groupLen[i];\n        }\n      }\n    }\n  } /*endif Mono or Stereo */\n\n  return(TRUE);\n}\n"
  },
  {
    "path": "jni/src/channel_map.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tchannel_map.c\n\n\tContent:\tchannel mapping functions\n\n*******************************************************************************/\n\n#include \"channel_map.h\"\n#include \"bitenc.h\"\n#include \"psy_const.h\"\n#include \"qc_data.h\"\n\nstatic const Word16 maxChannelBits = MAXBITS_COEF;\n\nstatic Word16 initElement(ELEMENT_INFO* elInfo, ELEMENT_TYPE elType)\n{\n  Word16 error=0;\n\n  elInfo->elType=elType;\n\n  switch(elInfo->elType) {\n\n    case ID_SCE:\n      elInfo->nChannelsInEl=1;\n\n      elInfo->ChannelIndex[0]=0;\n\n      elInfo->instanceTag=0;\n      break;\n\n    case ID_CPE:\n\n      elInfo->nChannelsInEl=2;\n\n      elInfo->ChannelIndex[0]=0;\n      elInfo->ChannelIndex[1]=1;\n\n      elInfo->instanceTag=0;\n      break;\n\n    default:\n      error=1;\n  }\n\n  return error;\n}\n\n\nWord16 InitElementInfo (Word16 nChannels, ELEMENT_INFO* elInfo)\n{\n  Word16 error;\n  error = 0;\n\n  switch(nChannels) {\n\n    case 1:\n      initElement(elInfo, ID_SCE);\n      break;\n\n    case 2:\n      initElement(elInfo, ID_CPE);\n      break;\n\n    default:\n      error=4;\n  }\n\n  return error;\n}\n\n\nWord16 InitElementBits(ELEMENT_BITS *elementBits,\n                       ELEMENT_INFO elInfo,\n                       Word32 bitrateTot,\n                       Word16 averageBitsTot,\n                       Word16 staticBitsTot)\n{\n  Word16 error;\n  error = 0;\n\n   switch(elInfo.nChannelsInEl) {\n    case 1:\n      elementBits->chBitrate = bitrateTot;\n      elementBits->averageBits = averageBitsTot - staticBitsTot;\n      elementBits->maxBits = maxChannelBits;\n\n      elementBits->maxBitResBits = maxChannelBits - averageBitsTot;\n      elementBits->maxBitResBits = elementBits->maxBitResBits - (elementBits->maxBitResBits & 7);\n      elementBits->bitResLevel = elementBits->maxBitResBits;\n      elementBits->relativeBits  = 0x4000; /* 1.0f/2 */\n      break;\n\n    case 2:\n      elementBits->chBitrate   = bitrateTot >> 1;\n      elementBits->averageBits = averageBitsTot - staticBitsTot;\n      elementBits->maxBits     = maxChannelBits << 1;\n\n      elementBits->maxBitResBits = (maxChannelBits << 1) - averageBitsTot;\n      elementBits->maxBitResBits = elementBits->maxBitResBits - (elementBits->maxBitResBits & 7);\n      elementBits->bitResLevel = elementBits->maxBitResBits;\n      elementBits->relativeBits = 0x4000; /* 1.0f/2 */\n      break;\n\n    default:\n      error = 1;\n  }\n  return error;\n}\n"
  },
  {
    "path": "jni/src/cmnMemory.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tcmnMemory.c\n\n\tContent:\tsample code for memory operator implementation\n\n*******************************************************************************/\n#include \"cmnMemory.h\"\n\n#include <stdlib.h>\n#include <string.h>\n\n//VO_MEM_OPERATOR\t\tg_memOP;\n\nVO_U32 cmnMemAlloc (VO_S32 uID,  VO_MEM_INFO * pMemInfo)\n{\n\tif (!pMemInfo)\n\t\treturn VO_ERR_INVALID_ARG;\n\n\tpMemInfo->VBuffer = malloc (pMemInfo->Size);\n\treturn 0;\n}\n\nVO_U32 cmnMemFree (VO_S32 uID, VO_PTR pMem)\n{\n\tfree (pMem);\n\treturn 0;\n}\n\nVO_U32\tcmnMemSet (VO_S32 uID, VO_PTR pBuff, VO_U8 uValue, VO_U32 uSize)\n{\n\tmemset (pBuff, uValue, uSize);\n\treturn 0;\n}\n\nVO_U32\tcmnMemCopy (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize)\n{\n\tmemcpy (pDest, pSource, uSize);\n\treturn 0;\n}\n\nVO_U32\tcmnMemCheck (VO_S32 uID, VO_PTR pBuffer, VO_U32 uSize)\n{\n\treturn 0;\n}\n\nVO_S32 cmnMemCompare (VO_S32 uID, VO_PTR pBuffer1, VO_PTR pBuffer2, VO_U32 uSize)\n{\n\treturn memcmp(pBuffer1, pBuffer2, uSize);\n}\n\nVO_U32\tcmnMemMove (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize)\n{\n\tmemmove (pDest, pSource, uSize);\n\treturn 0;\n}\n\n"
  },
  {
    "path": "jni/src/dyn_bits.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tdyn_bits.c\n\n\tContent:\tNoiseless coder module functions\n\n*******************************************************************************/\n\n#include \"aac_rom.h\"\n#include \"dyn_bits.h\"\n#include \"bit_cnt.h\"\n#include \"psy_const.h\"\n\n\n/*****************************************************************************\n*\n* function name: buildBitLookUp\n* description:  count bits using all possible tables\n*\n*****************************************************************************/\nstatic void\nbuildBitLookUp(const Word16 *quantSpectrum,\n               const Word16 maxSfb,\n               const Word16 *sfbOffset,\n               const UWord16 *sfbMax,\n               Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],\n               SECTION_INFO * sectionInfo)\n{\n  Word32 i;\n\n  for (i=0; i<maxSfb; i++) {\n    Word16 sfbWidth, maxVal;\n\n    sectionInfo[i].sfbCnt = 1;\n    sectionInfo[i].sfbStart = i;\n    sectionInfo[i].sectionBits = INVALID_BITCOUNT;\n    sectionInfo[i].codeBook = -1;\n    sfbWidth = sfbOffset[i + 1] - sfbOffset[i];\n    maxVal = sfbMax[i];\n    bitCount(quantSpectrum + sfbOffset[i], sfbWidth, maxVal, bitLookUp[i]);\n  }\n}\n\n\n/*****************************************************************************\n*\n* function name: findBestBook\n* description:  essential helper functions\n*\n*****************************************************************************/\nstatic Word16\nfindBestBook(const Word16 *bc, Word16 *book)\n{\n  Word32 minBits, j;\n  minBits = INVALID_BITCOUNT;\n\n  for (j=0; j<=CODE_BOOK_ESC_NDX; j++) {\n\n    if (bc[j] < minBits) {\n      minBits = bc[j];\n      *book = j;\n    }\n  }\n  return extract_l(minBits);\n}\n\nstatic Word16\nfindMinMergeBits(const Word16 *bc1, const Word16 *bc2)\n{\n  Word32 minBits, j, sum;\n  minBits = INVALID_BITCOUNT;\n\n  for (j=0; j<=CODE_BOOK_ESC_NDX; j++) {\n    sum = bc1[j] + bc2[j];\n    if (sum < minBits) {\n      minBits = sum;\n    }\n  }\n  return extract_l(minBits);\n}\n\nstatic void\nmergeBitLookUp(Word16 *bc1, const Word16 *bc2)\n{\n  Word32 j;\n\n  for (j=0; j<=CODE_BOOK_ESC_NDX; j++) {\n    bc1[j] = min(bc1[j] + bc2[j], INVALID_BITCOUNT);\n  }\n}\n\nstatic Word16\nfindMaxMerge(const Word16 mergeGainLookUp[MAX_SFB_LONG],\n             const SECTION_INFO *sectionInfo,\n             const Word16 maxSfb, Word16 *maxNdx)\n{\n  Word32 i, maxMergeGain;\n  maxMergeGain = 0;\n\n  for (i=0; i+sectionInfo[i].sfbCnt < maxSfb; i += sectionInfo[i].sfbCnt) {\n\n    if (mergeGainLookUp[i] > maxMergeGain) {\n      maxMergeGain = mergeGainLookUp[i];\n      *maxNdx = i;\n    }\n  }\n  return extract_l(maxMergeGain);\n}\n\n\n\nstatic Word16\nCalcMergeGain(const SECTION_INFO *sectionInfo,\n              Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],\n              const Word16 *sideInfoTab,\n              const Word16 ndx1,\n              const Word16 ndx2)\n{\n  Word32 SplitBits;\n  Word32 MergeBits;\n  Word32 MergeGain;\n\n  /*\n    Bit amount for splitted sections\n  */\n  SplitBits = sectionInfo[ndx1].sectionBits + sectionInfo[ndx2].sectionBits;\n\n  MergeBits = sideInfoTab[sectionInfo[ndx1].sfbCnt + sectionInfo[ndx2].sfbCnt] +\n                  findMinMergeBits(bitLookUp[ndx1], bitLookUp[ndx2]);\n  MergeGain = (SplitBits - MergeBits);\n\n  return extract_l(MergeGain);\n}\n\n/*\n  sectioning Stage 0:find minimum codbooks\n*/\n\nstatic void\ngmStage0(SECTION_INFO * sectionInfo,\n         Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],\n         const Word16 maxSfb)\n{\n  Word32 i;\n\n  for (i=0; i<maxSfb; i++) {\n    /* Side-Info bits will be calculated in Stage 1!  */\n\n    if (sectionInfo[i].sectionBits == INVALID_BITCOUNT) {\n      sectionInfo[i].sectionBits = findBestBook(bitLookUp[i], &(sectionInfo[i].codeBook));\n    }\n  }\n}\n\n/*\n  sectioning Stage 1:merge all connected regions with the same code book and\n  calculate side info\n*/\n\nstatic void\ngmStage1(SECTION_INFO * sectionInfo,\n         Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],\n         const Word16 maxSfb,\n         const Word16 *sideInfoTab)\n{\n  SECTION_INFO * sectionInfo_s;\n  SECTION_INFO * sectionInfo_e;\n  Word32 mergeStart, mergeEnd;\n  mergeStart = 0;\n\n  do {\n\n    sectionInfo_s = sectionInfo + mergeStart;\n\tfor (mergeEnd=mergeStart+1; mergeEnd<maxSfb; mergeEnd++) {\n      sectionInfo_e = sectionInfo + mergeEnd;\n      if (sectionInfo_s->codeBook != sectionInfo_e->codeBook)\n        break;\n      sectionInfo_s->sfbCnt += 1;\n      sectionInfo_s->sectionBits += sectionInfo_e->sectionBits;\n\n      mergeBitLookUp(bitLookUp[mergeStart], bitLookUp[mergeEnd]);\n    }\n\n    sectionInfo_s->sectionBits += sideInfoTab[sectionInfo_s->sfbCnt];\n    sectionInfo[mergeEnd - 1].sfbStart = sectionInfo_s->sfbStart;      /* speed up prev search */\n\n    mergeStart = mergeEnd;\n\n\n  } while (mergeStart - maxSfb < 0);\n}\n\n/*\n  sectioning Stage 2:greedy merge algorithm, merge connected sections with\n  maximum bit gain until no more gain is possible\n*/\nstatic void\ngmStage2(SECTION_INFO *sectionInfo,\n         Word16 mergeGainLookUp[MAX_SFB_LONG],\n         Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],\n         const Word16 maxSfb,\n         const Word16 *sideInfoTab)\n{\n  Word16 i;\n\n  for (i=0; i+sectionInfo[i].sfbCnt<maxSfb; i+=sectionInfo[i].sfbCnt) {\n    mergeGainLookUp[i] = CalcMergeGain(sectionInfo,\n                                       bitLookUp,\n                                       sideInfoTab,\n                                       i,\n                                       (i + sectionInfo[i].sfbCnt));\n  }\n\n  while (TRUE) {\n    Word16 maxMergeGain, maxNdx, maxNdxNext, maxNdxLast;\n\n    maxMergeGain = findMaxMerge(mergeGainLookUp, sectionInfo, maxSfb, &maxNdx);\n\n\n    if (maxMergeGain <= 0)\n      break;\n\n\n    maxNdxNext = maxNdx + sectionInfo[maxNdx].sfbCnt;\n\n    sectionInfo[maxNdx].sfbCnt = sectionInfo[maxNdx].sfbCnt + sectionInfo[maxNdxNext].sfbCnt;\n    sectionInfo[maxNdx].sectionBits = sectionInfo[maxNdx].sectionBits +\n                                          (sectionInfo[maxNdxNext].sectionBits - maxMergeGain);\n\n\n    mergeBitLookUp(bitLookUp[maxNdx], bitLookUp[maxNdxNext]);\n\n\n    if (maxNdx != 0) {\n      maxNdxLast = sectionInfo[maxNdx - 1].sfbStart;\n      mergeGainLookUp[maxNdxLast] = CalcMergeGain(sectionInfo,\n                                                  bitLookUp,\n                                                  sideInfoTab,\n                                                  maxNdxLast,\n                                                  maxNdx);\n    }\n    maxNdxNext = maxNdx + sectionInfo[maxNdx].sfbCnt;\n\n    sectionInfo[maxNdxNext - 1].sfbStart = sectionInfo[maxNdx].sfbStart;\n\n\n    if (maxNdxNext - maxSfb < 0) {\n      mergeGainLookUp[maxNdx] = CalcMergeGain(sectionInfo,\n                                              bitLookUp,\n                                              sideInfoTab,\n                                              maxNdx,\n                                              maxNdxNext);\n    }\n  }\n}\n\n/*\n  count bits used by the noiseless coder\n*/\nstatic void\nnoiselessCounter(SECTION_DATA *sectionData,\n                 Word16 mergeGainLookUp[MAX_SFB_LONG],\n                 Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],\n                 const Word16 *quantSpectrum,\n                 const UWord16 *maxValueInSfb,\n                 const Word16 *sfbOffset,\n                 const Word32 blockType)\n{\n  Word32 grpNdx, i;\n  const Word16 *sideInfoTab = NULL;\n  SECTION_INFO *sectionInfo;\n\n  /*\n    use appropriate side info table\n  */\n  switch (blockType)\n  {\n    case LONG_WINDOW:\n    case START_WINDOW:\n    case STOP_WINDOW:\n      sideInfoTab = sideInfoTabLong;\n      break;\n    case SHORT_WINDOW:\n      sideInfoTab = sideInfoTabShort;\n      break;\n  }\n\n\n  sectionData->noOfSections = 0;\n  sectionData->huffmanBits = 0;\n  sectionData->sideInfoBits = 0;\n\n\n  if (sectionData->maxSfbPerGroup == 0)\n    return;\n\n  /*\n    loop trough groups\n  */\n  for (grpNdx=0; grpNdx<sectionData->sfbCnt; grpNdx+=sectionData->sfbPerGroup) {\n\n    sectionInfo = sectionData->sectionInfo + sectionData->noOfSections;\n\n    buildBitLookUp(quantSpectrum,\n                   sectionData->maxSfbPerGroup,\n                   sfbOffset + grpNdx,\n                   maxValueInSfb + grpNdx,\n                   bitLookUp,\n                   sectionInfo);\n\n    /*\n       0.Stage\n    */\n    gmStage0(sectionInfo, bitLookUp, sectionData->maxSfbPerGroup);\n\n    /*\n       1.Stage\n    */\n    gmStage1(sectionInfo, bitLookUp, sectionData->maxSfbPerGroup, sideInfoTab);\n\n\n    /*\n       2.Stage\n    */\n    gmStage2(sectionInfo,\n             mergeGainLookUp,\n             bitLookUp,\n             sectionData->maxSfbPerGroup,\n             sideInfoTab);\n\n\n    /*\n       compress output, calculate total huff and side bits\n    */\n    for (i=0; i<sectionData->maxSfbPerGroup; i+=sectionInfo[i].sfbCnt) {\n      findBestBook(bitLookUp[i], &(sectionInfo[i].codeBook));\n      sectionInfo[i].sfbStart = sectionInfo[i].sfbStart + grpNdx;\n\n      sectionData->huffmanBits = (sectionData->huffmanBits +\n                                     (sectionInfo[i].sectionBits - sideInfoTab[sectionInfo[i].sfbCnt]));\n      sectionData->sideInfoBits = (sectionData->sideInfoBits + sideInfoTab[sectionInfo[i].sfbCnt]);\n      sectionData->sectionInfo[sectionData->noOfSections] = sectionInfo[i];\n      sectionData->noOfSections = sectionData->noOfSections + 1;\n    }\n  }\n}\n\n\n/*******************************************************************************\n*\n* functionname: scfCount\n* returns     : ---\n* description : count bits used by scalefactors.\n*\n********************************************************************************/\nstatic void scfCount(const Word16 *scalefacGain,\n                     const UWord16 *maxValueInSfb,\n                     SECTION_DATA * sectionData)\n\n{\n  SECTION_INFO *psectionInfo;\n  SECTION_INFO *psectionInfom;\n\n  /* counter */\n  Word32 i = 0; /* section counter */\n  Word32 j = 0; /* sfb counter */\n  Word32 k = 0; /* current section auxiliary counter */\n  Word32 m = 0; /* other section auxiliary counter */\n  Word32 n = 0; /* other sfb auxiliary counter */\n\n  /* further variables */\n  Word32 lastValScf     = 0;\n  Word32 deltaScf       = 0;\n  Flag found            = 0;\n  Word32 scfSkipCounter = 0;\n\n\n  sectionData->scalefacBits = 0;\n\n\n  if (scalefacGain == NULL) {\n    return;\n  }\n\n  lastValScf = 0;\n  sectionData->firstScf = 0;\n\n  psectionInfo = sectionData->sectionInfo;\n  for (i=0; i<sectionData->noOfSections; i++) {\n\n    if (psectionInfo->codeBook != CODE_BOOK_ZERO_NO) {\n      sectionData->firstScf = psectionInfo->sfbStart;\n      lastValScf = scalefacGain[sectionData->firstScf];\n      break;\n    }\n\tpsectionInfo += 1;\n  }\n\n  psectionInfo = sectionData->sectionInfo;\n  for (i=0; i<sectionData->noOfSections; i++, psectionInfo += 1) {\n\n    if (psectionInfo->codeBook != CODE_BOOK_ZERO_NO\n        && psectionInfo->codeBook != CODE_BOOK_PNS_NO) {\n      for (j = psectionInfo->sfbStart;\n           j < (psectionInfo->sfbStart + psectionInfo->sfbCnt); j++) {\n        /* check if we can repeat the last value to save bits */\n\n        if (maxValueInSfb[j] == 0) {\n          found = 0;\n\n          if (scfSkipCounter == 0) {\n            /* end of section */\n\n            if (j - ((psectionInfo->sfbStart + psectionInfo->sfbCnt) - 1) == 0) {\n              found = 0;\n            }\n            else {\n              for (k = j + 1; k < psectionInfo->sfbStart + psectionInfo->sfbCnt; k++) {\n\n                if (maxValueInSfb[k] != 0) {\n                  int tmp = L_abs(scalefacGain[k] - lastValScf);\n\t\t\t\t  found = 1;\n\n                  if ( tmp < CODE_BOOK_SCF_LAV) {\n                    /* save bits */\n                    deltaScf = 0;\n                  }\n                  else {\n                    /* do not save bits */\n                    deltaScf = lastValScf - scalefacGain[j];\n                    lastValScf = scalefacGain[j];\n                    scfSkipCounter = 0;\n                  }\n                  break;\n                }\n                /* count scalefactor skip */\n                scfSkipCounter = scfSkipCounter + 1;\n              }\n            }\n\n\t\t\tpsectionInfom = psectionInfo + 1;\n            /* search for the next maxValueInSfb[] != 0 in all other sections */\n            for (m = i + 1; (m < sectionData->noOfSections) && (found == 0); m++) {\n\n              if ((psectionInfom->codeBook != CODE_BOOK_ZERO_NO) &&\n                  (psectionInfom->codeBook != CODE_BOOK_PNS_NO)) {\n                for (n = psectionInfom->sfbStart;\n                     n < (psectionInfom->sfbStart + psectionInfom->sfbCnt); n++) {\n\n                  if (maxValueInSfb[n] != 0) {\n                    found = 1;\n\n                    if ( (abs_s(scalefacGain[n] - lastValScf) < CODE_BOOK_SCF_LAV)) {\n                      deltaScf = 0;\n                    }\n                    else {\n                      deltaScf = (lastValScf - scalefacGain[j]);\n                      lastValScf = scalefacGain[j];\n                      scfSkipCounter = 0;\n                    }\n                    break;\n                  }\n                  /* count scalefactor skip */\n                  scfSkipCounter = scfSkipCounter + 1;\n                }\n              }\n\n\t\t\t  psectionInfom += 1;\n            }\n\n            if (found == 0) {\n              deltaScf = 0;\n              scfSkipCounter = 0;\n            }\n          }\n          else {\n            deltaScf = 0;\n            scfSkipCounter = scfSkipCounter - 1;\n          }\n        }\n        else {\n          deltaScf = lastValScf - scalefacGain[j];\n          lastValScf = scalefacGain[j];\n        }\n        sectionData->scalefacBits += bitCountScalefactorDelta(deltaScf);\n      }\n    }\n  }\n}\n\n\ntypedef Word16 (*lookUpTable)[CODE_BOOK_ESC_NDX + 1];\n\n\nWord16\ndynBitCount(const Word16  *quantSpectrum,\n            const UWord16 *maxValueInSfb,\n            const Word16  *scalefac,\n            const Word16   blockType,\n            const Word16   sfbCnt,\n            const Word16   maxSfbPerGroup,\n            const Word16   sfbPerGroup,\n            const Word16  *sfbOffset,\n            SECTION_DATA  *sectionData)\n{\n  sectionData->blockType      = blockType;\n  sectionData->sfbCnt         = sfbCnt;\n  sectionData->sfbPerGroup    = sfbPerGroup;\n  if(sfbPerGroup)\n\tsectionData->noOfGroups   = sfbCnt/sfbPerGroup;\n  else\n\tsectionData->noOfGroups   = 0x7fff;\n  sectionData->maxSfbPerGroup = maxSfbPerGroup;\n\n  noiselessCounter(sectionData,\n                   sectionData->mergeGainLookUp,\n                   (lookUpTable)sectionData->bitLookUp,\n                   quantSpectrum,\n                   maxValueInSfb,\n                   sfbOffset,\n                   blockType);\n\n  scfCount(scalefac,\n           maxValueInSfb,\n           sectionData);\n\n\n  return (sectionData->huffmanBits + sectionData->sideInfoBits +\n\t      sectionData->scalefacBits);\n}\n\n"
  },
  {
    "path": "jni/src/grp_data.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tgrp_data.c\n\n\tContent:\tShort block grouping function\n\n*******************************************************************************/\n\n#include \"basic_op.h\"\n#include \"psy_const.h\"\n#include \"interface.h\"\n#include \"grp_data.h\"\n\n/*****************************************************************************\n*\n* function name: groupShortData\n* description:  group short data for next quantization and coding\n*\n**********************************************************************************/\nvoid\ngroupShortData(Word32        *mdctSpectrum,\n               Word32        *tmpSpectrum,\n               SFB_THRESHOLD *sfbThreshold,\n               SFB_ENERGY    *sfbEnergy,\n               SFB_ENERGY    *sfbEnergyMS,\n               SFB_ENERGY    *sfbSpreadedEnergy,\n               const Word16   sfbCnt,\n               const Word16  *sfbOffset,\n               const Word16  *sfbMinSnr,\n               Word16        *groupedSfbOffset,\n               Word16        *maxSfbPerGroup,\n               Word16        *groupedSfbMinSnr,\n               const Word16   noOfGroups,\n               const Word16  *groupLen)\n{\n  Word32 i, j;\n  Word32 line;\n  Word32 sfb;\n  Word32 grp;\n  Word32 wnd;\n  Word32 offset;\n  Word32 highestSfb;\n\n  /* for short: regroup and  */\n  /* cumulate energies und thresholds group-wise . */\n\n  /* calculate sfbCnt */\n  highestSfb = 0;\n  for (wnd=0; wnd<TRANS_FAC; wnd++) {\n    for (sfb=sfbCnt - 1; sfb>=highestSfb; sfb--) {\n      for (line=(sfbOffset[sfb + 1] - 1); line>=sfbOffset[sfb]; line--) {\n\n        if (mdctSpectrum[wnd*FRAME_LEN_SHORT+line] != 0) break;\n      }\n\n      if (line >= sfbOffset[sfb]) break;\n    }\n    highestSfb = max(highestSfb, sfb);\n  }\n\n  if (highestSfb < 0) {\n    highestSfb = 0;\n  }\n  *maxSfbPerGroup = highestSfb + 1;\n\n  /* calculate sfbOffset */\n  i = 0;\n  offset = 0;\n  for (grp = 0; grp < noOfGroups; grp++) {\n    for (sfb = 0; sfb < sfbCnt; sfb++) {\n      groupedSfbOffset[i] = offset + sfbOffset[sfb] * groupLen[grp];\n      i += 1;\n    }\n    offset += groupLen[grp] * FRAME_LEN_SHORT;\n  }\n  groupedSfbOffset[i] = FRAME_LEN_LONG;\n  i += 1;\n\n  /* calculate minSnr */\n  i = 0;\n  offset = 0;\n  for (grp = 0; grp < noOfGroups; grp++) {\n    for (sfb = 0; sfb < sfbCnt; sfb++) {\n      groupedSfbMinSnr[i] = sfbMinSnr[sfb];\n      i += 1;\n    }\n    offset += groupLen[grp] * FRAME_LEN_SHORT;\n  }\n\n\n  /* sum up sfbThresholds */\n  wnd = 0;\n  i = 0;\n  for (grp = 0; grp < noOfGroups; grp++) {\n    for (sfb = 0; sfb < sfbCnt; sfb++) {\n      Word32 thresh = sfbThreshold->sfbShort[wnd][sfb];\n      for (j=1; j<groupLen[grp]; j++) {\n        thresh = L_add(thresh, sfbThreshold->sfbShort[wnd+j][sfb]);\n      }\n      sfbThreshold->sfbLong[i] = thresh;\n      i += 1;\n    }\n    wnd += groupLen[grp];\n  }\n\n  /* sum up sfbEnergies left/right */\n  wnd = 0;\n  i = 0;\n  for (grp = 0; grp < noOfGroups; grp++) {\n    for (sfb = 0; sfb < sfbCnt; sfb++) {\n      Word32 energy = sfbEnergy->sfbShort[wnd][sfb];\n      for (j=1; j<groupLen[grp]; j++) {\n        energy = L_add(energy, sfbEnergy->sfbShort[wnd+j][sfb]);\n      }\n      sfbEnergy->sfbLong[i] = energy;\n      i += 1;\n    }\n    wnd += groupLen[grp];\n  }\n\n  /* sum up sfbEnergies mid/side */\n  wnd = 0;\n  i = 0;\n  for (grp = 0; grp < noOfGroups; grp++) {\n    for (sfb = 0; sfb < sfbCnt; sfb++) {\n      Word32 energy = sfbEnergyMS->sfbShort[wnd][sfb];\n      for (j=1; j<groupLen[grp]; j++) {\n        energy = L_add(energy, sfbEnergyMS->sfbShort[wnd+j][sfb]);\n      }\n      sfbEnergyMS->sfbLong[i] = energy;\n      i += 1;\n    }\n    wnd += groupLen[grp];\n  }\n\n  /* sum up sfbSpreadedEnergies */\n  wnd = 0;\n  i = 0;\n  for (grp = 0; grp < noOfGroups; grp++) {\n    for (sfb = 0; sfb < sfbCnt; sfb++) {\n      Word32 energy = sfbSpreadedEnergy->sfbShort[wnd][sfb];\n      for (j=1; j<groupLen[grp]; j++) {\n        energy = L_add(energy, sfbSpreadedEnergy->sfbShort[wnd+j][sfb]);\n      }\n      sfbSpreadedEnergy->sfbLong[i] = energy;\n      i += 1;\n    }\n    wnd += groupLen[grp];\n  }\n\n  /* re-group spectrum */\n  wnd = 0;\n  i = 0;\n  for (grp = 0; grp < noOfGroups; grp++) {\n    for (sfb = 0; sfb < sfbCnt; sfb++) {\n      for (j = 0; j < groupLen[grp]; j++) {\n        Word16 lineOffset = FRAME_LEN_SHORT * (wnd + j);\n        for (line = lineOffset + sfbOffset[sfb]; line < lineOffset + sfbOffset[sfb+1]; line++) {\n          tmpSpectrum[i] = mdctSpectrum[line];\n          i = i + 1;\n        }\n      }\n    }\n    wnd += groupLen[grp];\n  }\n\n  for(i=0;i<FRAME_LEN_LONG;i+=4) {\n    mdctSpectrum[i] = tmpSpectrum[i];\n\tmdctSpectrum[i+1] = tmpSpectrum[i+1];\n\tmdctSpectrum[i+2] = tmpSpectrum[i+2];\n\tmdctSpectrum[i+3] = tmpSpectrum[i+3];\n  }\n}\n\n"
  },
  {
    "path": "jni/src/interface.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tinterface.c\n\n\tContent:\tInterface psychoaccoustic/quantizer functions\n\n*******************************************************************************/\n\n#include \"basic_op.h\"\n#include \"oper_32b.h\"\n#include \"psy_const.h\"\n#include \"interface.h\"\n\n/*****************************************************************************\n*\n* function name: BuildInterface\n* description:  update output parameter\n*\n**********************************************************************************/\nvoid BuildInterface(Word32                  *groupedMdctSpectrum,\n                    const Word16             mdctScale,\n                    SFB_THRESHOLD           *groupedSfbThreshold,\n                    SFB_ENERGY              *groupedSfbEnergy,\n                    SFB_ENERGY              *groupedSfbSpreadedEnergy,\n                    const SFB_ENERGY_SUM     sfbEnergySumLR,\n                    const SFB_ENERGY_SUM     sfbEnergySumMS,\n                    const Word16             windowSequence,\n                    const Word16             windowShape,\n                    const Word16             groupedSfbCnt,\n                    const Word16            *groupedSfbOffset,\n                    const Word16             maxSfbPerGroup,\n                    const Word16            *groupedSfbMinSnr,\n                    const Word16             noOfGroups,\n                    const Word16            *groupLen,\n                    PSY_OUT_CHANNEL         *psyOutCh)\n{\n  Word32 j;\n  Word32 grp;\n  Word32 mask;\n  Word16 *tmpV;\n\n  /*\n  copy values to psyOut\n  */\n  psyOutCh->maxSfbPerGroup    = maxSfbPerGroup;\n  psyOutCh->sfbCnt            = groupedSfbCnt;\n  if(noOfGroups)\n\tpsyOutCh->sfbPerGroup     = groupedSfbCnt/ noOfGroups;\n  else\n\tpsyOutCh->sfbPerGroup     = 0x7fff;\n  psyOutCh->windowSequence    = windowSequence;\n  psyOutCh->windowShape       = windowShape;\n  psyOutCh->mdctScale         = mdctScale;\n  psyOutCh->mdctSpectrum      = groupedMdctSpectrum;\n  psyOutCh->sfbEnergy         = groupedSfbEnergy->sfbLong;\n  psyOutCh->sfbThreshold      = groupedSfbThreshold->sfbLong;\n  psyOutCh->sfbSpreadedEnergy = groupedSfbSpreadedEnergy->sfbLong;\n\n  tmpV = psyOutCh->sfbOffsets;\n  for(j=0; j<groupedSfbCnt + 1; j++) {\n      *tmpV++ = groupedSfbOffset[j];\n  }\n\n  tmpV = psyOutCh->sfbMinSnr;\n  for(j=0;j<groupedSfbCnt; j++) {\n\t  *tmpV++ =   groupedSfbMinSnr[j];\n  }\n\n  /* generate grouping mask */\n  mask = 0;\n  for (grp = 0; grp < noOfGroups; grp++) {\n    mask = mask << 1;\n    for (j=1; j<groupLen[grp]; j++) {\n      mask = mask << 1;\n      mask |= 1;\n    }\n  }\n  psyOutCh->groupingMask = mask;\n\n  if (windowSequence != SHORT_WINDOW) {\n    psyOutCh->sfbEnSumLR =  sfbEnergySumLR.sfbLong;\n    psyOutCh->sfbEnSumMS =  sfbEnergySumMS.sfbLong;\n  }\n  else {\n    Word32 i;\n    Word32 accuSumMS=0;\n    Word32 accuSumLR=0;\n    const Word32 *pSumMS = sfbEnergySumMS.sfbShort;\n    const Word32 *pSumLR = sfbEnergySumLR.sfbShort;\n\n    for (i=TRANS_FAC; i; i--) {\n      accuSumLR = L_add(accuSumLR, *pSumLR); pSumLR++;\n      accuSumMS = L_add(accuSumMS, *pSumMS); pSumMS++;\n    }\n    psyOutCh->sfbEnSumMS = accuSumMS;\n    psyOutCh->sfbEnSumLR = accuSumLR;\n  }\n}\n"
  },
  {
    "path": "jni/src/line_pe.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tline_pe.c\n\n\tContent:\tPerceptual entropie module functions\n\n*******************************************************************************/\n\n#include \"basic_op.h\"\n#include \"oper_32b.h\"\n#include \"typedef.h\"\n#include \"line_pe.h\"\n\n\nstatic const Word16  C1_I = 12;    /* log(8.0)/log(2) *4         */\nstatic const Word32  C2_I = 10830; /* log(2.5)/log(2) * 1024 * 4 * 2 */\nstatic const Word16  C3_I = 573;   /* (1-C2/C1) *1024            */\n\n\n/*****************************************************************************\n*\n* function name: prepareSfbPe\n* description:  constants that do not change during successive pe calculations\n*\n**********************************************************************************/\nvoid prepareSfbPe(PE_DATA *peData,\n                  PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],\n                  Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],\n                  Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],\n                  const Word16 nChannels,\n                  const Word16 peOffset)\n{\n  Word32 sfbGrp, sfb;\n  Word32 ch;\n\n  for(ch=0; ch<nChannels; ch++) {\n    PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];\n    PE_CHANNEL_DATA *peChanData=&peData->peChannelData[ch];\n    for(sfbGrp=0;sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup){\n      for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {\n\t    peChanData->sfbNLines4[sfbGrp+sfb] = sfbNRelevantLines[ch][sfbGrp+sfb];\n        sfbNRelevantLines[ch][sfbGrp+sfb] = sfbNRelevantLines[ch][sfbGrp+sfb] >> 2;\n\t    peChanData->sfbLdEnergy[sfbGrp+sfb] = logSfbEnergy[ch][sfbGrp+sfb];\n      }\n    }\n  }\n  peData->offset = peOffset;\n}\n\n\n/*****************************************************************************\n*\n* function name: calcSfbPe\n* description:  constPart is sfbPe without the threshold part n*ld(thr) or n*C3*ld(thr)\n*\n**********************************************************************************/\nvoid calcSfbPe(PE_DATA *peData,\n               PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],\n               const Word16 nChannels)\n{\n  Word32 ch;\n  Word32 sfbGrp, sfb;\n  Word32 nLines4;\n  Word32 ldThr, ldRatio;\n  Word32 pe, constPart, nActiveLines;\n\n  peData->pe = peData->offset;\n  peData->constPart = 0;\n  peData->nActiveLines = 0;\n  for(ch=0; ch<nChannels; ch++) {\n    PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];\n    PE_CHANNEL_DATA *peChanData = &peData->peChannelData[ch];\n    const Word32 *sfbEnergy = psyOutChan->sfbEnergy;\n    const Word32 *sfbThreshold = psyOutChan->sfbThreshold;\n\n    pe = 0;\n    constPart = 0;\n    nActiveLines = 0;\n\n    for(sfbGrp=0; sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup) {\n      for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {\n        Word32 nrg = sfbEnergy[sfbGrp+sfb];\n        Word32 thres = sfbThreshold[sfbGrp+sfb];\n        Word32 sfbLDEn = peChanData->sfbLdEnergy[sfbGrp+sfb];\n\n        if (nrg > thres) {\n          ldThr = iLog4(thres);\n\n          ldRatio = sfbLDEn - ldThr;\n\n          nLines4 = peChanData->sfbNLines4[sfbGrp+sfb];\n\n          /* sfbPe = nl*log2(en/thr)*/\n\t\t  if (ldRatio >= C1_I) {\n            peChanData->sfbPe[sfbGrp+sfb] = (nLines4*ldRatio + 8) >> 4;\n            peChanData->sfbConstPart[sfbGrp+sfb] = ((nLines4*sfbLDEn)) >> 4;\n          }\n          else {\n\t\t  /* sfbPe = nl*(c2 + c3*log2(en/thr))*/\n            peChanData->sfbPe[sfbGrp+sfb] = extract_l((L_mpy_wx(\n                    (C2_I + C3_I * ldRatio * 2) << 4, nLines4) + 4) >> 3);\n            peChanData->sfbConstPart[sfbGrp+sfb] = extract_l(( L_mpy_wx(\n                    (C2_I + C3_I * sfbLDEn * 2) << 4, nLines4) + 4) >> 3);\n            nLines4 = (nLines4 * C3_I + (1024<<1)) >> 10;\n          }\n          peChanData->sfbNActiveLines[sfbGrp+sfb] = nLines4 >> 2;\n        }\n        else {\n          peChanData->sfbPe[sfbGrp+sfb] = 0;\n          peChanData->sfbConstPart[sfbGrp+sfb] = 0;\n          peChanData->sfbNActiveLines[sfbGrp+sfb] = 0;\n        }\n        pe = pe + peChanData->sfbPe[sfbGrp+sfb];\n        constPart = constPart + peChanData->sfbConstPart[sfbGrp+sfb];\n        nActiveLines = nActiveLines + peChanData->sfbNActiveLines[sfbGrp+sfb];\n      }\n    }\n\n\tpeChanData->pe = saturate(pe);\n    peChanData->constPart = saturate(constPart);\n    peChanData->nActiveLines = saturate(nActiveLines);\n\n\n\tpe += peData->pe;\n\tpeData->pe = saturate(pe);\n    constPart += peData->constPart;\n\tpeData->constPart = saturate(constPart);\n    nActiveLines += peData->nActiveLines;\n\tpeData->nActiveLines = saturate(nActiveLines);\n  }\n}\n"
  },
  {
    "path": "jni/src/memalign.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n\n/*******************************************************************************\n\tFile:\t\tmem_align.c\n\n\tContent:\tMemory alloc alignments functions\n\n*******************************************************************************/\n\n\n#include\t\"memalign.h\"\n#ifdef _MSC_VER\n#include\t<stddef.h>\n#else\n#include\t<stdint.h>\n#endif\n\n/*****************************************************************************\n*\n* function name: mem_malloc\n* description:  malloc the alignments memory\n* returns:      the point of the memory\n*\n**********************************************************************************/\nvoid *\nmem_malloc(VO_MEM_OPERATOR *pMemop, unsigned int size, unsigned char alignment, unsigned int CodecID)\n{\n\tint ret;\n\tunsigned char *mem_ptr;\n\tVO_MEM_INFO MemInfo;\n\n\tif (!alignment) {\n\n\t\tMemInfo.Flag = 0;\n\t\tMemInfo.Size = size + 1;\n\t\tret = pMemop->Alloc(CodecID, &MemInfo);\n\t\tif(ret != 0)\n\t\t\treturn 0;\n\t\tmem_ptr = (unsigned char *)MemInfo.VBuffer;\n\n\t\tpMemop->Set(CodecID, mem_ptr, 0, size + 1);\n\n\t\t*mem_ptr = (unsigned char)1;\n\n\t\treturn ((void *)(mem_ptr+1));\n\t} else {\n\t\tunsigned char *tmp;\n\n\t\tMemInfo.Flag = 0;\n\t\tMemInfo.Size = size + alignment;\n\t\tret = pMemop->Alloc(CodecID, &MemInfo);\n\t\tif(ret != 0)\n\t\t\treturn 0;\n\n\t\ttmp = (unsigned char *)MemInfo.VBuffer;\n\n\t\tpMemop->Set(CodecID, tmp, 0, size + alignment);\n\n\t\tmem_ptr =\n\t\t\t(unsigned char *) ((intptr_t) (tmp + alignment - 1) &\n\t\t\t\t\t(~((intptr_t) (alignment - 1))));\n\n\t\tif (mem_ptr == tmp)\n\t\t\tmem_ptr += alignment;\n\n\t\t*(mem_ptr - 1) = (unsigned char) (mem_ptr - tmp);\n\n\t\treturn ((void *)mem_ptr);\n\t}\n\n\treturn(0);\n}\n\n\n/*****************************************************************************\n*\n* function name: mem_free\n* description:  free the memory\n*\n*******************************************************************************/\nvoid\nmem_free(VO_MEM_OPERATOR *pMemop, void *mem_ptr, unsigned int CodecID)\n{\n\n\tunsigned char *ptr;\n\n\tif (mem_ptr == 0)\n\t\treturn;\n\n\tptr = mem_ptr;\n\n\tptr -= *(ptr - 1);\n\n\tpMemop->Free(CodecID, ptr);\n}\n\n\n\n"
  },
  {
    "path": "jni/src/ms_stereo.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tms_stereo.c\n\n\tContent:\tMS stereo processing function\n\n*******************************************************************************/\n\n#include \"basic_op.h\"\n#include \"oper_32b.h\"\n#include \"psy_const.h\"\n#include \"ms_stereo.h\"\n\n\n/********************************************************************************\n*\n* function name: MsStereoProcessing\n* description:  detect use ms stereo or not\n*\t\t\t\tif ((min(thrLn, thrRn)*min(thrLn, thrRn))/(enMn*enSn))\n*\t\t\t\t>= ((thrLn *thrRn)/(enLn*enRn)) then ms stereo\n*\n**********************************************************************************/\nvoid MsStereoProcessing(Word32       *sfbEnergyLeft,\n                        Word32       *sfbEnergyRight,\n                        const Word32 *sfbEnergyMid,\n                        const Word32 *sfbEnergySide,\n                        Word32       *mdctSpectrumLeft,\n                        Word32       *mdctSpectrumRight,\n                        Word32       *sfbThresholdLeft,\n                        Word32       *sfbThresholdRight,\n                        Word32       *sfbSpreadedEnLeft,\n                        Word32       *sfbSpreadedEnRight,\n                        Word16       *msDigest,\n                        Word16       *msMask,\n                        const Word16  sfbCnt,\n                        const Word16  sfbPerGroup,\n                        const Word16  maxSfbPerGroup,\n                        const Word16 *sfbOffset) {\n  Word32 temp;\n  Word32 sfb,sfboffs, j;\n  Word32 msMaskTrueSomewhere = 0;\n  Word32 msMaskFalseSomewhere = 0;\n\n  for (sfb=0; sfb<sfbCnt; sfb+=sfbPerGroup) {\n    for (sfboffs=0;sfboffs<maxSfbPerGroup;sfboffs++) {\n\n      Word32 temp;\n      Word32 pnlr,pnms;\n      Word32 minThreshold;\n      Word32 thrL, thrR, nrgL, nrgR;\n      Word32 idx, shift;\n\n      idx = sfb + sfboffs;\n\n      thrL = sfbThresholdLeft[idx];\n      thrR = sfbThresholdRight[idx];\n      nrgL = sfbEnergyLeft[idx];\n      nrgR = sfbEnergyRight[idx];\n\n      minThreshold = min(thrL, thrR);\n\n      nrgL = max(nrgL,thrL) + 1;\n      shift = norm_l(nrgL);\n\t  nrgL = Div_32(thrL << shift, nrgL << shift);\n      nrgR = max(nrgR,thrR) + 1;\n      shift = norm_l(nrgR);\n\t  nrgR = Div_32(thrR << shift, nrgR << shift);\n\n\t  pnlr = fixmul(nrgL, nrgR);\n\n      nrgL = sfbEnergyMid[idx];\n      nrgR = sfbEnergySide[idx];\n\n      nrgL = max(nrgL,minThreshold) + 1;\n      shift = norm_l(nrgL);\n\t  nrgL = Div_32(minThreshold << shift, nrgL << shift);\n\n      nrgR = max(nrgR,minThreshold) + 1;\n      shift = norm_l(nrgR);\n\t  nrgR = Div_32(minThreshold << shift, nrgR << shift);\n\n      pnms = fixmul(nrgL, nrgR);\n\n      temp = (pnlr + 1) / ((pnms >> 8) + 1);\n\n      temp = pnms - pnlr;\n      if( temp > 0 ){\n\n        msMask[idx] = 1;\n        msMaskTrueSomewhere = 1;\n\n        for (j=sfbOffset[idx]; j<sfbOffset[idx+1]; j++) {\n          Word32 left, right;\n          left  = (mdctSpectrumLeft[j] >>  1);\n          right = (mdctSpectrumRight[j] >> 1);\n          mdctSpectrumLeft[j] =  left + right;\n          mdctSpectrumRight[j] =  left - right;\n        }\n\n        sfbThresholdLeft[idx] = minThreshold;\n        sfbThresholdRight[idx] = minThreshold;\n        sfbEnergyLeft[idx] = sfbEnergyMid[idx];\n        sfbEnergyRight[idx] = sfbEnergySide[idx];\n\n        sfbSpreadedEnRight[idx] = min(sfbSpreadedEnLeft[idx],sfbSpreadedEnRight[idx]) >> 1;\n        sfbSpreadedEnLeft[idx] = sfbSpreadedEnRight[idx];\n\n      }\n      else {\n        msMask[idx]  = 0;\n        msMaskFalseSomewhere = 1;\n      }\n    }\n    if ( msMaskTrueSomewhere ) {\n      if(msMaskFalseSomewhere ) {\n        *msDigest = SI_MS_MASK_SOME;\n      } else {\n        *msDigest = SI_MS_MASK_ALL;\n      }\n    } else {\n      *msDigest = SI_MS_MASK_NONE;\n    }\n  }\n\n}\n"
  },
  {
    "path": "jni/src/pre_echo_control.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tpre_echo_control.c\n\n\tContent:\tPre echo control functions\n\n*******************************************************************************/\n\n#include \"basic_op.h\"\n#include \"oper_32b.h\"\n\n#include \"oper_32b.h\"\n#include \"pre_echo_control.h\"\n\n\n/*****************************************************************************\n*\n* function name:InitPreEchoControl\n* description: init pre echo control parameter\n*\n*****************************************************************************/\nvoid InitPreEchoControl(Word32 *pbThresholdNm1,\n                        Word16  numPb,\n                        Word32 *pbThresholdQuiet)\n{\n  Word16 pb;\n\n  for(pb=0; pb<numPb; pb++) {\n    pbThresholdNm1[pb] = pbThresholdQuiet[pb];\n  }\n}\n\n/*****************************************************************************\n*\n* function name:PreEchoControl\n* description: update shreshold to avoid pre echo\n*\t\t\t   thr(n) = max(rpmin*thrq(n), min(thrq(n), rpelev*thrq1(n)))\n*\n*\n*****************************************************************************/\nvoid PreEchoControl(Word32 *pbThresholdNm1,\n                    Word16  numPb,\n                    Word32  maxAllowedIncreaseFactor,\n                    Word16  minRemainingThresholdFactor,\n                    Word32 *pbThreshold,\n                    Word16  mdctScale,\n                    Word16  mdctScalenm1)\n{\n  Word32 i;\n  Word32 tmpThreshold1, tmpThreshold2;\n  Word32 scaling;\n\n  /* maxAllowedIncreaseFactor is hard coded to 2 */\n  (void)maxAllowedIncreaseFactor;\n\n  scaling = ((mdctScale - mdctScalenm1) << 1);\n\n  if ( scaling > 0 ) {\n    for(i = 0; i < numPb; i++) {\n      tmpThreshold1 = pbThresholdNm1[i] >> (scaling-1);\n      tmpThreshold2 = L_mpy_ls(pbThreshold[i], minRemainingThresholdFactor);\n\n      /* copy thresholds to internal memory */\n      pbThresholdNm1[i] = pbThreshold[i];\n\n\n      if(pbThreshold[i] > tmpThreshold1) {\n        pbThreshold[i] = tmpThreshold1;\n      }\n\n      if(tmpThreshold2 > pbThreshold[i]) {\n        pbThreshold[i] = tmpThreshold2;\n      }\n\n    }\n  }\n  else {\n    scaling = -scaling;\n    for(i = 0; i < numPb; i++) {\n\n      tmpThreshold1 = pbThresholdNm1[i] << 1;\n      tmpThreshold2 = L_mpy_ls(pbThreshold[i], minRemainingThresholdFactor);\n\n      /* copy thresholds to internal memory */\n      pbThresholdNm1[i] = pbThreshold[i];\n\n\n      if(((pbThreshold[i] >> scaling) > tmpThreshold1)) {\n        pbThreshold[i] = tmpThreshold1 << scaling;\n      }\n\n      if(tmpThreshold2 > pbThreshold[i]) {\n        pbThreshold[i] = tmpThreshold2;\n      }\n\n    }\n  }\n}\n\n"
  },
  {
    "path": "jni/src/psy_configuration.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tpsy_configuration.c\n\n\tContent:\tPsychoaccoustic configuration functions\n\n*******************************************************************************/\n\n#include \"basic_op.h\"\n#include \"oper_32b.h\"\n#include \"psy_configuration.h\"\n#include \"adj_thr.h\"\n#include \"aac_rom.h\"\n\n\n\n#define BARC_SCALE\t100 /* integer barc values are scaled with 100 */\n#define LOG2_1000\t301 /* log2*1000 */\n#define PI2_1000\t1571 /* pi/2*1000*/\n#define ATAN_COEF1\t3560 /* 1000/0.280872f*/\n#define ATAN_COEF2\t281 /* 1000*0.280872f*/\n\n\ntypedef struct{\n  Word32 sampleRate;\n  const UWord8 *paramLong;\n  const UWord8 *paramShort;\n}SFB_INFO_TAB;\n\nstatic const Word16 ABS_LEV = 20;\nstatic const Word16 BARC_THR_QUIET[] = {15, 10,  7,  2,  0,  0,  0,  0,  0,  0,\n                                         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n                                         3,  5, 10, 20, 30};\n\n\n\nstatic const Word16 max_bark = 24; /* maximum bark-value */\nstatic const Word16 maskLow  = 30; /* in 1dB/bark */\nstatic const Word16 maskHigh = 15; /* in 1*dB/bark */\nstatic const Word16 c_ratio  = 0x0029; /* pow(10.0f, -(29.0f/10.0f)) */\n\nstatic const Word16 maskLowSprEnLong = 30;       /* in 1dB/bark */\nstatic const Word16 maskHighSprEnLong = 20;      /* in 1dB/bark */\nstatic const Word16 maskHighSprEnLongLowBr = 15; /* in 1dB/bark */\nstatic const Word16 maskLowSprEnShort = 20;      /* in 1dB/bark */\nstatic const Word16 maskHighSprEnShort = 15;     /* in 1dB/bark */\nstatic const Word16 c_minRemainingThresholdFactor = 0x0148;    /* 0.01 *(1 << 15)*/\nstatic const Word32 c_maxsnr = 0x66666666;\t\t /* upper limit is -1 dB */\nstatic const Word32 c_minsnr = 0x00624dd3;\t\t /* lower limit is -25 dB */\n\nstatic const Word32 c_maxClipEnergyLong = 0x77359400;  /* 2.0e9f*/\nstatic const Word32 c_maxClipEnergyShort = 0x01dcd650; /* 2.0e9f/(AACENC_TRANS_FAC*AACENC_TRANS_FAC)*/\n\n\nWord32 GetSRIndex(Word32 sampleRate)\n{\n    if (92017 <= sampleRate) return 0;\n    if (75132 <= sampleRate) return 1;\n    if (55426 <= sampleRate) return 2;\n    if (46009 <= sampleRate) return 3;\n    if (37566 <= sampleRate) return 4;\n    if (27713 <= sampleRate) return 5;\n    if (23004 <= sampleRate) return 6;\n    if (18783 <= sampleRate) return 7;\n    if (13856 <= sampleRate) return 8;\n    if (11502 <= sampleRate) return 9;\n    if (9391 <= sampleRate) return 10;\n\n    return 11;\n}\n\n\n/*********************************************************************************\n*\n* function name: atan_1000\n* description:  calculates 1000*atan(x/1000)\n*               based on atan approx for x > 0\n*\t\t\t\tatan(x) = x/((float)1.0f+(float)0.280872f*x*x)  if x < 1\n*\t\t\t\t\t\t= pi/2 - x/((float)0.280872f +x*x)\t    if x >= 1\n* return:       1000*atan(x/1000)\n*\n**********************************************************************************/\nstatic Word16 atan_1000(Word32 val)\n{\n  Word32 y;\n\n\n  if(L_sub(val, 1000) < 0) {\n    y = extract_l(((1000 * val) / (1000 + ((val * val) / ATAN_COEF1))));\n  }\n  else {\n    y = PI2_1000 - ((1000 * val) / (ATAN_COEF2 + ((val * val) / 1000)));\n  }\n\n  return extract_l(y);\n}\n\n\n/*****************************************************************************\n*\n* function name: BarcLineValue\n* description:  Calculates barc value for one frequency line\n* returns:      barc value of line * BARC_SCALE\n* input:        number of lines in transform, index of line to check, Fs\n* output:\n*\n*****************************************************************************/\nstatic Word16 BarcLineValue(Word16 noOfLines, Word16 fftLine, Word32 samplingFreq)\n{\n  Word32 center_freq, temp, bvalFFTLine;\n\n  /* center frequency of fft line */\n  center_freq = (fftLine * samplingFreq) / (noOfLines << 1);\n  temp =  atan_1000((center_freq << 2) / (3*10));\n  bvalFFTLine =\n    (26600 * atan_1000((center_freq*76) / 100) + 7*temp*temp) / (2*1000*1000 / BARC_SCALE);\n\n  return saturate(bvalFFTLine);\n}\n\n/*****************************************************************************\n*\n* function name: initThrQuiet\n* description:  init thredhold in quiet\n*\n*****************************************************************************/\nstatic void initThrQuiet(Word16  numPb,\n                         const Word16 *pbOffset,\n                         Word16 *pbBarcVal,\n                         Word32 *pbThresholdQuiet) {\n  Word16 i;\n  Word16 barcThrQuiet;\n\n  for(i=0; i<numPb; i++) {\n    Word16 bv1, bv2;\n\n\n    if (i>0)\n      bv1 = (pbBarcVal[i] + pbBarcVal[i-1]) >> 1;\n    else\n      bv1 = pbBarcVal[i] >> 1;\n\n\n    if (i < (numPb - 1))\n      bv2 = (pbBarcVal[i] + pbBarcVal[i+1]) >> 1;\n    else {\n      bv2 = pbBarcVal[i];\n    }\n\n    bv1 = min((bv1 / BARC_SCALE), max_bark);\n    bv2 = min((bv2 / BARC_SCALE), max_bark);\n\n    barcThrQuiet = min(BARC_THR_QUIET[bv1], BARC_THR_QUIET[bv2]);\n\n\n    /*\n      we calculate\n      pow(10.0f,(float)(barcThrQuiet - ABS_LEV)*0.1)*(float)ABS_LOW*(pbOffset[i+1] - pbOffset[i]);\n    */\n\n    pbThresholdQuiet[i] = pow2_xy((((barcThrQuiet - ABS_LEV) * 100) +\n                          LOG2_1000*(14+2*LOG_NORM_PCM)), LOG2_1000) * (pbOffset[i+1] - pbOffset[i]);\n  }\n}\n\n\n/*****************************************************************************\n*\n* function name: initSpreading\n* description:  init energy spreading parameter\n*\n*****************************************************************************/\nstatic void initSpreading(Word16  numPb,\n                          Word16 *pbBarcValue,\n                          Word16 *pbMaskLoFactor,\n                          Word16 *pbMaskHiFactor,\n                          Word16 *pbMaskLoFactorSprEn,\n                          Word16 *pbMaskHiFactorSprEn,\n                          const Word32 bitrate,\n                          const Word16 blockType)\n{\n  Word16 i;\n  Word16 maskLowSprEn, maskHighSprEn;\n\n\n  if (sub(blockType, SHORT_WINDOW) != 0) {\n    maskLowSprEn = maskLowSprEnLong;\n\n    if (bitrate > 22000)\n      maskHighSprEn = maskHighSprEnLong;\n    else\n      maskHighSprEn = maskHighSprEnLongLowBr;\n  }\n  else {\n    maskLowSprEn = maskLowSprEnShort;\n    maskHighSprEn = maskHighSprEnShort;\n  }\n\n  for(i=0; i<numPb; i++) {\n\n    if (i > 0) {\n      Word32 dbVal;\n      Word16 dbark = pbBarcValue[i] - pbBarcValue[i-1];\n\n      /*\n        we calulate pow(10.0f, -0.1*dbVal/BARC_SCALE)\n      */\n      dbVal = (maskHigh * dbark);\n      pbMaskHiFactor[i] = round16(pow2_xy(L_negate(dbVal), (Word32)LOG2_1000));             /* 0.301 log10(2) */\n\n      dbVal = (maskLow * dbark);\n      pbMaskLoFactor[i-1] = round16(pow2_xy(L_negate(dbVal),(Word32)LOG2_1000));\n\n\n      dbVal = (maskHighSprEn * dbark);\n      pbMaskHiFactorSprEn[i] =  round16(pow2_xy(L_negate(dbVal),(Word32)LOG2_1000));\n      dbVal = (maskLowSprEn * dbark);\n      pbMaskLoFactorSprEn[i-1] = round16(pow2_xy(L_negate(dbVal),(Word32)LOG2_1000));\n    }\n    else {\n      pbMaskHiFactor[i] = 0;\n      pbMaskLoFactor[numPb-1] = 0;\n\n      pbMaskHiFactorSprEn[i] = 0;\n      pbMaskLoFactorSprEn[numPb-1] = 0;\n    }\n  }\n\n}\n\n\n/*****************************************************************************\n*\n* function name: initBarcValues\n* description:  init bark value\n*\n*****************************************************************************/\nstatic void initBarcValues(Word16  numPb,\n                           const Word16 *pbOffset,\n                           Word16  numLines,\n                           Word32  samplingFrequency,\n                           Word16 *pbBval)\n{\n  Word16 i;\n  Word16 pbBval0, pbBval1;\n\n  pbBval0 = 0;\n\n  for(i=0; i<numPb; i++){\n    pbBval1 = BarcLineValue(numLines, pbOffset[i+1], samplingFrequency);\n    pbBval[i] = (pbBval0 + pbBval1) >> 1;\n    pbBval0 = pbBval1;\n  }\n}\n\n\n/*****************************************************************************\n*\n* function name: initMinSnr\n* description:  calculate min snr parameter\n*\t\t\t\tminSnr(n) = 1/(2^sfbPemin(n)/w(n) - 1.5)\n*\n*****************************************************************************/\nstatic void initMinSnr(const Word32  bitrate,\n                       const Word32  samplerate,\n                       const Word16  numLines,\n                       const Word16 *sfbOffset,\n                       const Word16 *pbBarcVal,\n                       const Word16  sfbActive,\n                       Word16       *sfbMinSnr)\n{\n  Word16 sfb;\n  Word16 barcWidth;\n  Word16 pePerWindow;\n  Word32 pePart;\n  Word32 snr;\n  Word16 pbVal0, pbVal1, shift;\n\n  /* relative number of active barks */\n\n\n  pePerWindow = bits2pe(extract_l((bitrate * numLines) / samplerate));\n\n  pbVal0 = 0;\n\n  for (sfb=0; sfb<sfbActive; sfb++) {\n\n    pbVal1 = (pbBarcVal[sfb] << 1) - pbVal0;\n    barcWidth = pbVal1 - pbVal0;\n    pbVal0 = pbVal1;\n\n    /* allow at least 2.4% of pe for each active barc */\n\tpePart = ((pePerWindow * 24) * (max_bark * barcWidth)) /\n        (pbBarcVal[sfbActive-1] * (sfbOffset[sfb+1] - sfbOffset[sfb]));\n\n\n    pePart = min(pePart, 8400);\n    pePart = max(pePart, 1400);\n\n    /* minSnr(n) = 1/(2^sfbPemin(n)/w(n) - 1.5)*/\n\t/* we add an offset of 2^16 to the pow functions */\n\t/* 0xc000 = 1.5*(1 << 15)*/\n\n    snr = pow2_xy((pePart - 16*1000),1000) - 0x0000c000;\n\n    if(snr > 0x00008000)\n\t{\n\t\tshift = norm_l(snr);\n\t\tsnr = Div_32(0x00008000 << shift, snr << shift);\n\t}\n\telse\n\t{\n\t\tsnr = 0x7fffffff;\n\t}\n\n    /* upper limit is -1 dB */\n    snr = min(snr, c_maxsnr);\n    /* lower limit is -25 dB */\n    snr = max(snr, c_minsnr);\n    sfbMinSnr[sfb] = round16(snr);\n  }\n\n}\n\n/*****************************************************************************\n*\n* function name: InitPsyConfigurationLong\n* description:  init long block psychoacoustic configuration\n*\n*****************************************************************************/\nWord16 InitPsyConfigurationLong(Word32 bitrate,\n                                Word32 samplerate,\n                                Word16 bandwidth,\n                                PSY_CONFIGURATION_LONG *psyConf)\n{\n  Word32 samplerateindex;\n  Word16 sfbBarcVal[MAX_SFB_LONG];\n  Word16 sfb;\n\n  /*\n    init sfb table\n  */\n  samplerateindex = GetSRIndex(samplerate);\n  psyConf->sfbCnt = sfBandTotalLong[samplerateindex];\n  psyConf->sfbOffset = sfBandTabLong + sfBandTabLongOffset[samplerateindex];\n  psyConf->sampRateIdx = samplerateindex;\n\n  /*\n    calculate barc values for each pb\n  */\n  initBarcValues(psyConf->sfbCnt,\n                 psyConf->sfbOffset,\n                 psyConf->sfbOffset[psyConf->sfbCnt],\n                 samplerate,\n                 sfbBarcVal);\n\n  /*\n    init thresholds in quiet\n  */\n  initThrQuiet(psyConf->sfbCnt,\n               psyConf->sfbOffset,\n               sfbBarcVal,\n               psyConf->sfbThresholdQuiet);\n\n  /*\n    calculate spreading function\n  */\n  initSpreading(psyConf->sfbCnt,\n                sfbBarcVal,\n                psyConf->sfbMaskLowFactor,\n                psyConf->sfbMaskHighFactor,\n                psyConf->sfbMaskLowFactorSprEn,\n                psyConf->sfbMaskHighFactorSprEn,\n                bitrate,\n                LONG_WINDOW);\n\n  /*\n    init ratio\n  */\n  psyConf->ratio = c_ratio;\n\n  psyConf->maxAllowedIncreaseFactor = 2;\n  psyConf->minRemainingThresholdFactor = c_minRemainingThresholdFactor;    /* 0.01 *(1 << 15)*/\n\n  psyConf->clipEnergy = c_maxClipEnergyLong;\n  psyConf->lowpassLine = extract_l((bandwidth<<1) * FRAME_LEN_LONG / samplerate);\n\n  for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) {\n    if (sub(psyConf->sfbOffset[sfb], psyConf->lowpassLine) >= 0)\n      break;\n  }\n  psyConf->sfbActive = sfb;\n\n  /*\n    calculate minSnr\n  */\n  initMinSnr(bitrate,\n             samplerate,\n             psyConf->sfbOffset[psyConf->sfbCnt],\n             psyConf->sfbOffset,\n             sfbBarcVal,\n             psyConf->sfbActive,\n             psyConf->sfbMinSnr);\n\n\n  return(0);\n}\n\n/*****************************************************************************\n*\n* function name: InitPsyConfigurationShort\n* description:  init short block psychoacoustic configuration\n*\n*****************************************************************************/\nWord16 InitPsyConfigurationShort(Word32 bitrate,\n                                 Word32 samplerate,\n                                 Word16 bandwidth,\n                                 PSY_CONFIGURATION_SHORT *psyConf)\n{\n  Word32 samplerateindex;\n  Word16 sfbBarcVal[MAX_SFB_SHORT];\n  Word16 sfb;\n  /*\n    init sfb table\n  */\n  samplerateindex = GetSRIndex(samplerate);\n  psyConf->sfbCnt = sfBandTotalShort[samplerateindex];\n  psyConf->sfbOffset = sfBandTabShort + sfBandTabShortOffset[samplerateindex];\n  psyConf->sampRateIdx = samplerateindex;\n  /*\n    calculate barc values for each pb\n  */\n  initBarcValues(psyConf->sfbCnt,\n                 psyConf->sfbOffset,\n                 psyConf->sfbOffset[psyConf->sfbCnt],\n                 samplerate,\n                 sfbBarcVal);\n\n  /*\n    init thresholds in quiet\n  */\n  initThrQuiet(psyConf->sfbCnt,\n               psyConf->sfbOffset,\n               sfbBarcVal,\n               psyConf->sfbThresholdQuiet);\n\n  /*\n    calculate spreading function\n  */\n  initSpreading(psyConf->sfbCnt,\n                sfbBarcVal,\n                psyConf->sfbMaskLowFactor,\n                psyConf->sfbMaskHighFactor,\n                psyConf->sfbMaskLowFactorSprEn,\n                psyConf->sfbMaskHighFactorSprEn,\n                bitrate,\n                SHORT_WINDOW);\n\n  /*\n    init ratio\n  */\n  psyConf->ratio = c_ratio;\n\n  psyConf->maxAllowedIncreaseFactor = 2;\n  psyConf->minRemainingThresholdFactor = c_minRemainingThresholdFactor;\n\n  psyConf->clipEnergy = c_maxClipEnergyShort;\n\n  psyConf->lowpassLine = extract_l(((bandwidth << 1) * FRAME_LEN_SHORT) / samplerate);\n\n  for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) {\n\n    if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLine)\n      break;\n  }\n  psyConf->sfbActive = sfb;\n\n  /*\n    calculate minSnr\n  */\n  initMinSnr(bitrate,\n             samplerate,\n             psyConf->sfbOffset[psyConf->sfbCnt],\n             psyConf->sfbOffset,\n             sfbBarcVal,\n             psyConf->sfbActive,\n             psyConf->sfbMinSnr);\n\n  return(0);\n}\n\n"
  },
  {
    "path": "jni/src/psy_main.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tpsy_main.c\n\n\tContent:\tPsychoacoustic major functions\n\n*******************************************************************************/\n\n#include \"typedef.h\"\n#include \"basic_op.h\"\n#include \"oper_32b.h\"\n#include \"psy_const.h\"\n#include \"block_switch.h\"\n#include \"transform.h\"\n#include \"spreading.h\"\n#include \"pre_echo_control.h\"\n#include \"band_nrg.h\"\n#include \"psy_configuration.h\"\n#include \"psy_data.h\"\n#include \"ms_stereo.h\"\n#include \"interface.h\"\n#include \"psy_main.h\"\n#include \"grp_data.h\"\n#include \"tns_func.h\"\n#include \"memalign.h\"\n\n/*                                    long       start       short       stop */\nstatic Word16 blockType2windowShape[] = {KBD_WINDOW,SINE_WINDOW,SINE_WINDOW,KBD_WINDOW};\n\n/*\n  forward definitions\n*/\nstatic Word16 advancePsychLong(PSY_DATA* psyData,\n                               TNS_DATA* tnsData,\n                               PSY_CONFIGURATION_LONG *hPsyConfLong,\n                               PSY_OUT_CHANNEL* psyOutChannel,\n                               Word32 *pScratchTns,\n                               const TNS_DATA *tnsData2,\n                               const Word16 ch);\n\nstatic Word16 advancePsychLongMS (PSY_DATA  psyData[MAX_CHANNELS],\n                                  const PSY_CONFIGURATION_LONG *hPsyConfLong);\n\nstatic Word16 advancePsychShort(PSY_DATA* psyData,\n                                TNS_DATA* tnsData,\n                                const PSY_CONFIGURATION_SHORT *hPsyConfShort,\n                                PSY_OUT_CHANNEL* psyOutChannel,\n                                Word32 *pScratchTns,\n                                const TNS_DATA *tnsData2,\n                                const Word16 ch);\n\nstatic Word16 advancePsychShortMS (PSY_DATA  psyData[MAX_CHANNELS],\n                                   const PSY_CONFIGURATION_SHORT *hPsyConfShort);\n\n\n/*****************************************************************************\n*\n* function name: PsyNew\n* description:  allocates memory for psychoacoustic\n* returns:      an error code\n* input:        pointer to a psych handle\n*\n*****************************************************************************/\nWord16 PsyNew(PSY_KERNEL *hPsy, Word32 nChan, VO_MEM_OPERATOR *pMemOP)\n{\n  Word16 i;\n  Word32 *mdctSpectrum;\n  Word32 *scratchTNS;\n  Word16 *mdctDelayBuffer;\n\n  mdctSpectrum = (Word32 *)mem_malloc(pMemOP, nChan * FRAME_LEN_LONG * sizeof(Word32), 32, VO_INDEX_ENC_AAC);\n  if(NULL == mdctSpectrum)\n\t  return 1;\n\n  scratchTNS = (Word32 *)mem_malloc(pMemOP, nChan * FRAME_LEN_LONG * sizeof(Word32), 32, VO_INDEX_ENC_AAC);\n  if(NULL == scratchTNS)\n  {\n\t  return 1;\n  }\n\n  mdctDelayBuffer = (Word16 *)mem_malloc(pMemOP, nChan * BLOCK_SWITCHING_OFFSET * sizeof(Word16), 32, VO_INDEX_ENC_AAC);\n  if(NULL == mdctDelayBuffer)\n  {\n\t  return 1;\n  }\n\n  for (i=0; i<nChan; i++){\n    hPsy->psyData[i].mdctDelayBuffer = mdctDelayBuffer + i*BLOCK_SWITCHING_OFFSET;\n    hPsy->psyData[i].mdctSpectrum = mdctSpectrum + i*FRAME_LEN_LONG;\n  }\n\n  hPsy->pScratchTns = scratchTNS;\n\n  return 0;\n}\n\n\n/*****************************************************************************\n*\n* function name: PsyDelete\n* description:  allocates memory for psychoacoustic\n* returns:      an error code\n*\n*****************************************************************************/\nWord16 PsyDelete(PSY_KERNEL  *hPsy, VO_MEM_OPERATOR *pMemOP)\n{\n  Word32 nch;\n\n  if(hPsy)\n  {\n\tif(hPsy->psyData[0].mdctDelayBuffer)\n\t\tmem_free(pMemOP, hPsy->psyData[0].mdctDelayBuffer, VO_INDEX_ENC_AAC);\n\n    if(hPsy->psyData[0].mdctSpectrum)\n\t\tmem_free(pMemOP, hPsy->psyData[0].mdctSpectrum, VO_INDEX_ENC_AAC);\n\n    for (nch=0; nch<MAX_CHANNELS; nch++){\n\t  hPsy->psyData[nch].mdctDelayBuffer = NULL;\n\t  hPsy->psyData[nch].mdctSpectrum = NULL;\n\t}\n\n\tif(hPsy->pScratchTns)\n\t{\n\t\tmem_free(pMemOP, hPsy->pScratchTns, VO_INDEX_ENC_AAC);\n\t\thPsy->pScratchTns = NULL;\n\t}\n  }\n\n  return 0;\n}\n\n\n/*****************************************************************************\n*\n* function name: PsyOutNew\n* description:  allocates memory for psyOut struc\n* returns:      an error code\n* input:        pointer to a psych handle\n*\n*****************************************************************************/\nWord16 PsyOutNew(PSY_OUT *hPsyOut, VO_MEM_OPERATOR *pMemOP)\n{\n  pMemOP->Set(VO_INDEX_ENC_AAC, hPsyOut, 0, sizeof(PSY_OUT));\n  /*\n    alloc some more stuff, tbd\n  */\n  return 0;\n}\n\n/*****************************************************************************\n*\n* function name: PsyOutDelete\n* description:  allocates memory for psychoacoustic\n* returns:      an error code\n*\n*****************************************************************************/\nWord16 PsyOutDelete(PSY_OUT *hPsyOut, VO_MEM_OPERATOR *pMemOP)\n{\n  hPsyOut=NULL;\n  return 0;\n}\n\n\n/*****************************************************************************\n*\n* function name: psyMainInit\n* description:  initializes psychoacoustic\n* returns:      an error code\n*\n*****************************************************************************/\n\nWord16 psyMainInit(PSY_KERNEL *hPsy,\n                   Word32 sampleRate,\n                   Word32 bitRate,\n                   Word16 channels,\n                   Word16 tnsMask,\n                   Word16 bandwidth)\n{\n  Word16 ch, err;\n  Word32 channelBitRate = bitRate/channels;\n\n  err = InitPsyConfigurationLong(channelBitRate,\n                                 sampleRate,\n                                 bandwidth,\n                                 &(hPsy->psyConfLong));\n\n  if (!err) {\n      hPsy->sampleRateIdx = hPsy->psyConfLong.sampRateIdx;\n\t  err = InitTnsConfigurationLong(bitRate, sampleRate, channels,\n                                   &hPsy->psyConfLong.tnsConf, &hPsy->psyConfLong, tnsMask&2);\n  }\n\n  if (!err)\n    err = InitPsyConfigurationShort(channelBitRate,\n                                    sampleRate,\n                                    bandwidth,\n                                    &hPsy->psyConfShort);\n  if (!err) {\n    err = InitTnsConfigurationShort(bitRate, sampleRate, channels,\n                                    &hPsy->psyConfShort.tnsConf, &hPsy->psyConfShort, tnsMask&1);\n  }\n\n  if (!err)\n    for(ch=0;ch < channels;ch++){\n\n      InitBlockSwitching(&hPsy->psyData[ch].blockSwitchingControl,\n                         bitRate, channels);\n\n      InitPreEchoControl(hPsy->psyData[ch].sfbThresholdnm1,\n                         hPsy->psyConfLong.sfbCnt,\n                         hPsy->psyConfLong.sfbThresholdQuiet);\n      hPsy->psyData[ch].mdctScalenm1 = 0;\n    }\n\n\treturn(err);\n}\n\n/*****************************************************************************\n*\n* function name: psyMain\n* description:  psychoacoustic main function\n* returns:      an error code\n*\n*    This function assumes that enough input data is in the modulo buffer.\n*\n*****************************************************************************/\n\nWord16 psyMain(Word16                   nChannels,\n               ELEMENT_INFO            *elemInfo,\n               Word16                  *timeSignal,\n               PSY_DATA                 psyData[MAX_CHANNELS],\n               TNS_DATA                 tnsData[MAX_CHANNELS],\n               PSY_CONFIGURATION_LONG  *hPsyConfLong,\n               PSY_CONFIGURATION_SHORT *hPsyConfShort,\n               PSY_OUT_CHANNEL          psyOutChannel[MAX_CHANNELS],\n               PSY_OUT_ELEMENT         *psyOutElement,\n               Word32                  *pScratchTns,\n\t\t\t   Word32\t\t\t\t   sampleRate)\n{\n  Word16 maxSfbPerGroup[MAX_CHANNELS];\n  Word16 mdctScalingArray[MAX_CHANNELS];\n\n  Word16 ch;   /* counts through channels          */\n  Word16 sfb;  /* counts through scalefactor bands */\n  Word16 line; /* counts through lines             */\n  Word16 channels;\n  Word16 maxScale;\n\n  channels = elemInfo->nChannelsInEl;\n  maxScale = 0;\n\n  /* block switching */\n  for(ch = 0; ch < channels; ch++) {\n    BlockSwitching(&psyData[ch].blockSwitchingControl,\n                   timeSignal+elemInfo->ChannelIndex[ch],\n\t\t\t\t   sampleRate,\n                   nChannels);\n  }\n\n  /* synch left and right block type */\n  SyncBlockSwitching(&psyData[0].blockSwitchingControl,\n                     &psyData[1].blockSwitchingControl,\n                     channels);\n\n  /* transform\n     and get maxScale (max mdctScaling) for all channels */\n  for(ch=0; ch<channels; ch++) {\n    Transform_Real(psyData[ch].mdctDelayBuffer,\n                   timeSignal+elemInfo->ChannelIndex[ch],\n                   nChannels,\n                   psyData[ch].mdctSpectrum,\n                   &(mdctScalingArray[ch]),\n                   psyData[ch].blockSwitchingControl.windowSequence);\n    maxScale = max(maxScale, mdctScalingArray[ch]);\n  }\n\n  /* common scaling for all channels */\n  for (ch=0; ch<channels; ch++) {\n    Word16 scaleDiff = maxScale - mdctScalingArray[ch];\n\n    if (scaleDiff > 0) {\n      Word32 *Spectrum = psyData[ch].mdctSpectrum;\n\t  for(line=0; line<FRAME_LEN_LONG; line++) {\n        *Spectrum = (*Spectrum) >> scaleDiff;\n\t\tSpectrum++;\n      }\n    }\n    psyData[ch].mdctScale = maxScale;\n  }\n\n  for (ch=0; ch<channels; ch++) {\n\n    if(psyData[ch].blockSwitchingControl.windowSequence != SHORT_WINDOW) {\n      /* update long block parameter */\n\t  advancePsychLong(&psyData[ch],\n                       &tnsData[ch],\n                       hPsyConfLong,\n                       &psyOutChannel[ch],\n                       pScratchTns,\n                       &tnsData[1 - ch],\n                       ch);\n\n      /* determine maxSfb */\n      for (sfb=hPsyConfLong->sfbCnt-1; sfb>=0; sfb--) {\n        for (line=hPsyConfLong->sfbOffset[sfb+1] - 1; line>=hPsyConfLong->sfbOffset[sfb]; line--) {\n\n          if (psyData[ch].mdctSpectrum[line] != 0) break;\n        }\n        if (line >= hPsyConfLong->sfbOffset[sfb]) break;\n      }\n      maxSfbPerGroup[ch] = sfb + 1;\n\n      /* Calc bandwise energies for mid and side channel\n         Do it only if 2 channels exist */\n\n      if (ch == 1)\n        advancePsychLongMS(psyData, hPsyConfLong);\n    }\n    else {\n      advancePsychShort(&psyData[ch],\n                        &tnsData[ch],\n                        hPsyConfShort,\n                        &psyOutChannel[ch],\n                        pScratchTns,\n                        &tnsData[1 - ch],\n                        ch);\n\n      /* Calc bandwise energies for mid and side channel\n         Do it only if 2 channels exist */\n\n      if (ch == 1)\n        advancePsychShortMS (psyData, hPsyConfShort);\n    }\n  }\n\n  /* group short data */\n  for(ch=0; ch<channels; ch++) {\n\n    if (psyData[ch].blockSwitchingControl.windowSequence == SHORT_WINDOW) {\n      groupShortData(psyData[ch].mdctSpectrum,\n                     pScratchTns,\n                     &psyData[ch].sfbThreshold,\n                     &psyData[ch].sfbEnergy,\n                     &psyData[ch].sfbEnergyMS,\n                     &psyData[ch].sfbSpreadedEnergy,\n                     hPsyConfShort->sfbCnt,\n                     hPsyConfShort->sfbOffset,\n                     hPsyConfShort->sfbMinSnr,\n                     psyOutElement->groupedSfbOffset[ch],\n                     &maxSfbPerGroup[ch],\n                     psyOutElement->groupedSfbMinSnr[ch],\n                     psyData[ch].blockSwitchingControl.noOfGroups,\n                     psyData[ch].blockSwitchingControl.groupLen);\n    }\n  }\n\n\n#if (MAX_CHANNELS>1)\n  /*\n    stereo Processing\n  */\n  if (channels == 2) {\n    psyOutElement->toolsInfo.msDigest = MS_NONE;\n    maxSfbPerGroup[0] = maxSfbPerGroup[1] = max(maxSfbPerGroup[0], maxSfbPerGroup[1]);\n\n\n    if (psyData[0].blockSwitchingControl.windowSequence != SHORT_WINDOW)\n      MsStereoProcessing(psyData[0].sfbEnergy.sfbLong,\n                         psyData[1].sfbEnergy.sfbLong,\n                         psyData[0].sfbEnergyMS.sfbLong,\n                         psyData[1].sfbEnergyMS.sfbLong,\n                         psyData[0].mdctSpectrum,\n                         psyData[1].mdctSpectrum,\n                         psyData[0].sfbThreshold.sfbLong,\n                         psyData[1].sfbThreshold.sfbLong,\n                         psyData[0].sfbSpreadedEnergy.sfbLong,\n                         psyData[1].sfbSpreadedEnergy.sfbLong,\n                         (Word16*)&psyOutElement->toolsInfo.msDigest,\n                         (Word16*)psyOutElement->toolsInfo.msMask,\n                         hPsyConfLong->sfbCnt,\n                         hPsyConfLong->sfbCnt,\n                         maxSfbPerGroup[0],\n                         (const Word16*)hPsyConfLong->sfbOffset);\n      else\n        MsStereoProcessing(psyData[0].sfbEnergy.sfbLong,\n                           psyData[1].sfbEnergy.sfbLong,\n                           psyData[0].sfbEnergyMS.sfbLong,\n                           psyData[1].sfbEnergyMS.sfbLong,\n                           psyData[0].mdctSpectrum,\n                           psyData[1].mdctSpectrum,\n                           psyData[0].sfbThreshold.sfbLong,\n                           psyData[1].sfbThreshold.sfbLong,\n                           psyData[0].sfbSpreadedEnergy.sfbLong,\n                           psyData[1].sfbSpreadedEnergy.sfbLong,\n                           (Word16*)&psyOutElement->toolsInfo.msDigest,\n                           (Word16*)psyOutElement->toolsInfo.msMask,\n                           psyData[0].blockSwitchingControl.noOfGroups*hPsyConfShort->sfbCnt,\n                           hPsyConfShort->sfbCnt,\n                           maxSfbPerGroup[0],\n                           (const Word16*)psyOutElement->groupedSfbOffset[0]);\n  }\n\n#endif /* (MAX_CHANNELS>1) */\n\n  /*\n    build output\n  */\n  for(ch=0;ch<channels;ch++) {\n\n    if (psyData[ch].blockSwitchingControl.windowSequence != SHORT_WINDOW)\n      BuildInterface(psyData[ch].mdctSpectrum,\n                     psyData[ch].mdctScale,\n                     &psyData[ch].sfbThreshold,\n                     &psyData[ch].sfbEnergy,\n                     &psyData[ch].sfbSpreadedEnergy,\n                     psyData[ch].sfbEnergySum,\n                     psyData[ch].sfbEnergySumMS,\n                     psyData[ch].blockSwitchingControl.windowSequence,\n                     blockType2windowShape[psyData[ch].blockSwitchingControl.windowSequence],\n                     hPsyConfLong->sfbCnt,\n                     hPsyConfLong->sfbOffset,\n                     maxSfbPerGroup[ch],\n                     hPsyConfLong->sfbMinSnr,\n                     psyData[ch].blockSwitchingControl.noOfGroups,\n                     psyData[ch].blockSwitchingControl.groupLen,\n                     &psyOutChannel[ch]);\n    else\n      BuildInterface(psyData[ch].mdctSpectrum,\n                     psyData[ch].mdctScale,\n                     &psyData[ch].sfbThreshold,\n                     &psyData[ch].sfbEnergy,\n                     &psyData[ch].sfbSpreadedEnergy,\n                     psyData[ch].sfbEnergySum,\n                     psyData[ch].sfbEnergySumMS,\n                     SHORT_WINDOW,\n                     SINE_WINDOW,\n                     psyData[0].blockSwitchingControl.noOfGroups*hPsyConfShort->sfbCnt,\n                     psyOutElement->groupedSfbOffset[ch],\n                     maxSfbPerGroup[ch],\n                     psyOutElement->groupedSfbMinSnr[ch],\n                     psyData[ch].blockSwitchingControl.noOfGroups,\n                     psyData[ch].blockSwitchingControl.groupLen,\n                     &psyOutChannel[ch]);\n  }\n\n  return(0); /* no error */\n}\n\n/*****************************************************************************\n*\n* function name: advancePsychLong\n* description:  psychoacoustic for long blocks\n*\n*****************************************************************************/\n\nstatic Word16 advancePsychLong(PSY_DATA* psyData,\n                               TNS_DATA* tnsData,\n                               PSY_CONFIGURATION_LONG *hPsyConfLong,\n                               PSY_OUT_CHANNEL* psyOutChannel,\n                               Word32 *pScratchTns,\n                               const TNS_DATA* tnsData2,\n                               const Word16 ch)\n{\n  Word32 i;\n  Word32 normEnergyShift = (psyData->mdctScale + 1) << 1; /* in reference code, mdct spectrum must be multipied with 2, so +1 */\n  Word32 clipEnergy = hPsyConfLong->clipEnergy >> normEnergyShift;\n  Word32 *data0, *data1, tdata;\n\n  /* low pass */\n  data0 = psyData->mdctSpectrum + hPsyConfLong->lowpassLine;\n  for(i=hPsyConfLong->lowpassLine; i<FRAME_LEN_LONG; i++) {\n    *data0++ = 0;\n  }\n\n  /* Calc sfb-bandwise mdct-energies for left and right channel */\n  CalcBandEnergy( psyData->mdctSpectrum,\n                  hPsyConfLong->sfbOffset,\n                  hPsyConfLong->sfbActive,\n                  psyData->sfbEnergy.sfbLong,\n                  &psyData->sfbEnergySum.sfbLong);\n\n  /*\n    TNS detect\n  */\n  TnsDetect(tnsData,\n            hPsyConfLong->tnsConf,\n            pScratchTns,\n            (const Word16*)hPsyConfLong->sfbOffset,\n            psyData->mdctSpectrum,\n            0,\n            psyData->blockSwitchingControl.windowSequence,\n            psyData->sfbEnergy.sfbLong);\n\n  /*  TnsSync */\n  if (ch == 1) {\n    TnsSync(tnsData,\n            tnsData2,\n            hPsyConfLong->tnsConf,\n            0,\n            psyData->blockSwitchingControl.windowSequence);\n  }\n\n  /*  Tns Encoder */\n  TnsEncode(&psyOutChannel->tnsInfo,\n            tnsData,\n            hPsyConfLong->sfbCnt,\n            hPsyConfLong->tnsConf,\n            hPsyConfLong->lowpassLine,\n            psyData->mdctSpectrum,\n            0,\n            psyData->blockSwitchingControl.windowSequence);\n\n  /* first part of threshold calculation */\n  data0 = psyData->sfbEnergy.sfbLong;\n  data1 = psyData->sfbThreshold.sfbLong;\n  for (i=hPsyConfLong->sfbCnt; i; i--) {\n    tdata = L_mpy_ls(*data0++, hPsyConfLong->ratio);\n    *data1++ = min(tdata, clipEnergy);\n  }\n\n  /* Calc sfb-bandwise mdct-energies for left and right channel again */\n  if (tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive!=0) {\n    Word16 tnsStartBand = hPsyConfLong->tnsConf.tnsStartBand;\n    CalcBandEnergy( psyData->mdctSpectrum,\n                    hPsyConfLong->sfbOffset+tnsStartBand,\n                    hPsyConfLong->sfbActive - tnsStartBand,\n                    psyData->sfbEnergy.sfbLong+tnsStartBand,\n                    &psyData->sfbEnergySum.sfbLong);\n\n\tdata0 = psyData->sfbEnergy.sfbLong;\n\ttdata = psyData->sfbEnergySum.sfbLong;\n\tfor (i=0; i<tnsStartBand; i++)\n      tdata += *data0++;\n\n\tpsyData->sfbEnergySum.sfbLong = tdata;\n  }\n\n\n  /* spreading energy */\n  SpreadingMax(hPsyConfLong->sfbCnt,\n               hPsyConfLong->sfbMaskLowFactor,\n               hPsyConfLong->sfbMaskHighFactor,\n               psyData->sfbThreshold.sfbLong);\n\n  /* threshold in quiet */\n  data0 = psyData->sfbThreshold.sfbLong;\n  data1 = hPsyConfLong->sfbThresholdQuiet;\n  for (i=hPsyConfLong->sfbCnt; i; i--)\n  {\n\t  *data0 = max(*data0, (*data1 >> normEnergyShift));\n\t  data0++; data1++;\n  }\n\n  /* preecho control */\n  if (psyData->blockSwitchingControl.windowSequence == STOP_WINDOW) {\n    data0 = psyData->sfbThresholdnm1;\n\tfor (i=hPsyConfLong->sfbCnt; i; i--) {\n      *data0++ = MAX_32;\n    }\n    psyData->mdctScalenm1 = 0;\n  }\n\n  PreEchoControl( psyData->sfbThresholdnm1,\n                  hPsyConfLong->sfbCnt,\n                  hPsyConfLong->maxAllowedIncreaseFactor,\n                  hPsyConfLong->minRemainingThresholdFactor,\n                  psyData->sfbThreshold.sfbLong,\n                  psyData->mdctScale,\n                  psyData->mdctScalenm1);\n  psyData->mdctScalenm1 = psyData->mdctScale;\n\n\n  if (psyData->blockSwitchingControl.windowSequence== START_WINDOW) {\n    data0 = psyData->sfbThresholdnm1;\n\tfor (i=hPsyConfLong->sfbCnt; i; i--) {\n      *data0++ = MAX_32;\n    }\n    psyData->mdctScalenm1 = 0;\n  }\n\n  /* apply tns mult table on cb thresholds */\n  ApplyTnsMultTableToRatios(hPsyConfLong->tnsConf.tnsRatioPatchLowestCb,\n                            hPsyConfLong->tnsConf.tnsStartBand,\n                            tnsData->dataRaw.tnsLong.subBlockInfo,\n                            psyData->sfbThreshold.sfbLong);\n\n\n  /* spreaded energy */\n  data0 = psyData->sfbSpreadedEnergy.sfbLong;\n  data1 = psyData->sfbEnergy.sfbLong;\n  for (i=hPsyConfLong->sfbCnt; i; i--) {\n    //psyData->sfbSpreadedEnergy.sfbLong[i] = psyData->sfbEnergy.sfbLong[i];\n\t  *data0++ = *data1++;\n  }\n\n  /* spreading energy */\n  SpreadingMax(hPsyConfLong->sfbCnt,\n               hPsyConfLong->sfbMaskLowFactorSprEn,\n               hPsyConfLong->sfbMaskHighFactorSprEn,\n               psyData->sfbSpreadedEnergy.sfbLong);\n\n  return 0;\n}\n\n/*****************************************************************************\n*\n* function name: advancePsychLongMS\n* description:   update mdct-energies for left add or minus right channel\n*\t\t\t\tfor long block\n*\n*****************************************************************************/\nstatic Word16 advancePsychLongMS (PSY_DATA psyData[MAX_CHANNELS],\n                                  const PSY_CONFIGURATION_LONG *hPsyConfLong)\n{\n  CalcBandEnergyMS(psyData[0].mdctSpectrum,\n                   psyData[1].mdctSpectrum,\n                   hPsyConfLong->sfbOffset,\n                   hPsyConfLong->sfbActive,\n                   psyData[0].sfbEnergyMS.sfbLong,\n                   &psyData[0].sfbEnergySumMS.sfbLong,\n                   psyData[1].sfbEnergyMS.sfbLong,\n                   &psyData[1].sfbEnergySumMS.sfbLong);\n\n  return 0;\n}\n\n\n/*****************************************************************************\n*\n* function name: advancePsychShort\n* description:  psychoacoustic for short blocks\n*\n*****************************************************************************/\n\nstatic Word16 advancePsychShort(PSY_DATA* psyData,\n                                TNS_DATA* tnsData,\n                                const PSY_CONFIGURATION_SHORT *hPsyConfShort,\n                                PSY_OUT_CHANNEL* psyOutChannel,\n                                Word32 *pScratchTns,\n                                const TNS_DATA *tnsData2,\n                                const Word16 ch)\n{\n  Word32 w;\n  Word32 normEnergyShift = (psyData->mdctScale + 1) << 1; /* in reference code, mdct spectrum must be multipied with 2, so +1 */\n  Word32 clipEnergy = hPsyConfShort->clipEnergy >> normEnergyShift;\n  Word32 wOffset = 0;\n  Word32 *data0;\n  const Word32 *data1;\n\n  for(w = 0; w < TRANS_FAC; w++) {\n    Word32 i, tdata;\n\n    /* low pass */\n    data0 = psyData->mdctSpectrum + wOffset + hPsyConfShort->lowpassLine;\n\tfor(i=hPsyConfShort->lowpassLine; i<FRAME_LEN_SHORT; i++){\n      *data0++ = 0;\n    }\n\n    /* Calc sfb-bandwise mdct-energies for left and right channel */\n    CalcBandEnergy( psyData->mdctSpectrum+wOffset,\n                    hPsyConfShort->sfbOffset,\n                    hPsyConfShort->sfbActive,\n                    psyData->sfbEnergy.sfbShort[w],\n                    &psyData->sfbEnergySum.sfbShort[w]);\n    /*\n       TNS\n    */\n    TnsDetect(tnsData,\n              hPsyConfShort->tnsConf,\n              pScratchTns,\n              (const Word16*)hPsyConfShort->sfbOffset,\n              psyData->mdctSpectrum+wOffset,\n              w,\n              psyData->blockSwitchingControl.windowSequence,\n              psyData->sfbEnergy.sfbShort[w]);\n\n    /*  TnsSync */\n    if (ch == 1) {\n      TnsSync(tnsData,\n              tnsData2,\n              hPsyConfShort->tnsConf,\n              w,\n              psyData->blockSwitchingControl.windowSequence);\n    }\n\n    TnsEncode(&psyOutChannel->tnsInfo,\n              tnsData,\n              hPsyConfShort->sfbCnt,\n              hPsyConfShort->tnsConf,\n              hPsyConfShort->lowpassLine,\n              psyData->mdctSpectrum+wOffset,\n              w,\n              psyData->blockSwitchingControl.windowSequence);\n\n    /* first part of threshold calculation */\n    data0 = psyData->sfbThreshold.sfbShort[w];\n\tdata1 = psyData->sfbEnergy.sfbShort[w];\n\tfor (i=hPsyConfShort->sfbCnt; i; i--) {\n      tdata = L_mpy_ls(*data1++, hPsyConfShort->ratio);\n      *data0++ = min(tdata, clipEnergy);\n    }\n\n    /* Calc sfb-bandwise mdct-energies for left and right channel again */\n    if (tnsData->dataRaw.tnsShort.subBlockInfo[w].tnsActive != 0) {\n      Word16 tnsStartBand = hPsyConfShort->tnsConf.tnsStartBand;\n      CalcBandEnergy( psyData->mdctSpectrum+wOffset,\n                      hPsyConfShort->sfbOffset+tnsStartBand,\n                      (hPsyConfShort->sfbActive - tnsStartBand),\n                      psyData->sfbEnergy.sfbShort[w]+tnsStartBand,\n                      &psyData->sfbEnergySum.sfbShort[w]);\n\n      tdata = psyData->sfbEnergySum.sfbShort[w];\n\t  data0 = psyData->sfbEnergy.sfbShort[w];\n\t  for (i=tnsStartBand; i; i--)\n        tdata += *data0++;\n\n\t  psyData->sfbEnergySum.sfbShort[w] = tdata;\n    }\n\n    /* spreading */\n    SpreadingMax(hPsyConfShort->sfbCnt,\n                 hPsyConfShort->sfbMaskLowFactor,\n                 hPsyConfShort->sfbMaskHighFactor,\n                 psyData->sfbThreshold.sfbShort[w]);\n\n\n    /* threshold in quiet */\n    data0 = psyData->sfbThreshold.sfbShort[w];\n\tdata1 = hPsyConfShort->sfbThresholdQuiet;\n\tfor (i=hPsyConfShort->sfbCnt; i; i--)\n    {\n\t\t*data0 = max(*data0, (*data1 >> normEnergyShift));\n\n\t\tdata0++; data1++;\n\t}\n\n\n    /* preecho */\n    PreEchoControl( psyData->sfbThresholdnm1,\n                    hPsyConfShort->sfbCnt,\n                    hPsyConfShort->maxAllowedIncreaseFactor,\n                    hPsyConfShort->minRemainingThresholdFactor,\n                    psyData->sfbThreshold.sfbShort[w],\n                    psyData->mdctScale,\n                    w==0 ? psyData->mdctScalenm1 : psyData->mdctScale);\n\n    /* apply tns mult table on cb thresholds */\n    ApplyTnsMultTableToRatios( hPsyConfShort->tnsConf.tnsRatioPatchLowestCb,\n                               hPsyConfShort->tnsConf.tnsStartBand,\n                               tnsData->dataRaw.tnsShort.subBlockInfo[w],\n                               psyData->sfbThreshold.sfbShort[w]);\n\n    /* spreaded energy */\n    data0 = psyData->sfbSpreadedEnergy.sfbShort[w];\n\tdata1 = psyData->sfbEnergy.sfbShort[w];\n\tfor (i=hPsyConfShort->sfbCnt; i; i--) {\n\t  *data0++ = *data1++;\n    }\n    SpreadingMax(hPsyConfShort->sfbCnt,\n                 hPsyConfShort->sfbMaskLowFactorSprEn,\n                 hPsyConfShort->sfbMaskHighFactorSprEn,\n                 psyData->sfbSpreadedEnergy.sfbShort[w]);\n\n    wOffset += FRAME_LEN_SHORT;\n  } /* for TRANS_FAC */\n\n  psyData->mdctScalenm1 = psyData->mdctScale;\n\n  return 0;\n}\n\n/*****************************************************************************\n*\n* function name: advancePsychShortMS\n* description:   update mdct-energies for left add or minus right channel\n*\t\t\t\tfor short block\n*\n*****************************************************************************/\nstatic Word16 advancePsychShortMS (PSY_DATA psyData[MAX_CHANNELS],\n                                   const PSY_CONFIGURATION_SHORT *hPsyConfShort)\n{\n  Word32 w, wOffset;\n  wOffset = 0;\n  for(w=0; w<TRANS_FAC; w++) {\n    CalcBandEnergyMS(psyData[0].mdctSpectrum+wOffset,\n                     psyData[1].mdctSpectrum+wOffset,\n                     hPsyConfShort->sfbOffset,\n                     hPsyConfShort->sfbActive,\n                     psyData[0].sfbEnergyMS.sfbShort[w],\n                     &psyData[0].sfbEnergySumMS.sfbShort[w],\n                     psyData[1].sfbEnergyMS.sfbShort[w],\n                     &psyData[1].sfbEnergySumMS.sfbShort[w]);\n    wOffset += FRAME_LEN_SHORT;\n  }\n\n  return 0;\n}\n"
  },
  {
    "path": "jni/src/qc_main.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tqc_main.c\n\n\tContent:\tQuantizing & coding functions\n\n*******************************************************************************/\n\n#include \"basic_op.h\"\n#include \"oper_32b.h\"\n#include \"qc_main.h\"\n#include \"quantize.h\"\n#include \"interface.h\"\n#include \"adj_thr.h\"\n#include \"sf_estim.h\"\n#include \"stat_bits.h\"\n#include \"bit_cnt.h\"\n#include \"dyn_bits.h\"\n#include \"channel_map.h\"\n#include \"memalign.h\"\n\n\ntypedef enum{\n  FRAME_LEN_BYTES_MODULO =  1,\n  FRAME_LEN_BYTES_INT    =  2\n}FRAME_LEN_RESULT_MODE;\n\nstatic const Word16 maxFillElemBits = 7 + 270*8;\n\n/* forward declarations */\n\nstatic Word16 calcMaxValueInSfb(Word16 sfbCnt,\n                                Word16 maxSfbPerGroup,\n                                Word16 sfbPerGroup,\n                                Word16 sfbOffset[MAX_GROUPED_SFB],\n                                Word16 quantSpectrum[FRAME_LEN_LONG],\n                                UWord16 maxValue[MAX_GROUPED_SFB]);\n\n\n/*****************************************************************************\n*\n* function name: calcFrameLen\n* description: estimate the frame length according the bitrates\n*\n*****************************************************************************/\nstatic Word16 calcFrameLen(Word32 bitRate,\n                           Word32 sampleRate,\n                           FRAME_LEN_RESULT_MODE mode)\n{\n\n  Word32 result;\n  Word32 quot;\n\n  result = (FRAME_LEN_LONG >> 3) * bitRate;\n  quot = result / sampleRate;\n\n\n  if (mode == FRAME_LEN_BYTES_MODULO) {\n    result -= quot * sampleRate;\n  }\n  else { /* FRAME_LEN_BYTES_INT */\n    result = quot;\n  }\n\n  return result;\n}\n\n/*****************************************************************************\n*\n*  function name:framePadding\n*  description: Calculates if padding is needed for actual frame\n*  returns: paddingOn or not\n*\n*****************************************************************************/\nstatic Word16 framePadding(Word32 bitRate,\n                           Word32 sampleRate,\n                           Word32 *paddingRest)\n{\n  Word16 paddingOn;\n  Word16 difference;\n\n  paddingOn = 0;\n\n  difference = calcFrameLen( bitRate,\n                             sampleRate,\n                             FRAME_LEN_BYTES_MODULO );\n  *paddingRest = *paddingRest - difference;\n\n\n  if (*paddingRest <= 0 ) {\n    paddingOn = 1;\n    *paddingRest = *paddingRest + sampleRate;\n  }\n\n  return paddingOn;\n}\n\n\n/*********************************************************************************\n*\n* function name: QCOutNew\n* description: init qcout parameter\n* returns:     0 if success\n*\n**********************************************************************************/\n\nWord16 QCOutNew(QC_OUT *hQC, Word16 nChannels, VO_MEM_OPERATOR *pMemOP)\n{\n  Word32 i;\n  Word16 *quantSpec;\n  Word16 *scf;\n  UWord16 *maxValueInSfb;\n\n  quantSpec = (Word16 *)mem_malloc(pMemOP, nChannels * FRAME_LEN_LONG * sizeof(Word16), 32, VO_INDEX_ENC_AAC);\n  if(NULL == quantSpec)\n\t  return 1;\n  scf = (Word16 *)mem_malloc(pMemOP, nChannels * MAX_GROUPED_SFB * sizeof(Word16), 32, VO_INDEX_ENC_AAC);\n  if(NULL == scf)\n  {\n\t  return 1;\n  }\n  maxValueInSfb = (UWord16 *)mem_malloc(pMemOP, nChannels * MAX_GROUPED_SFB * sizeof(UWord16), 32, VO_INDEX_ENC_AAC);\n  if(NULL == maxValueInSfb)\n  {\n\t  return 1;\n  }\n\n  for (i=0; i<nChannels; i++) {\n    hQC->qcChannel[i].quantSpec = quantSpec + i*FRAME_LEN_LONG;\n\n    hQC->qcChannel[i].maxValueInSfb = maxValueInSfb + i*MAX_GROUPED_SFB;\n\n    hQC->qcChannel[i].scf = scf + i*MAX_GROUPED_SFB;\n  }\n\n  return 0;\n}\n\n\n/*********************************************************************************\n*\n* function name: QCOutDelete\n* description: unint qcout parameter\n* returns:      0 if success\n*\n**********************************************************************************/\nvoid QCOutDelete(QC_OUT* hQC, VO_MEM_OPERATOR *pMemOP)\n{\n   Word32 i;\n   if(hQC)\n   {\n      if(hQC->qcChannel[0].quantSpec)\n\t\t mem_free(pMemOP, hQC->qcChannel[0].quantSpec, VO_INDEX_ENC_AAC);\n\n      if(hQC->qcChannel[0].maxValueInSfb)\n\t\t  mem_free(pMemOP, hQC->qcChannel[0].maxValueInSfb, VO_INDEX_ENC_AAC);\n\n\t  if(hQC->qcChannel[0].scf)\n\t\t  mem_free(pMemOP, hQC->qcChannel[0].scf, VO_INDEX_ENC_AAC);\n\n\t  for (i=0; i<MAX_CHANNELS; i++) {\n\t\t  hQC->qcChannel[i].quantSpec = NULL;\n\n\t\t  hQC->qcChannel[i].maxValueInSfb = NULL;\n\n\t\t  hQC->qcChannel[i].scf = NULL;\n\t  }\n   }\n}\n\n/*********************************************************************************\n*\n* function name: QCNew\n* description: set QC to zero\n* returns:     0 if success\n*\n**********************************************************************************/\nWord16 QCNew(QC_STATE *hQC, VO_MEM_OPERATOR *pMemOP)\n{\n  pMemOP->Set(VO_INDEX_ENC_AAC, hQC,0,sizeof(QC_STATE));\n\n  return (0);\n}\n\n/*********************************************************************************\n*\n* function name: QCDelete\n* description: unint qcout parameter\n*\n**********************************************************************************/\nvoid QCDelete(QC_STATE *hQC, VO_MEM_OPERATOR *pMemOP)\n{\n\n  /*\n     nothing to do\n  */\n  hQC=NULL;\n}\n\n/*********************************************************************************\n*\n* function name: QCInit\n* description: init QD parameter\n* returns:     0 if success\n*\n**********************************************************************************/\nWord16 QCInit(QC_STATE *hQC,\n              struct QC_INIT *init)\n{\n  hQC->nChannels       = init->elInfo->nChannelsInEl;\n  hQC->maxBitsTot      = init->maxBits;\n  hQC->bitResTot       = sub(init->bitRes, init->averageBits);\n  hQC->averageBitsTot  = init->averageBits;\n  hQC->maxBitFac       = init->maxBitFac;\n\n  hQC->padding.paddingRest = init->padding.paddingRest;\n\n  hQC->globStatBits    = 3;                          /* for ID_END */\n\n  /* channel elements init */\n  InitElementBits(&hQC->elementBits,\n                  *init->elInfo,\n                  init->bitrate,\n                  init->averageBits,\n                  hQC->globStatBits);\n\n  /* threshold parameter init */\n  AdjThrInit(&hQC->adjThr,\n             init->meanPe,\n             hQC->elementBits.chBitrate);\n\n  return 0;\n}\n\n\n/*********************************************************************************\n*\n* function name: QCMain\n* description:  quantization and coding the spectrum\n* returns:      0 if success\n*\n**********************************************************************************/\nWord16 QCMain(QC_STATE* hQC,\n              ELEMENT_BITS* elBits,\n              ATS_ELEMENT* adjThrStateElement,\n              PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],  /* may be modified in-place */\n              PSY_OUT_ELEMENT* psyOutElement,\n              QC_OUT_CHANNEL  qcOutChannel[MAX_CHANNELS],    /* out                      */\n              QC_OUT_ELEMENT* qcOutElement,\n              Word16 nChannels,\n\t\t\t  Word16 ancillaryDataBytes)\n{\n  Word16 maxChDynBits[MAX_CHANNELS];\n  Word16 chBitDistribution[MAX_CHANNELS];\n  Word32 ch;\n\n  if (elBits->bitResLevel < 0) {\n    return -1;\n  }\n\n  if (elBits->bitResLevel > elBits->maxBitResBits) {\n    return -1;\n  }\n\n  qcOutElement->staticBitsUsed = countStaticBitdemand(psyOutChannel,\n                                                      psyOutElement,\n                                                      nChannels,\n\t\t\t\t\t\t\t\t\t\t\t\t\t  qcOutElement->adtsUsed);\n\n\n  if (ancillaryDataBytes) {\n    qcOutElement->ancBitsUsed = 7 + (ancillaryDataBytes << 3);\n\n    if (ancillaryDataBytes >= 15)\n      qcOutElement->ancBitsUsed = qcOutElement->ancBitsUsed + 8;\n  }\n  else {\n    qcOutElement->ancBitsUsed = 0;\n  }\n\n  CalcFormFactor(hQC->logSfbFormFactor, hQC->sfbNRelevantLines, hQC->logSfbEnergy, psyOutChannel, nChannels);\n\n  /*adjust thresholds for the desired bitrate */\n  AdjustThresholds(&hQC->adjThr,\n                   adjThrStateElement,\n                   psyOutChannel,\n                   psyOutElement,\n                   chBitDistribution,\n                   hQC->logSfbEnergy,\n                   hQC->sfbNRelevantLines,\n                   qcOutElement,\n\t\t\t\t   elBits,\n\t\t\t\t   nChannels,\n\t\t\t\t   hQC->maxBitFac);\n\n  /*estimate scale factors */\n  EstimateScaleFactors(psyOutChannel,\n                       qcOutChannel,\n                       hQC->logSfbEnergy,\n                       hQC->logSfbFormFactor,\n                       hQC->sfbNRelevantLines,\n                       nChannels);\n\n  /* condition to prevent empty bitreservoir */\n  for (ch = 0; ch < nChannels; ch++) {\n    Word32 maxDynBits;\n    maxDynBits = elBits->averageBits + elBits->bitResLevel - 7; /* -7 bec. of align bits */\n    maxDynBits = maxDynBits - qcOutElement->staticBitsUsed + qcOutElement->ancBitsUsed;\n    maxChDynBits[ch] = extract_l(chBitDistribution[ch] * maxDynBits / 1000);\n  }\n\n  qcOutElement->dynBitsUsed = 0;\n  for (ch = 0; ch < nChannels; ch++) {\n    Word32 chDynBits;\n    Flag   constraintsFulfilled;\n    Word32 iter;\n    iter = 0;\n    do {\n      constraintsFulfilled = 1;\n\n      QuantizeSpectrum(psyOutChannel[ch].sfbCnt,\n                       psyOutChannel[ch].maxSfbPerGroup,\n                       psyOutChannel[ch].sfbPerGroup,\n                       psyOutChannel[ch].sfbOffsets,\n                       psyOutChannel[ch].mdctSpectrum,\n                       qcOutChannel[ch].globalGain,\n                       qcOutChannel[ch].scf,\n                       qcOutChannel[ch].quantSpec);\n\n      if (calcMaxValueInSfb(psyOutChannel[ch].sfbCnt,\n                            psyOutChannel[ch].maxSfbPerGroup,\n                            psyOutChannel[ch].sfbPerGroup,\n                            psyOutChannel[ch].sfbOffsets,\n                            qcOutChannel[ch].quantSpec,\n                            qcOutChannel[ch].maxValueInSfb) > MAX_QUANT) {\n        constraintsFulfilled = 0;\n      }\n\n      chDynBits = dynBitCount(qcOutChannel[ch].quantSpec,\n                              qcOutChannel[ch].maxValueInSfb,\n                              qcOutChannel[ch].scf,\n                              psyOutChannel[ch].windowSequence,\n                              psyOutChannel[ch].sfbCnt,\n                              psyOutChannel[ch].maxSfbPerGroup,\n                              psyOutChannel[ch].sfbPerGroup,\n                              psyOutChannel[ch].sfbOffsets,\n                              &qcOutChannel[ch].sectionData);\n\n      if (chDynBits >= maxChDynBits[ch]) {\n        constraintsFulfilled = 0;\n      }\n\n      if (!constraintsFulfilled) {\n        qcOutChannel[ch].globalGain = qcOutChannel[ch].globalGain + 1;\n      }\n\n      iter = iter + 1;\n\n    } while(!constraintsFulfilled);\n\n    qcOutElement->dynBitsUsed = qcOutElement->dynBitsUsed + chDynBits;\n\n    qcOutChannel[ch].mdctScale    = psyOutChannel[ch].mdctScale;\n    qcOutChannel[ch].groupingMask = psyOutChannel[ch].groupingMask;\n    qcOutChannel[ch].windowShape  = psyOutChannel[ch].windowShape;\n  }\n\n  /* save dynBitsUsed for correction of bits2pe relation */\n  AdjThrUpdate(adjThrStateElement, qcOutElement->dynBitsUsed);\n\n  {\n    Word16 bitResSpace = elBits->maxBitResBits - elBits->bitResLevel;\n    Word16 deltaBitRes = elBits->averageBits -\n                        (qcOutElement->staticBitsUsed +\n                         qcOutElement->dynBitsUsed + qcOutElement->ancBitsUsed);\n\n    qcOutElement->fillBits = max(0, (deltaBitRes - bitResSpace));\n  }\n\n  return 0; /* OK */\n}\n\n\n/*********************************************************************************\n*\n* function name: calcMaxValueInSfb\n* description:  search the max Spectrum in one sfb\n*\n**********************************************************************************/\nstatic Word16 calcMaxValueInSfb(Word16 sfbCnt,\n                                Word16 maxSfbPerGroup,\n                                Word16 sfbPerGroup,\n                                Word16 sfbOffset[MAX_GROUPED_SFB],\n                                Word16 quantSpectrum[FRAME_LEN_LONG],\n                                UWord16 maxValue[MAX_GROUPED_SFB])\n{\n  Word16 sfbOffs, sfb;\n  Word16 maxValueAll;\n\n  maxValueAll = 0;\n\n  for(sfbOffs=0;sfbOffs<sfbCnt;sfbOffs+=sfbPerGroup) {\n    for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {\n      Word16 line;\n      Word16 maxThisSfb;\n      maxThisSfb = 0;\n\n      for (line = sfbOffset[sfbOffs+sfb]; line < sfbOffset[sfbOffs+sfb+1]; line++) {\n        Word16 absVal;\n        absVal = abs_s(quantSpectrum[line]);\n        maxThisSfb = max(maxThisSfb, absVal);\n      }\n\n      maxValue[sfbOffs+sfb] = maxThisSfb;\n      maxValueAll = max(maxValueAll, maxThisSfb);\n    }\n  }\n  return maxValueAll;\n}\n\n\n/*********************************************************************************\n*\n* function name: updateBitres\n* description: update bitreservoir\n*\n**********************************************************************************/\nvoid updateBitres(QC_STATE* qcKernel,\n                  QC_OUT*   qcOut)\n\n{\n  ELEMENT_BITS *elBits;\n\n  qcKernel->bitResTot = 0;\n\n  elBits = &qcKernel->elementBits;\n\n\n  if (elBits->averageBits > 0) {\n    /* constant bitrate */\n    Word16 bitsUsed;\n    bitsUsed = (qcOut->qcElement.staticBitsUsed + qcOut->qcElement.dynBitsUsed) +\n                   (qcOut->qcElement.ancBitsUsed + qcOut->qcElement.fillBits);\n    elBits->bitResLevel = elBits->bitResLevel + (elBits->averageBits - bitsUsed);\n    qcKernel->bitResTot = qcKernel->bitResTot + elBits->bitResLevel;\n  }\n  else {\n    /* variable bitrate */\n    elBits->bitResLevel = elBits->maxBits;\n    qcKernel->bitResTot = qcKernel->maxBitsTot;\n  }\n}\n\n/*********************************************************************************\n*\n* function name: FinalizeBitConsumption\n* description: count bits used\n*\n**********************************************************************************/\nWord16 FinalizeBitConsumption(QC_STATE *qcKernel,\n                              QC_OUT* qcOut)\n{\n  Word32 nFullFillElem;\n  Word32 totFillBits;\n  Word16 diffBits;\n  Word16 bitsUsed;\n\n  totFillBits = 0;\n\n  qcOut->totStaticBitsUsed = qcKernel->globStatBits;\n  qcOut->totStaticBitsUsed += qcOut->qcElement.staticBitsUsed;\n  qcOut->totDynBitsUsed    = qcOut->qcElement.dynBitsUsed;\n  qcOut->totAncBitsUsed    = qcOut->qcElement.ancBitsUsed;\n  qcOut->totFillBits       = qcOut->qcElement.fillBits;\n\n  if (qcOut->qcElement.fillBits) {\n    totFillBits += qcOut->qcElement.fillBits;\n  }\n\n  nFullFillElem = (max((qcOut->totFillBits - 1), 0) / maxFillElemBits) * maxFillElemBits;\n\n  qcOut->totFillBits = qcOut->totFillBits - nFullFillElem;\n\n  /* check fill elements */\n\n  if (qcOut->totFillBits > 0) {\n    /* minimum Fillelement contains 7 (TAG + byte cnt) bits */\n    qcOut->totFillBits = max(7, qcOut->totFillBits);\n    /* fill element size equals n*8 + 7 */\n    qcOut->totFillBits = qcOut->totFillBits + ((8 - ((qcOut->totFillBits - 7) & 0x0007)) & 0x0007);\n  }\n\n  qcOut->totFillBits = qcOut->totFillBits + nFullFillElem;\n\n  /* now distribute extra fillbits and alignbits over channel elements */\n  qcOut->alignBits = 7 - ((qcOut->totDynBitsUsed + qcOut->totStaticBitsUsed +\n                           qcOut->totAncBitsUsed + qcOut->totFillBits - 1) & 0x0007);\n\n\n  if ( (qcOut->alignBits + qcOut->totFillBits - totFillBits == 8) &&\n       (qcOut->totFillBits > 8))\n    qcOut->totFillBits = qcOut->totFillBits - 8;\n\n\n  diffBits = qcOut->alignBits + qcOut->totFillBits - totFillBits;\n\n  if(diffBits>=0) {\n    qcOut->qcElement.fillBits += diffBits;\n  }\n\n  bitsUsed = qcOut->totDynBitsUsed + qcOut->totStaticBitsUsed + qcOut->totAncBitsUsed;\n  bitsUsed = bitsUsed + qcOut->totFillBits + qcOut->alignBits;\n\n  if (bitsUsed > qcKernel->maxBitsTot) {\n    return -1;\n  }\n  return bitsUsed;\n}\n\n\n/*********************************************************************************\n*\n* function name: AdjustBitrate\n* description:  adjusts framelength via padding on a frame to frame basis,\n*               to achieve a bitrate that demands a non byte aligned\n*               framelength\n* return:       errorcode\n*\n**********************************************************************************/\nWord16 AdjustBitrate(QC_STATE        *hQC,\n                     Word32           bitRate,    /* total bitrate */\n                     Word32           sampleRate) /* output sampling rate */\n{\n  Word16 paddingOn;\n  Word16 frameLen;\n  Word16 codeBits;\n  Word16 codeBitsLast;\n\n  /* Do we need a extra padding byte? */\n  paddingOn = framePadding(bitRate,\n                           sampleRate,\n                           &hQC->padding.paddingRest);\n\n  /* frame length */\n  frameLen = paddingOn + calcFrameLen(bitRate,\n                                      sampleRate,\n                                      FRAME_LEN_BYTES_INT);\n\n  frameLen = frameLen << 3;\n  codeBitsLast = hQC->averageBitsTot - hQC->globStatBits;\n  codeBits     = frameLen - hQC->globStatBits;\n\n  /* calculate bits for every channel element */\n  if (codeBits != codeBitsLast) {\n    Word16 totalBits = 0;\n\n    hQC->elementBits.averageBits = (hQC->elementBits.relativeBits * codeBits) >> 16; /* relativeBits was scaled down by 2 */\n    totalBits += hQC->elementBits.averageBits;\n\n    hQC->elementBits.averageBits = hQC->elementBits.averageBits + (codeBits - totalBits);\n  }\n\n  hQC->averageBitsTot = frameLen;\n\n  return 0;\n}\n"
  },
  {
    "path": "jni/src/quantize.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tquantize.c\n\n\tContent:\tquantization functions\n\n*******************************************************************************/\n\n#include \"typedef.h\"\n#include \"basic_op.h\"\n#include \"oper_32b.h\"\n#include \"quantize.h\"\n#include \"aac_rom.h\"\n\n#define MANT_DIGITS 9\n#define MANT_SIZE   (1<<MANT_DIGITS)\n\nstatic const Word32 XROUND = 0x33e425af; /* final rounding constant (-0.0946f+ 0.5f) */\n\n\n/*****************************************************************************\n*\n* function name:pow34\n* description: calculate $x^{\\frac{3}{4}}, for 0.5 < x < 1.0$.\n*\n*****************************************************************************/\n__inline Word32 pow34(Word32 x)\n{\n  /* index table using MANT_DIGITS bits, but mask out the sign bit and the MSB\n     which is always one */\n  return mTab_3_4[(x >> (INT_BITS-2-MANT_DIGITS)) & (MANT_SIZE-1)];\n}\n\n\n/*****************************************************************************\n*\n* function name:quantizeSingleLine\n* description: quantizes spectrum\n*              quaSpectrum = mdctSpectrum^3/4*2^(-(3/16)*gain)\n*\n*****************************************************************************/\nstatic Word16 quantizeSingleLine(const Word16 gain, const Word32 absSpectrum)\n{\n  Word32 e, minusFinalExp, finalShift;\n  Word32 x;\n  Word16 qua = 0;\n\n\n  if (absSpectrum) {\n    e = norm_l(absSpectrum);\n    x = pow34(absSpectrum << e);\n\n    /* calculate the final fractional exponent times 16 (was 3*(4*e + gain) + (INT_BITS-1)*16) */\n    minusFinalExp = (e << 2) + gain;\n    minusFinalExp = (minusFinalExp << 1) + minusFinalExp;\n    minusFinalExp = minusFinalExp + ((INT_BITS-1) << 4);\n\n    /* separate the exponent into a shift, and a multiply */\n    finalShift = minusFinalExp >> 4;\n\n    if (finalShift < INT_BITS) {\n      x = L_mpy_wx(x, pow2tominusNover16[minusFinalExp & 15]);\n\n      x += XROUND >> (INT_BITS - finalShift);\n\n      /* shift and quantize */\n\t  finalShift--;\n\n\t  if(finalShift >= 0)\n\t\t  x >>= finalShift;\n\t  else\n\t\t  x <<= (-finalShift);\n\n\t  qua = saturate(x);\n    }\n  }\n\n  return qua;\n}\n\n/*****************************************************************************\n*\n* function name:quantizeLines\n* description: quantizes spectrum lines\n*              quaSpectrum = mdctSpectrum^3/4*2^(-(3/16)*gain)\n*  input: global gain, number of lines to process, spectral data\n*  output: quantized spectrum\n*\n*****************************************************************************/\nstatic void quantizeLines(const Word16 gain,\n                          const Word16 noOfLines,\n                          const Word32 *mdctSpectrum,\n                          Word16 *quaSpectrum)\n{\n  Word32 line;\n  Word32 m = gain&3;\n  Word32 g = (gain >> 2) + 4;\n  Word32 mdctSpeL;\n  const Word16 *pquat;\n    /* gain&3 */\n\n  pquat = quantBorders[m];\n\n  g += 16;\n\n  if(g >= 0)\n  {\n\tfor (line=0; line<noOfLines; line++) {\n\t  Word32 qua;\n\t  qua = 0;\n\n\t  mdctSpeL = mdctSpectrum[line];\n\n\t  if (mdctSpeL) {\n\t\tWord32 sa;\n\t\tWord32 saShft;\n\n        sa = L_abs(mdctSpeL);\n        //saShft = L_shr(sa, 16 + g);\n\t    saShft = sa >> g;\n\n        if (saShft > pquat[0]) {\n\n          if (saShft < pquat[1]) {\n\n            qua = mdctSpeL>0 ? 1 : -1;\n\t\t  }\n          else {\n\n            if (saShft < pquat[2]) {\n\n              qua = mdctSpeL>0 ? 2 : -2;\n\t\t\t}\n            else {\n\n              if (saShft < pquat[3]) {\n\n                qua = mdctSpeL>0 ? 3 : -3;\n\t\t\t  }\n              else {\n                qua = quantizeSingleLine(gain, sa);\n                /* adjust the sign. Since 0 < qua < 1, this cannot overflow. */\n\n                if (mdctSpeL < 0)\n                  qua = -qua;\n\t\t\t  }\n\t\t\t}\n\t\t  }\n\t\t}\n\t  }\n      quaSpectrum[line] = qua ;\n\t}\n  }\n  else\n  {\n\tfor (line=0; line<noOfLines; line++) {\n\t  Word32 qua;\n\t  qua = 0;\n\n\t  mdctSpeL = mdctSpectrum[line];\n\n\t  if (mdctSpeL) {\n\t\tWord32 sa;\n\t\tWord32 saShft;\n\n        sa = L_abs(mdctSpeL);\n        saShft = sa << g;\n\n        if (saShft > pquat[0]) {\n\n          if (saShft < pquat[1]) {\n\n            qua = mdctSpeL>0 ? 1 : -1;\n\t\t  }\n          else {\n\n            if (saShft < pquat[2]) {\n\n              qua = mdctSpeL>0 ? 2 : -2;\n\t\t\t}\n            else {\n\n              if (saShft < pquat[3]) {\n\n                qua = mdctSpeL>0 ? 3 : -3;\n\t\t\t  }\n              else {\n                qua = quantizeSingleLine(gain, sa);\n                /* adjust the sign. Since 0 < qua < 1, this cannot overflow. */\n\n                if (mdctSpeL < 0)\n                  qua = -qua;\n\t\t\t  }\n\t\t\t}\n\t\t  }\n\t\t}\n\t  }\n      quaSpectrum[line] = qua ;\n\t}\n  }\n\n}\n\n\n/*****************************************************************************\n*\n* function name:iquantizeLines\n* description: iquantizes spectrum lines without sign\n*              mdctSpectrum = iquaSpectrum^4/3 *2^(0.25*gain)\n* input: global gain, number of lines to process,quantized spectrum\n* output: spectral data\n*\n*****************************************************************************/\nstatic void iquantizeLines(const Word16 gain,\n                           const Word16 noOfLines,\n                           const Word16 *quantSpectrum,\n                           Word32 *mdctSpectrum)\n{\n  Word32   iquantizermod;\n  Word32   iquantizershift;\n  Word32   line;\n\n  iquantizermod = gain & 3;\n  iquantizershift = gain >> 2;\n\n  for (line=0; line<noOfLines; line++) {\n\n    if( quantSpectrum[line] != 0 ) {\n      Word32 accu;\n      Word32 ex;\n\t  Word32 tabIndex;\n      Word32 specExp;\n      Word32 s,t;\n\n      accu = quantSpectrum[line];\n\n      ex = norm_l(accu);\n      accu = accu << ex;\n      specExp = INT_BITS-1 - ex;\n\n      tabIndex = (accu >> (INT_BITS-2-MANT_DIGITS)) & (~MANT_SIZE);\n\n      /* calculate \"mantissa\" ^4/3 */\n      s = mTab_4_3[tabIndex];\n\n      /* get approperiate exponent multiplier for specExp^3/4 combined with scfMod */\n      t = specExpMantTableComb_enc[iquantizermod][specExp];\n\n      /* multiply \"mantissa\" ^4/3 with exponent multiplier */\n      accu = MULHIGH(s, t);\n\n      /* get approperiate exponent shifter */\n      specExp = specExpTableComb_enc[iquantizermod][specExp];\n\n      specExp += iquantizershift + 1;\n\t  if(specExp >= 0)\n\t\t  mdctSpectrum[line] = accu << specExp;\n\t  else\n\t\t  mdctSpectrum[line] = accu >> (-specExp);\n    }\n    else {\n      mdctSpectrum[line] = 0;\n    }\n  }\n}\n\n/*****************************************************************************\n*\n* function name: QuantizeSpectrum\n* description: quantizes the entire spectrum\n* returns:\n* input: number of scalefactor bands to be quantized, ...\n* output: quantized spectrum\n*\n*****************************************************************************/\nvoid QuantizeSpectrum(Word16 sfbCnt,\n                      Word16 maxSfbPerGroup,\n                      Word16 sfbPerGroup,\n                      Word16 *sfbOffset,\n                      Word32 *mdctSpectrum,\n                      Word16 globalGain,\n                      Word16 *scalefactors,\n                      Word16 *quantizedSpectrum)\n{\n  Word32 sfbOffs, sfb;\n\n  for(sfbOffs=0;sfbOffs<sfbCnt;sfbOffs+=sfbPerGroup) {\n    Word32 sfbNext ;\n    for (sfb = 0; sfb < maxSfbPerGroup; sfb = sfbNext) {\n      Word16 scalefactor = scalefactors[sfbOffs+sfb];\n      /* coalesce sfbs with the same scalefactor */\n      for (sfbNext = sfb+1;\n           sfbNext < maxSfbPerGroup && scalefactor == scalefactors[sfbOffs+sfbNext];\n           sfbNext++) ;\n\n      quantizeLines(globalGain - scalefactor,\n                    sfbOffset[sfbOffs+sfbNext] - sfbOffset[sfbOffs+sfb],\n                    mdctSpectrum + sfbOffset[sfbOffs+sfb],\n                    quantizedSpectrum + sfbOffset[sfbOffs+sfb]);\n    }\n  }\n}\n\n\n/*****************************************************************************\n*\n* function name:calcSfbDist\n* description: quantizes and requantizes lines to calculate distortion\n* input:  number of lines to be quantized, ...\n* output: distortion\n*\n*****************************************************************************/\nWord32 calcSfbDist(const Word32 *spec,\n                   Word16  sfbWidth,\n                   Word16  gain)\n{\n  Word32 line;\n  Word32 dist;\n  Word32 m = gain&3;\n  Word32 g = (gain >> 2) + 4;\n  Word32 g2 = (g << 1) + 1;\n  const Word16 *pquat, *repquat;\n    /* gain&3 */\n\n  pquat = quantBorders[m];\n  repquat = quantRecon[m];\n\n  dist = 0;\n  g += 16;\n  if(g2 < 0 && g >= 0)\n  {\n\t  g2 = -g2;\n\t  for(line=0; line<sfbWidth; line++) {\n\t\t  if (spec[line]) {\n\t\t\t  Word32 diff;\n\t\t\t  Word32 distSingle;\n\t\t\t  Word32 sa;\n\t\t\t  Word32 saShft;\n\t\t\t  sa = L_abs(spec[line]);\n\t\t\t  //saShft = round16(L_shr(sa, g));\n\t\t\t  //saShft = L_shr(sa, 16+g);\n\t\t\t  saShft = sa >> g;\n\n\t\t\t  if (saShft < pquat[0]) {\n\t\t\t\t  distSingle = (saShft * saShft) >> g2;\n\t\t\t  }\n\t\t\t  else {\n\n\t\t\t\t  if (saShft < pquat[1]) {\n\t\t\t\t\t  diff = saShft - repquat[0];\n\t\t\t\t\t  distSingle = (diff * diff) >> g2;\n\t\t\t\t  }\n\t\t\t\t  else {\n\n\t\t\t\t\t  if (saShft < pquat[2]) {\n\t\t\t\t\t\t  diff = saShft - repquat[1];\n\t\t\t\t\t\t  distSingle = (diff * diff) >> g2;\n\t\t\t\t\t  }\n\t\t\t\t\t  else {\n\n\t\t\t\t\t\t  if (saShft < pquat[3]) {\n\t\t\t\t\t\t\t  diff = saShft - repquat[2];\n\t\t\t\t\t\t\t  distSingle = (diff * diff) >> g2;\n\t\t\t\t\t\t  }\n\t\t\t\t\t\t  else {\n\t\t\t\t\t\t\t  Word16 qua = quantizeSingleLine(gain, sa);\n\t\t\t\t\t\t\t  Word32 iqval, diff32;\n\t\t\t\t\t\t\t  /* now that we have quantized x, re-quantize it. */\n\t\t\t\t\t\t\t  iquantizeLines(gain, 1, &qua, &iqval);\n\t\t\t\t\t\t\t  diff32 = sa - iqval;\n\t\t\t\t\t\t\t  distSingle = fixmul(diff32, diff32);\n\t\t\t\t\t\t  }\n\t\t\t\t\t  }\n\t\t\t\t  }\n\t\t\t  }\n\n\t\t\t  dist = L_add(dist, distSingle);\n\t\t  }\n\t  }\n  }\n  else\n  {\n\t  for(line=0; line<sfbWidth; line++) {\n\t\t  if (spec[line]) {\n\t\t\t  Word32 diff;\n\t\t\t  Word32 distSingle;\n\t\t\t  Word32 sa;\n\t\t\t  Word32 saShft;\n\t\t\t  sa = L_abs(spec[line]);\n\t\t\t  //saShft = round16(L_shr(sa, g));\n\t\t\t  saShft = L_shr(sa, g);\n\n\t\t\t  if (saShft < pquat[0]) {\n\t\t\t\t  distSingle = L_shl((saShft * saShft), g2);\n\t\t\t  }\n\t\t\t  else {\n\n\t\t\t\t  if (saShft < pquat[1]) {\n\t\t\t\t\t  diff = saShft - repquat[0];\n\t\t\t\t\t  distSingle = L_shl((diff * diff), g2);\n\t\t\t\t  }\n\t\t\t\t  else {\n\n\t\t\t\t\t  if (saShft < pquat[2]) {\n\t\t\t\t\t\t  diff = saShft - repquat[1];\n\t\t\t\t\t\t  distSingle = L_shl((diff * diff), g2);\n\t\t\t\t\t  }\n\t\t\t\t\t  else {\n\n\t\t\t\t\t\t  if (saShft < pquat[3]) {\n\t\t\t\t\t\t\t  diff = saShft - repquat[2];\n\t\t\t\t\t\t\t  distSingle = L_shl((diff * diff), g2);\n\t\t\t\t\t\t  }\n\t\t\t\t\t\t  else {\n\t\t\t\t\t\t\t  Word16 qua = quantizeSingleLine(gain, sa);\n\t\t\t\t\t\t\t  Word32 iqval, diff32;\n\t\t\t\t\t\t\t  /* now that we have quantized x, re-quantize it. */\n\t\t\t\t\t\t\t  iquantizeLines(gain, 1, &qua, &iqval);\n\t\t\t\t\t\t\t  diff32 = sa - iqval;\n\t\t\t\t\t\t\t  distSingle = fixmul(diff32, diff32);\n\t\t\t\t\t\t  }\n\t\t\t\t\t  }\n\t\t\t\t  }\n\t\t\t  }\n\t\t\t  dist = L_add(dist, distSingle);\n\t\t  }\n\t  }\n  }\n\n  return dist;\n}\n"
  },
  {
    "path": "jni/src/sf_estim.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tsf_estim.c\n\n\tContent:\tScale factor estimation functions\n\n*******************************************************************************/\n\n#include \"basic_op.h\"\n#include \"oper_32b.h\"\n#include \"sf_estim.h\"\n#include \"quantize.h\"\n#include \"bit_cnt.h\"\n#include \"aac_rom.h\"\n\nstatic const Word16 MAX_SCF_DELTA = 60;\n\n/*!\nconstants reference in comments\n\n C0 = 6.75f;\n C1 = -69.33295f;   -16/3*log(MAX_QUANT+0.5-logCon)/log(2)\n C2 = 4.0f;\n C3 = 2.66666666f;\n\n  PE_C1 = 3.0f;        log(8.0)/log(2)\n  PE_C2 = 1.3219281f;  log(2.5)/log(2)\n  PE_C3 = 0.5593573f;  1-C2/C1\n\n*/\n\n#define FF_SQRT_BITS                    7\n#define FF_SQRT_TABLE_SIZE              (1<<FF_SQRT_BITS - 1<<(FF_SQRT_BITS-2))\n#define COEF08_31\t\t0x66666666\t\t/* 0.8*(1 << 31) */\n#define PE_C1_8\t\t\t24\t\t\t\t/* PE_C1*8 */\n#define PE_C2_16\t\t21\t\t\t\t/* PE_C2*8/PE_C3 */\n#define PE_SCALE\t\t0x059a\t\t\t/* 0.7 * (1 << (15 - 1 - 3))*/\n\n#define SCALE_ESTIMATE_COEF\t0x5555\t\t/* (8.8585/(4*log2(10))) * (1 << 15)*/\n\n/*********************************************************************************\n*\n* function name: formfac_sqrt\n* description:  calculates sqrt(x)/256\n*\n**********************************************************************************/\n__inline Word32 formfac_sqrt(Word32 x)\n{\n\tWord32 y;\n\tWord32 preshift, postshift;\n\n\n\tif (x==0) return 0;\n\tpreshift  = norm_l(x) - (INT_BITS-1-FF_SQRT_BITS);\n\tpostshift = preshift >> 1;\n\tpreshift  = postshift << 1;\n\tpostshift = postshift + 8;\t  /* sqrt/256 */\n\tif(preshift >= 0)\n\t\ty = x << preshift;        /* now 1/4 <= y < 1 */\n\telse\n\t\ty = x >> (-preshift);\n\ty = formfac_sqrttable[y-32];\n\n\tif(postshift >= 0)\n\t\ty = y >> postshift;\n\telse\n\t\ty = y << (-postshift);\n\n\treturn y;\n}\n\n\n/*********************************************************************************\n*\n* function name: CalcFormFactorChannel\n* description:  calculate the form factor one channel\n*\t\t\t\tffac(n) = sqrt(abs(X(k)) + sqrt(abs(X(k+1)) + ....\n*\n**********************************************************************************/\nstatic void\nCalcFormFactorChannel(Word16 *logSfbFormFactor,\n                      Word16 *sfbNRelevantLines,\n                      Word16 *logSfbEnergy,\n                      PSY_OUT_CHANNEL *psyOutChan)\n{\n\tWord32 sfbw, sfbw1;\n\tWord32 i, j;\n\tWord32 sfbOffs, sfb, shift;\n\n\tsfbw = sfbw1 = 0;\n\tfor (sfbOffs=0; sfbOffs<psyOutChan->sfbCnt; sfbOffs+=psyOutChan->sfbPerGroup){\n\t\tfor (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {\n\t\t\ti = sfbOffs+sfb;\n\n\t\t\tif (psyOutChan->sfbEnergy[i] > psyOutChan->sfbThreshold[i]) {\n\t\t\t\tWord32 accu, avgFormFactor,iSfbWidth;\n\t\t\t\tWord32 *mdctSpec;\n\t\t\t\tsfbw = psyOutChan->sfbOffsets[i+1] - psyOutChan->sfbOffsets[i];\n\t\t\t\tiSfbWidth = invSBF[(sfbw >> 2) - 1];\n\t\t\t\tmdctSpec = psyOutChan->mdctSpectrum + psyOutChan->sfbOffsets[i];\n\t\t\t\taccu = 0;\n\t\t\t\t/* calc sum of sqrt(spec) */\n\t\t\t\tfor (j=sfbw; j; j--) {\n\t\t\t\t\taccu += formfac_sqrt(L_abs(*mdctSpec)); mdctSpec++;\n\t\t\t\t}\n\t\t\t\tlogSfbFormFactor[i] = iLog4(accu);\n\t\t\t\tlogSfbEnergy[i] = iLog4(psyOutChan->sfbEnergy[i]);\n\t\t\t\tavgFormFactor = fixmul(rsqrt(psyOutChan->sfbEnergy[i],INT_BITS), iSfbWidth);\n\t\t\t\tavgFormFactor = rsqrt((Word32)avgFormFactor,INT_BITS) >> 10;\n\t\t\t\t/* result is multiplied by 4 */\n\t\t\t\tif(avgFormFactor)\n\t\t\t\t\tsfbNRelevantLines[i] = accu / avgFormFactor;\n\t\t\t\telse\n\t\t\t\t\tsfbNRelevantLines[i] = 0x7fff;\n\t\t\t}\n\t\t\telse {\n\t\t\t\t/* set number of lines to zero */\n\t\t\t\tsfbNRelevantLines[i] = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/*********************************************************************************\n*\n* function name: improveScf\n* description:  find better scalefactor with analysis by synthesis\n*\n**********************************************************************************/\nstatic Word16 improveScf(Word32 *spec,\n                         Word16  sfbWidth,\n                         Word32  thresh,\n                         Word16  scf,\n                         Word16  minScf,\n                         Word32 *dist,\n                         Word16 *minScfCalculated)\n{\n\tWord32 cnt;\n\tWord32 sfbDist;\n\tWord32 scfBest;\n\tWord32 thresh125 = L_add(thresh, (thresh >> 2));\n\n\tscfBest = scf;\n\n\t/* calc real distortion */\n\tsfbDist = calcSfbDist(spec, sfbWidth, scf);\n\t*minScfCalculated = scf;\n\tif(!sfbDist)\n\t  return scfBest;\n\n\tif (sfbDist > thresh125) {\n\t\tWord32 scfEstimated;\n\t\tWord32 sfbDistBest;\n\t\tscfEstimated = scf;\n\t\tsfbDistBest = sfbDist;\n\n\t\tcnt = 0;\n\t\twhile (sfbDist > thresh125 && (cnt < 3)) {\n\n\t\t\tscf = scf + 1;\n\t\t\tsfbDist = calcSfbDist(spec, sfbWidth, scf);\n\n\t\t\tif (sfbDist < sfbDistBest) {\n\t\t\t\tscfBest = scf;\n\t\t\t\tsfbDistBest = sfbDist;\n\t\t\t}\n\t\t\tcnt = cnt + 1;\n\t\t}\n\t\tcnt = 0;\n\t\tscf = scfEstimated;\n\t\tsfbDist = sfbDistBest;\n\t\twhile ((sfbDist > thresh125) && (cnt < 1) && (scf > minScf)) {\n\n\t\t\tscf = scf - 1;\n\t\t\tsfbDist = calcSfbDist(spec, sfbWidth, scf);\n\n\t\t\tif (sfbDist < sfbDistBest) {\n\t\t\t\tscfBest = scf;\n\t\t\t\tsfbDistBest = sfbDist;\n\t\t\t}\n\t\t\t*minScfCalculated = scf;\n\t\t\tcnt = cnt + 1;\n\t\t}\n\t\t*dist = sfbDistBest;\n\t}\n\telse {\n\t\tWord32 sfbDistBest;\n\t\tWord32 sfbDistAllowed;\n\t\tWord32 thresh08 = fixmul(COEF08_31, thresh);\n\t\tsfbDistBest = sfbDist;\n\n\t\tif (sfbDist < thresh08)\n\t\t\tsfbDistAllowed = sfbDist;\n\t\telse\n\t\t\tsfbDistAllowed = thresh08;\n\t\tfor (cnt=0; cnt<3; cnt++) {\n\t\t\tscf = scf + 1;\n\t\t\tsfbDist = calcSfbDist(spec, sfbWidth, scf);\n\n\t\t\tif (fixmul(COEF08_31,sfbDist) < sfbDistAllowed) {\n\t\t\t\t*minScfCalculated = scfBest + 1;\n\t\t\t\tscfBest = scf;\n\t\t\t\tsfbDistBest = sfbDist;\n\t\t\t}\n\t\t}\n\t\t*dist = sfbDistBest;\n\t}\n\n\t/* return best scalefactor */\n\treturn scfBest;\n}\n\n/*********************************************************************************\n*\n* function name: countSingleScfBits\n* description:  count single scf bits in huffum\n*\n**********************************************************************************/\nstatic Word16 countSingleScfBits(Word16 scf, Word16 scfLeft, Word16 scfRight)\n{\n\tWord16 scfBits;\n\n\tscfBits = bitCountScalefactorDelta(scfLeft - scf) +\n\t\tbitCountScalefactorDelta(scf - scfRight);\n\n\treturn scfBits;\n}\n\n/*********************************************************************************\n*\n* function name: calcSingleSpecPe\n* description:  ldRatio = log2(en(n)) - 0,375*scfGain(n)\n*\t\t\t\tnbits = 0.7*nLines*ldRation for ldRation >= c1\n*\t\t\t\tnbits = 0.7*nLines*(c2 + c3*ldRatio) for ldRation < c1\n*\n**********************************************************************************/\nstatic Word16 calcSingleSpecPe(Word16 scf, Word16 sfbConstPePart, Word16 nLines)\n{\n\tWord32 specPe;\n\tWord32 ldRatio;\n\tWord32 scf3;\n\n\tldRatio = sfbConstPePart << 3; /*  (sfbConstPePart -0.375*scf)*8 */\n\tscf3 = scf + scf + scf;\n\tldRatio = ldRatio - scf3;\n\n\tif (ldRatio < PE_C1_8) {\n\t\t/* 21 : 2*8*PE_C2, 2*PE_C3 ~ 1*/\n\t\tldRatio = (ldRatio + PE_C2_16) >> 1;\n\t}\n\tspecPe = nLines * ldRatio;\n\tspecPe = (specPe * PE_SCALE) >> 14;\n\n\treturn saturate(specPe);\n}\n\n\n/*********************************************************************************\n*\n* function name: countScfBitsDiff\n* description:  count different scf bits used\n*\n**********************************************************************************/\nstatic Word16 countScfBitsDiff(Word16 *scfOld, Word16 *scfNew,\n                               Word16 sfbCnt, Word16 startSfb, Word16 stopSfb)\n{\n\tWord32 scfBitsDiff;\n\tWord32 sfb, sfbLast;\n\tWord32 sfbPrev, sfbNext;\n\n\tscfBitsDiff = 0;\n\tsfb = 0;\n\n\t/* search for first relevant sfb */\n\tsfbLast = startSfb;\n\twhile (sfbLast < stopSfb && scfOld[sfbLast] == VOAAC_SHRT_MIN) {\n\n\t\tsfbLast = sfbLast + 1;\n\t}\n\t/* search for previous relevant sfb and count diff */\n\tsfbPrev = startSfb - 1;\n\twhile ((sfbPrev>=0) && scfOld[sfbPrev] == VOAAC_SHRT_MIN) {\n\n\t\tsfbPrev = sfbPrev - 1;\n\t}\n\n\tif (sfbPrev>=0) {\n\t\tscfBitsDiff += bitCountScalefactorDelta(scfNew[sfbPrev] - scfNew[sfbLast]) -\n\t\t\tbitCountScalefactorDelta(scfOld[sfbPrev] - scfOld[sfbLast]);\n\t}\n\t/* now loop through all sfbs and count diffs of relevant sfbs */\n\tfor (sfb=sfbLast+1; sfb<stopSfb; sfb++) {\n\n\t\tif (scfOld[sfb] != VOAAC_SHRT_MIN) {\n\t\t\tscfBitsDiff += bitCountScalefactorDelta(scfNew[sfbLast] - scfNew[sfb]) -\n\t\t\t\tbitCountScalefactorDelta(scfOld[sfbLast] - scfOld[sfb]);\n\t\t\tsfbLast = sfb;\n\t\t}\n\t}\n\t/* search for next relevant sfb and count diff */\n\tsfbNext = stopSfb;\n\twhile (sfbNext < sfbCnt && scfOld[sfbNext] == VOAAC_SHRT_MIN) {\n\n\t\tsfbNext = sfbNext + 1;\n\t}\n\n\tif (sfbNext < sfbCnt)\n\t\tscfBitsDiff += bitCountScalefactorDelta(scfNew[sfbLast] - scfNew[sfbNext]) -\n\t\tbitCountScalefactorDelta(scfOld[sfbLast] - scfOld[sfbNext]);\n\n\treturn saturate(scfBitsDiff);\n}\n\nstatic Word16 calcSpecPeDiff(Word16 *scfOld,\n                             Word16 *scfNew,\n                             Word16 *sfbConstPePart,\n                             Word16 *logSfbEnergy,\n                             Word16 *logSfbFormFactor,\n                             Word16 *sfbNRelevantLines,\n                             Word16 startSfb,\n                             Word16 stopSfb)\n{\n\tWord32 specPeDiff;\n\tWord32 sfb;\n\n\tspecPeDiff = 0;\n\n\t/* loop through all sfbs and count pe difference */\n\tfor (sfb=startSfb; sfb<stopSfb; sfb++) {\n\n\n\t\tif (scfOld[sfb] != VOAAC_SHRT_MIN) {\n\t\t\tWord32 ldRatioOld, ldRatioNew;\n\t\t\tWord32 scf3;\n\n\n\t\t\tif (sfbConstPePart[sfb] == MIN_16) {\n\t\t\t\tsfbConstPePart[sfb] = ((logSfbEnergy[sfb] -\n\t\t\t\t\tlogSfbFormFactor[sfb]) + 11-8*4+3) >> 2;\n\t\t\t}\n\n\n\t\t\tldRatioOld = sfbConstPePart[sfb] << 3;\n\t\t\tscf3 = scfOld[sfb] + scfOld[sfb] + scfOld[sfb];\n\t\t\tldRatioOld = ldRatioOld - scf3;\n\t\t\tldRatioNew = sfbConstPePart[sfb] << 3;\n\t\t\tscf3 = scfNew[sfb] + scfNew[sfb] + scfNew[sfb];\n\t\t\tldRatioNew = ldRatioNew - scf3;\n\n\t\t\tif (ldRatioOld < PE_C1_8) {\n\t\t\t\t/* 21 : 2*8*PE_C2, 2*PE_C3 ~ 1*/\n\t\t\t\tldRatioOld = (ldRatioOld + PE_C2_16) >> 1;\n\t\t\t}\n\n\t\t\tif (ldRatioNew < PE_C1_8) {\n\t\t\t\t/* 21 : 2*8*PE_C2, 2*PE_C3 ~ 1*/\n\t\t\t\tldRatioNew = (ldRatioNew + PE_C2_16) >> 1;\n\t\t\t}\n\n\t\t\tspecPeDiff +=  sfbNRelevantLines[sfb] * (ldRatioNew - ldRatioOld);\n\t\t}\n\t}\n\n\tspecPeDiff = (specPeDiff * PE_SCALE) >> 14;\n\n\treturn saturate(specPeDiff);\n}\n\n\n/*********************************************************************************\n*\n* function name: assimilateSingleScf\n* description:  searched for single scalefactor bands, where the number of bits gained\n*\t\t\t\tby using a smaller scfgain(n) is greater than the estimated increased\n*\t\t\t\tbit demand\n*\n**********************************************************************************/\nstatic void assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan,\n                                Word16 *scf,\n                                Word16 *minScf,\n                                Word32 *sfbDist,\n                                Word16 *sfbConstPePart,\n                                Word16 *logSfbEnergy,\n                                Word16 *logSfbFormFactor,\n                                Word16 *sfbNRelevantLines,\n                                Word16 *minScfCalculated,\n                                Flag    restartOnSuccess)\n{\n\tWord16 sfbLast, sfbAct, sfbNext, scfAct, scfMin;\n\tWord16 *scfLast, *scfNext;\n\tWord32 sfbPeOld, sfbPeNew;\n\tWord32 sfbDistNew;\n\tWord32 j;\n\tFlag   success;\n\tWord16 deltaPe, deltaPeNew, deltaPeTmp;\n\tWord16 *prevScfLast = psyOutChan->prevScfLast;\n\tWord16 *prevScfNext = psyOutChan->prevScfNext;\n\tWord16 *deltaPeLast = psyOutChan->deltaPeLast;\n\tFlag   updateMinScfCalculated;\n\n\tsuccess = 0;\n\tdeltaPe = 0;\n\n\tfor(j=0;j<psyOutChan->sfbCnt;j++){\n\t\tprevScfLast[j] = MAX_16;\n\t\tprevScfNext[j] = MAX_16;\n\t\tdeltaPeLast[j] = MAX_16;\n\t}\n\n\tsfbLast = -1;\n\tsfbAct = -1;\n\tsfbNext = -1;\n\tscfLast = 0;\n\tscfNext = 0;\n\tscfMin = MAX_16;\n\tdo {\n\t\t/* search for new relevant sfb */\n\t\tsfbNext = sfbNext + 1;\n\t\twhile (sfbNext < psyOutChan->sfbCnt && scf[sfbNext] == MIN_16) {\n\n\t\t\tsfbNext = sfbNext + 1;\n\t\t}\n\n\t\tif ((sfbLast>=0) && (sfbAct>=0) && sfbNext < psyOutChan->sfbCnt) {\n\t\t\t/* relevant scfs to the left and to the right */\n\t\t\tscfAct  = scf[sfbAct];\n\t\t\tscfLast = scf + sfbLast;\n\t\t\tscfNext = scf + sfbNext;\n\t\t\tscfMin  = min(*scfLast, *scfNext);\n\t\t}\n\t\telse {\n\n\t\t\tif (sfbLast == -1 && (sfbAct>=0) && sfbNext < psyOutChan->sfbCnt) {\n\t\t\t\t/* first relevant scf */\n\t\t\t\tscfAct  = scf[sfbAct];\n\t\t\t\tscfLast = &scfAct;\n\t\t\t\tscfNext = scf + sfbNext;\n\t\t\t\tscfMin  = *scfNext;\n\t\t\t}\n\t\t\telse {\n\n\t\t\t\tif ((sfbLast>=0) && (sfbAct>=0) && sfbNext == psyOutChan->sfbCnt) {\n\t\t\t\t\t/* last relevant scf */\n\t\t\t\t\tscfAct  = scf[sfbAct];\n\t\t\t\t\tscfLast = scf + sfbLast;\n\t\t\t\t\tscfNext = &scfAct;\n\t\t\t\t\tscfMin  = *scfLast;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (sfbAct>=0)\n\t\t\tscfMin = max(scfMin, minScf[sfbAct]);\n\n\t\tif ((sfbAct >= 0) &&\n\t\t\t(sfbLast>=0 || sfbNext < psyOutChan->sfbCnt) &&\n\t\t\tscfAct > scfMin &&\n\t\t\t(*scfLast != prevScfLast[sfbAct] ||\n\t\t\t*scfNext != prevScfNext[sfbAct] ||\n\t\t\tdeltaPe < deltaPeLast[sfbAct])) {\n\t\t\tsuccess = 0;\n\n\t\t\t/* estimate required bits for actual scf */\n\t\t\tif (sfbConstPePart[sfbAct] == MIN_16) {\n\t\t\t\tsfbConstPePart[sfbAct] = logSfbEnergy[sfbAct] -\n\t\t\t\t\tlogSfbFormFactor[sfbAct] + 11-8*4; /* 4*log2(6.75) - 32 */\n\n\t\t\t\tif (sfbConstPePart[sfbAct] < 0)\n\t\t\t\t\tsfbConstPePart[sfbAct] = sfbConstPePart[sfbAct] + 3;\n\t\t\t\tsfbConstPePart[sfbAct] = sfbConstPePart[sfbAct] >> 2;\n\t\t\t}\n\n\t\t\tsfbPeOld = calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct], sfbNRelevantLines[sfbAct]) +\n\t\t\t\tcountSingleScfBits(scfAct, *scfLast, *scfNext);\n\t\t\tdeltaPeNew = deltaPe;\n\t\t\tupdateMinScfCalculated = 1;\n\t\t\tdo {\n\t\t\t\tscfAct = scfAct - 1;\n\t\t\t\t/* check only if the same check was not done before */\n\n\t\t\t\tif (scfAct < minScfCalculated[sfbAct]) {\n\t\t\t\t\tsfbPeNew = calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct], sfbNRelevantLines[sfbAct]) +\n\t\t\t\t\t\tcountSingleScfBits(scfAct, *scfLast, *scfNext);\n\t\t\t\t\t/* use new scf if no increase in pe and\n\t\t\t\t\tquantization error is smaller */\n\t\t\t\t\tdeltaPeTmp = deltaPe + sfbPeNew - sfbPeOld;\n\n\t\t\t\t\tif (deltaPeTmp < 10) {\n\t\t\t\t\t\tsfbDistNew = calcSfbDist(psyOutChan->mdctSpectrum+\n\t\t\t\t\t\t\tpsyOutChan->sfbOffsets[sfbAct],\n\t\t\t\t\t\t\t(psyOutChan->sfbOffsets[sfbAct+1] - psyOutChan->sfbOffsets[sfbAct]),\n\t\t\t\t\t\t\tscfAct);\n\t\t\t\t\t\tif (sfbDistNew < sfbDist[sfbAct]) {\n\t\t\t\t\t\t\t/* success, replace scf by new one */\n\t\t\t\t\t\t\tscf[sfbAct] = scfAct;\n\t\t\t\t\t\t\tsfbDist[sfbAct] = sfbDistNew;\n\t\t\t\t\t\t\tdeltaPeNew = deltaPeTmp;\n\t\t\t\t\t\t\tsuccess = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t/* mark as already checked */\n\n\t\t\t\t\t\tif (updateMinScfCalculated) {\n\t\t\t\t\t\t\tminScfCalculated[sfbAct] = scfAct;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tupdateMinScfCalculated = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t} while (scfAct > scfMin);\n\t\t\tdeltaPe = deltaPeNew;\n\t\t\t/* save parameters to avoid multiple computations of the same sfb */\n\t\t\tprevScfLast[sfbAct] = *scfLast;\n\t\t\tprevScfNext[sfbAct] = *scfNext;\n\t\t\tdeltaPeLast[sfbAct] = deltaPe;\n\t\t}\n\n\t\tif (success && restartOnSuccess) {\n\t\t\t/* start again at first sfb */\n\t\t\tsfbLast = -1;\n\t\t\tsfbAct  = -1;\n\t\t\tsfbNext = -1;\n\t\t\tscfLast = 0;\n\t\t\tscfNext = 0;\n\t\t\tscfMin  = MAX_16;\n\t\t\tsuccess = 0;\n\t\t}\n\t\telse {\n\t\t\t/* shift sfbs for next band */\n\t\t\tsfbLast = sfbAct;\n\t\t\tsfbAct  = sfbNext;\n\t\t}\n\n  } while (sfbNext < psyOutChan->sfbCnt);\n}\n\n\n/*********************************************************************************\n*\n* function name: assimilateMultipleScf\n* description:  scalefactor difference reduction\n*\n**********************************************************************************/\nstatic void assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan,\n                                  Word16 *scf,\n                                  Word16 *minScf,\n                                  Word32 *sfbDist,\n                                  Word16 *sfbConstPePart,\n                                  Word16 *logSfbEnergy,\n                                  Word16 *logSfbFormFactor,\n                                  Word16 *sfbNRelevantLines)\n{\n\tWord32 sfb, startSfb, stopSfb, scfMin, scfMax, scfAct;\n\tFlag   possibleRegionFound;\n\tWord32 deltaScfBits;\n\tWord32 deltaSpecPe;\n\tWord32 deltaPe, deltaPeNew;\n\tWord32 sfbCnt;\n\tWord32 *sfbDistNew = psyOutChan->sfbDistNew;\n\tWord16 *scfTmp = psyOutChan->prevScfLast;\n\n\tdeltaPe = 0;\n\tsfbCnt = psyOutChan->sfbCnt;\n\n\t/* calc min and max scalfactors */\n\tscfMin = MAX_16;\n\tscfMax = MIN_16;\n\tfor (sfb=0; sfb<sfbCnt; sfb++) {\n\n\t\tif (scf[sfb] != MIN_16) {\n\t\t\tscfMin = min(scfMin, scf[sfb]);\n\t\t\tscfMax = max(scfMax, scf[sfb]);\n\t\t}\n\t}\n\n\tif (scfMax !=  MIN_16) {\n\n\t\tscfAct = scfMax;\n\n\t\tdo {\n\t\t\tscfAct = scfAct - 1;\n\t\t\tfor (sfb=0; sfb<sfbCnt; sfb++) {\n\t\t\t\tscfTmp[sfb] = scf[sfb];\n\t\t\t}\n\t\t\tstopSfb = 0;\n\t\t\tdo {\n\t\t\t\tsfb = stopSfb;\n\n\t\t\t\twhile (sfb < sfbCnt && (scf[sfb] == MIN_16 || scf[sfb] <= scfAct)) {\n\t\t\t\t\tsfb = sfb + 1;\n\t\t\t\t}\n\t\t\t\tstartSfb = sfb;\n\t\t\t\tsfb = sfb + 1;\n\n\t\t\t\twhile (sfb < sfbCnt && (scf[sfb] == MIN_16 || scf[sfb] > scfAct)) {\n\t\t\t\t\tsfb = sfb + 1;\n\t\t\t\t}\n\t\t\t\tstopSfb = sfb;\n\n\t\t\t\tpossibleRegionFound = 0;\n\n\t\t\t\tif (startSfb < sfbCnt) {\n\t\t\t\t\tpossibleRegionFound = 1;\n\t\t\t\t\tfor (sfb=startSfb; sfb<stopSfb; sfb++) {\n\n\t\t\t\t\t\tif (scf[sfb]!=MIN_16) {\n\n\t\t\t\t\t\t\tif (scfAct < minScf[sfb]) {\n\t\t\t\t\t\t\t\tpossibleRegionFound = 0;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\n\t\t\t\tif (possibleRegionFound) { /* region found */\n\n\t\t\t\t\t/* replace scfs in region by scfAct */\n\t\t\t\t\tfor (sfb=startSfb; sfb<stopSfb; sfb++) {\n\n\t\t\t\t\t\tif (scfTmp[sfb]!=MIN_16)\n\t\t\t\t\t\t\tscfTmp[sfb] = scfAct;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* estimate change in bit demand for new scfs */\n\t\t\t\t\tdeltaScfBits = countScfBitsDiff(scf,scfTmp,sfbCnt,startSfb,stopSfb);\n\t\t\t\t\tdeltaSpecPe = calcSpecPeDiff(scf, scfTmp, sfbConstPePart,\n\t\t\t\t\t\tlogSfbEnergy, logSfbFormFactor, sfbNRelevantLines,\n\t\t\t\t\t\tstartSfb, stopSfb);\n\t\t\t\t\tdeltaPeNew = deltaPe + deltaScfBits + deltaSpecPe;\n\n\n\t\t\t\t\tif (deltaPeNew < 10) {\n\t\t\t\t\t\tWord32 distOldSum, distNewSum;\n\n\t\t\t\t\t\t/* quantize and calc sum of new distortion */\n\t\t\t\t\t\tdistOldSum = 0;\n\t\t\t\t\t\tdistNewSum = 0;\n\t\t\t\t\t\tfor (sfb=startSfb; sfb<stopSfb; sfb++) {\n\n\t\t\t\t\t\t\tif (scfTmp[sfb] != MIN_16) {\n\t\t\t\t\t\t\t\tdistOldSum = L_add(distOldSum, sfbDist[sfb]);\n\n\t\t\t\t\t\t\t\tsfbDistNew[sfb] = calcSfbDist(psyOutChan->mdctSpectrum +\n\t\t\t\t\t\t\t\t\tpsyOutChan->sfbOffsets[sfb],\n\t\t\t\t\t\t\t\t\t(psyOutChan->sfbOffsets[sfb+1] - psyOutChan->sfbOffsets[sfb]),\n\t\t\t\t\t\t\t\t\tscfAct);\n\n\n\t\t\t\t\t\t\t\tif (sfbDistNew[sfb] > psyOutChan->sfbThreshold[sfb]) {\n\t\t\t\t\t\t\t\t\tdistNewSum = distOldSum << 1;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tdistNewSum = L_add(distNewSum, sfbDistNew[sfb]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (distNewSum < distOldSum) {\n\t\t\t\t\t\t\tdeltaPe = deltaPeNew;\n\t\t\t\t\t\t\tfor (sfb=startSfb; sfb<stopSfb; sfb++) {\n\n\t\t\t\t\t\t\t\tif (scf[sfb]!=MIN_16) {\n\t\t\t\t\t\t\t\t\tscf[sfb] = scfAct;\n\t\t\t\t\t\t\t\t\tsfbDist[sfb] = sfbDistNew[sfb];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} while (stopSfb <= sfbCnt);\n\t\t} while (scfAct > scfMin);\n\t}\n}\n\n/*********************************************************************************\n*\n* function name: EstimateScaleFactorsChannel\n* description:  estimate scale factors for one channel\n*\n**********************************************************************************/\nstatic void\nEstimateScaleFactorsChannel(PSY_OUT_CHANNEL *psyOutChan,\n                            Word16          *scf,\n                            Word16          *globalGain,\n                            Word16          *logSfbEnergy,\n                            Word16          *logSfbFormFactor,\n                            Word16          *sfbNRelevantLines)\n{\n\tWord32 i, j;\n\tWord32 thresh, energy;\n\tWord32 energyPart, thresholdPart;\n\tWord32 scfInt, minScf, maxScf, maxAllowedScf, lastSf;\n\tWord32 maxSpec;\n\tWord32 *sfbDist = psyOutChan->sfbDist;\n\tWord16 *minSfMaxQuant = psyOutChan->minSfMaxQuant;\n\tWord16 *minScfCalculated = psyOutChan->minScfCalculated;\n\n\n\tfor (i=0; i<psyOutChan->sfbCnt; i++) {\n\t\tWord32 sbfwith, sbfStart;\n\t\tWord32 *mdctSpec;\n\t\tthresh = psyOutChan->sfbThreshold[i];\n\t\tenergy = psyOutChan->sfbEnergy[i];\n\n\t\tsbfStart = psyOutChan->sfbOffsets[i];\n\t\tsbfwith = psyOutChan->sfbOffsets[i+1] - sbfStart;\n\t\tmdctSpec = psyOutChan->mdctSpectrum+sbfStart;\n\n\t\tmaxSpec = 0;\n\t\t/* maximum of spectrum */\n\t\tfor (j=sbfwith; j; j-- ) {\n\t\t\tWord32 absSpec = L_abs(*mdctSpec); mdctSpec++;\n\t\t\tmaxSpec |= absSpec;\n\t\t}\n\n\t\t/* scfs without energy or with thresh>energy are marked with MIN_16 */\n\t\tscf[i] = MIN_16;\n\t\tminSfMaxQuant[i] = MIN_16;\n\n\t\tif ((maxSpec > 0) && (energy > thresh)) {\n\n\t\t\tenergyPart = logSfbFormFactor[i];\n\t\t\tthresholdPart = iLog4(thresh);\n\t\t\t/* -20 = 4*log2(6.75) - 32 */\n\t\t\tscfInt = ((thresholdPart - energyPart - 20) * SCALE_ESTIMATE_COEF) >> 15;\n\n\t\t\tminSfMaxQuant[i] = iLog4(maxSpec) - 68; /* 68  -16/3*log(MAX_QUANT+0.5-logCon)/log(2) + 1 */\n\n\n\t\t\tif (minSfMaxQuant[i] > scfInt) {\n\t\t\t\tscfInt = minSfMaxQuant[i];\n\t\t\t}\n\n\t\t\t/* find better scalefactor with analysis by synthesis */\n\t\t\tscfInt = improveScf(psyOutChan->mdctSpectrum+sbfStart,\n\t\t\t\tsbfwith,\n\t\t\t\tthresh, scfInt, minSfMaxQuant[i],\n\t\t\t\t&sfbDist[i], &minScfCalculated[i]);\n\n\t\t\tscf[i] = scfInt;\n\t\t}\n\t}\n\n\n\t/* scalefactor differece reduction  */\n\t{\n\t\tWord16 sfbConstPePart[MAX_GROUPED_SFB];\n\t\tfor(i=0;i<psyOutChan->sfbCnt;i++) {\n\t\t\tsfbConstPePart[i] = MIN_16;\n\t\t}\n\n\t\tassimilateSingleScf(psyOutChan, scf,\n\t\t\tminSfMaxQuant, sfbDist, sfbConstPePart, logSfbEnergy,\n\t\t\tlogSfbFormFactor, sfbNRelevantLines, minScfCalculated, 1);\n\n\t\tassimilateMultipleScf(psyOutChan, scf,\n\t\t\tminSfMaxQuant, sfbDist, sfbConstPePart, logSfbEnergy,\n\t\t\tlogSfbFormFactor, sfbNRelevantLines);\n\t}\n\n\t/* get max scalefac for global gain */\n\tmaxScf = MIN_16;\n\tminScf = MAX_16;\n\tfor (i=0; i<psyOutChan->sfbCnt; i++) {\n\n\t\tif (maxScf < scf[i]) {\n\t\t\tmaxScf = scf[i];\n\t\t}\n\n\t\tif ((scf[i] != MIN_16) && (minScf > scf[i])) {\n\t\t\tminScf = scf[i];\n\t\t}\n\t}\n\t/* limit scf delta */\n\tmaxAllowedScf = minScf + MAX_SCF_DELTA;\n\tfor(i=0; i<psyOutChan->sfbCnt; i++) {\n\n\t\tif ((scf[i] != MIN_16) && (maxAllowedScf < scf[i])) {\n\t\t\tscf[i] = maxAllowedScf;\n\t\t}\n\t}\n\t/* new maxScf if any scf has been limited */\n\n\tif (maxAllowedScf < maxScf) {\n\t\tmaxScf = maxAllowedScf;\n\t}\n\n\t/* calc loop scalefactors */\n\n\tif (maxScf > MIN_16) {\n\t\t*globalGain = maxScf;\n\t\tlastSf = 0;\n\n\t\tfor(i=0; i<psyOutChan->sfbCnt; i++) {\n\n\t\t\tif (scf[i] == MIN_16) {\n\t\t\t\tscf[i] = lastSf;\n\t\t\t\t/* set band explicitely to zero */\n\t\t\t\tfor (j=psyOutChan->sfbOffsets[i]; j<psyOutChan->sfbOffsets[i+1]; j++) {\n\t\t\t\t\tpsyOutChan->mdctSpectrum[j] = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tscf[i] = maxScf - scf[i];\n\t\t\t\tlastSf = scf[i];\n\t\t\t}\n\t\t}\n\t}\n\telse{\n\t\t*globalGain = 0;\n\t\t/* set spectrum explicitely to zero */\n\t\tfor(i=0; i<psyOutChan->sfbCnt; i++) {\n\t\t\tscf[i] = 0;\n\t\t\tfor (j=psyOutChan->sfbOffsets[i]; j<psyOutChan->sfbOffsets[i+1]; j++) {\n\t\t\t\tpsyOutChan->mdctSpectrum[j] = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/*********************************************************************************\n*\n* function name: CalcFormFactor\n* description:  estimate Form factors for all channel\n*\n**********************************************************************************/\nvoid\nCalcFormFactor(Word16 logSfbFormFactor[MAX_CHANNELS][MAX_GROUPED_SFB],\n               Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],\n               Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],\n               PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],\n               const Word16 nChannels)\n{\n\tWord16 j;\n\n\tfor (j=0; j<nChannels; j++) {\n\t\tCalcFormFactorChannel(logSfbFormFactor[j], sfbNRelevantLines[j], logSfbEnergy[j], &psyOutChannel[j]);\n\t}\n}\n\n/*********************************************************************************\n*\n* function name: EstimateScaleFactors\n* description:  estimate scale factors for all channel\n*\n**********************************************************************************/\nvoid\nEstimateScaleFactors(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],\n                     QC_OUT_CHANNEL  qcOutChannel[MAX_CHANNELS],\n                     Word16          logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],\n                     Word16          logSfbFormFactor[MAX_CHANNELS][MAX_GROUPED_SFB],\n                     Word16          sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],\n                     const Word16    nChannels)\n{\n\tWord16 j;\n\n\tfor (j=0; j<nChannels; j++) {\n\t\tEstimateScaleFactorsChannel(&psyOutChannel[j],\n\t\t\tqcOutChannel[j].scf,\n\t\t\t&(qcOutChannel[j].globalGain),\n\t\t\tlogSfbEnergy[j],\n\t\t\tlogSfbFormFactor[j],\n\t\t\tsfbNRelevantLines[j]);\n\t}\n}\n\n"
  },
  {
    "path": "jni/src/spreading.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tspreading.c\n\n\tContent:\tSpreading of energy function\n\n*******************************************************************************/\n\n#include \"basic_op.h\"\n#include \"oper_32b.h\"\n#include \"spreading.h\"\n\n/*********************************************************************************\n*\n* function name: SpreadingMax\n* description:  spreading the energy\n*\t\t\t\t higher frequencies thr(n) = max(thr(n), sh(n)*thr(n-1))\n*\t\t\t\t lower frequencies  thr(n) = max(thr(n), sl(n)*thr(n+1))\n*\n**********************************************************************************/\nvoid SpreadingMax(const Word16 pbCnt,\n                  const Word16 *maskLowFactor,\n                  const Word16 *maskHighFactor,\n                  Word32       *pbSpreadedEnergy)\n{\n  Word32 i;\n\n  /* slope to higher frequencies */\n  for (i=1; i<pbCnt; i++) {\n    pbSpreadedEnergy[i] = max(pbSpreadedEnergy[i],\n                                L_mpy_ls(pbSpreadedEnergy[i-1], maskHighFactor[i]));\n  }\n  /* slope to lower frequencies */\n  for (i=pbCnt - 2; i>=0; i--) {\n    pbSpreadedEnergy[i] = max(pbSpreadedEnergy[i],\n                                L_mpy_ls(pbSpreadedEnergy[i+1], maskLowFactor[i]));\n  }\n}\n"
  },
  {
    "path": "jni/src/stat_bits.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\tstat_bits.c\n\n\tContent:\tStatic bit counter functions\n\n*******************************************************************************/\n\n#include \"stat_bits.h\"\n#include \"bitenc.h\"\n#include \"tns.h\"\n\n\ntypedef enum {\n  SI_ID_BITS                =(3),\n  SI_FILL_COUNT_BITS        =(4),\n  SI_FILL_ESC_COUNT_BITS    =(8),\n  SI_FILL_EXTENTION_BITS    =(4),\n  SI_FILL_NIBBLE_BITS       =(4),\n  SI_SCE_BITS               =(4),\n  SI_CPE_BITS               =(5),\n  SI_CPE_MS_MASK_BITS       =(2) ,\n  SI_ICS_INFO_BITS_LONG     =(1+2+1+6+1),\n  SI_ICS_INFO_BITS_SHORT    =(1+2+1+4+7),\n  SI_ICS_BITS               =(8+1+1+1)\n} SI_BITS;\n\n\n/*********************************************************************************\n*\n* function name: countMsMaskBits\n* description:   count ms stereo bits demand\n*\n**********************************************************************************/\nstatic Word16 countMsMaskBits(Word16   sfbCnt,\n                              Word16   sfbPerGroup,\n                              Word16   maxSfbPerGroup,\n                              struct TOOLSINFO *toolsInfo)\n{\n  Word16 msBits, sfbOff, sfb;\n  msBits = 0;\n\n\n  switch(toolsInfo->msDigest) {\n    case MS_NONE:\n    case MS_ALL:\n      break;\n\n    case MS_SOME:\n      for(sfbOff=0; sfbOff<sfbCnt; sfbOff+=sfbPerGroup)\n        for(sfb=0; sfb<maxSfbPerGroup; sfb++)\n          msBits += 1;\n      break;\n  }\n  return(msBits);\n}\n\n/*********************************************************************************\n*\n* function name: tnsCount\n* description:   count tns bit demand  core function\n*\n**********************************************************************************/\nstatic Word16 tnsCount(TNS_INFO *tnsInfo, Word16 blockType)\n{\n\n  Word32 i, k;\n  Flag tnsPresent;\n  Word32 numOfWindows;\n  Word32 count;\n  Word32 coefBits;\n  Word16 *ptcoef;\n\n  count = 0;\n\n  if (blockType == 2)\n    numOfWindows = 8;\n  else\n    numOfWindows = 1;\n  tnsPresent = 0;\n\n  for (i=0; i<numOfWindows; i++) {\n\n    if (tnsInfo->tnsActive[i]!=0) {\n      tnsPresent = 1;\n    }\n  }\n\n  if (tnsPresent) {\n    /* there is data to be written*/\n    /*count += 1; */\n    for (i=0; i<numOfWindows; i++) {\n\n      if (blockType == 2)\n        count += 1;\n      else\n        count += 2;\n\n      if (tnsInfo->tnsActive[i]) {\n        count += 1;\n\n        if (blockType == 2) {\n          count += 4;\n          count += 3;\n        }\n        else {\n          count += 6;\n          count += 5;\n        }\n\n        if (tnsInfo->order[i]) {\n          count += 1; /*direction*/\n          count += 1; /*coef_compression */\n\n          if (tnsInfo->coefRes[i] == 4) {\n            ptcoef = tnsInfo->coef + i*TNS_MAX_ORDER_SHORT;\n\t\t\tcoefBits = 3;\n            for(k=0; k<tnsInfo->order[i]; k++) {\n\n              if ((ptcoef[k] > 3) || (ptcoef[k] < -4)) {\n                coefBits = 4;\n                break;\n              }\n            }\n          }\n          else {\n            coefBits = 2;\n            ptcoef = tnsInfo->coef + i*TNS_MAX_ORDER_SHORT;\n\t\t\tfor(k=0; k<tnsInfo->order[i]; k++) {\n\n              if ((ptcoef[k] > 1) || (ptcoef[k] < -2)) {\n                coefBits = 3;\n                break;\n              }\n            }\n          }\n          for (k=0; k<tnsInfo->order[i]; k++ ) {\n            count += coefBits;\n          }\n        }\n      }\n    }\n  }\n\n  return count;\n}\n\n/**********************************************************************************\n*\n* function name: countTnsBits\n* description:   count tns bit demand\n*\n**********************************************************************************/\nstatic Word16 countTnsBits(TNS_INFO *tnsInfo,Word16 blockType)\n{\n  return(tnsCount(tnsInfo, blockType));\n}\n\n/*********************************************************************************\n*\n* function name: countStaticBitdemand\n* description:   count static bit demand include tns\n*\n**********************************************************************************/\nWord16 countStaticBitdemand(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],\n                            PSY_OUT_ELEMENT *psyOutElement,\n                            Word16 channels,\n\t\t\t\t\t\t\tWord16 adtsUsed)\n{\n  Word32 statBits;\n  Word32 ch;\n\n  statBits = 0;\n\n  /* if adts used, add 56 bits */\n  if(adtsUsed) statBits += 56;\n\n\n  switch (channels) {\n    case 1:\n      statBits += SI_ID_BITS+SI_SCE_BITS+SI_ICS_BITS;\n      statBits += countTnsBits(&(psyOutChannel[0].tnsInfo),\n                               psyOutChannel[0].windowSequence);\n\n      switch(psyOutChannel[0].windowSequence){\n        case LONG_WINDOW:\n        case START_WINDOW:\n        case STOP_WINDOW:\n          statBits += SI_ICS_INFO_BITS_LONG;\n          break;\n        case SHORT_WINDOW:\n          statBits += SI_ICS_INFO_BITS_SHORT;\n          break;\n      }\n      break;\n    case 2:\n      statBits += SI_ID_BITS+SI_CPE_BITS+2*SI_ICS_BITS;\n\n      statBits += SI_CPE_MS_MASK_BITS;\n      statBits += countMsMaskBits(psyOutChannel[0].sfbCnt,\n\t\t\t\t\t\t\t\t  psyOutChannel[0].sfbPerGroup,\n\t\t\t\t\t\t\t\t  psyOutChannel[0].maxSfbPerGroup,\n\t\t\t\t\t\t\t\t  &psyOutElement->toolsInfo);\n\n      switch (psyOutChannel[0].windowSequence) {\n        case LONG_WINDOW:\n        case START_WINDOW:\n        case STOP_WINDOW:\n          statBits += SI_ICS_INFO_BITS_LONG;\n          break;\n        case SHORT_WINDOW:\n          statBits += SI_ICS_INFO_BITS_SHORT;\n          break;\n      }\n      for(ch=0; ch<2; ch++)\n        statBits += countTnsBits(&(psyOutChannel[ch].tnsInfo),\n                                 psyOutChannel[ch].windowSequence);\n      break;\n  }\n\n  return statBits;\n}\n\n"
  },
  {
    "path": "jni/src/tns.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\ttns.c\n\n\tContent:\tDefinition TNS tools functions\n\n*******************************************************************************/\n\n#include \"basic_op.h\"\n#include \"oper_32b.h\"\n#include \"assert.h\"\n#include \"aac_rom.h\"\n#include \"psy_const.h\"\n#include \"tns.h\"\n#include \"tns_param.h\"\n#include \"psy_configuration.h\"\n#include \"tns_func.h\"\n\n#define TNS_MODIFY_BEGIN         2600  /* Hz */\n#define RATIO_PATCH_LOWER_BORDER 380   /* Hz */\n#define TNS_GAIN_THRESH\t\t\t 141   /* 1.41*100 */\n#define NORM_COEF\t\t\t\t 0x028f5c28\n\nstatic const Word32 TNS_PARCOR_THRESH = 0x0ccccccd; /* 0.1*(1 << 31) */\n/* Limit bands to > 2.0 kHz */\nstatic unsigned short tnsMinBandNumberLong[12] =\n{ 11, 12, 15, 16, 17, 20, 25, 26, 24, 28, 30, 31 };\nstatic unsigned short tnsMinBandNumberShort[12] =\n{ 2, 2, 2, 3, 3, 4, 6, 6, 8, 10, 10, 12 };\n\n/**************************************/\n/* Main/Low Profile TNS Parameters    */\n/**************************************/\nstatic unsigned short tnsMaxBandsLongMainLow[12] =\n{ 31, 31, 34, 40, 42, 51, 46, 46, 42, 42, 42, 39 };\n\nstatic unsigned short tnsMaxBandsShortMainLow[12] =\n{ 9, 9, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14 };\n\n\nstatic void CalcWeightedSpectrum(const Word32 spectrum[],\n                                 Word16 weightedSpectrum[],\n                                 Word32* sfbEnergy,\n                                 const Word16* sfbOffset, Word16 lpcStartLine,\n                                 Word16 lpcStopLine, Word16 lpcStartBand,Word16 lpcStopBand,\n                                 Word32 *pWork32);\n\n\n\nvoid AutoCorrelation(const Word16 input[], Word32 corr[],\n                            Word16 samples, Word16 corrCoeff);\nstatic Word16 AutoToParcor(Word32 workBuffer[], Word32 reflCoeff[], Word16 numOfCoeff);\n\nstatic Word16 CalcTnsFilter(const Word16* signal, const Word32 window[], Word16 numOfLines,\n                                              Word16 tnsOrder, Word32 parcor[]);\n\n\nstatic void Parcor2Index(const Word32 parcor[], Word16 index[], Word16 order,\n                         Word16 bitsPerCoeff);\n\nstatic void Index2Parcor(const Word16 index[], Word32 parcor[], Word16 order,\n                         Word16 bitsPerCoeff);\n\n\n\nstatic void AnalysisFilterLattice(const Word32 signal[], Word16 numOfLines,\n                                  const Word32 parCoeff[], Word16 order,\n                                  Word32 output[]);\n\n\n/**\n*\n* function name: FreqToBandWithRounding\n* description:  Retrieve index of nearest band border\n* returnt:\t\tindex\n*\n*/\nstatic Word16 FreqToBandWithRounding(Word32 freq,                   /*!< frequency in Hertz */\n                                     Word32 fs,                     /*!< Sampling frequency in Hertz */\n                                     Word16 numOfBands,             /*!< total number of bands */\n                                     const Word16 *bandStartOffset) /*!< table of band borders */\n{\n  Word32 lineNumber, band;\n  Word32 temp, shift;\n\n  /*  assert(freq >= 0);  */\n  shift = norm_l(fs);\n  lineNumber = (extract_l(fixmul((bandStartOffset[numOfBands] << 2),Div_32(freq << shift,fs << shift))) + 1) >> 1;\n\n  /* freq > fs/2 */\n  temp = lineNumber - bandStartOffset[numOfBands] ;\n  if (temp >= 0)\n    return numOfBands;\n\n  /* find band the line number lies in */\n  for (band=0; band<numOfBands; band++) {\n    temp = bandStartOffset[band + 1] - lineNumber;\n    if (temp > 0) break;\n  }\n\n  temp = (lineNumber - bandStartOffset[band]);\n  temp = (temp - (bandStartOffset[band + 1] - lineNumber));\n  if ( temp > 0 )\n  {\n    band = band + 1;\n  }\n\n  return extract_l(band);\n}\n\n\n/**\n*\n* function name: InitTnsConfigurationLong\n* description:  Fill TNS_CONFIG structure with sensible content for long blocks\n* returns:\t\t0 if success\n*\n*/\nWord16 InitTnsConfigurationLong(Word32 bitRate,          /*!< bitrate */\n                                Word32 sampleRate,          /*!< Sampling frequency */\n                                Word16 channels,            /*!< number of channels */\n                                TNS_CONFIG *tC,             /*!< TNS Config struct (modified) */\n                                PSY_CONFIGURATION_LONG *pC, /*!< psy config struct */\n                                Word16 active)              /*!< tns active flag */\n{\n\n  Word32 bitratePerChannel;\n  tC->maxOrder     = TNS_MAX_ORDER;\n  tC->tnsStartFreq = 1275;\n  tC->coefRes      = 4;\n\n  /* to avoid integer division */\n  if ( sub(channels,2) == 0 ) {\n    bitratePerChannel = bitRate >> 1;\n  }\n  else {\n    bitratePerChannel = bitRate;\n  }\n\n  tC->tnsMaxSfb = tnsMaxBandsLongMainLow[pC->sampRateIdx];\n\n  tC->tnsActive = active;\n\n  /* now calc band and line borders */\n  tC->tnsStopBand = min(pC->sfbCnt, tC->tnsMaxSfb);\n  tC->tnsStopLine = pC->sfbOffset[tC->tnsStopBand];\n\n  tC->tnsStartBand = FreqToBandWithRounding(tC->tnsStartFreq, sampleRate,\n                                            pC->sfbCnt, (const Word16*)pC->sfbOffset);\n\n  tC->tnsModifyBeginCb = FreqToBandWithRounding(TNS_MODIFY_BEGIN,\n                                                sampleRate,\n                                                pC->sfbCnt,\n                                                (const Word16*)pC->sfbOffset);\n\n  tC->tnsRatioPatchLowestCb = FreqToBandWithRounding(RATIO_PATCH_LOWER_BORDER,\n                                                     sampleRate,\n                                                     pC->sfbCnt,\n                                                     (const Word16*)pC->sfbOffset);\n\n\n  tC->tnsStartLine = pC->sfbOffset[tC->tnsStartBand];\n\n  tC->lpcStopBand = tnsMaxBandsLongMainLow[pC->sampRateIdx];\n  tC->lpcStopBand = min(tC->lpcStopBand, pC->sfbActive);\n\n  tC->lpcStopLine = pC->sfbOffset[tC->lpcStopBand];\n\n  tC->lpcStartBand = tnsMinBandNumberLong[pC->sampRateIdx];\n\n  tC->lpcStartLine = pC->sfbOffset[tC->lpcStartBand];\n\n  tC->threshold = TNS_GAIN_THRESH;\n\n\n  return(0);\n}\n\n/**\n*\n* function name: InitTnsConfigurationShort\n* description:  Fill TNS_CONFIG structure with sensible content for short blocks\n* returns:\t\t0 if success\n*\n*/\nWord16 InitTnsConfigurationShort(Word32 bitRate,              /*!< bitrate */\n                                 Word32 sampleRate,           /*!< Sampling frequency */\n                                 Word16 channels,             /*!< number of channels */\n                                 TNS_CONFIG *tC,              /*!< TNS Config struct (modified) */\n                                 PSY_CONFIGURATION_SHORT *pC, /*!< psy config struct */\n                                 Word16 active)               /*!< tns active flag */\n{\n  Word32 bitratePerChannel;\n  tC->maxOrder     = TNS_MAX_ORDER_SHORT;\n  tC->tnsStartFreq = 2750;\n  tC->coefRes      = 3;\n\n  /* to avoid integer division */\n  if ( sub(channels,2) == 0 ) {\n    bitratePerChannel = L_shr(bitRate,1);\n  }\n  else {\n    bitratePerChannel = bitRate;\n  }\n\n  tC->tnsMaxSfb = tnsMaxBandsShortMainLow[pC->sampRateIdx];\n\n  tC->tnsActive = active;\n\n  /* now calc band and line borders */\n  tC->tnsStopBand = min(pC->sfbCnt, tC->tnsMaxSfb);\n  tC->tnsStopLine = pC->sfbOffset[tC->tnsStopBand];\n\n  tC->tnsStartBand=FreqToBandWithRounding(tC->tnsStartFreq, sampleRate,\n                                          pC->sfbCnt, (const Word16*)pC->sfbOffset);\n\n  tC->tnsModifyBeginCb = FreqToBandWithRounding(TNS_MODIFY_BEGIN,\n                                                sampleRate,\n                                                pC->sfbCnt,\n                                                (const Word16*)pC->sfbOffset);\n\n  tC->tnsRatioPatchLowestCb = FreqToBandWithRounding(RATIO_PATCH_LOWER_BORDER,\n                                                     sampleRate,\n                                                     pC->sfbCnt,\n                                                     (const Word16*)pC->sfbOffset);\n\n\n  tC->tnsStartLine = pC->sfbOffset[tC->tnsStartBand];\n\n  tC->lpcStopBand = tnsMaxBandsShortMainLow[pC->sampRateIdx];\n\n  tC->lpcStopBand = min(tC->lpcStopBand, pC->sfbActive);\n\n  tC->lpcStopLine = pC->sfbOffset[tC->lpcStopBand];\n\n  tC->lpcStartBand = tnsMinBandNumberShort[pC->sampRateIdx];\n\n  tC->lpcStartLine = pC->sfbOffset[tC->lpcStartBand];\n\n  tC->threshold = TNS_GAIN_THRESH;\n\n  return(0);\n}\n\n/**\n*\n* function name: TnsDetect\n* description:  Calculate TNS filter and decide on TNS usage\n* returns:\t\t0 if success\n*\n*/\nWord32 TnsDetect(TNS_DATA* tnsData,        /*!< tns data structure (modified) */\n                 TNS_CONFIG tC,            /*!< tns config structure */\n                 Word32* pScratchTns,      /*!< pointer to scratch space */\n                 const Word16 sfbOffset[], /*!< scalefactor size and table */\n                 Word32* spectrum,         /*!< spectral data */\n                 Word16 subBlockNumber,    /*!< subblock num */\n                 Word16 blockType,         /*!< blocktype (long or short) */\n                 Word32 * sfbEnergy)       /*!< sfb-wise energy */\n{\n\n  Word32  predictionGain;\n  Word32  temp;\n  Word32* pWork32 = &pScratchTns[subBlockNumber >> 8];\n  Word16* pWeightedSpectrum = (Word16 *)&pScratchTns[subBlockNumber >> 8];\n\n\n  if (tC.tnsActive) {\n    CalcWeightedSpectrum(spectrum,\n                         pWeightedSpectrum,\n                         sfbEnergy,\n                         sfbOffset,\n                         tC.lpcStartLine,\n                         tC.lpcStopLine,\n                         tC.lpcStartBand,\n                         tC.lpcStopBand,\n                         pWork32);\n\n    temp = blockType - SHORT_WINDOW;\n    if ( temp != 0 ) {\n        predictionGain = CalcTnsFilter( &pWeightedSpectrum[tC.lpcStartLine],\n                                        tC.acfWindow,\n                                        tC.lpcStopLine - tC.lpcStartLine,\n                                        tC.maxOrder,\n                                        tnsData->dataRaw.tnsLong.subBlockInfo.parcor);\n\n\n        temp = predictionGain - tC.threshold;\n        if ( temp > 0 ) {\n          tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive = 1;\n        }\n        else {\n          tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive = 0;\n        }\n\n        tnsData->dataRaw.tnsLong.subBlockInfo.predictionGain = predictionGain;\n    }\n    else{\n\n        predictionGain = CalcTnsFilter( &pWeightedSpectrum[tC.lpcStartLine],\n                                        tC.acfWindow,\n                                        tC.lpcStopLine - tC.lpcStartLine,\n                                        tC.maxOrder,\n                                        tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].parcor);\n\n        temp = predictionGain - tC.threshold;\n        if ( temp > 0 ) {\n          tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].tnsActive = 1;\n        }\n        else {\n          tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].tnsActive = 0;\n        }\n\n        tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].predictionGain = predictionGain;\n    }\n\n  }\n  else{\n\n    temp = blockType - SHORT_WINDOW;\n    if ( temp != 0 ) {\n        tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive = 0;\n        tnsData->dataRaw.tnsLong.subBlockInfo.predictionGain = 0;\n    }\n    else {\n        tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].tnsActive = 0;\n        tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].predictionGain = 0;\n    }\n  }\n\n  return(0);\n}\n\n\n/*****************************************************************************\n*\n* function name: TnsSync\n* description: update tns parameter\n*\n*****************************************************************************/\nvoid TnsSync(TNS_DATA *tnsDataDest,\n             const TNS_DATA *tnsDataSrc,\n             const TNS_CONFIG tC,\n             const Word16 subBlockNumber,\n             const Word16 blockType)\n{\n   TNS_SUBBLOCK_INFO *sbInfoDest;\n   const TNS_SUBBLOCK_INFO *sbInfoSrc;\n   Word32 i, temp;\n\n   temp =  blockType - SHORT_WINDOW;\n   if ( temp != 0 ) {\n      sbInfoDest = &tnsDataDest->dataRaw.tnsLong.subBlockInfo;\n      sbInfoSrc  = &tnsDataSrc->dataRaw.tnsLong.subBlockInfo;\n   }\n   else {\n      sbInfoDest = &tnsDataDest->dataRaw.tnsShort.subBlockInfo[subBlockNumber];\n      sbInfoSrc  = &tnsDataSrc->dataRaw.tnsShort.subBlockInfo[subBlockNumber];\n   }\n\n   if (100*abs_s(sbInfoDest->predictionGain - sbInfoSrc->predictionGain) <\n       (3 * sbInfoDest->predictionGain)) {\n      sbInfoDest->tnsActive = sbInfoSrc->tnsActive;\n      for ( i=0; i< tC.maxOrder; i++) {\n        sbInfoDest->parcor[i] = sbInfoSrc->parcor[i];\n      }\n   }\n}\n\n/*****************************************************************************\n*\n* function name: TnsEncode\n* description: do TNS filtering\n* returns:     0 if success\n*\n*****************************************************************************/\nWord16 TnsEncode(TNS_INFO* tnsInfo,     /*!< tns info structure (modified) */\n                 TNS_DATA* tnsData,     /*!< tns data structure (modified) */\n                 Word16 numOfSfb,       /*!< number of scale factor bands */\n                 TNS_CONFIG tC,         /*!< tns config structure */\n                 Word16 lowPassLine,    /*!< lowpass line */\n                 Word32* spectrum,      /*!< spectral data (modified) */\n                 Word16 subBlockNumber, /*!< subblock num */\n                 Word16 blockType)      /*!< blocktype (long or short) */\n{\n  Word32 i;\n  Word32 temp_s;\n  Word32 temp;\n  TNS_SUBBLOCK_INFO *psubBlockInfo;\n\n  temp_s = blockType - SHORT_WINDOW;\n  if ( temp_s != 0) {\n    psubBlockInfo = &tnsData->dataRaw.tnsLong.subBlockInfo;\n\tif (psubBlockInfo->tnsActive == 0) {\n      tnsInfo->tnsActive[subBlockNumber] = 0;\n      return(0);\n    }\n    else {\n\n      Parcor2Index(psubBlockInfo->parcor,\n                   tnsInfo->coef,\n                   tC.maxOrder,\n                   tC.coefRes);\n\n      Index2Parcor(tnsInfo->coef,\n                   psubBlockInfo->parcor,\n                   tC.maxOrder,\n                   tC.coefRes);\n\n      for (i=tC.maxOrder - 1; i>=0; i--)  {\n        temp = psubBlockInfo->parcor[i] - TNS_PARCOR_THRESH;\n        if ( temp > 0 )\n          break;\n        temp = psubBlockInfo->parcor[i] + TNS_PARCOR_THRESH;\n        if ( temp < 0 )\n          break;\n      }\n      tnsInfo->order[subBlockNumber] = i + 1;\n\n\n      tnsInfo->tnsActive[subBlockNumber] = 1;\n      for (i=subBlockNumber+1; i<TRANS_FAC; i++) {\n        tnsInfo->tnsActive[i] = 0;\n      }\n      tnsInfo->coefRes[subBlockNumber] = tC.coefRes;\n      tnsInfo->length[subBlockNumber] = numOfSfb - tC.tnsStartBand;\n\n\n      AnalysisFilterLattice(&(spectrum[tC.tnsStartLine]),\n                            (min(tC.tnsStopLine,lowPassLine) - tC.tnsStartLine),\n                            psubBlockInfo->parcor,\n                            tnsInfo->order[subBlockNumber],\n                            &(spectrum[tC.tnsStartLine]));\n\n    }\n  }     /* if (blockType!=SHORT_WINDOW) */\n  else /*short block*/ {\n    psubBlockInfo = &tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber];\n\tif (psubBlockInfo->tnsActive == 0) {\n      tnsInfo->tnsActive[subBlockNumber] = 0;\n      return(0);\n    }\n    else {\n\n      Parcor2Index(psubBlockInfo->parcor,\n                   &tnsInfo->coef[subBlockNumber*TNS_MAX_ORDER_SHORT],\n                   tC.maxOrder,\n                   tC.coefRes);\n\n      Index2Parcor(&tnsInfo->coef[subBlockNumber*TNS_MAX_ORDER_SHORT],\n                   psubBlockInfo->parcor,\n                   tC.maxOrder,\n                   tC.coefRes);\n      for (i=(tC.maxOrder - 1); i>=0; i--)  {\n        temp = psubBlockInfo->parcor[i] - TNS_PARCOR_THRESH;\n         if ( temp > 0 )\n          break;\n\n        temp = psubBlockInfo->parcor[i] + TNS_PARCOR_THRESH;\n        if ( temp < 0 )\n          break;\n      }\n      tnsInfo->order[subBlockNumber] = i + 1;\n\n      tnsInfo->tnsActive[subBlockNumber] = 1;\n      tnsInfo->coefRes[subBlockNumber] = tC.coefRes;\n      tnsInfo->length[subBlockNumber] = numOfSfb - tC.tnsStartBand;\n\n\n      AnalysisFilterLattice(&(spectrum[tC.tnsStartLine]), (tC.tnsStopLine - tC.tnsStartLine),\n                 psubBlockInfo->parcor,\n                 tnsInfo->order[subBlockNumber],\n                 &(spectrum[tC.tnsStartLine]));\n\n    }\n  }\n\n  return(0);\n}\n\n\n/*****************************************************************************\n*\n* function name: m_pow2_cordic\n* description: Iterative power function\n*\n*\tCalculates pow(2.0,x-1.0*(scale+1)) with INT_BITS bit precision\n*\tusing modified cordic algorithm\n* returns:     the result of pow2\n*\n*****************************************************************************/\nstatic Word32 m_pow2_cordic(Word32 x, Word16 scale)\n{\n  Word32 k;\n\n  Word32 accu_y = 0x40000000;\n  accu_y = L_shr(accu_y,scale);\n\n  for(k=1; k<INT_BITS; k++) {\n    const Word32 z = m_log2_table[k];\n\n    while(L_sub(x,z) >= 0) {\n\n      x = L_sub(x, z);\n      accu_y = L_add(accu_y, (accu_y >> k));\n    }\n  }\n  return(accu_y);\n}\n\n\n/*****************************************************************************\n*\n* function name: CalcWeightedSpectrum\n* description: Calculate weighted spectrum for LPC calculation\n*\n*****************************************************************************/\nstatic void CalcWeightedSpectrum(const Word32  spectrum[],         /*!< input spectrum */\n                                 Word16        weightedSpectrum[],\n                                 Word32       *sfbEnergy,          /*!< sfb energies */\n                                 const Word16 *sfbOffset,\n                                 Word16        lpcStartLine,\n                                 Word16        lpcStopLine,\n                                 Word16        lpcStartBand,\n                                 Word16        lpcStopBand,\n                                 Word32       *pWork32)\n{\n    #define INT_BITS_SCAL 1<<(INT_BITS/2)\n\n    Word32 i, sfb, shift;\n    Word32 maxShift;\n    Word32 tmp_s, tmp2_s;\n    Word32 tmp, tmp2;\n    Word32 maxWS;\n    Word32 tnsSfbMean[MAX_SFB];    /* length [lpcStopBand-lpcStartBand] should be sufficient here */\n\n    maxWS = 0;\n\n    /* calc 1.0*2^-INT_BITS/2/sqrt(en) */\n    for( sfb = lpcStartBand; sfb < lpcStopBand; sfb++) {\n\n      tmp2 = sfbEnergy[sfb] - 2;\n      if( tmp2 > 0) {\n        tmp = rsqrt(sfbEnergy[sfb], INT_BITS);\n\t\tif(tmp > INT_BITS_SCAL)\n\t\t{\n\t\t\tshift =  norm_l(tmp);\n\t\t\ttmp = Div_32( INT_BITS_SCAL << shift, tmp << shift );\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttmp = 0x7fffffff;\n\t\t}\n      }\n      else {\n        tmp = 0x7fffffff;\n      }\n      tnsSfbMean[sfb] = tmp;\n    }\n\n    /* spread normalized values from sfbs to lines */\n    sfb = lpcStartBand;\n    tmp = tnsSfbMean[sfb];\n    for ( i=lpcStartLine; i<lpcStopLine; i++){\n      tmp_s = sfbOffset[sfb + 1] - i;\n      if ( tmp_s == 0 ) {\n        sfb = sfb + 1;\n        tmp2_s = sfb + 1 - lpcStopBand;\n        if (tmp2_s <= 0) {\n          tmp = tnsSfbMean[sfb];\n        }\n      }\n      pWork32[i] = tmp;\n    }\n    /*filter down*/\n    for (i=(lpcStopLine - 2); i>=lpcStartLine; i--){\n        pWork32[i] = (pWork32[i] + pWork32[i + 1]) >> 1;\n    }\n    /* filter up */\n    for (i=(lpcStartLine + 1); i<lpcStopLine; i++){\n       pWork32[i] = (pWork32[i] + pWork32[i - 1]) >> 1;\n    }\n\n    /* weight and normalize */\n    for (i=lpcStartLine; i<lpcStopLine; i++){\n      pWork32[i] = MULHIGH(pWork32[i], spectrum[i]);\n      maxWS |= L_abs(pWork32[i]);\n    }\n    maxShift = norm_l(maxWS);\n\n\tmaxShift = 16 - maxShift;\n    if(maxShift >= 0)\n\t{\n\t\tfor (i=lpcStartLine; i<lpcStopLine; i++){\n\t\t\tweightedSpectrum[i] = pWork32[i] >> maxShift;\n\t\t}\n    }\n\telse\n\t{\n\t\tmaxShift = -maxShift;\n\t\tfor (i=lpcStartLine; i<lpcStopLine; i++){\n\t\t\tweightedSpectrum[i] = saturate(pWork32[i] << maxShift);\n\t\t}\n\t}\n}\n\n\n\n\n/*****************************************************************************\n*\n* function name: CalcTnsFilter\n* description:  LPC calculation for one TNS filter\n* returns:      prediction gain\n* input:        signal spectrum, acf window, no. of spectral lines,\n*                max. TNS order, ptr. to reflection ocefficients\n* output:       reflection coefficients\n*(half) window size must be larger than tnsOrder !!*\n******************************************************************************/\n\nstatic Word16 CalcTnsFilter(const Word16 *signal,\n                            const Word32 window[],\n                            Word16 numOfLines,\n                            Word16 tnsOrder,\n                            Word32 parcor[])\n{\n  Word32 parcorWorkBuffer[2*TNS_MAX_ORDER+1];\n  Word32 predictionGain;\n  Word32 i;\n  Word32 tnsOrderPlus1 = tnsOrder + 1;\n\n  assert(tnsOrder <= TNS_MAX_ORDER);      /* remove asserts later? (btg) */\n\n  for(i=0;i<tnsOrder;i++) {\n    parcor[i] = 0;\n  }\n\n  AutoCorrelation(signal, parcorWorkBuffer, numOfLines, tnsOrderPlus1);\n\n  /* early return if signal is very low: signal prediction off, with zero parcor coeffs */\n  if (parcorWorkBuffer[0] == 0)\n    return 0;\n\n  predictionGain = AutoToParcor(parcorWorkBuffer, parcor, tnsOrder);\n\n  return(predictionGain);\n}\n\n/*****************************************************************************\n*\n* function name: AutoCorrelation\n* description:  calc. autocorrelation (acf)\n* returns:      -\n* input:        input values, no. of input values, no. of acf values\n* output:       acf values\n*\n*****************************************************************************/\n#ifndef ARMV5E\nvoid AutoCorrelation(const Word16\t\t input[],\n                            Word32       corr[],\n                            Word16       samples,\n                            Word16       corrCoeff) {\n  Word32 i, j, isamples;\n  Word32 accu;\n  Word32 scf;\n\n  scf = 10 - 1;\n\n  isamples = samples;\n  /* calc first corrCoef:  R[0] = sum { t[i] * t[i] } ; i = 0..N-1 */\n  accu = 0;\n  for(j=0; j<isamples; j++) {\n    accu = L_add(accu, ((input[j] * input[j]) >> scf));\n  }\n  corr[0] = accu;\n\n  /* early termination if all corr coeffs are likely going to be zero */\n  if(corr[0] == 0) return ;\n\n  /* calc all other corrCoef:  R[j] = sum { t[i] * t[i+j] } ; i = 0..(N-j-1), j=1..p */\n  for(i=1; i<corrCoeff; i++) {\n    isamples = isamples - 1;\n    accu = 0;\n    for(j=0; j<isamples; j++) {\n      accu = L_add(accu, ((input[j] * input[j+i]) >> scf));\n    }\n    corr[i] = accu;\n  }\n}\n#endif\n\n/*****************************************************************************\n*\n* function name: AutoToParcor\n* description:  conversion autocorrelation to reflection coefficients\n* returns:      prediction gain\n* input:        <order+1> input values, no. of output values (=order),\n*               ptr. to workbuffer (required size: 2*order)\n* output:       <order> reflection coefficients\n*\n*****************************************************************************/\nstatic Word16 AutoToParcor(Word32 workBuffer[], Word32 reflCoeff[], Word16 numOfCoeff) {\n\n  Word32 i, j, shift;\n  Word32 *pWorkBuffer; /* temp pointer */\n  Word32 predictionGain = 0;\n  Word32 num, denom;\n  Word32 temp, workBuffer0;\n\n\n  num = workBuffer[0];\n  temp = workBuffer[numOfCoeff];\n\n  for(i=0; i<numOfCoeff-1; i++) {\n    workBuffer[i + numOfCoeff] = workBuffer[i + 1];\n  }\n  workBuffer[i + numOfCoeff] = temp;\n\n  for(i=0; i<numOfCoeff; i++) {\n    Word32 refc;\n\n\n    if (workBuffer[0] < L_abs(workBuffer[i + numOfCoeff])) {\n      return 0 ;\n    }\n\tshift = norm_l(workBuffer[0]);\n\tworkBuffer0 = Div_32(1 << shift, workBuffer[0] << shift);\n    /* calculate refc = -workBuffer[numOfCoeff+i] / workBuffer[0]; -1 <= refc < 1 */\n\trefc = L_negate(fixmul(workBuffer[numOfCoeff + i], workBuffer0));\n\n    reflCoeff[i] = refc;\n\n    pWorkBuffer = &(workBuffer[numOfCoeff]);\n\n    for(j=i; j<numOfCoeff; j++) {\n      Word32 accu1, accu2;\n      accu1 = L_add(pWorkBuffer[j], fixmul(refc, workBuffer[j - i]));\n      accu2 = L_add(workBuffer[j - i], fixmul(refc, pWorkBuffer[j]));\n      pWorkBuffer[j] = accu1;\n      workBuffer[j - i] = accu2;\n    }\n  }\n\n  denom = MULHIGH(workBuffer[0], NORM_COEF);\n\n  if (denom != 0) {\n    Word32 temp;\n\tshift = norm_l(denom);\n\ttemp = Div_32(1 << shift, denom << shift);\n    predictionGain = fixmul(num, temp);\n  }\n\n  return extract_l(predictionGain);\n}\n\n\n\nstatic Word16 Search3(Word32 parcor)\n{\n  Word32 index = 0;\n  Word32 i;\n  Word32 temp;\n\n  for (i=0;i<8;i++) {\n    temp = L_sub( parcor, tnsCoeff3Borders[i]);\n    if (temp > 0)\n      index=i;\n  }\n  return extract_l(index - 4);\n}\n\nstatic Word16 Search4(Word32 parcor)\n{\n  Word32 index = 0;\n  Word32 i;\n  Word32 temp;\n\n\n  for (i=0;i<16;i++) {\n    temp = L_sub(parcor, tnsCoeff4Borders[i]);\n    if (temp > 0)\n      index=i;\n  }\n  return extract_l(index - 8);\n}\n\n\n\n/*****************************************************************************\n*\n* functionname: Parcor2Index\n* description:  quantization index for reflection coefficients\n*\n*****************************************************************************/\nstatic void Parcor2Index(const Word32 parcor[],   /*!< parcor coefficients */\n                         Word16 index[],          /*!< quantized coeff indices */\n                         Word16 order,            /*!< filter order */\n                         Word16 bitsPerCoeff) {   /*!< quantizer resolution */\n  Word32 i;\n  Word32 temp;\n\n  for(i=0; i<order; i++) {\n    temp = bitsPerCoeff - 3;\n    if (temp == 0) {\n      index[i] = Search3(parcor[i]);\n    }\n    else {\n      index[i] = Search4(parcor[i]);\n    }\n  }\n}\n\n/*****************************************************************************\n*\n* functionname: Index2Parcor\n* description:  Inverse quantization for reflection coefficients\n*\n*****************************************************************************/\nstatic void Index2Parcor(const Word16 index[],  /*!< quantized values */\n                         Word32 parcor[],       /*!< ptr. to reflection coefficients (output) */\n                         Word16 order,          /*!< no. of coefficients */\n                         Word16 bitsPerCoeff)   /*!< quantizer resolution */\n{\n  Word32 i;\n  Word32 temp;\n\n  for (i=0; i<order; i++) {\n    temp = bitsPerCoeff - 4;\n    if ( temp == 0 ) {\n        parcor[i] = tnsCoeff4[index[i] + 8];\n    }\n    else {\n        parcor[i] = tnsCoeff3[index[i] + 4];\n    }\n  }\n}\n\n/*****************************************************************************\n*\n* functionname: FIRLattice\n* description:  in place lattice filtering of spectral data\n* returns:\t\tpointer to modified data\n*\n*****************************************************************************/\nstatic Word32 FIRLattice(Word16 order,           /*!< filter order */\n                         Word32 x,               /*!< spectral data */\n                         Word32 *state_par,      /*!< filter states */\n                         const Word32 *coef_par) /*!< filter coefficients */\n{\n   Word32 i;\n   Word32 accu,tmp,tmpSave;\n\n   x = x >> 1;\n   tmpSave = x;\n\n   for (i=0; i<(order - 1); i++) {\n\n     tmp = L_add(fixmul(coef_par[i], x), state_par[i]);\n     x   = L_add(fixmul(coef_par[i], state_par[i]), x);\n\n     state_par[i] = tmpSave;\n     tmpSave = tmp;\n  }\n\n  /* last stage: only need half operations */\n  accu = fixmul(state_par[order - 1], coef_par[(order - 1)]);\n  state_par[(order - 1)] = tmpSave;\n\n  x = L_add(accu, x);\n  x = L_add(x, x);\n\n  return x;\n}\n\n/*****************************************************************************\n*\n* functionname: AnalysisFilterLattice\n* description:  filters spectral lines with TNS filter\n*\n*****************************************************************************/\nstatic void AnalysisFilterLattice(const  Word32 signal[],  /*!< input spectrum */\n                                  Word16 numOfLines,       /*!< no. of lines */\n                                  const  Word32 parCoeff[],/*!< PARC coefficients */\n                                  Word16 order,            /*!< filter order */\n                                  Word32 output[])         /*!< filtered signal values */\n{\n\n  Word32 state_par[TNS_MAX_ORDER];\n  Word32 j;\n\n  for ( j=0; j<TNS_MAX_ORDER; j++ ) {\n    state_par[j] = 0;\n  }\n\n  for(j=0; j<numOfLines; j++) {\n    output[j] = FIRLattice(order,signal[j],state_par,parCoeff);\n  }\n}\n\n/*****************************************************************************\n*\n* functionname: ApplyTnsMultTableToRatios\n* description:  Change thresholds according to tns\n*\n*****************************************************************************/\nvoid ApplyTnsMultTableToRatios(Word16 startCb,\n                               Word16 stopCb,\n                               TNS_SUBBLOCK_INFO subInfo, /*!< TNS subblock info */\n                               Word32 *thresholds)        /*!< thresholds (modified) */\n{\n  Word32 i;\n  if (subInfo.tnsActive) {\n    for(i=startCb; i<stopCb; i++) {\n      /* thresholds[i] * 0.25 */\n      thresholds[i] = (thresholds[i] >> 2);\n    }\n  }\n}\n"
  },
  {
    "path": "jni/src/transform.c",
    "content": "/*\n ** Copyright 2003-2010, VisualOn, Inc.\n **\n ** Licensed under the Apache License, Version 2.0 (the \"License\");\n ** you may not use this file except in compliance with the License.\n ** You may obtain a copy of the License at\n **\n **     http://www.apache.org/licenses/LICENSE-2.0\n **\n ** Unless required by applicable law or agreed to in writing, software\n ** distributed under the License is distributed on an \"AS IS\" BASIS,\n ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ** See the License for the specific language governing permissions and\n ** limitations under the License.\n */\n/*******************************************************************************\n\tFile:\t\ttransform.c\n\n\tContent:\tMDCT Transform functionss\n\n*******************************************************************************/\n\n#include \"basic_op.h\"\n#include \"psy_const.h\"\n#include \"transform.h\"\n#include \"aac_rom.h\"\n\n\n#define LS_TRANS ((FRAME_LEN_LONG-FRAME_LEN_SHORT)/2) /* 448 */\n#define SQRT1_2 0x5a82799a\t/* sqrt(1/2) in Q31 */\n#define swap2(p0,p1) \\\n\tt = p0; t1 = *(&(p0)+1);\t\\\n\tp0 = p1; *(&(p0)+1) = *(&(p1)+1);\t\\\n\tp1 = t; *(&(p1)+1) = t1\n\n/*********************************************************************************\n*\n* function name: Shuffle\n* description:  Shuffle points prepared function for fft\n*\n**********************************************************************************/\nstatic void Shuffle(int *buf, int num, const unsigned char* bitTab)\n{\n    int *part0, *part1;\n\tint i, j;\n\tint t, t1;\n\n\tpart0 = buf;\n    part1 = buf + num;\n\n\twhile ((i = *bitTab++) != 0) {\n        j = *bitTab++;\n\n        swap2(part0[4*i+0], part0[4*j+0]);\n        swap2(part0[4*i+2], part1[4*j+0]);\n        swap2(part1[4*i+0], part0[4*j+2]);\n        swap2(part1[4*i+2], part1[4*j+2]);\n    }\n\n    do {\n        swap2(part0[4*i+2], part1[4*i+0]);\n    } while ((i = *bitTab++) != 0);\n}\n\n#if !defined(ARMV5E) && !defined(ARMV7Neon)\n\n/*****************************************************************************\n*\n* function name: Radix4First\n* description:  Radix 4 point prepared function for fft\n*\n**********************************************************************************/\nstatic void Radix4First(int *buf, int num)\n{\n    int r0, r1, r2, r3;\n\tint r4, r5, r6, r7;\n\n\tfor (; num != 0; num--)\n\t{\n\t\tr0 = buf[0] + buf[2];\n\t\tr1 = buf[1] + buf[3];\n\t\tr2 = buf[0] - buf[2];\n\t\tr3 = buf[1] - buf[3];\n\t\tr4 = buf[4] + buf[6];\n\t\tr5 = buf[5] + buf[7];\n\t\tr6 = buf[4] - buf[6];\n\t\tr7 = buf[5] - buf[7];\n\n\t\tbuf[0] = r0 + r4;\n\t\tbuf[1] = r1 + r5;\n\t\tbuf[4] = r0 - r4;\n\t\tbuf[5] = r1 - r5;\n\t\tbuf[2] = r2 + r7;\n\t\tbuf[3] = r3 - r6;\n\t\tbuf[6] = r2 - r7;\n\t\tbuf[7] = r3 + r6;\n\n\t\tbuf += 8;\n\t}\n}\n\n/*****************************************************************************\n*\n* function name: Radix8First\n* description:  Radix 8 point prepared function for fft\n*\n**********************************************************************************/\nstatic void Radix8First(int *buf, int num)\n{\n   int r0, r1, r2, r3;\n   int i0, i1, i2, i3;\n   int r4, r5, r6, r7;\n   int i4, i5, i6, i7;\n   int t0, t1, t2, t3;\n\n\tfor ( ; num != 0; num--)\n\t{\n\t\tr0 = buf[0] + buf[2];\n\t\ti0 = buf[1] + buf[3];\n\t\tr1 = buf[0] - buf[2];\n\t\ti1 = buf[1] - buf[3];\n\t\tr2 = buf[4] + buf[6];\n\t\ti2 = buf[5] + buf[7];\n\t\tr3 = buf[4] - buf[6];\n\t\ti3 = buf[5] - buf[7];\n\n\t\tr4 = (r0 + r2) >> 1;\n\t\ti4 = (i0 + i2) >> 1;\n\t\tr5 = (r0 - r2) >> 1;\n\t\ti5 = (i0 - i2) >> 1;\n\t\tr6 = (r1 - i3) >> 1;\n\t\ti6 = (i1 + r3) >> 1;\n\t\tr7 = (r1 + i3) >> 1;\n\t\ti7 = (i1 - r3) >> 1;\n\n\t\tr0 = buf[ 8] + buf[10];\n\t\ti0 = buf[ 9] + buf[11];\n\t\tr1 = buf[ 8] - buf[10];\n\t\ti1 = buf[ 9] - buf[11];\n\t\tr2 = buf[12] + buf[14];\n\t\ti2 = buf[13] + buf[15];\n\t\tr3 = buf[12] - buf[14];\n\t\ti3 = buf[13] - buf[15];\n\n\t\tt0 = (r0 + r2) >> 1;\n\t\tt1 = (i0 + i2) >> 1;\n\t\tt2 = (r0 - r2) >> 1;\n\t\tt3 = (i0 - i2) >> 1;\n\n\t\tbuf[ 0] = r4 + t0;\n\t\tbuf[ 1] = i4 + t1;\n\t\tbuf[ 8] = r4 - t0;\n\t\tbuf[ 9] = i4 - t1;\n\t\tbuf[ 4] = r5 + t3;\n\t\tbuf[ 5] = i5 - t2;\n\t\tbuf[12] = r5 - t3;\n\t\tbuf[13] = i5 + t2;\n\n\t\tr0 = r1 - i3;\n\t\ti0 = i1 + r3;\n\t\tr2 = r1 + i3;\n\t\ti2 = i1 - r3;\n\n\t\tt0 = MULHIGH(SQRT1_2, r0 - i0);\n\t\tt1 = MULHIGH(SQRT1_2, r0 + i0);\n\t\tt2 = MULHIGH(SQRT1_2, r2 - i2);\n\t\tt3 = MULHIGH(SQRT1_2, r2 + i2);\n\n\t\tbuf[ 6] = r6 - t0;\n\t\tbuf[ 7] = i6 - t1;\n\t\tbuf[14] = r6 + t0;\n\t\tbuf[15] = i6 + t1;\n\t\tbuf[ 2] = r7 + t3;\n\t\tbuf[ 3] = i7 - t2;\n\t\tbuf[10] = r7 - t3;\n\t\tbuf[11] = i7 + t2;\n\n\t\tbuf += 16;\n\t}\n}\n\n/*****************************************************************************\n*\n* function name: Radix4FFT\n* description:  Radix 4 point fft core function\n*\n**********************************************************************************/\nstatic void Radix4FFT(int *buf, int num, int bgn, int *twidTab)\n{\n\tint r0, r1, r2, r3;\n\tint r4, r5, r6, r7;\n\tint t0, t1;\n\tint sinx, cosx;\n\tint i, j, step;\n\tint *xptr, *csptr;\n\n\tfor (num >>= 2; num != 0; num >>= 2)\n\t{\n\t\tstep = 2*bgn;\n\t\txptr = buf;\n\n    \tfor (i = num; i != 0; i--)\n\t\t{\n\t\t\tcsptr = twidTab;\n\n\t\t\tfor (j = bgn; j != 0; j--)\n\t\t\t{\n\t\t\t\tr0 = xptr[0];\n\t\t\t\tr1 = xptr[1];\n\t\t\t\txptr += step;\n\n\t\t\t\tt0 = xptr[0];\n\t\t\t\tt1 = xptr[1];\n\t\t\t\tcosx = csptr[0];\n\t\t\t\tsinx = csptr[1];\n\t\t\t\tr2 = MULHIGH(cosx, t0) + MULHIGH(sinx, t1);\t\t/* cos*br + sin*bi */\n\t\t\t\tr3 = MULHIGH(cosx, t1) - MULHIGH(sinx, t0);\t\t/* cos*bi - sin*br */\n\t\t\t\txptr += step;\n\n\t\t\t\tt0 = r0 >> 2;\n\t\t\t\tt1 = r1 >> 2;\n\t\t\t\tr0 = t0 - r2;\n\t\t\t\tr1 = t1 - r3;\n\t\t\t\tr2 = t0 + r2;\n\t\t\t\tr3 = t1 + r3;\n\n\t\t\t\tt0 = xptr[0];\n\t\t\t\tt1 = xptr[1];\n\t\t\t\tcosx = csptr[2];\n\t\t\t\tsinx = csptr[3];\n\t\t\t\tr4 = MULHIGH(cosx, t0) + MULHIGH(sinx, t1);\t\t/* cos*cr + sin*ci */\n\t\t\t\tr5 = MULHIGH(cosx, t1) - MULHIGH(sinx, t0);\t\t/* cos*ci - sin*cr */\n\t\t\t\txptr += step;\n\n\t\t\t\tt0 = xptr[0];\n\t\t\t\tt1 = xptr[1];\n\t\t\t\tcosx = csptr[4];\n\t\t\t\tsinx = csptr[5];\n\t\t\t\tr6 = MULHIGH(cosx, t0) + MULHIGH(sinx, t1);\t\t/* cos*cr + sin*ci */\n\t\t\t\tr7 = MULHIGH(cosx, t1) - MULHIGH(sinx, t0);\t\t/* cos*ci - sin*cr */\n\t\t\t\tcsptr += 6;\n\n\t\t\t\tt0 = r4;\n\t\t\t\tt1 = r5;\n\t\t\t\tr4 = t0 + r6;\n\t\t\t\tr5 = r7 - t1;\n\t\t\t\tr6 = t0 - r6;\n\t\t\t\tr7 = r7 + t1;\n\n\t\t\t\txptr[0] = r0 + r5;\n\t\t\t\txptr[1] = r1 + r6;\n\t\t\t\txptr -= step;\n\n\t\t\t\txptr[0] = r2 - r4;\n\t\t\t\txptr[1] = r3 - r7;\n\t\t\t\txptr -= step;\n\n\t\t\t\txptr[0] = r0 - r5;\n\t\t\t\txptr[1] = r1 - r6;\n\t\t\t\txptr -= step;\n\n\t\t\t\txptr[0] = r2 + r4;\n\t\t\t\txptr[1] = r3 + r7;\n\t\t\t\txptr += 2;\n\t\t\t}\n\t\t\txptr += 3*step;\n\t\t}\n\t\ttwidTab += 3*step;\n\t\tbgn <<= 2;\n\t}\n}\n\n/*********************************************************************************\n*\n* function name: PreMDCT\n* description:  prepare MDCT process for next FFT compute\n*\n**********************************************************************************/\nstatic void PreMDCT(int *buf0, int num, const int *csptr)\n{\n\tint i;\n\tint tr1, ti1, tr2, ti2;\n\tint cosa, sina, cosb, sinb;\n\tint *buf1;\n\n\tbuf1 = buf0 + num - 1;\n\n\tfor(i = num >> 2; i != 0; i--)\n\t{\n\t\tcosa = *csptr++;\n\t\tsina = *csptr++;\n\t\tcosb = *csptr++;\n\t\tsinb = *csptr++;\n\n\t\ttr1 = *(buf0 + 0);\n\t\tti2 = *(buf0 + 1);\n\t\ttr2 = *(buf1 - 1);\n\t\tti1 = *(buf1 + 0);\n\n\t\t*buf0++ = MULHIGH(cosa, tr1) + MULHIGH(sina, ti1);\n\t\t*buf0++ = MULHIGH(cosa, ti1) - MULHIGH(sina, tr1);\n\n\t\t*buf1-- = MULHIGH(cosb, ti2) - MULHIGH(sinb, tr2);\n\t\t*buf1-- = MULHIGH(cosb, tr2) + MULHIGH(sinb, ti2);\n\t}\n}\n\n/*********************************************************************************\n*\n* function name: PostMDCT\n* description:   post MDCT process after next FFT for MDCT\n*\n**********************************************************************************/\nstatic void PostMDCT(int *buf0, int num, const int *csptr)\n{\n\tint i;\n\tint tr1, ti1, tr2, ti2;\n\tint cosa, sina, cosb, sinb;\n\tint *buf1;\n\n\tbuf1 = buf0 + num - 1;\n\n\tfor(i = num >> 2; i != 0; i--)\n\t{\n\t\tcosa = *csptr++;\n\t\tsina = *csptr++;\n\t\tcosb = *csptr++;\n\t\tsinb = *csptr++;\n\n\t\ttr1 = *(buf0 + 0);\n\t\tti1 = *(buf0 + 1);\n\t\tti2 = *(buf1 + 0);\n\t\ttr2 = *(buf1 - 1);\n\n\t\t*buf0++ = MULHIGH(cosa, tr1) + MULHIGH(sina, ti1);\n\t\t*buf1-- = MULHIGH(sina, tr1) - MULHIGH(cosa, ti1);\n\n\t\t*buf0++ = MULHIGH(sinb, tr2) - MULHIGH(cosb, ti2);\n\t\t*buf1-- = MULHIGH(cosb, tr2) + MULHIGH(sinb, ti2);\n\t}\n}\n#else\nvoid Radix4First(int *buf, int num);\nvoid Radix8First(int *buf, int num);\nvoid Radix4FFT(int *buf, int num, int bgn, int *twidTab);\nvoid PreMDCT(int *buf0, int num, const int *csptr);\nvoid PostMDCT(int *buf0, int num, const int *csptr);\n#endif\n\n\n/**********************************************************************************\n*\n* function name: Mdct_Long\n* description:  the long block mdct, include long_start block, end_long block\n*\n**********************************************************************************/\nvoid Mdct_Long(int *buf)\n{\n\tPreMDCT(buf, 1024, cossintab + 128);\n\n\tShuffle(buf, 512, bitrevTab + 17);\n\tRadix8First(buf, 512 >> 3);\n\tRadix4FFT(buf, 512 >> 3, 8, (int *)twidTab512);\n\n\tPostMDCT(buf, 1024, cossintab + 128);\n}\n\n\n/**********************************************************************************\n*\n* function name: Mdct_Short\n* description:  the short block mdct\n*\n**********************************************************************************/\nvoid Mdct_Short(int *buf)\n{\n\tPreMDCT(buf, 128, cossintab);\n\n\tShuffle(buf, 64, bitrevTab);\n\tRadix4First(buf, 64 >> 2);\n\tRadix4FFT(buf, 64 >> 2, 4, (int *)twidTab64);\n\n\tPostMDCT(buf, 128, cossintab);\n}\n\n\n/*****************************************************************************\n*\n* function name: shiftMdctDelayBuffer\n* description:    the mdct delay buffer has a size of 1600,\n*  so the calculation of LONG,STOP must be  spilt in two\n*  passes with 1024 samples and a mid shift,\n*  the SHORT transforms can be completed in the delay buffer,\n*  and afterwards a shift\n*\n**********************************************************************************/\nstatic void shiftMdctDelayBuffer(Word16 *mdctDelayBuffer, /*! start of mdct delay buffer */\n\t\t\t\t\t\t\t\t Word16 *timeSignal,      /*! pointer to new time signal samples, interleaved */\n\t\t\t\t\t\t\t\t Word16 chIncrement       /*! number of channels */\n\t\t\t\t\t\t\t\t )\n{\n\tWord32 i;\n\tWord16 *srBuf = mdctDelayBuffer;\n\tWord16 *dsBuf = mdctDelayBuffer+FRAME_LEN_LONG;\n\n\tfor(i = 0; i < BLOCK_SWITCHING_OFFSET-FRAME_LEN_LONG; i+= 8)\n\t{\n\t\t*srBuf++ = *dsBuf++;\t *srBuf++ = *dsBuf++;\n\t\t*srBuf++ = *dsBuf++;\t *srBuf++ = *dsBuf++;\n\t\t*srBuf++ = *dsBuf++;\t *srBuf++ = *dsBuf++;\n\t\t*srBuf++ = *dsBuf++;\t *srBuf++ = *dsBuf++;\n\t}\n\n\tsrBuf = mdctDelayBuffer + BLOCK_SWITCHING_OFFSET-FRAME_LEN_LONG;\n\tdsBuf = timeSignal;\n\n\tfor(i=0; i<FRAME_LEN_LONG; i+=8)\n\t{\n\t\t*srBuf++ = *dsBuf; dsBuf += chIncrement;\n\t\t*srBuf++ = *dsBuf; dsBuf += chIncrement;\n\t\t*srBuf++ = *dsBuf; dsBuf += chIncrement;\n\t\t*srBuf++ = *dsBuf; dsBuf += chIncrement;\n\t\t*srBuf++ = *dsBuf; dsBuf += chIncrement;\n\t\t*srBuf++ = *dsBuf; dsBuf += chIncrement;\n\t\t*srBuf++ = *dsBuf; dsBuf += chIncrement;\n\t\t*srBuf++ = *dsBuf; dsBuf += chIncrement;\n\t}\n}\n\n\n/*****************************************************************************\n*\n* function name: getScalefactorOfShortVectorStride\n* description:  Calculate max possible scale factor for input vector of shorts\n* returns:      Maximum scale factor\n*\n**********************************************************************************/\nstatic Word16 getScalefactorOfShortVectorStride(const Word16 *vector, /*!< Pointer to input vector */\n\t\t\t\t\t\t\t\t\t\t\t\tWord16 len,           /*!< Length of input vector */\n\t\t\t\t\t\t\t\t\t\t\t\tWord16 stride)        /*!< Stride of input vector */\n{\n\tWord16 maxVal = 0;\n\tWord16 absVal;\n\tWord16 i;\n\n\tfor(i=0; i<len; i++){\n\t\tabsVal = abs_s(vector[i*stride]);\n\t\tmaxVal |= absVal;\n\t}\n\n\treturn( maxVal ? norm_s(maxVal) : 15);\n}\n\n\n/*****************************************************************************\n*\n* function name: Transform_Real\n* description:  Calculate transform filter for input vector of shorts\n* returns:      TRUE if success\n*\n**********************************************************************************/\nvoid Transform_Real(Word16 *mdctDelayBuffer,\n                    Word16 *timeSignal,\n                    Word16 chIncrement,\n                    Word32 *realOut,\n                    Word16 *mdctScale,\n                    Word16 blockType\n                    )\n{\n\tWord32 i,w;\n\tWord32 timeSignalSample;\n\tWord32 ws1,ws2;\n\tWord16 *dctIn0, *dctIn1;\n\tWord32 *outData0, *outData1;\n\tWord32 *winPtr;\n\n\tWord32 delayBufferSf,timeSignalSf,minSf;\n\tWord32 headRoom=0;\n\n\tswitch(blockType){\n\n\n\tcase LONG_WINDOW:\n\t\t/*\n\t\twe access BLOCK_SWITCHING_OFFSET (1600 ) delay buffer samples + 448 new timeSignal samples\n\t\tand get the biggest scale factor for next calculate more precise\n\t\t*/\n\t\tdelayBufferSf = getScalefactorOfShortVectorStride(mdctDelayBuffer,BLOCK_SWITCHING_OFFSET,1);\n\t\ttimeSignalSf  = getScalefactorOfShortVectorStride(timeSignal,2*FRAME_LEN_LONG-BLOCK_SWITCHING_OFFSET,chIncrement);\n\t\tminSf = min(delayBufferSf,timeSignalSf);\n\t\tminSf = min(minSf,14);\n\n\t\tdctIn0 = mdctDelayBuffer;\n\t\tdctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1;\n\t\toutData0 = realOut + FRAME_LEN_LONG/2;\n\n\t\t/* add windows and pre add for mdct to last buffer*/\n\t\twinPtr = (int *)LongWindowKBD;\n\t\tfor(i=0;i<FRAME_LEN_LONG/2;i++){\n\t\t\ttimeSignalSample = (*dctIn0++) << minSf;\n\t\t\tws1 = timeSignalSample * (*winPtr >> 16);\n\t\t\ttimeSignalSample = (*dctIn1--) << minSf;\n\t\t\tws2 = timeSignalSample * (*winPtr & 0xffff);\n\t\t\twinPtr ++;\n\t\t\t/* shift 2 to avoid overflow next */\n\t\t\t*outData0++ = (ws1 >> 2) - (ws2 >> 2);\n\t\t}\n\n\t\tshiftMdctDelayBuffer(mdctDelayBuffer,timeSignal,chIncrement);\n\n\t\t/* add windows and pre add for mdct to new buffer*/\n\t\tdctIn0 = mdctDelayBuffer;\n\t\tdctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1;\n\t\toutData0 = realOut + FRAME_LEN_LONG/2 - 1;\n\t\twinPtr = (int *)LongWindowKBD;\n\t\tfor(i=0;i<FRAME_LEN_LONG/2;i++){\n\t\t\ttimeSignalSample = (*dctIn0++) << minSf;\n\t\t\tws1 = timeSignalSample * (*winPtr & 0xffff);\n\t\t\ttimeSignalSample = (*dctIn1--) << minSf;\n\t\t\tws2 = timeSignalSample * (*winPtr >> 16);\n\t\t\twinPtr++;\n\t\t\t/* shift 2 to avoid overflow next */\n\t\t\t*outData0-- = -((ws1 >> 2) + (ws2 >> 2));\n\t\t}\n\n\t\tMdct_Long(realOut);\n\t\t/* update scale factor */\n\t\tminSf = 14 - minSf;\n\t\t*mdctScale=minSf;\n\t\tbreak;\n\n\tcase START_WINDOW:\n\t\t/*\n\t\twe access BLOCK_SWITCHING_OFFSET (1600 ) delay buffer samples + no timeSignal samples\n\t\tand get the biggest scale factor for next calculate more precise\n\t\t*/\n\t\tminSf = getScalefactorOfShortVectorStride(mdctDelayBuffer,BLOCK_SWITCHING_OFFSET,1);\n\t\tminSf = min(minSf,14);\n\n\t\tdctIn0 = mdctDelayBuffer;\n\t\tdctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1;\n\t\toutData0 = realOut + FRAME_LEN_LONG/2;\n\t\twinPtr = (int *)LongWindowKBD;\n\n\t\t/* add windows and pre add for mdct to last buffer*/\n\t\tfor(i=0;i<FRAME_LEN_LONG/2;i++){\n\t\t\ttimeSignalSample = (*dctIn0++) << minSf;\n\t\t\tws1 = timeSignalSample * (*winPtr >> 16);\n\t\t\ttimeSignalSample = (*dctIn1--) << minSf;\n\t\t\tws2 = timeSignalSample * (*winPtr & 0xffff);\n\t\t\twinPtr ++;\n\t\t\t*outData0++ = (ws1 >> 2) - (ws2 >> 2);  /* shift 2 to avoid overflow next */\n\t\t}\n\n\t\tshiftMdctDelayBuffer(mdctDelayBuffer,timeSignal,chIncrement);\n\n\t\toutData0 = realOut + FRAME_LEN_LONG/2 - 1;\n\t\tfor(i=0;i<LS_TRANS;i++){\n\t\t\t*outData0-- = -mdctDelayBuffer[i] << (15 - 2 + minSf);\n\t\t}\n\n\t\t/* add windows and pre add for mdct to new buffer*/\n\t\tdctIn0 = mdctDelayBuffer + LS_TRANS;\n\t\tdctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1 - LS_TRANS;\n\t\toutData0 = realOut + FRAME_LEN_LONG/2 - 1 -LS_TRANS;\n\t\twinPtr = (int *)ShortWindowSine;\n\t\tfor(i=0;i<FRAME_LEN_SHORT/2;i++){\n\t\t\ttimeSignalSample= (*dctIn0++) << minSf;\n\t\t\tws1 = timeSignalSample * (*winPtr & 0xffff);\n\t\t\ttimeSignalSample= (*dctIn1--) << minSf;\n\t\t\tws2 = timeSignalSample * (*winPtr >> 16);\n\t\t\twinPtr++;\n\t\t\t*outData0-- =  -((ws1 >> 2) + (ws2 >> 2));  /* shift 2 to avoid overflow next */\n\t\t}\n\n\t\tMdct_Long(realOut);\n\t\t/* update scale factor */\n\t\tminSf = 14 - minSf;\n\t\t*mdctScale= minSf;\n\t\tbreak;\n\n\tcase STOP_WINDOW:\n\t\t/*\n\t\twe access BLOCK_SWITCHING_OFFSET-LS_TRANS (1600-448 ) delay buffer samples + 448 new timeSignal samples\n\t\tand get the biggest scale factor for next calculate more precise\n\t\t*/\n\t\tdelayBufferSf = getScalefactorOfShortVectorStride(mdctDelayBuffer+LS_TRANS,BLOCK_SWITCHING_OFFSET-LS_TRANS,1);\n\t\ttimeSignalSf  = getScalefactorOfShortVectorStride(timeSignal,2*FRAME_LEN_LONG-BLOCK_SWITCHING_OFFSET,chIncrement);\n\t\tminSf = min(delayBufferSf,timeSignalSf);\n\t\tminSf = min(minSf,13);\n\n\t\toutData0 = realOut + FRAME_LEN_LONG/2;\n\t\tdctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1;\n\t\tfor(i=0;i<LS_TRANS;i++){\n\t\t\t*outData0++ = -(*dctIn1--) << (15 - 2 + minSf);\n\t\t}\n\n\t\t/* add windows and pre add for mdct to last buffer*/\n\t\tdctIn0 = mdctDelayBuffer + LS_TRANS;\n\t\tdctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1 - LS_TRANS;\n\t\toutData0 = realOut + FRAME_LEN_LONG/2 + LS_TRANS;\n\t\twinPtr = (int *)ShortWindowSine;\n\t\tfor(i=0;i<FRAME_LEN_SHORT/2;i++){\n\t\t\ttimeSignalSample = (*dctIn0++) << minSf;\n\t\t\tws1 = timeSignalSample * (*winPtr >> 16);\n\t\t\ttimeSignalSample= (*dctIn1--) << minSf;\n\t\t\tws2 = timeSignalSample * (*winPtr & 0xffff);\n\t\t\twinPtr++;\n\t\t\t*outData0++ = (ws1 >> 2) - (ws2 >> 2);  /* shift 2 to avoid overflow next */\n\t\t}\n\n\t\tshiftMdctDelayBuffer(mdctDelayBuffer,timeSignal,chIncrement);\n\n\t\t/* add windows and pre add for mdct to new buffer*/\n\t\tdctIn0 = mdctDelayBuffer;\n\t\tdctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1;\n\t\toutData0 = realOut + FRAME_LEN_LONG/2 - 1;\n\t\twinPtr = (int *)LongWindowKBD;\n\t\tfor(i=0;i<FRAME_LEN_LONG/2;i++){\n\t\t\ttimeSignalSample= (*dctIn0++) << minSf;\n\t\t\tws1 = timeSignalSample *(*winPtr & 0xffff);\n\t\t\ttimeSignalSample= (*dctIn1--) << minSf;\n\t\t\tws2 = timeSignalSample * (*winPtr >> 16);\n\t\t\t*outData0-- =  -((ws1 >> 2) + (ws2 >> 2));  /* shift 2 to avoid overflow next */\n\t\t\twinPtr++;\n\t\t}\n\n\t\tMdct_Long(realOut);\n\t\tminSf = 14 - minSf;\n\t\t*mdctScale= minSf; /* update scale factor */\n\t\tbreak;\n\n\tcase SHORT_WINDOW:\n\t\t/*\n\t\twe access BLOCK_SWITCHING_OFFSET (1600 ) delay buffer samples + no new timeSignal samples\n\t\tand get the biggest scale factor for next calculate more precise\n\t\t*/\n\t\tminSf = getScalefactorOfShortVectorStride(mdctDelayBuffer+TRANSFORM_OFFSET_SHORT,9*FRAME_LEN_SHORT,1);\n\t\tminSf = min(minSf,10);\n\n\n\t\tfor(w=0;w<TRANS_FAC;w++){\n\t\t\tdctIn0 = mdctDelayBuffer+w*FRAME_LEN_SHORT+TRANSFORM_OFFSET_SHORT;\n\t\t\tdctIn1 = mdctDelayBuffer+w*FRAME_LEN_SHORT+TRANSFORM_OFFSET_SHORT + FRAME_LEN_SHORT-1;\n\t\t\toutData0 = realOut + FRAME_LEN_SHORT/2;\n\t\t\toutData1 = realOut + FRAME_LEN_SHORT/2 - 1;\n\n\t\t\twinPtr = (int *)ShortWindowSine;\n\t\t\tfor(i=0;i<FRAME_LEN_SHORT/2;i++){\n\t\t\t\ttimeSignalSample= *dctIn0 << minSf;\n\t\t\t\tws1 = timeSignalSample * (*winPtr >> 16);\n\t\t\t\ttimeSignalSample= *dctIn1 << minSf;\n\t\t\t\tws2 = timeSignalSample * (*winPtr & 0xffff);\n\t\t\t\t*outData0++ = (ws1 >> 2) - (ws2 >> 2);  /* shift 2 to avoid overflow next */\n\n\t\t\t\ttimeSignalSample= *(dctIn0 + FRAME_LEN_SHORT) << minSf;\n\t\t\t\tws1 = timeSignalSample * (*winPtr & 0xffff);\n\t\t\t\ttimeSignalSample= *(dctIn1 + FRAME_LEN_SHORT) << minSf;\n\t\t\t\tws2 = timeSignalSample * (*winPtr >> 16);\n\t\t\t\t*outData1-- =  -((ws1 >> 2) + (ws2 >> 2));  /* shift 2 to avoid overflow next */\n\n\t\t\t\twinPtr++;\n\t\t\t\tdctIn0++;\n\t\t\t\tdctIn1--;\n\t\t\t}\n\n\t\t\tMdct_Short(realOut);\n\t\t\trealOut += FRAME_LEN_SHORT;\n\t\t}\n\n\t\tminSf = 11 - minSf;\n\t\t*mdctScale = minSf; /* update scale factor */\n\n\t\tshiftMdctDelayBuffer(mdctDelayBuffer,timeSignal,chIncrement);\n\t\tbreak;\n  }\n}\n\n"
  },
  {
    "path": "local.properties",
    "content": "# This file is automatically generated by Android Tools.\n# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n#\n# This file must *NOT* be checked in Version Control Systems,\n# as it contains information specific to your local configuration.\n\n# location of the SDK. This is only used by Ant\n# For customization when using a Version Control System, please read the\n# header note.\nsdk.dir=/home/timsu/src/android-sdk\n"
  },
  {
    "path": "proguard.cfg",
    "content": "-optimizationpasses 5\n-dontusemixedcaseclassnames\n-dontskipnonpubliclibraryclasses\n-dontpreverify\n-verbose\n-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*\n\n-keep public class * extends android.app.Activity\n-keep public class * extends android.app.Application\n-keep public class * extends android.app.Service\n-keep public class * extends android.content.BroadcastReceiver\n-keep public class * extends android.content.ContentProvider\n-keep public class * extends android.app.backup.BackupAgentHelper\n-keep public class * extends android.preference.Preference\n-keep public class com.android.vending.licensing.ILicensingService\n\n-keepclasseswithmembernames class * {\n    native <methods>;\n}\n\n-keepclasseswithmembers class * {\n    public <init>(android.content.Context, android.util.AttributeSet);\n}\n\n-keepclasseswithmembers class * {\n    public <init>(android.content.Context, android.util.AttributeSet, int);\n}\n\n-keepclassmembers class * extends android.app.Activity {\n   public void *(android.view.View);\n}\n\n-keepclassmembers enum * {\n    public static **[] values();\n    public static ** valueOf(java.lang.String);\n}\n\n-keep class * implements android.os.Parcelable {\n  public static final android.os.Parcelable$Creator *;\n}\n"
  },
  {
    "path": "project.properties",
    "content": "# This file is automatically generated by Android Tools.\n# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n#\n# This file must be checked in Version Control Systems.\n#\n# To customize properties used by the Ant build system use,\n# \"ant.properties\", and override values to adapt the script to your\n# project structure.\n\n# Project target.\ntarget=android-8\n"
  },
  {
    "path": "res/layout/main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"fill_parent\"\n    android:layout_height=\"fill_parent\"\n    android:orientation=\"vertical\" >\n\n    <Button android:id=\"@+id/write\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"Record new M4A\" />\n\n    <Button android:id=\"@+id/play\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"Play Current M4A\" />\n\n    <TextView android:id=\"@+id/text\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"fill_parent\"\n        android:gravity=\"center\"\n         />\n\n</LinearLayout>"
  },
  {
    "path": "res/raw/isoparser.properties",
    "content": "hint=com.coremedia.iso.boxes.TrackReferenceTypeBox(type)\ncdsc=com.coremedia.iso.boxes.TrackReferenceTypeBox(type)\nmeta-ilst=com.coremedia.iso.boxes.apple.AppleItemListBox()\n-----name=com.coremedia.iso.boxes.apple.AppleNameBox()\n-----mean=com.coremedia.iso.boxes.apple.AppleMeanBox()\n-----data=com.coremedia.iso.boxes.apple.AppleDataBox()\nrmra=com.coremedia.iso.boxes.apple.AppleReferenceMovieBox()\nrmda=com.coremedia.iso.boxes.apple.AppleReferenceMovieDescriptorBox()\nrmdr=com.coremedia.iso.boxes.apple.AppleDataRateBox()\nrdrf=com.coremedia.iso.boxes.apple.AppleDataReferenceBox()\nilst-cprt=com.coremedia.iso.boxes.apple.AppleCopyrightBox()\nilst-\\u00A9cmt=com.coremedia.iso.boxes.apple.AppleCommentBox()\nilst-desc=com.coremedia.iso.boxes.apple.AppleDescriptionBox()\nilst-covr=com.coremedia.iso.boxes.apple.AppleCoverBox()\nilst-\\u00A9alb=com.coremedia.iso.boxes.apple.AppleAlbumBox()\nilst-\\u00A9gen=com.coremedia.iso.boxes.apple.AppleCustomGenreBox()\nilst-\\u00A9grp=com.coremedia.iso.boxes.apple.AppleGroupingBox()\nilst-\\u00A9wrt=com.coremedia.iso.boxes.apple.AppleTrackAuthorBox()\nilst-aART=com.coremedia.iso.boxes.apple.AppleAlbumArtistBox()\nilst-tvsh=com.coremedia.iso.boxes.apple.AppleShowBox()\nilst-stik=com.coremedia.iso.boxes.apple.AppleMediaTypeBox()\nilst-pgap=com.coremedia.iso.boxes.apple.AppleGaplessPlaybackBox()\nilst-tmpo=com.coremedia.iso.boxes.apple.AppleTempBox()\nilst-\\u00A9nam=com.coremedia.iso.boxes.apple.AppleTrackTitleBox()\nilst-ldes=com.coremedia.iso.boxes.apple.AppleSynopsisBox()\nilst-\\u00A9ART=com.coremedia.iso.boxes.apple.AppleArtistBox()\nilst-name=com.coremedia.iso.boxes.apple.AppleNameBox()\nilst-cpil=com.coremedia.iso.boxes.apple.AppleCompilationBox()\nilst-purd=com.coremedia.iso.boxes.apple.ApplePurchaseDateBox()\nilst-\\u00A9too=com.coremedia.iso.boxes.apple.AppleEncoderBox()\nilst-sfID=com.coremedia.iso.boxes.apple.AppleStoreCountryCodeBox()\nilst-gnre=com.coremedia.iso.boxes.apple.AppleStandardGenreBox()\nilst-tves=com.coremedia.iso.boxes.apple.AppleTvEpisodeBox()\nilst-ilst=com.coremedia.iso.boxes.apple.AppleItemListBox()\nilst-data=com.coremedia.iso.boxes.apple.AppleDataBox()\nilst-tvsn=com.coremedia.iso.boxes.apple.AppleTvSeasonBox()\nilst-soal=com.coremedia.iso.boxes.apple.AppleSortAlbumBox()\nilst-tven=com.coremedia.iso.boxes.apple.AppleTvEpisodeNumberBox()\nilst-trkn=com.coremedia.iso.boxes.apple.AppleTrackNumberBox()\nilst-\\u00A9day=com.coremedia.iso.boxes.apple.AppleRecordingYearBox()\nilst-----=com.coremedia.iso.boxes.apple.AppleGenericBox()\nilst-akID=com.coremedia.iso.boxes.apple.AppleStoreAccountTypeBox()\nilst-rtng=com.coremedia.iso.boxes.apple.AppleRatingBox()\nilst-tvnn=com.coremedia.iso.boxes.apple.AppleNetworkBox()\nilst-apID=com.coremedia.iso.boxes.apple.AppleIdBox()\nwave=com.coremedia.iso.boxes.apple.AppleWaveBox()\n\nudta-ccid=com.coremedia.iso.boxes.odf.OmaDrmContentIdBox()\nudta-yrrc=com.coremedia.iso.boxes.RecordingYearBox()\nudta-titl=com.coremedia.iso.boxes.TitleBox()\nudta-dscp=com.coremedia.iso.boxes.DescriptionBox()\nudta-icnu=com.coremedia.iso.boxes.odf.OmaDrmIconUriBox()\nudta-infu=com.coremedia.iso.boxes.odf.OmaDrmInfoUrlBox()\nudta-albm=com.coremedia.iso.boxes.AlbumBox()\nudta-cprt=com.coremedia.iso.boxes.CopyrightBox()\nudta-gnre=com.coremedia.iso.boxes.GenreBox()\nudta-perf=com.coremedia.iso.boxes.PerformerBox()\nudta-auth=com.coremedia.iso.boxes.AuthorBox()\nudta-kywd=com.coremedia.iso.boxes.KeywordsBox()\nudta-loci=com.coremedia.iso.boxes.threegpp26244.LocationInformationBox()\nudta-rtng=com.coremedia.iso.boxes.RatingBox()\nudta-clsf=com.coremedia.iso.boxes.ClassificationBox()\nudta-cdis=com.coremedia.iso.boxes.vodafone.ContentDistributorIdBox()\nudta-albr=com.coremedia.iso.boxes.vodafone.AlbumArtistBox()\nudta-cvru=com.coremedia.iso.boxes.odf.OmaDrmCoverUriBox()\nudta-lrcu=com.coremedia.iso.boxes.odf.OmaDrmLyricsUriBox()\n\n\n\n\nstsd-tx3g=com.coremedia.iso.boxes.sampleentry.TextSampleEntry(type)\nstsd-enct=com.coremedia.iso.boxes.sampleentry.TextSampleEntry(type)\nstsd-samr=com.coremedia.iso.boxes.sampleentry.AudioSampleEntry(type)\nstsd-sawb=com.coremedia.iso.boxes.sampleentry.AudioSampleEntry(type)\nstsd-mp4a=com.coremedia.iso.boxes.sampleentry.AudioSampleEntry(type)\nstsd-drms=com.coremedia.iso.boxes.sampleentry.AudioSampleEntry(type)\nstsd-alac=com.coremedia.iso.boxes.sampleentry.AudioSampleEntry(type)\nstsd-mp4s=com.coremedia.iso.boxes.sampleentry.MpegSampleEntry(type)\nstsd-owma=com.coremedia.iso.boxes.sampleentry.AudioSampleEntry(type)\nstsd-ac-3=com.coremedia.iso.boxes.sampleentry.AudioSampleEntry(type)\ndac3=com.googlecode.mp4parser.boxes.AC3SpecificBox()\nstsd-ec-3=com.coremedia.iso.boxes.sampleentry.AudioSampleEntry(type)\ndec3=com.googlecode.mp4parser.boxes.EC3SpecificBox()\nstsd-lpcm=com.coremedia.iso.boxes.sampleentry.AudioSampleEntry(type)\nstsd-dtsc=com.coremedia.iso.boxes.sampleentry.AudioSampleEntry(type)\nstsd-dtsh=com.coremedia.iso.boxes.sampleentry.AudioSampleEntry(type)\nstsd-dtsl=com.coremedia.iso.boxes.sampleentry.AudioSampleEntry(type)\nddts=com.googlecode.mp4parser.boxes.DTSSpecificBox()\nstsd-dtse=com.coremedia.iso.boxes.sampleentry.AudioSampleEntry(type)\nstsd-mlpa=com.coremedia.iso.boxes.sampleentry.AudioSampleEntry(type)\ndmlp=com.googlecode.mp4parser.boxes.MLPSpecificBox()\nstsd-enca=com.coremedia.iso.boxes.sampleentry.AudioSampleEntry(type)\nstsd-encv=com.coremedia.iso.boxes.sampleentry.VisualSampleEntry(type)\nstsd-mp4v=com.coremedia.iso.boxes.sampleentry.VisualSampleEntry(type)\nstsd-s263=com.coremedia.iso.boxes.sampleentry.VisualSampleEntry(type)\nstsd-avc1=com.coremedia.iso.boxes.sampleentry.VisualSampleEntry(type)\nstsd-ovc1=com.coremedia.iso.boxes.sampleentry.Ovc1VisualSampleEntryImpl()\nstsd-stpp=com.coremedia.iso.boxes.sampleentry.SubtitleSampleEntry(type)\navcC=com.coremedia.iso.boxes.h264.AvcConfigurationBox()\nalac=com.coremedia.iso.boxes.apple.AppleLosslessSpecificBox()\nbtrt=com.coremedia.iso.boxes.BitRateBox()\nftyp=com.coremedia.iso.boxes.FileTypeBox()\nmdat=com.coremedia.iso.boxes.mdat.MediaDataBox()\nmoov=com.coremedia.iso.boxes.MovieBox()\nmvhd=com.coremedia.iso.boxes.MovieHeaderBox()\ntrak=com.coremedia.iso.boxes.TrackBox()\ntkhd=com.coremedia.iso.boxes.TrackHeaderBox()\nedts=com.coremedia.iso.boxes.EditBox()\nelst=com.coremedia.iso.boxes.EditListBox()\nmdia=com.coremedia.iso.boxes.MediaBox()\nmdhd=com.coremedia.iso.boxes.MediaHeaderBox()\nhdlr=com.coremedia.iso.boxes.HandlerBox()\nminf=com.coremedia.iso.boxes.MediaInformationBox()\nvmhd=com.coremedia.iso.boxes.VideoMediaHeaderBox()\nsmhd=com.coremedia.iso.boxes.SoundMediaHeaderBox()\nsthd=com.coremedia.iso.boxes.SubtitleMediaHeaderBox()\nhmhd=com.coremedia.iso.boxes.HintMediaHeaderBox()\ndinf=com.coremedia.iso.boxes.DataInformationBox()\ndref=com.coremedia.iso.boxes.DataReferenceBox()\nurl\\ =com.coremedia.iso.boxes.DataEntryUrlBox()\nurn\\ =com.coremedia.iso.boxes.DataEntryUrnBox()\nstbl=com.coremedia.iso.boxes.SampleTableBox()\nctts=com.coremedia.iso.boxes.CompositionTimeToSample()\nstsd=com.coremedia.iso.boxes.SampleDescriptionBox()\nstts=com.coremedia.iso.boxes.TimeToSampleBox()\nstss=com.coremedia.iso.boxes.SyncSampleBox()\nstsc=com.coremedia.iso.boxes.SampleToChunkBox()\nstsz=com.coremedia.iso.boxes.SampleSizeBox()\nstco=com.coremedia.iso.boxes.StaticChunkOffsetBox()\nsubs=com.coremedia.iso.boxes.SubSampleInformationBox()\nsbgp=com.coremedia.iso.boxes.SampleToGroupBox()\nudta=com.coremedia.iso.boxes.UserDataBox()\nskip=com.coremedia.iso.boxes.FreeSpaceBox()\ntref=com.coremedia.iso.boxes.TrackReferenceBox()\niloc=com.coremedia.iso.boxes.ItemLocationBox()\nidat=com.coremedia.iso.boxes.ItemDataBox()\nsaio=com.coremedia.iso.boxes.SampleAuxiliaryInformationOffsetsBox()\nsaiz=com.coremedia.iso.boxes.SampleAuxiliaryInformationSizesBox()\ndamr=com.coremedia.iso.boxes.sampleentry.AmrSpecificBox()\nmeta=com.coremedia.iso.boxes.MetaBox()\nipro=com.coremedia.iso.boxes.ItemProtectionBox()\nsinf=com.coremedia.iso.boxes.ProtectionSchemeInformationBox()\nfrma=com.coremedia.iso.boxes.OriginalFormatBox()\nschi=com.coremedia.iso.boxes.SchemeInformationBox()\nodkm=com.coremedia.iso.boxes.odf.OmaDrmKeyManagenentSystemBox()\nodaf=com.coremedia.iso.boxes.OmaDrmAccessUnitFormatBox()\nschm=com.coremedia.iso.boxes.SchemeTypeBox()\nuuid=com.coremedia.iso.boxes.UserBox(userType)\nfree=com.coremedia.iso.boxes.FreeBox()\nmvex=com.coremedia.iso.boxes.fragment.MovieExtendsBox()\nmehd=com.coremedia.iso.boxes.fragment.MovieExtendsHeaderBox()\ntrex=com.coremedia.iso.boxes.fragment.TrackExtendsBox()\n\nmoof=com.coremedia.iso.boxes.fragment.MovieFragmentBox()\nmfhd=com.coremedia.iso.boxes.fragment.MovieFragmentHeaderBox()\ntraf=com.coremedia.iso.boxes.fragment.TrackFragmentBox()\ntfhd=com.coremedia.iso.boxes.fragment.TrackFragmentHeaderBox()\ntrun=com.coremedia.iso.boxes.fragment.TrackRunBox()\nsdtp=com.coremedia.iso.boxes.SampleDependencyTypeBox()\nmfra=com.coremedia.iso.boxes.fragment.MovieFragmentRandomAccessBox()\ntfra=com.coremedia.iso.boxes.fragment.TrackFragmentRandomAccessBox()\nmfro=com.coremedia.iso.boxes.fragment.MovieFragmentRandomAccessOffsetBox()\ntfdt=com.coremedia.iso.boxes.fragment.TrackFragmentBaseMediaDecodeTimeBox()\nnmhd=com.coremedia.iso.boxes.NullMediaHeaderBox()\ngmhd=com.coremedia.iso.boxes.GenericMediaHeaderBoxImpl()\ncslg=com.coremedia.iso.boxes.CompositionShiftLeastGreatestAtom()\npdin=com.coremedia.iso.boxes.ProgressiveDownloadInformationBox()\nbloc=com.googlecode.mp4parser.boxes.ultraviolet.BaseLocationBox()\nftab=com.googlecode.mp4parser.boxes.threegpp26245.FontTableBox()\nco64=com.coremedia.iso.boxes.ChunkOffset64BitBox()\nxml\\ =com.coremedia.iso.boxes.XmlBox()\navcn=com.googlecode.mp4parser.boxes.basemediaformat.AvcNalUnitStorageBox()\nainf=com.googlecode.mp4parser.boxes.ultraviolet.AssetInformationBox()\n\ntrik=com.coremedia.iso.boxes.dece.TrickPlayBox()\nuuid[A2394F525A9B4F14A2446C427C648DF4]=com.googlecode.mp4parser.boxes.piff.PiffSampleEncryptionBox()\nuuid[8974DBCE7BE74C5184F97148F9882554]=com.googlecode.mp4parser.boxes.piff.PiffTrackEncryptionBox()\nuuid[D4807EF2CA3946958E5426CB9E46A79F]=com.googlecode.mp4parser.boxes.piff.TfrfBox()\nuuid[6D1D9B0542D544E680E2141DAFF757B2]=com.googlecode.mp4parser.boxes.piff.TfxdBox()\nuuid[D08A4F1810F34A82B6C832D8ABA183D3]=com.googlecode.mp4parser.boxes.piff.UuidBasedProtectionSystemSpecificHeaderBox()\nsenc=com.googlecode.mp4parser.boxes.basemediaformat.SampleEncryptionBox()\ntenc=com.googlecode.mp4parser.boxes.basemediaformat.TrackEncryptionBox()\namf0=com.googlecode.mp4parser.boxes.adobe.ActionMessageFormat0SampleEntryBox()\n\n#iods=com.googlecode.mp4parser.boxes.mp4.ObjectDescriptorBox()\nesds=com.googlecode.mp4parser.boxes.mp4.ESDescriptorBox()\n\ntmcd=com.googlecode.mp4parser.boxes.apple.TimeCodeBox()\n\ndefault=com.coremedia.iso.boxes.UnknownBox(type)\n\n\n\n#stsd-rtp\\ =com.coremedia.iso.boxes.rtp.RtpHintSampleEntry(type)\n#udta-hnti=com.coremedia.iso.boxes.rtp.HintInformationBox()\n#udta-hinf=com.coremedia.iso.boxes.rtp.HintStatisticsBox()\n#hnti-sdp\\ =com.coremedia.iso.boxes.rtp.RtpTrackSdpHintInformationBox()\n#hnti-rtp\\ =com.coremedia.iso.boxes.rtp.RtpMovieHintInformationBox()\n#hinf-pmax=com.coremedia.iso.boxes.rtp.LargestHintPacketBox()\n#hinf-payt=com.coremedia.iso.boxes.rtp.PayloadTypeBox()\n#hinf-tmin=com.coremedia.iso.boxes.rtp.SmallestRelativeTransmissionTimeBox()\n#hinf-tmax=com.coremedia.iso.boxes.rtp.LargestRelativeTransmissionTimeBox()\n#hinf-maxr=com.coremedia.iso.boxes.rtp.MaximumDataRateBox()\n#hinf-dmax=com.coremedia.iso.boxes.rtp.LargestHintPacketDurationBox()\n#hinf-hnti=com.coremedia.iso.boxes.rtp.HintInformationBox()\n#hinf-tims=com.coremedia.iso.boxes.rtp.TimeScaleEntry()\n\n#hinf-nump=com.coremedia.iso.boxes.rtp.HintPacketsSentBox(type)\n#hinf-npck=com.coremedia.iso.boxes.rtp.HintPacketsSentBox(type)\n\n#hinf-trpy=com.coremedia.iso.boxes.rtp.HintStatisticBoxes(type)\n#hinf-totl=com.coremedia.iso.boxes.rtp.HintStatisticBoxes(type)\n#hinf-tpyl=com.coremedia.iso.boxes.rtp.HintStatisticBoxes(type)\n#hinf-tpay=com.coremedia.iso.boxes.rtp.HintStatisticBoxes(type)\n#hinf-dmed=com.coremedia.iso.boxes.rtp.HintStatisticBoxes(type)\n#hinf-dimm=com.coremedia.iso.boxes.rtp.HintStatisticBoxes(type)\n#hinf-drep=com.coremedia.iso.boxes.rtp.HintStatisticBoxes(type)\n#tims=com.coremedia.iso.boxes.rtp.TimeScaleEntry()\n\n#odrm=com.coremedia.iso.boxes.odf.OmaDrmContainerBox()\n#mdri=com.coremedia.iso.boxes.odf.MutableDrmInformationBox()\n#odtt=com.coremedia.iso.boxes.odf.OmaDrmTransactionTrackingBox()\n#odrb=com.coremedia.iso.boxes.odf.OmaDrmRightsObjectBox()\n#odhe=com.coremedia.iso.boxes.odf.OmaDrmDiscreteHeadersBox()\n#odda=com.coremedia.iso.boxes.odf.OmaDrmContentObjectBox()\n#ohdr=com.coremedia.iso.boxes.odf.OmaDrmCommonHeadersBox()\n#grpi=com.coremedia.iso.boxes.odf.OmaDrmGroupIdBox()\n"
  },
  {
    "path": "res/values/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n    <string name=\"hello\">Hello World, Main!</string>\n    <string name=\"app_name\">AAC Encoder</string>\n\n</resources>"
  },
  {
    "path": "src/com/coremedia/iso/AbstractBoxParser.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.coremedia.iso;\n\nimport com.coremedia.iso.boxes.Box;\nimport com.coremedia.iso.boxes.ContainerBox;\nimport com.coremedia.iso.boxes.UserBox;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.channels.FileChannel;\nimport java.nio.channels.ReadableByteChannel;\nimport java.util.logging.Logger;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\n/**\n * This BoxParser handles the basic stuff like reading size and extracting box type.\n */\npublic abstract class AbstractBoxParser implements BoxParser {\n\n    private static Logger LOG = Logger.getLogger(AbstractBoxParser.class.getName());\n\n    public abstract Box createBox(String type, byte[] userType, String parent);\n\n    /**\n     * Parses the next size and type, creates a box instance and parses the box's content.\n     *\n     * @param byteChannel the FileChannel pointing to the ISO file\n     * @param parent      the current box's parent (null if no parent)\n     * @return the box just parsed\n     * @throws java.io.IOException if reading from <code>in</code> fails\n     */\n    public Box parseBox(ReadableByteChannel byteChannel, ContainerBox parent) throws IOException {\n\n\n        ByteBuffer header = ChannelHelper.readFully(byteChannel, 8);\n\n        long size = IsoTypeReader.readUInt32(header);\n        // do plausibility check\n        if (size < 8 && size > 1) {\n            LOG.severe(\"Plausibility check failed: size < 8 (size = \" + size + \"). Stop parsing!\");\n            return null;\n        }\n\n\n        String type = IsoTypeReader.read4cc(header);\n        byte[] usertype = null;\n        long contentSize;\n\n        if (size == 1) {\n            ByteBuffer bb = ByteBuffer.allocate(8);\n            byteChannel.read(bb);\n            bb.rewind();\n            size = IsoTypeReader.readUInt64(bb);\n            contentSize = size - 16;\n        } else if (size == 0) {\n            if (byteChannel instanceof FileChannel) {\n                size = ((FileChannel) byteChannel).size() - ((FileChannel) byteChannel).position() - 8;\n            } else {\n                throw new RuntimeException(\"Only FileChannel inputs may use size == 0 (box reaches to the end of file)\");\n            }\n            contentSize = size - 8;\n        } else {\n            contentSize = size - 8;\n        }\n        if (UserBox.TYPE.equals(type)) {\n            ByteBuffer bb = ByteBuffer.allocate(16);\n            byteChannel.read(bb);\n            bb.rewind();\n            usertype = bb.array();\n            contentSize -= 16;\n        }\n        Box box = createBox(type, usertype, parent.getType());\n        box.setParent(parent);\n        LOG.finest(\"Parsing \" + box.getType());\n        // System.out.println(\"parsing \" + Arrays.toString(box.getType()) + \" \" + box.getClass().getName() + \" size=\" + size);\n\n\n        if (l2i(size - contentSize) == 8) {\n            // default - no large box - no uuid\n            // do nothing header's already correct\n            header.rewind();\n        } else if (l2i(size - contentSize) == 16) {\n            header = ByteBuffer.allocate(16);\n            IsoTypeWriter.writeUInt32(header, 1);\n            header.put(IsoFile.fourCCtoBytes(type));\n            IsoTypeWriter.writeUInt64(header, size);\n        } else if (l2i(size - contentSize) == 24) {\n            header = ByteBuffer.allocate(24);\n            IsoTypeWriter.writeUInt32(header, size);\n            header.put(IsoFile.fourCCtoBytes(type));\n            header.put(usertype);\n        } else if (l2i(size - contentSize) == 32) {\n            header = ByteBuffer.allocate(32);\n            IsoTypeWriter.writeUInt32(header, size);\n            header.put(IsoFile.fourCCtoBytes(type));\n            IsoTypeWriter.writeUInt64(header, size);\n            header.put(usertype);\n        } else {\n            throw new RuntimeException(\"I didn't expect that\");\n        }\n\n\n        box.parse(byteChannel, header, contentSize, this);\n        // System.out.println(\"box = \" + box);\n\n\n        assert size == box.getSize() :\n                \"Reconstructed Size is not x to the number of parsed bytes! (\" +\n                        box.getType() + \")\"\n                        + \" Actual Box size: \" + size + \" Calculated size: \" + box.getSize();\n        return box;\n    }\n\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/Ascii.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.coremedia.iso;\n\nimport java.io.UnsupportedEncodingException;\n\n/**\n * Converts <code>byte[]</code> -> <code>String</code> and vice versa.\n */\npublic final class Ascii {\n  public static byte[] convert(String s) {\n    try {\n      if (s != null) {\n        return s.getBytes(\"us-ascii\");\n      } else {\n        return null;\n      }\n    } catch (UnsupportedEncodingException e) {\n      throw new Error(e);\n    }\n  }\n\n  public static String convert(byte[] b) {\n    try {\n      if (b != null) {\n        return new String(b, \"us-ascii\");\n      } else {\n        return null;\n      }\n    } catch (UnsupportedEncodingException e) {\n      throw new Error(e);\n    }\n  }\n}"
  },
  {
    "path": "src/com/coremedia/iso/BoxParser.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.coremedia.iso;\n\nimport com.coremedia.iso.boxes.Box;\nimport com.coremedia.iso.boxes.ContainerBox;\n\nimport java.io.IOException;\nimport java.nio.channels.ReadableByteChannel;\n\n/**\n * Basic interface to create boxes from a <code>IsoBufferWrapper</code> and its parent.\n */\npublic interface BoxParser {\n    Class<? extends Box> getClassForFourCc(String type, byte[] userType, String parent);\n\n    Box parseBox(ReadableByteChannel in, ContainerBox parent) throws IOException;\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/ChannelHelper.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.coremedia.iso;\n\nimport java.io.EOFException;\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.channels.FileChannel;\nimport java.nio.channels.ReadableByteChannel;\nimport java.nio.channels.SelectionKey;\nimport java.nio.channels.WritableByteChannel;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\n\npublic class ChannelHelper {\n    public static ByteBuffer readFully(final ReadableByteChannel channel, long size) throws IOException {\n\n        if (channel instanceof FileChannel && size > 1024 * 1024) {\n            ByteBuffer bb = ((FileChannel) channel).map(FileChannel.MapMode.READ_ONLY, ((FileChannel) channel).position(), size);\n            ((FileChannel) channel).position(((FileChannel) channel).position() + size);\n            return bb;\n        } else {\n            ByteBuffer buf = ByteBuffer.allocate(l2i(size));\n            readFully(channel, buf, buf.limit());\n            buf.rewind();\n            assert buf.limit() == size;\n\n            return buf;\n        }\n\n    }\n\n\n    public static void readFully(final ReadableByteChannel channel, final ByteBuffer buf)\n            throws IOException {\n        readFully(channel, buf, buf.remaining());\n    }\n\n    public static int readFully(final ReadableByteChannel channel, final ByteBuffer buf, final int length)\n            throws IOException {\n        int n, count = 0;\n        while (-1 != (n = channel.read(buf))) {\n            count += n;\n            if (count == length) {\n                break;\n            }\n        }\n        if (n == -1) {\n            throw new EOFException(\"End of file. No more boxes.\");\n        }\n        return count;\n    }\n\n\n    public static void writeFully(final WritableByteChannel channel, final ByteBuffer buf)\n            throws IOException {\n        do {\n            int written = channel.write(buf);\n            if (written < 0) {\n                throw new EOFException();\n            }\n        } while (buf.hasRemaining());\n    }\n\n\n    public static void close(SelectionKey key) {\n        try {\n            key.channel().close();\n        } catch (IOException e) {\n            // nop\n        }\n\n    }\n\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/Hex.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\nExtracted from commons-codec\n */\npackage com.coremedia.iso;\n\nimport java.io.ByteArrayOutputStream;\n\n/**\n * Converts hexadecimal Strings.\n */\npublic class Hex {\n    private static final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};\n\n    public static String encodeHex(byte[] data) {\n        int l = data.length;\n        char[] out = new char[l << 1];\n        // two characters form the hex value.\n        for (int i = 0, j = 0; i < l; i++) {\n            out[j++] = DIGITS[(0xF0 & data[i]) >>> 4];\n            out[j++] = DIGITS[0x0F & data[i]];\n        }\n        return new String(out);\n    }\n\n    public static byte[] decodeHex(String hexString) {\n        ByteArrayOutputStream bas = new ByteArrayOutputStream();\n        for (int i = 0; i < hexString.length(); i += 2) {\n            int b = Integer.parseInt(hexString.substring(i, i + 2), 16);\n            bas.write(b);\n        }\n        return bas.toByteArray();\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/IsoFile.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso;\n\nimport com.googlecode.mp4parser.AbstractContainerBox;\nimport com.coremedia.iso.boxes.Box;\nimport com.coremedia.iso.boxes.MovieBox;\nimport com.googlecode.mp4parser.annotations.DoNotParseDetail;\n\nimport java.io.EOFException;\nimport java.io.IOException;\nimport java.io.UnsupportedEncodingException;\nimport java.nio.ByteBuffer;\nimport java.nio.channels.FileChannel;\nimport java.nio.channels.ReadableByteChannel;\nimport java.nio.channels.WritableByteChannel;\n\n/**\n * The most upper container for ISO Boxes. It is a container box that is a file.\n * Uses IsoBufferWrapper  to access the underlying file.\n */\n@DoNotParseDetail\npublic class IsoFile extends AbstractContainerBox {\n    protected BoxParser boxParser = new PropertyBoxParserImpl();\n    ReadableByteChannel byteChannel;\n\n    public IsoFile() {\n        super(\"\");\n    }\n\n    public IsoFile(ReadableByteChannel byteChannel) throws IOException {\n        super(\"\");\n        this.byteChannel = byteChannel;\n        boxParser = createBoxParser();\n        parse();\n    }\n\n    public IsoFile(ReadableByteChannel byteChannel, BoxParser boxParser) throws IOException {\n        super(\"\");\n        this.byteChannel = byteChannel;\n        this.boxParser = boxParser;\n        parse();\n\n\n    }\n\n    protected BoxParser createBoxParser() {\n        return new PropertyBoxParserImpl();\n    }\n\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        // there are no details to parse we should be just file\n    }\n\n    public void parse(ReadableByteChannel inFC, ByteBuffer header, long contentSize, AbstractBoxParser abstractBoxParser) throws IOException {\n        throw new IOException(\"This method is not meant to be called. Use #parse() directly.\");\n    }\n\n    private void parse() throws IOException {\n\n        boolean done = false;\n        while (!done) {\n            try {\n                Box box = boxParser.parseBox(byteChannel, this);\n                if (box != null) {\n                    //  System.err.println(box.getType());\n                    boxes.add(box);\n                } else {\n                    done = true;\n                }\n            } catch (EOFException e) {\n                done = true;\n            }\n        }\n    }\n\n    @DoNotParseDetail\n    public String toString() {\n        StringBuilder buffer = new StringBuilder();\n        buffer.append(\"IsoFile[\");\n        if (boxes == null) {\n            buffer.append(\"unparsed\");\n        } else {\n            for (int i = 0; i < boxes.size(); i++) {\n                if (i > 0) {\n                    buffer.append(\";\");\n                }\n                buffer.append(boxes.get(i).toString());\n            }\n        }\n        buffer.append(\"]\");\n        return buffer.toString();\n    }\n\n    @DoNotParseDetail\n    public static byte[] fourCCtoBytes(String fourCC) {\n        byte[] result = new byte[4];\n        if (fourCC != null) {\n            for (int i = 0; i < Math.min(4, fourCC.length()); i++) {\n                result[i] = (byte) fourCC.charAt(i);\n            }\n        }\n        return result;\n    }\n\n    @DoNotParseDetail\n    public static String bytesToFourCC(byte[] type) {\n        byte[] result = new byte[]{0, 0, 0, 0};\n        if (type != null) {\n            System.arraycopy(type, 0, result, 0, Math.min(type.length, 4));\n        }\n        try {\n            return new String(result, \"ISO-8859-1\");\n        } catch (UnsupportedEncodingException e) {\n            throw new Error(\"Required character encoding is missing\", e);\n        }\n    }\n\n\n    @Override\n    public long getNumOfBytesToFirstChild() {\n        return 0;\n    }\n\n    @Override\n    public long getSize() {\n        long size = 0;\n        for (Box box : boxes) {\n            size += box.getSize();\n        }\n        return size;\n    }\n\n    @Override\n    public IsoFile getIsoFile() {\n        return this;\n    }\n\n\n    /**\n     * Shortcut to get the MovieBox since it is often needed and present in\n     * nearly all ISO 14496 files (at least if they are derived from MP4 ).\n     *\n     * @return the MovieBox or <code>null</code>\n     */\n    @DoNotParseDetail\n    public MovieBox getMovieBox() {\n        for (Box box : boxes) {\n            if (box instanceof MovieBox) {\n                return (MovieBox) box;\n            }\n        }\n        return null;\n    }\n\n    public void getBox(WritableByteChannel os) throws IOException {\n        for (Box box : boxes) {\n\n            if (os instanceof FileChannel) {\n                long startPos = ((FileChannel) os).position();\n                box.getBox(os);\n                long size = ((FileChannel) os).position() - startPos;\n                assert size == box.getSize();\n            } else {\n                box.getBox(os);\n            }\n\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/IsoFileConvenienceHelper.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.coremedia.iso;\n\nimport com.coremedia.iso.boxes.Box;\nimport com.coremedia.iso.boxes.ContainerBox;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\n/**\n * A fine selection of useful methods.\n *\n * @author Andre John Mas\n * @author Sebastian Annies\n * @deprecated please use {@link com.googlecode.mp4parser.util.Path}. I will remove that class before 1.0.\n */\npublic class IsoFileConvenienceHelper {\n\n\n    public static Box get(ContainerBox containerBox, String path) {\n\n        String[] parts = path.split(\"/\");\n        if (parts.length == 0) {\n            return null;\n        }\n\n        List<String> partList = new ArrayList<String>(Arrays.asList(parts));\n\n        if (\"\".equals(partList.get(0))) {\n            partList.remove(0);\n        }\n\n        if (partList.size() > 0) {\n            return get((List<Box>) containerBox.getBoxes(), partList);\n        }\n        return null;\n    }\n\n    private static Box get(List<Box> boxes, List<String> path) {\n\n\n        String typeInPath = path.remove(0);\n\n        for (Box box : boxes) {\n            if (box instanceof ContainerBox) {\n                ContainerBox boxContainer = (ContainerBox) box;\n                String type = boxContainer.getType();\n\n                if (typeInPath.equals(type)) {\n                    List<Box> children = boxContainer.getBoxes();\n                    if (path.size() > 0) {\n                        if (children.size() > 0) {\n                            return get(children, path);\n                        }\n                    } else {\n                        return box;\n                    }\n                }\n\n            } else {\n                String type = box.getType();\n\n                if (path.size() == 0 && typeInPath.equals(type)) {\n                    return box;\n                }\n\n            }\n\n        }\n\n        return null;\n    }\n}\n\n"
  },
  {
    "path": "src/com/coremedia/iso/IsoTypeReader.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.coremedia.iso;\n\nimport java.io.ByteArrayOutputStream;\nimport java.nio.ByteBuffer;\n\npublic final class IsoTypeReader {\n\n\n    public static long readUInt32BE(ByteBuffer bb) {\n        long ch1 = readUInt8(bb);\n        long ch2 = readUInt8(bb);\n        long ch3 = readUInt8(bb);\n        long ch4 = readUInt8(bb);\n        return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0));\n\n    }\n\n\n    public static long readUInt32(ByteBuffer bb) {\n        long ch1 = readUInt8(bb);\n        long ch2 = readUInt8(bb);\n        long ch3 = readUInt8(bb);\n        long ch4 = readUInt8(bb);\n        return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));\n\n    }\n\n    public static int readUInt24(ByteBuffer bb) {\n        int result = 0;\n        result += readUInt16(bb) << 8;\n        result += byte2int(bb.get());\n        return result;\n    }\n\n\n    public static int readUInt16(ByteBuffer bb) {\n        int result = 0;\n        result += byte2int(bb.get()) << 8;\n        result += byte2int(bb.get());\n        return result;\n    }\n\n    public static int readUInt16BE(ByteBuffer bb) {\n        int result = 0;\n        result += byte2int(bb.get());\n        result += byte2int(bb.get()) << 8;\n        return result;\n    }\n\n    public static int readUInt8(ByteBuffer bb) {\n        return byte2int(bb.get());\n    }\n\n    public static int byte2int(byte b) {\n        return b < 0 ? b + 256 : b;\n    }\n\n\n    /**\n     * Reads a zero terminated UTF-8 string.\n     *\n     * @param byteBuffer the data source\n     * @return the string readByte\n     * @throws Error in case of an error in the underlying stream\n     */\n    public static String readString(ByteBuffer byteBuffer) {\n\n        ByteArrayOutputStream out = new ByteArrayOutputStream();\n        int read;\n        while ((read = byteBuffer.get()) != 0) {\n            out.write(read);\n        }\n        return Utf8.convert(out.toByteArray());\n    }\n\n    public static String readString(ByteBuffer byteBuffer, int length) {\n        byte[] buffer = new byte[length];\n        byteBuffer.get(buffer);\n        return Utf8.convert(buffer);\n\n    }\n\n    public static long readUInt64(ByteBuffer byteBuffer) {\n        long result = 0;\n        // thanks to Erik Nicolas for finding a bug! Cast to long is definitivly needed\n        result += readUInt32(byteBuffer) << 32;\n        if (result < 0) {\n            throw new RuntimeException(\"I don't know how to deal with UInt64! long is not sufficient and I don't want to use BigInt\");\n        }\n        result += readUInt32(byteBuffer);\n\n        return result;\n    }\n\n    public static double readFixedPoint1616(ByteBuffer bb) {\n        byte[] bytes = new byte[4];\n        bb.get(bytes);\n\n        int result = 0;\n        result |= ((bytes[0] << 24) & 0xFF000000);\n        result |= ((bytes[1] << 16) & 0xFF0000);\n        result |= ((bytes[2] << 8) & 0xFF00);\n        result |= ((bytes[3]) & 0xFF);\n        return ((double) result) / 65536;\n\n    }\n\n    public static float readFixedPoint88(ByteBuffer bb) {\n        byte[] bytes = new byte[2];\n        bb.get(bytes);\n        short result = 0;\n        result |= ((bytes[0] << 8) & 0xFF00);\n        result |= ((bytes[1]) & 0xFF);\n        return ((float) result) / 256;\n    }\n\n    public static String readIso639(ByteBuffer bb) {\n        int bits = readUInt16(bb);\n        StringBuilder result = new StringBuilder();\n        for (int i = 0; i < 3; i++) {\n            int c = (bits >> (2 - i) * 5) & 0x1f;\n            result.append((char) (c + 0x60));\n        }\n        return result.toString();\n    }\n\n    public static String read4cc(ByteBuffer bb) {\n        byte[] b = new byte[4];\n        bb.get(b);\n        return IsoFile.bytesToFourCC(b);\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/IsoTypeReaderVariable.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.coremedia.iso;\n\nimport java.nio.ByteBuffer;\n\npublic final class IsoTypeReaderVariable {\n\n    public static long read(ByteBuffer bb, int bytes) {\n        switch (bytes) {\n            case 1:\n                return IsoTypeReader.readUInt8(bb);\n            case 2:\n                return IsoTypeReader.readUInt16(bb);\n            case 3:\n                return IsoTypeReader.readUInt24(bb);\n            case 4:\n                return IsoTypeReader.readUInt32(bb);\n            case 8:\n                return IsoTypeReader.readUInt64(bb);\n            default:\n                throw new RuntimeException(\"I don't know how to read \" + bytes + \" bytes\");\n        }\n\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/IsoTypeWriter.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.coremedia.iso;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\n\npublic final class IsoTypeWriter {\n\n    public static void writeUInt64(ByteBuffer bb, long u) {\n\n        writeUInt32(bb, ((u >> 32) & 0xFFFFFFFFl));\n        writeUInt32(bb, u & 0xFFFFFFFFl);\n\n    }\n\n    public static void writeUInt32(ByteBuffer bb, long u) {\n        assert u >= 0 && u <= 1L << 32 : \"The given long is not in the range of uint32 (\" + u + \")\";\n        writeUInt16(bb, (int) ((u >> 16) & 0xFFFF));\n        writeUInt16(bb, (int) u & 0xFFFF);\n\n    }\n\n    public static void writeUInt32BE(ByteBuffer bb, long u) {\n        assert u >= 0 && u <= 1L << 32 : \"The given long is not in the range of uint32 (\" + u + \")\";\n        writeUInt16BE(bb, (int) u & 0xFFFF);\n        writeUInt16BE(bb, (int) ((u >> 16) & 0xFFFF));\n\n    }\n\n\n    public static void writeUInt24(ByteBuffer bb, int i) {\n        i = i & 0xFFFFFF;\n        writeUInt16(bb, i >> 8);\n        writeUInt8(bb, i);\n\n    }\n\n\n    public static void writeUInt16(ByteBuffer bb, int i) {\n        i = i & 0xFFFF;\n        writeUInt8(bb, i >> 8);\n        writeUInt8(bb, i & 0xFF);\n    }\n\n    public static void writeUInt16BE(ByteBuffer bb, int i) {\n        i = i & 0xFFFF;\n        writeUInt8(bb, i & 0xFF);\n        writeUInt8(bb, i >> 8);\n    }\n\n    public static void writeUInt8(ByteBuffer bb, int i) {\n        bb.put(int2byte(i));\n    }\n\n\n    public static void writeFixedPont1616(ByteBuffer bb, double v) {\n        int result = (int) (v * 65536);\n        bb.put((byte) ((result & 0xFF000000) >> 24));\n        bb.put((byte) ((result & 0x00FF0000) >> 16));\n        bb.put((byte) ((result & 0x0000FF00) >> 8));\n        bb.put((byte) ((result & 0x000000FF)));\n    }\n\n    public static void writeFixedPont88(ByteBuffer bb, double v) {\n        short result = (short) (v * 256);\n        bb.put((byte) ((result & 0xFF00) >> 8));\n        bb.put((byte) ((result & 0x00FF)));\n    }\n\n    public static byte int2byte(int i) {\n        i = i & 0xFF;\n        return (byte) (i > 127 ? i - 256 : i);\n    }\n\n    public static void writeIso639(ByteBuffer bb, String language) {\n        int bits = 0;\n        for (int i = 0; i < 3; i++) {\n            bits += (language.getBytes()[i] - 0x60) << (2 - i) * 5;\n        }\n        writeUInt16(bb, bits);\n    }\n\n    public static void writeUtf8String(ByteBuffer bb, String string) {\n\n        bb.put(Utf8.convert(string));\n        writeUInt8(bb, 0);\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/IsoTypeWriterVariable.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.coremedia.iso;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\n\npublic final class IsoTypeWriterVariable {\n\n    public static void write(long v, ByteBuffer bb, int bytes) {\n        switch (bytes) {\n            case 1:\n                IsoTypeWriter.writeUInt8(bb, (int) (v & 0xff));\n                break;\n            case 2:\n                IsoTypeWriter.writeUInt16(bb, (int) (v & 0xffff));\n                break;\n            case 3:\n                IsoTypeWriter.writeUInt24(bb, (int) (v & 0xffffff));\n                break;\n            case 4:\n                IsoTypeWriter.writeUInt32(bb, v);\n                break;\n            case 8:\n                IsoTypeWriter.writeUInt64(bb, v);\n                break;\n            default:\n                throw new RuntimeException(\"I don't know how to read \" + bytes + \" bytes\");\n        }\n\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/PropertyBoxParserImpl.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.coremedia.iso;\n\nimport java.io.BufferedInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.InvocationTargetException;\nimport java.net.URL;\nimport java.util.Enumeration;\nimport java.util.Properties;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport android.content.Context;\n\nimport com.coremedia.iso.boxes.Box;\nimport com.googlecode.mp4parser.AbstractBox;\nimport com.todoroo.aacenc.AACToM4A;\nimport com.todoroo.aacenc.R;\n\n/**\n * A Property file based BoxFactory\n */\npublic class PropertyBoxParserImpl extends AbstractBoxParser {\n    Properties mapping;\n\n    public PropertyBoxParserImpl(String... customProperties) {\n        Context context = AACToM4A.getContext();\n        InputStream raw = null, is = null;\n        mapping = new Properties();\n        try {\n            raw = context.getResources().openRawResource(R.raw.isoparser);\n            is = new BufferedInputStream(raw);\n            mapping.load(is);\n            Enumeration<URL> enumeration = Thread.currentThread().getContextClassLoader().getResources(\"isoparser-custom.properties\");\n\n            while (enumeration.hasMoreElements()) {\n                URL url = enumeration.nextElement();\n                InputStream customIS = new BufferedInputStream(url.openStream());\n                try {\n                    mapping.load(customIS);\n                } finally {\n                    customIS.close();\n                }\n            }\n            for (String customProperty : customProperties) {\n                mapping.load(new BufferedInputStream(getClass().getResourceAsStream(customProperty)));\n            }\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        } finally {\n            try {\n                if(raw != null)\n                    raw.close();\n                if(is != null)\n                    is.close();\n            } catch (IOException e) {\n                e.printStackTrace();\n                // ignore - I can't help\n            }\n        }\n    }\n\n    public PropertyBoxParserImpl(Properties mapping) {\n        this.mapping = mapping;\n    }\n\n    Pattern p = Pattern.compile(\"(.*)\\\\((.*?)\\\\)\");\n\n    @SuppressWarnings(\"unchecked\")\n    public Class<? extends Box> getClassForFourCc(String type, byte[] userType, String parent) {\n        FourCcToBox fourCcToBox = new FourCcToBox(type, userType, parent).invoke();\n        try {\n            return (Class<? extends Box>) Class.forName(fourCcToBox.clazzName);\n        } catch (ClassNotFoundException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    @Override\n    public Box createBox(String type, byte[] userType, String parent) {\n\n        FourCcToBox fourCcToBox = new FourCcToBox(type, userType, parent).invoke();\n        String[] param = fourCcToBox.getParam();\n        String clazzName = fourCcToBox.getClazzName();\n        try {\n            if (param[0].trim().length() == 0) {\n                param = new String[]{};\n            }\n            Class clazz = Class.forName(clazzName);\n\n            Class[] constructorArgsClazz = new Class[param.length];\n            Object[] constructorArgs = new Object[param.length];\n            for (int i = 0; i < param.length; i++) {\n\n                if (\"userType\".equals(param[i])) {\n                    constructorArgs[i] = userType;\n                    constructorArgsClazz[i] = byte[].class;\n                } else if (\"type\".equals(param[i])) {\n                    constructorArgs[i] = type;\n                    constructorArgsClazz[i] = String.class;\n                } else if (\"parent\".equals(param[i])) {\n                    constructorArgs[i] = parent;\n                    constructorArgsClazz[i] = String.class;\n                } else {\n                    throw new InternalError(\"No such param: \" + param[i]);\n                }\n\n\n            }\n            Constructor<AbstractBox> constructorObject;\n            try {\n                if (param.length > 0) {\n                    constructorObject = clazz.getConstructor(constructorArgsClazz);\n                } else {\n                    constructorObject = clazz.getConstructor();\n                }\n\n                return constructorObject.newInstance(constructorArgs);\n            } catch (NoSuchMethodException e) {\n                throw new RuntimeException(e);\n            } catch (InvocationTargetException e) {\n                throw new RuntimeException(e);\n            } catch (InstantiationException e) {\n                throw new RuntimeException(e);\n            } catch (IllegalAccessException e) {\n                throw new RuntimeException(e);\n            }\n\n\n        } catch (ClassNotFoundException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    private class FourCcToBox {\n        private String type;\n        private byte[] userType;\n        private String parent;\n        private String clazzName;\n        private String[] param;\n\n        public FourCcToBox(String type, byte[] userType, String parent) {\n            this.type = type;\n            this.parent = parent;\n            this.userType = userType;\n        }\n\n        public String getClazzName() {\n            return clazzName;\n        }\n\n        public String[] getParam() {\n            return param;\n        }\n\n        public FourCcToBox invoke() {\n            String constructor;\n            if (userType != null) {\n                if (!\"uuid\".equals((type))) {\n                    throw new RuntimeException(\"we have a userType but no uuid box type. Something's wrong\");\n                }\n                constructor = mapping.getProperty((parent) + \"-uuid[\" + Hex.encodeHex(userType).toUpperCase() + \"]\");\n                if (constructor == null) {\n                    constructor = mapping.getProperty(\"uuid[\" + Hex.encodeHex(userType).toUpperCase() + \"]\");\n                }\n                if (constructor == null) {\n                    constructor = mapping.getProperty(\"uuid\");\n                }\n            } else {\n                constructor = mapping.getProperty((parent) + \"-\" + (type));\n                if (constructor == null) {\n                    constructor = mapping.getProperty((type));\n                }\n            }\n            if (constructor == null) {\n                constructor = mapping.getProperty(\"default\");\n            }\n            if (constructor == null) {\n                throw new RuntimeException(\"No box object found for \" + type);\n            }\n            Matcher m = p.matcher(constructor);\n            boolean matches = m.matches();\n            if (!matches) {\n                throw new RuntimeException(\"Cannot work with that constructor: \" + constructor);\n            }\n            clazzName = m.group(1);\n            param = m.group(2).split(\",\");\n            return this;\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/Utf8.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.coremedia.iso;\n\nimport java.io.UnsupportedEncodingException;\n\n/**\n * Converts <code>byte[]</code> -> <code>String</code> and vice versa.\n */\npublic final class Utf8 {\n    public static byte[] convert(String s) {\n        try {\n            if (s != null) {\n                return s.getBytes(\"UTF-8\");\n            } else {\n                return null;\n            }\n        } catch (UnsupportedEncodingException e) {\n            throw new Error(e);\n        }\n    }\n\n    public static String convert(byte[] b) {\n        try {\n            if (b != null) {\n                return new String(b, \"UTF-8\");\n            } else {\n                return null;\n            }\n        } catch (UnsupportedEncodingException e) {\n            throw new Error(e);\n        }\n    }\n\n    public static int utf8StringLengthInBytes(String utf8) {\n        try {\n            if (utf8 != null) {\n                return utf8.getBytes(\"UTF-8\").length;\n            } else {\n                return 0;\n            }\n        } catch (UnsupportedEncodingException e) {\n            throw new RuntimeException();\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/AbstractMediaHeaderBox.java",
    "content": "/*\n * Copyright 2011 Sebastian Annies, Hamburg, Germany\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.googlecode.mp4parser.AbstractFullBox;\n\n/**\n * A common superclass for all MediaInformationHeaderBoxes. E.g.\n * VideoMediaHeaderBox, SoundMediaHeaderBox & HintMediaHeaderBox\n */\npublic abstract class AbstractMediaHeaderBox extends AbstractFullBox {\n    protected AbstractMediaHeaderBox(String type) {\n        super(type);\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/AlbumBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Meta information in a 'udta' box about a track.\n * Defined in 3GPP 26.244.\n *\n * @see com.coremedia.iso.boxes.UserDataBox\n */\npublic class AlbumBox extends AbstractFullBox {\n    public static final String TYPE = \"albm\";\n\n    private String language;\n    private String albumTitle;\n    private int trackNumber;\n\n    public AlbumBox() {\n        super(TYPE);\n    }\n\n    /**\n     * Declares the language code for the {@link #getAlbumTitle()} return value. See ISO 639-2/T for the set of three\n     * character codes.Each character is packed as the difference between its ASCII value and 0x60. The code is\n     * confined to being three lower-case letters, so these values are strictly positive.\n     *\n     * @return the language code\n     */\n    public String getLanguage() {\n        return language;\n    }\n\n    public String getAlbumTitle() {\n        return albumTitle;\n    }\n\n    public int getTrackNumber() {\n        return trackNumber;\n    }\n\n    public void setLanguage(String language) {\n        this.language = language;\n    }\n\n    public void setAlbumTitle(String albumTitle) {\n        this.albumTitle = albumTitle;\n    }\n\n    public void setTrackNumber(int trackNumber) {\n        this.trackNumber = trackNumber;\n    }\n\n    protected long getContentSize() {\n        return 6 + Utf8.utf8StringLengthInBytes(albumTitle) + 1 + (trackNumber == -1 ? 0 : 1);\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        language = IsoTypeReader.readIso639(content);\n        albumTitle = IsoTypeReader.readString(content);\n\n        if (content.remaining() > 0) {\n            trackNumber = IsoTypeReader.readUInt8(content);\n        } else {\n            trackNumber = -1;\n        }\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeIso639(byteBuffer, language);\n        byteBuffer.put(Utf8.convert(albumTitle));\n        byteBuffer.put((byte) 0);\n        if (trackNumber != -1) {\n            IsoTypeWriter.writeUInt8(byteBuffer, trackNumber);\n        }\n    }\n\n    public String toString() {\n        StringBuilder buffer = new StringBuilder();\n        buffer.append(\"AlbumBox[language=\").append(getLanguage()).append(\";\");\n        buffer.append(\"albumTitle=\").append(getAlbumTitle());\n        if (trackNumber >= 0) {\n            buffer.append(\";trackNumber=\").append(getTrackNumber());\n        }\n        buffer.append(\"]\");\n        return buffer.toString();\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/AuthorBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Meta information in a 'udta' box about a track.\n * Defined in 3GPP 26.244.\n *\n * @see com.coremedia.iso.boxes.UserDataBox\n */\npublic class AuthorBox extends AbstractFullBox {\n    public static final String TYPE = \"auth\";\n\n    private String language;\n    private String author;\n\n    public AuthorBox() {\n        super(TYPE);\n    }\n\n    /**\n     * Declares the language code for the {@link #getAuthor()} return value. See ISO 639-2/T for the set of three\n     * character codes.Each character is packed as the difference between its ASCII value and 0x60. The code is\n     * confined to being three lower-case letters, so these values are strictly positive.\n     *\n     * @return the language code\n     */\n    public String getLanguage() {\n        return language;\n    }\n\n    /**\n     * Author information.\n     *\n     * @return the author\n     */\n    public String getAuthor() {\n        return author;\n    }\n\n    public void setLanguage(String language) {\n        this.language = language;\n    }\n\n    public void setAuthor(String author) {\n        this.author = author;\n    }\n\n    protected long getContentSize() {\n        return 7 + Utf8.utf8StringLengthInBytes(author);\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        language = IsoTypeReader.readIso639(content);\n        author = IsoTypeReader.readString(content);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeIso639(byteBuffer, language);\n        byteBuffer.put(Utf8.convert(author));\n        byteBuffer.put((byte) 0);\n    }\n\n\n    public String toString() {\n        return \"AuthorBox[language=\" + getLanguage() + \";author=\" + getAuthor() + \"]\";\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/BitRateBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * <code>class BitRateBox extends Box('btrt') {<br/>\n * unsigned int(32) bufferSizeDB;<br/>\n * // gives the size of the decoding buffer for<br/>\n * // the elementary stream in bytes.<br/>\n * unsigned int(32) maxBitrate;<br/>\n * // gives the maximum rate in bits/second <br/>\n * // over any window of one second.<br/>\n * unsigned int(32) avgBitrate;<br/>\n * // avgBitrate gives the average rate in <br/>\n * // bits/second over the entire presentation.<br/>\n * }</code>\n */\n\npublic final class BitRateBox extends AbstractBox {\n    public static final String TYPE = \"btrt\";\n\n    private long bufferSizeDb;\n    private long maxBitrate;\n    private long avgBitrate;\n\n    public BitRateBox() {\n        super(TYPE);\n    }\n\n    protected long getContentSize() {\n        return 12;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        bufferSizeDb = IsoTypeReader.readUInt32(content);\n        maxBitrate = IsoTypeReader.readUInt32(content);\n        avgBitrate = IsoTypeReader.readUInt32(content);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        IsoTypeWriter.writeUInt32(byteBuffer, bufferSizeDb);\n        IsoTypeWriter.writeUInt32(byteBuffer, maxBitrate);\n        IsoTypeWriter.writeUInt32(byteBuffer, avgBitrate);\n    }\n\n    public long getBufferSizeDb() {\n        return bufferSizeDb;\n    }\n\n    public void setBufferSizeDb(long bufferSizeDb) {\n        this.bufferSizeDb = bufferSizeDb;\n    }\n\n    public long getMaxBitrate() {\n        return maxBitrate;\n    }\n\n    public void setMaxBitrate(long maxBitrate) {\n        this.maxBitrate = maxBitrate;\n    }\n\n    public long getAvgBitrate() {\n        return avgBitrate;\n    }\n\n    public void setAvgBitrate(long avgBitrate) {\n        this.avgBitrate = avgBitrate;\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/Box.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.BoxParser;\nimport com.coremedia.iso.boxes.ContainerBox;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.channels.ReadableByteChannel;\nimport java.nio.channels.WritableByteChannel;\n\n/**\n * Defines basic interaction possibilities for any ISO box. Each box has a parent box and a type.\n */\npublic interface Box {\n    ContainerBox getParent();\n\n    void setParent(ContainerBox parent);\n\n    long getSize();\n\n    /**\n     * The box's 4-cc type.\n     * @return the 4 character type of the box\n     */\n    String getType();\n\n    /**\n     * Writes the complete box - size | 4-cc | content - to the given <code>writableByteChannel</code>.\n     * @param writableByteChannel the box's sink\n     * @throws IOException in case of problems with the <code>Channel</code>\n     */\n    void getBox(WritableByteChannel writableByteChannel) throws IOException;\n\n    void parse(ReadableByteChannel readableByteChannel, ByteBuffer header, long contentSize, BoxParser boxParser) throws IOException;\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/ChunkOffset64BitBox.java",
    "content": "package com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\n\nimport java.nio.ByteBuffer;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\n/**\n * Abstract Chunk Offset Box\n */\npublic class ChunkOffset64BitBox extends ChunkOffsetBox {\n    public static final String TYPE = \"co64\";\n    private long[] chunkOffsets;\n\n    public ChunkOffset64BitBox() {\n        super(TYPE);\n    }\n\n    @Override\n    public long[] getChunkOffsets() {\n        return chunkOffsets;\n    }\n\n    @Override\n    protected long getContentSize() {\n        return 8 + 8 * chunkOffsets.length;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        int entryCount = l2i(IsoTypeReader.readUInt32(content));\n        chunkOffsets = new long[entryCount];\n        for (int i = 0; i < entryCount; i++) {\n            chunkOffsets[i] = IsoTypeReader.readUInt64(content);\n        }\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt32(byteBuffer, chunkOffsets.length);\n        for (long chunkOffset : chunkOffsets) {\n            IsoTypeWriter.writeUInt64(byteBuffer, chunkOffset);\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/ChunkOffsetBox.java",
    "content": "package com.coremedia.iso.boxes;\n\nimport com.googlecode.mp4parser.AbstractFullBox;\n\n/**\n * Abstract Chunk Offset Box\n */\npublic abstract class ChunkOffsetBox extends AbstractFullBox {\n\n    public ChunkOffsetBox(String type) {\n        super(type);\n    }\n\n    public abstract long[] getChunkOffsets();\n\n\n    public String toString() {\n        return this.getClass().getSimpleName() + \"[entryCount=\" + getChunkOffsets().length + \"]\";\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/ClassificationBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoFile;\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Classification of the media according to 3GPP 26.244.\n */\npublic class ClassificationBox extends AbstractFullBox {\n    public static final String TYPE = \"clsf\";\n\n\n    private String classificationEntity;\n    private int classificationTableIndex;\n    private String language;\n    private String classificationInfo;\n\n    public ClassificationBox() {\n        super(TYPE);\n    }\n\n    public String getLanguage() {\n        return language;\n    }\n\n    public String getClassificationEntity() {\n        return classificationEntity;\n    }\n\n    public int getClassificationTableIndex() {\n        return classificationTableIndex;\n    }\n\n    public String getClassificationInfo() {\n        return classificationInfo;\n    }\n\n    public void setClassificationEntity(String classificationEntity) {\n        this.classificationEntity = classificationEntity;\n    }\n\n    public void setClassificationTableIndex(int classificationTableIndex) {\n        this.classificationTableIndex = classificationTableIndex;\n    }\n\n    public void setLanguage(String language) {\n        this.language = language;\n    }\n\n    public void setClassificationInfo(String classificationInfo) {\n        this.classificationInfo = classificationInfo;\n    }\n\n    protected long getContentSize() {\n        return 4 + 2 + 2 + Utf8.utf8StringLengthInBytes(classificationInfo) + 1;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        byte[] cE = new byte[4];\n        content.get(cE);\n        classificationEntity = IsoFile.bytesToFourCC(cE);\n        classificationTableIndex = IsoTypeReader.readUInt16(content);\n        language = IsoTypeReader.readIso639(content);\n        classificationInfo = IsoTypeReader.readString(content);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        byteBuffer.put(IsoFile.fourCCtoBytes(classificationEntity));\n        IsoTypeWriter.writeUInt16(byteBuffer, classificationTableIndex);\n        IsoTypeWriter.writeIso639(byteBuffer, language);\n        byteBuffer.put(Utf8.convert(classificationInfo));\n        byteBuffer.put((byte) 0);\n    }\n\n\n    public String toString() {\n        StringBuilder buffer = new StringBuilder();\n        buffer.append(\"ClassificationBox[language=\").append(getLanguage());\n        buffer.append(\"classificationEntity=\").append(getClassificationEntity());\n        buffer.append(\";classificationTableIndex=\").append(getClassificationTableIndex());\n        buffer.append(\";language=\").append(getLanguage());\n        buffer.append(\";classificationInfo=\").append(getClassificationInfo());\n        buffer.append(\"]\");\n        return buffer.toString();\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/CompositionShiftLeastGreatestAtom.java",
    "content": "package com.coremedia.iso.boxes;\n\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * The optional composition shift least greatest atom summarizes the calculated\n * minimum and maximum offsets between decode and composition time, as well as\n * the start and end times, for all samples. This allows a reader to determine\n * the minimum required time for decode to obtain proper presentation order without\n * needing to scan the sample table for the range of offsets. The type of the\n * composition shift least greatest atom is ‘cslg’.\n */\npublic class CompositionShiftLeastGreatestAtom extends AbstractFullBox {\n    public CompositionShiftLeastGreatestAtom() {\n        super(\"cslg\");\n    }\n\n    // A 32-bit unsigned integer that specifies the calculated value.\n    int compositionOffsetToDisplayOffsetShift;\n\n    // A 32-bit signed integer that specifies the calculated value.\n    int leastDisplayOffset;\n\n    // A 32-bit signed integer that specifies the calculated value.\n    int greatestDisplayOffset;\n\n    //A 32-bit signed integer that specifies the calculated value.\n    int displayStartTime;\n\n    //A 32-bit signed integer that specifies the calculated value.\n    int displayEndTime;\n\n\n    @Override\n    protected long getContentSize() {\n        return 24;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        compositionOffsetToDisplayOffsetShift = content.getInt();\n        leastDisplayOffset = content.getInt();\n        greatestDisplayOffset = content.getInt();\n        displayStartTime = content.getInt();\n        displayEndTime = content.getInt();\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        byteBuffer.putInt(compositionOffsetToDisplayOffsetShift);\n        byteBuffer.putInt(leastDisplayOffset);\n        byteBuffer.putInt(greatestDisplayOffset);\n        byteBuffer.putInt(displayStartTime);\n        byteBuffer.putInt(displayEndTime);\n    }\n\n\n    public int getCompositionOffsetToDisplayOffsetShift() {\n        return compositionOffsetToDisplayOffsetShift;\n    }\n\n    public void setCompositionOffsetToDisplayOffsetShift(int compositionOffsetToDisplayOffsetShift) {\n        this.compositionOffsetToDisplayOffsetShift = compositionOffsetToDisplayOffsetShift;\n    }\n\n    public int getLeastDisplayOffset() {\n        return leastDisplayOffset;\n    }\n\n    public void setLeastDisplayOffset(int leastDisplayOffset) {\n        this.leastDisplayOffset = leastDisplayOffset;\n    }\n\n    public int getGreatestDisplayOffset() {\n        return greatestDisplayOffset;\n    }\n\n    public void setGreatestDisplayOffset(int greatestDisplayOffset) {\n        this.greatestDisplayOffset = greatestDisplayOffset;\n    }\n\n    public int getDisplayStartTime() {\n        return displayStartTime;\n    }\n\n    public void setDisplayStartTime(int displayStartTime) {\n        this.displayStartTime = displayStartTime;\n    }\n\n    public int getDisplayEndTime() {\n        return displayEndTime;\n    }\n\n    public void setDisplayEndTime(int displayEndTime) {\n        this.displayEndTime = displayEndTime;\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/CompositionTimeToSample.java",
    "content": "package com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\n/**\n * <pre>\n * aligned(8) class CompositionOffsetBox\n * extends FullBox(‘ctts’, version = 0, 0) {\n *  unsigned int(32) entry_count;\n *  int i;\n *  if (version==0) {\n *   for (i=0; i < entry_count; i++) {\n *    unsigned int(32) sample_count;\n *    unsigned int(32) sample_offset;\n *   }\n *  }\n *  else if (version == 1) {\n *   for (i=0; i < entry_count; i++) {\n *    unsigned int(32) sample_count;\n *    signed int(32) sample_offset;\n *   }\n *  }\n * }\n * </pre>\n * <p/>\n * This box provides the offset between decoding time and composition time.\n * In version 0 of this box the decoding time must be less than the composition time, and\n * the offsets are expressed as unsigned numbers such that\n * CT(n) = DT(n) + CTTS(n) where CTTS(n) is the (uncompressed) table entry for sample n.\n * <p/>\n * In version 1 of this box, the composition timeline and the decoding timeline are\n * still derived from each other, but the offsets are signed.\n * It is recommended that for the computed composition timestamps, there is\n * exactly one with the value 0 (zero).\n */\npublic class CompositionTimeToSample extends AbstractFullBox {\n    public static final String TYPE = \"ctts\";\n\n    List<Entry> entries = Collections.emptyList();\n\n    public CompositionTimeToSample() {\n        super(TYPE);\n    }\n\n    protected long getContentSize() {\n        return 8 + 8 * entries.size();\n    }\n\n    public List<Entry> getEntries() {\n        return entries;\n    }\n\n    public void setEntries(List<Entry> entries) {\n        this.entries = entries;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        int numberOfEntries = l2i(IsoTypeReader.readUInt32(content));\n        entries = new ArrayList<Entry>(numberOfEntries);\n        for (int i = 0; i < numberOfEntries; i++) {\n            Entry e = new Entry(l2i(IsoTypeReader.readUInt32(content)), content.getInt());\n            entries.add(e);\n        }\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt32(byteBuffer, entries.size());\n\n        for (Entry entry : entries) {\n            IsoTypeWriter.writeUInt32(byteBuffer, entry.getCount());\n            byteBuffer.putInt(entry.getOffset());\n        }\n\n    }\n\n\n    public static class Entry {\n        int count;\n        int offset;\n\n        public Entry(int count, int offset) {\n            this.count = count;\n            this.offset = offset;\n        }\n\n        public int getCount() {\n            return count;\n        }\n\n        public int getOffset() {\n            return offset;\n        }\n\n        public void setCount(int count) {\n            this.count = count;\n        }\n\n        public void setOffset(int offset) {\n            this.offset = offset;\n        }\n\n        @Override\n        public String toString() {\n            return \"Entry{\" +\n                    \"count=\" + count +\n                    \", offset=\" + offset +\n                    '}';\n        }\n    }\n\n\n    /**\n     * Decompresses the list of entries and returns the list of composition times.\n     *\n     * @return decoding time per sample\n     */\n    public static int[] blowupCompositionTimes(List<CompositionTimeToSample.Entry> entries) {\n        long numOfSamples = 0;\n        for (CompositionTimeToSample.Entry entry : entries) {\n            numOfSamples += entry.getCount();\n        }\n        assert numOfSamples <= Integer.MAX_VALUE;\n        int[] decodingTime = new int[(int) numOfSamples];\n\n        int current = 0;\n\n\n        for (CompositionTimeToSample.Entry entry : entries) {\n            for (int i = 0; i < entry.getCount(); i++) {\n                decodingTime[current++] = entry.getOffset();\n            }\n        }\n\n        return decodingTime;\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/ContainerBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoFile;\n\nimport java.util.List;\n\n/**\n * Interface for all ISO boxes that may contain other boxes.\n */\npublic interface ContainerBox extends Box {\n\n    /**\n     * Gets all child boxes. May not return <code>null</code>.\n     *\n     * @return an array of boxes, empty array in case of no children.\n     */\n    List<Box> getBoxes();\n\n    /**\n     * Sets all boxes and removes all previous child boxes.\n     * @param boxes the new list of children\n     */\n    void setBoxes(List<Box> boxes);\n\n    /**\n     * Gets all child boxes of the given type. May not return <code>null</code>.\n     *\n     * @param clazz child box's type\n     * @return an array of boxes, empty array in case of no children.\n     */\n    <T extends Box> List<T> getBoxes(Class<T> clazz);\n\n    /**\n     * Gets all child boxes of the given type. May not return <code>null</code>.\n     *\n     * @param clazz     child box's type\n     * @param recursive step down the tree\n     * @return an array of boxes, empty array in case of no children.\n     */\n    <T extends Box> List<T> getBoxes(Class<T> clazz, boolean recursive);\n\n    /**\n     * Gets the parent box. May be <code>null</code> in case of the\n     * {@link com.coremedia.iso.IsoFile} itself.\n     *\n     * @return a <code>ContainerBox</code> that contains <code>this</code>\n     */\n    ContainerBox getParent();\n\n    /**\n     * Returns the number of bytes from the start of the box to start of the first child.\n     *\n     * @return offset of first child from box start\n     */\n    long getNumOfBytesToFirstChild();\n\n    IsoFile getIsoFile();\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/CopyrightBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * The copyright box contains a copyright declaration which applies to the entire presentation, when contained\n * within the MovieBox, or, when contained in a track, to that entire track. There may be multple boxes using\n * different language codes.\n *\n * @see MovieBox\n * @see TrackBox\n */\npublic class CopyrightBox extends AbstractFullBox {\n    public static final String TYPE = \"cprt\";\n\n    private String language;\n    private String copyright;\n\n    public CopyrightBox() {\n        super(TYPE);\n    }\n\n    public String getLanguage() {\n        return language;\n    }\n\n    public String getCopyright() {\n        return copyright;\n    }\n\n    public void setLanguage(String language) {\n        this.language = language;\n    }\n\n    public void setCopyright(String copyright) {\n        this.copyright = copyright;\n    }\n\n    protected long getContentSize() {\n        return 7 + Utf8.utf8StringLengthInBytes(copyright);\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        language = IsoTypeReader.readIso639(content);\n        copyright = IsoTypeReader.readString(content);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeIso639(byteBuffer, language);\n        byteBuffer.put(Utf8.convert(copyright));\n        byteBuffer.put((byte) 0);\n    }\n\n    public String toString() {\n        return \"CopyrightBox[language=\" + getLanguage() + \";copyright=\" + getCopyright() + \"]\";\n    }\n\n\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/DataEntryUrlBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Only used within the DataReferenceBox. Find more information there.\n *\n * @see com.coremedia.iso.boxes.DataReferenceBox\n */\npublic class DataEntryUrlBox extends AbstractFullBox {\n    public static final String TYPE = \"url \";\n\n    public DataEntryUrlBox() {\n        super(TYPE);\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n    }\n\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n    }\n\n    protected long getContentSize() {\n        return 4;\n    }\n\n    public String toString() {\n        return \"DataEntryUrlBox[]\";\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/DataEntryUrnBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Only used within the DataReferenceBox. Find more information there.\n *\n * @see com.coremedia.iso.boxes.DataReferenceBox\n */\npublic class DataEntryUrnBox extends AbstractFullBox {\n    private String name;\n    private String location;\n    public static final String TYPE = \"urn \";\n\n    public DataEntryUrnBox() {\n        super(TYPE);\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public String getLocation() {\n        return location;\n    }\n\n    protected long getContentSize() {\n        return Utf8.utf8StringLengthInBytes(name) + 1 + Utf8.utf8StringLengthInBytes(location) + 1;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        name = IsoTypeReader.readString(content);\n        location = IsoTypeReader.readString(content);\n\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        byteBuffer.put(Utf8.convert(name));\n        byteBuffer.put((byte) 0);\n        byteBuffer.put(Utf8.convert(location));\n        byteBuffer.put((byte) 0);\n    }\n\n    public String toString() {\n        return \"DataEntryUrlBox[name=\" + getName() + \";location=\" + getLocation() + \"]\";\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/DataInformationBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.googlecode.mp4parser.AbstractContainerBox;\n\n/**\n * <code>\n * Box Type: 'dinf'<br>\n * Container: {@link com.coremedia.iso.boxes.MediaInformationBox} ('minf')<br>\n * Mandatory: Yes<br>\n * Quantity: Exactly one<br><br></code>\n * The data information box contains objects that declare the location of the media information in a track.\n */\npublic class DataInformationBox extends AbstractContainerBox {\n    public static final String TYPE = \"dinf\";\n\n    public DataInformationBox() {\n        super(TYPE);\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/DataReferenceBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\n\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.FullContainerBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * The data reference object contains a table of data references (normally URLs) that declare the location(s) of\n * the media data used within the presentation. The data reference index in the sample description ties entries in\n * this table to the samples in the track. A track may be split over several sources in this way.\n * If the flag is set indicating that the data is in the same file as this box, then no string (not even an empty one)\n * shall be supplied in the entry field.\n * The DataEntryBox within the DataReferenceBox shall be either a DataEntryUrnBox or a DataEntryUrlBox.\n *\n * @see com.coremedia.iso.boxes.DataEntryUrlBox\n * @see com.coremedia.iso.boxes.DataEntryUrnBox\n */\npublic class DataReferenceBox extends FullContainerBox {\n\n    public static final String TYPE = \"dref\";\n\n    public DataReferenceBox() {\n        super(TYPE);\n\n    }\n\n    @Override\n    protected long getContentSize() {\n        return super.getContentSize() + 4;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        content.get(new byte[4]); // basically a skip of 4 bytes signaling the number of child boxes\n        parseChildBoxes(content);\n    }\n\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt32(byteBuffer, getBoxes().size());\n        writeChildBoxes(byteBuffer);\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/DescriptionBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Gives a language dependent description of the media contained in the ISO file.\n */\npublic class DescriptionBox extends AbstractFullBox {\n    public static final String TYPE = \"dscp\";\n\n    private String language;\n    private String description;\n\n    public DescriptionBox() {\n        super(TYPE);\n    }\n\n    public String getLanguage() {\n        return language;\n    }\n\n    public String getDescription() {\n        return description;\n    }\n\n    protected long getContentSize() {\n        return 7 + Utf8.utf8StringLengthInBytes(description);\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        language = IsoTypeReader.readIso639(content);\n        description = IsoTypeReader.readString(content);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeIso639(byteBuffer, language);\n        byteBuffer.put(Utf8.convert(description));\n        byteBuffer.put((byte) 0);\n    }\n\n    public String toString() {\n        return \"DescriptionBox[language=\" + getLanguage() + \";description=\" + getDescription() + \"]\";\n    }\n\n    public void setLanguage(String language) {\n        this.language = language;\n    }\n\n    public void setDescription(String description) {\n        this.description = description;\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/EditBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.googlecode.mp4parser.AbstractContainerBox;\n\n/**\n * An Edit Box maps the presentation time-line to the media time-line as it is stored in the file.\n * The Edit Box is a container fpr the edit lists. Defined in ISO/IEC 14496-12.\n *\n * @see EditListBox\n */\npublic class EditBox extends AbstractContainerBox {\n    public static final String TYPE = \"edts\";\n\n    public EditBox() {\n        super(TYPE);\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/EditListBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.util.LinkedList;\nimport java.util.List;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\n/**\n * <code>\n * Box Type  : 'elst'<br>\n * Container: {@link EditBox}('edts')<br>\n * Mandatory: No<br>\n * Quantity  : Zero or one</code><br><br>\n * This box contains an explicit timeline map. Each entry defines part of the track time-line: by mapping part of\n * the media time-line, or by indicating 'empty' time, or by defining a 'dwell', where a single time-point in the\n * media is held for a period.<br>\n * Note that edits are not restricted to fall on sample times. This means that when entering an edit, it can be\n * necessary to (a) back up to a sync point, and pre-roll from there and then (b) be careful about the duration of\n * the first sample - it might have been truncated if the edit enters it during its normal duration. If this is audio,\n * that frame might need to be decoded, and then the final slicing done. Likewise, the duration of the last sample\n * in an edit might need slicing. <br>\n * Starting offsets for tracks (streams) are represented by an initial empty edit. For example, to play a track from\n * its start for 30 seconds, but at 10 seconds into the presentation, we have the following edit list:<br>\n * <p/>\n * <li>Entry-count = 2</li>\n * <li>Segment-duration = 10 seconds</li>\n * <li>Media-Time = -1</li>\n * <li>Media-Rate = 1</li>\n * <li>Segment-duration = 30 seconds (could be the length of the whole track)</li>\n * <li>Media-Time = 0 seconds</li>\n * <li>Media-Rate = 1</li>\n */\npublic class EditListBox extends AbstractFullBox {\n    private List<Entry> entries = new LinkedList<Entry>();\n    public static final String TYPE = \"elst\";\n\n    public EditListBox() {\n        super(TYPE);\n    }\n\n\n    public List<Entry> getEntries() {\n        return entries;\n    }\n\n    public void setEntries(List<Entry> entries) {\n        this.entries = entries;\n    }\n\n    protected long getContentSize() {\n        long contentSize = 8;\n        if (getVersion() == 1) {\n            contentSize += entries.size() * 20;\n        } else {\n            contentSize += entries.size() * 12;\n        }\n\n        return contentSize;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        int entryCount = l2i(IsoTypeReader.readUInt32(content));\n        entries = new LinkedList<Entry>();\n        for (int i = 0; i < entryCount; i++) {\n            entries.add(new Entry(this, content));\n\n        }\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt32(byteBuffer, entries.size());\n        for (Entry entry : entries) {\n            entry.getContent(byteBuffer);\n        }\n    }\n\n    @Override\n    public String toString() {\n        return \"EditListBox{\" +\n                \"entries=\" + entries +\n                '}';\n    }\n\n    public static class Entry {\n        private long segmentDuration;\n        private long mediaTime;\n        private double mediaRate;\n        EditListBox editListBox;\n\n        /**\n         * Creates a new <code>Entry</code> with all values set.\n         *\n         * @param segmentDuration duration in movie timescale\n         * @param mediaTime       starting time\n         * @param mediaRate       relative play rate\n         */\n        public Entry(EditListBox editListBox, long segmentDuration, long mediaTime, double mediaRate) {\n            this.segmentDuration = segmentDuration;\n            this.mediaTime = mediaTime;\n            this.mediaRate = mediaRate;\n            this.editListBox = editListBox;\n        }\n\n        public Entry(EditListBox editListBox, ByteBuffer bb) {\n            if (editListBox.getVersion() == 1) {\n                segmentDuration = IsoTypeReader.readUInt64(bb);\n                mediaTime = IsoTypeReader.readUInt64(bb);\n                mediaRate = IsoTypeReader.readFixedPoint1616(bb);\n            } else {\n                segmentDuration = IsoTypeReader.readUInt32(bb);\n                mediaTime = IsoTypeReader.readUInt32(bb);\n                mediaRate = IsoTypeReader.readFixedPoint1616(bb);\n            }\n            this.editListBox = editListBox;\n        }\n\n        /**\n         * The segment duration is an integer that specifies the duration\n         * of this edit segment in units of the timescale in the Movie\n         * Header Box\n         *\n         * @return segment duration in movie timescale\n         */\n        public long getSegmentDuration() {\n            return segmentDuration;\n        }\n\n        /**\n         * The segment duration is an integer that specifies the duration\n         * of this edit segment in units of the timescale in the Movie\n         * Header Box\n         *\n         * @param segmentDuration new segment duration in movie timescale\n         */\n        public void setSegmentDuration(long segmentDuration) {\n            this.segmentDuration = segmentDuration;\n        }\n\n        /**\n         * The media time is an integer containing the starting time\n         * within the media of a specific edit segment(in media time\n         * scale units, in composition time)\n         *\n         * @return starting time\n         */\n        public long getMediaTime() {\n            return mediaTime;\n        }\n\n        /**\n         * The media time is an integer containing the starting time\n         * within the media of a specific edit segment(in media time\n         * scale units, in composition time)\n         *\n         * @param mediaTime starting time\n         */\n        public void setMediaTime(long mediaTime) {\n            this.mediaTime = mediaTime;\n        }\n\n        /**\n         * The media rate specifies the relative rate at which to play the\n         * media corresponding to a specific edit segment.\n         *\n         * @return relative play rate\n         */\n        public double getMediaRate() {\n            return mediaRate;\n        }\n\n        /**\n         * The media rate specifies the relative rate at which to play the\n         * media corresponding to a specific edit segment.\n         *\n         * @param mediaRate new relative play rate\n         */\n        public void setMediaRate(double mediaRate) {\n            this.mediaRate = mediaRate;\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            if (this == o) return true;\n            if (o == null || getClass() != o.getClass()) return false;\n\n            Entry entry = (Entry) o;\n\n            if (mediaTime != entry.mediaTime) return false;\n            if (segmentDuration != entry.segmentDuration) return false;\n\n            return true;\n        }\n\n        @Override\n        public int hashCode() {\n            int result = (int) (segmentDuration ^ (segmentDuration >>> 32));\n            result = 31 * result + (int) (mediaTime ^ (mediaTime >>> 32));\n            return result;\n        }\n\n        public void getContent(ByteBuffer bb)  {\n            if (editListBox.getVersion() == 1) {\n                IsoTypeWriter.writeUInt64(bb, segmentDuration);\n                IsoTypeWriter.writeUInt64(bb, mediaTime);\n            } else {\n                IsoTypeWriter.writeUInt32(bb, l2i(segmentDuration));\n                bb.putInt(l2i(mediaTime));\n            }\n            IsoTypeWriter.writeFixedPont1616(bb, mediaRate);\n        }\n\n        @Override\n        public String toString() {\n            return \"Entry{\" +\n                    \"segmentDuration=\" + segmentDuration +\n                    \", mediaTime=\" + mediaTime +\n                    \", mediaRate=\" + mediaRate +\n                    '}';\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/FileTypeBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoFile;\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractBox;\nimport com.googlecode.mp4parser.annotations.DoNotParseDetail;\n\nimport java.nio.ByteBuffer;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.LinkedList;\nimport java.util.List;\n\n/**\n * This box identifies the specifications to which this file complies. <br>\n * Each brand is a printable four-character code, registered with ISO, that\n * identifies a precise specification.\n */\npublic class FileTypeBox extends AbstractBox {\n    public static final String TYPE = \"ftyp\";\n\n    private String majorBrand;\n    private long minorVersion;\n    private List<String> compatibleBrands = Collections.emptyList();\n\n    public FileTypeBox() {\n        super(TYPE);\n    }\n\n    public FileTypeBox(String majorBrand, long minorVersion, List<String> compatibleBrands) {\n        super(TYPE);\n        this.majorBrand = majorBrand;\n        this.minorVersion = minorVersion;\n        this.compatibleBrands = compatibleBrands;\n    }\n\n    protected long getContentSize() {\n        return 8 + compatibleBrands.size() * 4;\n\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        majorBrand = IsoTypeReader.read4cc(content);\n        minorVersion = IsoTypeReader.readUInt32(content);\n        int compatibleBrandsCount = content.remaining() / 4;\n        compatibleBrands = new LinkedList<String>();\n        for (int i = 0; i < compatibleBrandsCount; i++) {\n            compatibleBrands.add(IsoTypeReader.read4cc(content));\n        }\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        byteBuffer.put(IsoFile.fourCCtoBytes(majorBrand));\n        IsoTypeWriter.writeUInt32(byteBuffer, minorVersion);\n        for (String compatibleBrand : compatibleBrands) {\n            byteBuffer.put(IsoFile.fourCCtoBytes(compatibleBrand));\n        }\n\n    }\n\n    /**\n     * Gets the brand identifier.\n     *\n     * @return the brand identifier\n     */\n    public String getMajorBrand() {\n        return majorBrand;\n    }\n\n    /**\n     * Sets the major brand of the file used to determine an appropriate reader.\n     *\n     * @param majorBrand the new major brand\n     */\n    public void setMajorBrand(String majorBrand) {\n        this.majorBrand = majorBrand;\n    }\n\n    /**\n     * Sets the \"informative integer for the minor version of the major brand\".\n     *\n     * @param minorVersion the version number of the major brand\n     */\n    public void setMinorVersion(int minorVersion) {\n        this.minorVersion = minorVersion;\n    }\n\n    /**\n     * Gets an informative integer for the minor version of the major brand.\n     *\n     * @return an informative integer\n     * @see FileTypeBox#getMajorBrand()\n     */\n    public long getMinorVersion() {\n        return minorVersion;\n    }\n\n    /**\n     * Gets an array of 4-cc brands.\n     *\n     * @return the compatible brands\n     */\n    public List<String> getCompatibleBrands() {\n        return compatibleBrands;\n    }\n\n    public void setCompatibleBrands(List<String> compatibleBrands) {\n        this.compatibleBrands = compatibleBrands;\n    }\n\n    @DoNotParseDetail\n    public String toString() {\n        StringBuilder result = new StringBuilder();\n        result.append(\"FileTypeBox[\");\n        result.append(\"majorBrand=\").append(getMajorBrand());\n        result.append(\";\");\n        result.append(\"minorVersion=\").append(getMinorVersion());\n        for (String compatibleBrand : compatibleBrands) {\n            result.append(\";\");\n            result.append(\"compatibleBrand=\").append(compatibleBrand);\n        }\n        result.append(\"]\");\n        return result.toString();\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/FreeBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\n\nimport com.googlecode.mp4parser.AbstractBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * A free box. Just a placeholder to enable editing without rewriting the whole file.\n */\npublic class FreeBox extends AbstractBox {\n    public static final String TYPE = \"free\";\n    ByteBuffer data;\n\n    public FreeBox() {\n        super(TYPE);\n    }\n\n    public FreeBox(int size) {\n        super(TYPE);\n        this.data = ByteBuffer.allocate(size);\n    }\n\n    @Override\n    protected long getContentSize() {\n        return data.limit();\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        data = content;\n        data.position(data.position() + data.remaining());\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        data.rewind();\n        byteBuffer.put(data);\n    }\n\n    public ByteBuffer getData() {\n        return data;\n    }\n\n    public void setData(ByteBuffer data) {\n        this.data = data;\n    }\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/FreeSpaceBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.googlecode.mp4parser.AbstractBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * The contents of a free-space box are irrelevant and may be ignored, or the object deleted, without affecting the\n * presentation. Care should be excercized when deleting the object, as this may invalidate the offsets used in the\n * sample table.\n */\npublic class FreeSpaceBox extends AbstractBox {\n    public static final String TYPE = \"skip\";\n\n    byte[] data;\n\n    protected long getContentSize() {\n        return data.length;\n    }\n\n    public FreeSpaceBox() {\n        super(TYPE);\n    }\n\n    public void setData(byte[] data) {\n        this.data = data;\n    }\n\n    public byte[] getData() {\n        return data;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        data = new byte[content.remaining()];\n        content.get(data);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        byteBuffer.put(data);\n    }\n\n    public String toString() {\n        return \"FreeSpaceBox[size=\" + data.length + \";type=\" + getType() + \"]\";\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/FullBox.java",
    "content": "package com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.boxes.Box;\n\n/**\n * The <code>FullBox</code> contains all getters and setters specific\n * to a so-called full box according to the ISO/IEC 14496/12 specification.\n */\npublic interface FullBox extends Box {\n    int getVersion();\n\n    void setVersion(int version);\n\n    int getFlags();\n\n    void setFlags(int flags);\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/GenericMediaHeaderBoxImpl.java",
    "content": "package com.coremedia.iso.boxes;\n\nimport java.nio.ByteBuffer;\n\npublic class GenericMediaHeaderBoxImpl extends AbstractMediaHeaderBox {\n\n    ByteBuffer data;\n\n    @Override\n    protected long getContentSize() {\n        return 4 + data.limit();\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        this.data = content.slice();\n        content.position(content.remaining() + content.position());\n\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        byteBuffer.put((ByteBuffer) data.rewind());\n    }\n\n    public GenericMediaHeaderBoxImpl() {\n        super(\"gmhd\");\n    }\n\n    public ByteBuffer getData() {\n        return data;\n    }\n\n    public void setData(ByteBuffer data) {\n        this.data = data;\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/GenreBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Containing genre information and contained in the <code>UserDataBox</code>.\n *\n * @see com.coremedia.iso.boxes.UserDataBox\n */\npublic class GenreBox extends AbstractFullBox {\n    public static final String TYPE = \"gnre\";\n\n    private String language;\n    private String genre;\n\n    public GenreBox() {\n        super(TYPE);\n    }\n\n    public String getLanguage() {\n        return language;\n    }\n\n    public String getGenre() {\n        return genre;\n    }\n\n    public void setLanguage(String language) {\n        this.language = language;\n    }\n\n    public void setGenre(String genre) {\n        this.genre = genre;\n    }\n\n    protected long getContentSize() {\n        return 7 + Utf8.utf8StringLengthInBytes(genre);\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        language = IsoTypeReader.readIso639(content);\n        genre = IsoTypeReader.readString(content);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeIso639(byteBuffer, language);\n        byteBuffer.put(Utf8.convert(genre));\n        byteBuffer.put((byte) 0);\n    }\n\n    public String toString() {\n        return \"GenreBox[language=\" + getLanguage() + \";genre=\" + getGenre() + \"]\";\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/HandlerBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\n\nimport com.coremedia.iso.IsoFile;\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * This box within a Media Box declares the process by which the media-data in the track is presented,\n * and thus, the nature of the media in a track.\n * This Box when present in a Meta Box, declares the structure or format of the 'meta' box contents.\n * See ISO/IEC 14496-12 for details.\n *\n * @see MetaBox\n * @see MediaBox\n */\npublic class HandlerBox extends AbstractFullBox {\n    public static final String TYPE = \"hdlr\";\n    public static final Map<String, String> readableTypes;\n\n    static {\n        HashMap<String, String> hm = new HashMap<String, String>();\n        hm.put(\"odsm\", \"ObjectDescriptorStream - defined in ISO/IEC JTC1/SC29/WG11 - CODING OF MOVING PICTURES AND AUDIO\");\n        hm.put(\"crsm\", \"ClockReferenceStream - defined in ISO/IEC JTC1/SC29/WG11 - CODING OF MOVING PICTURES AND AUDIO\");\n        hm.put(\"sdsm\", \"SceneDescriptionStream - defined in ISO/IEC JTC1/SC29/WG11 - CODING OF MOVING PICTURES AND AUDIO\");\n        hm.put(\"m7sm\", \"MPEG7Stream - defined in ISO/IEC JTC1/SC29/WG11 - CODING OF MOVING PICTURES AND AUDIO\");\n        hm.put(\"ocsm\", \"ObjectContentInfoStream - defined in ISO/IEC JTC1/SC29/WG11 - CODING OF MOVING PICTURES AND AUDIO\");\n        hm.put(\"ipsm\", \"IPMP Stream - defined in ISO/IEC JTC1/SC29/WG11 - CODING OF MOVING PICTURES AND AUDIO\");\n        hm.put(\"mjsm\", \"MPEG-J Stream - defined in ISO/IEC JTC1/SC29/WG11 - CODING OF MOVING PICTURES AND AUDIO\");\n        hm.put(\"mdir\", \"Apple Meta Data iTunes Reader\");\n        hm.put(\"mp7b\", \"MPEG-7 binary XML\");\n        hm.put(\"mp7t\", \"MPEG-7 XML\");\n        hm.put(\"vide\", \"Video Track\");\n        hm.put(\"soun\", \"Sound Track\");\n        hm.put(\"hint\", \"Hint Track\");\n        hm.put(\"appl\", \"Apple specific\");\n        hm.put(\"meta\", \"Timed Metadata track - defined in ISO/IEC JTC1/SC29/WG11 - CODING OF MOVING PICTURES AND AUDIO\");\n\n        readableTypes = Collections.unmodifiableMap(hm);\n\n    }\n\n    private String handlerType;\n    private String name = null;\n    private long a, b, c;\n    private boolean zeroTerm = true;\n\n    private long shouldBeZeroButAppleWritesHereSomeValue;\n\n    public HandlerBox() {\n        super(TYPE);\n    }\n\n    public String getHandlerType() {\n        return handlerType;\n    }\n\n    /**\n     * You are required to add a '\\0' string termination by yourself.\n     *\n     * @param name the new human readable name\n     */\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public void setHandlerType(String handlerType) {\n        this.handlerType = handlerType;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public String getHumanReadableTrackType() {\n        return readableTypes.get(handlerType) != null ? readableTypes.get(handlerType) : \"Unknown Handler Type\";\n    }\n\n    protected long getContentSize() {\n        if (zeroTerm) {\n            return 25 + Utf8.utf8StringLengthInBytes(name);\n        } else {\n            return 24 + Utf8.utf8StringLengthInBytes(name);\n        }\n\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        shouldBeZeroButAppleWritesHereSomeValue = IsoTypeReader.readUInt32(content);\n        handlerType = IsoTypeReader.read4cc(content);\n        a = IsoTypeReader.readUInt32(content);\n        b = IsoTypeReader.readUInt32(content);\n        c = IsoTypeReader.readUInt32(content);\n        if (content.remaining() > 0) {\n            name = IsoTypeReader.readString(content, content.remaining());\n            if (name.endsWith(\"\\0\")) {\n                name = name.substring(0, name.length() - 1);\n                zeroTerm = true;\n            } else {\n                zeroTerm = false;\n            }\n        } else {\n            zeroTerm = false; //No string at all, not even zero term char\n        }\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt32(byteBuffer, shouldBeZeroButAppleWritesHereSomeValue);\n        byteBuffer.put(IsoFile.fourCCtoBytes(handlerType));\n        IsoTypeWriter.writeUInt32(byteBuffer, a);\n        IsoTypeWriter.writeUInt32(byteBuffer, b);\n        IsoTypeWriter.writeUInt32(byteBuffer, c);\n        if (name != null) {\n            byteBuffer.put(Utf8.convert(name));\n        }\n        if (zeroTerm) {\n            byteBuffer.put((byte) 0);\n        }\n    }\n\n    public String toString() {\n        return \"HandlerBox[handlerType=\" + getHandlerType() + \";name=\" + getName() + \"]\";\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/HintMediaHeaderBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\n\nimport java.nio.ByteBuffer;\n\n/**\n * The hint media header contains general information, independent of the protocaol, for hint tracks. Resides\n * in Media Information Box.\n *\n * @see com.coremedia.iso.boxes.MediaInformationBox\n */\npublic class HintMediaHeaderBox extends AbstractMediaHeaderBox {\n    private int maxPduSize;\n    private int avgPduSize;\n    private long maxBitrate;\n    private long avgBitrate;\n    public static final String TYPE = \"hmhd\";\n\n    public HintMediaHeaderBox() {\n        super(TYPE);\n    }\n\n    public int getMaxPduSize() {\n        return maxPduSize;\n    }\n\n    public int getAvgPduSize() {\n        return avgPduSize;\n    }\n\n    public long getMaxBitrate() {\n        return maxBitrate;\n    }\n\n    public long getAvgBitrate() {\n        return avgBitrate;\n    }\n\n    protected long getContentSize() {\n        return 20;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        maxPduSize = IsoTypeReader.readUInt16(content);\n        avgPduSize = IsoTypeReader.readUInt16(content);\n        maxBitrate = IsoTypeReader.readUInt32(content);\n        avgBitrate = IsoTypeReader.readUInt32(content);\n        IsoTypeReader.readUInt32(content);    // reserved!\n\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt16(byteBuffer, maxPduSize);\n        IsoTypeWriter.writeUInt16(byteBuffer, avgPduSize);\n        IsoTypeWriter.writeUInt32(byteBuffer, maxBitrate);\n        IsoTypeWriter.writeUInt32(byteBuffer, avgBitrate);\n        IsoTypeWriter.writeUInt32(byteBuffer, 0);\n    }\n\n    @Override\n    public String toString() {\n        return \"HintMediaHeaderBox{\" +\n                \"maxPduSize=\" + maxPduSize +\n                \", avgPduSize=\" + avgPduSize +\n                \", maxBitrate=\" + maxBitrate +\n                \", avgBitrate=\" + avgBitrate +\n                '}';\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/ItemDataBox.java",
    "content": "package com.coremedia.iso.boxes;\n\nimport com.googlecode.mp4parser.AbstractBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n *\n */\npublic class ItemDataBox extends AbstractBox {\n    ByteBuffer data = ByteBuffer.allocate(0);\n    public static final String TYPE = \"idat\";\n\n\n    public ItemDataBox() {\n        super(TYPE);\n    }\n\n    public ByteBuffer getData() {\n        return data;\n    }\n\n    public void setData(ByteBuffer data) {\n        this.data = data;\n    }\n\n    @Override\n    protected long getContentSize() {\n        return data.limit();\n    }\n\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        data = content.slice();\n        content.position(content.position() + content.remaining());\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        byteBuffer.put(data);\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/ItemLocationBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeReaderVariable;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.IsoTypeWriterVariable;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.util.LinkedList;\nimport java.util.List;\n\n/**\n * aligned(8) class ItemLocationBox extends FullBox(‘iloc’, version, 0) {\n * unsigned int(4) offset_size;\n * unsigned int(4) length_size;\n * unsigned int(4) base_offset_size;\n * if (version == 1)\n * unsigned int(4) index_size;\n * else\n * unsigned int(4) reserved;\n * unsigned int(16) item_count;\n * for (i=0; i<item_count; i++) {\n * unsigned int(16) item_ID;\n * if (version == 1) {\n * unsigned int(12) reserved = 0;\n * unsigned int(4) construction_method;\n * }\n * unsigned int(16) data_reference_index;\n * unsigned int(base_offset_size*8) base_offset;\n * unsigned int(16) extent_count;\n * for (j=0; j<extent_count; j++) {\n * if ((version == 1) && (index_size > 0)) {\n * unsigned int(index_size*8) extent_index;\n * }\n * unsigned int(offset_size*8) extent_offset;\n * unsigned int(length_size*8) extent_length;\n * }\n * }\n * }\n */\npublic class ItemLocationBox extends AbstractFullBox {\n    public int offsetSize = 8;\n    public int lengthSize = 8;\n    public int baseOffsetSize = 8;\n    public int indexSize = 0;\n    public List<Item> items = new LinkedList<Item>();\n\n    public static final String TYPE = \"iloc\";\n\n    public ItemLocationBox() {\n        super(TYPE);\n    }\n\n    @Override\n    protected long getContentSize() {\n        long size = 8;\n        for (Item item : items) {\n            size += item.getSize();\n        }\n        return size;\n    }\n\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt8(byteBuffer, ((offsetSize << 4) | lengthSize));\n        if (getVersion() == 1) {\n            IsoTypeWriter.writeUInt8(byteBuffer, (baseOffsetSize << 4 | indexSize));\n        } else {\n            IsoTypeWriter.writeUInt8(byteBuffer, (baseOffsetSize << 4));\n        }\n        IsoTypeWriter.writeUInt16(byteBuffer, items.size());\n        for (Item item : items) {\n            item.getContent(byteBuffer);\n        }\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        int tmp = IsoTypeReader.readUInt8(content);\n        offsetSize = tmp >>> 4;\n        lengthSize = tmp & 0xf;\n        tmp = IsoTypeReader.readUInt8(content);\n        baseOffsetSize = tmp >>> 4;\n\n        if (getVersion() == 1) {\n            indexSize = tmp & 0xf;\n        }\n        int itemCount = IsoTypeReader.readUInt16(content);\n        for (int i = 0; i < itemCount; i++) {\n            items.add(new Item(content));\n        }\n    }\n\n\n    public int getOffsetSize() {\n        return offsetSize;\n    }\n\n    public void setOffsetSize(int offsetSize) {\n        this.offsetSize = offsetSize;\n    }\n\n    public int getLengthSize() {\n        return lengthSize;\n    }\n\n    public void setLengthSize(int lengthSize) {\n        this.lengthSize = lengthSize;\n    }\n\n    public int getBaseOffsetSize() {\n        return baseOffsetSize;\n    }\n\n    public void setBaseOffsetSize(int baseOffsetSize) {\n        this.baseOffsetSize = baseOffsetSize;\n    }\n\n    public int getIndexSize() {\n        return indexSize;\n    }\n\n    public void setIndexSize(int indexSize) {\n        this.indexSize = indexSize;\n    }\n\n    public List<Item> getItems() {\n        return items;\n    }\n\n    public void setItems(List<Item> items) {\n        this.items = items;\n    }\n\n\n    public Item createItem(int itemId, int constructionMethod, int dataReferenceIndex, long baseOffset, List<Extent> extents) {\n        return new Item(itemId, constructionMethod, dataReferenceIndex, baseOffset, extents);\n    }\n\n    Item createItem(ByteBuffer bb) {\n        return new Item(bb);\n    }\n\n    public class Item {\n        public int itemId;\n        public int constructionMethod;\n        public int dataReferenceIndex;\n        public long baseOffset;\n        public List<Extent> extents = new LinkedList<Extent>();\n\n        public Item(ByteBuffer in) {\n            itemId = IsoTypeReader.readUInt16(in);\n\n            if (getVersion() == 1) {\n                int tmp = IsoTypeReader.readUInt16(in);\n                constructionMethod = tmp & 0xf;\n            }\n\n            dataReferenceIndex = IsoTypeReader.readUInt16(in);\n            if (baseOffsetSize > 0) {\n                baseOffset = IsoTypeReaderVariable.read(in, baseOffsetSize);\n            } else {\n                baseOffset = 0;\n            }\n            int extentCount = IsoTypeReader.readUInt16(in);\n\n\n            for (int i = 0; i < extentCount; i++) {\n                extents.add(new Extent(in));\n            }\n        }\n\n        public Item(int itemId, int constructionMethod, int dataReferenceIndex, long baseOffset, List<Extent> extents) {\n            this.itemId = itemId;\n            this.constructionMethod = constructionMethod;\n            this.dataReferenceIndex = dataReferenceIndex;\n            this.baseOffset = baseOffset;\n            this.extents = extents;\n        }\n\n        public int getSize() {\n            int size = 2;\n\n            if (getVersion() == 1) {\n                size += 2;\n            }\n\n            size += 2;\n            size += baseOffsetSize;\n            size += 2;\n\n\n            for (Extent extent : extents) {\n                size += extent.getSize();\n            }\n            return size;\n        }\n\n        public void setBaseOffset(long baseOffset) {\n            this.baseOffset = baseOffset;\n        }\n\n        public void getContent(ByteBuffer bb)  {\n            IsoTypeWriter.writeUInt16(bb, itemId);\n\n            if (getVersion() == 1) {\n                IsoTypeWriter.writeUInt16(bb, constructionMethod);\n            }\n\n\n            IsoTypeWriter.writeUInt16(bb, dataReferenceIndex);\n            if (baseOffsetSize > 0) {\n                IsoTypeWriterVariable.write(baseOffset, bb, baseOffsetSize);\n            }\n            IsoTypeWriter.writeUInt16(bb, extents.size());\n\n            for (Extent extent : extents) {\n                extent.getContent(bb);\n            }\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            if (this == o) return true;\n            if (o == null || getClass() != o.getClass()) return false;\n\n            Item item = (Item) o;\n\n            if (baseOffset != item.baseOffset) return false;\n            if (constructionMethod != item.constructionMethod) return false;\n            if (dataReferenceIndex != item.dataReferenceIndex) return false;\n            if (itemId != item.itemId) return false;\n            if (extents != null ? !extents.equals(item.extents) : item.extents != null) return false;\n\n            return true;\n        }\n\n        @Override\n        public int hashCode() {\n            int result = itemId;\n            result = 31 * result + constructionMethod;\n            result = 31 * result + dataReferenceIndex;\n            result = 31 * result + (int) (baseOffset ^ (baseOffset >>> 32));\n            result = 31 * result + (extents != null ? extents.hashCode() : 0);\n            return result;\n        }\n\n        @Override\n        public String toString() {\n            return \"Item{\" +\n                    \"baseOffset=\" + baseOffset +\n                    \", itemId=\" + itemId +\n                    \", constructionMethod=\" + constructionMethod +\n                    \", dataReferenceIndex=\" + dataReferenceIndex +\n                    \", extents=\" + extents +\n                    '}';\n        }\n    }\n\n\n    public Extent createExtent(long extentOffset, long extentLength, long extentIndex) {\n        return new Extent(extentOffset, extentLength, extentIndex);\n    }\n\n    Extent createExtent(ByteBuffer bb) {\n        return new Extent(bb);\n    }\n\n\n    public class Extent {\n        public long extentOffset;\n        public long extentLength;\n        public long extentIndex;\n\n        public Extent(long extentOffset, long extentLength, long extentIndex) {\n            this.extentOffset = extentOffset;\n            this.extentLength = extentLength;\n            this.extentIndex = extentIndex;\n        }\n\n\n        public Extent(ByteBuffer in) {\n            if ((getVersion() == 1) && indexSize > 0) {\n                extentIndex = IsoTypeReaderVariable.read(in, indexSize);\n            }\n            extentOffset = IsoTypeReaderVariable.read(in, offsetSize);\n            extentLength = IsoTypeReaderVariable.read(in, lengthSize);\n        }\n\n        public void getContent(ByteBuffer os)  {\n            if ((getVersion() == 1) && indexSize > 0) {\n                IsoTypeWriterVariable.write(extentIndex, os, indexSize);\n            }\n            IsoTypeWriterVariable.write(extentOffset, os, offsetSize);\n            IsoTypeWriterVariable.write(extentLength, os, lengthSize);\n        }\n\n        public int getSize() {\n            return (indexSize > 0 ? indexSize : 0) + offsetSize + lengthSize;\n        }\n\n\n        @Override\n        public boolean equals(Object o) {\n            if (this == o) return true;\n            if (o == null || getClass() != o.getClass()) return false;\n\n            Extent extent = (Extent) o;\n\n            if (extentIndex != extent.extentIndex) return false;\n            if (extentLength != extent.extentLength) return false;\n            if (extentOffset != extent.extentOffset) return false;\n\n            return true;\n        }\n\n        @Override\n        public int hashCode() {\n            int result = (int) (extentOffset ^ (extentOffset >>> 32));\n            result = 31 * result + (int) (extentLength ^ (extentLength >>> 32));\n            result = 31 * result + (int) (extentIndex ^ (extentIndex >>> 32));\n            return result;\n        }\n\n        @Override\n        public String toString() {\n            final StringBuilder sb = new StringBuilder();\n            sb.append(\"Extent\");\n            sb.append(\"{extentOffset=\").append(extentOffset);\n            sb.append(\", extentLength=\").append(extentLength);\n            sb.append(\", extentIndex=\").append(extentIndex);\n            sb.append('}');\n            return sb.toString();\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/ItemProtectionBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.FullContainerBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * The Item Protection Box provides an array of item protection information, for use by the Item Information Box.\n *\n * @see com.coremedia.iso.boxes.ItemProtectionBox\n */\npublic class ItemProtectionBox extends FullContainerBox {\n\n    public static final String TYPE = \"ipro\";\n\n    public ItemProtectionBox() {\n        super(TYPE);\n    }\n\n    public SchemeInformationBox getItemProtectionScheme() {\n        if (!getBoxes(SchemeInformationBox.class).isEmpty()) {\n            return getBoxes(SchemeInformationBox.class).get(0);\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        IsoTypeReader.readUInt16(content);\n        parseChildBoxes(content);\n    }\n\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt16(byteBuffer, getBoxes().size());\n        writeChildBoxes(byteBuffer);\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/KeywordsBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * List of keywords according to 3GPP 26.244.\n */\npublic class KeywordsBox extends AbstractFullBox {\n    public static final String TYPE = \"kywd\";\n\n    private String language;\n    private String[] keywords;\n\n    public KeywordsBox() {\n        super(TYPE);\n    }\n\n    public String getLanguage() {\n        return language;\n    }\n\n    public String[] getKeywords() {\n        return keywords;\n    }\n\n    public void setLanguage(String language) {\n        this.language = language;\n    }\n\n    public void setKeywords(String[] keywords) {\n        this.keywords = keywords;\n    }\n\n    protected long getContentSize() {\n        long contentSize = 7;\n        for (String keyword : keywords) {\n            contentSize += 1 + Utf8.utf8StringLengthInBytes(keyword) + 1;\n        }\n        return contentSize;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        language = IsoTypeReader.readIso639(content);\n        int keywordCount = IsoTypeReader.readUInt8(content);\n        keywords = new String[keywordCount];\n        for (int i = 0; i < keywordCount; i++) {\n            IsoTypeReader.readUInt8(content);\n            keywords[i] = IsoTypeReader.readString(content);\n        }\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeIso639(byteBuffer, language);\n        IsoTypeWriter.writeUInt8(byteBuffer, keywords.length);\n        for (String keyword : keywords) {\n            IsoTypeWriter.writeUInt8(byteBuffer, Utf8.utf8StringLengthInBytes(keyword) + 1);\n            byteBuffer.put(Utf8.convert(keyword));\n        }\n    }\n\n    public String toString() {\n        StringBuffer buffer = new StringBuffer();\n        buffer.append(\"KeywordsBox[language=\").append(getLanguage());\n        for (int i = 0; i < keywords.length; i++) {\n            buffer.append(\";keyword\").append(i).append(\"=\").append(keywords[i]);\n        }\n        buffer.append(\"]\");\n        return buffer.toString();\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/MediaBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\n\nimport com.googlecode.mp4parser.AbstractContainerBox;\n\n/**\n * The media declaration container contains all the objects that declare information about the media data within a\n * track.\n */\npublic class MediaBox extends AbstractContainerBox {\n    public static final String TYPE = \"mdia\";\n\n    public MediaBox() {\n        super(TYPE);\n    }\n\n    public MediaInformationBox getMediaInformationBox() {\n        for (Box box : boxes) {\n            if (box instanceof MediaInformationBox) {\n                return (MediaInformationBox) box;\n            }\n        }\n        return null;\n    }\n\n    public MediaHeaderBox getMediaHeaderBox() {\n        for (Box box : boxes) {\n            if (box instanceof MediaHeaderBox) {\n                return (MediaHeaderBox) box;\n            }\n        }\n        return null;\n    }\n\n    public HandlerBox getHandlerBox() {\n        for (Box box : boxes) {\n            if (box instanceof HandlerBox) {\n                return (HandlerBox) box;\n            }\n        }\n        return null;\n    }\n\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/MediaHeaderBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * This box defines overall information which is media-independent, and relevant to the entire presentation\n * considered as a whole.\n */\npublic class MediaHeaderBox extends AbstractFullBox {\n    public static final String TYPE = \"mdhd\";\n\n\n    private long creationTime;\n    private long modificationTime;\n    private long timescale;\n    private long duration;\n    private String language;\n\n    public MediaHeaderBox() {\n        super(TYPE);\n    }\n\n    public long getCreationTime() {\n        return creationTime;\n    }\n\n    public long getModificationTime() {\n        return modificationTime;\n    }\n\n    public long getTimescale() {\n        return timescale;\n    }\n\n    public long getDuration() {\n        return duration;\n    }\n\n    public String getLanguage() {\n        return language;\n    }\n\n    protected long getContentSize() {\n        long contentSize = 4;\n        if (getVersion() == 1) {\n            contentSize += 8 + 8 + 4 + 8;\n        } else {\n            contentSize += 4 + 4 + 4 + 4;\n        }\n        contentSize += 2;\n        contentSize += 2;\n        return contentSize;\n\n    }\n\n    public void setCreationTime(long creationTime) {\n        this.creationTime = creationTime;\n    }\n\n    public void setModificationTime(long modificationTime) {\n        this.modificationTime = modificationTime;\n    }\n\n    public void setTimescale(long timescale) {\n        this.timescale = timescale;\n    }\n\n    public void setDuration(long duration) {\n        this.duration = duration;\n    }\n\n    public void setLanguage(String language) {\n        this.language = language;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        if (getVersion() == 1) {\n            creationTime = IsoTypeReader.readUInt64(content);\n            modificationTime = IsoTypeReader.readUInt64(content);\n            timescale = IsoTypeReader.readUInt32(content);\n            duration = IsoTypeReader.readUInt64(content);\n        } else {\n            creationTime = IsoTypeReader.readUInt32(content);\n            modificationTime = IsoTypeReader.readUInt32(content);\n            timescale = IsoTypeReader.readUInt32(content);\n            duration = IsoTypeReader.readUInt32(content);\n        }\n        language = IsoTypeReader.readIso639(content);\n        IsoTypeReader.readUInt16(content);\n    }\n\n\n    public String toString() {\n        StringBuilder result = new StringBuilder();\n        result.append(\"MeditHeaderBox[\");\n        result.append(\"creationTime=\").append(getCreationTime());\n        result.append(\";\");\n        result.append(\"modificationTime=\").append(getModificationTime());\n        result.append(\";\");\n        result.append(\"timescale=\").append(getTimescale());\n        result.append(\";\");\n        result.append(\"duration=\").append(getDuration());\n        result.append(\";\");\n        result.append(\"language=\").append(getLanguage());\n        result.append(\"]\");\n        return result.toString();\n    }\n\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        if (getVersion() == 1) {\n            IsoTypeWriter.writeUInt64(byteBuffer, creationTime);\n            IsoTypeWriter.writeUInt64(byteBuffer, modificationTime);\n            IsoTypeWriter.writeUInt32(byteBuffer, timescale);\n            IsoTypeWriter.writeUInt64(byteBuffer, duration);\n        } else {\n            IsoTypeWriter.writeUInt32(byteBuffer, creationTime);\n            IsoTypeWriter.writeUInt32(byteBuffer, modificationTime);\n            IsoTypeWriter.writeUInt32(byteBuffer, timescale);\n            IsoTypeWriter.writeUInt32(byteBuffer, duration);\n        }\n        IsoTypeWriter.writeIso639(byteBuffer, language);\n        IsoTypeWriter.writeUInt16(byteBuffer, 0);\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/MediaInformationBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.googlecode.mp4parser.AbstractContainerBox;\n\n/**\n * This box contains all the objects that declare characteristic information of the media in the track.\n */\npublic class MediaInformationBox extends AbstractContainerBox {\n    public static final String TYPE = \"minf\";\n\n    public MediaInformationBox() {\n        super(TYPE);\n    }\n\n    public SampleTableBox getSampleTableBox() {\n        for (Box box : boxes) {\n            if (box instanceof SampleTableBox) {\n                return (SampleTableBox) box;\n            }\n        }\n        return null;\n    }\n\n    public AbstractMediaHeaderBox getMediaHeaderBox() {\n        for (Box box : boxes) {\n            if (box instanceof AbstractMediaHeaderBox) {\n                return (AbstractMediaHeaderBox) box;\n            }\n        }\n        return null;\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/MetaBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractContainerBox;\nimport com.googlecode.mp4parser.util.ByteBufferByteChannel;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\n\n\n/**\n * A common base structure to contain general metadata. See ISO/IEC 14496-12 Ch. 8.44.1.\n */\npublic class MetaBox extends AbstractContainerBox {\n    private int version = 0;\n    private int flags = 0;\n\n    public static final String TYPE = \"meta\";\n\n    public MetaBox() {\n        super(TYPE);\n    }\n\n    @Override\n    public long getContentSize() {\n        if (isMp4Box()) {\n            // it's a fullbox\n            return 4 + super.getContentSize();\n        } else {\n            // it's an apple metabox\n            return super.getContentSize();\n        }\n    }\n\n    @Override\n    public long getNumOfBytesToFirstChild() {\n        if (isMp4Box()) {\n            // it's a fullbox\n            return 12;\n        } else {\n            // it's an apple metabox\n            return 8;\n        }\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        int pos = content.position();\n        content.get(new byte[4]);\n        String isHdlr = IsoTypeReader.read4cc(content);\n        if (\"hdlr\".equals(isHdlr)) {\n            //  this is apple bullshit - it's NO FULLBOX\n            content.position(pos);\n            version = -1;\n            flags = -1;\n        } else {\n            content.position(pos);\n            version = IsoTypeReader.readUInt8(content);\n            flags = IsoTypeReader.readUInt24(content);\n        }\n        while (content.remaining() >= 8) {\n            try {\n                boxes.add(boxParser.parseBox(new ByteBufferByteChannel(content), this));\n            } catch (IOException e) {\n                throw new RuntimeException(\"Sebastian needs to fix 7518765283\");\n            }\n        }\n        if (content.remaining() > 0) {\n            throw new RuntimeException(\"Sebastian needs to fix it 90732r26537\");\n        }\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        if (isMp4Box()) {\n            IsoTypeWriter.writeUInt8(byteBuffer, version);\n            IsoTypeWriter.writeUInt24(byteBuffer, flags);\n        }\n        writeChildBoxes(byteBuffer);\n    }\n\n\n    public boolean isMp4Box() {\n        return version != -1 && flags != -1;\n    }\n\n    public void setMp4Box(boolean mp4) {\n        if (mp4) {\n            version = 0;\n            flags = 0;\n        } else {\n            version = -1;\n            flags = -1;\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/MovieBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\n\nimport com.googlecode.mp4parser.AbstractBox;\nimport com.googlecode.mp4parser.AbstractContainerBox;\n\nimport java.util.List;\n\n/**\n * The metadata for a presentation is stored in the single Movie Box which occurs at the top-level of a file.\n * Normally this box is close to the beginning or end of the file, though this is not required.\n */\npublic class MovieBox extends AbstractContainerBox {\n    public static final String TYPE = \"moov\";\n\n    public MovieBox() {\n        super(TYPE);\n    }\n\n    public int getTrackCount() {\n        return getBoxes(TrackBox.class).size();\n    }\n\n\n    /**\n     * Returns the track numbers associated with this <code>MovieBox</code>.\n     *\n     * @return the tracknumbers (IDs) of the tracks in their order of appearance in the file\n     */\n    public long[] getTrackNumbers() {\n\n        List<TrackBox> trackBoxes = this.getBoxes(TrackBox.class);\n        long[] trackNumbers = new long[trackBoxes.size()];\n        for (int trackCounter = 0; trackCounter < trackBoxes.size(); trackCounter++) {\n            AbstractBox trackBoxe = trackBoxes.get(trackCounter);\n            TrackBox trackBox = (TrackBox) trackBoxe;\n            trackNumbers[trackCounter] = trackBox.getTrackHeaderBox().getTrackId();\n        }\n        return trackNumbers;\n    }\n\n    public MovieHeaderBox getMovieHeaderBox() {\n        for (Box box : boxes) {\n            if (box instanceof MovieHeaderBox) {\n                return (MovieHeaderBox) box;\n            }\n        }\n        return null;\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/MovieHeaderBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * <code>\n * Box Type: 'mvhd'<br>\n * Container: {@link MovieBox} ('moov')<br>\n * Mandatory: Yes<br>\n * Quantity: Exactly one<br><br>\n * </code>\n * This box defines overall information which is media-independent, and relevant to the entire presentation\n * considered as a whole.\n */\npublic class MovieHeaderBox extends AbstractFullBox {\n    private long creationTime;\n    private long modificationTime;\n    private long timescale;\n    private long duration;\n    private double rate = 1.0;\n    private float volume = 1.0f;\n    private long[] matrix = new long[]{0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000};\n    private long nextTrackId;\n    public static final String TYPE = \"mvhd\";\n\n    public MovieHeaderBox() {\n        super(TYPE);\n    }\n\n    public long getCreationTime() {\n        return creationTime;\n    }\n\n    public long getModificationTime() {\n        return modificationTime;\n    }\n\n    public long getTimescale() {\n        return timescale;\n    }\n\n    public long getDuration() {\n        return duration;\n    }\n\n    public double getRate() {\n        return rate;\n    }\n\n    public float getVolume() {\n        return volume;\n    }\n\n    public long[] getMatrix() {\n        return matrix;\n    }\n\n    public long getNextTrackId() {\n        return nextTrackId;\n    }\n\n    protected long getContentSize() {\n        long contentSize = 4;\n        if (getVersion() == 1) {\n            contentSize += 28;\n        } else {\n            contentSize += 16;\n        }\n        contentSize += 80;\n        return contentSize;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        if (getVersion() == 1) {\n            creationTime = IsoTypeReader.readUInt64(content);\n            modificationTime = IsoTypeReader.readUInt64(content);\n            timescale = IsoTypeReader.readUInt32(content);\n            duration = IsoTypeReader.readUInt64(content);\n        } else {\n            creationTime = IsoTypeReader.readUInt32(content);\n            modificationTime = IsoTypeReader.readUInt32(content);\n            timescale = IsoTypeReader.readUInt32(content);\n            duration = IsoTypeReader.readUInt32(content);\n        }\n        rate = IsoTypeReader.readFixedPoint1616(content);\n        volume = IsoTypeReader.readFixedPoint88(content);\n        IsoTypeReader.readUInt16(content);\n        IsoTypeReader.readUInt32(content);\n        IsoTypeReader.readUInt32(content);\n        matrix = new long[9];\n        for (int i = 0; i < 9; i++) {\n            matrix[i] = IsoTypeReader.readUInt32(content);\n        }\n        for (int i = 0; i < 6; i++) {\n            IsoTypeReader.readUInt32(content);\n        }\n        nextTrackId = IsoTypeReader.readUInt32(content);\n\n    }\n\n    public String toString() {\n        StringBuilder result = new StringBuilder();\n        result.append(\"MovieHeaderBox[\");\n        result.append(\"creationTime=\").append(getCreationTime());\n        result.append(\";\");\n        result.append(\"modificationTime=\").append(getModificationTime());\n        result.append(\";\");\n        result.append(\"timescale=\").append(getTimescale());\n        result.append(\";\");\n        result.append(\"duration=\").append(getDuration());\n        result.append(\";\");\n        result.append(\"rate=\").append(getRate());\n        result.append(\";\");\n        result.append(\"volume=\").append(getVolume());\n        for (int i = 0; i < matrix.length; i++) {\n            result.append(\";\");\n            result.append(\"matrix\").append(i).append(\"=\").append(matrix[i]);\n        }\n        result.append(\";\");\n        result.append(\"nextTrackId=\").append(getNextTrackId());\n        result.append(\"]\");\n        return result.toString();\n    }\n\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        if (getVersion() == 1) {\n            IsoTypeWriter.writeUInt64(byteBuffer, creationTime);\n            IsoTypeWriter.writeUInt64(byteBuffer, modificationTime);\n            IsoTypeWriter.writeUInt32(byteBuffer, timescale);\n            IsoTypeWriter.writeUInt64(byteBuffer, duration);\n        } else {\n            IsoTypeWriter.writeUInt32(byteBuffer, creationTime);\n            IsoTypeWriter.writeUInt32(byteBuffer, modificationTime);\n            IsoTypeWriter.writeUInt32(byteBuffer, timescale);\n            IsoTypeWriter.writeUInt32(byteBuffer, duration);\n        }\n        IsoTypeWriter.writeFixedPont1616(byteBuffer, rate);\n        IsoTypeWriter.writeFixedPont88(byteBuffer, volume);\n        IsoTypeWriter.writeUInt16(byteBuffer, 0);\n        IsoTypeWriter.writeUInt32(byteBuffer, 0);\n        IsoTypeWriter.writeUInt32(byteBuffer, 0);\n\n\n        for (int i = 0; i < 9; i++) {\n            IsoTypeWriter.writeUInt32(byteBuffer, matrix[i]);\n        }\n        for (int i = 0; i < 6; i++) {\n            IsoTypeWriter.writeUInt32(byteBuffer, 0);\n        }\n        IsoTypeWriter.writeUInt32(byteBuffer, nextTrackId);\n    }\n\n\n    public void setCreationTime(long creationTime) {\n        this.creationTime = creationTime;\n    }\n\n    public void setModificationTime(long modificationTime) {\n        this.modificationTime = modificationTime;\n    }\n\n    public void setTimescale(long timescale) {\n        this.timescale = timescale;\n    }\n\n    public void setDuration(long duration) {\n        this.duration = duration;\n    }\n\n    public void setRate(double rate) {\n        this.rate = rate;\n    }\n\n    public void setVolume(float volume) {\n        this.volume = volume;\n    }\n\n    public void setMatrix(long[] matrix) {\n        this.matrix = matrix;\n    }\n\n    public void setNextTrackId(long nextTrackId) {\n        this.nextTrackId = nextTrackId;\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/NullMediaHeaderBox.java",
    "content": "/*\n * Copyright 2011 Sebastian Annies, Hamburg, Germany\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.coremedia.iso.boxes;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Streams other than visual and audio (e.g., timed metadata streams) may use a\n * Null Media Header Box.\n */\npublic class NullMediaHeaderBox extends AbstractMediaHeaderBox {\n    public NullMediaHeaderBox() {\n        super(\"nmhd\");\n    }\n\n    @Override\n    protected long getContentSize() {\n        return 4;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/ObjectDescriptorBox.java",
    "content": ""
  },
  {
    "path": "src/com/coremedia/iso/boxes/OmaDrmAccessUnitFormatBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Describes the format of media access units in PDCF files.\n */\npublic final class OmaDrmAccessUnitFormatBox extends AbstractFullBox {\n    public static final String TYPE = \"odaf\";\n\n    private boolean selectiveEncryption;\n    private byte allBits;\n\n    private int keyIndicatorLength;\n    private int initVectorLength;\n\n    protected long getContentSize() {\n        return 7;\n    }\n\n    public OmaDrmAccessUnitFormatBox() {\n        super(\"odaf\");\n    }\n\n    public boolean isSelectiveEncryption() {\n        return selectiveEncryption;\n    }\n\n    public int getKeyIndicatorLength() {\n        return keyIndicatorLength;\n    }\n\n    public int getInitVectorLength() {\n        return initVectorLength;\n    }\n\n    public void setInitVectorLength(int initVectorLength) {\n        this.initVectorLength = initVectorLength;\n    }\n\n    public void setKeyIndicatorLength(int keyIndicatorLength) {\n        this.keyIndicatorLength = keyIndicatorLength;\n    }\n\n    public void setAllBits(byte allBits) {\n        this.allBits = allBits;\n        selectiveEncryption = (allBits & 0x80) == 0x80;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        allBits = (byte) IsoTypeReader.readUInt8(content);\n        selectiveEncryption = (allBits & 0x80) == 0x80;\n        keyIndicatorLength = IsoTypeReader.readUInt8(content);\n        initVectorLength = IsoTypeReader.readUInt8(content);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt8(byteBuffer, allBits);\n        IsoTypeWriter.writeUInt8(byteBuffer, keyIndicatorLength);\n        IsoTypeWriter.writeUInt8(byteBuffer, initVectorLength);\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/OriginalFormatBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoFile;\nimport com.coremedia.iso.IsoTypeReader;\nimport com.googlecode.mp4parser.AbstractBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * The Original Format Box contains the four-character-code of the original untransformed sample description.\n * See ISO/IEC 14496-12 for details.\n *\n * @see ProtectionSchemeInformationBox\n */\n\npublic class OriginalFormatBox extends AbstractBox {\n    public static final String TYPE = \"frma\";\n\n    private String dataFormat = \"    \";\n\n    public OriginalFormatBox() {\n        super(\"frma\");\n    }\n\n    public String getDataFormat() {\n        return dataFormat;\n    }\n\n\n    public void setDataFormat(String dataFormat) {\n        assert dataFormat.length() == 4;\n        this.dataFormat = dataFormat;\n    }\n\n    protected long getContentSize() {\n        return 4;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        dataFormat = IsoTypeReader.read4cc(content);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        byteBuffer.put(IsoFile.fourCCtoBytes(dataFormat));\n    }\n\n\n    public String toString() {\n        return \"OriginalFormatBox[dataFormat=\" + getDataFormat() + \"]\";\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/PerformerBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Used to give information about the performer. Mostly used in confunction with music files.\n * See 3GPP 26.234 for details.\n */\npublic class PerformerBox extends AbstractFullBox {\n    public static final String TYPE = \"perf\";\n\n    private String language;\n    private String performer;\n\n    public PerformerBox() {\n        super(TYPE);\n    }\n\n    public String getLanguage() {\n        return language;\n    }\n\n    public String getPerformer() {\n        return performer;\n    }\n\n    public void setLanguage(String language) {\n        this.language = language;\n    }\n\n    public void setPerformer(String performer) {\n        this.performer = performer;\n    }\n\n    protected long getContentSize() {\n        return 6 + Utf8.utf8StringLengthInBytes(performer) + 1;\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeIso639(byteBuffer, language);\n        byteBuffer.put(Utf8.convert(performer));\n        byteBuffer.put((byte) 0);\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        language = IsoTypeReader.readIso639(content);\n        performer = IsoTypeReader.readString(content);\n    }\n\n    public String toString() {\n        return \"PerformerBox[language=\" + getLanguage() + \";performer=\" + getPerformer() + \"]\";\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/ProgressiveDownloadInformationBox.java",
    "content": "package com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\nimport java.util.Collections;\nimport java.util.LinkedList;\nimport java.util.List;\n\npublic class ProgressiveDownloadInformationBox extends AbstractFullBox {\n\n\n    List<Entry> entries = Collections.emptyList();\n\n    public ProgressiveDownloadInformationBox() {\n        super(\"pdin\");\n    }\n\n    @Override\n    protected long getContentSize() {\n        return 4 + entries.size() * 8;\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        for (Entry entry : entries) {\n            IsoTypeWriter.writeUInt32(byteBuffer, entry.getRate());\n            IsoTypeWriter.writeUInt32(byteBuffer, entry.getInitialDelay());\n        }\n    }\n\n    public List<Entry> getEntries() {\n        return entries;\n    }\n\n    public void setEntries(List<Entry> entries) {\n        this.entries = entries;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        entries = new LinkedList<Entry>();\n        while (content.remaining() >= 8) {\n            Entry entry = new Entry(IsoTypeReader.readUInt32(content), IsoTypeReader.readUInt32(content));\n            entries.add(entry);\n        }\n    }\n\n\n    public static class Entry {\n        long rate;\n        long initialDelay;\n\n        public Entry(long rate, long initialDelay) {\n            this.rate = rate;\n            this.initialDelay = initialDelay;\n        }\n\n        public long getRate() {\n            return rate;\n        }\n\n        public void setRate(long rate) {\n            this.rate = rate;\n        }\n\n        public long getInitialDelay() {\n            return initialDelay;\n        }\n\n        public void setInitialDelay(long initialDelay) {\n            this.initialDelay = initialDelay;\n        }\n\n        @Override\n        public String toString() {\n            return \"Entry{\" +\n                    \"rate=\" + rate +\n                    \", initialDelay=\" + initialDelay +\n                    '}';\n        }\n    }\n\n    @Override\n    public String toString() {\n        return \"ProgressiveDownloadInfoBox{\" +\n                \"entries=\" + entries +\n                '}';\n    }\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/ProtectionSchemeInformationBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.googlecode.mp4parser.AbstractContainerBox;\n\n/**\n * The <code>ProtectionSchemeInformationBox</code> contains all the information required both\n * to understand the encryption transform applied and its parameters, and also to find other\n * information such as the kind and location of the key management system. It also documents the\n * the original (unencrypted) format of the media. The <code>ProtectionSchemeInformationBox</code>\n * is a container box. It is mandatory in a sample entry that uses a code idicating a\n * protected stream.\n *\n * @see com.coremedia.iso.boxes.odf.OmaDrmKeyManagenentSystemBox\n * @see com.coremedia.iso.boxes.sampleentry.AudioSampleEntry#TYPE_ENCRYPTED\n * @see com.coremedia.iso.boxes.sampleentry.VisualSampleEntry#TYPE_ENCRYPTED\n */\npublic class ProtectionSchemeInformationBox extends AbstractContainerBox {\n    public static final String TYPE = \"sinf\";\n\n    public ProtectionSchemeInformationBox() {\n        super(TYPE);\n\n    }\n\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/RatingBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoFile;\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n\n/**\n * Contained a the <code>UserDataBox</code> and containing information about the media's rating. E.g.\n * PG13or FSK16.\n */\npublic class RatingBox extends AbstractFullBox {\n    public static final String TYPE = \"rtng\";\n\n    private String ratingEntity;\n    private String ratingCriteria;\n    private String language;\n    private String ratingInfo;\n\n    public RatingBox() {\n        super(TYPE);\n    }\n\n\n    public void setRatingEntity(String ratingEntity) {\n        this.ratingEntity = ratingEntity;\n    }\n\n    public void setRatingCriteria(String ratingCriteria) {\n        this.ratingCriteria = ratingCriteria;\n    }\n\n    public void setLanguage(String language) {\n        this.language = language;\n    }\n\n    public void setRatingInfo(String ratingInfo) {\n        this.ratingInfo = ratingInfo;\n    }\n\n    public String getLanguage() {\n        return language;\n    }\n\n    /**\n     * Gets a four-character code that indicates the rating entity grading the asset, e.g., 'BBFC'. The values of this\n     * field should follow common names of worldwide movie rating systems, such as those mentioned in\n     * [http://www.movie-ratings.net/, October 2002].\n     *\n     * @return the rating organization\n     */\n    public String getRatingEntity() {\n        return ratingEntity;\n    }\n\n    /**\n     * Gets the four-character code that indicates which rating criteria are being used for the corresponding rating\n     * entity, e.g., 'PG13'.\n     *\n     * @return the actual rating\n     */\n    public String getRatingCriteria() {\n        return ratingCriteria;\n    }\n\n    public String getRatingInfo() {\n        return ratingInfo;\n    }\n\n    protected long getContentSize() {\n        return 15 + Utf8.utf8StringLengthInBytes(ratingInfo);\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        ratingEntity = IsoTypeReader.read4cc(content);\n        ratingCriteria = IsoTypeReader.read4cc(content);\n        language = IsoTypeReader.readIso639(content);\n        ratingInfo = IsoTypeReader.readString(content);\n\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        byteBuffer.put(IsoFile.fourCCtoBytes(ratingEntity));\n        byteBuffer.put(IsoFile.fourCCtoBytes(ratingCriteria));\n        IsoTypeWriter.writeIso639(byteBuffer, language);\n        byteBuffer.put(Utf8.convert(ratingInfo));\n        byteBuffer.put((byte) 0);\n    }\n\n    public String toString() {\n        StringBuilder buffer = new StringBuilder();\n        buffer.append(\"RatingBox[language=\").append(getLanguage());\n        buffer.append(\"ratingEntity=\").append(getRatingEntity());\n        buffer.append(\";ratingCriteria=\").append(getRatingCriteria());\n        buffer.append(\";language=\").append(getLanguage());\n        buffer.append(\";ratingInfo=\").append(getRatingInfo());\n        buffer.append(\"]\");\n        return buffer.toString();\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/RecordingYearBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n *\n */\npublic class RecordingYearBox extends AbstractFullBox {\n    public static final String TYPE = \"yrrc\";\n\n    int recordingYear;\n\n    public RecordingYearBox() {\n        super(TYPE);\n    }\n\n\n    protected long getContentSize() {\n        return 6;\n    }\n\n    public int getRecordingYear() {\n        return recordingYear;\n    }\n\n    public void setRecordingYear(int recordingYear) {\n        this.recordingYear = recordingYear;\n    }\n\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        recordingYear = IsoTypeReader.readUInt16(content);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt16(byteBuffer, recordingYear);\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/SampleAuxiliaryInformationOffsetsBox.java",
    "content": "/*\n * Copyright 2009 castLabs GmbH, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\nimport java.util.LinkedList;\nimport java.util.List;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\n/*\naligned(8) class SampleAuxiliaryInformationOffsetsBox\n            extends FullBox(‘saio’, version, flags)\n{\n            if (flags & 1) {\n                        unsigned int(32) aux_info_type;\n                        unsigned int(32) aux_info_type_parameter;\n            }\n            unsigned int(32) entry_count;\n            if ( version == 0 )\n            {\n                        unsigned int(32) offset[ entry_count ];\n            }\n            else\n            {\n                        unsigned int(64) offset[ entry_count ];\n            }\n}\n */\npublic class SampleAuxiliaryInformationOffsetsBox extends AbstractFullBox {\n    public static final String TYPE = \"saio\";\n\n    private List<Long> offsets = new LinkedList<Long>();\n    private long auxInfoType;\n    private long auxInfoTypeParameter;\n\n    public SampleAuxiliaryInformationOffsetsBox() {\n        super(TYPE);\n    }\n\n    @Override\n    protected long getContentSize() {\n        return 8 + (getVersion() == 0 ? 4 * offsets.size() : 8 * offsets.size()) + ((getFlags() & 1) == 1 ? 8 : 0);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        if ((getFlags() & 1) == 1) {\n            IsoTypeWriter.writeUInt32(byteBuffer, auxInfoType);\n            IsoTypeWriter.writeUInt32(byteBuffer, auxInfoTypeParameter);\n        }\n\n        IsoTypeWriter.writeUInt32(byteBuffer, offsets.size());\n        for (Long offset : offsets) {\n            if (getVersion() == 0) {\n                IsoTypeWriter.writeUInt32(byteBuffer, offset);\n            } else {\n                IsoTypeWriter.writeUInt64(byteBuffer, offset);\n            }\n        }\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n\n        if ((getFlags() & 1) == 1) {\n            auxInfoType = IsoTypeReader.readUInt32(content);\n            auxInfoTypeParameter = IsoTypeReader.readUInt32(content);\n        }\n\n        int entryCount = l2i(IsoTypeReader.readUInt32(content));\n        offsets.clear();\n\n        for (int i = 0; i < entryCount; i++) {\n            if (getVersion() == 0) {\n                offsets.add(IsoTypeReader.readUInt32(content));\n            } else {\n                offsets.add(IsoTypeReader.readUInt64(content));\n            }\n        }\n    }\n\n\n    public long getAuxInfoType() {\n        return auxInfoType;\n    }\n\n    public void setAuxInfoType(long auxInfoType) {\n        this.auxInfoType = auxInfoType;\n    }\n\n    public long getAuxInfoTypeParameter() {\n        return auxInfoTypeParameter;\n    }\n\n    public void setAuxInfoTypeParameter(long auxInfoTypeParameter) {\n        this.auxInfoTypeParameter = auxInfoTypeParameter;\n    }\n\n    public List<Long> getOffsets() {\n        return offsets;\n    }\n\n    public void setOffsets(List<Long> offsets) {\n        this.offsets = offsets;\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/SampleAuxiliaryInformationSizesBox.java",
    "content": "/*\n * Copyright 2009 castLabs GmbH, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoFile;\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\nimport java.util.LinkedList;\nimport java.util.List;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\npublic class SampleAuxiliaryInformationSizesBox extends AbstractFullBox {\n    public static final String TYPE = \"saiz\";\n\n    private int defaultSampleInfoSize;\n    private List<Short> sampleInfoSizes = new LinkedList<Short>();\n    private int sampleCount;\n    private String auxInfoType;\n    private String auxInfoTypeParameter;\n\n    public SampleAuxiliaryInformationSizesBox() {\n        super(TYPE);\n    }\n\n    @Override\n    protected long getContentSize() {\n        int size = 4;\n        if ((getFlags() & 1) == 1) {\n            size += 8;\n        }\n\n        size += 5;\n        size += sampleInfoSizes.size();\n        return size;\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        if ((getFlags() & 1) == 1) {\n            byteBuffer.put(IsoFile.fourCCtoBytes(auxInfoType));\n            byteBuffer.put(IsoFile.fourCCtoBytes(auxInfoTypeParameter));\n        }\n\n        IsoTypeWriter.writeUInt8(byteBuffer, defaultSampleInfoSize);\n        if (defaultSampleInfoSize == 0) {\n            IsoTypeWriter.writeUInt32(byteBuffer, sampleInfoSizes.size());\n            for (short sampleInfoSize : sampleInfoSizes) {\n                IsoTypeWriter.writeUInt8(byteBuffer, sampleInfoSize);\n            }\n        } else {\n            IsoTypeWriter.writeUInt32(byteBuffer, sampleCount);\n        }\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        if ((getFlags() & 1) == 1) {\n            auxInfoType = IsoTypeReader.read4cc(content);\n            auxInfoTypeParameter = IsoTypeReader.read4cc(content);\n        }\n\n        defaultSampleInfoSize = (short) IsoTypeReader.readUInt8(content);\n        int sampleCount = l2i(IsoTypeReader.readUInt32(content));\n\n        sampleInfoSizes.clear();\n\n        for (int i = 0; i < sampleCount; i++) {\n            sampleInfoSizes.add((short) IsoTypeReader.readUInt8(content));\n        }\n    }\n\n    public String getAuxInfoType() {\n        return auxInfoType;\n    }\n\n    public void setAuxInfoType(String auxInfoType) {\n        this.auxInfoType = auxInfoType;\n    }\n\n    public String getAuxInfoTypeParameter() {\n        return auxInfoTypeParameter;\n    }\n\n    public void setAuxInfoTypeParameter(String auxInfoTypeParameter) {\n        this.auxInfoTypeParameter = auxInfoTypeParameter;\n    }\n\n    public int getDefaultSampleInfoSize() {\n        return defaultSampleInfoSize;\n    }\n\n    public void setDefaultSampleInfoSize(int defaultSampleInfoSize) {\n        assert defaultSampleInfoSize <= 255;\n        assert defaultSampleInfoSize > 0;\n        this.defaultSampleInfoSize = defaultSampleInfoSize;\n    }\n\n\n    public List<Short> getSampleInfoSizes() {\n        return sampleInfoSizes;\n    }\n\n    public void setSampleInfoSizes(List<Short> sampleInfoSizes) {\n        this.sampleInfoSizes = sampleInfoSizes;\n    }\n\n    public int getSampleCount() {\n        return sampleCount;\n    }\n\n    public void setSampleCount(int sampleCount) {\n        this.sampleCount = sampleCount;\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/SampleDependencyTypeBox.java",
    "content": "/*\n * Copyright 2009 castLabs GmbH, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * aligned(8) class SampleDependencyTypeBox\n * extends FullBox('sdtp', version = 0, 0) {\n * for (i=0; i < sample_count; i++){\n * unsigned int(2) reserved = 0;\n * unsigned int(2) sample_depends_on;\n * unsigned int(2) sample_is_depended_on;\n * unsigned int(2) sample_has_redundancy;\n * }\n * }\n */\npublic class SampleDependencyTypeBox extends AbstractFullBox {\n    public static final String TYPE = \"sdtp\";\n\n    private List<Entry> entries = new ArrayList<Entry>();\n\n    public static class Entry {\n\n        public Entry(int value) {\n            this.value = value;\n        }\n\n        private int value;\n\n\n        public int getReserved() {\n            return (value >> 6) & 0x03;\n        }\n\n        public void setReserved(int res) {\n            value = (res & 0x03) << 6 | value & 0x3f;\n        }\n\n        public int getSampleDependsOn() {\n            return (value >> 4) & 0x03;\n        }\n\n        public void setSampleDependsOn(int sdo) {\n            value = (sdo & 0x03) << 4 | value & 0xcf;\n        }\n\n        public int getSampleIsDependentOn() {\n            return (value >> 2) & 0x03;\n        }\n\n        public void setSampleIsDependentOn(int sido) {\n            value = (sido & 0x03) << 2 | value & 0xf3;\n        }\n\n        public int getSampleHasRedundancy() {\n            return value & 0x03;\n        }\n\n        public void setSampleHasRedundancy(int shr) {\n            value = shr & 0x03 | value & 0xfc;\n        }\n\n        @Override\n        public String toString() {\n            return \"Entry{\" +\n                    \"reserved=\" + getReserved() +\n                    \", sampleDependsOn=\" + getSampleDependsOn() +\n                    \", sampleIsDependentOn=\" + getSampleIsDependentOn() +\n                    \", sampleHasRedundancy=\" + getSampleHasRedundancy() +\n                    '}';\n        }\n    }\n\n    public SampleDependencyTypeBox() {\n        super(TYPE);\n    }\n\n    @Override\n    protected long getContentSize() {\n        return 4 + entries.size();\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        for (Entry entry : entries) {\n            IsoTypeWriter.writeUInt8(byteBuffer, entry.value);\n        }\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        while (content.remaining() > 0) {\n            entries.add(new Entry(IsoTypeReader.readUInt8(content)));\n        }\n    }\n\n    public List<Entry> getEntries() {\n        return entries;\n    }\n\n    public void setEntries(List<Entry> entries) {\n        this.entries = entries;\n    }\n\n    @Override\n    public String toString() {\n        final StringBuilder sb = new StringBuilder();\n        sb.append(\"SampleDependencyTypeBox\");\n        sb.append(\"{entries=\").append(entries);\n        sb.append('}');\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/SampleDescriptionBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.boxes.sampleentry.SampleEntry;\nimport com.googlecode.mp4parser.FullContainerBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * The sample description table gives detailed information about the coding type used, and any initialization\n * information needed for that coding. <br>\n * The information stored in the sample description box after the entry-count is both track-type specific as\n * documented here, and can also have variants within a track type (e.g. different codings may use different\n * specific information after some common fields, even within a video track).<br>\n * For video tracks, a VisualSampleEntry is used; for audio tracks, an AudioSampleEntry. Hint tracks use an\n * entry format specific to their protocol, with an appropriate name. Timed Text tracks use a TextSampleEntry\n * For hint tracks, the sample description contains appropriate declarative data for the streaming protocol being\n * used, and the format of the hint track. The definition of the sample description is specific to the protocol.\n * Multiple descriptions may be used within a track.<br>\n * The 'protocol' and 'codingname' fields are registered identifiers that uniquely identify the streaming protocol or\n * compression format decoder to be used. A given protocol or codingname may have optional or required\n * extensions to the sample description (e.g. codec initialization parameters). All such extensions shall be within\n * boxes; these boxes occur after the required fields. Unrecognized boxes shall be ignored.\n * <br>\n * Defined in ISO/IEC 14496-12\n *\n * @see com.coremedia.iso.boxes.sampleentry.VisualSampleEntry\n * @see com.coremedia.iso.boxes.sampleentry.TextSampleEntry\n * @see com.coremedia.iso.boxes.sampleentry.AudioSampleEntry\n */\npublic class SampleDescriptionBox extends FullContainerBox {\n    public static final String TYPE = \"stsd\";\n\n    public SampleDescriptionBox() {\n        super(TYPE);\n    }\n\n    @Override\n    protected long getContentSize() {\n        return super.getContentSize() + 4;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        content.get(new byte[4]);\n        parseChildBoxes(content);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt32(byteBuffer, boxes.size());\n        writeChildBoxes(byteBuffer);\n    }\n\n    public SampleEntry getSampleEntry() {\n        for (Box box : boxes) {\n            if (box instanceof SampleEntry) {\n                return (SampleEntry) box;\n            }\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/SampleSizeBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\n/**\n * This box containes the sample count and a table giving the size in bytes of each sample.\n * Defined in ISO/IEC 14496-12.\n */\npublic class SampleSizeBox extends AbstractFullBox {\n    private long sampleSize;\n    private long[] sampleSizes = new long[0];\n    public static final String TYPE = \"stsz\";\n    int sampleCount;\n\n    public SampleSizeBox() {\n        super(TYPE);\n    }\n\n    /**\n     * Returns the field sample size.\n     * If sampleSize > 0 every sample has the same size.\n     * If sampleSize == 0 the samples have different size as stated in the sampleSizes field.\n     *\n     * @return the sampleSize field\n     */\n    public long getSampleSize() {\n        return sampleSize;\n    }\n\n    public void setSampleSize(long sampleSize) {\n        this.sampleSize = sampleSize;\n    }\n\n\n    public long getSampleSizeAtIndex(int index) {\n        if (sampleSize > 0) {\n            return sampleSize;\n        } else {\n            return sampleSizes[index];\n        }\n    }\n\n    public long getSampleCount() {\n        if (sampleSize > 0) {\n            return sampleCount;\n        } else {\n            return sampleSizes.length;\n        }\n\n    }\n\n    public long[] getSampleSizes() {\n        return sampleSizes;\n    }\n\n    public void setSampleSizes(long[] sampleSizes) {\n        this.sampleSizes = sampleSizes;\n    }\n\n    protected long getContentSize() {\n        return 12 + (sampleSize == 0 ? sampleSizes.length * 4 : 0);\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        sampleSize = IsoTypeReader.readUInt32(content);\n        sampleCount = l2i(IsoTypeReader.readUInt32(content));\n\n        if (sampleSize == 0) {\n            sampleSizes = new long[(int) sampleCount];\n\n            for (int i = 0; i < sampleCount; i++) {\n                sampleSizes[i] = IsoTypeReader.readUInt32(content);\n            }\n        }\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt32(byteBuffer, sampleSize);\n\n        if (sampleSize == 0) {\n            IsoTypeWriter.writeUInt32(byteBuffer, sampleSizes.length);\n            for (long sampleSize1 : sampleSizes) {\n                IsoTypeWriter.writeUInt32(byteBuffer, sampleSize1);\n            }\n        } else {\n            IsoTypeWriter.writeUInt32(byteBuffer, sampleCount);\n        }\n\n    }\n\n    public String toString() {\n        return \"SampleSizeBox[sampleSize=\" + getSampleSize() + \";sampleCount=\" + getSampleCount() + \"]\";\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/SampleTableBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.googlecode.mp4parser.AbstractContainerBox;\n\n/**\n * The sample table contains all the time and data indexing of the media samples in a track. Using the tables\n * here, it is possible to locate samples in time, determine their type (e.g. I-frame or not), and determine their\n * size, container, and offset into that container.  <br>\n * If the track that contains the Sample Table Box references no data, then the Sample Table Box does not need\n * to contain any sub-boxes (this is not a very useful media track).                                          <br>\n * If the track that the Sample Table Box is contained in does reference data, then the following sub-boxes are\n * required: Sample Description, Sample Size, Sample To Chunk, and Chunk Offset. Further, the Sample\n * Description Box shall contain at least one entry. A Sample Description Box is required because it contains the\n * data reference index field which indicates which Data Reference Box to use to retrieve the media samples.\n * Without the Sample Description, it is not possible to determine where the media samples are stored. The Sync\n * Sample Box is optional. If the Sync Sample Box is not present, all samples are sync samples.<br>\n * Annex A provides a narrative description of random access using the structures defined in the Sample Table\n * Box.\n */\npublic class SampleTableBox extends AbstractContainerBox {\n    public static final String TYPE = \"stbl\";\n\n    public SampleTableBox() {\n        super(TYPE);\n    }\n\n    public SampleDescriptionBox getSampleDescriptionBox() {\n        for (Box box : boxes) {\n            if (box instanceof SampleDescriptionBox) {\n                return (SampleDescriptionBox) box;\n            }\n        }\n        return null;\n    }\n\n    public SampleSizeBox getSampleSizeBox() {\n        for (Box box : boxes) {\n            if (box instanceof SampleSizeBox) {\n                return (SampleSizeBox) box;\n            }\n        }\n        return null;\n    }\n\n    public SampleToChunkBox getSampleToChunkBox() {\n        for (Box box : boxes) {\n            if (box instanceof SampleToChunkBox) {\n                return (SampleToChunkBox) box;\n            }\n        }\n        return null;\n    }\n\n    public ChunkOffsetBox getChunkOffsetBox() {\n        for (Box box : boxes) {\n            if (box instanceof ChunkOffsetBox) {\n                return (ChunkOffsetBox) box;\n            }\n        }\n        return null;\n    }\n\n    public void setChunkOffsetBox(ChunkOffsetBox b) {\n        for (int i = 0; i < boxes.size(); i++) {\n            Box box = boxes.get(i);\n            if (box instanceof ChunkOffsetBox) {\n                boxes.set(i, b);\n            }\n        }\n    }\n\n    public TimeToSampleBox getTimeToSampleBox() {\n        for (Box box : boxes) {\n            if (box instanceof TimeToSampleBox) {\n                return (TimeToSampleBox) box;\n            }\n        }\n        return null;\n    }\n\n    public SyncSampleBox getSyncSampleBox() {\n        for (Box box : boxes) {\n            if (box instanceof SyncSampleBox) {\n                return (SyncSampleBox) box;\n            }\n        }\n        return null;\n    }\n\n    public CompositionTimeToSample getCompositionTimeToSample() {\n        for (Box box : boxes) {\n            if (box instanceof CompositionTimeToSample) {\n                return (CompositionTimeToSample) box;\n            }\n        }\n        return null;\n    }\n\n    public SampleDependencyTypeBox getSampleDependencyTypeBox() {\n        for (Box box : boxes) {\n            if (box instanceof SampleDependencyTypeBox) {\n                return (SampleDependencyTypeBox) box;\n            }\n        }\n        return null;\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/SampleToChunkBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Iterator;\nimport java.util.LinkedList;\nimport java.util.List;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\n/**\n * Samples within the media data are grouped into chunks. Chunks can be of different sizes, and the\n * samples within a chunk can have different sizes. This table can be used to find the chunk that\n * contains a sample, its position, and the associated sample description. Defined in ISO/IEC 14496-12.\n */\npublic class SampleToChunkBox extends AbstractFullBox {\n    List<Entry> entries = Collections.emptyList();\n\n    public static final String TYPE = \"stsc\";\n\n    public SampleToChunkBox() {\n        super(TYPE);\n    }\n\n    public List<Entry> getEntries() {\n        return entries;\n    }\n\n    public void setEntries(List<Entry> entries) {\n        this.entries = entries;\n    }\n\n    protected long getContentSize() {\n        return entries.size() * 12 + 8;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n\n        int entryCount = l2i(IsoTypeReader.readUInt32(content));\n        entries = new ArrayList<Entry>(entryCount);\n        for (int i = 0; i < entryCount; i++) {\n            entries.add(new Entry(\n                    IsoTypeReader.readUInt32(content),\n                    IsoTypeReader.readUInt32(content),\n                    IsoTypeReader.readUInt32(content)));\n        }\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt32(byteBuffer, entries.size());\n        for (Entry entry : entries) {\n            IsoTypeWriter.writeUInt32(byteBuffer, entry.getFirstChunk());\n            IsoTypeWriter.writeUInt32(byteBuffer, entry.getSamplesPerChunk());\n            IsoTypeWriter.writeUInt32(byteBuffer, entry.getSampleDescriptionIndex());\n        }\n    }\n\n    public String toString() {\n        return \"SampleToChunkBox[entryCount=\" + entries.size() + \"]\";\n    }\n\n    /**\n     * Decompresses the list of entries and returns the number of samples per chunk for\n     * every single chunk.\n     *\n     * @param chunkCount overall number of chunks\n     * @return number of samples per chunk\n     */\n    public long[] blowup(int chunkCount) {\n        long[] numberOfSamples = new long[chunkCount];\n        int j = 0;\n        List<SampleToChunkBox.Entry> sampleToChunkEntries = new LinkedList<Entry>(entries);\n        Collections.reverse(sampleToChunkEntries);\n        Iterator<Entry> iterator = sampleToChunkEntries.iterator();\n        SampleToChunkBox.Entry currentEntry = iterator.next();\n\n        for (int i = numberOfSamples.length; i > 1; i--) {\n            numberOfSamples[i - 1] = currentEntry.getSamplesPerChunk();\n            if (i == currentEntry.getFirstChunk()) {\n                currentEntry = iterator.next();\n            }\n        }\n        numberOfSamples[0] = currentEntry.getSamplesPerChunk();\n        return numberOfSamples;\n    }\n\n    public static class Entry {\n        long firstChunk;\n        long samplesPerChunk;\n        long sampleDescriptionIndex;\n\n        public Entry(long firstChunk, long samplesPerChunk, long sampleDescriptionIndex) {\n            this.firstChunk = firstChunk;\n            this.samplesPerChunk = samplesPerChunk;\n            this.sampleDescriptionIndex = sampleDescriptionIndex;\n        }\n\n        public long getFirstChunk() {\n            return firstChunk;\n        }\n\n        public void setFirstChunk(long firstChunk) {\n            this.firstChunk = firstChunk;\n        }\n\n        public long getSamplesPerChunk() {\n            return samplesPerChunk;\n        }\n\n        public void setSamplesPerChunk(long samplesPerChunk) {\n            this.samplesPerChunk = samplesPerChunk;\n        }\n\n        public long getSampleDescriptionIndex() {\n            return sampleDescriptionIndex;\n        }\n\n        public void setSampleDescriptionIndex(long sampleDescriptionIndex) {\n            this.sampleDescriptionIndex = sampleDescriptionIndex;\n        }\n\n        @Override\n        public String toString() {\n            return \"Entry{\" +\n                    \"firstChunk=\" + firstChunk +\n                    \", samplesPerChunk=\" + samplesPerChunk +\n                    \", sampleDescriptionIndex=\" + sampleDescriptionIndex +\n                    '}';\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/SampleToGroupBox.java",
    "content": "package com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * aligned(8) class SampleToGroupBox\n * extends FullBox('sbgp', version = 0, 0)\n * {\n * unsigned int(32) grouping_type;\n * unsigned int(32) entry_count;\n * for (i=1; i <= entry_count; i++)\n * {\n * unsigned int(32) sample_count;\n * unsigned int(32) group_description_index;\n * }\n * }\n */\npublic class SampleToGroupBox extends AbstractFullBox {\n    public static final String TYPE = \"sbgp\";\n    private long groupingType;\n    private long entryCount;\n    private long groupingTypeParameter;\n    private List<Entry> entries = new ArrayList<Entry>();\n\n    public SampleToGroupBox() {\n        super(TYPE);\n    }\n\n    @Override\n    protected long getContentSize() {\n        return 12 + entryCount * 8;\n    }\n\n    public long getGroupingTypeParameter() {\n        return groupingTypeParameter;\n    }\n\n    /**\n     * Usage of this parameter requires version == 1. The version must be set manually.\n     */\n    public void setGroupingTypeParameter(long groupingTypeParameter) {\n        this.groupingTypeParameter = groupingTypeParameter;\n    }\n\n    public List<Entry> getEntries() {\n        return entries;\n    }\n\n    public void setEntries(List<Entry> entries) {\n        this.entries = entries;\n    }\n\n    public long getGroupingType() {\n        return groupingType;\n    }\n\n\n    public void setGroupingType(long groupingType) {\n        this.groupingType = groupingType;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        groupingType = IsoTypeReader.readUInt32(content);\n        if (getVersion() == 1) {\n            groupingTypeParameter = IsoTypeReader.readUInt32(content);\n        } else {\n            groupingTypeParameter = -1;\n        }\n        entryCount = IsoTypeReader.readUInt32(content);\n\n        for (int i = 0; i < entryCount; i++) {\n            Entry entry = new Entry();\n            entry.setSampleCount(IsoTypeReader.readUInt32(content));\n            entry.setGroupDescriptionIndex(IsoTypeReader.readUInt32(content));\n            entries.add(entry);\n        }\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n\n        IsoTypeWriter.writeUInt32(byteBuffer, groupingType);\n        if (getVersion() == 1) {\n            IsoTypeWriter.writeUInt32(byteBuffer, groupingTypeParameter);\n        }\n        IsoTypeWriter.writeUInt32(byteBuffer, entryCount);\n        for (Entry entry : entries) {\n            IsoTypeWriter.writeUInt32(byteBuffer, entry.getSampleCount());\n            IsoTypeWriter.writeUInt32(byteBuffer, entry.getGroupDescriptionIndex());\n        }\n    }\n\n    public static class Entry {\n        private long sampleCount;\n        private long groupDescriptionIndex;\n\n        public long getSampleCount() {\n            return sampleCount;\n        }\n\n        public void setSampleCount(long sampleCount) {\n            this.sampleCount = sampleCount;\n        }\n\n        public long getGroupDescriptionIndex() {\n            return groupDescriptionIndex;\n        }\n\n        public void setGroupDescriptionIndex(long groupDescriptionIndex) {\n            this.groupDescriptionIndex = groupDescriptionIndex;\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/SchemeInformationBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.googlecode.mp4parser.AbstractContainerBox;\n\n/**\n * The Scheme Information Box is a container box that is only interpreted by the scheme beeing used.\n * Any information the encryption system needs is stored here. The content of this box is a series of\n * boxexes whose type annd format are defined by the scheme declared in the {@link com.coremedia.iso.boxes.SchemeTypeBox}.\n */\npublic class SchemeInformationBox extends AbstractContainerBox {\n    public static final String TYPE = \"schi\";\n\n    public SchemeInformationBox() {\n        super(TYPE);\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/SchemeTypeBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoFile;\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * The Scheme Type Box identifies the protection scheme. Resides in  a Protection Scheme Information Box or\n * an SRTP Process Box.\n *\n * @see com.coremedia.iso.boxes.SchemeInformationBox\n */\npublic class SchemeTypeBox extends AbstractFullBox {\n    public static final String TYPE = \"schm\";\n    String schemeType = \"    \";\n    long schemeVersion;\n    String schemeUri = null;\n\n    public SchemeTypeBox() {\n        super(TYPE);\n    }\n\n    public String getSchemeType() {\n        return schemeType;\n    }\n\n    public long getSchemeVersion() {\n        return schemeVersion;\n    }\n\n    public String getSchemeUri() {\n        return schemeUri;\n    }\n\n    public void setSchemeType(String schemeType) {\n        assert schemeType != null && schemeType.length() == 4 : \"SchemeType may not be null or not 4 bytes long\";\n        this.schemeType = schemeType;\n    }\n\n    public void setSchemeVersion(int schemeVersion) {\n        this.schemeVersion = schemeVersion;\n    }\n\n    public void setSchemeUri(String schemeUri) {\n        this.schemeUri = schemeUri;\n    }\n\n    protected long getContentSize() {\n        return 12 + (((getFlags() & 1) == 1) ? Utf8.utf8StringLengthInBytes(schemeUri) + 1 : 0);\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        schemeType = IsoTypeReader.read4cc(content);\n        schemeVersion = IsoTypeReader.readUInt32(content);\n        if ((getFlags() & 1) == 1) {\n            schemeUri = IsoTypeReader.readString(content);\n        }\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        byteBuffer.put(IsoFile.fourCCtoBytes(schemeType));\n        IsoTypeWriter.writeUInt32(byteBuffer, schemeVersion);\n        if ((getFlags() & 1) == 1) {\n            byteBuffer.put(Utf8.convert(schemeUri));\n        }\n    }\n\n    public String toString() {\n        StringBuilder buffer = new StringBuilder();\n        buffer.append(\"Schema Type Box[\");\n        buffer.append(\"schemeUri=\").append(schemeUri).append(\"; \");\n        buffer.append(\"schemeType=\").append(schemeType).append(\"; \");\n        buffer.append(\"schemeVersion=\").append(schemeUri).append(\"; \");\n        buffer.append(\"]\");\n        return buffer.toString();\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/SoundMediaHeaderBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\n\nimport java.nio.ByteBuffer;\n\npublic class SoundMediaHeaderBox extends AbstractMediaHeaderBox {\n\n    public static final String TYPE = \"smhd\";\n    private float balance;\n\n    public SoundMediaHeaderBox() {\n        super(TYPE);\n    }\n\n    public float getBalance() {\n        return balance;\n    }\n\n    protected long getContentSize() {\n        return 8;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        balance = IsoTypeReader.readFixedPoint88(content);\n        IsoTypeReader.readUInt16(content);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeFixedPont88(byteBuffer, balance);\n        IsoTypeWriter.writeUInt16(byteBuffer, 0);\n    }\n\n    public String toString() {\n        return \"SoundMediaHeaderBox[balance=\" + getBalance() + \"]\";\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/StaticChunkOffsetBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\n\nimport java.nio.ByteBuffer;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\n/**\n * The chunk offset table gives the index of each chunk into the containing file. Defined in ISO/IEC 14496-12.\n */\npublic class StaticChunkOffsetBox extends ChunkOffsetBox {\n    public static final String TYPE = \"stco\";\n\n    private long[] chunkOffsets = new long[0];\n\n    public StaticChunkOffsetBox() {\n        super(TYPE);\n    }\n\n    public long[] getChunkOffsets() {\n        return chunkOffsets;\n    }\n\n    protected long getContentSize() {\n        return 8 + chunkOffsets.length * 4;\n    }\n\n    public void setChunkOffsets(long[] chunkOffsets) {\n        this.chunkOffsets = chunkOffsets;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        int entryCount = l2i(IsoTypeReader.readUInt32(content));\n        chunkOffsets = new long[entryCount];\n        for (int i = 0; i < entryCount; i++) {\n            chunkOffsets[i] = IsoTypeReader.readUInt32(content);\n        }\n\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt32(byteBuffer, chunkOffsets.length);\n        for (long chunkOffset : chunkOffsets) {\n            IsoTypeWriter.writeUInt32(byteBuffer, chunkOffset);\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/SubSampleInformationBox.java",
    "content": "package com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\n/**\n * aligned(8) class SubSampleInformationBox\n * extends FullBox('subs', version, 0) {\n * unsigned int(32) entry_count;\n * int i,j;\n * for (i=0; i < entry_count; i++) {\n * unsigned int(32) sample_delta;\n * unsigned int(16) subsample_count;\n * if (subsample_count > 0) {\n * for (j=0; j < subsample_count; j++) {\n * if(version == 1)\n * {\n * unsigned int(32) subsample_size;\n * }\n * else\n * {\n * unsigned int(16) subsample_size;\n * }\n * unsigned int(8) subsample_priority;\n * unsigned int(8) discardable;\n * unsigned int(32) reserved = 0;\n * }\n * }\n * }\n * }\n */\npublic class SubSampleInformationBox extends AbstractFullBox {\n    public static final String TYPE = \"subs\";\n\n    private long entryCount;\n    private List<SampleEntry> entries = new ArrayList<SampleEntry>();\n\n    public SubSampleInformationBox() {\n        super(TYPE);\n    }\n\n    public List<SampleEntry> getEntries() {\n        return entries;\n    }\n\n    public void setEntries(List<SampleEntry> entries) {\n        this.entries = entries;\n        entryCount = entries.size();\n    }\n\n    @Override\n    protected long getContentSize() {\n        long entries = 8 + ((4 + 2) * entryCount);\n        int subsampleEntries = 0;\n        for (SampleEntry sampleEntry : this.entries) {\n            subsampleEntries += sampleEntry.getSubsampleCount() * (((getVersion() == 1) ? 4 : 2) + 1 + 1 + 4);\n        }\n        return entries + subsampleEntries;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n\n        entryCount = IsoTypeReader.readUInt32(content);\n\n        for (int i = 0; i < entryCount; i++) {\n            SampleEntry sampleEntry = new SampleEntry();\n            sampleEntry.setSampleDelta(IsoTypeReader.readUInt32(content));\n            int subsampleCount = IsoTypeReader.readUInt16(content);\n            for (int j = 0; j < subsampleCount; j++) {\n                SampleEntry.SubsampleEntry subsampleEntry = new SampleEntry.SubsampleEntry();\n                subsampleEntry.setSubsampleSize(getVersion() == 1 ? IsoTypeReader.readUInt32(content) : IsoTypeReader.readUInt16(content));\n                subsampleEntry.setSubsamplePriority(IsoTypeReader.readUInt8(content));\n                subsampleEntry.setDiscardable(IsoTypeReader.readUInt8(content));\n                subsampleEntry.setReserved(IsoTypeReader.readUInt32(content));\n                sampleEntry.addSubsampleEntry(subsampleEntry);\n            }\n            entries.add(sampleEntry);\n        }\n\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt32(byteBuffer, entries.size());\n        for (SampleEntry sampleEntry : entries) {\n            IsoTypeWriter.writeUInt32(byteBuffer, sampleEntry.getSampleDelta());\n            IsoTypeWriter.writeUInt16(byteBuffer, sampleEntry.getSubsampleCount());\n            List<SampleEntry.SubsampleEntry> subsampleEntries = sampleEntry.getSubsampleEntries();\n            for (SampleEntry.SubsampleEntry subsampleEntry : subsampleEntries) {\n                if (getVersion() == 1) {\n                    IsoTypeWriter.writeUInt32(byteBuffer, subsampleEntry.getSubsampleSize());\n                } else {\n                    IsoTypeWriter.writeUInt16(byteBuffer, l2i(subsampleEntry.getSubsampleSize()));\n                }\n                IsoTypeWriter.writeUInt8(byteBuffer, subsampleEntry.getSubsamplePriority());\n                IsoTypeWriter.writeUInt8(byteBuffer, subsampleEntry.getDiscardable());\n                IsoTypeWriter.writeUInt32(byteBuffer, subsampleEntry.getReserved());\n            }\n        }\n    }\n\n    @Override\n    public String toString() {\n        return \"SubSampleInformationBox{\" +\n                \"entryCount=\" + entryCount +\n                \", entries=\" + entries +\n                '}';\n    }\n\n    public static class SampleEntry {\n        private long sampleDelta;\n        private int subsampleCount;\n        private List<SubsampleEntry> subsampleEntries = new ArrayList<SubsampleEntry>();\n\n        public long getSampleDelta() {\n            return sampleDelta;\n        }\n\n        public void setSampleDelta(long sampleDelta) {\n            this.sampleDelta = sampleDelta;\n        }\n\n        public int getSubsampleCount() {\n            return subsampleCount;\n        }\n\n        public void setSubsampleCount(int subsampleCount) {\n            this.subsampleCount = subsampleCount;\n        }\n\n        public List<SubsampleEntry> getSubsampleEntries() {\n            return subsampleEntries;\n        }\n\n        public void addSubsampleEntry(SubsampleEntry subsampleEntry) {\n            subsampleEntries.add(subsampleEntry);\n            subsampleCount++;\n        }\n\n        public static class SubsampleEntry {\n            private long subsampleSize;\n            private int subsamplePriority;\n            private int discardable;\n            private long reserved;\n\n            public long getSubsampleSize() {\n                return subsampleSize;\n            }\n\n            public void setSubsampleSize(long subsampleSize) {\n                this.subsampleSize = subsampleSize;\n            }\n\n            public int getSubsamplePriority() {\n                return subsamplePriority;\n            }\n\n            public void setSubsamplePriority(int subsamplePriority) {\n                this.subsamplePriority = subsamplePriority;\n            }\n\n            public int getDiscardable() {\n                return discardable;\n            }\n\n            public void setDiscardable(int discardable) {\n                this.discardable = discardable;\n            }\n\n            public long getReserved() {\n                return reserved;\n            }\n\n            public void setReserved(long reserved) {\n                this.reserved = reserved;\n            }\n\n            @Override\n            public String toString() {\n                return \"SubsampleEntry{\" +\n                        \"subsampleSize=\" + subsampleSize +\n                        \", subsamplePriority=\" + subsamplePriority +\n                        \", discardable=\" + discardable +\n                        \", reserved=\" + reserved +\n                        '}';\n            }\n        }\n\n        @Override\n        public String toString() {\n            return \"SampleEntry{\" +\n                    \"sampleDelta=\" + sampleDelta +\n                    \", subsampleCount=\" + subsampleCount +\n                    \", subsampleEntries=\" + subsampleEntries +\n                    '}';\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/SubtitleMediaHeaderBox.java",
    "content": "package com.coremedia.iso.boxes;\n\nimport java.nio.ByteBuffer;\n\npublic class SubtitleMediaHeaderBox extends AbstractMediaHeaderBox {\n\n    public static final String TYPE = \"sthd\";\n\n    public SubtitleMediaHeaderBox() {\n        super(TYPE);\n    }\n\n    protected long getContentSize() {\n        return 4;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n    }\n\n    public String toString() {\n        return \"SubtitleMediaHeaderBox\";\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/SyncSampleBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\n/**\n * This box provides a compact marking of the random access points withinthe stream. The table is arranged in\n * strictly decreasinf order of sample number. Defined in ISO/IEC 14496-12.\n */\npublic class SyncSampleBox extends AbstractFullBox {\n    public static final String TYPE = \"stss\";\n\n    private long[] sampleNumber;\n\n    public SyncSampleBox() {\n        super(TYPE);\n    }\n\n    /**\n     * Gives the numbers of the samples that are random access points in the stream.\n     *\n     * @return random access sample numbers.\n     */\n    public long[] getSampleNumber() {\n        return sampleNumber;\n    }\n\n    protected long getContentSize() {\n        return sampleNumber.length * 4 + 8;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        int entryCount = l2i(IsoTypeReader.readUInt32(content));\n\n        sampleNumber = new long[entryCount];\n        for (int i = 0; i < entryCount; i++) {\n            sampleNumber[i] = IsoTypeReader.readUInt32(content);\n        }\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n\n        IsoTypeWriter.writeUInt32(byteBuffer, sampleNumber.length);\n\n        for (long aSampleNumber : sampleNumber) {\n            IsoTypeWriter.writeUInt32(byteBuffer, aSampleNumber);\n        }\n\n    }\n\n    public String toString() {\n        return \"SyncSampleBox[entryCount=\" + sampleNumber.length + \"]\";\n    }\n\n    public void setSampleNumber(long[] sampleNumber) {\n        this.sampleNumber = sampleNumber;\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/TimeToSampleBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\n/**\n * This box contains a compact version of a table that allows indexing from decoding time to sample number.\n * Other tables give sample sizes and pointers, from the sample number. Each entry in the table gives the\n * number of consecutive samples with the same time delta, and the delta of those samples. By adding the\n * deltas a complete time-to-sample map may be built.<br>\n * The Decoding Time to Sample Box contains decode time delta's: <code>DT(n+1) = DT(n) + STTS(n)</code> where STTS(n)\n * is the (uncompressed) table entry for sample n.<br>\n * The sample entries are ordered by decoding time stamps; therefore the deltas are all non-negative. <br>\n * The DT axis has a zero origin; <code>DT(i) = SUM(for j=0 to i-1 of delta(j))</code>, and the sum of all\n * deltas gives the length of the media in the track (not mapped to the overall timescale, and not considering\n * any edit list).    <br>\n * The Edit List Box provides the initial CT value if it is non-empty (non-zero).\n */\npublic class TimeToSampleBox extends AbstractFullBox {\n    public static final String TYPE = \"stts\";\n\n    List<Entry> entries = Collections.emptyList();\n\n\n    public TimeToSampleBox() {\n        super(TYPE);\n    }\n\n    protected long getContentSize() {\n        return 8 + entries.size() * 8;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        int entryCount = l2i(IsoTypeReader.readUInt32(content));\n        entries = new ArrayList<Entry>(entryCount);\n\n        for (int i = 0; i < entryCount; i++) {\n            entries.add(new Entry(IsoTypeReader.readUInt32(content), IsoTypeReader.readUInt32(content)));\n        }\n\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt32(byteBuffer, entries.size());\n        for (Entry entry : entries) {\n            IsoTypeWriter.writeUInt32(byteBuffer, entry.getCount());\n            IsoTypeWriter.writeUInt32(byteBuffer, entry.getDelta());\n        }\n    }\n\n    public List<Entry> getEntries() {\n        return entries;\n    }\n\n    public void setEntries(List<Entry> entries) {\n        this.entries = entries;\n    }\n\n    public String toString() {\n        return \"TimeToSampleBox[entryCount=\" + entries.size() + \"]\";\n    }\n\n    public static class Entry {\n        long count;\n        long delta;\n\n        public Entry(long count, long delta) {\n            this.count = count;\n            this.delta = delta;\n        }\n\n        public long getCount() {\n            return count;\n        }\n\n        public long getDelta() {\n            return delta;\n        }\n\n        public void setCount(long count) {\n            this.count = count;\n        }\n\n        public void setDelta(long delta) {\n            this.delta = delta;\n        }\n\n        @Override\n        public String toString() {\n            return \"Entry{\" +\n                    \"count=\" + count +\n                    \", delta=\" + delta +\n                    '}';\n        }\n    }\n\n    /**\n     * Decompresses the list of entries and returns the list of decoding times.\n     *\n     * @return decoding time per sample\n     */\n    public static long[] blowupTimeToSamples(List<TimeToSampleBox.Entry> entries) {\n        long numOfSamples = 0;\n        for (TimeToSampleBox.Entry entry : entries) {\n            numOfSamples += entry.getCount();\n        }\n        assert numOfSamples <= Integer.MAX_VALUE;\n        long[] decodingTime = new long[(int) numOfSamples];\n\n        int current = 0;\n\n\n        for (TimeToSampleBox.Entry entry : entries) {\n            for (int i = 0; i < entry.getCount(); i++) {\n                decodingTime[current++] = entry.getDelta();\n            }\n        }\n\n        return decodingTime;\n    }\n\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/TitleBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * <code>\n * Box Type: 'titl'<br>\n * Container: {@link UserDataBox} ('udta')<br>\n * Mandatory: No<br>\n * Quantity: Zero or one<br><br>\n * </code>\n * <p/>\n * Title for the media.\n */\npublic class TitleBox extends AbstractFullBox {\n    public static final String TYPE = \"titl\";\n\n    private String language;\n    private String title;\n\n    public TitleBox() {\n        super(TYPE);\n    }\n\n    public String getLanguage() {\n        return language;\n    }\n\n    public String getTitle() {\n        return title;\n    }\n\n    /**\n     * Sets the 3-letter ISO-639 language for this title.\n     *\n     * @param language 3-letter ISO-639 code\n     */\n    public void setLanguage(String language) {\n        this.language = language;\n    }\n\n    public void setTitle(String title) {\n        this.title = title;\n    }\n\n    protected long getContentSize() {\n        return 7 + Utf8.utf8StringLengthInBytes(title);\n    }\n\n\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeIso639(byteBuffer, language);\n        byteBuffer.put(Utf8.convert(title));\n        byteBuffer.put((byte) 0);\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        language = IsoTypeReader.readIso639(content);\n        title = IsoTypeReader.readString(content);\n    }\n\n    public String toString() {\n        return \"TitleBox[language=\" + getLanguage() + \";title=\" + getTitle() + \"]\";\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/TrackBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.googlecode.mp4parser.AbstractContainerBox;\n\n/**\n * Tracks are used for two purposes: (a) to contain media data (media tracks) and (b) to contain packetization\n * information for streaming protocols (hint tracks).  <br>\n * There shall be at least one media track within an ISO file, and all the media tracks that contributed to the hint\n * tracks shall remain in the file, even if the media data within them is not referenced by the hint tracks; after\n * deleting all hint tracks, the entire un-hinted presentation shall remain.\n */\npublic class TrackBox extends AbstractContainerBox {\n    public static final String TYPE = \"trak\";\n\n    public TrackBox() {\n        super(TYPE);\n    }\n\n    public TrackHeaderBox getTrackHeaderBox() {\n        for (Box box : boxes) {\n            if (box instanceof TrackHeaderBox) {\n                return (TrackHeaderBox) box;\n            }\n        }\n        return null;\n    }\n\n    /**\n     * Gets the SampleTableBox at mdia/minf/stbl if existing.\n     *\n     * @return the SampleTableBox or <code>null</code>\n     */\n    public SampleTableBox getSampleTableBox() {\n        MediaBox mdia = getMediaBox();\n        if (mdia != null) {\n            MediaInformationBox minf = mdia.getMediaInformationBox();\n            if (minf != null) {\n                return minf.getSampleTableBox();\n            }\n        }\n        return null;\n\n    }\n\n\n    public MediaBox getMediaBox() {\n        for (Box box : boxes) {\n            if (box instanceof MediaBox) {\n                return (MediaBox) box;\n            }\n        }\n        return null;\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/TrackHeaderBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * This box specifies the characteristics of a single track. Exactly one Track Header Box is contained in a track.<br>\n * In the absence of an edit list, the presentation of a track starts at the beginning of the overall presentation. An\n * empty edit is used to offset the start time of a track. <br>\n * The default value of the track header flags for media tracks is 7 (track_enabled, track_in_movie,\n * track_in_preview). If in a presentation all tracks have neither track_in_movie nor track_in_preview set, then all\n * tracks shall be treated as if both flags were set on all tracks. Hint tracks should have the track header flags set\n * to 0, so that they are ignored for local playback and preview.\n */\npublic class TrackHeaderBox extends AbstractFullBox {\n\n    public static final String TYPE = \"tkhd\";\n\n    private long creationTime;\n    private long modificationTime;\n    private long trackId;\n    private long duration;\n    private int layer;\n    private int alternateGroup;\n    private float volume;\n    private long[] matrix = new long[]{0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000};\n    private double width;\n    private double height;\n\n\n    public TrackHeaderBox() {\n        super(TYPE);\n\n    }\n\n    public long getCreationTime() {\n        return creationTime;\n    }\n\n    public long getModificationTime() {\n        return modificationTime;\n    }\n\n    public long getTrackId() {\n        return trackId;\n    }\n\n    public long getDuration() {\n        return duration;\n    }\n\n    public int getLayer() {\n        return layer;\n    }\n\n    public int getAlternateGroup() {\n        return alternateGroup;\n    }\n\n    public float getVolume() {\n        return volume;\n    }\n\n    public long[] getMatrix() {\n        return matrix;\n    }\n\n    public double getWidth() {\n        return width;\n    }\n\n    public double getHeight() {\n        return height;\n    }\n\n    protected long getContentSize() {\n        long contentSize = 4;\n        if (getVersion() == 1) {\n            contentSize += 32;\n        } else {\n            contentSize += 20;\n        }\n        contentSize += 60;\n        return contentSize;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        if (getVersion() == 1) {\n            creationTime = IsoTypeReader.readUInt64(content);\n            modificationTime = IsoTypeReader.readUInt64(content);\n            trackId = IsoTypeReader.readUInt32(content);\n            IsoTypeReader.readUInt32(content);\n            duration = IsoTypeReader.readUInt64(content);\n        } else {\n            creationTime = IsoTypeReader.readUInt32(content);\n            modificationTime = IsoTypeReader.readUInt32(content);\n            trackId = IsoTypeReader.readUInt32(content);\n            IsoTypeReader.readUInt32(content);\n            duration = IsoTypeReader.readUInt32(content);\n        } // 196\n        IsoTypeReader.readUInt32(content);\n        IsoTypeReader.readUInt32(content);\n        layer = IsoTypeReader.readUInt16(content);    // 204\n        alternateGroup = IsoTypeReader.readUInt16(content);\n        volume = IsoTypeReader.readFixedPoint88(content);\n        IsoTypeReader.readUInt16(content);     // 212\n        matrix = new long[9];\n        for (int i = 0; i < 9; i++) {\n            matrix[i] = IsoTypeReader.readUInt32(content);\n        }\n        width = IsoTypeReader.readFixedPoint1616(content);    // 248\n        height = IsoTypeReader.readFixedPoint1616(content);\n    }\n\n    public void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        if (getVersion() == 1) {\n            IsoTypeWriter.writeUInt64(byteBuffer, creationTime);\n            IsoTypeWriter.writeUInt64(byteBuffer, modificationTime);\n            IsoTypeWriter.writeUInt32(byteBuffer, trackId);\n            IsoTypeWriter.writeUInt32(byteBuffer, 0);\n            IsoTypeWriter.writeUInt64(byteBuffer, duration);\n        } else {\n            IsoTypeWriter.writeUInt32(byteBuffer, creationTime);\n            IsoTypeWriter.writeUInt32(byteBuffer, modificationTime);\n            IsoTypeWriter.writeUInt32(byteBuffer, trackId);\n            IsoTypeWriter.writeUInt32(byteBuffer, 0);\n            IsoTypeWriter.writeUInt32(byteBuffer, duration);\n        } // 196\n        IsoTypeWriter.writeUInt32(byteBuffer, 0);\n        IsoTypeWriter.writeUInt32(byteBuffer, 0);\n        IsoTypeWriter.writeUInt16(byteBuffer, layer);\n        IsoTypeWriter.writeUInt16(byteBuffer, alternateGroup);\n        IsoTypeWriter.writeFixedPont88(byteBuffer, volume);\n        IsoTypeWriter.writeUInt16(byteBuffer, 0);\n        for (int i = 0; i < 9; i++) {\n            IsoTypeWriter.writeUInt32(byteBuffer, matrix[i]);\n        }\n        IsoTypeWriter.writeFixedPont1616(byteBuffer, width);\n        IsoTypeWriter.writeFixedPont1616(byteBuffer, height);\n    }\n\n    public String toString() {\n        StringBuilder result = new StringBuilder();\n        result.append(\"TrackHeaderBox[\");\n        result.append(\"creationTime=\").append(getCreationTime());\n        result.append(\";\");\n        result.append(\"modificationTime=\").append(getModificationTime());\n        result.append(\";\");\n        result.append(\"trackId=\").append(getTrackId());\n        result.append(\";\");\n        result.append(\"duration=\").append(getDuration());\n        result.append(\";\");\n        result.append(\"layer=\").append(getLayer());\n        result.append(\";\");\n        result.append(\"alternateGroup=\").append(getAlternateGroup());\n        result.append(\";\");\n        result.append(\"volume=\").append(getVolume());\n        for (int i = 0; i < matrix.length; i++) {\n            result.append(\";\");\n            result.append(\"matrix\").append(i).append(\"=\").append(matrix[i]);\n        }\n        result.append(\";\");\n        result.append(\"width=\").append(getWidth());\n        result.append(\";\");\n        result.append(\"height=\").append(getHeight());\n        result.append(\"]\");\n        return result.toString();\n    }\n\n    public void setCreationTime(long creationTime) {\n        this.creationTime = creationTime;\n    }\n\n    public void setModificationTime(long modificationTime) {\n        this.modificationTime = modificationTime;\n    }\n\n    public void setTrackId(long trackId) {\n        this.trackId = trackId;\n    }\n\n    public void setDuration(long duration) {\n        this.duration = duration;\n    }\n\n    public void setLayer(int layer) {\n        this.layer = layer;\n    }\n\n    public void setAlternateGroup(int alternateGroup) {\n        this.alternateGroup = alternateGroup;\n    }\n\n    public void setVolume(float volume) {\n        this.volume = volume;\n    }\n\n    public void setMatrix(long[] matrix) {\n        this.matrix = matrix;\n    }\n\n    public void setWidth(double width) {\n        this.width = width;\n    }\n\n    public void setHeight(double height) {\n        this.height = height;\n    }\n\n\n    public boolean isEnabled() {\n        return (getFlags() & 1) > 0;\n    }\n\n    public boolean isInMovie() {\n        return (getFlags() & 2) > 0;\n    }\n\n    public boolean isInPreview() {\n        return (getFlags() & 4) > 0;\n    }\n\n    public boolean isInPoster() {\n        return (getFlags() & 8) > 0;\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/TrackReferenceBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.googlecode.mp4parser.AbstractContainerBox;\n\n/**\n * <code>\n * Box Type: 'tref'<br>\n * Container: {@link TrackBox} ('trak')<br>\n * Mandatory: No<br>\n * Quantity: Zero or one<br><br>\n * </code>\n * This box provides a reference from the containing track to another track in the presentation. These references\n * are typed. A 'hint' reference links from the containing hint track to the media data that it hints. A content\n * description reference 'cdsc' links a descriptive or metadata track to the content which it describes.\n * Exactly one Track Reference Box can be contained within the Track Box.\n * If this box is not present, the track is not referencing any other track in any way. The reference array is sized\n * to fill the reference type box.\n */\npublic class TrackReferenceBox extends AbstractContainerBox {\n    public static final String TYPE = \"tref\";\n\n    public TrackReferenceBox() {\n        super(TYPE);\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/TrackReferenceTypeBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Contains a reference to a track. The type of the box gives the kind of reference.\n */\npublic class TrackReferenceTypeBox extends AbstractBox {\n\n    public static final String TYPE1 = \"hint\";\n    public static final String TYPE2 = \"cdsc\";\n\n    private long[] trackIds;\n\n    public TrackReferenceTypeBox(String type) {\n        super(type);\n    }\n\n    public long[] getTrackIds() {\n        return trackIds;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        int count = (int) (content.remaining() / 4);\n        trackIds = new long[count];\n        for (int i = 0; i < count; i++) {\n            trackIds[i] = IsoTypeReader.readUInt32(content);\n        }\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        for (long trackId : trackIds) {\n            IsoTypeWriter.writeUInt32(byteBuffer, trackId);\n        }\n    }\n\n\n    protected long getContentSize() {\n        return trackIds.length * 4;\n    }\n\n    public String toString() {\n        StringBuilder buffer = new StringBuilder();\n        buffer.append(\"TrackReferenceTypeBox[type=\").append(getType());\n        for (int i = 0; i < trackIds.length; i++) {\n            buffer.append(\";trackId\");\n            buffer.append(i);\n            buffer.append(\"=\");\n            buffer.append(trackIds[i]);\n        }\n        buffer.append(\"]\");\n        return buffer.toString();\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/UnknownBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\n\nimport com.googlecode.mp4parser.AbstractBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * A box unknown to the ISO Parser. If there is no specific Box implementation for a Box this <code>UnknownBox</code>\n * will just hold the box's data.\n */\npublic class UnknownBox extends AbstractBox {\n    ByteBuffer data;\n\n    public UnknownBox(String type) {\n        super(type);\n    }\n\n    @Override\n    protected long getContentSize() {\n        return data.limit();\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        data = content;\n        content.position(content.position() + content.remaining());\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        data.rewind();\n        byteBuffer.put(data);\n    }\n\n    public ByteBuffer getData() {\n        return data;\n    }\n\n    public void setData(ByteBuffer data) {\n        this.data = data;\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/UserBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.googlecode.mp4parser.AbstractBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * A user specifc box. See ISO/IEC 14496-12 for details.\n */\npublic class UserBox extends AbstractBox {\n    byte[] data;\n    public static final String TYPE = \"uuid\";\n\n    public UserBox(byte[] userType) {\n        super(TYPE, userType);\n    }\n\n\n    protected long getContentSize() {\n        return data.length;\n    }\n\n    public String toString() {\n        return \"UserBox[type=\" + (getType()) +\n                \";userType=\" + new String(getUserType()) +\n                \";contentLength=\" + data.length + \"]\";\n    }\n\n\n    public byte[] getData() {\n        return data;\n    }\n\n    public void setData(byte[] data) {\n        this.data = data;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        data = new byte[content.remaining()];\n        content.get(data);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        byteBuffer.put(data);\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/UserDataBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.BoxParser;\nimport com.googlecode.mp4parser.AbstractContainerBox;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.channels.ReadableByteChannel;\n\n/**\n * This box contains objects that declare user information about the containing box and its data (presentation or\n * track).<br>\n * The User Data Box is a container box for informative user-data. This user data is formatted as a set of boxes\n * with more specific box types, which declare more precisely their content\n */\npublic class UserDataBox extends AbstractContainerBox {\n    public static final String TYPE = \"udta\";\n\n    @Override\n    protected long getContentSize() {\n        return super.getContentSize();    //To change body of overridden methods use File | Settings | File Templates.\n    }\n\n    @Override\n    public void parse(ReadableByteChannel readableByteChannel, ByteBuffer header, long contentSize, BoxParser boxParser) throws IOException {\n        super.parse(readableByteChannel, header, contentSize, boxParser);    //To change body of overridden methods use File | Settings | File Templates.\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        super._parseDetails(content);    //To change body of overridden methods use File | Settings | File Templates.\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        super.getContent(byteBuffer);    //To change body of overridden methods use File | Settings | File Templates.\n    }\n\n    public UserDataBox() {\n        super(TYPE);\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/VideoMediaHeaderBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\n\nimport java.nio.ByteBuffer;\n\n/**\n * The video media header contains general presentation information, independent of the coding, for video\n * media. Note that the flags field has the value 1.\n */\npublic class VideoMediaHeaderBox extends AbstractMediaHeaderBox {\n    private int graphicsmode = 0;\n    private int[] opcolor = new int[]{0, 0, 0};\n    public static final String TYPE = \"vmhd\";\n\n    public VideoMediaHeaderBox() {\n        super(TYPE);\n        setFlags(1); // 1 is default.\n    }\n\n    public int getGraphicsmode() {\n        return graphicsmode;\n    }\n\n    public int[] getOpcolor() {\n        return opcolor;\n    }\n\n    protected long getContentSize() {\n        return 12;\n    }\n\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        graphicsmode = IsoTypeReader.readUInt16(content);\n        opcolor = new int[3];\n        for (int i = 0; i < 3; i++) {\n            opcolor[i] = IsoTypeReader.readUInt16(content);\n        }\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt16(byteBuffer, graphicsmode);\n        for (int anOpcolor : opcolor) {\n            IsoTypeWriter.writeUInt16(byteBuffer, anOpcolor);\n        }\n    }\n\n    public String toString() {\n        return \"VideoMediaHeaderBox[graphicsmode=\" + getGraphicsmode() + \";opcolor0=\" + getOpcolor()[0] + \";opcolor1=\" + getOpcolor()[1] + \";opcolor2=\" + getOpcolor()[2] + \"]\";\n    }\n\n    public void setOpcolor(int[] opcolor) {\n        this.opcolor = opcolor;\n    }\n\n    public void setGraphicsmode(int graphicsmode) {\n        this.graphicsmode = graphicsmode;\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/WriteListener.java",
    "content": "package com.coremedia.iso.boxes;\n\n/**\n * The <class>WriteListener</class> is used to get the offset of\n * a box before writing the box. This can be used if a box written\n * later needs an offset.\n */\npublic interface WriteListener {\n    public void beforeWrite(long offset);\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/XmlBox.java",
    "content": "package com.coremedia.iso.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n *\n */\npublic class XmlBox extends AbstractFullBox {\n    String xml = \"\";\n    public static final String TYPE = \"xml \";\n\n    public XmlBox() {\n        super(TYPE);\n    }\n\n    public String getXml() {\n        return xml;\n    }\n\n    public void setXml(String xml) {\n        this.xml = xml;\n    }\n\n    @Override\n    protected long getContentSize() {\n        return 4 + Utf8.utf8StringLengthInBytes(xml);\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        xml = IsoTypeReader.readString(content, content.remaining());\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        byteBuffer.put(Utf8.convert(xml));\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AbstractAppleMetaDataBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractBox;\nimport com.coremedia.iso.boxes.Box;\nimport com.coremedia.iso.boxes.ContainerBox;\nimport com.googlecode.mp4parser.util.ByteBufferByteChannel;\n\nimport java.io.IOException;\nimport java.math.BigInteger;\nimport java.nio.ByteBuffer;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.logging.Logger;\n\n/**\n *\n */\npublic abstract class AbstractAppleMetaDataBox extends AbstractBox implements ContainerBox {\n    private static Logger LOG = Logger.getLogger(AbstractAppleMetaDataBox.class.getName());\n    AppleDataBox appleDataBox = new AppleDataBox();\n\n    public List<Box> getBoxes() {\n        return Collections.singletonList((Box) appleDataBox);\n    }\n\n    public void setBoxes(List<Box> boxes) {\n        if (boxes.size() == 1 && boxes.get(0) instanceof AppleDataBox) {\n            appleDataBox = (AppleDataBox) boxes.get(0);\n        } else {\n            throw new IllegalArgumentException(\"This box only accepts one AppleDataBox child\");\n        }\n    }\n\n    public <T extends Box> List<T> getBoxes(Class<T> clazz) {\n        return getBoxes(clazz, false);\n    }\n\n    public <T extends Box> List<T> getBoxes(Class<T> clazz, boolean recursive) {\n        //todo recursive?\n        if (clazz.isAssignableFrom(appleDataBox.getClass())) {\n            return (List<T>) Collections.singletonList(appleDataBox);\n        }\n        return null;\n    }\n\n    public AbstractAppleMetaDataBox(String type) {\n        super(type);\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        long dataBoxSize = IsoTypeReader.readUInt32(content);\n        String thisShouldBeData = IsoTypeReader.read4cc(content);\n        assert \"data\".equals(thisShouldBeData);\n        appleDataBox = new AppleDataBox();\n        try {\n            appleDataBox.parse(new ByteBufferByteChannel(content), null, content.remaining(), null);\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n        appleDataBox.setParent(this);\n    }\n\n\n    protected long getContentSize() {\n        return appleDataBox.getSize();\n    }\n\n    protected void getContent(ByteBuffer byteBuffer) {\n        try {\n            appleDataBox.getBox(new ByteBufferByteChannel(byteBuffer));\n        } catch (IOException e) {\n            throw new RuntimeException(\"The Channel is based on a ByteBuffer and therefore it shouldn't throw any exception\");\n        }\n    }\n\n    public long getNumOfBytesToFirstChild() {\n        return getSize() - appleDataBox.getSize();\n    }\n\n    @Override\n    public String toString() {\n        return this.getClass().getSimpleName() + \"{\" +\n                \"appleDataBox=\" + getValue() +\n                '}';\n    }\n\n    static long toLong(byte b) {\n        return b < 0 ? b + 256 : b;\n    }\n\n    public void setValue(String value) {\n        if (appleDataBox.getFlags() == 1) {\n            appleDataBox = new AppleDataBox();\n            appleDataBox.setVersion(0);\n            appleDataBox.setFlags(1);\n            appleDataBox.setFourBytes(new byte[4]);\n            appleDataBox.setData(Utf8.convert(value));\n        } else if (appleDataBox.getFlags() == 21) {\n            byte[] content = appleDataBox.getData();\n            appleDataBox = new AppleDataBox();\n            appleDataBox.setVersion(0);\n            appleDataBox.setFlags(21);\n            appleDataBox.setFourBytes(new byte[4]);\n\n            ByteBuffer bb = ByteBuffer.allocate(content.length);\n            if (content.length == 1) {\n                IsoTypeWriter.writeUInt8(bb, (Byte.parseByte(value) & 0xFF));\n            } else if (content.length == 2) {\n                IsoTypeWriter.writeUInt16(bb, Integer.parseInt(value));\n            } else if (content.length == 4) {\n                IsoTypeWriter.writeUInt32(bb, Long.parseLong(value));\n            } else if (content.length == 8) {\n                IsoTypeWriter.writeUInt64(bb, Long.parseLong(value));\n            } else {\n                throw new Error(\"The content length within the appleDataBox is neither 1, 2, 4 or 8. I can't handle that!\");\n            }\n            appleDataBox.setData(bb.array());\n        } else if (appleDataBox.getFlags() == 0) {\n            appleDataBox = new AppleDataBox();\n            appleDataBox.setVersion(0);\n            appleDataBox.setFlags(0);\n            appleDataBox.setFourBytes(new byte[4]);\n            appleDataBox.setData(hexStringToByteArray(value));\n\n        } else {\n            LOG.warning(\"Don't know how to handle appleDataBox with flag=\" + appleDataBox.getFlags());\n        }\n    }\n\n    public String getValue() {\n        if (appleDataBox.getFlags() == 1) {\n            return Utf8.convert(appleDataBox.getData());\n        } else if (appleDataBox.getFlags() == 21) {\n            byte[] content = appleDataBox.getData();\n            long l = 0;\n            int current = 1;\n            int length = content.length;\n            for (byte b : content) {\n                l += toLong(b) << (8 * (length - current++));\n            }\n            return \"\" + l;\n        } else if (appleDataBox.getFlags() == 0) {\n            return String.format(\"%x\", new BigInteger(appleDataBox.getData()));\n        } else {\n            return \"unknown\";\n        }\n    }\n\n    public static byte[] hexStringToByteArray(String s) {\n        int len = s.length();\n        byte[] data = new byte[len / 2];\n        for (int i = 0; i < len; i += 2) {\n            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)\n                    + Character.digit(s.charAt(i + 1), 16));\n        }\n        return data;\n    }\n\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleAlbumArtistBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n * itunes MetaData comment box.\n */\npublic class AppleAlbumArtistBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"aART\";\n\n\n    public AppleAlbumArtistBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getStringAppleDataBox();\n    }\n\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleAlbumBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n *\n */\npublic final class AppleAlbumBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"\\u00a9alb\";\n\n\n    public AppleAlbumBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getStringAppleDataBox();\n    }\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleArtistBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n * iTunes Artist box.\n */\npublic final class AppleArtistBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"\\u00a9ART\";\n\n\n    public AppleArtistBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getStringAppleDataBox();\n    }\n\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleCommentBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n * itunes MetaData comment box.\n */\npublic final class AppleCommentBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"\\u00a9cmt\";\n\n\n    public AppleCommentBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getStringAppleDataBox();\n    }\n\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleCompilationBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n * Compilation.\n */\npublic final class AppleCompilationBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"cpil\";\n\n\n    public AppleCompilationBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getUint8AppleDataBox();\n    }\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleCopyrightBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n * itunes MetaData comment box.\n */\npublic final class AppleCopyrightBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"cprt\";\n\n\n    public AppleCopyrightBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getStringAppleDataBox();\n    }\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleCoverBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\nimport java.util.logging.Logger;\n\n/**\n *\n */\npublic final class AppleCoverBox extends AbstractAppleMetaDataBox {\n    private static Logger LOG = Logger.getLogger(AppleCoverBox.class.getName());\n    public static final String TYPE = \"covr\";\n\n\n    public AppleCoverBox() {\n        super(TYPE);\n    }\n\n\n    public void setPng(byte[] pngData) {\n        appleDataBox = new AppleDataBox();\n        appleDataBox.setVersion(0);\n        appleDataBox.setFlags(0xe);\n        appleDataBox.setFourBytes(new byte[4]);\n        appleDataBox.setData(pngData);\n    }\n\n\n    public void setJpg(byte[] jpgData) {\n        appleDataBox = new AppleDataBox();\n        appleDataBox.setVersion(0);\n        appleDataBox.setFlags(0xd);\n        appleDataBox.setFourBytes(new byte[4]);\n        appleDataBox.setData(jpgData);\n    }\n\n    @Override\n    public void setValue(String value) {\n        LOG.warning(\"---\");\n    }\n\n    @Override\n    public String getValue() {\n        return \"---\";\n    }\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleCustomGenreBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\nimport com.coremedia.iso.Utf8;\n\n/**\n *\n */\npublic final class AppleCustomGenreBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"\\u00a9gen\";\n\n\n    public AppleCustomGenreBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getStringAppleDataBox();\n    }\n\n    public void setGenre(String genre) {\n        appleDataBox = new AppleDataBox();\n        appleDataBox.setVersion(0);\n        appleDataBox.setFlags(1);\n        appleDataBox.setFourBytes(new byte[4]);\n        appleDataBox.setData(Utf8.convert(genre));\n    }\n\n    public String getGenre() {\n        return Utf8.convert(appleDataBox.getData());\n    }\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleDataBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Most stupid box of the world. Encapsulates actual data within\n */\npublic final class AppleDataBox extends AbstractFullBox {\n    public static final String TYPE = \"data\";\n\n    private byte[] fourBytes = new byte[4];\n    private byte[] data;\n\n    private static AppleDataBox getEmpty() {\n        AppleDataBox appleDataBox = new AppleDataBox();\n        appleDataBox.setVersion(0);\n        appleDataBox.setFourBytes(new byte[4]);\n        return appleDataBox;\n    }\n\n    public static AppleDataBox getStringAppleDataBox() {\n        AppleDataBox appleDataBox = getEmpty();\n        appleDataBox.setFlags(1);\n        appleDataBox.setData(new byte[]{0});\n        return appleDataBox;\n    }\n\n    public static AppleDataBox getUint8AppleDataBox() {\n        AppleDataBox appleDataBox = new AppleDataBox();\n        appleDataBox.setFlags(21);\n        appleDataBox.setData(new byte[]{0});\n        return appleDataBox;\n    }\n\n    public static AppleDataBox getUint16AppleDataBox() {\n        AppleDataBox appleDataBox = new AppleDataBox();\n        appleDataBox.setFlags(21);\n        appleDataBox.setData(new byte[]{0, 0});\n        return appleDataBox;\n    }\n\n    public static AppleDataBox getUint32AppleDataBox() {\n        AppleDataBox appleDataBox = new AppleDataBox();\n        appleDataBox.setFlags(21);\n        appleDataBox.setData(new byte[]{0, 0, 0, 0});\n        return appleDataBox;\n    }\n\n    public AppleDataBox() {\n        super(TYPE);\n    }\n\n    protected long getContentSize() {\n        return data.length + 8;\n    }\n\n    public void setData(byte[] data) {\n        this.data = new byte[data.length];\n        System.arraycopy(data, 0, this.data, 0, data.length);\n    }\n\n    public void setFourBytes(byte[] fourBytes) {\n        System.arraycopy(fourBytes, 0, this.fourBytes, 0, 4);\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        fourBytes = new byte[4];\n        content.get(fourBytes);\n        data = new byte[content.remaining()];\n        content.get(data);\n    }\n\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        byteBuffer.put(fourBytes, 0, 4);\n        byteBuffer.put(data);\n    }\n\n    public byte[] getFourBytes() {\n        return fourBytes;\n    }\n\n    public byte[] getData() {\n        return data;\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleDataRateBox.java",
    "content": "/*\n * Copyright 2009 castLabs GmbH, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.coremedia.iso.boxes.apple;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\npublic class AppleDataRateBox extends AbstractFullBox {\n    public static final String TYPE = \"rmdr\";\n    private long dataRate;\n\n    public AppleDataRateBox() {\n        super(TYPE);\n    }\n\n    protected long getContentSize() {\n        return 8;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        dataRate = IsoTypeReader.readUInt32(content);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt32(byteBuffer, dataRate);\n    }\n\n\n    public long getDataRate() {\n        return dataRate;\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleDataReferenceBox.java",
    "content": "/*\n * Copyright 2009 castLabs GmbH, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.coremedia.iso.boxes.apple;\n\nimport com.coremedia.iso.IsoFile;\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\npublic class AppleDataReferenceBox extends AbstractFullBox {\n    public static final String TYPE = \"rdrf\";\n    private int dataReferenceSize;\n    private String dataReferenceType;\n    private String dataReference;\n\n    public AppleDataReferenceBox() {\n        super(TYPE);\n    }\n\n\n    protected long getContentSize() {\n        return 12 + dataReferenceSize;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        dataReferenceType = IsoTypeReader.read4cc(content);\n        dataReferenceSize = l2i(IsoTypeReader.readUInt32(content));\n        dataReference = IsoTypeReader.readString(content, dataReferenceSize);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        byteBuffer.put(IsoFile.fourCCtoBytes(dataReferenceType));\n        IsoTypeWriter.writeUInt32(byteBuffer, dataReferenceSize);\n        byteBuffer.put(Utf8.convert(dataReference));\n    }\n\n    public long getDataReferenceSize() {\n        return dataReferenceSize;\n    }\n\n    public String getDataReferenceType() {\n        return dataReferenceType;\n    }\n\n    public String getDataReference() {\n        return dataReference;\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleDescriptionBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n *\n */\npublic final class AppleDescriptionBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"desc\";\n\n\n    public AppleDescriptionBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getStringAppleDataBox();\n    }\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleEncoderBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n * itunes MetaData comment box.\n */\npublic final class AppleEncoderBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"\\u00a9too\";\n\n\n    public AppleEncoderBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getStringAppleDataBox();\n    }\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleGaplessPlaybackBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n * Gapless Playback.\n */\npublic final class AppleGaplessPlaybackBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"pgap\";\n\n\n    public AppleGaplessPlaybackBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getUint8AppleDataBox();\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleGenericBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\nimport com.googlecode.mp4parser.AbstractContainerBox;\n\n/**\n *\n */\npublic final class AppleGenericBox extends AbstractContainerBox {\n    public static final String TYPE = \"----\";\n\n    public AppleGenericBox() {\n        super(TYPE);\n    }\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleGroupingBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n * itunes MetaData comment box.\n */\npublic final class AppleGroupingBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"\\u00a9grp\";\n\n\n    public AppleGroupingBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getStringAppleDataBox();\n    }\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleIdBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n *\n */\npublic final class AppleIdBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"apID\";\n\n\n    public AppleIdBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getStringAppleDataBox();\n    }\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleItemListBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\nimport com.googlecode.mp4parser.AbstractContainerBox;\n\n/**\n * undocumented iTunes MetaData Box.\n */\npublic class AppleItemListBox extends AbstractContainerBox {\n    public static final String TYPE = \"ilst\";\n\n    public AppleItemListBox() {\n        super(TYPE);\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleLosslessSpecificBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n *\n */\npublic final class AppleLosslessSpecificBox extends AbstractFullBox {\n\n    public static final String TYPE = \"alac\";\n    /*\n   Extradata: 32bit size 32bit tag (=alac) 32bit zero?\n   32bit max sample per frame 8bit ?? (zero?) 8bit sample\n   size 8bit history mult 8bit initial history 8bit kmodifier\n   8bit channels? 16bit ?? 32bit max coded frame size 32bit\n   bitrate? 32bit samplerate\n    */\n    private long maxSamplePerFrame; // 32bi\n    private int unknown1; // 8bit\n    private int sampleSize; // 8bit\n    private int historyMult; // 8bit\n    private int initialHistory; // 8bit\n    private int kModifier; // 8bit\n    private int channels; // 8bit\n    private int unknown2; // 16bit\n    private long maxCodedFrameSize; // 32bit\n    private long bitRate; // 32bit\n    private long sampleRate; // 32bit\n\n    public long getMaxSamplePerFrame() {\n        return maxSamplePerFrame;\n    }\n\n    public void setMaxSamplePerFrame(int maxSamplePerFrame) {\n        this.maxSamplePerFrame = maxSamplePerFrame;\n    }\n\n    public int getUnknown1() {\n        return unknown1;\n    }\n\n    public void setUnknown1(int unknown1) {\n        this.unknown1 = unknown1;\n    }\n\n    public int getSampleSize() {\n        return sampleSize;\n    }\n\n    public void setSampleSize(int sampleSize) {\n        this.sampleSize = sampleSize;\n    }\n\n    public int getHistoryMult() {\n        return historyMult;\n    }\n\n    public void setHistoryMult(int historyMult) {\n        this.historyMult = historyMult;\n    }\n\n    public int getInitialHistory() {\n        return initialHistory;\n    }\n\n    public void setInitialHistory(int initialHistory) {\n        this.initialHistory = initialHistory;\n    }\n\n    public int getKModifier() {\n        return kModifier;\n    }\n\n    public void setKModifier(int kModifier) {\n        this.kModifier = kModifier;\n    }\n\n    public int getChannels() {\n        return channels;\n    }\n\n    public void setChannels(int channels) {\n        this.channels = channels;\n    }\n\n    public int getUnknown2() {\n        return unknown2;\n    }\n\n    public void setUnknown2(int unknown2) {\n        this.unknown2 = unknown2;\n    }\n\n    public long getMaxCodedFrameSize() {\n        return maxCodedFrameSize;\n    }\n\n    public void setMaxCodedFrameSize(int maxCodedFrameSize) {\n        this.maxCodedFrameSize = maxCodedFrameSize;\n    }\n\n    public long getBitRate() {\n        return bitRate;\n    }\n\n    public void setBitRate(int bitRate) {\n        this.bitRate = bitRate;\n    }\n\n    public long getSampleRate() {\n        return sampleRate;\n    }\n\n    public void setSampleRate(int sampleRate) {\n        this.sampleRate = sampleRate;\n    }\n\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        maxSamplePerFrame = IsoTypeReader.readUInt32(content);\n        unknown1 = IsoTypeReader.readUInt8(content);\n        sampleSize = IsoTypeReader.readUInt8(content);\n        historyMult = IsoTypeReader.readUInt8(content);\n        initialHistory = IsoTypeReader.readUInt8(content);\n        kModifier = IsoTypeReader.readUInt8(content);\n        channels = IsoTypeReader.readUInt8(content);\n        unknown2 = IsoTypeReader.readUInt16(content);\n        maxCodedFrameSize = IsoTypeReader.readUInt32(content);\n        bitRate = IsoTypeReader.readUInt32(content);\n        sampleRate = IsoTypeReader.readUInt32(content);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt32(byteBuffer, maxSamplePerFrame);\n        IsoTypeWriter.writeUInt8(byteBuffer, unknown1);\n        IsoTypeWriter.writeUInt8(byteBuffer, sampleSize);\n        IsoTypeWriter.writeUInt8(byteBuffer, historyMult);\n        IsoTypeWriter.writeUInt8(byteBuffer, initialHistory);\n        IsoTypeWriter.writeUInt8(byteBuffer, kModifier);\n        IsoTypeWriter.writeUInt8(byteBuffer, channels);\n        IsoTypeWriter.writeUInt16(byteBuffer, unknown2);\n        IsoTypeWriter.writeUInt32(byteBuffer, maxCodedFrameSize);\n        IsoTypeWriter.writeUInt32(byteBuffer, bitRate);\n        IsoTypeWriter.writeUInt32(byteBuffer, sampleRate);\n    }\n\n    public AppleLosslessSpecificBox() {\n        super(\"alac\");\n    }\n\n    protected long getContentSize() {\n        return 28;\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleMeanBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Apple Meaning box. Allowed as subbox of \"----\" box.\n *\n * @see com.coremedia.iso.boxes.apple.AppleGenericBox\n */\npublic final class AppleMeanBox extends AbstractFullBox {\n    public static final String TYPE = \"mean\";\n    private String meaning;\n\n    public AppleMeanBox() {\n        super(TYPE);\n    }\n\n    protected long getContentSize() {\n        return 4 + Utf8.utf8StringLengthInBytes(meaning);\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        meaning = IsoTypeReader.readString(content, content.remaining());\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        byteBuffer.put(Utf8.convert(meaning));\n    }\n\n    public String getMeaning() {\n        return meaning;\n    }\n\n    public void setMeaning(String meaning) {\n        this.meaning = meaning;\n    }\n\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleMediaTypeBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * itunes MetaData comment box.\n */\npublic class AppleMediaTypeBox extends AbstractAppleMetaDataBox {\n    private static Map<String, String> mediaTypes = new HashMap<String, String>();\n\n    static {\n        mediaTypes.put(\"0\", \"Movie (is now 9)\");\n        mediaTypes.put(\"1\", \"Normal (Music)\");\n        mediaTypes.put(\"2\", \"Audiobook\");\n        mediaTypes.put(\"6\", \"Music Video\");\n        mediaTypes.put(\"9\", \"Movie\");\n        mediaTypes.put(\"10\", \"TV Show\");\n        mediaTypes.put(\"11\", \"Booklet\");\n        mediaTypes.put(\"14\", \"Ringtone\");\n    }\n\n    public static final String TYPE = \"stik\";\n\n\n    public AppleMediaTypeBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getUint8AppleDataBox();\n    }\n\n    public String getReadableValue() {\n        if (mediaTypes.containsKey(getValue())) {\n            return mediaTypes.get(getValue());\n        } else {\n            return \"unknown media type \" + getValue();\n        }\n\n    }\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleNameBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Apple Name box. Allowed as subbox of \"----\" box.\n *\n * @see AppleGenericBox\n */\npublic final class AppleNameBox extends AbstractFullBox {\n    public static final String TYPE = \"name\";\n    private String name;\n\n    public AppleNameBox() {\n        super(TYPE);\n    }\n\n    protected long getContentSize() {\n        return 4 + Utf8.convert(name).length;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        name = IsoTypeReader.readString(content, content.remaining());\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        byteBuffer.put(Utf8.convert(name));\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleNetworkBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n *\n */\npublic final class AppleNetworkBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"tvnn\";\n\n\n    public AppleNetworkBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getStringAppleDataBox();\n    }\n\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/ApplePurchaseDateBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n *\n */\npublic final class ApplePurchaseDateBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"purd\";\n\n\n    public ApplePurchaseDateBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getStringAppleDataBox();\n    }\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleRatingBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n * iTunes Rating Box.\n */\npublic final class AppleRatingBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"rtng\";\n\n\n    public AppleRatingBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getUint8AppleDataBox();\n    }\n\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleRecordingYearBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n *\n */\npublic class AppleRecordingYearBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"\\u00a9day\";\n\n\n    public AppleRecordingYearBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getStringAppleDataBox();\n    }\n\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleReferenceMovieBox.java",
    "content": "/*\n * Copyright 2009 castLabs GmbH, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.coremedia.iso.boxes.apple;\n\nimport com.googlecode.mp4parser.AbstractContainerBox;\n\npublic class AppleReferenceMovieBox extends AbstractContainerBox {\n    public static final String TYPE = \"rmra\";\n\n    public AppleReferenceMovieBox() {\n        super(TYPE);\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleReferenceMovieDescriptorBox.java",
    "content": "/*\n * Copyright 2009 castLabs GmbH, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.coremedia.iso.boxes.apple;\n\nimport com.googlecode.mp4parser.AbstractContainerBox;\n\npublic class AppleReferenceMovieDescriptorBox extends AbstractContainerBox {\n    public static final String TYPE = \"rmda\";\n\n    public AppleReferenceMovieDescriptorBox() {\n        super(TYPE);\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleShowBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n *\n */\npublic final class AppleShowBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"tvsh\";\n\n\n    public AppleShowBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getStringAppleDataBox();\n    }\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleSortAlbumBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n *\n */\npublic final class AppleSortAlbumBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"soal\";\n\n\n    public AppleSortAlbumBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getStringAppleDataBox();\n    }\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleStandardGenreBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n *\n */\npublic final class AppleStandardGenreBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"gnre\";\n\n\n    public AppleStandardGenreBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getUint16AppleDataBox();\n    }\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleStoreAccountTypeBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n * itunes MetaData comment box.\n */\npublic class AppleStoreAccountTypeBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"akID\";\n\n\n    public AppleStoreAccountTypeBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getUint8AppleDataBox();\n    }\n\n    public String getReadableValue() {\n        byte value = this.appleDataBox.getData()[0];\n        switch (value) {\n            case 0:\n                return \"iTunes Account\";\n            case 1:\n                return \"AOL Account\";\n            default:\n                return \"unknown Account\";\n        }\n\n    }\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleStoreCountryCodeBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * itunes MetaData comment box.\n */\npublic class AppleStoreCountryCodeBox extends AbstractAppleMetaDataBox {\n    private static Map<String, String> countryCodes = new HashMap<String, String>();\n\n    static {\n        countryCodes.put(\"143460\", \"Australia\");\n        countryCodes.put(\"143445\", \"Austria\");\n        countryCodes.put(\"143446\", \"Belgium\");\n        countryCodes.put(\"143455\", \"Canada\");\n        countryCodes.put(\"143458\", \"Denmark\");\n        countryCodes.put(\"143447\", \"Finland\");\n        countryCodes.put(\"143442\", \"France\");\n        countryCodes.put(\"143443\", \"Germany\");\n        countryCodes.put(\"143448\", \"Greece\");\n        countryCodes.put(\"143449\", \"Ireland\");\n        countryCodes.put(\"143450\", \"Italy\");\n        countryCodes.put(\"143462\", \"Japan\");\n        countryCodes.put(\"143451\", \"Luxembourg\");\n        countryCodes.put(\"143452\", \"Netherlands\");\n        countryCodes.put(\"143461\", \"New Zealand\");\n        countryCodes.put(\"143457\", \"Norway\");\n        countryCodes.put(\"143453\", \"Portugal\");\n        countryCodes.put(\"143454\", \"Spain\");\n        countryCodes.put(\"143456\", \"Sweden\");\n        countryCodes.put(\"143459\", \"Switzerland\");\n        countryCodes.put(\"143444\", \"United Kingdom\");\n        countryCodes.put(\"143441\", \"United States\");\n    }\n\n    public static final String TYPE = \"sfID\";\n\n\n    public AppleStoreCountryCodeBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getUint32AppleDataBox();\n    }\n\n\n    public String getReadableValue() {\n        if (countryCodes.containsKey(getValue())) {\n            return countryCodes.get(getValue());\n        } else {\n            return \"unknown country code \" + getValue();\n        }\n\n    }\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleSynopsisBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n *\n */\npublic final class AppleSynopsisBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"ldes\";\n\n\n    public AppleSynopsisBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getStringAppleDataBox();\n    }\n\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleTempBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n * Beats per minute.\n */\npublic final class AppleTempBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"tmpo\";\n\n\n    public AppleTempBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getUint16AppleDataBox();\n    }\n\n\n    public int getTempo() {\n        return appleDataBox.getData()[1];\n    }\n\n    public void setTempo(int tempo) {\n        appleDataBox = new AppleDataBox();\n        appleDataBox.setVersion(0);\n        appleDataBox.setFlags(21);\n        appleDataBox.setFourBytes(new byte[4]);\n        appleDataBox.setData(new byte[]{0, (byte) (tempo & 0xFF)});\n\n    }\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleTrackAuthorBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n *\n */\npublic final class AppleTrackAuthorBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"\\u00a9wrt\";\n\n\n    public AppleTrackAuthorBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getStringAppleDataBox();\n    }\n\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleTrackNumberBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n *\n */\npublic final class AppleTrackNumberBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"trkn\";\n\n\n    public AppleTrackNumberBox() {\n        super(TYPE);\n    }\n\n\n    /**\n     * @param track the actual track number\n     * @param of    number of tracks overall\n     */\n    public void setTrackNumber(byte track, byte of) {\n        appleDataBox = new AppleDataBox();\n        appleDataBox.setVersion(0);\n        appleDataBox.setFlags(0);\n        appleDataBox.setFourBytes(new byte[4]);\n        appleDataBox.setData(new byte[]{0, 0, 0, track, 0, of, 0, 0});\n    }\n\n    public byte getTrackNumber() {\n        return appleDataBox.getData()[3];\n    }\n\n    public byte getNumberOfTracks() {\n        return appleDataBox.getData()[5];\n    }\n\n    public void setNumberOfTracks(byte numberOfTracks) {\n        byte[] content = appleDataBox.getData();\n        content[5] = numberOfTracks;\n        appleDataBox.setData(content);\n    }\n\n    public void setTrackNumber(byte trackNumber) {\n        byte[] content = appleDataBox.getData();\n        content[3] = trackNumber;\n        appleDataBox.setData(content);\n    }\n\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleTrackTitleBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n *\n */\npublic final class AppleTrackTitleBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"\\u00a9nam\";\n\n\n    public AppleTrackTitleBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getStringAppleDataBox();\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleTvEpisodeBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n * Tv Episode.\n */\npublic class AppleTvEpisodeBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"tves\";\n\n\n    public AppleTvEpisodeBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getUint32AppleDataBox();\n    }\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleTvEpisodeNumberBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n * Tv Episode.\n */\npublic class AppleTvEpisodeNumberBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"tven\";\n\n\n    public AppleTvEpisodeNumberBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getStringAppleDataBox();\n    }\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleTvSeasonBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\n/**\n * Tv Season.\n */\npublic final class AppleTvSeasonBox extends AbstractAppleMetaDataBox {\n    public static final String TYPE = \"tvsn\";\n\n\n    public AppleTvSeasonBox() {\n        super(TYPE);\n        appleDataBox = AppleDataBox.getUint32AppleDataBox();\n    }\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/apple/AppleWaveBox.java",
    "content": "package com.coremedia.iso.boxes.apple;\n\nimport com.googlecode.mp4parser.AbstractContainerBox;\n\n/**\n *\n */\npublic final class AppleWaveBox extends AbstractContainerBox {\n    public static final String TYPE = \"wave\";\n\n    public AppleWaveBox() {\n        super(TYPE);\n    }\n\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/dece/TrickPlayBox.java",
    "content": "package com.coremedia.iso.boxes.dece;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * aligned(8) class TrickPlayBox\n * extends FullBox(‘trik’, version=0, flags=0)\n * {\n * for (i=0; I < sample_count; i++) {\n * unsigned int(2) pic_type;\n * unsigned int(6) dependency_level;\n * }\n * }\n */\npublic class TrickPlayBox extends AbstractFullBox {\n    public static final String TYPE = \"trik\";\n\n    private List<Entry> entries = new ArrayList<Entry>();\n\n    public TrickPlayBox() {\n        super(TYPE);\n    }\n\n    public void setEntries(List<Entry> entries) {\n        this.entries = entries;\n    }\n\n    public List<Entry> getEntries() {\n        return entries;\n    }\n\n    public static class Entry {\n\n        public Entry() {\n        }\n\n        public Entry(int value) {\n            this.value = value;\n        }\n\n\n        private int value;\n\n        public int getPicType() {\n            return (value >> 6) & 0x03;\n        }\n\n        public void setPicType(int picType) {\n            value = value & (0xff >> 3);\n            value = (picType & 0x03) << 6 | value;\n        }\n\n        public int getDependencyLevel() {\n            return value & 0x3f;\n        }\n\n        public void setDependencyLevel(int dependencyLevel) {\n            value = (dependencyLevel & 0x3f) | value;\n        }\n\n\n        @Override\n        public String toString() {\n            final StringBuilder sb = new StringBuilder();\n            sb.append(\"Entry\");\n            sb.append(\"{picType=\").append(getPicType());\n            sb.append(\",dependencyLevel=\").append(getDependencyLevel());\n            sb.append('}');\n            return sb.toString();\n        }\n    }\n\n    @Override\n    protected long getContentSize() {\n        return 4 + entries.size();\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        while (content.remaining() > 0) {\n            entries.add(new Entry(IsoTypeReader.readUInt8(content)));\n        }\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        for (Entry entry : entries) {\n            IsoTypeWriter.writeUInt8(byteBuffer, entry.value);\n        }\n    }\n\n    @Override\n    public String toString() {\n        final StringBuilder sb = new StringBuilder();\n        sb.append(\"TrickPlayBox\");\n        sb.append(\"{entries=\").append(entries);\n        sb.append('}');\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/fragment/MovieExtendsBox.java",
    "content": "/*\n * Copyright 2009 castLabs GmbH, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.coremedia.iso.boxes.fragment;\n\nimport com.googlecode.mp4parser.AbstractContainerBox;\n\n/**\n * aligned(8) class MovieExtendsBox extends Box('mvex'){\n * }\n */\npublic class MovieExtendsBox extends AbstractContainerBox {\n    public static final String TYPE = \"mvex\";\n\n    public MovieExtendsBox() {\n        super(TYPE);\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/fragment/MovieExtendsHeaderBox.java",
    "content": "/*\n * Copyright 2009 castLabs GmbH, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.coremedia.iso.boxes.fragment;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * aligned(8) class MovieExtendsHeaderBox extends FullBox('mehd', version, 0) {\n * if (version==1) {\n * unsigned int(64) fragment_duration;\n * } else { // version==0\n * unsigned int(32) fragment_duration;\n * }\n * }\n */\npublic class MovieExtendsHeaderBox extends AbstractFullBox {\n    public static final String TYPE = \"mehd\";\n    private long fragmentDuration;\n\n    public MovieExtendsHeaderBox() {\n        super(TYPE);\n    }\n\n    @Override\n    protected long getContentSize() {\n        return getVersion() == 1 ? 12 : 8;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        fragmentDuration = getVersion() == 1 ? IsoTypeReader.readUInt64(content) : IsoTypeReader.readUInt32(content);\n    }\n\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        if (getVersion() == 1) {\n            IsoTypeWriter.writeUInt64(byteBuffer, fragmentDuration);\n        } else {\n            IsoTypeWriter.writeUInt32(byteBuffer, fragmentDuration);\n        }\n    }\n\n    public long getFragmentDuration() {\n        return fragmentDuration;\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/fragment/MovieFragmentBox.java",
    "content": "/*\n * Copyright 2009 castLabs GmbH, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.coremedia.iso.boxes.fragment;\n\nimport com.googlecode.mp4parser.AbstractContainerBox;\nimport com.coremedia.iso.boxes.Box;\nimport com.coremedia.iso.boxes.SampleDependencyTypeBox;\nimport com.googlecode.mp4parser.annotations.DoNotParseDetail;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * aligned(8) class MovieFragmentBox extends Box(moof){\n * }\n */\n\npublic class MovieFragmentBox extends AbstractContainerBox {\n    public static final String TYPE = \"moof\";\n\n    public MovieFragmentBox() {\n        super(TYPE);\n    }\n\n\n    public List<Long> getSyncSamples(SampleDependencyTypeBox sdtp) {\n        List<Long> result = new ArrayList<Long>();\n\n        final List<SampleDependencyTypeBox.Entry> sampleEntries = sdtp.getEntries();\n        long i = 1;\n        for (SampleDependencyTypeBox.Entry sampleEntry : sampleEntries) {\n            if (sampleEntry.getSampleDependsOn() == 2) {\n                result.add(i);\n            }\n            i++;\n        }\n\n        return result;\n    }\n\n    @DoNotParseDetail\n    public long getOffset() {\n        Box b = this;\n        long offset = 0;\n        while (b.getParent() != null) {\n            for (Box box : b.getParent().getBoxes()) {\n                if (b == box) {\n                    break;\n                }\n                offset += box.getSize();\n            }\n            b = b.getParent();\n        }\n        return offset;\n    }\n\n\n    public int getTrackCount() {\n        return getBoxes(TrackFragmentBox.class, false).size();\n    }\n\n    /**\n     * Returns the track numbers associated with this <code>MovieBox</code>.\n     *\n     * @return the tracknumbers (IDs) of the tracks in their order of appearance in the file\n     */\n\n    public long[] getTrackNumbers() {\n\n        List<TrackFragmentBox> trackBoxes = this.getBoxes(TrackFragmentBox.class, false);\n        long[] trackNumbers = new long[trackBoxes.size()];\n        for (int trackCounter = 0; trackCounter < trackBoxes.size(); trackCounter++) {\n            TrackFragmentBox trackBoxe = trackBoxes.get(trackCounter);\n            trackNumbers[trackCounter] = trackBoxe.getTrackFragmentHeaderBox().getTrackId();\n        }\n        return trackNumbers;\n    }\n\n    public List<TrackRunBox> getTrackRunBoxes() {\n        return getBoxes(TrackRunBox.class, true);\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/fragment/MovieFragmentHeaderBox.java",
    "content": "/*\n * Copyright 2009 castLabs GmbH, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.coremedia.iso.boxes.fragment;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * aligned(8) class MovieFragmentHeaderBox\n * extends FullBox('mfhd', 0, 0){\n * unsigned int(32) sequence_number;\n * }\n */\n\npublic class MovieFragmentHeaderBox extends AbstractFullBox {\n    public static final String TYPE = \"mfhd\";\n    private long sequenceNumber;\n\n    public MovieFragmentHeaderBox() {\n        super(TYPE);\n    }\n\n    protected long getContentSize() {\n        return 8;\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt32(byteBuffer, sequenceNumber);\n    }\n\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        sequenceNumber = IsoTypeReader.readUInt32(content);\n\n    }\n\n    public long getSequenceNumber() {\n        return sequenceNumber;\n    }\n\n    public void setSequenceNumber(long sequenceNumber) {\n        this.sequenceNumber = sequenceNumber;\n    }\n\n    @Override\n    public String toString() {\n        return \"MovieFragmentHeaderBox{\" +\n                \"sequenceNumber=\" + sequenceNumber +\n                '}';\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/fragment/MovieFragmentRandomAccessBox.java",
    "content": "/*\n * Copyright 2009 castLabs GmbH, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.coremedia.iso.boxes.fragment;\n\nimport com.googlecode.mp4parser.AbstractContainerBox;\n\n/**\n * aligned(8) class MovieFragmentRandomAccessBox\n * extends Box('mfra')\n * {\n * }\n */\npublic class MovieFragmentRandomAccessBox extends AbstractContainerBox {\n    public static final String TYPE = \"mfra\";\n\n    public MovieFragmentRandomAccessBox() {\n        super(TYPE);\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/fragment/MovieFragmentRandomAccessOffsetBox.java",
    "content": "/*\n * Copyright 2009 castLabs GmbH, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.coremedia.iso.boxes.fragment;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * aligned(8) class MovieFragmentRandomAccessOffsetBox\n * extends FullBox('mfro', version, 0) {\n * unsigned int(32) size;\n * }\n */\npublic class MovieFragmentRandomAccessOffsetBox extends AbstractFullBox {\n    public static final String TYPE = \"mfro\";\n    private long mfraSize;\n\n    public MovieFragmentRandomAccessOffsetBox() {\n        super(TYPE);\n    }\n\n    protected long getContentSize() {\n        return 8;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        mfraSize = IsoTypeReader.readUInt32(content);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt32(byteBuffer, mfraSize);\n    }\n\n    public long getMfraSize() {\n        return mfraSize;\n    }\n\n    public void setMfraSize(long mfraSize) {\n        this.mfraSize = mfraSize;\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/fragment/SampleFlags.java",
    "content": "/*\n * Copyright 2009 castLabs GmbH, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.coremedia.iso.boxes.fragment;\n\nimport com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitReaderBuffer;\nimport com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitWriterBuffer;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\n\n/**\n * bit(6) reserved=0;\n * unsigned int(2) sample_depends_on;\n * unsigned int(2) sample_is_depended_on;\n * unsigned int(2) sample_has_redundancy;\n * bit(3) sample_padding_value;\n * bit(1) sample_is_difference_sample;\n * // i.e. when 1 signals a non-key or non-sync sample\n * unsigned int(16) sample_degradation_priority;\n */\npublic class SampleFlags {\n    private int reserved;\n    private int sampleDependsOn;\n    private int sampleIsDependedOn;\n    private int sampleHasRedundancy;\n    private int samplePaddingValue;\n    private boolean sampleIsDifferenceSample;\n    private int sampleDegradationPriority;\n\n    public SampleFlags() {\n\n    }\n\n    public SampleFlags(ByteBuffer bb) {\n        BitReaderBuffer brb = new BitReaderBuffer(bb);\n        reserved = brb.readBits(6);\n        sampleDependsOn = brb.readBits(2);\n        sampleIsDependedOn = brb.readBits(2);\n        sampleHasRedundancy = brb.readBits(2);\n        samplePaddingValue = brb.readBits(3);\n        sampleIsDifferenceSample = brb.readBits(1) == 1;\n        sampleDegradationPriority = brb.readBits(16);\n    }\n\n\n    public void getContent(ByteBuffer os) {\n        BitWriterBuffer bitWriterBuffer = new BitWriterBuffer(os);\n        bitWriterBuffer.writeBits(reserved, 6);\n        bitWriterBuffer.writeBits(sampleDependsOn, 2);\n        bitWriterBuffer.writeBits(sampleIsDependedOn, 2);\n        bitWriterBuffer.writeBits(sampleHasRedundancy, 2);\n        bitWriterBuffer.writeBits(samplePaddingValue, 3);\n        bitWriterBuffer.writeBits(this.sampleIsDifferenceSample ? 1 : 0, 1);\n        bitWriterBuffer.writeBits(sampleDegradationPriority, 16);\n    }\n\n    public int getReserved() {\n        return reserved;\n    }\n\n    public void setReserved(int reserved) {\n        this.reserved = reserved;\n    }\n\n    /**\n     * @see #setSampleDependsOn(int)\n     */\n    public int getSampleDependsOn() {\n        return sampleDependsOn;\n    }\n\n    /**\n     * sample_depends_on takes one of the following four values:\n     * <pre>\n     * 0: the dependency of this sample is unknown;\n     * 1: this sample does depend on others (not an I picture);\n     * 2: this sample does not depend on others (I picture);\n     * 3: reserved\n     * </pre>\n     *\n     */\n    public void setSampleDependsOn(int sampleDependsOn) {\n        this.sampleDependsOn = sampleDependsOn;\n    }\n\n    /**\n     * @see #setSampleIsDependedOn(int)\n     */\n    public int getSampleIsDependedOn() {\n        return sampleIsDependedOn;\n    }\n\n    /**\n     * sample_is_depended_on takes one of the following four values:\n     * <pre>\n     * 0: the dependency of other samples on this sample is unknown;\n     * 1: other samples may depend on this one (not disposable);\n     * 2: no other sample depends on this one (disposable);\n     * 3: reserved\n     * </pre>\n     *\n     */\n    public void setSampleIsDependedOn(int sampleIsDependedOn) {\n        this.sampleIsDependedOn = sampleIsDependedOn;\n    }\n\n    /**\n     * @see #setSampleHasRedundancy(int)\n     */\n    public int getSampleHasRedundancy() {\n        return sampleHasRedundancy;\n    }\n\n    /**\n     * sample_has_redundancy takes one of the following four values:\n     * <pre>\n     * 0: it is unknown whether there is redundant coding in this sample;\n     * 1: there is redundant coding in this sample;\n     * 2: there is no redundant coding in this sample;\n     * 3: reserved\n     * </pre>\n     */\n    public void setSampleHasRedundancy(int sampleHasRedundancy) {\n        this.sampleHasRedundancy = sampleHasRedundancy;\n    }\n\n    public int getSamplePaddingValue() {\n        return samplePaddingValue;\n    }\n\n    public void setSamplePaddingValue(int samplePaddingValue) {\n        this.samplePaddingValue = samplePaddingValue;\n    }\n\n    public boolean isSampleIsDifferenceSample() {\n        return sampleIsDifferenceSample;\n    }\n\n\n    public void setSampleIsDifferenceSample(boolean sampleIsDifferenceSample) {\n        this.sampleIsDifferenceSample = sampleIsDifferenceSample;\n    }\n\n    public int getSampleDegradationPriority() {\n        return sampleDegradationPriority;\n    }\n\n    public void setSampleDegradationPriority(int sampleDegradationPriority) {\n        this.sampleDegradationPriority = sampleDegradationPriority;\n    }\n\n    @Override\n    public String toString() {\n        return \"SampleFlags{\" +\n                \"reserved=\" + reserved +\n                \", sampleDependsOn=\" + sampleDependsOn +\n                \", sampleHasRedundancy=\" + sampleHasRedundancy +\n                \", samplePaddingValue=\" + samplePaddingValue +\n                \", sampleIsDifferenceSample=\" + sampleIsDifferenceSample +\n                \", sampleDegradationPriority=\" + sampleDegradationPriority +\n                '}';\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        SampleFlags that = (SampleFlags) o;\n\n        if (reserved != that.reserved) return false;\n        if (sampleDegradationPriority != that.sampleDegradationPriority) return false;\n        if (sampleDependsOn != that.sampleDependsOn) return false;\n        if (sampleHasRedundancy != that.sampleHasRedundancy) return false;\n        if (sampleIsDependedOn != that.sampleIsDependedOn) return false;\n        if (sampleIsDifferenceSample != that.sampleIsDifferenceSample) return false;\n        if (samplePaddingValue != that.samplePaddingValue) return false;\n\n        return true;\n    }\n\n    @Override\n    public int hashCode() {\n        int result = reserved;\n        result = 31 * result + sampleDependsOn;\n        result = 31 * result + sampleIsDependedOn;\n        result = 31 * result + sampleHasRedundancy;\n        result = 31 * result + samplePaddingValue;\n        result = 31 * result + (sampleIsDifferenceSample ? 1 : 0);\n        result = 31 * result + sampleDegradationPriority;\n        return result;\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/fragment/TrackExtendsBox.java",
    "content": "/*\n * Copyright 2009 castLabs GmbH, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.coremedia.iso.boxes.fragment;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * aligned(8) class TrackExtendsBox extends FullBox('trex', 0, 0){\n * unsigned int(32) track_ID;\n * unsigned int(32) default_sample_description_index;\n * unsigned int(32) default_sample_duration;\n * unsigned int(32) default_sample_size;\n * unsigned int(32) default_sample_flags\n * }\n */\npublic class TrackExtendsBox extends AbstractFullBox {\n    public static final String TYPE = \"trex\";\n    private long trackId;\n    private long defaultSampleDescriptionIndex;\n    private long defaultSampleDuration;\n    private long defaultSampleSize;\n    private SampleFlags defaultSampleFlags;\n\n    public TrackExtendsBox() {\n        super(TYPE);\n    }\n\n    @Override\n    protected long getContentSize() {\n        return 5 * 4 + 4;\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt32(byteBuffer, trackId);\n        IsoTypeWriter.writeUInt32(byteBuffer, defaultSampleDescriptionIndex);\n        IsoTypeWriter.writeUInt32(byteBuffer, defaultSampleDuration);\n        IsoTypeWriter.writeUInt32(byteBuffer, defaultSampleSize);\n        defaultSampleFlags.getContent(byteBuffer);\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        trackId = IsoTypeReader.readUInt32(content);\n        defaultSampleDescriptionIndex = IsoTypeReader.readUInt32(content);\n        defaultSampleDuration = IsoTypeReader.readUInt32(content);\n        defaultSampleSize = IsoTypeReader.readUInt32(content);\n        defaultSampleFlags = new SampleFlags(content);\n    }\n\n    public long getTrackId() {\n        return trackId;\n    }\n\n    public long getDefaultSampleDescriptionIndex() {\n        return defaultSampleDescriptionIndex;\n    }\n\n    public long getDefaultSampleDuration() {\n        return defaultSampleDuration;\n    }\n\n    public long getDefaultSampleSize() {\n        return defaultSampleSize;\n    }\n\n    public SampleFlags getDefaultSampleFlags() {\n        return defaultSampleFlags;\n    }\n\n    public String getDefaultSampleFlagsStr() {\n        return defaultSampleFlags.toString();\n    }\n\n    public void setTrackId(long trackId) {\n        this.trackId = trackId;\n    }\n\n    public void setDefaultSampleDescriptionIndex(long defaultSampleDescriptionIndex) {\n        this.defaultSampleDescriptionIndex = defaultSampleDescriptionIndex;\n    }\n\n    public void setDefaultSampleDuration(long defaultSampleDuration) {\n        this.defaultSampleDuration = defaultSampleDuration;\n    }\n\n    public void setDefaultSampleSize(long defaultSampleSize) {\n        this.defaultSampleSize = defaultSampleSize;\n    }\n\n    public void setDefaultSampleFlags(SampleFlags defaultSampleFlags) {\n        this.defaultSampleFlags = defaultSampleFlags;\n\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/fragment/TrackFragmentBaseMediaDecodeTimeBox.java",
    "content": "/*\n * Copyright 2009 castLabs GmbH, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.coremedia.iso.boxes.fragment;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\npublic class TrackFragmentBaseMediaDecodeTimeBox extends AbstractFullBox {\n    public static final String TYPE = \"tfdt\";\n\n    private long baseMediaDecodeTime;\n\n    public TrackFragmentBaseMediaDecodeTimeBox() {\n        super(TYPE);\n    }\n\n    @Override\n    protected long getContentSize() {\n        return getVersion() == 0 ? 8 : 12;\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        if (getVersion() == 1) {\n            IsoTypeWriter.writeUInt64(byteBuffer, baseMediaDecodeTime);\n        } else {\n            IsoTypeWriter.writeUInt32(byteBuffer, baseMediaDecodeTime);\n        }\n    }\n\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        if (getVersion() == 1) {\n            baseMediaDecodeTime = IsoTypeReader.readUInt64(content);\n        } else {\n            baseMediaDecodeTime = IsoTypeReader.readUInt32(content);\n        }\n\n    }\n\n\n    public long getBaseMediaDecodeTime() {\n        return baseMediaDecodeTime;\n    }\n\n    public void setBaseMediaDecodeTime(long baseMediaDecodeTime) {\n        this.baseMediaDecodeTime = baseMediaDecodeTime;\n    }\n\n    @Override\n    public String toString() {\n        return \"TrackFragmentBaseMediaDecodeTimeBox{\" +\n                \"baseMediaDecodeTime=\" + baseMediaDecodeTime +\n                '}';\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/fragment/TrackFragmentBox.java",
    "content": "/*\n * Copyright 2009 castLabs GmbH, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.coremedia.iso.boxes.fragment;\n\nimport com.googlecode.mp4parser.AbstractContainerBox;\nimport com.coremedia.iso.boxes.Box;\n\n/**\n * aligned(8) class TrackFragmentBox extends Box('traf'){\n * }\n */\npublic class TrackFragmentBox extends AbstractContainerBox {\n    public static final String TYPE = \"traf\";\n\n    public TrackFragmentBox() {\n        super(TYPE);\n    }\n\n\n    public TrackFragmentHeaderBox getTrackFragmentHeaderBox() {\n        for (Box box : getBoxes()) {\n            if (box instanceof TrackFragmentHeaderBox) {\n                return (TrackFragmentHeaderBox) box;\n            }\n        }\n        return null;\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/fragment/TrackFragmentHeaderBox.java",
    "content": "/*\n * Copyright 2009 castLabs GmbH, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.coremedia.iso.boxes.fragment;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * aligned(8) class TrackFragmentHeaderBox\n * extends FullBox('tfhd', 0, tf_flags){\n * unsigned int(32) track_ID;\n * // all the following are optional fields\n * unsigned int(64) base_data_offset;\n * unsigned int(32) sample_description_index;\n * unsigned int(32) default_sample_duration;\n * unsigned int(32) default_sample_size;\n * unsigned int(32) default_sample_flags\n * }\n */\npublic class TrackFragmentHeaderBox extends AbstractFullBox {\n    public static final String TYPE = \"tfhd\";\n\n    private long trackId;\n    private long baseDataOffset = -1;\n    private long sampleDescriptionIndex;\n    private long defaultSampleDuration = -1;\n    private long defaultSampleSize = -1;\n    private SampleFlags defaultSampleFlags;\n    private boolean durationIsEmpty;\n\n    public TrackFragmentHeaderBox() {\n        super(TYPE);\n    }\n\n    protected long getContentSize() {\n        long size = 8;\n        int flags = getFlags();\n        if ((flags & 0x1) == 1) { //baseDataOffsetPresent\n            size += 8;\n        }\n        if ((flags & 0x2) == 0x2) { //sampleDescriptionIndexPresent\n            size += 4;\n        }\n        if ((flags & 0x8) == 0x8) { //defaultSampleDurationPresent\n            size += 4;\n        }\n        if ((flags & 0x10) == 0x10) { //defaultSampleSizePresent\n            size += 4;\n        }\n        if ((flags & 0x20) == 0x20) { //defaultSampleFlagsPresent\n            size += 4;\n        }\n        return size;\n    }\n\n\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt32(byteBuffer, trackId);\n\n        if ((getFlags() & 0x1) == 1) { //baseDataOffsetPresent\n            IsoTypeWriter.writeUInt64(byteBuffer, getBaseDataOffset());\n        }\n        if ((getFlags() & 0x2) == 0x2) { //sampleDescriptionIndexPresent\n            IsoTypeWriter.writeUInt32(byteBuffer, getSampleDescriptionIndex());\n        }\n        if ((getFlags() & 0x8) == 0x8) { //defaultSampleDurationPresent\n            IsoTypeWriter.writeUInt32(byteBuffer, getDefaultSampleDuration());\n        }\n        if ((getFlags() & 0x10) == 0x10) { //defaultSampleSizePresent\n            IsoTypeWriter.writeUInt32(byteBuffer, getDefaultSampleSize());\n        }\n        if ((getFlags() & 0x20) == 0x20) { //defaultSampleFlagsPresent\n            defaultSampleFlags.getContent(byteBuffer);\n        }\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        trackId = IsoTypeReader.readUInt32(content);\n        if ((getFlags() & 0x1) == 1) { //baseDataOffsetPresent\n            baseDataOffset = IsoTypeReader.readUInt64(content);\n        }\n        if ((getFlags() & 0x2) == 0x2) { //sampleDescriptionIndexPresent\n            sampleDescriptionIndex = IsoTypeReader.readUInt32(content);\n        }\n        if ((getFlags() & 0x8) == 0x8) { //defaultSampleDurationPresent\n            defaultSampleDuration = IsoTypeReader.readUInt32(content);\n        }\n        if ((getFlags() & 0x10) == 0x10) { //defaultSampleSizePresent\n            defaultSampleSize = IsoTypeReader.readUInt32(content);\n        }\n        if ((getFlags() & 0x20) == 0x20) { //defaultSampleFlagsPresent\n            defaultSampleFlags = new SampleFlags(content);\n        }\n        if ((getFlags() & 0x10000) == 0x10000) { //durationIsEmpty\n            durationIsEmpty = true;\n        }\n    }\n\n    public boolean hasBaseDataOffset() {\n        return (getFlags() & 0x1) != 0;\n    }\n\n    public long getTrackId() {\n        return trackId;\n    }\n\n    public long getBaseDataOffset() {\n        return baseDataOffset;\n    }\n\n    public long getSampleDescriptionIndex() {\n        return sampleDescriptionIndex;\n    }\n\n    public long getDefaultSampleDuration() {\n        return defaultSampleDuration;\n    }\n\n    public long getDefaultSampleSize() {\n        return defaultSampleSize;\n    }\n\n    public SampleFlags getDefaultSampleFlags() {\n        return defaultSampleFlags;\n    }\n\n    public boolean isDurationIsEmpty() {\n        return durationIsEmpty;\n    }\n\n    public void setTrackId(long trackId) {\n        this.trackId = trackId;\n    }\n\n    public void setBaseDataOffset(long baseDataOffset) {\n        if (baseDataOffset == -1) {\n            setFlags(getFlags() & (Integer.MAX_VALUE ^ 0x1));\n        } else {\n            setFlags(getFlags() | 0x1); // activate the field\n        }\n        this.baseDataOffset = baseDataOffset;\n    }\n\n    public void setSampleDescriptionIndex(long sampleDescriptionIndex) {\n        if (sampleDescriptionIndex == -1) {\n            setFlags(getFlags() & (Integer.MAX_VALUE ^ 0x2));\n        } else {\n            setFlags(getFlags() | 0x2); // activate the field\n        }\n        this.sampleDescriptionIndex = sampleDescriptionIndex;\n    }\n\n    public void setDefaultSampleDuration(long defaultSampleDuration) {\n        setFlags(getFlags() | 0x8); // activate the field\n        this.defaultSampleDuration = defaultSampleDuration;\n    }\n\n    public void setDefaultSampleSize(long defaultSampleSize) {\n        setFlags(getFlags() | 0x10); // activate the field\n        this.defaultSampleSize = defaultSampleSize;\n    }\n\n    public void setDefaultSampleFlags(SampleFlags defaultSampleFlags) {\n        setFlags(getFlags() | 0x20); // activate the field\n        this.defaultSampleFlags = defaultSampleFlags;\n    }\n\n    public void setDurationIsEmpty(boolean durationIsEmpty) {\n        setFlags(getFlags() | 0x10000); // activate the field\n        this.durationIsEmpty = durationIsEmpty;\n    }\n\n    @Override\n    public String toString() {\n        final StringBuilder sb = new StringBuilder();\n        sb.append(\"TrackFragmentHeaderBox\");\n        sb.append(\"{trackId=\").append(trackId);\n        sb.append(\", baseDataOffset=\").append(baseDataOffset);\n        sb.append(\", sampleDescriptionIndex=\").append(sampleDescriptionIndex);\n        sb.append(\", defaultSampleDuration=\").append(defaultSampleDuration);\n        sb.append(\", defaultSampleSize=\").append(defaultSampleSize);\n        sb.append(\", defaultSampleFlags=\").append(defaultSampleFlags);\n        sb.append(\", durationIsEmpty=\").append(durationIsEmpty);\n        sb.append('}');\n        return sb.toString();\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/fragment/TrackFragmentRandomAccessBox.java",
    "content": "/*\n * Copyright 2009 castLabs GmbH, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.coremedia.iso.boxes.fragment;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeReaderVariable;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.IsoTypeWriterVariable;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * aligned(8) class TrackFragmentRandomAccessBox\n * extends FullBox('tfra', version, 0) {\n * unsigned int(32) track_ID;\n * const unsigned int(26) reserved = 0;\n * unsigned int(2) length_size_of_traf_num;\n * unsigned int(2) length_size_of_trun_num;\n * unsigned int(2) length_size_of_sample_num;\n * unsigned int(32) number_of_entry;\n * for(i=1; i <= number_of_entry; i++){\n * if(version==1){\n * unsigned int(64) time;\n * unsigned int(64) moof_offset;\n * }else{\n * unsigned int(32) time;\n * unsigned int(32) moof_offset;\n * }\n * unsigned int((length_size_of_traf_num+1) * 8) traf_number;\n * unsigned int((length_size_of_trun_num+1) * 8) trun_number;\n * unsigned int((length_size_of_sample_num+1) * 8) sample_number;\n * }\n * }\n */\npublic class TrackFragmentRandomAccessBox extends AbstractFullBox {\n    public static final String TYPE = \"tfra\";\n\n    private long trackId;\n    private int reserved;\n    private int lengthSizeOfTrafNum = 2;\n    private int lengthSizeOfTrunNum = 2;\n    private int lengthSizeOfSampleNum = 2;\n    private List<Entry> entries = Collections.emptyList();\n\n    public TrackFragmentRandomAccessBox() {\n        super(TYPE);\n    }\n\n\n    protected long getContentSize() {\n        long contentSize = 4;\n        contentSize += 4 + 4 /*26 + 2 + 2 + 2 */ + 4;\n        if (getVersion() == 1) {\n            contentSize += (8 + 8) * entries.size();\n        } else {\n            contentSize += (4 + 4) * entries.size();\n        }\n        contentSize += lengthSizeOfTrafNum * entries.size();\n        contentSize += lengthSizeOfTrunNum * entries.size();\n        contentSize += lengthSizeOfSampleNum * entries.size();\n        return contentSize;\n    }\n\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        trackId = IsoTypeReader.readUInt32(content);\n        long temp = IsoTypeReader.readUInt32(content);\n        reserved = (int) (temp >> 6);\n        lengthSizeOfTrafNum = ((int) (temp & 0x3F) >> 4) + 1;\n        lengthSizeOfTrunNum = ((int) (temp & 0xC) >> 2) + 1;\n        lengthSizeOfSampleNum = ((int) (temp & 0x3)) + 1;\n        long numberOfEntries = IsoTypeReader.readUInt32(content);\n\n        entries = new ArrayList<Entry>();\n\n        for (int i = 0; i < numberOfEntries; i++) {\n            Entry entry = new Entry();\n            if (getVersion() == 1) {\n                entry.time = IsoTypeReader.readUInt64(content);\n                entry.moofOffset = IsoTypeReader.readUInt64(content);\n            } else {\n                entry.time = IsoTypeReader.readUInt32(content);\n                entry.moofOffset = IsoTypeReader.readUInt32(content);\n            }\n            entry.trafNumber = IsoTypeReaderVariable.read(content, lengthSizeOfTrafNum);\n            entry.trunNumber = IsoTypeReaderVariable.read(content, lengthSizeOfTrunNum);\n            entry.sampleNumber = IsoTypeReaderVariable.read(content, lengthSizeOfSampleNum);\n\n            entries.add(entry);\n        }\n\n    }\n\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt32(byteBuffer, trackId);\n        long temp;\n        temp = reserved << 6;\n        temp = temp | (((lengthSizeOfTrafNum - 1) & 0x3) << 4);\n        temp = temp | (((lengthSizeOfTrunNum - 1) & 0x3) << 2);\n        temp = temp | ((lengthSizeOfSampleNum - 1) & 0x3);\n        IsoTypeWriter.writeUInt32(byteBuffer, temp);\n        IsoTypeWriter.writeUInt32(byteBuffer, entries.size());\n\n        for (Entry entry : entries) {\n            if (getVersion() == 1) {\n                IsoTypeWriter.writeUInt64(byteBuffer, entry.time);\n                IsoTypeWriter.writeUInt64(byteBuffer, entry.moofOffset);\n            } else {\n                IsoTypeWriter.writeUInt32(byteBuffer, entry.time);\n                IsoTypeWriter.writeUInt32(byteBuffer, entry.moofOffset);\n            }\n            IsoTypeWriterVariable.write(entry.trafNumber, byteBuffer, lengthSizeOfTrafNum);\n            IsoTypeWriterVariable.write(entry.trunNumber, byteBuffer, lengthSizeOfTrunNum);\n            IsoTypeWriterVariable.write(entry.sampleNumber, byteBuffer, lengthSizeOfSampleNum);\n\n        }\n    }\n\n\n    public void setTrackId(long trackId) {\n        this.trackId = trackId;\n    }\n\n    public void setLengthSizeOfTrafNum(int lengthSizeOfTrafNum) {\n        this.lengthSizeOfTrafNum = lengthSizeOfTrafNum;\n    }\n\n    public void setLengthSizeOfTrunNum(int lengthSizeOfTrunNum) {\n        this.lengthSizeOfTrunNum = lengthSizeOfTrunNum;\n    }\n\n    public void setLengthSizeOfSampleNum(int lengthSizeOfSampleNum) {\n        this.lengthSizeOfSampleNum = lengthSizeOfSampleNum;\n    }\n\n    public long getTrackId() {\n        return trackId;\n    }\n\n    public int getReserved() {\n        return reserved;\n    }\n\n    public int getLengthSizeOfTrafNum() {\n        return lengthSizeOfTrafNum;\n    }\n\n    public int getLengthSizeOfTrunNum() {\n        return lengthSizeOfTrunNum;\n    }\n\n    public int getLengthSizeOfSampleNum() {\n        return lengthSizeOfSampleNum;\n    }\n\n    public long getNumberOfEntries() {\n        return entries.size();\n    }\n\n    public List<Entry> getEntries() {\n        return Collections.unmodifiableList(entries);\n    }\n\n    public void setEntries(List<Entry> entries) {\n        this.entries = entries;\n    }\n\n    public static class Entry {\n        private long time;\n        private long moofOffset;\n        private long trafNumber;\n        private long trunNumber;\n        private long sampleNumber;\n\n        public Entry() {\n        }\n\n        public Entry(long time, long moofOffset, long trafNumber, long trunNumber, long sampleNumber) {\n            this.moofOffset = moofOffset;\n            this.sampleNumber = sampleNumber;\n            this.time = time;\n            this.trafNumber = trafNumber;\n            this.trunNumber = trunNumber;\n        }\n\n        public long getTime() {\n            return time;\n        }\n\n        public long getMoofOffset() {\n            return moofOffset;\n        }\n\n        public long getTrafNumber() {\n            return trafNumber;\n        }\n\n        public long getTrunNumber() {\n            return trunNumber;\n        }\n\n        public long getSampleNumber() {\n            return sampleNumber;\n        }\n\n        public void setTime(long time) {\n            this.time = time;\n        }\n\n        public void setMoofOffset(long moofOffset) {\n            this.moofOffset = moofOffset;\n        }\n\n        public void setTrafNumber(long trafNumber) {\n            this.trafNumber = trafNumber;\n        }\n\n        public void setTrunNumber(long trunNumber) {\n            this.trunNumber = trunNumber;\n        }\n\n        public void setSampleNumber(long sampleNumber) {\n            this.sampleNumber = sampleNumber;\n        }\n\n        @Override\n        public String toString() {\n            return \"Entry{\" +\n                    \"time=\" + time +\n                    \", moofOffset=\" + moofOffset +\n                    \", trafNumber=\" + trafNumber +\n                    \", trunNumber=\" + trunNumber +\n                    \", sampleNumber=\" + sampleNumber +\n                    '}';\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            if (this == o) return true;\n            if (o == null || getClass() != o.getClass()) return false;\n\n            Entry entry = (Entry) o;\n\n            if (moofOffset != entry.moofOffset) return false;\n            if (sampleNumber != entry.sampleNumber) return false;\n            if (time != entry.time) return false;\n            if (trafNumber != entry.trafNumber) return false;\n            if (trunNumber != entry.trunNumber) return false;\n\n            return true;\n        }\n\n        @Override\n        public int hashCode() {\n            int result = (int) (time ^ (time >>> 32));\n            result = 31 * result + (int) (moofOffset ^ (moofOffset >>> 32));\n            result = 31 * result + (int) (trafNumber ^ (trafNumber >>> 32));\n            result = 31 * result + (int) (trunNumber ^ (trunNumber >>> 32));\n            result = 31 * result + (int) (sampleNumber ^ (sampleNumber >>> 32));\n            return result;\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/fragment/TrackRunBox.java",
    "content": "/*\n * Copyright 2009 castLabs GmbH, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.coremedia.iso.boxes.fragment;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\n/**\n * aligned(8) class TrackRunBox\n * extends FullBox('trun', 0, tr_flags) {\n * unsigned int(32) sample_count;\n * // the following are optional fields\n * signed int(32) data_offset;\n * unsigned int(32) first_sample_flags;\n * // all fields in the following array are optional\n * {\n * unsigned int(32) sample_duration;\n * unsigned int(32) sample_size;\n * unsigned int(32) sample_flags\n * unsigned int(32) sample_composition_time_offset;\n * }[ sample_count ]\n * }\n */\n\npublic class TrackRunBox extends AbstractFullBox {\n    public static final String TYPE = \"trun\";\n    private int dataOffset;\n    private SampleFlags firstSampleFlags;\n    private List<Entry> entries = new ArrayList<Entry>();\n\n\n    public List<Entry> getEntries() {\n        return entries;\n    }\n\n    public static class Entry {\n        private long sampleDuration;\n        private long sampleSize;\n        private SampleFlags sampleFlags;\n        private int sampleCompositionTimeOffset;\n\n        public Entry() {\n        }\n\n        public Entry(long sampleDuration, long sampleSize, SampleFlags sampleFlags, int sampleCompositionTimeOffset) {\n            this.sampleDuration = sampleDuration;\n            this.sampleSize = sampleSize;\n            this.sampleFlags = sampleFlags;\n            this.sampleCompositionTimeOffset = sampleCompositionTimeOffset;\n        }\n\n        public long getSampleDuration() {\n            return sampleDuration;\n        }\n\n        public long getSampleSize() {\n            return sampleSize;\n        }\n\n        public SampleFlags getSampleFlags() {\n            return sampleFlags;\n        }\n\n        public int getSampleCompositionTimeOffset() {\n            return sampleCompositionTimeOffset;\n        }\n\n        public void setSampleDuration(long sampleDuration) {\n            this.sampleDuration = sampleDuration;\n        }\n\n        public void setSampleSize(long sampleSize) {\n            this.sampleSize = sampleSize;\n        }\n\n        public void setSampleFlags(SampleFlags sampleFlags) {\n            this.sampleFlags = sampleFlags;\n        }\n\n        public void setSampleCompositionTimeOffset(int sampleCompositionTimeOffset) {\n            this.sampleCompositionTimeOffset = sampleCompositionTimeOffset;\n        }\n\n        @Override\n        public String toString() {\n            return \"Entry{\" +\n                    \"sampleDuration=\" + sampleDuration +\n                    \", sampleSize=\" + sampleSize +\n                    \", sampleFlags=\" + sampleFlags +\n                    \", sampleCompositionTimeOffset=\" + sampleCompositionTimeOffset +\n                    '}';\n        }\n    }\n\n    public void setDataOffset(int dataOffset) {\n        if (dataOffset == -1) {\n            setFlags(getFlags() & (0xFFFFFF ^ 1));\n        } else {\n            setFlags(getFlags() | 0x1); // turn on dataoffset\n        }\n        this.dataOffset = dataOffset;\n    }\n\n    public long[] getSampleOffsets() {\n        long[] result = new long[entries.size()];\n\n        long offset = 0;\n        for (int i = 0; i < result.length; i++) {\n            result[i] = offset;\n            if (isSampleSizePresent()) {\n                offset += entries.get(i).getSampleSize();\n            } else {\n                offset += ((TrackFragmentBox) getParent()).getTrackFragmentHeaderBox().getDefaultSampleSize();\n            }\n        }\n\n        return result;\n    }\n\n    public long[] getSampleSizes() {\n        long[] result = new long[entries.size()];\n\n        for (int i = 0; i < result.length; i++) {\n            if (isSampleSizePresent()) {\n                result[i] = entries.get(i).getSampleSize();\n            } else {\n                result[i] = ((TrackFragmentBox) getParent()).getTrackFragmentHeaderBox().getDefaultSampleSize();\n            }\n        }\n\n        return result;\n    }\n\n    public long[] getSampleCompositionTimeOffsets() {\n        if (isSampleCompositionTimeOffsetPresent()) {\n            long[] result = new long[entries.size()];\n\n            for (int i = 0; i < result.length; i++) {\n                result[i] = entries.get(i).getSampleCompositionTimeOffset();\n            }\n            return result;\n        }\n        return null;\n    }\n\n    public long[] getSampleDurations() {\n        long[] result = new long[entries.size()];\n\n        for (int i = 0; i < result.length; i++) {\n            if (isSampleDurationPresent()) {\n                result[i] = entries.get(i).getSampleDuration();\n            } else {\n                result[i] = ((TrackFragmentBox) getParent()).getTrackFragmentHeaderBox().getDefaultSampleDuration();\n            }\n        }\n\n        return result;\n    }\n\n    public TrackRunBox() {\n        super(TYPE);\n    }\n\n    protected long getContentSize() {\n        long size = 8;\n        int flags = getFlags();\n\n        if ((flags & 0x1) == 0x1) { //dataOffsetPresent\n            size += 4;\n        }\n        if ((flags & 0x4) == 0x4) { //firstSampleFlagsPresent\n            size += 4;\n        }\n\n        long entrySize = 0;\n        if ((flags & 0x100) == 0x100) { //sampleDurationPresent\n            entrySize += 4;\n        }\n        if ((flags & 0x200) == 0x200) { //sampleSizePresent\n            entrySize += 4;\n        }\n        if ((flags & 0x400) == 0x400) { //sampleFlagsPresent\n            entrySize += 4;\n        }\n        if ((flags & 0x800) == 0x800) { //sampleCompositionTimeOffsetPresent\n            entrySize += 4;\n        }\n        size += entrySize * entries.size();\n        return size;\n    }\n\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt32(byteBuffer, entries.size());\n        int flags = getFlags();\n\n        if ((flags & 0x1) == 1) { //dataOffsetPresent\n            IsoTypeWriter.writeUInt32(byteBuffer, dataOffset);\n        }\n        if ((flags & 0x4) == 0x4) { //firstSampleFlagsPresent\n            firstSampleFlags.getContent(byteBuffer);\n        }\n\n        for (Entry entry : entries) {\n            if ((flags & 0x100) == 0x100) { //sampleDurationPresent\n                IsoTypeWriter.writeUInt32(byteBuffer, entry.sampleDuration);\n            }\n            if ((flags & 0x200) == 0x200) { //sampleSizePresent\n                IsoTypeWriter.writeUInt32(byteBuffer, entry.sampleSize);\n            }\n            if ((flags & 0x400) == 0x400) { //sampleFlagsPresent\n                entry.sampleFlags.getContent(byteBuffer);\n            }\n            if ((flags & 0x800) == 0x800) { //sampleCompositionTimeOffsetPresent\n                byteBuffer.putInt(entry.sampleCompositionTimeOffset);\n            }\n        }\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        long sampleCount = IsoTypeReader.readUInt32(content);\n\n        if ((getFlags() & 0x1) == 1) { //dataOffsetPresent\n            dataOffset = l2i(IsoTypeReader.readUInt32(content));\n        } else {\n            dataOffset = -1;\n        }\n        if ((getFlags() & 0x4) == 0x4) { //firstSampleFlagsPresent\n            firstSampleFlags = new SampleFlags(content);\n        }\n\n        for (int i = 0; i < sampleCount; i++) {\n            Entry entry = new Entry();\n            if ((getFlags() & 0x100) == 0x100) { //sampleDurationPresent\n                entry.sampleDuration = IsoTypeReader.readUInt32(content);\n            }\n            if ((getFlags() & 0x200) == 0x200) { //sampleSizePresent\n                entry.sampleSize = IsoTypeReader.readUInt32(content);\n            }\n            if ((getFlags() & 0x400) == 0x400) { //sampleFlagsPresent\n                entry.sampleFlags = new SampleFlags(content);\n            }\n            if ((getFlags() & 0x800) == 0x800) { //sampleCompositionTimeOffsetPresent\n                entry.sampleCompositionTimeOffset = content.getInt();\n            }\n            entries.add(entry);\n        }\n\n    }\n\n    public long getSampleCount() {\n        return entries.size();\n    }\n\n    public boolean isDataOffsetPresent() {\n        return (getFlags() & 0x1) == 1;\n    }\n\n    public boolean isFirstSampleFlagsPresent() {\n        return (getFlags() & 0x4) == 0x4;\n    }\n\n\n    public boolean isSampleSizePresent() {\n        return (getFlags() & 0x200) == 0x200;\n    }\n\n    public boolean isSampleDurationPresent() {\n        return (getFlags() & 0x100) == 0x100;\n    }\n\n    public boolean isSampleFlagsPresent() {\n        return (getFlags() & 0x400) == 0x400;\n    }\n\n    public boolean isSampleCompositionTimeOffsetPresent() {\n        return (getFlags() & 0x800) == 0x800;\n    }\n\n    public void setDataOffsetPresent(boolean v) {\n        if (v) {\n            setFlags(getFlags() | 0x01);\n        } else {\n            setFlags(getFlags() & (0xFFFFFF ^ 0x1));\n        }\n    }\n\n    public void setSampleSizePresent(boolean v) {\n        if (v) {\n            setFlags(getFlags() | 0x200);\n        } else {\n            setFlags(getFlags() & (0xFFFFFF ^ 0x200));\n        }\n    }\n\n    public void setSampleDurationPresent(boolean v) {\n\n        if (v) {\n            setFlags(getFlags() | 0x100);\n        } else {\n            setFlags(getFlags() & (0xFFFFFF ^ 0x100));\n        }\n    }\n\n    public void setSampleFlagsPresent(boolean v) {\n        if (v) {\n            setFlags(getFlags() | 0x400);\n        } else {\n            setFlags(getFlags() & (0xFFFFFF ^ 0x400));\n        }\n    }\n\n    public void setSampleCompositionTimeOffsetPresent(boolean v) {\n        if (v) {\n            setFlags(getFlags() | 0x800);\n        } else {\n            setFlags(getFlags() & (0xFFFFFF ^ 0x800));\n        }\n\n    }\n\n    public int getDataOffset() {\n        return dataOffset;\n    }\n\n    public SampleFlags getFirstSampleFlags() {\n        return firstSampleFlags;\n    }\n\n    public void setFirstSampleFlags(SampleFlags firstSampleFlags) {\n        if (firstSampleFlags == null) {\n            setFlags(getFlags() & (0xFFFFFF ^ 0x4));\n        } else {\n            setFlags(getFlags() | 0x4);\n        }\n        this.firstSampleFlags = firstSampleFlags;\n    }\n\n    @Override\n    public String toString() {\n        final StringBuilder sb = new StringBuilder();\n        sb.append(\"TrackRunBox\");\n        sb.append(\"{sampleCount=\").append(entries.size());\n        sb.append(\", dataOffset=\").append(dataOffset);\n        sb.append(\", dataOffsetPresent=\").append(isDataOffsetPresent());\n        sb.append(\", sampleSizePresent=\").append(isSampleSizePresent());\n        sb.append(\", sampleDurationPresent=\").append(isSampleDurationPresent());\n        sb.append(\", sampleFlagsPresentPresent=\").append(isSampleFlagsPresent());\n        sb.append(\", sampleCompositionTimeOffsetPresent=\").append(isSampleCompositionTimeOffsetPresent());\n        sb.append(\", firstSampleFlags=\").append(firstSampleFlags);\n        sb.append('}');\n        return sb.toString();\n    }\n\n    public void setEntries(List<Entry> entries) {\n        this.entries = entries;\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/h264/AvcConfigurationBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes.h264;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractBox;\nimport com.googlecode.mp4parser.h264.model.PictureParameterSet;\nimport com.googlecode.mp4parser.h264.model.SeqParameterSet;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * Defined in ISO/IEC 14496-15:2004.\n */\npublic final class AvcConfigurationBox extends AbstractBox {\n    public static final String TYPE = \"avcC\";\n\n    private int configurationVersion;\n    private int avcProfileIndicaation;\n    private int profileCompatibility;\n    private int avcLevelIndication;\n    private int lengthSizeMinusOne;\n    List<byte[]> sequenceParameterSets = new ArrayList<byte[]>();\n    List<byte[]> pictureParameterSets = new ArrayList<byte[]>();\n    \n    boolean hasExts = true;\n    private int chromaFormat = 1;\n    private int bitDepthLumaMinus8  = 0;\n    private int bitDepthChromaMinus8 = 0;\n    List<byte[]> sequenceParameterSetExts = new ArrayList<byte[]>();\n\n    public AvcConfigurationBox() {\n        super(TYPE);\n    }\n\n    public int getConfigurationVersion() {\n        return configurationVersion;\n    }\n\n    public int getAvcProfileIndicaation() {\n        return avcProfileIndicaation;\n    }\n\n    public int getProfileCompatibility() {\n        return profileCompatibility;\n    }\n\n    public int getAvcLevelIndication() {\n        return avcLevelIndication;\n    }\n\n    public int getLengthSizeMinusOne() {\n        return lengthSizeMinusOne;\n    }\n\n    public List<byte[]> getSequenceParameterSets() {\n        return Collections.unmodifiableList(sequenceParameterSets);\n    }\n\n    public List<byte[]> getPictureParameterSets() {\n        return Collections.unmodifiableList(pictureParameterSets);\n    }\n\n    public void setConfigurationVersion(int configurationVersion) {\n        this.configurationVersion = configurationVersion;\n    }\n\n    public void setAvcProfileIndicaation(int avcProfileIndicaation) {\n        this.avcProfileIndicaation = avcProfileIndicaation;\n    }\n\n    public void setProfileCompatibility(int profileCompatibility) {\n        this.profileCompatibility = profileCompatibility;\n    }\n\n    public void setAvcLevelIndication(int avcLevelIndication) {\n        this.avcLevelIndication = avcLevelIndication;\n    }\n\n    public void setLengthSizeMinusOne(int lengthSizeMinusOne) {\n        this.lengthSizeMinusOne = lengthSizeMinusOne;\n    }\n\n    public void setSequenceParameterSets(List<byte[]> sequenceParameterSets) {\n        this.sequenceParameterSets = sequenceParameterSets;\n    }\n\n    public void setPictureParameterSets(List<byte[]> pictureParameterSets) {\n        this.pictureParameterSets = pictureParameterSets;\n    }\n\n    public int getChromaFormat() {\n        return chromaFormat;\n    }\n\n    public void setChromaFormat(int chromaFormat) {\n        this.chromaFormat = chromaFormat;\n    }\n\n    public int getBitDepthLumaMinus8() {\n        return bitDepthLumaMinus8;\n    }\n\n    public void setBitDepthLumaMinus8(int bitDepthLumaMinus8) {\n        this.bitDepthLumaMinus8 = bitDepthLumaMinus8;\n    }\n\n    public int getBitDepthChromaMinus8() {\n        return bitDepthChromaMinus8;\n    }\n\n    public void setBitDepthChromaMinus8(int bitDepthChromaMinus8) {\n        this.bitDepthChromaMinus8 = bitDepthChromaMinus8;\n    }\n\n    public List<byte[]> getSequenceParameterSetExts() {\n        return sequenceParameterSetExts;\n    }\n\n    public void setSequenceParameterSetExts(List<byte[]> sequenceParameterSetExts) {\n        this.sequenceParameterSetExts = sequenceParameterSetExts;\n    }\n\n    public boolean hasExts() {\n        return hasExts;\n    }\n\n    public void setHasExts(boolean hasExts) {\n        this.hasExts = hasExts;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        configurationVersion = IsoTypeReader.readUInt8(content);\n        avcProfileIndicaation = IsoTypeReader.readUInt8(content);\n        profileCompatibility = IsoTypeReader.readUInt8(content);\n        avcLevelIndication = IsoTypeReader.readUInt8(content);\n        int temp = IsoTypeReader.readUInt8(content);\n        lengthSizeMinusOne = temp & 3;\n        long numberOfSeuqenceParameterSets = IsoTypeReader.readUInt8(content) & 31;\n        for (int i = 0; i < numberOfSeuqenceParameterSets; i++) {\n            int sequenceParameterSetLength = IsoTypeReader.readUInt16(content);\n\n            byte[] sequenceParameterSetNALUnit = new byte[sequenceParameterSetLength];\n            content.get(sequenceParameterSetNALUnit);\n            sequenceParameterSets.add(sequenceParameterSetNALUnit);\n        }\n        long numberOfPictureParameterSets = IsoTypeReader.readUInt8(content);\n        for (int i = 0; i < numberOfPictureParameterSets; i++) {\n            int pictureParameterSetLength = IsoTypeReader.readUInt16(content);\n            byte[] pictureParameterSetNALUnit = new byte[pictureParameterSetLength];\n            content.get(pictureParameterSetNALUnit);\n            pictureParameterSets.add(pictureParameterSetNALUnit);\n        }\n        if (content.remaining() < 4) {\n            hasExts = false;\n        }\n        if (hasExts && (avcProfileIndicaation == 100 || avcProfileIndicaation == 110 || avcProfileIndicaation == 122 || avcProfileIndicaation == 144)) {\n            chromaFormat = IsoTypeReader.readUInt8(content) & 3;\n            bitDepthLumaMinus8 = IsoTypeReader.readUInt8(content) & 7;\n            bitDepthChromaMinus8 = IsoTypeReader.readUInt8(content) & 7;\n            long numOfSequenceParameterSetExt = IsoTypeReader.readUInt8(content);\n            for (int i = 0; i < numOfSequenceParameterSetExt; i++) {\n                int sequenceParameterSetExtLength = IsoTypeReader.readUInt16(content);\n                byte[] sequenceParameterSetExtNALUnit = new byte[sequenceParameterSetExtLength];\n                content.get(sequenceParameterSetExtNALUnit);\n                sequenceParameterSetExts.add(sequenceParameterSetExtNALUnit);\n            }\n        } else {\n            chromaFormat = -1;\n            bitDepthLumaMinus8 = -1;\n            bitDepthChromaMinus8 = -1;\n        }\n\n    }\n\n\n    public long getContentSize() {\n        long size = 5;\n        size += 1; // sequenceParamsetLength\n        for (byte[] sequenceParameterSetNALUnit : sequenceParameterSets) {\n            size += 2; //lengthSizeMinusOne field\n            size += sequenceParameterSetNALUnit.length;\n        }\n        size += 1; // pictureParamsetLength\n        for (byte[] pictureParameterSetNALUnit : pictureParameterSets) {\n            size += 2; //lengthSizeMinusOne field\n            size += pictureParameterSetNALUnit.length;\n        }\n        if (hasExts && (avcProfileIndicaation == 100 || avcProfileIndicaation == 110 || avcProfileIndicaation == 122 || avcProfileIndicaation == 144)) {\n            size += 4;\n            for (byte[] sequenceParameterSetExtNALUnit : sequenceParameterSetExts) {\n                size += 2;\n                size += sequenceParameterSetExtNALUnit.length;\n            }\n        }\n\n        return size;\n    }\n\n\n    @Override\n    public void getContent(ByteBuffer byteBuffer) {\n        IsoTypeWriter.writeUInt8(byteBuffer, configurationVersion);\n        IsoTypeWriter.writeUInt8(byteBuffer, avcProfileIndicaation);\n        IsoTypeWriter.writeUInt8(byteBuffer, profileCompatibility);\n        IsoTypeWriter.writeUInt8(byteBuffer, avcLevelIndication);\n        IsoTypeWriter.writeUInt8(byteBuffer, lengthSizeMinusOne | (63 << 2));\n        IsoTypeWriter.writeUInt8(byteBuffer, (pictureParameterSets.size() & 31) | (7 << 5));\n        for (byte[] sequenceParameterSetNALUnit : sequenceParameterSets) {\n            IsoTypeWriter.writeUInt16(byteBuffer, sequenceParameterSetNALUnit.length);\n            byteBuffer.put(sequenceParameterSetNALUnit);\n        }\n        IsoTypeWriter.writeUInt8(byteBuffer, pictureParameterSets.size());\n        for (byte[] pictureParameterSetNALUnit : pictureParameterSets) {\n            IsoTypeWriter.writeUInt16(byteBuffer, pictureParameterSetNALUnit.length);\n            byteBuffer.put(pictureParameterSetNALUnit);\n        }\n        if (hasExts && (avcProfileIndicaation == 100 || avcProfileIndicaation == 110 || avcProfileIndicaation == 122 || avcProfileIndicaation == 144)) {\n            IsoTypeWriter.writeUInt8(byteBuffer, chromaFormat | (63 << 2));\n            IsoTypeWriter.writeUInt8(byteBuffer, bitDepthLumaMinus8 | (31 << 3));\n            IsoTypeWriter.writeUInt8(byteBuffer, bitDepthChromaMinus8 | (31 << 3));\n            IsoTypeWriter.writeUInt8(byteBuffer, sequenceParameterSetExts.size());\n            for (byte[] sequenceParameterSetExtNALUnit : sequenceParameterSetExts) {\n                IsoTypeWriter.writeUInt16(byteBuffer, sequenceParameterSetExtNALUnit.length);\n                byteBuffer.put(sequenceParameterSetExtNALUnit);\n            }\n        }\n    }\n\n\n    // just to display sps in isoviewer no practical use\n    public String[] getPPS() {\n        ArrayList<String> l = new ArrayList<String>();\n        for (byte[] pictureParameterSet : pictureParameterSets) {\n            String details = \"not parsable\";\n            try {\n                details = PictureParameterSet.read(pictureParameterSet).toString();\n            } catch (IOException e) {\n                throw new RuntimeException(e);\n            }\n\n            l.add(details);\n        }\n        return l.toArray(new String[l.size()]);\n    }\n\n    // just to display sps in isoviewer no practical use\n    public String[] getSPS() {\n        ArrayList<String> l = new ArrayList<String>();\n        for (byte[] sequenceParameterSet : sequenceParameterSets) {\n            String detail = \"not parsable\";\n            try {\n                detail = SeqParameterSet.read(new ByteArrayInputStream(sequenceParameterSet)).toString();\n            } catch (IOException e) {\n\n            }\n            l.add(detail);\n        }\n        return l.toArray(new String[l.size()]);\n    }\n\n\n}\n\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/mdat/DummyMap.java",
    "content": "package com.coremedia.iso.boxes.mdat;\n\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\n\n/**\n * A SortedSet that contains just one value.\n */\npublic class DummyMap<K, V> implements Map<K, V> {\n    HashSet<K> keys = new HashSet<K>();\n    V value;\n\n    public DummyMap(V value) {\n        this.value = value;\n    }\n\n    public Comparator<? super K> comparator() {\n        return null;  // I don't have any\n    }\n\n    public void addKeys(K[] keys) {\n        Collections.addAll(this.keys, keys);\n\n    }\n\n    public int size() {\n        return keys.size();\n    }\n\n    public boolean isEmpty() {\n        return keys.isEmpty();\n    }\n\n    public boolean containsKey(Object key) {\n        return keys.contains(key);\n    }\n\n    public boolean containsValue(Object value) {\n        return this.value == value;\n    }\n\n    public V get(Object key) {\n        return keys.contains(key) ? value : null;\n    }\n\n    public V put(K key, V value) {\n        assert this.value == value;\n        keys.add(key);\n        return this.value;\n    }\n\n    public V remove(Object key) {\n        V v = get(key);\n        keys.remove(key);\n        return v;\n    }\n\n    public void putAll(Map<? extends K, ? extends V> m) {\n        for (K k : m.keySet()) {\n            assert m.get(k) == value;\n            this.keys.add(k);\n        }\n    }\n\n    public void clear() {\n        keys.clear();\n    }\n\n    public Set<K> keySet() {\n        return keys;\n    }\n\n    public Collection<V> values() {\n        throw new UnsupportedOperationException();\n    }\n\n    public Set<Entry<K, V>> entrySet() {\n        throw new UnsupportedOperationException();\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/mdat/MediaDataBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes.mdat;\n\nimport com.coremedia.iso.BoxParser;\nimport com.coremedia.iso.ChannelHelper;\nimport com.coremedia.iso.boxes.Box;\nimport com.coremedia.iso.boxes.ContainerBox;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.channels.FileChannel;\nimport java.nio.channels.ReadableByteChannel;\nimport java.nio.channels.WritableByteChannel;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\n/**\n * This box contains the media data. In video tracks, this box would contain video frames. A presentation may\n * contain zero or more Media Data Boxes. The actual media data follows the type field; its structure is described\n * by the metadata (see {@link com.coremedia.iso.boxes.SampleTableBox}).<br>\n * In large presentations, it may be desirable to have more data in this box than a 32-bit size would permit. In this\n * case, the large variant of the size field is used.<br>\n * There may be any number of these boxes in the file (including zero, if all the media data is in other files). The\n * metadata refers to media data by its absolute offset within the file (see {@link com.coremedia.iso.boxes.StaticChunkOffsetBox});\n * so Media Data Box headers and free space may easily be skipped, and files without any box structure may\n * also be referenced and used.\n */\npublic final class MediaDataBox implements Box {\n    public static final String TYPE = \"mdat\";\n    ContainerBox parent;\n\n    ByteBuffer header;\n    ByteBuffer content;\n\n\n    public ContainerBox getParent() {\n        return parent;\n    }\n\n    public void setParent(ContainerBox parent) {\n        this.parent = parent;\n    }\n\n    public String getType() {\n        return TYPE;\n    }\n\n    public void getBox(WritableByteChannel writableByteChannel) throws IOException {\n        header.rewind();\n        content.rewind();\n        writableByteChannel.write(header);\n        writableByteChannel.write(content);\n    }\n\n    public long getSize() {\n        return header.limit() + content.limit();\n    }\n\n    public void parse(ReadableByteChannel readableByteChannel, ByteBuffer header, long contentSize, BoxParser boxParser) throws IOException {\n        this.header = header;\n        if (readableByteChannel instanceof FileChannel && contentSize > 1024 * 1024) {\n            // It's quite expensive to map a file into the memory. Just do it when the box is larger than a MB.\n            content = ((FileChannel) readableByteChannel).map(FileChannel.MapMode.READ_ONLY, ((FileChannel) readableByteChannel).position(), contentSize);\n            ((FileChannel) readableByteChannel).position(((FileChannel) readableByteChannel).position() + contentSize);\n        } else {\n            content = ChannelHelper.readFully(readableByteChannel, l2i(contentSize));\n        }\n\n\n    }\n\n    public ByteBuffer getContent() {\n        return content;\n    }\n\n    public ByteBuffer getHeader() {\n        return header;\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/mdat/SampleList.java",
    "content": "package com.coremedia.iso.boxes.mdat;\n\nimport com.coremedia.iso.IsoFile;\nimport com.coremedia.iso.boxes.Box;\nimport com.coremedia.iso.boxes.ChunkOffsetBox;\nimport com.coremedia.iso.boxes.SampleSizeBox;\nimport com.coremedia.iso.boxes.SampleToChunkBox;\nimport com.coremedia.iso.boxes.TrackBox;\nimport com.coremedia.iso.boxes.fragment.MovieExtendsBox;\nimport com.coremedia.iso.boxes.fragment.MovieFragmentBox;\nimport com.coremedia.iso.boxes.fragment.TrackExtendsBox;\nimport com.coremedia.iso.boxes.fragment.TrackFragmentBox;\nimport com.coremedia.iso.boxes.fragment.TrackRunBox;\n\nimport java.nio.ByteBuffer;\nimport java.util.AbstractList;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\n/**\n * Creates a list of <code>ByteBuffer</code>s that represent the samples of a given track.\n */\npublic class SampleList extends AbstractList<ByteBuffer> {\n\n    Map<Long, Long> offsets2Sizes;\n    List<Long> offsetKeys = null;\n    IsoFile isoFile;\n    HashMap<MediaDataBox, Long> mdatStartCache = new HashMap<MediaDataBox, Long>();\n    HashMap<MediaDataBox, Long> mdatEndCache = new HashMap<MediaDataBox, Long>();\n    ArrayList<MediaDataBox> mdats = new ArrayList<MediaDataBox>(1);\n\n    /**\n     * Gets a sorted random access optimized list of all sample offsets.\n     * Basically it is a map from sample number to sample offset.\n     *\n     * @return the sorted list of sample offsets\n     */\n    public List<Long> getOffsetKeys() {\n        if (offsetKeys == null) {\n            List<Long> offsetKeys = new ArrayList<Long>(offsets2Sizes.size());\n            for (Long aLong : offsets2Sizes.keySet()) {\n                offsetKeys.add(aLong);\n            }\n            Collections.sort(offsetKeys);\n            this.offsetKeys = offsetKeys;\n        }\n        return offsetKeys;\n    }\n\n\n    public SampleList(TrackBox trackBox) {\n        this.isoFile = trackBox.getIsoFile(); // where are we?\n        offsets2Sizes = new HashMap<Long, Long>();\n\n        // find all mdats first to be able to use them later with explicitly looking them up\n        long currentOffset = 0;\n        for (Box b : isoFile.getBoxes()) {\n            long currentSize = b.getSize();\n            if (\"mdat\".equals(b.getType())) {\n                if (b instanceof MediaDataBox) {\n                    long contentOffset = currentOffset + ((MediaDataBox) b).getHeader().limit();\n                    mdatStartCache.put((MediaDataBox) b, contentOffset);\n                    mdatEndCache.put((MediaDataBox) b, contentOffset + currentSize);\n                    mdats.add((MediaDataBox) b);\n                } else {\n                    throw new RuntimeException(\"Sample need to be in mdats and mdats need to be instanceof MediaDataBox\");\n                }\n            }\n            currentOffset += currentSize;\n        }\n\n\n        // first we get all sample from the 'normal' MP4 part.\n        // if there are none - no problem.\n\n        SampleSizeBox sampleSizeBox = trackBox.getSampleTableBox().getSampleSizeBox();\n        ChunkOffsetBox chunkOffsetBox = trackBox.getSampleTableBox().getChunkOffsetBox();\n        SampleToChunkBox sampleToChunkBox = trackBox.getSampleTableBox().getSampleToChunkBox();\n\n\n        if (sampleToChunkBox != null && sampleToChunkBox.getEntries().size() > 0 && chunkOffsetBox != null &&\n                chunkOffsetBox.getChunkOffsets().length > 0 && sampleSizeBox != null && sampleSizeBox.getSampleCount() > 0) {\n            long[] numberOfSamplesInChunk = sampleToChunkBox.blowup(chunkOffsetBox.getChunkOffsets().length);\n            if (sampleSizeBox.getSampleSize() > 0) {\n                // Every sample has the same size!\n                // no need to store each size separately\n                // this happens when people use raw audio formats in MP4 (are you stupid guys???)\n                offsets2Sizes = new DummyMap<Long, Long>(sampleSizeBox.getSampleSize());\n                long sampleSize = sampleSizeBox.getSampleSize();\n                for (int i = 0; i < numberOfSamplesInChunk.length; i++) {\n                    long thisChunksNumberOfSamples = numberOfSamplesInChunk[i];\n                    long sampleOffset = chunkOffsetBox.getChunkOffsets()[i];\n                    for (int j = 0; j < thisChunksNumberOfSamples; j++) {\n                        offsets2Sizes.put(sampleOffset, sampleSize);\n                        sampleOffset += sampleSize;\n                    }\n                }\n            } else {\n                // the normal case where all samples have different sizes\n                int sampleIndex = 0;\n                long sampleSizes[] = sampleSizeBox.getSampleSizes();\n                for (int i = 0; i < numberOfSamplesInChunk.length; i++) {\n                    long thisChunksNumberOfSamples = numberOfSamplesInChunk[i];\n                    long sampleOffset = chunkOffsetBox.getChunkOffsets()[i];\n                    for (int j = 0; j < thisChunksNumberOfSamples; j++) {\n                        long sampleSize = sampleSizes[sampleIndex];\n                        offsets2Sizes.put(sampleOffset, sampleSize);\n                        sampleOffset += sampleSize;\n                        sampleIndex++;\n                    }\n                }\n\n            }\n        }\n\n        // Next we add all samples from the fragments\n        // in most cases - I've never seen it different it's either normal or fragmented.\n\n        List<MovieExtendsBox> movieExtendsBoxes = trackBox.getParent().getBoxes(MovieExtendsBox.class);\n\n        if (movieExtendsBoxes.size() > 0) {\n            List<TrackExtendsBox> trackExtendsBoxes = movieExtendsBoxes.get(0).getBoxes(TrackExtendsBox.class);\n            for (TrackExtendsBox trackExtendsBox : trackExtendsBoxes) {\n                if (trackExtendsBox.getTrackId() == trackBox.getTrackHeaderBox().getTrackId()) {\n                    for (MovieFragmentBox movieFragmentBox : trackBox.getIsoFile().getBoxes(MovieFragmentBox.class)) {\n                        offsets2Sizes.putAll(getOffsets(movieFragmentBox, trackBox.getTrackHeaderBox().getTrackId()));\n                    }\n                }\n            }\n        }\n\n\n        // We have now a map from all sample offsets to their sizes\n    }\n\n\n    @Override\n    public int size() {\n        return offsets2Sizes.size();\n    }\n\n\n    @Override\n    public ByteBuffer get(int index) {\n        // it is a two stage lookup: from index to offset to size\n        Long offset = getOffsetKeys().get(index);\n        int sampleSize = l2i(offsets2Sizes.get(offset));\n\n        for (MediaDataBox mediaDataBox : mdats) {\n            long start = mdatStartCache.get(mediaDataBox);\n            long end = mdatEndCache.get(mediaDataBox);\n            if ((start <= offset) && (offset + sampleSize <= end)) {\n                ByteBuffer bb = mediaDataBox.getContent();\n                bb.position(l2i(offset - start));\n                ByteBuffer sample = bb.slice();\n                sample.limit(sampleSize);\n                return sample;\n            }\n        }\n\n        throw new RuntimeException(\"The sample with offset \" + offset + \" and size \" + sampleSize + \" is NOT located within an mdat\");\n    }\n\n    Map<Long, Long> getOffsets(MovieFragmentBox moof, long trackId) {\n        Map<Long, Long> offsets2Sizes = new HashMap<Long, Long>();\n        List<TrackFragmentBox> traf = moof.getBoxes(TrackFragmentBox.class);\n        for (TrackFragmentBox trackFragmentBox : traf) {\n            if (trackFragmentBox.getTrackFragmentHeaderBox().getTrackId() == trackId) {\n                long baseDataOffset;\n                if (trackFragmentBox.getTrackFragmentHeaderBox().hasBaseDataOffset()) {\n                    baseDataOffset = trackFragmentBox.getTrackFragmentHeaderBox().getBaseDataOffset();\n                } else {\n                    baseDataOffset = moof.getOffset();\n                }\n\n                for (TrackRunBox trun : trackFragmentBox.getBoxes(TrackRunBox.class)) {\n                    long sampleBaseOffset = baseDataOffset + trun.getDataOffset();\n                    long[] sampleOffsets = trun.getSampleOffsets();\n                    long[] sampleSizes = trun.getSampleSizes();\n                    for (int i = 0; i < sampleSizes.length; i++) {\n                        offsets2Sizes.put(sampleOffsets[i] + sampleBaseOffset, sampleSizes[i]);\n                    }\n                }\n            }\n        }\n        return offsets2Sizes;\n    }\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/mdat/Segment.java",
    "content": "package com.coremedia.iso.boxes.mdat;\n\npublic class Segment {\n    public Segment(long offset, long size) {\n        this.offset = offset;\n        this.size = size;\n    }\n\n    public long offset;\n    public long size;\n\n}"
  },
  {
    "path": "src/com/coremedia/iso/boxes/sampleentry/AmrSpecificBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes.sampleentry;\n\n\nimport com.coremedia.iso.IsoFile;\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * AMR audio format specific subbox of an audio sample entry.\n *\n * @see com.coremedia.iso.boxes.sampleentry.AudioSampleEntry\n */\npublic class AmrSpecificBox extends AbstractBox {\n    public static final String TYPE = \"damr\";\n\n    private String vendor;\n    private int decoderVersion;\n    private int modeSet;\n    private int modeChangePeriod;\n    private int framesPerSample;\n\n    public AmrSpecificBox() {\n        super(TYPE);\n    }\n\n    public String getVendor() {\n        return vendor;\n    }\n\n    public int getDecoderVersion() {\n        return decoderVersion;\n    }\n\n    public int getModeSet() {\n        return modeSet;\n    }\n\n    public int getModeChangePeriod() {\n        return modeChangePeriod;\n    }\n\n    public int getFramesPerSample() {\n        return framesPerSample;\n    }\n\n    protected long getContentSize() {\n        return 9;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        byte[] v = new byte[4];\n        content.get(v);\n        vendor = IsoFile.bytesToFourCC(v);\n\n        decoderVersion = IsoTypeReader.readUInt8(content);\n        modeSet = IsoTypeReader.readUInt16(content);\n        modeChangePeriod = IsoTypeReader.readUInt8(content);\n        framesPerSample = IsoTypeReader.readUInt8(content);\n\n    }\n\n\n    public void getContent(ByteBuffer byteBuffer) {\n        byteBuffer.put(IsoFile.fourCCtoBytes(vendor));\n        IsoTypeWriter.writeUInt8(byteBuffer, decoderVersion);\n        IsoTypeWriter.writeUInt16(byteBuffer, modeSet);\n        IsoTypeWriter.writeUInt8(byteBuffer, modeChangePeriod);\n        IsoTypeWriter.writeUInt8(byteBuffer, framesPerSample);\n    }\n\n    public String toString() {\n        StringBuilder buffer = new StringBuilder();\n        buffer.append(\"AmrSpecificBox[vendor=\").append(getVendor());\n        buffer.append(\";decoderVersion=\").append(getDecoderVersion());\n        buffer.append(\";modeSet=\").append(getModeSet());\n        buffer.append(\";modeChangePeriod=\").append(getModeChangePeriod());\n        buffer.append(\";framesPerSample=\").append(getFramesPerSample());\n        buffer.append(\"]\");\n        return buffer.toString();\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/sampleentry/AudioSampleEntry.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes.sampleentry;\n\nimport com.coremedia.iso.BoxParser;\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.boxes.Box;\nimport com.coremedia.iso.boxes.ContainerBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Contains basic information about the audio samples in this track. Format-specific information\n * is appened as boxes after the data described in ISO/IEC 14496-12 chapter 8.16.2.\n */\npublic class AudioSampleEntry extends SampleEntry implements ContainerBox {\n\n    public static final String TYPE1 = \"samr\";\n    public static final String TYPE2 = \"sawb\";\n    public static final String TYPE3 = \"mp4a\";\n    public static final String TYPE4 = \"drms\";\n    public static final String TYPE5 = \"alac\";\n    public static final String TYPE7 = \"owma\";\n    public static final String TYPE8 = \"ac-3\"; /* ETSI TS 102 366 1.2.1 Annex F */\n    public static final String TYPE9 = \"ec-3\"; /* ETSI TS 102 366 1.2.1 Annex F */\n    public static final String TYPE10 = \"mlpa\";\n\n    /**\n     * Identifier for an encrypted audio track.\n     *\n     * @see com.coremedia.iso.boxes.ProtectionSchemeInformationBox\n     */\n    public static final String TYPE_ENCRYPTED = \"enca\";\n\n    private int channelCount;\n    private int sampleSize;\n    private long sampleRate;\n    private int soundVersion;\n    private int compressionId;\n    private int packetSize;\n    private long samplesPerPacket;\n    private long bytesPerPacket;\n    private long bytesPerFrame;\n    private long bytesPerSample;\n\n    private int reserved1;\n    private long reserved2;\n    private byte[] soundVersion2Data;\n    private BoxParser boxParser;\n\n    public AudioSampleEntry(String type) {\n        super(type);\n    }\n\n    public int getChannelCount() {\n        return channelCount;\n    }\n\n    public int getSampleSize() {\n        return sampleSize;\n    }\n\n    public long getSampleRate() {\n        return sampleRate;\n    }\n\n    public int getSoundVersion() {\n        return soundVersion;\n    }\n\n    public int getCompressionId() {\n        return compressionId;\n    }\n\n    public int getPacketSize() {\n        return packetSize;\n    }\n\n    public long getSamplesPerPacket() {\n        return samplesPerPacket;\n    }\n\n    public long getBytesPerPacket() {\n        return bytesPerPacket;\n    }\n\n    public long getBytesPerFrame() {\n        return bytesPerFrame;\n    }\n\n    public long getBytesPerSample() {\n        return bytesPerSample;\n    }\n\n    public void setChannelCount(int channelCount) {\n        this.channelCount = channelCount;\n    }\n\n    public void setSampleSize(int sampleSize) {\n        this.sampleSize = sampleSize;\n    }\n\n    public void setSampleRate(long sampleRate) {\n        this.sampleRate = sampleRate;\n    }\n\n    public void setSoundVersion(int soundVersion) {\n        this.soundVersion = soundVersion;\n    }\n\n    public void setCompressionId(int compressionId) {\n        this.compressionId = compressionId;\n    }\n\n    public void setPacketSize(int packetSize) {\n        this.packetSize = packetSize;\n    }\n\n    public void setSamplesPerPacket(long samplesPerPacket) {\n        this.samplesPerPacket = samplesPerPacket;\n    }\n\n    public void setBytesPerPacket(long bytesPerPacket) {\n        this.bytesPerPacket = bytesPerPacket;\n    }\n\n    public void setBytesPerFrame(long bytesPerFrame) {\n        this.bytesPerFrame = bytesPerFrame;\n    }\n\n    public void setBytesPerSample(long bytesPerSample) {\n        this.bytesPerSample = bytesPerSample;\n    }\n\n    public void setReserved1(int reserved1) {\n        this.reserved1 = reserved1;\n    }\n\n    public void setReserved2(long reserved2) {\n        this.reserved2 = reserved2;\n    }\n\n    public void setSoundVersion2Data(byte[] soundVersion2Data) {\n        this.soundVersion2Data = soundVersion2Data;\n    }\n\n    public void setBoxParser(BoxParser boxParser) {\n        this.boxParser = boxParser;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        _parseReservedAndDataReferenceIndex(content);    //parses the six reserved bytes and dataReferenceIndex\n        // 8 bytes already parsed\n        //reserved bits - used by qt\n        soundVersion = IsoTypeReader.readUInt16(content);\n\n        //reserved\n        reserved1 = IsoTypeReader.readUInt16(content);\n        reserved2 = IsoTypeReader.readUInt32(content);\n\n        channelCount = IsoTypeReader.readUInt16(content);\n        sampleSize = IsoTypeReader.readUInt16(content);\n        //reserved bits - used by qt\n        compressionId = IsoTypeReader.readUInt16(content);\n        //reserved bits - used by qt\n        packetSize = IsoTypeReader.readUInt16(content);\n        //sampleRate = in.readFixedPoint1616();\n        sampleRate = IsoTypeReader.readUInt32(content);\n        if (!type.equals(\"mlpa\")) {\n            sampleRate = sampleRate >>> 16;\n        }\n\n        //more qt stuff - see http://mp4v2.googlecode.com/svn-history/r388/trunk/src/atom_sound.cpp\n        if (soundVersion > 0) {\n            samplesPerPacket = IsoTypeReader.readUInt32(content);\n            bytesPerPacket = IsoTypeReader.readUInt32(content);\n            bytesPerFrame = IsoTypeReader.readUInt32(content);\n            bytesPerSample = IsoTypeReader.readUInt32(content);\n        }\n        if (soundVersion == 2) {\n\n            soundVersion2Data = new byte[20];\n            content.get(20);\n        }\n        _parseChildBoxes(content);\n\n    }\n\n\n    @Override\n    protected long getContentSize() {\n        long contentSize = 28;\n        contentSize += soundVersion > 0 ? 16 : 0;\n        contentSize += soundVersion == 2 ? 20 : 0;\n        for (Box boxe : boxes) {\n            contentSize += boxe.getSize();\n        }\n        return contentSize;\n    }\n\n\n    public String toString() {\n        return \"AudioSampleEntry\";\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        _writeReservedAndDataReferenceIndex(byteBuffer);\n        IsoTypeWriter.writeUInt16(byteBuffer, soundVersion);\n        IsoTypeWriter.writeUInt16(byteBuffer, reserved1);\n        IsoTypeWriter.writeUInt32(byteBuffer, reserved2);\n        IsoTypeWriter.writeUInt16(byteBuffer, channelCount);\n        IsoTypeWriter.writeUInt16(byteBuffer, sampleSize);\n        IsoTypeWriter.writeUInt16(byteBuffer, compressionId);\n        IsoTypeWriter.writeUInt16(byteBuffer, packetSize);\n        //isos.writeFixedPont1616(getSampleRate());\n        if (type.equals(\"mlpa\")) {\n            IsoTypeWriter.writeUInt32(byteBuffer, getSampleRate());\n        } else {\n            IsoTypeWriter.writeUInt32(byteBuffer, getSampleRate() << 16);\n        }\n\n        if (soundVersion > 0) {\n            IsoTypeWriter.writeUInt32(byteBuffer, samplesPerPacket);\n            IsoTypeWriter.writeUInt32(byteBuffer, bytesPerPacket);\n            IsoTypeWriter.writeUInt32(byteBuffer, bytesPerFrame);\n            IsoTypeWriter.writeUInt32(byteBuffer, bytesPerSample);\n        }\n\n        if (soundVersion == 2) {\n            byteBuffer.put(soundVersion2Data);\n        }\n        _writeChildBoxes(byteBuffer);\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/sampleentry/MpegSampleEntry.java",
    "content": "package com.coremedia.iso.boxes.sampleentry;\n\nimport com.coremedia.iso.BoxParser;\nimport com.coremedia.iso.boxes.Box;\nimport com.coremedia.iso.boxes.ContainerBox;\n\nimport java.nio.ByteBuffer;\nimport java.util.Arrays;\n\npublic class MpegSampleEntry extends SampleEntry implements ContainerBox {\n\n    private BoxParser boxParser;\n\n    public MpegSampleEntry(String type) {\n        super(type);\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        _parseReservedAndDataReferenceIndex(content);\n        _parseChildBoxes(content);\n\n    }\n\n    @Override\n    protected long getContentSize() {\n        long contentSize = 8;\n        for (Box boxe : boxes) {\n            contentSize += boxe.getSize();\n        }\n        return contentSize;\n    }\n\n    public String toString() {\n        return \"MpegSampleEntry\" + Arrays.asList(getBoxes());\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        _writeReservedAndDataReferenceIndex(byteBuffer);\n        _writeChildBoxes(byteBuffer);\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/sampleentry/Ovc1VisualSampleEntryImpl.java",
    "content": "package com.coremedia.iso.boxes.sampleentry;\n\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.boxes.Box;\n\nimport java.nio.ByteBuffer;\n\n\npublic class Ovc1VisualSampleEntryImpl extends SampleEntry {\n    private byte[] vc1Content;\n    public static final String TYPE = \"ovc1\";\n\n\n    @Override\n    protected long getContentSize() {\n        long size = 8;\n\n        for (Box box : boxes) {\n            size += box.getSize();\n        }\n        size += vc1Content.length;\n        return size;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        _parseReservedAndDataReferenceIndex(content);\n        vc1Content = new byte[content.remaining()];\n        content.get(vc1Content);\n\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        byteBuffer.put(new byte[6]);\n        IsoTypeWriter.writeUInt16(byteBuffer, getDataReferenceIndex());\n        byteBuffer.put(vc1Content);\n    }\n\n\n    protected Ovc1VisualSampleEntryImpl() {\n        super(TYPE);\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/sampleentry/SampleEntry.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes.sampleentry;\n\nimport com.coremedia.iso.BoxParser;\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractBox;\nimport com.coremedia.iso.boxes.Box;\nimport com.coremedia.iso.boxes.ContainerBox;\nimport com.googlecode.mp4parser.util.ByteBufferByteChannel;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.channels.Channels;\nimport java.nio.channels.ReadableByteChannel;\nimport java.nio.channels.WritableByteChannel;\nimport java.util.ArrayList;\nimport java.util.LinkedList;\nimport java.util.List;\n\n/**\n * Abstract base class for all sample entries.\n *\n * @see com.coremedia.iso.boxes.sampleentry.AudioSampleEntry\n * @see com.coremedia.iso.boxes.sampleentry.VisualSampleEntry\n * @see com.coremedia.iso.boxes.sampleentry.TextSampleEntry\n */\npublic abstract class SampleEntry extends AbstractBox implements ContainerBox {\n\n\n    private int dataReferenceIndex;\n    protected List<Box> boxes = new LinkedList<Box>();\n    private BoxParser boxParser;\n\n\n    protected SampleEntry(String type) {\n        super(type);\n    }\n\n    public void setType(String type) {\n        this.type = type;\n    }\n\n    public int getDataReferenceIndex() {\n        return dataReferenceIndex;\n    }\n\n    public void setDataReferenceIndex(int dataReferenceIndex) {\n        this.dataReferenceIndex = dataReferenceIndex;\n    }\n\n    public void setBoxes(List<Box> boxes) {\n        this.boxes = new LinkedList<Box>(boxes);\n    }\n\n    public void addBox(AbstractBox b) {\n        boxes.add(b);\n    }\n\n    public boolean removeBox(Box b) {\n        return boxes.remove(b);\n    }\n\n    public List<Box> getBoxes() {\n        return boxes;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public <T extends Box> List<T> getBoxes(Class<T> clazz, boolean recursive) {\n        List<T> boxesToBeReturned = new ArrayList<T>(2);\n        for (Box boxe : boxes) { //clazz.isInstance(boxe) / clazz == boxe.getClass()?\n            if (clazz == boxe.getClass()) {\n                boxesToBeReturned.add((T) boxe);\n            }\n\n            if (recursive && boxe instanceof ContainerBox) {\n                boxesToBeReturned.addAll(((ContainerBox) boxe).getBoxes(clazz, recursive));\n            }\n        }\n        // Optimize here! Spare object creation work on arrays directly! System.arrayCopy\n        return boxesToBeReturned;\n        //return (T[]) boxesToBeReturned.toArray();\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public <T extends Box> List<T> getBoxes(Class<T> clazz) {\n        return getBoxes(clazz, false);\n    }\n\n    @Override\n    public void parse(ReadableByteChannel readableByteChannel, ByteBuffer header, long contentSize, BoxParser boxParser) throws IOException {\n        super.parse(readableByteChannel, header, contentSize, boxParser);\n        this.boxParser = boxParser;\n    }\n\n\n    public void _parseReservedAndDataReferenceIndex(ByteBuffer content) {\n        content.get(new byte[6]); // ignore 6 reserved bytes;\n        dataReferenceIndex = IsoTypeReader.readUInt16(content);\n    }\n\n    public void _parseChildBoxes(ByteBuffer content) {\n        while (content.remaining() > 8) {\n            try {\n                boxes.add(boxParser.parseBox(new ByteBufferByteChannel(content), this));\n            } catch (IOException e) {\n                throw new RuntimeException(e);\n            }\n\n        }\n        setDeadBytes(content.slice());\n    }\n\n    public void _writeReservedAndDataReferenceIndex(ByteBuffer bb) {\n        bb.put(new byte[6]);\n        IsoTypeWriter.writeUInt16(bb, dataReferenceIndex);\n    }\n\n    public void _writeChildBoxes(ByteBuffer bb) {\n        ByteArrayOutputStream baos = new ByteArrayOutputStream();\n        WritableByteChannel wbc = Channels.newChannel(baos);\n        try {\n            for (Box box : boxes) {\n                box.getBox(wbc);\n            }\n            wbc.close();\n        } catch (IOException e) {\n            throw new RuntimeException(\"Cannot happen. Everything should be in memory and therefore no exceptions.\");\n        }\n        bb.put(baos.toByteArray());\n    }\n\n    public long getNumOfBytesToFirstChild() {\n        long sizeOfChildren = 0;\n        for (Box box : boxes) {\n            sizeOfChildren += box.getSize();\n        }\n        return getSize() - sizeOfChildren;\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/sampleentry/SubtitleSampleEntry.java",
    "content": "package com.coremedia.iso.boxes.sampleentry;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Created by IntelliJ IDEA.\n * User: magnus\n * Date: 2012-03-08\n * Time: 11:36\n * To change this template use File | Settings | File Templates.\n */\npublic class SubtitleSampleEntry extends SampleEntry {\n\n    public static final String TYPE1 = \"stpp\";\n\n    public static final String TYPE_ENCRYPTED = \"\"; // This is not known!\n\n    private String namespace;\n    private String schemaLocation;\n    private String imageMimeType;\n\n    public SubtitleSampleEntry(String type) {\n        super(type);\n    }\n\n    @Override\n    protected long getContentSize() {\n        long contentSize = 8 + namespace.length() + schemaLocation.length() + imageMimeType.length() + 3;\n        return contentSize;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        _parseReservedAndDataReferenceIndex(content);\n        namespace = IsoTypeReader.readString(content);\n        schemaLocation = IsoTypeReader.readString(content);\n        imageMimeType = IsoTypeReader.readString(content);\n        _parseChildBoxes(content);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        _writeReservedAndDataReferenceIndex(byteBuffer);\n        IsoTypeWriter.writeUtf8String(byteBuffer, namespace);\n        IsoTypeWriter.writeUtf8String(byteBuffer, schemaLocation);\n        IsoTypeWriter.writeUtf8String(byteBuffer, imageMimeType);\n    }\n\n    public String getNamespace() {\n        return namespace;\n    }\n\n    public void setNamespace(String namespace) {\n        this.namespace = namespace;\n    }\n\n    public String getSchemaLocation() {\n        return schemaLocation;\n    }\n\n    public void setSchemaLocation(String schemaLocation) {\n        this.schemaLocation = schemaLocation;\n    }\n\n    public String getImageMimeType() {\n        return imageMimeType;\n    }\n\n    public void setImageMimeType(String imageMimeType) {\n        this.imageMimeType = imageMimeType;\n    }\n}\n\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/sampleentry/TextSampleEntry.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes.sampleentry;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.boxes.Box;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\n\n/**\n * Entry type for timed text samples defined in the timed text specification (ISO/IEC 14496-17).\n */\npublic class TextSampleEntry extends SampleEntry {\n\n    public static final String TYPE1 = \"tx3g\";\n\n    public static final String TYPE_ENCRYPTED = \"enct\";\n\n/*  class TextSampleEntry() extends SampleEntry ('tx3g') {\n    unsigned int(32)  displayFlags;\n    signed int(8)     horizontal-justification;\n    signed int(8)     vertical-justification;\n    unsigned int(8)   background-color-rgba[4];\n    BoxRecord         default-text-box;\n    StyleRecord       default-style;\n    FontTableBox      font-table;\n  }\n  */\n\n    private long displayFlags; // 32 bits\n    private int horizontalJustification; // 8 bit\n    private int verticalJustification;  // 8 bit\n    private int[] backgroundColorRgba = new int[4]; // 4 bytes\n    private BoxRecord boxRecord = new BoxRecord();\n    private StyleRecord styleRecord = new StyleRecord();\n\n    public TextSampleEntry(String type) {\n        super(type);\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        _parseReservedAndDataReferenceIndex(content);\n        displayFlags = IsoTypeReader.readUInt32(content);\n        horizontalJustification = IsoTypeReader.readUInt8(content);\n        verticalJustification = IsoTypeReader.readUInt8(content);\n        backgroundColorRgba = new int[4];\n        backgroundColorRgba[0] = IsoTypeReader.readUInt8(content);\n        backgroundColorRgba[1] = IsoTypeReader.readUInt8(content);\n        backgroundColorRgba[2] = IsoTypeReader.readUInt8(content);\n        backgroundColorRgba[3] = IsoTypeReader.readUInt8(content);\n        boxRecord = new BoxRecord();\n        boxRecord.parse(content);\n\n        styleRecord = new StyleRecord();\n        styleRecord.parse(content);\n        _parseChildBoxes(content);\n    }\n\n\n    protected long getContentSize() {\n        long contentSize = 18;\n        contentSize += boxRecord.getSize();\n        contentSize += styleRecord.getSize();\n        for (Box boxe : boxes) {\n            contentSize += boxe.getSize();\n        }\n        return contentSize;\n    }\n\n    public String toString() {\n        return \"TextSampleEntry\";\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        _writeReservedAndDataReferenceIndex(byteBuffer);\n        IsoTypeWriter.writeUInt32(byteBuffer, displayFlags);\n        IsoTypeWriter.writeUInt8(byteBuffer, horizontalJustification);\n        IsoTypeWriter.writeUInt8(byteBuffer, verticalJustification);\n        IsoTypeWriter.writeUInt8(byteBuffer, backgroundColorRgba[0]);\n        IsoTypeWriter.writeUInt8(byteBuffer, backgroundColorRgba[1]);\n        IsoTypeWriter.writeUInt8(byteBuffer, backgroundColorRgba[2]);\n        IsoTypeWriter.writeUInt8(byteBuffer, backgroundColorRgba[3]);\n        boxRecord.getContent(byteBuffer);\n        styleRecord.getContent(byteBuffer);\n\n        _writeChildBoxes(byteBuffer);\n    }\n\n    public BoxRecord getBoxRecord() {\n        return boxRecord;\n    }\n\n    public void setBoxRecord(BoxRecord boxRecord) {\n        this.boxRecord = boxRecord;\n    }\n\n    public StyleRecord getStyleRecord() {\n        return styleRecord;\n    }\n\n    public void setStyleRecord(StyleRecord styleRecord) {\n        this.styleRecord = styleRecord;\n    }\n\n    public boolean isScrollIn() {\n        return (displayFlags & 0x00000020) == 0x00000020;\n    }\n\n    public void setScrollIn(boolean scrollIn) {\n        if (scrollIn) {\n            displayFlags |= 0x00000020;\n        } else {\n            displayFlags &= ~0x00000020;\n        }\n    }\n\n    public boolean isScrollOut() {\n        return (displayFlags & 0x00000040) == 0x00000040;\n    }\n\n    public void setScrollOut(boolean scrollOutIn) {\n        if (scrollOutIn) {\n            displayFlags |= 0x00000040;\n        } else {\n            displayFlags &= ~0x00000040;\n        }\n    }\n\n    public boolean isScrollDirection() {\n        return (displayFlags & 0x00000180) == 0x00000180;\n    }\n\n    public void setScrollDirection(boolean scrollOutIn) {\n        if (scrollOutIn) {\n            displayFlags |= 0x00000180;\n        } else {\n            displayFlags &= ~0x00000180;\n        }\n    }\n\n    public boolean isContinuousKaraoke() {\n        return (displayFlags & 0x00000800) == 0x00000800;\n    }\n\n    public void setContinuousKaraoke(boolean continuousKaraoke) {\n        if (continuousKaraoke) {\n            displayFlags |= 0x00000800;\n        } else {\n            displayFlags &= ~0x00000800;\n        }\n    }\n\n    public boolean isWriteTextVertically() {\n        return (displayFlags & 0x00020000) == 0x00020000;\n    }\n\n    public void setWriteTextVertically(boolean writeTextVertically) {\n        if (writeTextVertically) {\n            displayFlags |= 0x00020000;\n        } else {\n            displayFlags &= ~0x00020000;\n        }\n    }\n\n\n    public boolean isFillTextRegion() {\n        return (displayFlags & 0x00040000) == 0x00040000;\n    }\n\n    public void setFillTextRegion(boolean fillTextRegion) {\n        if (fillTextRegion) {\n            displayFlags |= 0x00040000;\n        } else {\n            displayFlags &= ~0x00040000;\n        }\n    }\n\n\n    public int getHorizontalJustification() {\n        return horizontalJustification;\n    }\n\n    public void setHorizontalJustification(int horizontalJustification) {\n        this.horizontalJustification = horizontalJustification;\n    }\n\n    public int getVerticalJustification() {\n        return verticalJustification;\n    }\n\n    public void setVerticalJustification(int verticalJustification) {\n        this.verticalJustification = verticalJustification;\n    }\n\n    public int[] getBackgroundColorRgba() {\n        return backgroundColorRgba;\n    }\n\n    public void setBackgroundColorRgba(int[] backgroundColorRgba) {\n        this.backgroundColorRgba = backgroundColorRgba;\n    }\n\n    public static class BoxRecord {\n        int top;\n        int left;\n        int bottom;\n        int right;\n\n        public void parse(ByteBuffer in) {\n            top = IsoTypeReader.readUInt16(in);\n            left = IsoTypeReader.readUInt16(in);\n            bottom = IsoTypeReader.readUInt16(in);\n            right = IsoTypeReader.readUInt16(in);\n        }\n\n        public void getContent(ByteBuffer bb)  {\n            IsoTypeWriter.writeUInt16(bb, top);\n            IsoTypeWriter.writeUInt16(bb, left);\n            IsoTypeWriter.writeUInt16(bb, bottom);\n            IsoTypeWriter.writeUInt16(bb, right);\n        }\n\n        public int getSize() {\n            return 8;\n        }\n    }\n\n    /*\n    class FontRecord {\n\tunsigned int(16) \tfont-ID;\n\tunsigned int(8)\tfont-name-length;\n\tunsigned int(8)\tfont[font-name-length];\n}\n     */\n\n\n    /*\n   aligned(8) class StyleRecord {\n   unsigned int(16) \tstartChar;\n   unsigned int(16)\tendChar;\n   unsigned int(16)\tfont-ID;\n   unsigned int(8)\tface-style-flags;\n   unsigned int(8)\tfont-size;\n   unsigned int(8)\ttext-color-rgba[4];\n}\n    */\n    public static class StyleRecord {\n        int startChar;\n        int endChar;\n        int fontId;\n        int faceStyleFlags;\n        int fontSize;\n        int[] textColor = new int[]{0xff, 0xff, 0xff, 0xff};\n\n        public void parse(ByteBuffer in) {\n            startChar = IsoTypeReader.readUInt16(in);\n            endChar = IsoTypeReader.readUInt16(in);\n            fontId = IsoTypeReader.readUInt16(in);\n            faceStyleFlags = IsoTypeReader.readUInt8(in);\n            fontSize = IsoTypeReader.readUInt8(in);\n            textColor = new int[4];\n            textColor[0] = IsoTypeReader.readUInt8(in);\n            textColor[1] = IsoTypeReader.readUInt8(in);\n            textColor[2] = IsoTypeReader.readUInt8(in);\n            textColor[3] = IsoTypeReader.readUInt8(in);\n        }\n\n\n        public void getContent(ByteBuffer bb) {\n            IsoTypeWriter.writeUInt16(bb, startChar);\n            IsoTypeWriter.writeUInt16(bb, endChar);\n            IsoTypeWriter.writeUInt16(bb, fontId);\n            IsoTypeWriter.writeUInt8(bb, faceStyleFlags);\n            IsoTypeWriter.writeUInt8(bb, fontSize);\n            IsoTypeWriter.writeUInt8(bb, textColor[0]);\n            IsoTypeWriter.writeUInt8(bb, textColor[1]);\n            IsoTypeWriter.writeUInt8(bb, textColor[2]);\n            IsoTypeWriter.writeUInt8(bb, textColor[3]);\n        }\n\n        public int getSize() {\n            return 12;\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/sampleentry/VisualSampleEntry.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes.sampleentry;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.Utf8;\nimport com.coremedia.iso.boxes.Box;\nimport com.coremedia.iso.boxes.ContainerBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Contains information common to all visual tracks.\n * <code>\n * <pre>\n * class VisualSampleEntry(codingname) extends SampleEntry (codingname){\n * unsigned int(16) pre_defined = 0;\n * const unsigned int(16) reserved = 0;\n * unsigned int(32)[3] pre_defined = 0;\n * unsigned int(16) width;\n * unsigned int(16) height;\n * template unsigned int(32) horizresolution = 0x00480000; // 72 dpi\n * template unsigned int(32) vertresolution = 0x00480000; // 72 dpi\n * const unsigned int(32) reserved = 0;\n * template unsigned int(16) frame_count = 1;\n * string[32] compressorname;\n * template unsigned int(16) depth = 0x0018;\n * int(16) pre_defined = -1;\n * }<br>\n * </pre>\n * </code>\n * <p/>\n * Format-specific informationis appened as boxes after the data described in ISO/IEC 14496-12 chapter 8.16.2.\n */\npublic class VisualSampleEntry extends SampleEntry implements ContainerBox {\n    public static final String TYPE1 = \"mp4v\";\n    public static final String TYPE2 = \"s263\";\n    public static final String TYPE3 = \"avc1\";\n\n\n    /**\n     * Identifier for an encrypted video track.\n     *\n     * @see com.coremedia.iso.boxes.ProtectionSchemeInformationBox\n     */\n    public static final String TYPE_ENCRYPTED = \"encv\";\n\n\n    private int width;\n    private int height;\n    private double horizresolution;\n    private double vertresolution;\n    private int frameCount;\n    private String compressorname;\n    private int depth;\n\n    private long[] predefined = new long[3];\n\n    public VisualSampleEntry(String type) {\n        super(type);\n    }\n\n    public int getWidth() {\n        return width;\n    }\n\n    public int getHeight() {\n        return height;\n    }\n\n    public double getHorizresolution() {\n        return horizresolution;\n    }\n\n    public double getVertresolution() {\n        return vertresolution;\n    }\n\n    public int getFrameCount() {\n        return frameCount;\n    }\n\n    public String getCompressorname() {\n        return compressorname;\n    }\n\n    public int getDepth() {\n        return depth;\n    }\n\n    public void setCompressorname(String compressorname) {\n        this.compressorname = compressorname;\n    }\n\n    public void setWidth(int width) {\n        this.width = width;\n    }\n\n    public void setHeight(int height) {\n        this.height = height;\n    }\n\n    public void setHorizresolution(double horizresolution) {\n        this.horizresolution = horizresolution;\n    }\n\n    public void setVertresolution(double vertresolution) {\n        this.vertresolution = vertresolution;\n    }\n\n    public void setFrameCount(int frameCount) {\n        this.frameCount = frameCount;\n    }\n\n    public void setDepth(int depth) {\n        this.depth = depth;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        _parseReservedAndDataReferenceIndex(content);\n        long tmp = IsoTypeReader.readUInt16(content);\n        assert 0 == tmp : \"reserved byte not 0\";\n        tmp = IsoTypeReader.readUInt16(content);\n        assert 0 == tmp : \"reserved byte not 0\";\n        predefined[0] = IsoTypeReader.readUInt32(content);     // should be zero\n        predefined[1] = IsoTypeReader.readUInt32(content);     // should be zero\n        predefined[2] = IsoTypeReader.readUInt32(content);     // should be zero\n        width = IsoTypeReader.readUInt16(content);\n        height = IsoTypeReader.readUInt16(content);\n        horizresolution = IsoTypeReader.readFixedPoint1616(content);\n        vertresolution = IsoTypeReader.readFixedPoint1616(content);\n        tmp = IsoTypeReader.readUInt32(content);\n        assert 0 == tmp : \"reserved byte not 0\";\n        frameCount = IsoTypeReader.readUInt16(content);\n        int compressornameDisplayAbleData = IsoTypeReader.readUInt8(content);\n        if (compressornameDisplayAbleData > 31) {\n            System.out.println(\"invalid compressor name displayable data: \" + compressornameDisplayAbleData);\n            compressornameDisplayAbleData = 31;\n        }\n        byte[] bytes = new byte[compressornameDisplayAbleData];\n        content.get(bytes);\n        compressorname = Utf8.convert(bytes);\n        if (compressornameDisplayAbleData < 31) {\n            byte[] zeros = new byte[31 - compressornameDisplayAbleData];\n            content.get(zeros);\n            //assert Arrays.equals(zeros, new byte[zeros.length]) : \"The compressor name length was not filled up with zeros\";\n        }\n        depth = IsoTypeReader.readUInt16(content);\n        tmp = IsoTypeReader.readUInt16(content);\n        assert 0xFFFF == tmp;\n\n        _parseChildBoxes(content);\n\n    }\n\n\n    protected long getContentSize() {\n        long contentSize = 78;\n        for (Box boxe : boxes) {\n            contentSize += boxe.getSize();\n        }\n        return contentSize;\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        _writeReservedAndDataReferenceIndex(byteBuffer);\n        IsoTypeWriter.writeUInt16(byteBuffer, 0);\n        IsoTypeWriter.writeUInt16(byteBuffer, 0);\n        IsoTypeWriter.writeUInt32(byteBuffer, predefined[0]);\n        IsoTypeWriter.writeUInt32(byteBuffer, predefined[1]);\n        IsoTypeWriter.writeUInt32(byteBuffer, predefined[2]);\n\n        IsoTypeWriter.writeUInt16(byteBuffer, getWidth());\n        IsoTypeWriter.writeUInt16(byteBuffer, getHeight());\n\n        IsoTypeWriter.writeFixedPont1616(byteBuffer, getHorizresolution());\n        IsoTypeWriter.writeFixedPont1616(byteBuffer, getVertresolution());\n\n\n        IsoTypeWriter.writeUInt32(byteBuffer, 0);\n        IsoTypeWriter.writeUInt16(byteBuffer, getFrameCount());\n        IsoTypeWriter.writeUInt8(byteBuffer, Utf8.utf8StringLengthInBytes(getCompressorname()));\n        byteBuffer.put(Utf8.convert(getCompressorname()));\n        int a = Utf8.utf8StringLengthInBytes(getCompressorname());\n        while (a < 31) {\n            a++;\n            byteBuffer.put((byte) 0);\n        }\n        IsoTypeWriter.writeUInt16(byteBuffer, getDepth());\n        IsoTypeWriter.writeUInt16(byteBuffer, 0xFFFF);\n\n        _writeChildBoxes(byteBuffer);\n\n    }\n\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/threegpp26244/LocationInformationBox.java",
    "content": "package com.coremedia.iso.boxes.threegpp26244;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Location Information Box as specified in TS 26.244.\n */\npublic class LocationInformationBox extends AbstractFullBox {\n    public static final String TYPE = \"loci\";\n\n    private String language;\n    private String name = \"\";\n    private int role;\n    private double longitude;\n    private double latitude;\n    private double altitude;\n    private String astronomicalBody = \"\";\n    private String additionalNotes = \"\";\n\n    public LocationInformationBox() {\n        super(TYPE);\n    }\n\n    public String getLanguage() {\n        return language;\n    }\n\n    public void setLanguage(String language) {\n        this.language = language;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public int getRole() {\n        return role;\n    }\n\n    public void setRole(int role) {\n        this.role = role;\n    }\n\n    public double getLongitude() {\n        return longitude;\n    }\n\n    public void setLongitude(double longitude) {\n        this.longitude = longitude;\n    }\n\n    public double getLatitude() {\n        return latitude;\n    }\n\n    public void setLatitude(double latitude) {\n        this.latitude = latitude;\n    }\n\n    public double getAltitude() {\n        return altitude;\n    }\n\n    public void setAltitude(double altitude) {\n        this.altitude = altitude;\n    }\n\n    public String getAstronomicalBody() {\n        return astronomicalBody;\n    }\n\n    public void setAstronomicalBody(String astronomicalBody) {\n        this.astronomicalBody = astronomicalBody;\n    }\n\n    public String getAdditionalNotes() {\n        return additionalNotes;\n    }\n\n    public void setAdditionalNotes(String additionalNotes) {\n        this.additionalNotes = additionalNotes;\n    }\n\n    protected long getContentSize() {\n        return 22 + Utf8.convert(name).length + Utf8.convert(astronomicalBody).length + Utf8.convert(additionalNotes).length;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        language = IsoTypeReader.readIso639(content);\n        name = IsoTypeReader.readString(content);\n        role = IsoTypeReader.readUInt8(content);\n        longitude = IsoTypeReader.readFixedPoint1616(content);\n        latitude = IsoTypeReader.readFixedPoint1616(content);\n        altitude = IsoTypeReader.readFixedPoint1616(content);\n        astronomicalBody = IsoTypeReader.readString(content);\n        additionalNotes = IsoTypeReader.readString(content);\n    }\n\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeIso639(byteBuffer, language);\n        byteBuffer.put(Utf8.convert(name));\n        byteBuffer.put((byte) 0);\n        IsoTypeWriter.writeUInt8(byteBuffer, role);\n        IsoTypeWriter.writeFixedPont1616(byteBuffer, longitude);\n        IsoTypeWriter.writeFixedPont1616(byteBuffer, latitude);\n        IsoTypeWriter.writeFixedPont1616(byteBuffer, altitude);\n        byteBuffer.put(Utf8.convert(astronomicalBody));\n        byteBuffer.put((byte) 0);\n        byteBuffer.put(Utf8.convert(additionalNotes));\n        byteBuffer.put((byte) 0);\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/vodafone/AlbumArtistBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes.vodafone;\n\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Special box used by Vodafone in their DCF containing information about the artist. Mainly used for OMA DCF files\n * containing music. Resides in the {@link com.coremedia.iso.boxes.UserDataBox}.\n */\npublic class AlbumArtistBox extends AbstractFullBox {\n    public static final String TYPE = \"albr\";\n\n    private String language;\n    private String albumArtist;\n\n    public AlbumArtistBox() {\n        super(TYPE);\n    }\n\n    public String getLanguage() {\n        return language;\n    }\n\n    public String getAlbumArtist() {\n        return albumArtist;\n    }\n\n    public void setLanguage(String language) {\n        this.language = language;\n    }\n\n    public void setAlbumArtist(String albumArtist) {\n        this.albumArtist = albumArtist;\n    }\n\n    protected long getContentSize() {\n        return 6 + Utf8.utf8StringLengthInBytes(albumArtist) + 1;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        language = IsoTypeReader.readIso639(content);\n        albumArtist = IsoTypeReader.readString(content);\n    }\n\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeIso639(byteBuffer, language);\n        byteBuffer.put(Utf8.convert(albumArtist));\n        byteBuffer.put((byte) 0);\n    }\n\n    public String toString() {\n        return \"AlbumArtistBox[language=\" + getLanguage() + \";albumArtist=\" + getAlbumArtist() + \"]\";\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/vodafone/ContentDistributorIdBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes.vodafone;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Vodafone specific box. Usage unclear.\n */\npublic class ContentDistributorIdBox extends AbstractFullBox {\n    public static final String TYPE = \"cdis\";\n\n    private String language;\n    private String contentDistributorId;\n\n    public ContentDistributorIdBox() {\n        super(TYPE);\n    }\n\n    public String getLanguage() {\n        return language;\n    }\n\n    public String getContentDistributorId() {\n        return contentDistributorId;\n    }\n\n    protected long getContentSize() {\n        return 2 + Utf8.utf8StringLengthInBytes(contentDistributorId) + 5;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        language = IsoTypeReader.readIso639(content);\n        contentDistributorId = IsoTypeReader.readString(content);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeIso639(byteBuffer, language);\n        byteBuffer.put(Utf8.convert(contentDistributorId));\n        byteBuffer.put((byte) 0);\n\n    }\n\n    public String toString() {\n        return \"ContentDistributorIdBox[language=\" + getLanguage() + \";contentDistributorId=\" + getContentDistributorId() + \"]\";\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/vodafone/CoverUriBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes.vodafone;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * A vodafone specific box.\n */\npublic class CoverUriBox extends AbstractFullBox {\n    public static final String TYPE = \"cvru\";\n\n    private String coverUri;\n\n    public CoverUriBox() {\n        super(TYPE);\n    }\n\n    public String getCoverUri() {\n        return coverUri;\n    }\n\n    public void setCoverUri(String coverUri) {\n        this.coverUri = coverUri;\n    }\n\n    protected long getContentSize() {\n        return Utf8.utf8StringLengthInBytes(coverUri) + 5;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        coverUri = IsoTypeReader.readString(content);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        byteBuffer.put(Utf8.convert(coverUri));\n        byteBuffer.put((byte) 0);\n    }\n\n\n    public String toString() {\n        return \"CoverUriBox[coverUri=\" + getCoverUri() + \"]\";\n    }\n}\n"
  },
  {
    "path": "src/com/coremedia/iso/boxes/vodafone/LyricsUriBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.coremedia.iso.boxes.vodafone;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * A box in the {@link com.coremedia.iso.boxes.UserDataBox} containing information about the lyric location.\n * Invented by Vodafone.\n */\npublic class LyricsUriBox extends AbstractFullBox {\n    public static final String TYPE = \"lrcu\";\n\n    private String lyricsUri;\n\n    public LyricsUriBox() {\n        super(TYPE);\n    }\n\n    public String getLyricsUri() {\n        return lyricsUri;\n    }\n\n    public void setLyricsUri(String lyricsUri) {\n        this.lyricsUri = lyricsUri;\n    }\n\n    protected long getContentSize() {\n        return Utf8.utf8StringLengthInBytes(lyricsUri) + 5;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        lyricsUri = IsoTypeReader.readString(content);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        byteBuffer.put(Utf8.convert(lyricsUri));\n        byteBuffer.put((byte) 0);\n    }\n\n    public String toString() {\n        return \"LyricsUriBox[lyricsUri=\" + getLyricsUri() + \"]\";\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/AbstractBox.java",
    "content": "/*  \n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.googlecode.mp4parser;\n\nimport com.coremedia.iso.BoxParser;\nimport com.coremedia.iso.ChannelHelper;\nimport com.coremedia.iso.Hex;\nimport com.coremedia.iso.IsoFile;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.boxes.Box;\nimport com.coremedia.iso.boxes.ContainerBox;\nimport com.coremedia.iso.boxes.UserBox;\nimport com.googlecode.mp4parser.annotations.DoNotParseDetail;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.channels.FileChannel;\nimport java.nio.channels.ReadableByteChannel;\nimport java.nio.channels.WritableByteChannel;\nimport java.util.logging.Logger;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\n/**\n * A basic on-demand parsing box. Requires the implementation of three methods to become a fully working box:\n * <ol>\n * <li>{@link #_parseDetails(java.nio.ByteBuffer)}</li>\n * <li>{@link #getContent(java.nio.ByteBuffer)}</li>\n * <li>{@link #getContentSize()}</li>\n * </ol>\n * additionally this new box has to be put into the <code>isoparser-default.properties</code> file so that\n * it is accessible by the <code>PropertyBoxParserImpl</code>\n */\npublic abstract class AbstractBox implements Box {\n    private static Logger LOG = Logger.getLogger(AbstractBox.class.getName());\n\n    protected String type;\n    private byte[] userType;\n    private ContainerBox parent;\n\n    private ByteBuffer content;\n    private ByteBuffer deadBytes = null;\n\n\n    protected AbstractBox(String type) {\n        this.type = type;\n    }\n\n    protected AbstractBox(String type, byte[] userType) {\n        this.type = type;\n        this.userType = userType;\n    }\n\n    /**\n     * Get the box's content size without its header. This must be the exact number of bytes\n     * that <code>getContent(ByteBuffer)</code> writes.\n     *\n     * @return Gets the box's content size in bytes\n     * @see #getContent(java.nio.ByteBuffer)\n     */\n    protected abstract long getContentSize();\n\n    /**\n     * Write the box's content into the given <code>ByteBuffer</code>. This must include flags\n     * and version in case of a full box. <code>byteBuffer</code> has been initialized with\n     * <code>getSize()</code> bytes.\n     *\n     * @param byteBuffer the sink for the box's content\n     */\n    protected abstract void getContent(ByteBuffer byteBuffer);\n\n    /**\n     * Parse the box's fields and child boxes if any.\n     *\n     * @param content the box's raw content beginning after the 4-cc field.\n     */\n    protected abstract void _parseDetails(ByteBuffer content);\n\n    /**\n     * Read the box's content from a byte channel without parsing it. Parsing is done on-demand.\n     *\n     * @param readableByteChannel the (part of the) iso file to parse\n     * @param contentSize         expected contentSize of the box\n     * @param boxParser           creates inner boxes\n     * @throws IOException in case of an I/O error.\n     */\n    @DoNotParseDetail\n    public void parse(ReadableByteChannel readableByteChannel, ByteBuffer header, long contentSize, BoxParser boxParser) throws IOException {\n        if (readableByteChannel instanceof FileChannel && contentSize > 1024 * 1024) {\n            // It's quite expensive to map a file into the memory. Just do it when the box is larger than a MB.\n            content = ((FileChannel) readableByteChannel).map(FileChannel.MapMode.READ_ONLY, ((FileChannel) readableByteChannel).position(), contentSize);\n            ((FileChannel) readableByteChannel).position(((FileChannel) readableByteChannel).position() + contentSize);\n        } else {\n            assert contentSize < Integer.MAX_VALUE;\n            content = ChannelHelper.readFully(readableByteChannel, contentSize);\n        }\n    }\n\n    public void getBox(WritableByteChannel os) throws IOException {\n        ByteBuffer bb = ByteBuffer.allocate(l2i(getSize()));\n        getHeader(bb);\n        if (content == null) {\n            getContent(bb);\n            if (deadBytes != null) {\n                deadBytes.rewind();\n                while (deadBytes.remaining() > 0) {\n                    bb.put(deadBytes);\n                }\n            }\n        } else {\n            content.rewind();\n            bb.put(content);\n        }\n        bb.rewind();\n        os.write(bb);\n    }\n\n\n    /**\n     * Parses the raw content of the box. It surrounds the actual parsing\n     * which is done\n     */\n    synchronized final void parseDetails() {\n        if (content != null) {\n            ByteBuffer content = this.content;\n            this.content = null;\n            content.rewind();\n            _parseDetails(content);\n            if (content.remaining() > 0) {\n                deadBytes = content.slice();\n            }\n            assert verify(content);\n        }\n    }\n\n    /**\n     * Sets the 'dead' bytes. These bytes are left if the content of the box\n     * has been parsed but not all bytes have been used up.\n     *\n     * @param newDeadBytes the unused bytes with no meaning but required for bytewise reconstruction\n     */\n    protected void setDeadBytes(ByteBuffer newDeadBytes) {\n        deadBytes = newDeadBytes;\n    }\n\n\n    /**\n     * Gets the full size of the box including header and content.\n     *\n     * @return the box's size\n     */\n    public long getSize() {\n        long size = (content == null ? getContentSize() : content.limit());\n        size += (8 + // size|type\n                (size >= ((1L << 32) - 8) ? 8 : 0) + // 32bit - 8 byte size and type\n                (UserBox.TYPE.equals(getType()) ? 16 : 0));\n        size += (deadBytes == null ? 0 : deadBytes.limit());\n        return size;\n    }\n\n    @DoNotParseDetail\n    public String getType() {\n        return type;\n    }\n\n    @DoNotParseDetail\n    public byte[] getUserType() {\n        return userType;\n    }\n\n    @DoNotParseDetail\n    public ContainerBox getParent() {\n        return parent;\n    }\n\n    @DoNotParseDetail\n    public void setParent(ContainerBox parent) {\n        this.parent = parent;\n    }\n\n    @DoNotParseDetail\n    public IsoFile getIsoFile() {\n        return parent.getIsoFile();\n    }\n\n    /**\n     * Check if details are parsed.\n     *\n     * @return <code>true</code> whenever the content <code>ByteBuffer</code> is not <code>null</code>\n     */\n    public boolean isParsed() {\n        return content == null;\n    }\n\n\n    /**\n     * Verifies that a box can be reconstructed byte-exact after parsing.\n     *\n     * @param content the raw content of the box\n     * @return <code>true</code> if raw content exactly matches the reconstructed content\n     */\n    private boolean verify(ByteBuffer content) {\n        ByteBuffer bb = ByteBuffer.allocate(l2i(getContentSize() + (deadBytes != null ? deadBytes.limit() : 0)));\n        getContent(bb);\n        if (deadBytes != null) {\n            deadBytes.rewind();\n            while (deadBytes.remaining() > 0) {\n                bb.put(deadBytes);\n            }\n        }\n        content.rewind();\n        bb.rewind();\n\n\n        if (content.remaining() != bb.remaining()) {\n            LOG.severe(\"remaining differs \" + content.remaining() + \" vs. \" + bb.remaining());\n            return false;\n        }\n        int p = content.position();\n        for (int i = content.limit() - 1, j = bb.limit() - 1; i >= p; i--, j--) {\n            byte v1 = content.get(i);\n            byte v2 = bb.get(j);\n            if (v1 != v2) {\n                LOG.severe(\"buffers differ at \" + i + \": \"  + v1 + \"/\" + v2);\n                byte[] b1 = new byte[content.remaining()];\n                byte[] b2 = new byte[bb.remaining()];\n                content.get(b1);\n                bb.get(b2);\n                System.err.println(Hex.encodeHex(b1));\n                System.err.println(Hex.encodeHex(b2));\n                return false;\n            }\n        }\n        return true;\n\n    }\n\n    private boolean isSmallBox() {\n        return (content == null ? (getContentSize() + (deadBytes != null ? deadBytes.limit() : 0) + 8) : content.limit()) < 1L << 32;\n    }\n\n    private void getHeader(ByteBuffer byteBuffer) {\n        if (isSmallBox()) {\n            IsoTypeWriter.writeUInt32(byteBuffer, this.getSize());\n            byteBuffer.put(IsoFile.fourCCtoBytes(getType()));\n        } else {\n            IsoTypeWriter.writeUInt32(byteBuffer, 1);\n            byteBuffer.put(IsoFile.fourCCtoBytes(getType()));\n            IsoTypeWriter.writeUInt64(byteBuffer, getSize());\n        }\n        if (UserBox.TYPE.equals(getType())) {\n            byteBuffer.put(getUserType());\n        }\n\n\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/AbstractContainerBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.googlecode.mp4parser;\n\nimport com.coremedia.iso.BoxParser;\nimport com.coremedia.iso.boxes.Box;\nimport com.coremedia.iso.boxes.ContainerBox;\nimport com.googlecode.mp4parser.util.ByteBufferByteChannel;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.channels.ReadableByteChannel;\nimport java.nio.channels.WritableByteChannel;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.logging.Logger;\n\n\n/**\n * Abstract base class suitable for most boxes acting purely as container for other boxes.\n */\npublic abstract class AbstractContainerBox extends AbstractBox implements ContainerBox {\n    private static Logger LOG = Logger.getLogger(AbstractContainerBox.class.getName());\n\n    protected List<Box> boxes = new LinkedList<Box>();\n    protected BoxParser boxParser;\n\n    @Override\n    protected long getContentSize() {\n        long contentSize = 0;\n        for (Box boxe : boxes) {\n            contentSize += boxe.getSize();\n        }\n        return contentSize;\n    }\n\n    public AbstractContainerBox(String type) {\n        super(type);\n    }\n\n    public List<Box> getBoxes() {\n        return Collections.unmodifiableList(boxes);\n    }\n\n    public void setBoxes(List<Box> boxes) {\n        this.boxes = new LinkedList<Box>(boxes);\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public <T extends Box> List<T> getBoxes(Class<T> clazz) {\n        return getBoxes(clazz, false);\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public <T extends Box> List<T> getBoxes(Class<T> clazz, boolean recursive) {\n        List<T> boxesToBeReturned = new ArrayList<T>(2);\n        for (Box boxe : boxes) {\n            //clazz.isInstance(boxe) / clazz == boxe.getClass()?\n            // I hereby finally decide to use isInstance\n\n            if (clazz.isInstance(boxe)) {\n                boxesToBeReturned.add((T) boxe);\n            }\n\n            if (recursive && boxe instanceof ContainerBox) {\n                boxesToBeReturned.addAll(((ContainerBox) boxe).getBoxes(clazz, recursive));\n            }\n        }\n        return boxesToBeReturned;\n    }\n\n    /**\n     * Add <code>b</code> to the container and sets the parent correctly.\n     *\n     * @param b will be added to the container\n     */\n    public void addBox(Box b) {\n        b.setParent(this);\n        boxes.add(b);\n    }\n\n    public void removeBox(Box b) {\n        boxes.remove(b);\n    }\n\n    @Override\n    public void parse(ReadableByteChannel readableByteChannel, ByteBuffer header, long contentSize, BoxParser boxParser) throws IOException {\n        super.parse(readableByteChannel, header, contentSize, boxParser);\n        this.boxParser = boxParser;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseChildBoxes(content);\n    }\n\n\n    public String toString() {\n        StringBuilder buffer = new StringBuilder();\n\n        buffer.append(this.getClass().getSimpleName()).append(\"[\");\n        for (int i = 0; i < boxes.size(); i++) {\n            if (i > 0) {\n                buffer.append(\";\");\n            }\n            buffer.append(boxes.get(i).toString());\n        }\n        buffer.append(\"]\");\n        return buffer.toString();\n    }\n\n    /**\n     * The number of bytes from box start (first length byte) to the\n     * first length byte of the first child box\n     *\n     * @return offset to first child box\n     */\n    public long getNumOfBytesToFirstChild() {\n        return 8;\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeChildBoxes(byteBuffer);\n    }\n\n    protected final void parseChildBoxes(ByteBuffer content) {\n        try {\n            while (content.remaining() >= 8) { //  8 is the minimal size for a sane box\n                boxes.add(boxParser.parseBox(new ByteBufferByteChannel(content), this));\n            }\n\n            if (content.remaining() != 0) {\n                setDeadBytes(content.slice());\n                LOG.warning(\"Something's wrong with the sizes. There are dead bytes in a container box.\");\n            }\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    protected final void writeChildBoxes(ByteBuffer bb) {\n        WritableByteChannel wbc = new ByteBufferByteChannel(bb);\n        for (Box box : boxes) {\n            try {\n                box.getBox(wbc);\n            } catch (IOException e) {\n                // My WritableByteChannel won't throw any excpetion\n                throw new RuntimeException(\"Cannot happen to me\", e);\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/AbstractFullBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.googlecode.mp4parser;\n\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.boxes.FullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Base class for all ISO Full boxes.\n */\npublic abstract class AbstractFullBox extends AbstractBox implements FullBox {\n    private int version;\n    private int flags;\n\n    protected AbstractFullBox(String type) {\n        super(type);\n    }\n\n    protected AbstractFullBox(String type, byte[] userType) {\n        super(type, userType);\n    }\n\n    public int getVersion() {\n        return version;\n    }\n\n    public void setVersion(int version) {\n        this.version = version;\n    }\n\n    public int getFlags() {\n        return flags;\n    }\n\n    public void setFlags(int flags) {\n        this.flags = flags;\n    }\n\n\n    /**\n     * Parses the version/flags header and returns the remaining box size.\n     *\n     * @param content\n     * @return number of bytes read\n     */\n    protected final long parseVersionAndFlags(ByteBuffer content) {\n        version = IsoTypeReader.readUInt8(content);\n        flags = IsoTypeReader.readUInt24(content);\n        return 4;\n    }\n\n    protected final void writeVersionAndFlags(ByteBuffer bb) {\n        IsoTypeWriter.writeUInt8(bb, version);\n        IsoTypeWriter.writeUInt24(bb, flags);\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/FullContainerBox.java",
    "content": "/*  \n * Copyright 2008 CoreMedia AG, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License); \n * you may not use this file except in compliance with the License. \n * You may obtain a copy of the License at \n * \n *     http://www.apache.org/licenses/LICENSE-2.0 \n * \n * Unless required by applicable law or agreed to in writing, software \n * distributed under the License is distributed on an AS IS BASIS, \n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n * See the License for the specific language governing permissions and \n * limitations under the License. \n */\n\npackage com.googlecode.mp4parser;\n\nimport com.coremedia.iso.BoxParser;\nimport com.coremedia.iso.boxes.Box;\nimport com.coremedia.iso.boxes.ContainerBox;\nimport com.googlecode.mp4parser.util.ByteBufferByteChannel;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.channels.ReadableByteChannel;\nimport java.nio.channels.WritableByteChannel;\nimport java.util.ArrayList;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.logging.Logger;\n\n/**\n * Abstract base class for a full iso box only containing ither boxes.\n */\npublic abstract class FullContainerBox extends AbstractFullBox implements ContainerBox {\n    protected List<Box> boxes = new LinkedList<Box>();\n    private static Logger LOG = Logger.getLogger(FullContainerBox.class.getName());\n    BoxParser boxParser;\n\n    public void setBoxes(List<Box> boxes) {\n        this.boxes = new LinkedList<Box>(boxes);\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public <T extends Box> List<T> getBoxes(Class<T> clazz) {\n        return getBoxes(clazz, false);\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public <T extends Box> List<T> getBoxes(Class<T> clazz, boolean recursive) {\n        List<T> boxesToBeReturned = new ArrayList<T>(2);\n        for (Box boxe : boxes) { //clazz.isInstance(boxe) / clazz == boxe.getClass()?\n            if (clazz == boxe.getClass()) {\n                boxesToBeReturned.add((T) boxe);\n            }\n\n            if (recursive && boxe instanceof ContainerBox) {\n                boxesToBeReturned.addAll((((ContainerBox) boxe).getBoxes(clazz, recursive)));\n            }\n        }\n        // Optimize here! Spare object creation work on arrays directly! System.arrayCopy\n        return boxesToBeReturned;\n        //return (T[]) boxesToBeReturned.toArray();\n    }\n\n    protected long getContentSize() {\n        long contentSize = 4; // flags and version\n        for (Box boxe : boxes) {\n            contentSize += boxe.getSize();\n        }\n        return contentSize;\n    }\n\n    public void addBox(Box b) {\n        boxes.add(b);\n    }\n\n    public void removeBox(Box b) {\n        boxes.remove(b);\n    }\n\n    public FullContainerBox(String type) {\n        super(type);\n    }\n\n    public List<Box> getBoxes() {\n        return boxes;\n    }\n\n    @Override\n    public void parse(ReadableByteChannel readableByteChannel, ByteBuffer header, long contentSize, BoxParser boxParser) throws IOException {\n        super.parse(readableByteChannel, header, contentSize, boxParser);\n        this.boxParser = boxParser;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        parseChildBoxes(content);\n    }\n\n    protected final void parseChildBoxes(ByteBuffer content) {\n        try {\n            while (content.remaining() >= 8) { //  8 is the minimal size for a sane box\n                boxes.add(boxParser.parseBox(new ByteBufferByteChannel(content), this));\n            }\n\n            if (content.remaining() != 0) {\n                setDeadBytes(content.slice());\n                LOG.severe(\"Some sizes are wrong\");\n            }\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    public String toString() {\n        StringBuilder buffer = new StringBuilder();\n        buffer.append(this.getClass().getSimpleName()).append(\"[\");\n        for (int i = 0; i < boxes.size(); i++) {\n            if (i > 0) {\n                buffer.append(\";\");\n            }\n            buffer.append(boxes.get(i).toString());\n        }\n        buffer.append(\"]\");\n        return buffer.toString();\n    }\n\n\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        writeChildBoxes(byteBuffer);\n    }\n\n    protected final void writeChildBoxes(ByteBuffer bb) {\n        WritableByteChannel wbc = new ByteBufferByteChannel(bb);\n        for (Box box : boxes) {\n            try {\n                box.getBox(wbc);\n            } catch (IOException e) {\n                // cannot happen since my WritableByteChannel won't throw any excpetion\n                throw new RuntimeException(\"Cannot happen.\", e);\n            }\n\n        }\n    }\n\n    public long getNumOfBytesToFirstChild() {\n        long sizeOfChildren = 0;\n        for (Box box : boxes) {\n            sizeOfChildren += box.getSize();\n        }\n        return getSize() - sizeOfChildren;\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/annotations/DoNotParseDetail.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.annotations;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Inherited;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n *\n */\n\n@Target({ElementType.METHOD, ElementType.TYPE})\n@Retention(RetentionPolicy.RUNTIME)\n@Inherited\n@Documented\n/**\n * Mark a method with this annotation to prevent triggering the call of\n * <code>AbstractBox#parseDetails()</code> before actually executing the\n * method.\n * @see com.googlecode.mp4parser.RequiresParseDetailAspect\n */\npublic @interface DoNotParseDetail {\n}\n\n\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/annotations/ParseDetail.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.annotations;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Inherited;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n\n@Target({ElementType.METHOD, ElementType.TYPE})\n@Retention(RetentionPolicy.RUNTIME)\n@Inherited\n@Documented\npublic @interface ParseDetail {\n}\n\n\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/AbstractTrack.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.authoring;\n\n/**\n *\n */\npublic abstract class AbstractTrack implements Track {\n    private boolean enabled = true;\n    private boolean inMovie = true;\n    private boolean inPreview = true;\n    private boolean inPoster = true;\n\n    public boolean isEnabled() {\n        return enabled;\n    }\n\n    public boolean isInMovie() {\n        return inMovie;\n    }\n\n    public boolean isInPreview() {\n        return inPreview;\n    }\n\n    public boolean isInPoster() {\n        return inPoster;\n    }\n\n    public void setEnabled(boolean enabled) {\n        this.enabled = enabled;\n    }\n\n    public void setInMovie(boolean inMovie) {\n        this.inMovie = inMovie;\n    }\n\n    public void setInPreview(boolean inPreview) {\n        this.inPreview = inPreview;\n    }\n\n    public void setInPoster(boolean inPoster) {\n        this.inPoster = inPoster;\n    }\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/DateHelper.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring;\n\nimport java.util.Date;\n\n/**\n * Converts ISO Dates (seconds since 1/1/1904) to Date and vice versa.\n */\npublic class DateHelper {\n    /**\n     * Converts a long value with seconds since 1/1/1904 to Date.\n     *\n     * @param secondsSince seconds since 1/1/1904\n     * @return date the corresponding <code>Date</code>\n     */\n    static public Date convert(long secondsSince) {\n        return new Date((secondsSince - 2082844800L) * 1000L);\n    }\n\n\n    /**\n     * Converts a date as long to a mac date as long\n     *\n     * @param date date to convert\n     * @return date in mac format\n     */\n    static public long convert(Date date) {\n        return (date.getTime() / 1000L) + 2082844800L;\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/Movie.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring;\n\nimport java.util.LinkedList;\nimport java.util.List;\n\n/**\n *\n */\npublic class Movie {\n    List<Track> tracks = new LinkedList<Track>();\n\n    public List<Track> getTracks() {\n        return tracks;\n    }\n\n    public void setTracks(List<Track> tracks) {\n        this.tracks = tracks;\n    }\n\n    public void addTrack(Track nuTrack) {\n        // do some checking\n        // perhaps the movie needs to get longer!\n        if (getTrackByTrackId(nuTrack.getTrackMetaData().getTrackId()) != null) {\n            // We already have a track with that trackId. Create a new one\n            nuTrack.getTrackMetaData().setTrackId(getNextTrackId());\n        }\n        tracks.add(nuTrack);\n    }\n\n\n    @Override\n    public String toString() {\n        String s = \"Movie{ \";\n        for (Track track : tracks) {\n            s += \"track_\" + track.getTrackMetaData().getTrackId() + \" (\" + track.getHandler() + \") \";\n        }\n\n        s += '}';\n        return s;\n    }\n\n    public long getNextTrackId() {\n        long nextTrackId = 0;\n        for (Track track : tracks) {\n            nextTrackId = nextTrackId < track.getTrackMetaData().getTrackId() ? track.getTrackMetaData().getTrackId() : nextTrackId;\n        }\n        return ++nextTrackId;\n    }\n\n\n    public Track getTrackByTrackId(long trackId) {\n        for (Track track : tracks) {\n            if (track.getTrackMetaData().getTrackId() == trackId) {\n                return track;\n            }\n        }\n        return null;\n    }\n\n\n    public long getTimescale() {\n        long timescale = this.getTracks().iterator().next().getTrackMetaData().getTimescale();\n        for (Track track : this.getTracks()) {\n            timescale = gcd(track.getTrackMetaData().getTimescale(), timescale);\n        }\n        return timescale;\n    }\n\n    public static long gcd(long a, long b) {\n        if (b == 0) {\n            return a;\n        }\n        return gcd(b, a % b);\n    }\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/Mp4TrackImpl.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring;\n\nimport com.coremedia.iso.boxes.*;\nimport com.coremedia.iso.boxes.fragment.MovieExtendsBox;\nimport com.coremedia.iso.boxes.fragment.MovieFragmentBox;\nimport com.coremedia.iso.boxes.fragment.TrackFragmentBox;\nimport com.coremedia.iso.boxes.fragment.TrackRunBox;\nimport com.coremedia.iso.boxes.mdat.SampleList;\n\nimport java.nio.ByteBuffer;\nimport java.util.LinkedList;\nimport java.util.List;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\n/**\n * Represents a single track of an MP4 file.\n */\npublic class Mp4TrackImpl extends AbstractTrack {\n    private List<ByteBuffer> samples;\n    private SampleDescriptionBox sampleDescriptionBox;\n    private List<TimeToSampleBox.Entry> decodingTimeEntries;\n    private List<CompositionTimeToSample.Entry> compositionTimeEntries;\n    private long[] syncSamples;\n    private List<SampleDependencyTypeBox.Entry> sampleDependencies;\n    private TrackMetaData trackMetaData = new TrackMetaData();\n    private String handler;\n    private AbstractMediaHeaderBox mihd;\n\n    public Mp4TrackImpl(TrackBox trackBox) {\n        samples = new SampleList(trackBox);\n        SampleTableBox stbl = trackBox.getMediaBox().getMediaInformationBox().getSampleTableBox();\n        handler = trackBox.getMediaBox().getHandlerBox().getHandlerType();\n\n\n        mihd = trackBox.getMediaBox().getMediaInformationBox().getMediaHeaderBox();\n\n\n        sampleDescriptionBox = stbl.getSampleDescriptionBox();\n        if (trackBox.getParent().getBoxes(MovieExtendsBox.class).size() > 0) {\n\n            decodingTimeEntries = new LinkedList<TimeToSampleBox.Entry>();\n            compositionTimeEntries = new LinkedList<CompositionTimeToSample.Entry>();\n            sampleDependencies = new LinkedList<SampleDependencyTypeBox.Entry>();\n\n            for (MovieFragmentBox movieFragmentBox : trackBox.getIsoFile().getBoxes(MovieFragmentBox.class)) {\n                List<TrackFragmentBox> trafs = movieFragmentBox.getBoxes(TrackFragmentBox.class);\n                for (TrackFragmentBox traf : trafs) {\n                    if (traf.getTrackFragmentHeaderBox().getTrackId() == trackBox.getTrackHeaderBox().getTrackId()) {\n                        List<TrackRunBox> truns = traf.getBoxes(TrackRunBox.class);\n                        for (TrackRunBox trun : truns) {\n                            for (TrackRunBox.Entry entry : trun.getEntries()) {\n                                if (trun.isSampleDurationPresent()) {\n                                    if (decodingTimeEntries.size() == 0 ||\n                                            decodingTimeEntries.get(decodingTimeEntries.size() - 1).getDelta() != entry.getSampleDuration()) {\n                                        decodingTimeEntries.add(new TimeToSampleBox.Entry(1, entry.getSampleDuration()));\n                                    } else {\n                                        TimeToSampleBox.Entry e = decodingTimeEntries.get(decodingTimeEntries.size() - 1);\n                                        e.setCount(e.getCount() + 1);\n                                    }\n                                }\n                                if (trun.isSampleCompositionTimeOffsetPresent()) {\n                                    if (compositionTimeEntries.size() == 0 ||\n                                            compositionTimeEntries.get(compositionTimeEntries.size() - 1).getOffset() != entry.getSampleCompositionTimeOffset()) {\n                                        compositionTimeEntries.add(new CompositionTimeToSample.Entry(1, l2i(entry.getSampleCompositionTimeOffset())));\n                                    } else {\n                                        CompositionTimeToSample.Entry e = compositionTimeEntries.get(compositionTimeEntries.size() - 1);\n                                        e.setCount(e.getCount() + 1);\n                                    }\n                                }\n\n                            }\n\n\n                        }\n\n\n                    }\n                }\n            }\n        } else {\n            decodingTimeEntries = stbl.getTimeToSampleBox().getEntries();\n            if (stbl.getCompositionTimeToSample() != null) {\n                compositionTimeEntries = stbl.getCompositionTimeToSample().getEntries();\n            }\n            if (stbl.getSyncSampleBox() != null) {\n                syncSamples = stbl.getSyncSampleBox().getSampleNumber();\n            }\n            if (stbl.getSampleDependencyTypeBox() != null) {\n                sampleDependencies = stbl.getSampleDependencyTypeBox().getEntries();\n            }\n        }\n        MediaHeaderBox mdhd = trackBox.getMediaBox().getMediaHeaderBox();\n        TrackHeaderBox tkhd = trackBox.getTrackHeaderBox();\n\n        setEnabled(tkhd.isEnabled());\n        setInMovie(tkhd.isInMovie());\n        setInPoster(tkhd.isInPoster());\n        setInPreview(tkhd.isInPreview());\n\n        trackMetaData.setTrackId(tkhd.getTrackId());\n        trackMetaData.setCreationTime(DateHelper.convert(mdhd.getCreationTime()));\n        trackMetaData.setLanguage(mdhd.getLanguage());\n/*        System.err.println(mdhd.getModificationTime());\n        System.err.println(DateHelper.convert(mdhd.getModificationTime()));\n        System.err.println(DateHelper.convert(DateHelper.convert(mdhd.getModificationTime())));\n        System.err.println(DateHelper.convert(DateHelper.convert(DateHelper.convert(mdhd.getModificationTime()))));*/\n\n        trackMetaData.setModificationTime(DateHelper.convert(mdhd.getModificationTime()));\n        trackMetaData.setTimescale(mdhd.getTimescale());\n        trackMetaData.setHeight(tkhd.getHeight());\n        trackMetaData.setWidth(tkhd.getWidth());\n        trackMetaData.setLayer(tkhd.getLayer());\n    }\n\n    public List<ByteBuffer> getSamples() {\n        return samples;\n    }\n\n\n    public SampleDescriptionBox getSampleDescriptionBox() {\n        return sampleDescriptionBox;\n    }\n\n    public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {\n        return decodingTimeEntries;\n    }\n\n    public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {\n        return compositionTimeEntries;\n    }\n\n    public long[] getSyncSamples() {\n        return syncSamples;\n    }\n\n    public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {\n        return sampleDependencies;\n    }\n\n    public TrackMetaData getTrackMetaData() {\n        return trackMetaData;\n    }\n\n    public String getHandler() {\n        return handler;\n    }\n\n    public AbstractMediaHeaderBox getMediaHeaderBox() {\n        return mihd;\n    }\n\n    public SubSampleInformationBox getSubsampleInformationBox() {\n        return null;\n    }\n\n    @Override\n    public String toString() {\n        return \"Mp4TrackImpl{\" +\n                \"handler='\" + handler + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/Track.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring;\n\nimport com.coremedia.iso.boxes.*;\n\nimport java.nio.ByteBuffer;\nimport java.util.List;\n\n/**\n * Represents a Track. A track is a timed sequence of related samples.\n * <p/>\n * <b>NOTE: </b><br/\n * For media data, a track corresponds to a sequence of images or sampled audio; for hint tracks, a track\n * corresponds to a streaming channel.\n */\npublic interface Track {\n\n    SampleDescriptionBox getSampleDescriptionBox();\n\n    List<TimeToSampleBox.Entry> getDecodingTimeEntries();\n\n    List<CompositionTimeToSample.Entry> getCompositionTimeEntries();\n\n    long[] getSyncSamples();\n\n    List<SampleDependencyTypeBox.Entry> getSampleDependencies();\n\n    TrackMetaData getTrackMetaData();\n\n    String getHandler();\n\n    boolean isEnabled();\n\n    boolean isInMovie();\n\n    boolean isInPreview();\n\n    boolean isInPoster();\n\n    List<ByteBuffer> getSamples();\n\n    public AbstractMediaHeaderBox getMediaHeaderBox();\n\n    public SubSampleInformationBox getSubsampleInformationBox();\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/TrackMetaData.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring;\n\nimport java.util.Date;\n\n/**\n *\n */\npublic class TrackMetaData implements Cloneable {\n    private String language;\n    private long timescale;\n    private Date modificationTime;\n    private Date creationTime;\n    private double width;\n    private double height;\n    private float volume;\n    private long trackId = 1; // zero is not allowed\n    private int group = 0;\n    private double startTime = 0;\n\n\n    /**\n     * specifies the front-to-back ordering of video tracks; tracks with lower\n     * numbers are closer to the viewer. 0 is the normal value, and -1 would be\n     * in front of track 0, and so on.\n     */\n    int layer;\n\n    public String getLanguage() {\n        return language;\n    }\n\n    public void setLanguage(String language) {\n        this.language = language;\n    }\n\n    public long getTimescale() {\n        return timescale;\n    }\n\n    public void setTimescale(long timescale) {\n        this.timescale = timescale;\n    }\n\n    public Date getModificationTime() {\n        return modificationTime;\n    }\n\n    public void setModificationTime(Date modificationTime) {\n        this.modificationTime = modificationTime;\n    }\n\n    public Date getCreationTime() {\n        return creationTime;\n    }\n\n    public void setCreationTime(Date creationTime) {\n        this.creationTime = creationTime;\n    }\n\n    public double getWidth() {\n        return width;\n    }\n\n    public void setWidth(double width) {\n        this.width = width;\n    }\n\n    public double getHeight() {\n        return height;\n    }\n\n    public void setHeight(double height) {\n        this.height = height;\n    }\n\n    public long getTrackId() {\n        return trackId;\n    }\n\n    public void setTrackId(long trackId) {\n        this.trackId = trackId;\n    }\n\n    public int getLayer() {\n        return layer;\n    }\n\n    public void setLayer(int layer) {\n        this.layer = layer;\n    }\n\n    public float getVolume() {\n        return volume;\n    }\n\n    public void setVolume(float volume) {\n        this.volume = volume;\n    }\n\n    public int getGroup() {\n        return group;\n    }\n\n    public void setGroup(int group) {\n        this.group = group;\n    }\n\n    public double getStartTime() {\n        return startTime;\n    }\n\n    public void setStartTime(double startTime) {\n        this.startTime = startTime;\n    }\n\n    public Object clone() {\n        try {\n            return super.clone();\n        } catch (CloneNotSupportedException e) {\n            return null;\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/builder/ByteBufferHelper.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring.builder;\n\nimport java.nio.ByteBuffer;\nimport java.nio.MappedByteBuffer;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Used to merge adjacent byte buffers.\n */\npublic class ByteBufferHelper {\n    public static List<ByteBuffer> mergeAdjacentBuffers(List<ByteBuffer> samples) {\n        ArrayList<ByteBuffer> nuSamples = new ArrayList<ByteBuffer>(samples.size());\n        for (ByteBuffer buffer : samples) {\n            int lastIndex = nuSamples.size() - 1;\n            if (lastIndex >= 0 && buffer.hasArray() && nuSamples.get(lastIndex).hasArray() && buffer.array() == nuSamples.get(lastIndex).array() &&\n                    nuSamples.get(lastIndex).arrayOffset() + nuSamples.get(lastIndex).limit() == buffer.arrayOffset()) {\n                ByteBuffer oldBuffer = nuSamples.remove(lastIndex);\n                ByteBuffer nu = ByteBuffer.wrap(buffer.array(), oldBuffer.arrayOffset(), oldBuffer.limit() + buffer.limit()).slice();\n                // We need to slice here since wrap([], offset, length) just sets position and not the arrayOffset.\n                nuSamples.add(nu);\n            } else if (lastIndex >= 0 &&\n                    buffer instanceof MappedByteBuffer && nuSamples.get(lastIndex) instanceof MappedByteBuffer &&\n                    nuSamples.get(lastIndex).limit() == nuSamples.get(lastIndex).capacity() - buffer.capacity()) {\n                // This can go wrong - but will it?\n                ByteBuffer oldBuffer = nuSamples.get(lastIndex);\n                oldBuffer.limit(buffer.limit() + oldBuffer.limit());\n            } else {\n                buffer.rewind();\n                nuSamples.add(buffer);\n            }\n        }\n        return nuSamples;\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/builder/DefaultMp4Builder.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring.builder;\n\nimport com.coremedia.iso.BoxParser;\nimport com.coremedia.iso.IsoFile;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.boxes.Box;\nimport com.coremedia.iso.boxes.CompositionTimeToSample;\nimport com.coremedia.iso.boxes.ContainerBox;\nimport com.coremedia.iso.boxes.DataEntryUrlBox;\nimport com.coremedia.iso.boxes.DataInformationBox;\nimport com.coremedia.iso.boxes.DataReferenceBox;\nimport com.coremedia.iso.boxes.EditBox;\nimport com.coremedia.iso.boxes.EditListBox;\nimport com.coremedia.iso.boxes.FileTypeBox;\nimport com.coremedia.iso.boxes.HandlerBox;\nimport com.coremedia.iso.boxes.MediaBox;\nimport com.coremedia.iso.boxes.MediaHeaderBox;\nimport com.coremedia.iso.boxes.MediaInformationBox;\nimport com.coremedia.iso.boxes.MovieBox;\nimport com.coremedia.iso.boxes.MovieHeaderBox;\nimport com.coremedia.iso.boxes.SampleDependencyTypeBox;\nimport com.coremedia.iso.boxes.SampleSizeBox;\nimport com.coremedia.iso.boxes.SampleTableBox;\nimport com.coremedia.iso.boxes.SampleToChunkBox;\nimport com.coremedia.iso.boxes.StaticChunkOffsetBox;\nimport com.coremedia.iso.boxes.SyncSampleBox;\nimport com.coremedia.iso.boxes.TimeToSampleBox;\nimport com.coremedia.iso.boxes.TrackBox;\nimport com.coremedia.iso.boxes.TrackHeaderBox;\nimport com.googlecode.mp4parser.authoring.DateHelper;\nimport com.googlecode.mp4parser.authoring.Movie;\nimport com.googlecode.mp4parser.authoring.Track;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.MappedByteBuffer;\nimport java.nio.channels.GatheringByteChannel;\nimport java.nio.channels.ReadableByteChannel;\nimport java.nio.channels.WritableByteChannel;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.logging.Logger;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\n/**\n * Creates a plain MP4 file from a video. Plain as plain can be.\n */\npublic class DefaultMp4Builder implements Mp4Builder {\n    Set<StaticChunkOffsetBox> chunkOffsetBoxes = new HashSet<StaticChunkOffsetBox>();\n    private static Logger LOG = Logger.getLogger(DefaultMp4Builder.class.getName());\n\n    HashMap<Track, List<ByteBuffer>> track2Sample = new HashMap<Track, List<ByteBuffer>>();\n    HashMap<Track, long[]> track2SampleSizes = new HashMap<Track, long[]>();\n    private FragmentIntersectionFinder intersectionFinder = new TwoSecondIntersectionFinder();\n\n    List<String> hdlrs = new LinkedList<String>();\n\n    public void setAllowedHandlers(List<String> hdlrs) {\n        this.hdlrs = hdlrs;\n    }\n\n    public void setIntersectionFinder(FragmentIntersectionFinder intersectionFinder) {\n        this.intersectionFinder = intersectionFinder;\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    public IsoFile build(Movie movie)  {\n        LOG.fine(\"Creating movie \" + movie);\n        for (Track track : movie.getTracks()) {\n            // getting the samples may be a time consuming activity\n            List<ByteBuffer> samples = track.getSamples();\n            track2Sample.put(track, samples);\n            long[] sizes = new long[samples.size()];\n            for (int i = 0; i < sizes.length; i++) {\n                sizes[i] = samples.get(i).limit();\n            }\n            track2SampleSizes.put(track, sizes);\n        }\n\n        IsoFile isoFile = new IsoFile();\n        // ouch that is ugly but I don't know how to do it else\n        List<String> minorBrands = new LinkedList<String>();\n        minorBrands.add(\"isom\");\n        minorBrands.add(\"iso2\");\n        minorBrands.add(\"avc1\");\n\n        isoFile.addBox(new FileTypeBox(\"isom\", 0, minorBrands));\n        isoFile.addBox(createMovieBox(movie));\n        InterleaveChunkMdat mdat = new InterleaveChunkMdat(movie);\n        isoFile.addBox(mdat);\n\n        /*\n        dataOffset is where the first sample starts. In this special mdat the samples always start\n        at offset 16 so that we can use the same offset for large boxes and small boxes\n         */\n        long dataOffset = mdat.getDataOffset();\n        for (StaticChunkOffsetBox chunkOffsetBox : chunkOffsetBoxes) {\n            long[] offsets = chunkOffsetBox.getChunkOffsets();\n            for (int i = 0; i < offsets.length; i++) {\n                offsets[i] += dataOffset;\n            }\n        }\n\n\n        return isoFile;\n    }\n\n    private MovieBox createMovieBox(Movie movie) {\n        MovieBox movieBox = new MovieBox();\n        List<Box> movieBoxChildren = new LinkedList<Box>();\n        MovieHeaderBox mvhd = new MovieHeaderBox();\n        mvhd.setVersion(1);\n        mvhd.setCreationTime(DateHelper.convert(new Date()));\n        mvhd.setModificationTime(DateHelper.convert(new Date()));\n\n        long movieTimeScale = getTimescale(movie);\n        long duration = 0;\n\n        for (Track track : movie.getTracks()) {\n            long tracksDuration = getDuration(track) * movieTimeScale / track.getTrackMetaData().getTimescale();\n            if (tracksDuration > duration) {\n                duration = tracksDuration;\n            }\n\n\n        }\n\n        mvhd.setDuration(duration);\n        mvhd.setTimescale(movieTimeScale);\n        // find the next available trackId\n        long nextTrackId = 0;\n        for (Track track : movie.getTracks()) {\n            nextTrackId = nextTrackId < track.getTrackMetaData().getTrackId() ? track.getTrackMetaData().getTrackId() : nextTrackId;\n        }\n        mvhd.setNextTrackId(++nextTrackId);\n        movieBoxChildren.add(mvhd);\n        for (Track track : movie.getTracks()) {\n            movieBoxChildren.add(createTrackBox(track, movie));\n        }\n        // metadata here\n        movieBox.setBoxes(movieBoxChildren);\n        Box udta = createUdta(movie);\n        if (udta != null) {\n            movieBox.addBox(udta);\n        }\n        return movieBox;\n\n    }\n\n    /**\n     * Override to create a user data box that may contain metadata.\n     * @return a 'udta' box or <code>null</code> if none provided\n     */\n    protected Box createUdta(Movie movie) {\n        return null;\n    }\n\n    private TrackBox createTrackBox(Track track, Movie movie) {\n\n        LOG.info(\"Creating Mp4TrackImpl \" + track);\n        TrackBox trackBox = new TrackBox();\n        TrackHeaderBox tkhd = new TrackHeaderBox();\n        tkhd.setVersion(1);\n        int flags = 0;\n        if (track.isEnabled()) {\n            flags += 1;\n        }\n\n        if (track.isInMovie()) {\n            flags += 2;\n        }\n\n        if (track.isInPreview()) {\n            flags += 4;\n        }\n\n        if (track.isInPoster()) {\n            flags += 8;\n        }\n        tkhd.setFlags(flags);\n\n        tkhd.setAlternateGroup(track.getTrackMetaData().getGroup());\n        tkhd.setCreationTime(DateHelper.convert(track.getTrackMetaData().getCreationTime()));\n        // We need to take edit list box into account in trackheader duration\n        // but as long as I don't support edit list boxes it is sufficient to\n        // just translate media duration to movie timescale\n        tkhd.setDuration(getDuration(track) * getTimescale(movie) / track.getTrackMetaData().getTimescale());\n        tkhd.setHeight(track.getTrackMetaData().getHeight());\n        tkhd.setWidth(track.getTrackMetaData().getWidth());\n        tkhd.setLayer(track.getTrackMetaData().getLayer());\n        tkhd.setModificationTime(DateHelper.convert(new Date()));\n        tkhd.setTrackId(track.getTrackMetaData().getTrackId());\n        tkhd.setVolume(track.getTrackMetaData().getVolume());\n        trackBox.addBox(tkhd);\n\n/*\n        EditBox edit = new EditBox();\n        EditListBox editListBox = new EditListBox();\n        editListBox.setEntries(Collections.singletonList(\n                new EditListBox.Entry(editListBox, (long) (track.getTrackMetaData().getStartTime() * getTimescale(movie)), -1, 1)));\n        edit.addBox(editListBox);\n        trackBox.addBox(edit);\n*/\n\n        MediaBox mdia = new MediaBox();\n        trackBox.addBox(mdia);\n        MediaHeaderBox mdhd = new MediaHeaderBox();\n        mdhd.setCreationTime(DateHelper.convert(track.getTrackMetaData().getCreationTime()));\n        mdhd.setDuration(getDuration(track));\n        mdhd.setTimescale(track.getTrackMetaData().getTimescale());\n        mdhd.setLanguage(track.getTrackMetaData().getLanguage());\n        mdia.addBox(mdhd);\n        HandlerBox hdlr = new HandlerBox();\n        mdia.addBox(hdlr);\n\n        hdlr.setHandlerType(track.getHandler());\n\n        MediaInformationBox minf = new MediaInformationBox();\n        minf.addBox(track.getMediaHeaderBox());\n\n        // dinf: all these three boxes tell us is that the actual\n        // data is in the current file and not somewhere external\n        DataInformationBox dinf = new DataInformationBox();\n        DataReferenceBox dref = new DataReferenceBox();\n        dinf.addBox(dref);\n        DataEntryUrlBox url = new DataEntryUrlBox();\n        url.setFlags(1);\n        dref.addBox(url);\n        minf.addBox(dinf);\n        //\n\n        SampleTableBox stbl = new SampleTableBox();\n\n        stbl.addBox(track.getSampleDescriptionBox());\n\n        List<TimeToSampleBox.Entry> decodingTimeToSampleEntries = track.getDecodingTimeEntries();\n        if (decodingTimeToSampleEntries != null && !track.getDecodingTimeEntries().isEmpty()) {\n            TimeToSampleBox stts = new TimeToSampleBox();\n            stts.setEntries(track.getDecodingTimeEntries());\n            stbl.addBox(stts);\n        }\n\n        List<CompositionTimeToSample.Entry> compositionTimeToSampleEntries = track.getCompositionTimeEntries();\n        if (compositionTimeToSampleEntries != null && !compositionTimeToSampleEntries.isEmpty()) {\n            CompositionTimeToSample ctts = new CompositionTimeToSample();\n            ctts.setEntries(compositionTimeToSampleEntries);\n            stbl.addBox(ctts);\n        }\n\n        long[] syncSamples = track.getSyncSamples();\n        if (syncSamples != null && syncSamples.length > 0) {\n            SyncSampleBox stss = new SyncSampleBox();\n            stss.setSampleNumber(syncSamples);\n            stbl.addBox(stss);\n        }\n\n        if (track.getSampleDependencies() != null && !track.getSampleDependencies().isEmpty()) {\n            SampleDependencyTypeBox sdtp = new SampleDependencyTypeBox();\n            sdtp.setEntries(track.getSampleDependencies());\n            stbl.addBox(sdtp);\n        }\n        int chunkSize[] = getChunkSizes(track, movie);\n        SampleToChunkBox stsc = new SampleToChunkBox();\n        stsc.setEntries(new LinkedList<SampleToChunkBox.Entry>());\n        long lastChunkSize = Integer.MIN_VALUE; // to be sure the first chunks hasn't got the same size\n        for (int i = 0; i < chunkSize.length; i++) {\n            // The sample description index references the sample description box\n            // that describes the samples of this chunk. My Tracks cannot have more\n            // than one sample description box. Therefore 1 is always right\n            // the first chunk has the number '1'\n            if (lastChunkSize != chunkSize[i]) {\n                stsc.getEntries().add(new SampleToChunkBox.Entry(i + 1, chunkSize[i], 1));\n                lastChunkSize = chunkSize[i];\n            }\n        }\n        stbl.addBox(stsc);\n\n        SampleSizeBox stsz = new SampleSizeBox();\n        stsz.setSampleSizes(track2SampleSizes.get(track));\n\n        stbl.addBox(stsz);\n        // The ChunkOffsetBox we create here is just a stub\n        // since we haven't created the whole structure we can't tell where the\n        // first chunk starts (mdat box). So I just let the chunk offset\n        // start at zero and I will add the mdat offset later.\n        StaticChunkOffsetBox stco = new StaticChunkOffsetBox();\n        this.chunkOffsetBoxes.add(stco);\n        long offset = 0;\n        long[] chunkOffset = new long[chunkSize.length];\n        // all tracks have the same number of chunks\n        LOG.fine(\"Calculating chunk offsets for track_\" + track.getTrackMetaData().getTrackId());\n        for (int i = 0; i < chunkSize.length; i++) {\n            // The filelayout will be:\n            // chunk_1_track_1,... ,chunk_1_track_n, chunk_2_track_1,... ,chunk_2_track_n, ... , chunk_m_track_1,... ,chunk_m_track_n\n            // calculating the offsets\n            LOG.finer(\"Calculating chunk offsets for track_\" + track.getTrackMetaData().getTrackId() + \" chunk \" + i);\n            for (Track current : movie.getTracks()) {\n                LOG.finest(\"Adding offsets of track_\" + current.getTrackMetaData().getTrackId());\n                int[] chunkSizes = getChunkSizes(current, movie);\n                long firstSampleOfChunk = 0;\n                for (int j = 0; j < i; j++) {\n                    firstSampleOfChunk += chunkSizes[j];\n                }\n                if (current == track) {\n                    chunkOffset[i] = offset;\n                }\n                for (int j = l2i(firstSampleOfChunk); j < firstSampleOfChunk + chunkSizes[i]; j++) {\n                    offset += track2SampleSizes.get(current)[j];\n                }\n            }\n        }\n        stco.setChunkOffsets(chunkOffset);\n        stbl.addBox(stco);\n        minf.addBox(stbl);\n        mdia.addBox(minf);\n\n        return trackBox;\n    }\n\n    private class InterleaveChunkMdat implements Box {\n        List<Track> tracks;\n        List<ByteBuffer> samples = new LinkedList<ByteBuffer>();\n        ContainerBox parent;\n\n        long contentSize = 0;\n\n        public ContainerBox getParent() {\n            return parent;\n        }\n\n        public void setParent(ContainerBox parent) {\n            this.parent = parent;\n        }\n\n        public void parse(ReadableByteChannel readableByteChannel, ByteBuffer header, long contentSize, BoxParser boxParser) throws IOException {\n        }\n\n        private InterleaveChunkMdat(Movie movie) {\n\n            tracks = movie.getTracks();\n            Map<Track, int[]> chunks = new HashMap<Track, int[]>();\n            for (Track track : movie.getTracks()) {\n                chunks.put(track, getChunkSizes(track, movie));\n            }\n\n            for (int i = 0; i < chunks.values().iterator().next().length; i++) {\n                for (Track track : tracks) {\n\n                    int[] chunkSizes = chunks.get(track);\n                    long firstSampleOfChunk = 0;\n                    for (int j = 0; j < i; j++) {\n                        firstSampleOfChunk += chunkSizes[j];\n                    }\n\n                    for (int j = l2i(firstSampleOfChunk); j < firstSampleOfChunk + chunkSizes[i]; j++) {\n\n                        ByteBuffer s = DefaultMp4Builder.this.track2Sample.get(track).get(j);\n                        contentSize += s.limit();\n                        samples.add((ByteBuffer) s.rewind());\n                    }\n\n                }\n\n            }\n\n        }\n\n        public long getDataOffset() {\n            Box b = this;\n            long offset = 16;\n            while (b.getParent() != null) {\n                for (Box box : b.getParent().getBoxes()) {\n                    if (b == box) {\n                        break;\n                    }\n                    offset += box.getSize();\n                }\n                b = b.getParent();\n            }\n            return offset;\n        }\n\n\n        public String getType() {\n            return \"mdat\";\n        }\n\n        public long getSize() {\n            return 16 + contentSize;\n        }\n\n        private boolean isSmallBox(long contentSize) {\n            return (contentSize + 8) < 4294967296L;\n        }\n\n\n        public void getBox(WritableByteChannel writableByteChannel) throws IOException {\n            ByteBuffer bb = ByteBuffer.allocate(16);\n            long size = getSize();\n            if (isSmallBox(size)) {\n                IsoTypeWriter.writeUInt32(bb, size);\n            } else {\n                IsoTypeWriter.writeUInt32(bb, 1);\n            }\n            bb.put(IsoFile.fourCCtoBytes(\"mdat\"));\n            if (isSmallBox(size)) {\n                bb.put(new byte[8]);\n            } else {\n                IsoTypeWriter.writeUInt64(bb, size);\n            }\n            bb.rewind();\n            writableByteChannel.write(bb);\n            if (writableByteChannel instanceof GatheringByteChannel) {\n                List<ByteBuffer> nuSamples = unifyAdjacentBuffers(samples);\n\n                int STEPSIZE = 1024;\n                for (int i = 0; i < Math.ceil((double) nuSamples.size() / STEPSIZE); i++) {\n                    List<ByteBuffer> sublist = nuSamples.subList(\n                            i * STEPSIZE, // start\n                            (i + 1) * STEPSIZE < nuSamples.size() ? (i + 1) * STEPSIZE : nuSamples.size()); // end\n                    ByteBuffer sampleArray[] = sublist.toArray(new ByteBuffer[sublist.size()]);\n                    do {\n                        ((GatheringByteChannel) writableByteChannel).write(sampleArray);\n                    } while (sampleArray[sampleArray.length - 1].remaining() > 0);\n                }\n                //System.err.println(bytesWritten);\n            } else {\n                for (ByteBuffer sample : samples) {\n                    sample.rewind();\n                    writableByteChannel.write(sample);\n                }\n            }\n        }\n\n    }\n\n    /**\n     * Gets the chunk sizes for the given track.\n     *\n     * @param track\n     * @param movie\n     * @return\n     */\n    int[] getChunkSizes(Track track, Movie movie) {\n\n        long[] referenceChunkStarts = intersectionFinder.sampleNumbers(track, movie);\n        int[] chunkSizes = new int[referenceChunkStarts.length];\n\n\n        for (int i = 0; i < referenceChunkStarts.length; i++) {\n            long start = referenceChunkStarts[i] - 1;\n            long end;\n            if (referenceChunkStarts.length == i + 1) {\n                end = track.getSamples().size() - 1;\n            } else {\n                end = referenceChunkStarts[i + 1] - 1;\n            }\n\n            chunkSizes[i] = l2i(end - start);\n            // The Stretch makes sure that there are as much audio and video chunks!\n        }\n        assert DefaultMp4Builder.this.track2Sample.get(track).size() == sum(chunkSizes) : \"The number of samples and the sum of all chunk lengths must be equal\";\n        return chunkSizes;\n\n\n    }\n\n\n    private static long sum(int[] ls) {\n        long rc = 0;\n        for (long l : ls) {\n            rc += l;\n        }\n        return rc;\n    }\n\n    protected static long getDuration(Track track) {\n        long duration = 0;\n        for (TimeToSampleBox.Entry entry : track.getDecodingTimeEntries()) {\n            duration += entry.getCount() * entry.getDelta();\n        }\n        return duration;\n    }\n\n    public long getTimescale(Movie movie) {\n        long timescale = movie.getTracks().iterator().next().getTrackMetaData().getTimescale();\n        for (Track track : movie.getTracks()) {\n            timescale = gcd(track.getTrackMetaData().getTimescale(), timescale);\n        }\n        return timescale;\n    }\n\n    public static long gcd(long a, long b) {\n        if (b == 0) {\n            return a;\n        }\n        return gcd(b, a % b);\n    }\n\n    public List<ByteBuffer> unifyAdjacentBuffers(List<ByteBuffer> samples) {\n        ArrayList<ByteBuffer> nuSamples = new ArrayList<ByteBuffer>(samples.size());\n        for (ByteBuffer buffer : samples) {\n            int lastIndex = nuSamples.size() - 1;\n            if (lastIndex >= 0 && buffer.hasArray() && nuSamples.get(lastIndex).hasArray() && buffer.array() == nuSamples.get(lastIndex).array() &&\n                    nuSamples.get(lastIndex).arrayOffset() + nuSamples.get(lastIndex).limit() == buffer.arrayOffset()) {\n                ByteBuffer oldBuffer = nuSamples.remove(lastIndex);\n                ByteBuffer nu = ByteBuffer.wrap(buffer.array(), oldBuffer.arrayOffset(), oldBuffer.limit() + buffer.limit()).slice();\n                // We need to slice here since wrap([], offset, length) just sets position and not the arrayOffset.\n                nuSamples.add(nu);\n            } else if (lastIndex >= 0 &&\n                    buffer instanceof MappedByteBuffer && nuSamples.get(lastIndex) instanceof MappedByteBuffer &&\n                    nuSamples.get(lastIndex).limit() == nuSamples.get(lastIndex).capacity() - buffer.capacity()) {\n                // This can go wrong - but will it?\n                ByteBuffer oldBuffer = nuSamples.get(lastIndex);\n                oldBuffer.limit(buffer.limit() + oldBuffer.limit());\n            } else {\n                nuSamples.add(buffer);\n            }\n        }\n        return nuSamples;\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/builder/FragmentIntersectionFinder.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring.builder;\n\nimport com.googlecode.mp4parser.authoring.Movie;\nimport com.googlecode.mp4parser.authoring.Track;\n\n/**\n *\n */\npublic interface FragmentIntersectionFinder {\n    /**\n     * Gets the ordinal number of the samples which will be the first sample\n     * in each fragment.\n     *\n     * @param track concerned track\n     * @param movie the context of the track\n     * @return an array containing the ordinal of each fragment's first sample\n     */\n    public long[] sampleNumbers(Track track, Movie movie);\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/builder/FragmentedMp4Builder.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring.builder;\n\nimport com.coremedia.iso.BoxParser;\nimport com.coremedia.iso.IsoFile;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.boxes.Box;\nimport com.coremedia.iso.boxes.CompositionTimeToSample;\nimport com.coremedia.iso.boxes.ContainerBox;\nimport com.coremedia.iso.boxes.DataEntryUrlBox;\nimport com.coremedia.iso.boxes.DataInformationBox;\nimport com.coremedia.iso.boxes.DataReferenceBox;\nimport com.coremedia.iso.boxes.FileTypeBox;\nimport com.coremedia.iso.boxes.HandlerBox;\nimport com.coremedia.iso.boxes.MediaBox;\nimport com.coremedia.iso.boxes.MediaHeaderBox;\nimport com.coremedia.iso.boxes.MediaInformationBox;\nimport com.coremedia.iso.boxes.MovieBox;\nimport com.coremedia.iso.boxes.MovieHeaderBox;\nimport com.coremedia.iso.boxes.SampleDependencyTypeBox;\nimport com.coremedia.iso.boxes.SampleTableBox;\nimport com.coremedia.iso.boxes.StaticChunkOffsetBox;\nimport com.coremedia.iso.boxes.TimeToSampleBox;\nimport com.coremedia.iso.boxes.TrackBox;\nimport com.coremedia.iso.boxes.TrackHeaderBox;\nimport com.coremedia.iso.boxes.fragment.MovieExtendsBox;\nimport com.coremedia.iso.boxes.fragment.MovieFragmentBox;\nimport com.coremedia.iso.boxes.fragment.MovieFragmentHeaderBox;\nimport com.coremedia.iso.boxes.fragment.MovieFragmentRandomAccessBox;\nimport com.coremedia.iso.boxes.fragment.MovieFragmentRandomAccessOffsetBox;\nimport com.coremedia.iso.boxes.fragment.SampleFlags;\nimport com.coremedia.iso.boxes.fragment.TrackExtendsBox;\nimport com.coremedia.iso.boxes.fragment.TrackFragmentBox;\nimport com.coremedia.iso.boxes.fragment.TrackFragmentHeaderBox;\nimport com.coremedia.iso.boxes.fragment.TrackFragmentRandomAccessBox;\nimport com.coremedia.iso.boxes.fragment.TrackRunBox;\nimport com.googlecode.mp4parser.authoring.DateHelper;\nimport com.googlecode.mp4parser.authoring.Movie;\nimport com.googlecode.mp4parser.authoring.Track;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.channels.GatheringByteChannel;\nimport java.nio.channels.ReadableByteChannel;\nimport java.nio.channels.WritableByteChannel;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.Date;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Queue;\nimport java.util.logging.Logger;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\n/**\n * Creates a fragmented MP4 file.\n */\npublic class FragmentedMp4Builder implements Mp4Builder {\n    FragmentIntersectionFinder intersectionFinder = new SyncSampleIntersectFinderImpl();\n\n    private static final Logger LOG = Logger.getLogger(FragmentedMp4Builder.class.getName());\n\n    public List<String> getAllowedHandlers() {\n        return Arrays.asList(\"soun\", \"vide\");\n    }\n\n    public Box createFtyp(Movie movie) {\n        List<String> minorBrands = new LinkedList<String>();\n        minorBrands.add(\"isom\");\n        minorBrands.add(\"iso2\");\n        minorBrands.add(\"avc1\");\n        return new FileTypeBox(\"isom\", 0, minorBrands);\n    }\n\n    protected List<Box> createMoofMdat(final Movie movie) {\n        List<Box> boxes = new LinkedList<Box>();\n        int maxNumberOfFragments = 0;\n        for (Track track : movie.getTracks()) {\n            int currentLength = intersectionFinder.sampleNumbers(track, movie).length;\n            maxNumberOfFragments = currentLength > maxNumberOfFragments ? currentLength : maxNumberOfFragments;\n        }\n        int sequence = 1;\n        for (int i = 0; i < maxNumberOfFragments; i++) {\n\n            final List<Track> sizeSortedTracks = new LinkedList<Track>(movie.getTracks());\n            final int j = i;\n            Collections.sort(sizeSortedTracks, new Comparator<Track>() {\n                public int compare(Track o1, Track o2) {\n                    long[] startSamples1 = intersectionFinder.sampleNumbers(o1, movie);\n                    long startSample1 = startSamples1[j];\n                    // one based sample numbers - the first sample is 1\n                    long endSample1 = j + 1 < startSamples1.length ? startSamples1[j + 1] : o1.getSamples().size() + 1;\n                    long[] startSamples2 = intersectionFinder.sampleNumbers(o2, movie);\n                    long startSample2 = startSamples2[j];\n                    // one based sample numbers - the first sample is 1\n                    long endSample2 = j + 1 < startSamples2.length ? startSamples2[j + 1] : o2.getSamples().size() + 1;\n                    List<ByteBuffer> samples1 = o1.getSamples().subList(l2i(startSample1) - 1, l2i(endSample1) - 1);\n                    List<ByteBuffer> samples2 = o2.getSamples().subList(l2i(startSample2) - 1, l2i(endSample2) - 1);\n                    int size1 = 0;\n                    for (ByteBuffer byteBuffer : samples1) {\n                        size1 += byteBuffer.limit();\n                    }\n                    int size2 = 0;\n                    for (ByteBuffer byteBuffer : samples2) {\n                        size2 += byteBuffer.limit();\n                    }\n                    return size1 - size2;\n                }\n            });\n\n            for (Track track : sizeSortedTracks) {\n                if (getAllowedHandlers().isEmpty() || getAllowedHandlers().contains(track.getHandler())) {\n                    long[] startSamples = intersectionFinder.sampleNumbers(track, movie);\n\n                    if (i < startSamples.length) {\n                        long startSample = startSamples[i];\n                        // one based sample numbers - the first sample is 1\n                        long endSample = i + 1 < startSamples.length ? startSamples[i + 1] : track.getSamples().size() + 1;\n\n                        if (startSample == endSample) {\n                            // empty fragment\n                            // just don't add any boxes.\n                        } else {\n                            boxes.add(createMoof(startSample, endSample, track, sequence));\n                            boxes.add(createMdat(startSample, endSample, track, sequence++));\n                        }\n\n                    } else {\n                        //obvious this track has not that many fragments\n                    }\n                }\n            }\n\n\n        }\n        return boxes;\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    public IsoFile build(Movie movie) {\n        LOG.fine(\"Creating movie \" + movie);\n        IsoFile isoFile = new IsoFile();\n\n\n        isoFile.addBox(createFtyp(movie));\n        isoFile.addBox(createMoov(movie));\n\n        for (Box box : createMoofMdat(movie)) {\n            isoFile.addBox(box);\n        }\n        isoFile.addBox(createMfra(movie, isoFile));\n\n        return isoFile;\n    }\n\n    protected Box createMdat(final long startSample, final long endSample, final Track track, final int i) {\n\n        class Mdat implements Box {\n            ContainerBox parent;\n\n            public ContainerBox getParent() {\n                return parent;\n            }\n\n            public void setParent(ContainerBox parent) {\n                this.parent = parent;\n            }\n\n            public long getSize() {\n                long size = 8; // I don't expect 2gig fragments\n                for (ByteBuffer sample : getSamples(startSample, endSample, track, i)) {\n                    size += sample.limit();\n                }\n                return size;\n            }\n\n            public String getType() {\n                return \"mdat\";\n            }\n\n            public void getBox(WritableByteChannel writableByteChannel) throws IOException {\n                List<ByteBuffer> bbs = getSamples(startSample, endSample, track, i);\n                final List<ByteBuffer> samples = ByteBufferHelper.mergeAdjacentBuffers(bbs);\n                ByteBuffer header = ByteBuffer.allocate(8);\n                IsoTypeWriter.writeUInt32(header, l2i(getSize()));\n                header.put(IsoFile.fourCCtoBytes(getType()));\n                header.rewind();\n                writableByteChannel.write(header);\n                if (writableByteChannel instanceof GatheringByteChannel) {\n\n                    int STEPSIZE = 1024;\n                    for (int i = 0; i < Math.ceil((double) samples.size() / STEPSIZE); i++) {\n                        List<ByteBuffer> sublist = samples.subList(\n                                i * STEPSIZE, // start\n                                (i + 1) * STEPSIZE < samples.size() ? (i + 1) * STEPSIZE : samples.size()); // end\n                        ByteBuffer sampleArray[] = sublist.toArray(new ByteBuffer[sublist.size()]);\n                        do {\n                            ((GatheringByteChannel) writableByteChannel).write(sampleArray);\n                        } while (sampleArray[sampleArray.length - 1].remaining() > 0);\n                    }\n                    //System.err.println(bytesWritten);\n                } else {\n                    for (ByteBuffer sample : samples) {\n                        sample.rewind();\n                        writableByteChannel.write(sample);\n                    }\n                }\n\n            }\n\n            public void parse(ReadableByteChannel readableByteChannel, ByteBuffer header, long contentSize, BoxParser boxParser) throws IOException {\n\n            }\n        }\n\n        return new Mdat();\n    }\n\n    protected Box createTfhd(long startSample, long endSample, Track track, int sequenceNumber) {\n        TrackFragmentHeaderBox tfhd = new TrackFragmentHeaderBox();\n        SampleFlags sf = new SampleFlags();\n\n        tfhd.setDefaultSampleFlags(sf);\n        tfhd.setBaseDataOffset(-1);\n        tfhd.setTrackId(track.getTrackMetaData().getTrackId());\n        return tfhd;\n    }\n\n    protected Box createMfhd(long startSample, long endSample, Track track, int sequenceNumber) {\n        MovieFragmentHeaderBox mfhd = new MovieFragmentHeaderBox();\n        mfhd.setSequenceNumber(sequenceNumber);\n        return mfhd;\n    }\n\n    protected Box createTraf(long startSample, long endSample, Track track, int sequenceNumber) {\n        TrackFragmentBox traf = new TrackFragmentBox();\n        traf.addBox(createTfhd(startSample, endSample, track, sequenceNumber));\n        for (Box trun : createTruns(startSample, endSample, track, sequenceNumber)) {\n            traf.addBox(trun);\n        }\n\n        return traf;\n    }\n\n\n    /**\n     * @param startSample    first sample in list starting with 1. 1 is the first sample.\n     * @param endSample\n     * @param track\n     * @param sequenceNumber\n     * @return\n     */\n    protected List<ByteBuffer> getSamples(long startSample, long endSample, Track track, int sequenceNumber) {\n        // since startSample and endSample are one-based substract 1 before addressing list elements\n        return track.getSamples().subList(l2i(startSample) - 1, l2i(endSample) - 1);\n    }\n\n\n    protected List<? extends Box> createTruns(long startSample, long endSample, Track track, int sequenceNumber) {\n        List<ByteBuffer> samples = getSamples(startSample, endSample, track, sequenceNumber);\n\n        long[] sampleSizes = new long[samples.size()];\n        for (int i = 0; i < sampleSizes.length; i++) {\n            sampleSizes[i] = samples.get(i).limit();\n        }\n        TrackRunBox trun = new TrackRunBox();\n\n\n        trun.setSampleDurationPresent(true);\n        trun.setSampleSizePresent(true);\n        List<TrackRunBox.Entry> entries = new ArrayList<TrackRunBox.Entry>(l2i(endSample - startSample));\n\n\n        Queue<TimeToSampleBox.Entry> timeQueue = new LinkedList<TimeToSampleBox.Entry>(track.getDecodingTimeEntries());\n        long left = startSample;\n        long curEntryLeft = timeQueue.peek().getCount();\n        while (left >= curEntryLeft) {\n            left -= curEntryLeft;\n            timeQueue.remove();\n            curEntryLeft = timeQueue.peek().getCount();\n        }\n        curEntryLeft -= left;\n\n\n        Queue<CompositionTimeToSample.Entry> compositionTimeQueue =\n                track.getCompositionTimeEntries() != null && track.getCompositionTimeEntries().size() > 0 ?\n                        new LinkedList<CompositionTimeToSample.Entry>(track.getCompositionTimeEntries()) : null;\n        long compositionTimeEntriesLeft = compositionTimeQueue != null ? compositionTimeQueue.peek().getCount() : -1;\n\n\n        trun.setSampleCompositionTimeOffsetPresent(compositionTimeEntriesLeft > 0);\n\n        // fast forward composition stuff\n        for (long i = 1; i < startSample; i++) {\n            if (compositionTimeQueue != null) {\n                trun.setSampleCompositionTimeOffsetPresent(true);\n                if (--compositionTimeEntriesLeft == 0 && compositionTimeQueue.size() > 1) {\n                    compositionTimeQueue.remove();\n                    compositionTimeEntriesLeft = compositionTimeQueue.element().getCount();\n                }\n            }\n        }\n\n        boolean sampleFlagsRequired = (track.getSampleDependencies() != null && !track.getSampleDependencies().isEmpty() ||\n                track.getSyncSamples() != null && track.getSyncSamples().length != 0);\n\n        trun.setSampleFlagsPresent(sampleFlagsRequired);\n\n        for (int i = 0; i < sampleSizes.length; i++) {\n            TrackRunBox.Entry entry = new TrackRunBox.Entry();\n            entry.setSampleSize(sampleSizes[i]);\n            if (sampleFlagsRequired) {\n                //if (false) {\n                SampleFlags sflags = new SampleFlags();\n\n                if (track.getSampleDependencies() != null && !track.getSampleDependencies().isEmpty()) {\n                    SampleDependencyTypeBox.Entry e = track.getSampleDependencies().get(i);\n                    sflags.setSampleDependsOn(e.getSampleDependsOn());\n                    sflags.setSampleIsDependedOn(e.getSampleIsDependentOn());\n                    sflags.setSampleHasRedundancy(e.getSampleHasRedundancy());\n                }\n                if (track.getSyncSamples() != null && track.getSyncSamples().length > 0) {\n                    // we have to mark non-sync samples!\n                    if (Arrays.binarySearch(track.getSyncSamples(), startSample + i) >= 0) {\n                        sflags.setSampleIsDifferenceSample(false);\n                        sflags.setSampleDependsOn(2);\n                    } else {\n                        sflags.setSampleIsDifferenceSample(true);\n                        sflags.setSampleDependsOn(1);\n                    }\n                }\n                // i don't have sample degradation\n                entry.setSampleFlags(sflags);\n\n            }\n\n            entry.setSampleDuration(timeQueue.peek().getDelta());\n            if (--curEntryLeft == 0 && timeQueue.size() > 1) {\n                timeQueue.remove();\n                curEntryLeft = timeQueue.peek().getCount();\n            }\n\n            if (compositionTimeQueue != null) {\n                trun.setSampleCompositionTimeOffsetPresent(true);\n                entry.setSampleCompositionTimeOffset(compositionTimeQueue.peek().getOffset());\n                if (--compositionTimeEntriesLeft == 0 && compositionTimeQueue.size() > 1) {\n                    compositionTimeQueue.remove();\n                    compositionTimeEntriesLeft = compositionTimeQueue.element().getCount();\n                }\n            }\n            entries.add(entry);\n        }\n\n        trun.setEntries(entries);\n\n        return Collections.singletonList(trun);\n    }\n\n    protected Box createMoof(long startSample, long endSample, Track track, int sequenceNumber) {\n\n\n        MovieFragmentBox moof = new MovieFragmentBox();\n        moof.addBox(createMfhd(startSample, endSample, track, sequenceNumber));\n        moof.addBox(createTraf(startSample, endSample, track, sequenceNumber));\n\n        TrackRunBox firstTrun = moof.getTrackRunBoxes().get(0);\n        firstTrun.setDataOffset(1); // dummy to make size correct\n        firstTrun.setDataOffset((int) (8 + moof.getSize())); // mdat header + moof size\n\n        return moof;\n    }\n\n    protected Box createMvhd(Movie movie) {\n        MovieHeaderBox mvhd = new MovieHeaderBox();\n        mvhd.setVersion(1);\n        mvhd.setCreationTime(DateHelper.convert(new Date()));\n        mvhd.setModificationTime(DateHelper.convert(new Date()));\n        long movieTimeScale = movie.getTimescale();\n        long duration = 0;\n\n        for (Track track : movie.getTracks()) {\n            long tracksDuration = getDuration(track) * movieTimeScale / track.getTrackMetaData().getTimescale();\n            if (tracksDuration > duration) {\n                duration = tracksDuration;\n            }\n\n\n        }\n\n        mvhd.setDuration(duration);\n        mvhd.setTimescale(movieTimeScale);\n        // find the next available trackId\n        long nextTrackId = 0;\n        for (Track track : movie.getTracks()) {\n            nextTrackId = nextTrackId < track.getTrackMetaData().getTrackId() ? track.getTrackMetaData().getTrackId() : nextTrackId;\n        }\n        mvhd.setNextTrackId(++nextTrackId);\n        return mvhd;\n    }\n\n    protected Box createMoov(Movie movie) {\n        MovieBox movieBox = new MovieBox();\n\n        movieBox.addBox(createMvhd(movie));\n        movieBox.addBox(createMvex(movie));\n\n        for (Track track : movie.getTracks()) {\n            movieBox.addBox(createTrak(track, movie));\n        }\n        // metadata here\n        return movieBox;\n\n    }\n\n    protected Box createTfra(Track track, IsoFile isoFile) {\n        TrackFragmentRandomAccessBox tfra = new TrackFragmentRandomAccessBox();\n        tfra.setVersion(1); // use long offsets and times\n        List<TrackFragmentRandomAccessBox.Entry> offset2timeEntries = new LinkedList<TrackFragmentRandomAccessBox.Entry>();\n        List<Box> boxes = isoFile.getBoxes();\n        long offset = 0;\n        long duration = 0;\n        for (Box box : boxes) {\n            if (box instanceof MovieFragmentBox) {\n                List<TrackFragmentBox> trafs = ((MovieFragmentBox) box).getBoxes(TrackFragmentBox.class);\n                for (int i = 0; i < trafs.size(); i++) {\n                    TrackFragmentBox traf = trafs.get(i);\n                    if (traf.getTrackFragmentHeaderBox().getTrackId() == track.getTrackMetaData().getTrackId()) {\n                        // here we are at the offset required for the current entry.\n                        List<TrackRunBox> truns = traf.getBoxes(TrackRunBox.class);\n                        for (int j = 0; j < truns.size(); j++) {\n                            List<TrackFragmentRandomAccessBox.Entry> offset2timeEntriesThisTrun = new LinkedList<TrackFragmentRandomAccessBox.Entry>();\n                            TrackRunBox trun = truns.get(j);\n                            for (int k = 0; k < trun.getEntries().size(); k++) {\n                                TrackRunBox.Entry trunEntry = trun.getEntries().get(k);\n                                SampleFlags sf = null;\n                                if (k == 0 && trun.isFirstSampleFlagsPresent()) {\n                                    sf = trun.getFirstSampleFlags();\n                                } else if (trun.isSampleFlagsPresent()) {\n                                    sf = trunEntry.getSampleFlags();\n                                } else {\n                                    List<MovieExtendsBox> mvexs = isoFile.getMovieBox().getBoxes(MovieExtendsBox.class);\n                                    for (MovieExtendsBox mvex : mvexs) {\n                                        List<TrackExtendsBox> trexs = mvex.getBoxes(TrackExtendsBox.class);\n                                        for (TrackExtendsBox trex : trexs) {\n                                            if (trex.getTrackId() == track.getTrackMetaData().getTrackId()) {\n                                                sf = trex.getDefaultSampleFlags();\n                                            }\n                                        }\n                                    }\n\n                                }\n                                if (sf == null) {\n                                    throw new RuntimeException(\"Could not find any SampleFlags to indicate random access or not\");\n                                }\n                                if (sf.getSampleDependsOn() == 2) {\n                                    offset2timeEntriesThisTrun.add(new TrackFragmentRandomAccessBox.Entry(\n                                            duration,\n                                            offset,\n                                            i + 1, j + 1, k + 1));\n                                }\n                                duration += trunEntry.getSampleDuration();\n                            }\n                            if (offset2timeEntriesThisTrun.size() == trun.getEntries().size() && trun.getEntries().size() > 0) {\n                                // Oooops every sample seems to be random access sample\n                                // is this an audio track? I don't care.\n                                // I just use the first for trun sample for tfra random access\n                                offset2timeEntries.add(offset2timeEntriesThisTrun.get(0));\n                            } else {\n                                offset2timeEntries.addAll(offset2timeEntriesThisTrun);\n                            }\n                        }\n                    }\n                }\n            }\n\n\n            offset += box.getSize();\n        }\n        tfra.setEntries(offset2timeEntries);\n        tfra.setTrackId(track.getTrackMetaData().getTrackId());\n        return tfra;\n    }\n\n    protected Box createMfra(Movie movie, IsoFile isoFile) {\n        MovieFragmentRandomAccessBox mfra = new MovieFragmentRandomAccessBox();\n        for (Track track : movie.getTracks()) {\n            mfra.addBox(createTfra(track, isoFile));\n        }\n\n        MovieFragmentRandomAccessOffsetBox mfro = new MovieFragmentRandomAccessOffsetBox();\n        mfra.addBox(mfro);\n        mfro.setMfraSize(mfra.getSize());\n        return mfra;\n    }\n\n    protected Box createTrex(Movie movie, Track track) {\n        TrackExtendsBox trex = new TrackExtendsBox();\n        trex.setTrackId(track.getTrackMetaData().getTrackId());\n        trex.setDefaultSampleDescriptionIndex(1);\n        trex.setDefaultSampleDuration(0);\n        trex.setDefaultSampleSize(0);\n        SampleFlags sf = new SampleFlags();\n        if (\"soun\".equals(track.getHandler())) {\n            // as far as I know there is no audio encoding\n            // where the sample are not self contained.\n            sf.setSampleDependsOn(2);\n            sf.setSampleIsDependedOn(2);\n        }\n        trex.setDefaultSampleFlags(sf);\n        return trex;\n    }\n\n\n    protected Box createMvex(Movie movie) {\n        MovieExtendsBox mvex = new MovieExtendsBox();\n\n        for (Track track : movie.getTracks()) {\n            mvex.addBox(createTrex(movie, track));\n        }\n        return mvex;\n    }\n\n    protected Box createTkhd(Movie movie, Track track) {\n        TrackHeaderBox tkhd = new TrackHeaderBox();\n        tkhd.setVersion(1);\n        int flags = 0;\n        if (track.isEnabled()) {\n            flags += 1;\n        }\n\n        if (track.isInMovie()) {\n            flags += 2;\n        }\n\n        if (track.isInPreview()) {\n            flags += 4;\n        }\n\n        if (track.isInPoster()) {\n            flags += 8;\n        }\n        tkhd.setFlags(flags);\n\n        tkhd.setAlternateGroup(track.getTrackMetaData().getGroup());\n        tkhd.setCreationTime(DateHelper.convert(track.getTrackMetaData().getCreationTime()));\n        // We need to take edit list box into account in trackheader duration\n        // but as long as I don't support edit list boxes it is sufficient to\n        // just translate media duration to movie timescale\n        tkhd.setDuration(getDuration(track) * movie.getTimescale() / track.getTrackMetaData().getTimescale());\n        tkhd.setHeight(track.getTrackMetaData().getHeight());\n        tkhd.setWidth(track.getTrackMetaData().getWidth());\n        tkhd.setLayer(track.getTrackMetaData().getLayer());\n        tkhd.setModificationTime(DateHelper.convert(new Date()));\n        tkhd.setTrackId(track.getTrackMetaData().getTrackId());\n        tkhd.setVolume(track.getTrackMetaData().getVolume());\n        return tkhd;\n    }\n\n    protected Box createMdhd(Movie movie, Track track) {\n        MediaHeaderBox mdhd = new MediaHeaderBox();\n        mdhd.setCreationTime(DateHelper.convert(track.getTrackMetaData().getCreationTime()));\n        mdhd.setDuration(getDuration(track));\n        mdhd.setTimescale(track.getTrackMetaData().getTimescale());\n        mdhd.setLanguage(track.getTrackMetaData().getLanguage());\n        return mdhd;\n    }\n\n    protected Box createStbl(Movie movie, Track track) {\n        SampleTableBox stbl = new SampleTableBox();\n\n        stbl.addBox(track.getSampleDescriptionBox());\n        stbl.addBox(new TimeToSampleBox());\n        //stbl.addBox(new SampleToChunkBox());\n        stbl.addBox(new StaticChunkOffsetBox());\n        return stbl;\n    }\n\n    protected Box createMinf(Track track, Movie movie) {\n        MediaInformationBox minf = new MediaInformationBox();\n        minf.addBox(track.getMediaHeaderBox());\n        minf.addBox(createDinf(movie, track));\n        minf.addBox(createStbl(movie, track));\n        return minf;\n    }\n\n    protected Box createMdiaHdlr(Track track, Movie movie) {\n        HandlerBox hdlr = new HandlerBox();\n        hdlr.setHandlerType(track.getHandler());\n        return hdlr;\n    }\n\n    protected Box createMdia(Track track, Movie movie) {\n        MediaBox mdia = new MediaBox();\n        mdia.addBox(createMdhd(movie, track));\n\n\n        mdia.addBox(createMdiaHdlr(track, movie));\n\n\n        mdia.addBox(createMinf(track, movie));\n        return mdia;\n    }\n\n    protected Box createTrak(Track track, Movie movie) {\n        LOG.fine(\"Creating Track \" + track);\n        TrackBox trackBox = new TrackBox();\n        trackBox.addBox(createTkhd(movie, track));\n        trackBox.addBox(createMdia(track, movie));\n        return trackBox;\n    }\n\n    protected DataInformationBox createDinf(Movie movie, Track track) {\n        DataInformationBox dinf = new DataInformationBox();\n        DataReferenceBox dref = new DataReferenceBox();\n        dinf.addBox(dref);\n        DataEntryUrlBox url = new DataEntryUrlBox();\n        url.setFlags(1);\n        dref.addBox(url);\n        return dinf;\n    }\n\n    public void setIntersectionFinder(FragmentIntersectionFinder intersectionFinder) {\n        this.intersectionFinder = intersectionFinder;\n    }\n\n    protected long getDuration(Track track) {\n        long duration = 0;\n        for (TimeToSampleBox.Entry entry : track.getDecodingTimeEntries()) {\n            duration += entry.getCount() * entry.getDelta();\n        }\n        return duration;\n    }\n\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/builder/Mp4Builder.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring.builder;\n\nimport com.coremedia.iso.IsoFile;\nimport com.googlecode.mp4parser.authoring.Movie;\n\nimport java.io.IOException;\n\n/**\n * Transforms a <code>Movie</code> object to an IsoFile. Implementations can\n * determine the specific format: Fragmented MP4, MP4, MP4 with Apple Metadata,\n * MP4 with 3GPP Metadata, MOV.\n */\npublic interface Mp4Builder {\n    /**\n     * Builds the actual IsoFile from the Movie.\n     *\n     * @param movie data source\n     * @return the freshly built IsoFile\n     */\n    public IsoFile build(Movie movie);\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/builder/SyncSampleIntersectFinderImpl.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring.builder;\n\nimport com.coremedia.iso.boxes.TimeToSampleBox;\nimport com.coremedia.iso.boxes.sampleentry.AudioSampleEntry;\nimport com.googlecode.mp4parser.authoring.Movie;\nimport com.googlecode.mp4parser.authoring.Track;\n\nimport java.util.Arrays;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Queue;\nimport java.util.logging.Logger;\n\nimport static com.googlecode.mp4parser.util.Math.lcm;\n\n/**\n * This <code>FragmentIntersectionFinder</code> cuts the input movie video tracks in\n * fragments of the same length exactly before the sync samples. Audio tracks are cut\n * into pieces of similar length.\n */\npublic class SyncSampleIntersectFinderImpl implements FragmentIntersectionFinder {\n\n    private static Logger LOG = Logger.getLogger(SyncSampleIntersectFinderImpl.class.getName());\n\n    /**\n     * Gets an array of sample numbers that are meant to be the first sample of each\n     * chunk or fragment.\n     *\n     * @param track concerned track\n     * @param movie the context of the track\n     * @return an array containing the ordinal of each fragment's first sample\n     */\n    public long[] sampleNumbers(Track track, Movie movie) {\n        if (\"vide\".equals(track.getHandler())) {\n            if (track.getSyncSamples() != null && track.getSyncSamples().length > 0) {\n                List<long[]> times = getSyncSamplesTimestamps(movie, track);\n                return getCommonIndices(track.getSyncSamples(), getTimes(movie, track), times.toArray(new long[times.size()][]));\n            } else {\n                throw new RuntimeException(\"Video Tracks need sync samples. Only tracks other than video may have no sync samples.\");\n            }\n        } else if (\"soun\".equals(track.getHandler())) {\n            Track referenceTrack = null;\n            for (Track candidate : movie.getTracks()) {\n                if (candidate.getSyncSamples() != null && candidate.getSyncSamples().length > 0) {\n                    referenceTrack = candidate;\n                }\n            }\n            if (referenceTrack != null) {\n\n                // Gets the reference track's fra\n                long[] refSyncSamples = sampleNumbers(referenceTrack, movie);\n\n                int refSampleCount = referenceTrack.getSamples().size();\n\n                long[] syncSamples = new long[refSyncSamples.length];\n                long minSampleRate = 192000;\n                for (Track testTrack : movie.getTracks()) {\n                    if (\"soun\".equals(testTrack.getHandler())) {\n                        AudioSampleEntry ase = (AudioSampleEntry) testTrack.getSampleDescriptionBox().getSampleEntry();\n                        if (ase.getSampleRate() < minSampleRate) {\n                            minSampleRate = ase.getSampleRate();\n                            long sc = testTrack.getSamples().size();\n                            double stretch = (double) sc / refSampleCount;\n\n                            for (int i = 0; i < syncSamples.length; i++) {\n                                int start = (int) Math.ceil(stretch * (refSyncSamples[i] - 1)) + 1;\n                                syncSamples[i] = start;\n                                // The Stretch makes sure that there are as much audio and video chunks!\n                            }\n                        }\n                    }\n                }\n                AudioSampleEntry ase = (AudioSampleEntry) track.getSampleDescriptionBox().getSampleEntry();\n                double factor = (double) ase.getSampleRate() / (double) minSampleRate;\n                if (factor != Math.rint(factor)) { // Not an integer\n                    throw new RuntimeException(\"Sample rates must be a multiple of the lowest sample rate to create a correct file!\");\n                }\n                for (int i = 1; i < syncSamples.length; i++) {\n                    syncSamples[i] = (int) (1 + (syncSamples[i] - 1) * factor);\n                }\n                return syncSamples;\n            }\n            throw new RuntimeException(\"There was absolutely no Track with sync samples. I can't work with that!\");\n        } else {\n            // Ok, my track has no sync samples - let's find one with sync samples.\n            for (Track candidate : movie.getTracks()) {\n                if (candidate.getSyncSamples() != null && candidate.getSyncSamples().length > 0) {\n                    long[] refSyncSamples = sampleNumbers(candidate, movie);\n                    int refSampleCount = candidate.getSamples().size();\n\n                    long[] syncSamples = new long[refSyncSamples.length];\n                    long sc = track.getSamples().size();\n                    double stretch = (double) sc / refSampleCount;\n\n                    for (int i = 0; i < syncSamples.length; i++) {\n                        int start = (int) Math.ceil(stretch * (refSyncSamples[i] - 1)) + 1;\n                        syncSamples[i] = start;\n                        // The Stretch makes sure that there are as much audio and video chunks!\n                    }\n                    return syncSamples;\n                }\n            }\n            throw new RuntimeException(\"There was absolutely no Track with sync samples. I can't work with that!\");\n        }\n\n\n    }\n\n    /**\n     * Calculates the timestamp of all tracks' sync samples.\n     *\n     * @param movie\n     * @param track\n     * @return\n     */\n    public static List<long[]> getSyncSamplesTimestamps(Movie movie, Track track) {\n        List<long[]> times = new LinkedList<long[]>();\n        for (Track currentTrack : movie.getTracks()) {\n            if (currentTrack.getHandler().equals(track.getHandler())) {\n                long[] currentTrackSyncSamples = currentTrack.getSyncSamples();\n                if (currentTrackSyncSamples != null && currentTrackSyncSamples.length > 0) {\n                    final long[] currentTrackTimes = getTimes(movie, currentTrack);\n                    times.add(currentTrackTimes);\n                }\n            }\n        }\n        return times;\n    }\n\n    public static long[] getCommonIndices(long[] syncSamples, long[] syncSampleTimes, long[]... otherTracksTimes) {\n        List<Long> nuSyncSamples = new LinkedList<Long>();\n        for (int i = 0; i < syncSampleTimes.length; i++) {\n            boolean foundInEveryRef = true;\n            for (long[] times : otherTracksTimes) {\n                foundInEveryRef &= (Arrays.binarySearch(times, syncSampleTimes[i]) >= 0);\n            }\n            if (foundInEveryRef) {\n                nuSyncSamples.add(syncSamples[i]);\n            }\n        }\n        long[] nuSyncSampleArray = new long[nuSyncSamples.size()];\n        for (int i = 0; i < nuSyncSampleArray.length; i++) {\n            nuSyncSampleArray[i] = nuSyncSamples.get(i);\n        }\n        if (nuSyncSampleArray.length < (syncSamples.length * 0.3)) {\n            LOG.warning(\"There are less than 25% of common sync samples in the given track.\");\n            throw new RuntimeException(\"There are less than 25% of common sync samples in the given track.\");\n        } else if (nuSyncSampleArray.length < (syncSamples.length * 0.5)) {\n            LOG.fine(\"There are less than 50% of common sync samples in the given track. This is implausible but I'm ok to continue.\");\n        } else if (nuSyncSampleArray.length < syncSamples.length) {\n            LOG.finest(\"Common SyncSample positions vs. this tracks SyncSample positions: \" + nuSyncSampleArray.length + \" vs. \" + syncSamples.length);\n        }\n        return nuSyncSampleArray;\n    }\n\n\n    private static long[] getTimes(Movie m, Track track) {\n        long[] syncSamples = track.getSyncSamples();\n        long[] syncSampleTimes = new long[syncSamples.length];\n        Queue<TimeToSampleBox.Entry> timeQueue = new LinkedList<TimeToSampleBox.Entry>(track.getDecodingTimeEntries());\n\n        int currentSample = 1;  // first syncsample is 1\n        long currentDuration = 0;\n        long currentDelta = 0;\n        int currentSyncSampleIndex = 0;\n        long left = 0;\n\n        long timeScale = 1;\n        for (Track track1 : m.getTracks()) {\n            if (track1.getTrackMetaData().getTimescale() != track.getTrackMetaData().getTimescale()) {\n                timeScale = lcm(timeScale, track1.getTrackMetaData().getTimescale());\n            }\n        }\n\n\n        while (currentSample <= syncSamples[syncSamples.length - 1]) {\n            if (currentSample++ == syncSamples[currentSyncSampleIndex]) {\n                syncSampleTimes[currentSyncSampleIndex++] = currentDuration * timeScale;\n            }\n            if (left-- == 0) {\n                TimeToSampleBox.Entry entry = timeQueue.poll();\n                left = entry.getCount();\n                currentDelta = entry.getDelta();\n            }\n            currentDuration += currentDelta;\n        }\n        return syncSampleTimes;\n\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/builder/TwoSecondIntersectionFinder.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring.builder;\n\nimport java.util.Arrays;\nimport java.util.List;\n\nimport com.coremedia.iso.boxes.TimeToSampleBox;\nimport com.googlecode.mp4parser.authoring.Movie;\nimport com.googlecode.mp4parser.authoring.Track;\n\n/**\n * This <code>FragmentIntersectionFinder</code> cuts the input movie in 2 second\n * snippets.\n */\npublic class TwoSecondIntersectionFinder implements FragmentIntersectionFinder {\n\n    protected long getDuration(Track track) {\n        long duration = 0;\n        for (TimeToSampleBox.Entry entry : track.getDecodingTimeEntries()) {\n            duration += entry.getCount() * entry.getDelta();\n        }\n        return duration;\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    public long[] sampleNumbers(Track track, Movie movie) {\n        List<TimeToSampleBox.Entry> entries = track.getDecodingTimeEntries();\n\n        double trackLength = 0;\n        for (Track thisTrack : movie.getTracks()) {\n            double thisTracksLength = getDuration(thisTrack) / thisTrack.getTrackMetaData().getTimescale();\n            if (trackLength < thisTracksLength) {\n                trackLength = thisTracksLength;\n            }\n        }\n\n        long fragments[] = new long[(int) Math.max(2, Math.ceil(trackLength / 2)) - 1];\n        Arrays.fill(fragments, -1);\n        fragments[0] = 0;\n\n        long time = 0;\n        int samples = 0;\n        for (TimeToSampleBox.Entry entry : entries) {\n            for (int i = 0; i < entry.getCount(); i++) {\n                int currentFragment = (int) (time / track.getTrackMetaData().getTimescale() / 2) + 1;\n                if (currentFragment >= fragments.length) {\n                    break;\n                }\n                fragments[currentFragment] = samples++;\n                time += entry.getDelta();\n            }\n        }\n        long last = samples;\n        // fill all -1 ones.\n        for (int i = fragments.length - 1; i >= 0; i--) {\n            if (fragments[i] == -1) {\n                fragments[i] = last;\n            }\n            last = fragments[i];\n        }\n        return fragments;\n\n    }\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/builder/smoothstreaming/AudioQuality.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring.builder.smoothstreaming;\n\n\npublic class AudioQuality {\n    long bitrate;\n    int audioTag;\n    long samplingRate;\n    int channels;\n    int bitPerSample;\n    int packetSize;\n    String language;\n    String codecPrivateData;\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/builder/smoothstreaming/FlatManifestWriterImpl.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring.builder.smoothstreaming;\n\nimport com.coremedia.iso.Hex;\nimport com.coremedia.iso.boxes.OriginalFormatBox;\nimport com.coremedia.iso.boxes.SampleDescriptionBox;\nimport com.coremedia.iso.boxes.SoundMediaHeaderBox;\nimport com.coremedia.iso.boxes.TimeToSampleBox;\nimport com.coremedia.iso.boxes.VideoMediaHeaderBox;\nimport com.coremedia.iso.boxes.h264.AvcConfigurationBox;\nimport com.coremedia.iso.boxes.sampleentry.AudioSampleEntry;\nimport com.coremedia.iso.boxes.sampleentry.SampleEntry;\nimport com.coremedia.iso.boxes.sampleentry.VisualSampleEntry;\nimport com.googlecode.mp4parser.authoring.Movie;\nimport com.googlecode.mp4parser.authoring.Track;\nimport com.googlecode.mp4parser.authoring.builder.FragmentIntersectionFinder;\nimport com.googlecode.mp4parser.authoring.builder.SyncSampleIntersectFinderImpl;\nimport com.googlecode.mp4parser.boxes.mp4.ESDescriptorBox;\nimport nu.xom.Attribute;\nimport nu.xom.Document;\nimport nu.xom.Element;\nimport nu.xom.Serializer;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.util.Arrays;\nimport java.util.LinkedList;\nimport java.util.List;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\npublic class FlatManifestWriterImpl implements ManifestWriter {\n\n\n    private FragmentIntersectionFinder intersectionFinder = new SyncSampleIntersectFinderImpl();\n    private long[] audioFragmentsDurations;\n    private long[] videoFragmentsDurations;\n\n\n    public void setIntersectionFinder(FragmentIntersectionFinder intersectionFinder) {\n        this.intersectionFinder = intersectionFinder;\n    }\n\n    /**\n     * Overwrite this method in subclasses to add your specialities.\n     *\n     * @param manifest the original manifest\n     * @return your customized version of the manifest\n     */\n    protected Document customizeManifest(Document manifest) {\n        return manifest;\n    }\n\n    public String getManifest(Movie movie) throws IOException {\n\n        LinkedList<VideoQuality> videoQualities = new LinkedList<VideoQuality>();\n        long videoTimescale = -1;\n\n        LinkedList<AudioQuality> audioQualities = new LinkedList<AudioQuality>();\n        long audioTimescale = -1;\n\n\n\n        for (Track track : movie.getTracks()) {\n            if (track.getMediaHeaderBox() instanceof VideoMediaHeaderBox) {\n                videoFragmentsDurations = checkFragmentsAlign(videoFragmentsDurations, calculateFragmentDurations(track, movie));\n                SampleDescriptionBox stsd = track.getSampleDescriptionBox();\n                videoQualities.add(getVideoQuality(track, (VisualSampleEntry) stsd.getSampleEntry()));\n                if (videoTimescale == -1) {\n                    videoTimescale = track.getTrackMetaData().getTimescale();\n                } else {\n                    assert videoTimescale == track.getTrackMetaData().getTimescale();\n                }\n            }\n            if (track.getMediaHeaderBox() instanceof SoundMediaHeaderBox) {\n                audioFragmentsDurations = checkFragmentsAlign(audioFragmentsDurations, calculateFragmentDurations(track, movie));\n                SampleDescriptionBox stsd = track.getSampleDescriptionBox();\n                audioQualities.add(getAudioQuality(track, (AudioSampleEntry) stsd.getSampleEntry()));\n                if (audioTimescale == -1) {\n                    audioTimescale = track.getTrackMetaData().getTimescale();\n                } else {\n                    assert audioTimescale == track.getTrackMetaData().getTimescale();\n                }\n\n            }\n        }\n\n        Element smoothStreamingMedia = new Element(\"SmoothStreamingMedia\");\n        smoothStreamingMedia.addAttribute(new Attribute(\"MajorVersion\", \"2\"));\n        smoothStreamingMedia.addAttribute(new Attribute(\"MinorVersion\", \"1\"));\n// silverlight ignores the timescale attr        smoothStreamingMedia.addAttribute(new Attribute(\"TimeScale\", Long.toString(movieTimeScale)));\n        smoothStreamingMedia.addAttribute(new Attribute(\"Duration\", \"0\"));\n\n        Element videoStreamIndex = new Element(\"StreamIndex\");\n        videoStreamIndex.addAttribute(new Attribute(\"Type\", \"video\"));\n        videoStreamIndex.addAttribute(new Attribute(\"TimeScale\", Long.toString(videoTimescale))); // silverlight ignores the timescale attr\n        videoStreamIndex.addAttribute(new Attribute(\"Chunks\", Integer.toString(videoFragmentsDurations.length)));\n        videoStreamIndex.addAttribute(new Attribute(\"Url\", \"video/{bitrate}/{start time}\"));\n        videoStreamIndex.addAttribute(new Attribute(\"QualityLevels\", Integer.toString(videoQualities.size())));\n        smoothStreamingMedia.appendChild(videoStreamIndex);\n\n        for (int i = 0; i < videoQualities.size(); i++) {\n            VideoQuality vq = videoQualities.get(i);\n            Element qualityLevel = new Element(\"QualityLevel\");\n            qualityLevel.addAttribute(new Attribute(\"Index\", Integer.toString(i)));\n            qualityLevel.addAttribute(new Attribute(\"Bitrate\", Long.toString(vq.bitrate)));\n            qualityLevel.addAttribute(new Attribute(\"FourCC\", vq.fourCC));\n            qualityLevel.addAttribute(new Attribute(\"MaxWidth\", Long.toString(vq.width)));\n            qualityLevel.addAttribute(new Attribute(\"MaxHeight\", Long.toString(vq.height)));\n            qualityLevel.addAttribute(new Attribute(\"CodecPrivateData\", vq.codecPrivateData));\n            qualityLevel.addAttribute(new Attribute(\"NALUnitLengthField\", Integer.toString(vq.nalLength)));\n            videoStreamIndex.appendChild(qualityLevel);\n        }\n\n        for (int i = 0; i < videoFragmentsDurations.length; i++) {\n            Element c = new Element(\"c\");\n            c.addAttribute(new Attribute(\"n\", Integer.toString(i)));\n            c.addAttribute(new Attribute(\"d\", Long.toString((long) (videoFragmentsDurations[i] ))));\n            videoStreamIndex.appendChild(c);\n        }\n\n        if (audioFragmentsDurations != null) {\n            Element audioStreamIndex = new Element(\"StreamIndex\");\n            audioStreamIndex.addAttribute(new Attribute(\"Type\", \"audio\"));\n            audioStreamIndex.addAttribute(new Attribute(\"TimeScale\", Long.toString(audioTimescale))); // silverlight ignores the timescale attr\n            audioStreamIndex.addAttribute(new Attribute(\"Chunks\", Integer.toString(audioFragmentsDurations.length)));\n            audioStreamIndex.addAttribute(new Attribute(\"Url\", \"audio/{bitrate}/{start time}\"));\n            audioStreamIndex.addAttribute(new Attribute(\"QualityLevels\", Integer.toString(audioQualities.size())));\n            smoothStreamingMedia.appendChild(audioStreamIndex);\n\n            for (int i = 0; i < audioQualities.size(); i++) {\n                AudioQuality aq = audioQualities.get(i);\n                Element qualityLevel = new Element(\"QualityLevel\");\n                qualityLevel.addAttribute(new Attribute(\"Index\", Integer.toString(i)));\n                qualityLevel.addAttribute(new Attribute(\"Bitrate\", Long.toString(aq.bitrate)));\n                qualityLevel.addAttribute(new Attribute(\"AudioTag\", Integer.toString(aq.audioTag)));\n                qualityLevel.addAttribute(new Attribute(\"SamplingRate\", Long.toString(aq.samplingRate)));\n                qualityLevel.addAttribute(new Attribute(\"Channels\", Integer.toString(aq.channels)));\n                qualityLevel.addAttribute(new Attribute(\"BitsPerSample\", Integer.toString(aq.bitPerSample)));\n                qualityLevel.addAttribute(new Attribute(\"PacketSize\", Integer.toString(aq.packetSize)));\n                qualityLevel.addAttribute(new Attribute(\"CodecPrivateData\", aq.codecPrivateData));\n                audioStreamIndex.appendChild(qualityLevel);\n            }\n            for (int i = 0; i < audioFragmentsDurations.length; i++) {\n                Element c = new Element(\"c\");\n                c.addAttribute(new Attribute(\"n\", Integer.toString(i)));\n                c.addAttribute(new Attribute(\"d\", Long.toString((long) (audioFragmentsDurations[i] ))));\n                audioStreamIndex.appendChild(c);\n            }\n        }\n        ByteArrayOutputStream baos = new ByteArrayOutputStream();\n        Serializer serializer = new Serializer(baos);\n        serializer.setIndent(4);\n        serializer.write(customizeManifest(new Document(smoothStreamingMedia)));\n\n        return baos.toString(\"UTF-8\");\n\n    }\n\n    private AudioQuality getAudioQuality(Track track, AudioSampleEntry ase) {\n        if (getFormat(ase).equals(\"mp4a\")) {\n            AudioQuality l = new AudioQuality();\n            l.bitrate = getBitrate(track);\n            l.audioTag = 255;\n            l.samplingRate = ase.getSampleRate();\n            l.channels = ase.getChannelCount();\n            l.bitPerSample = ase.getSampleSize();\n            l.packetSize = 4;\n            l.codecPrivateData = getAudioCodecPrivateData(ase.getBoxes(ESDescriptorBox.class).get(0));\n            //Index=\"0\" Bitrate=\"103000\" AudioTag=\"255\" SamplingRate=\"44100\" Channels=\"2\" BitsPerSample=\"16\" packetSize=\"4\" CodecPrivateData=\"\"\n            return l;\n        } else {\n            throw new InternalError(\"I don't know what to do with audio of type \" + getFormat(ase));\n        }\n\n    }\n\n    public long getBitrate(Track track) {\n        long bitrate = 0;\n        for (ByteBuffer sample : track.getSamples()) {\n            bitrate += sample.limit();\n        }\n        bitrate *= 8; // from bytes to bits\n        bitrate /= ((double) getDuration(track)) / track.getTrackMetaData().getTimescale(); // per second\n        return bitrate;\n    }\n\n\n    private String getAudioCodecPrivateData(ESDescriptorBox esDescriptorBox) {\n\n        ByteBuffer configBytes = esDescriptorBox.getEsDescriptor().getDecoderConfigDescriptor().getAudioSpecificInfo().getConfigBytes();\n        byte[] configByteArray = new byte[configBytes.limit()];\n        configBytes.rewind();\n        configBytes.get(configByteArray);\n        return Hex.encodeHex(configByteArray);\n    }\n\n\n    private VideoQuality getVideoQuality(Track track, VisualSampleEntry vse) {\n        VideoQuality l;\n        if (\"avc1\".equals(getFormat(vse))) {\n            AvcConfigurationBox avcConfigurationBox = vse.getBoxes(AvcConfigurationBox.class).get(0);\n            l = new VideoQuality();\n            l.bitrate = getBitrate(track);\n            l.codecPrivateData = Hex.encodeHex(getAvcCodecPrivateData(avcConfigurationBox));\n            l.fourCC = \"AVC1\";\n            l.width = vse.getWidth();\n            l.height = vse.getHeight();\n            l.nalLength = avcConfigurationBox.getLengthSizeMinusOne() + 1;\n\n        } else {\n            throw new InternalError(\"I don't know how to handle video of type \" + getFormat(vse));\n        }\n        return l;\n    }\n\n    private long[] checkFragmentsAlign(long[] referenceTimes, long[] checkTimes) throws IOException {\n\n        if (referenceTimes == null || referenceTimes.length == 0) {\n            return checkTimes;\n        }\n        long[] referenceTimesMinusLast = new long[referenceTimes.length - 1];\n        System.arraycopy(referenceTimes, 0, referenceTimesMinusLast, 0, referenceTimes.length - 1);\n        long[] checkTimesMinusLast = new long[checkTimes.length - 1];\n        System.arraycopy(checkTimes, 0, checkTimesMinusLast, 0, checkTimes.length - 1);\n\n        if (!Arrays.equals(checkTimesMinusLast, referenceTimesMinusLast)) {\n            System.err.print(\"Reference     :  [\");\n            for (long l : checkTimes) {\n                System.err.print(l + \",\");\n            }\n            System.err.println(\"]\");\n\n\n            System.err.print(\"Current       :  [\");\n            for (long l : referenceTimes) {\n                System.err.print(l + \",\");\n            }\n            System.err.println(\"]\");\n            throw new IOException(\"Track does not have the same fragment borders as its predecessor.\");\n\n\n        } else {\n            return checkTimes;\n        }\n    }\n\n    private byte[] getAvcCodecPrivateData(AvcConfigurationBox avcConfigurationBox) {\n        List<byte[]> sps = avcConfigurationBox.getSequenceParameterSets();\n        List<byte[]> pps = avcConfigurationBox.getPictureParameterSets();\n        ByteArrayOutputStream baos = new ByteArrayOutputStream();\n        try {\n            baos.write(new byte[]{0, 0, 0, 1});\n\n            for (byte[] sp : sps) {\n                baos.write(sp);\n            }\n            baos.write(new byte[]{0, 0, 0, 1});\n            for (byte[] pp : pps) {\n                baos.write(pp);\n            }\n        } catch (IOException ex) {\n            throw new InternalError(\"ByteArrayOutputStream do not throw IOException ?!?!?\");\n        }\n        return baos.toByteArray();\n    }\n\n    private String getFormat(SampleEntry se) {\n        String type = se.getType();\n        if (type.equals(\"encv\") || type.equals(\"enca\") || type.equals(\"encv\")) {\n            OriginalFormatBox frma = se.getBoxes(OriginalFormatBox.class, true).get(0);\n            type = frma.getDataFormat();\n        }\n        return type;\n    }\n\n    /**\n     * Calculates the length of each fragment in the given <code>track</code> (as part of <code>movie</code>).\n     *\n     * @param track target of calculation\n     * @param movie the <code>track</code> must be part of this <code>movie</code>\n     * @return the duration of each fragment in track timescale\n     */\n    public long[] calculateFragmentDurations(Track track, Movie movie) {\n        long[] startSamples = intersectionFinder.sampleNumbers(track, movie);\n        long[] durations = new long[startSamples.length];\n        int currentFragment = -1;\n        int currentSample = 1; // sync samples start with 1 !\n\n        for (TimeToSampleBox.Entry entry : track.getDecodingTimeEntries()) {\n            for (int max = currentSample + l2i(entry.getCount()); currentSample <= max; currentSample++) {\n                // in this loop we go through the entry.getCount() samples starting from current sample.\n                // the next entry.getCount() samples have the same decoding time.\n                if (currentFragment != startSamples.length - 1 && currentSample == startSamples[currentFragment + 1]) {\n                    // we are not in the last fragment && the current sample is the start sample of the next fragment\n                    currentFragment++;\n                }\n                durations[currentFragment] += entry.getDelta();\n            }\n        }\n        return durations;\n\n    }\n\n\n    protected static long getDuration(Track track) {\n        long duration = 0;\n        for (TimeToSampleBox.Entry entry : track.getDecodingTimeEntries()) {\n            duration += entry.getCount() * entry.getDelta();\n        }\n        return duration;\n    }\n\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/builder/smoothstreaming/FlatPackageWriterImpl.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring.builder.smoothstreaming;\n\nimport com.coremedia.iso.IsoFile;\nimport com.coremedia.iso.boxes.*;\nimport com.coremedia.iso.boxes.fragment.MovieFragmentBox;\nimport com.googlecode.mp4parser.authoring.Movie;\nimport com.googlecode.mp4parser.authoring.Track;\nimport com.googlecode.mp4parser.authoring.builder.DefaultMp4Builder;\nimport com.googlecode.mp4parser.authoring.builder.FragmentIntersectionFinder;\nimport com.googlecode.mp4parser.authoring.builder.FragmentedMp4Builder;\nimport com.googlecode.mp4parser.authoring.builder.Mp4Builder;\nimport com.googlecode.mp4parser.authoring.builder.SyncSampleIntersectFinderImpl;\nimport com.googlecode.mp4parser.authoring.tracks.ChangeTimeScaleTrack;\n\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.FileWriter;\nimport java.io.IOException;\nimport java.nio.channels.FileChannel;\nimport java.util.Iterator;\nimport java.util.logging.Logger;\n\nimport static com.googlecode.mp4parser.util.Math.gcd;\nimport static com.googlecode.mp4parser.util.Math.lcm;\n\npublic class FlatPackageWriterImpl implements PackageWriter {\n    private static Logger LOG = Logger.getLogger(FlatPackageWriterImpl.class.getName());\n    long timeScale = 10000000;\n\n    private File outputDirectory;\n    private boolean debugOutput;\n    private Mp4Builder ismvBuilder;\n    ManifestWriter manifestWriter;\n    FragmentIntersectionFinder fragmentIntersectionFinder;\n\n    {\n        ismvBuilder = new FragmentedMp4Builder();\n        fragmentIntersectionFinder = new SyncSampleIntersectFinderImpl();\n        ((FragmentedMp4Builder) ismvBuilder).setIntersectionFinder(fragmentIntersectionFinder);\n        manifestWriter = new FlatManifestWriterImpl();\n    }\n\n\n    public void setOutputDirectory(File outputDirectory) {\n        assert outputDirectory.isDirectory();\n        this.outputDirectory = outputDirectory;\n\n    }\n\n    public void setDebugOutput(boolean debugOutput) {\n        this.debugOutput = debugOutput;\n    }\n\n    public void setIsmvBuilder(Mp4Builder ismvBuilder) {\n        this.ismvBuilder = ismvBuilder;\n    }\n\n    public void setManifestWriter(ManifestWriter manifestWriter) {\n        this.manifestWriter = manifestWriter;\n    }\n\n    /**\n     * Writes the movie given as <code>qualities</code> flattened into the\n     * <code>outputDirectory</code>.\n     *\n     * @param source the source movie with all qualities\n     * @throws IOException\n     */\n    public void write(Movie source) throws IOException {\n\n        if (debugOutput) {\n            DefaultMp4Builder defaultMp4Builder = new DefaultMp4Builder();\n            IsoFile muxed = defaultMp4Builder.build(source);\n            File muxedFile = new File(outputDirectory, \"debug_1_muxed.mp4\");\n            FileOutputStream muxedFileOutputStream = new FileOutputStream(muxedFile);\n            muxed.getBox(muxedFileOutputStream.getChannel());\n            muxedFileOutputStream.close();\n        }\n        Movie movieWithAdjustedTimescale = correctTimescale(source);\n        if (debugOutput) {\n            DefaultMp4Builder defaultMp4Builder = new DefaultMp4Builder();\n            IsoFile muxed = defaultMp4Builder.build(movieWithAdjustedTimescale);\n            File muxedFile = new File(outputDirectory, \"debug_2_timescale.mp4\");\n            FileOutputStream muxedFileOutputStream = new FileOutputStream(muxedFile);\n            muxed.getBox(muxedFileOutputStream.getChannel());\n            muxedFileOutputStream.close();\n        }\n        IsoFile isoFile = ismvBuilder.build(movieWithAdjustedTimescale);\n        if (debugOutput) {\n            File allQualities = new File(outputDirectory, \"debug_3_fragmented.mp4\");\n            FileOutputStream allQualis = new FileOutputStream(allQualities);\n            isoFile.getBox(allQualis.getChannel());\n            allQualis.close();\n        }\n\n\n        for (Track track : movieWithAdjustedTimescale.getTracks()) {\n            String bitrate = Long.toString(manifestWriter.getBitrate(track));\n            long trackId = track.getTrackMetaData().getTrackId();\n            Iterator<Box> boxIt = isoFile.getBoxes().iterator();\n            File mediaOutDir;\n            if (track.getMediaHeaderBox() instanceof SoundMediaHeaderBox) {\n                mediaOutDir = new File(outputDirectory, \"audio\");\n\n            } else if (track.getMediaHeaderBox() instanceof VideoMediaHeaderBox) {\n                mediaOutDir = new File(outputDirectory, \"video\");\n            } else {\n                System.err.println(\"Skipping Track with handler \" + track.getHandler() + \" and \" + track.getMediaHeaderBox().getClass().getSimpleName());\n                continue;\n            }\n            File bitRateOutputDir = new File(mediaOutDir, bitrate);\n            bitRateOutputDir.mkdirs();\n            LOG.finer(\"Created : \" + bitRateOutputDir.getCanonicalPath());\n\n            long[] fragmentTimes = manifestWriter.calculateFragmentDurations(track, movieWithAdjustedTimescale);\n            long startTime = 0;\n            int currentFragment = 0;\n            while (boxIt.hasNext()) {\n                Box b = boxIt.next();\n                if (b instanceof MovieFragmentBox) {\n                    assert ((MovieFragmentBox) b).getTrackCount() == 1;\n                    if (((MovieFragmentBox) b).getTrackNumbers()[0] == trackId) {\n                        FileOutputStream fos = new FileOutputStream(new File(bitRateOutputDir, Long.toString(startTime)));\n                        startTime += fragmentTimes[currentFragment++];\n                        FileChannel fc = fos.getChannel();\n                        Box mdat = boxIt.next();\n                        assert mdat.getType().equals(\"mdat\");\n                        b.getBox(fc); // moof\n                        mdat.getBox(fc); // mdat\n                        fc.truncate(fc.position());\n                        fc.close();\n                    }\n                }\n\n            }\n        }\n        FileWriter fw = new FileWriter(new File(outputDirectory, \"Manifest\"));\n        fw.write(manifestWriter.getManifest(movieWithAdjustedTimescale));\n        fw.close();\n\n    }\n\n\n    /**\n     * Returns a new <code>Movie</code> in that all tracks have the timescale 10000000. CTS & DTS are modified\n     * in a way that even with more than one framerate the fragments exactly begin at the same time.\n     *\n     * @param movie\n     * @return a movie with timescales suitable for smooth streaming manifests\n     */\n    public Movie correctTimescale(Movie movie) {\n\n        Movie nuMovie = new Movie();\n\n        for (Track track : movie.getTracks()) {\n            nuMovie.addTrack(new ChangeTimeScaleTrack(track, timeScale, fragmentIntersectionFinder.sampleNumbers(track, movie)));\n        }\n        movie.setTracks(nuMovie.getTracks());\n        return movie;\n    }\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/builder/smoothstreaming/ManifestWriter.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring.builder.smoothstreaming;\n\n\nimport com.googlecode.mp4parser.authoring.Movie;\nimport com.googlecode.mp4parser.authoring.Track;\n\nimport java.io.IOException;\n\npublic interface ManifestWriter {\n    String getManifest(Movie inputs) throws IOException;\n\n    long getBitrate(Track track);\n\n    long[] calculateFragmentDurations(Track track, Movie movie);\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/builder/smoothstreaming/PackageWriter.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring.builder.smoothstreaming;\n\nimport com.googlecode.mp4parser.authoring.Movie;\n\nimport java.io.IOException;\n\n/**\n * Writes the whole package.\n */\npublic interface PackageWriter {\n    public void write(Movie qualities) throws IOException;\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/builder/smoothstreaming/VideoQuality.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring.builder.smoothstreaming;\n\nclass VideoQuality {\n    long bitrate;\n    String fourCC;\n    int width;\n    int height;\n    String codecPrivateData;\n    int nalLength;\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/container/mp4/MovieCreator.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring.container.mp4;\n\nimport com.coremedia.iso.IsoFile;\nimport com.coremedia.iso.boxes.TrackBox;\nimport com.googlecode.mp4parser.authoring.Movie;\nimport com.googlecode.mp4parser.authoring.Mp4TrackImpl;\n\nimport java.io.IOException;\nimport java.nio.channels.ReadableByteChannel;\nimport java.util.List;\n\n/**\n * Shortcut to build a movie from an MP4 file.\n */\npublic class MovieCreator {\n    public static Movie build(ReadableByteChannel channel) throws IOException {\n        IsoFile isoFile = new IsoFile(channel);\n        Movie m = new Movie();\n        List<TrackBox> trackBoxes = isoFile.getMovieBox().getBoxes(TrackBox.class);\n        for (TrackBox trackBox : trackBoxes) {\n            m.addTrack(new Mp4TrackImpl(trackBox));\n        }\n        return m;\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/tracks/AACTrackImpl.java",
    "content": "package com.googlecode.mp4parser.authoring.tracks;\n\nimport java.io.IOException;\nimport java.io.PushbackInputStream;\nimport java.nio.ByteBuffer;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Map;\n\nimport com.coremedia.iso.boxes.AbstractMediaHeaderBox;\nimport com.coremedia.iso.boxes.CompositionTimeToSample;\nimport com.coremedia.iso.boxes.SampleDependencyTypeBox;\nimport com.coremedia.iso.boxes.SampleDescriptionBox;\nimport com.coremedia.iso.boxes.SoundMediaHeaderBox;\nimport com.coremedia.iso.boxes.SubSampleInformationBox;\nimport com.coremedia.iso.boxes.TimeToSampleBox;\nimport com.coremedia.iso.boxes.sampleentry.AudioSampleEntry;\nimport com.googlecode.mp4parser.authoring.AbstractTrack;\nimport com.googlecode.mp4parser.authoring.TrackMetaData;\nimport com.googlecode.mp4parser.boxes.mp4.ESDescriptorBox;\nimport com.googlecode.mp4parser.boxes.mp4.objectdescriptors.AudioSpecificConfig;\nimport com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitReaderBuffer;\nimport com.googlecode.mp4parser.boxes.mp4.objectdescriptors.DecoderConfigDescriptor;\nimport com.googlecode.mp4parser.boxes.mp4.objectdescriptors.ESDescriptor;\nimport com.googlecode.mp4parser.boxes.mp4.objectdescriptors.SLConfigDescriptor;\n\n/**\n * Created with IntelliJ IDEA.\n * User: magnus\n * Date: 2012-04-20\n * Time: 11:14\n * To change this template use File | Settings | File Templates.\n */\npublic class AACTrackImpl extends AbstractTrack {\n    TrackMetaData trackMetaData = new TrackMetaData();\n    SampleDescriptionBox sampleDescriptionBox;\n\n    int samplerate;\n    int bitrate;\n    int channelCount;\n    int channelconfig;\n\n    int bufferSizeDB;\n    long maxBitRate;\n    long avgBitRate;\n\n    private PushbackInputStream inputStream;\n    private List<ByteBuffer> samples;\n    boolean readSamples = false;\n    List<TimeToSampleBox.Entry> stts;\n    public static Map<Integer, Integer> samplingFrequencyIndexMap = new HashMap<Integer, Integer>();\n\n    public AACTrackImpl(PushbackInputStream inputStream) throws IOException {\n        this.inputStream = inputStream;\n        stts = new LinkedList<TimeToSampleBox.Entry>();\n\n        samplingFrequencyIndexMap.put(96000, 0);\n        samplingFrequencyIndexMap.put(88200, 1);\n        samplingFrequencyIndexMap.put(64000, 2);\n        samplingFrequencyIndexMap.put(48000, 3);\n        samplingFrequencyIndexMap.put(44100, 4);\n        samplingFrequencyIndexMap.put(32000, 5);\n        samplingFrequencyIndexMap.put(24000, 6);\n        samplingFrequencyIndexMap.put(22050, 7);\n        samplingFrequencyIndexMap.put(16000, 8);\n        samplingFrequencyIndexMap.put(12000, 9);\n        samplingFrequencyIndexMap.put(11025, 10);\n        samplingFrequencyIndexMap.put(8000, 11);\n        samplingFrequencyIndexMap.put(0x0, 96000);\n        samplingFrequencyIndexMap.put(0x1, 88200);\n        samplingFrequencyIndexMap.put(0x2, 64000);\n        samplingFrequencyIndexMap.put(0x3, 48000);\n        samplingFrequencyIndexMap.put(0x4, 44100);\n        samplingFrequencyIndexMap.put(0x5, 32000);\n        samplingFrequencyIndexMap.put(0x6, 24000);\n        samplingFrequencyIndexMap.put(0x7, 22050);\n        samplingFrequencyIndexMap.put(0x8, 16000);\n        samplingFrequencyIndexMap.put(0x9, 12000);\n        samplingFrequencyIndexMap.put(0xa, 11025);\n        samplingFrequencyIndexMap.put(0xb, 8000);\n\n        if (!readVariables()) {\n            throw new IOException();\n        }\n\n        samples = new LinkedList<ByteBuffer>();\n        if (!readSamples()) {\n            throw new IOException();\n        }\n\n        double packetsPerSecond = (double)samplerate / 1024.0;\n        double duration = samples.size() / packetsPerSecond;\n\n        long dataSize = 0;\n        LinkedList<Integer> queue = new LinkedList<Integer>();\n        for (int i = 0; i < samples.size(); i++) {\n            int size = samples.get(i).capacity();\n            dataSize += size;\n            queue.add(size);\n            while (queue.size() > packetsPerSecond) {\n                queue.removeFirst();\n            }\n            if (queue.size() == (int) packetsPerSecond) {\n                int currSize = 0;\n                for (int j = 0 ; j < queue.size(); j++) {\n                    currSize += queue.get(j);\n                }\n                double currBitrate = 8.0 * currSize / queue.size() * packetsPerSecond;\n                if (currBitrate > maxBitRate) {\n                    maxBitRate = (int)currBitrate;\n                }\n            }\n        }\n\n        avgBitRate = (int) (8 * dataSize / duration);\n\n        bufferSizeDB = 1536; /* TODO: Calcultate this somehow! */\n\n        sampleDescriptionBox = new SampleDescriptionBox();\n        AudioSampleEntry audioSampleEntry = new AudioSampleEntry(\"mp4a\");\n        audioSampleEntry.setChannelCount(2);\n        audioSampleEntry.setSampleRate(samplerate);\n        audioSampleEntry.setDataReferenceIndex(1);\n        audioSampleEntry.setSampleSize(16);\n\n\n        ESDescriptorBox esds = new ESDescriptorBox();\n        ESDescriptor descriptor = new ESDescriptor();\n        descriptor.setEsId(0);\n\n        SLConfigDescriptor slConfigDescriptor = new SLConfigDescriptor();\n        slConfigDescriptor.setPredefined(2);\n        descriptor.setSlConfigDescriptor(slConfigDescriptor);\n\n        DecoderConfigDescriptor decoderConfigDescriptor = new DecoderConfigDescriptor();\n        decoderConfigDescriptor.setObjectTypeIndication(0x40);\n        decoderConfigDescriptor.setStreamType(5);\n        decoderConfigDescriptor.setBufferSizeDB(bufferSizeDB);\n        decoderConfigDescriptor.setMaxBitRate(maxBitRate);\n        decoderConfigDescriptor.setAvgBitRate(avgBitRate);\n\n        AudioSpecificConfig audioSpecificConfig = new AudioSpecificConfig();\n        audioSpecificConfig.setAudioObjectType(2); // AAC LC\n        audioSpecificConfig.setSamplingFrequencyIndex(samplingFrequencyIndexMap.get(samplerate));\n        audioSpecificConfig.setChannelConfiguration(channelconfig);\n        decoderConfigDescriptor.setAudioSpecificInfo(audioSpecificConfig);\n\n        descriptor.setDecoderConfigDescriptor(decoderConfigDescriptor);\n\n        ByteBuffer data = descriptor.serialize();\n        esds.setData(data);\n        audioSampleEntry.addBox(esds);\n        sampleDescriptionBox.addBox(audioSampleEntry);\n\n        trackMetaData.setCreationTime(new Date());\n        trackMetaData.setModificationTime(new Date());\n        trackMetaData.setLanguage(\"eng\");\n        trackMetaData.setTimescale(samplerate); // Audio tracks always use samplerate as timescale\n\n     }\n\n    public SampleDescriptionBox getSampleDescriptionBox() {\n        return sampleDescriptionBox;  //To change body of implemented methods use File | Settings | File Templates.\n    }\n\n    public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {\n        return stts;  //To change body of implemented methods use File | Settings | File Templates.\n    }\n\n    public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {\n        return null;  //To change body of implemented methods use File | Settings | File Templates.\n    }\n\n    public long[] getSyncSamples() {\n        return null;  //To change body of implemented methods use File | Settings | File Templates.\n    }\n\n    public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {\n        return null;  //To change body of implemented methods use File | Settings | File Templates.\n    }\n\n    public TrackMetaData getTrackMetaData() {\n        return trackMetaData;  //To change body of implemented methods use File | Settings | File Templates.\n    }\n\n    public String getHandler() {\n        return \"soun\";  //To change body of implemented methods use File | Settings | File Templates.\n    }\n\n    public List<ByteBuffer> getSamples() {\n        return samples;  //To change body of implemented methods use File | Settings | File Templates.\n    }\n\n    public AbstractMediaHeaderBox getMediaHeaderBox() {\n        return new SoundMediaHeaderBox();\n    }\n\n    public SubSampleInformationBox getSubsampleInformationBox() {\n        return null;  //To change body of implemented methods use File | Settings | File Templates.\n    }\n\n    private boolean readVariables() throws IOException {\n        byte[] data = new byte[100];\n        if (100 != inputStream.read(data, 0, 100)) {\n            return false;\n        }\n        inputStream.unread(data);\n\n        ByteBuffer bb = ByteBuffer.wrap(data);\n        BitReaderBuffer brb = new BitReaderBuffer(bb);\n        int syncword = brb.readBits(12);\n\n        if (syncword != 0xfff) {\n            return false;\n        }\n        int id = brb.readBits(1);\n        int layer = brb.readBits(2);\n        int protectionAbsent = brb.readBits(1);\n        int profile = brb.readBits(2);\n        samplerate = samplingFrequencyIndexMap.get(brb.readBits(4));\n        brb.readBits(1);\n        channelconfig = brb.readBits(3);\n        int original = brb.readBits(1);\n        int home = brb.readBits(1);\n        int emphasis = brb.readBits(2);\n\n        return true;\n    }\n\n    private boolean readSamples() throws IOException {\n        if (readSamples) {\n            return true;\n        }\n\n        readSamples = true;\n        byte[] header = new byte[15];\n        boolean ret = false;\n        while (-1 != inputStream.read(header)) {\n            ret = true;\n            ByteBuffer bb = ByteBuffer.wrap(header);\n\n            inputStream.unread(header);\n            BitReaderBuffer brb = new BitReaderBuffer(bb);\n            int syncword = brb.readBits(12);\n\n            if (syncword != 0xfff) {\n                return false;\n            }\n            brb.readBits(3);\n            int protectionAbsent = brb.readBits(1);\n            brb.readBits(14);\n            int frameSize = brb.readBits(13);\n            int bufferFullness = brb.readBits(11);\n            int noBlocks = brb.readBits(2);\n            int used = (int) Math.ceil(brb.getPosition() / 8.0);\n            if (protectionAbsent == 0) {\n                used += 2;\n            }\n            inputStream.skip(used);\n            frameSize -= used;\n//            System.out.println(\"Size: \" + frameSize + \" fullness: \" + bufferFullness + \" no blocks: \" + noBlocks);\n            byte[] data = new byte[frameSize];\n            inputStream.read(data);\n            samples.add(ByteBuffer.wrap(data));\n            stts.add(new TimeToSampleBox.Entry(1, 1024));\n\n        }\n        return ret;\n    }\n}\n\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/tracks/AC3TrackImpl.java",
    "content": "package com.googlecode.mp4parser.authoring.tracks;\n\nimport com.coremedia.iso.boxes.*;\nimport com.coremedia.iso.boxes.sampleentry.AudioSampleEntry;\nimport com.googlecode.mp4parser.authoring.AbstractTrack;\nimport com.googlecode.mp4parser.authoring.TrackMetaData;\nimport com.googlecode.mp4parser.boxes.AC3SpecificBox;\nimport com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitReaderBuffer;\n\nimport java.io.InputStream;\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.util.Date;\nimport java.util.LinkedList;\nimport java.util.List;\n\npublic class AC3TrackImpl extends AbstractTrack {\n    TrackMetaData trackMetaData = new TrackMetaData();\n    SampleDescriptionBox sampleDescriptionBox;\n\n    int samplerate;\n    int bitrate;\n    int channelCount;\n\n    int fscod;\n    int bsid;\n    int bsmod;\n    int acmod;\n    int lfeon;\n    int frmsizecod;\n\n    int frameSize;\n    int[][][][] bitRateAndFrameSizeTable;\n\n    private InputStream inputStream;\n    private List<ByteBuffer> samples;\n    boolean readSamples = false;\n    List<TimeToSampleBox.Entry> stts;\n\n    public AC3TrackImpl(InputStream fin) throws IOException {\n        inputStream = fin;\n        bitRateAndFrameSizeTable = new int[19][2][3][2];\n        stts = new LinkedList<TimeToSampleBox.Entry>();\n        initBitRateAndFrameSizeTable();\n        if (!readVariables()) {\n            throw new IOException();\n        }\n\n        sampleDescriptionBox = new SampleDescriptionBox();\n        AudioSampleEntry audioSampleEntry = new AudioSampleEntry(\"ac-3\");\n        audioSampleEntry.setChannelCount(2);\n        audioSampleEntry.setSampleRate(samplerate);\n        audioSampleEntry.setDataReferenceIndex(1);\n        audioSampleEntry.setSampleSize(16);\n\n        AC3SpecificBox ac3 = new AC3SpecificBox();\n        ac3.setAcmod(acmod);\n        ac3.setBitRateCode(frmsizecod >> 1);\n        ac3.setBsid(bsid);\n        ac3.setBsmod(bsmod);\n        ac3.setFscod(fscod);\n        ac3.setLfeon(lfeon);\n        ac3.setReserved(0);\n\n        audioSampleEntry.addBox(ac3);\n        sampleDescriptionBox.addBox(audioSampleEntry);\n\n        trackMetaData.setCreationTime(new Date());\n        trackMetaData.setModificationTime(new Date());\n        trackMetaData.setLanguage(\"eng\");\n        trackMetaData.setTimescale(samplerate); // Audio tracks always use samplerate as timescale\n\n        samples = new LinkedList<ByteBuffer>();\n        if (!readSamples()) {\n            throw new IOException();\n        }\n    }\n\n\n    public List<ByteBuffer> getSamples() {\n\n        return samples;\n    }\n\n    public SampleDescriptionBox getSampleDescriptionBox() {\n        return sampleDescriptionBox;\n    }\n\n    public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {\n        return stts;\n    }\n\n    public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {\n        return null;\n    }\n\n    public long[] getSyncSamples() {\n        return null;\n    }\n\n    public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {\n        return null;\n    }\n\n    public TrackMetaData getTrackMetaData() {\n        return trackMetaData;\n    }\n\n    public String getHandler() {\n        return \"soun\";\n    }\n\n    public AbstractMediaHeaderBox getMediaHeaderBox() {\n        return new SoundMediaHeaderBox();\n    }\n\n    public SubSampleInformationBox getSubsampleInformationBox() {\n        return null;\n    }\n\n    private boolean readVariables() throws IOException {\n        byte[] data = new byte[100];\n        if (100 != inputStream.read(data, 0, 100)) {\n            return false;\n        }\n        inputStream.skip(-100); // Rewind\n        ByteBuffer bb = ByteBuffer.wrap(data);\n        BitReaderBuffer brb = new BitReaderBuffer(bb);\n        int syncword = brb.readBits(16);\n        if (syncword != 0xb77) {\n            return false;\n        }\n        brb.readBits(16); // CRC-1\n        fscod = brb.readBits(2);\n\n        switch (fscod) {\n            case 0:\n                samplerate = 48000;\n                break;\n\n            case 1:\n                samplerate = 44100;\n                break;\n\n            case 2:\n                samplerate = 32000;\n                break;\n\n            case 3:\n                samplerate = 0;\n                break;\n\n        }\n        if (samplerate == 0) {\n            return false;\n        }\n\n        frmsizecod = brb.readBits(6);\n\n        if (!calcBitrateAndFrameSize(frmsizecod)) {\n            return false;\n        }\n\n        if (frameSize == 0) {\n            return false;\n        }\n        bsid = brb.readBits(5);\n        bsmod = brb.readBits(3);\n        acmod = brb.readBits(3);\n\n        if (bsid == 9) {\n            samplerate /= 2;\n        } else if (bsid != 8 && bsid != 6) {\n            return false;\n        }\n\n        if ((acmod != 1) && ((acmod & 1) == 1)) {\n            brb.readBits(2);\n        }\n\n        if (0 != (acmod & 4)) {\n            brb.readBits(2);\n        }\n\n        if (acmod == 2) {\n            brb.readBits(2);\n        }\n\n        switch (acmod) {\n            case 0:\n                channelCount = 2;\n                break;\n\n            case 1:\n                channelCount = 1;\n                break;\n\n            case 2:\n                channelCount = 2;\n                break;\n\n            case 3:\n                channelCount = 3;\n                break;\n\n            case 4:\n                channelCount = 3;\n                break;\n\n            case 5:\n                channelCount = 4;\n                break;\n\n            case 6:\n                channelCount = 4;\n                break;\n\n            case 7:\n                channelCount = 5;\n                break;\n\n        }\n\n        lfeon = brb.readBits(1);\n\n        if (lfeon == 1) {\n            channelCount++;\n        }\n        return true;\n    }\n\n    private boolean calcBitrateAndFrameSize(int code) {\n        int frmsizecode = code >>> 1;\n        int flag = code & 1;\n        if (frmsizecode > 18 || flag > 1 || fscod > 2) {\n            return false;\n        }\n        bitrate = bitRateAndFrameSizeTable[frmsizecode][flag][fscod][0];\n        frameSize = 2 * bitRateAndFrameSizeTable[frmsizecode][flag][fscod][1];\n        return true;\n    }\n\n    private boolean readSamples() throws IOException {\n        if (readSamples) {\n            return true;\n        }\n        readSamples = true;\n        byte[] header = new byte[5];\n        boolean ret = false;\n        while (-1 != inputStream.read(header)) {\n            ret = true;\n            int frmsizecode = header[4] & 63;\n            calcBitrateAndFrameSize(frmsizecode);\n            inputStream.skip(-5);\n            byte[] data = new byte[frameSize];\n            inputStream.read(data);\n            samples.add(ByteBuffer.wrap(data));\n            stts.add(new TimeToSampleBox.Entry(1, 1536));\n\n        }\n        return ret;\n    }\n\n    private void initBitRateAndFrameSizeTable() {\n        // ETSI 102 366 Table 4.13, in frmsizecod, flag, fscod, bitrate/size order. Note that all sizes are in words, and all bitrates in kbps\n\n        // 48kHz\n        bitRateAndFrameSizeTable[0][0][0][0] = 32;\n        bitRateAndFrameSizeTable[0][1][0][0] = 32;\n        bitRateAndFrameSizeTable[0][0][0][1] = 64;\n        bitRateAndFrameSizeTable[0][1][0][1] = 64;\n        bitRateAndFrameSizeTable[1][0][0][0] = 40;\n        bitRateAndFrameSizeTable[1][1][0][0] = 40;\n        bitRateAndFrameSizeTable[1][0][0][1] = 80;\n        bitRateAndFrameSizeTable[1][1][0][1] = 80;\n        bitRateAndFrameSizeTable[2][0][0][0] = 48;\n        bitRateAndFrameSizeTable[2][1][0][0] = 48;\n        bitRateAndFrameSizeTable[2][0][0][1] = 96;\n        bitRateAndFrameSizeTable[2][1][0][1] = 96;\n        bitRateAndFrameSizeTable[3][0][0][0] = 56;\n        bitRateAndFrameSizeTable[3][1][0][0] = 56;\n        bitRateAndFrameSizeTable[3][0][0][1] = 112;\n        bitRateAndFrameSizeTable[3][1][0][1] = 112;\n        bitRateAndFrameSizeTable[4][0][0][0] = 64;\n        bitRateAndFrameSizeTable[4][1][0][0] = 64;\n        bitRateAndFrameSizeTable[4][0][0][1] = 128;\n        bitRateAndFrameSizeTable[4][1][0][1] = 128;\n        bitRateAndFrameSizeTable[5][0][0][0] = 80;\n        bitRateAndFrameSizeTable[5][1][0][0] = 80;\n        bitRateAndFrameSizeTable[5][0][0][1] = 160;\n        bitRateAndFrameSizeTable[5][1][0][1] = 160;\n        bitRateAndFrameSizeTable[6][0][0][0] = 96;\n        bitRateAndFrameSizeTable[6][1][0][0] = 96;\n        bitRateAndFrameSizeTable[6][0][0][1] = 192;\n        bitRateAndFrameSizeTable[6][1][0][1] = 192;\n        bitRateAndFrameSizeTable[7][0][0][0] = 112;\n        bitRateAndFrameSizeTable[7][1][0][0] = 112;\n        bitRateAndFrameSizeTable[7][0][0][1] = 224;\n        bitRateAndFrameSizeTable[7][1][0][1] = 224;\n        bitRateAndFrameSizeTable[8][0][0][0] = 128;\n        bitRateAndFrameSizeTable[8][1][0][0] = 128;\n        bitRateAndFrameSizeTable[8][0][0][1] = 256;\n        bitRateAndFrameSizeTable[8][1][0][1] = 256;\n        bitRateAndFrameSizeTable[9][0][0][0] = 160;\n        bitRateAndFrameSizeTable[9][1][0][0] = 160;\n        bitRateAndFrameSizeTable[9][0][0][1] = 320;\n        bitRateAndFrameSizeTable[9][1][0][1] = 320;\n        bitRateAndFrameSizeTable[10][0][0][0] = 192;\n        bitRateAndFrameSizeTable[10][1][0][0] = 192;\n        bitRateAndFrameSizeTable[10][0][0][1] = 384;\n        bitRateAndFrameSizeTable[10][1][0][1] = 384;\n        bitRateAndFrameSizeTable[11][0][0][0] = 224;\n        bitRateAndFrameSizeTable[11][1][0][0] = 224;\n        bitRateAndFrameSizeTable[11][0][0][1] = 448;\n        bitRateAndFrameSizeTable[11][1][0][1] = 448;\n        bitRateAndFrameSizeTable[12][0][0][0] = 256;\n        bitRateAndFrameSizeTable[12][1][0][0] = 256;\n        bitRateAndFrameSizeTable[12][0][0][1] = 512;\n        bitRateAndFrameSizeTable[12][1][0][1] = 512;\n        bitRateAndFrameSizeTable[13][0][0][0] = 320;\n        bitRateAndFrameSizeTable[13][1][0][0] = 320;\n        bitRateAndFrameSizeTable[13][0][0][1] = 640;\n        bitRateAndFrameSizeTable[13][1][0][1] = 640;\n        bitRateAndFrameSizeTable[14][0][0][0] = 384;\n        bitRateAndFrameSizeTable[14][1][0][0] = 384;\n        bitRateAndFrameSizeTable[14][0][0][1] = 768;\n        bitRateAndFrameSizeTable[14][1][0][1] = 768;\n        bitRateAndFrameSizeTable[15][0][0][0] = 448;\n        bitRateAndFrameSizeTable[15][1][0][0] = 448;\n        bitRateAndFrameSizeTable[15][0][0][1] = 896;\n        bitRateAndFrameSizeTable[15][1][0][1] = 896;\n        bitRateAndFrameSizeTable[16][0][0][0] = 512;\n        bitRateAndFrameSizeTable[16][1][0][0] = 512;\n        bitRateAndFrameSizeTable[16][0][0][1] = 1024;\n        bitRateAndFrameSizeTable[16][1][0][1] = 1024;\n        bitRateAndFrameSizeTable[17][0][0][0] = 576;\n        bitRateAndFrameSizeTable[17][1][0][0] = 576;\n        bitRateAndFrameSizeTable[17][0][0][1] = 1152;\n        bitRateAndFrameSizeTable[17][1][0][1] = 1152;\n        bitRateAndFrameSizeTable[18][0][0][0] = 640;\n        bitRateAndFrameSizeTable[18][1][0][0] = 640;\n        bitRateAndFrameSizeTable[18][0][0][1] = 1280;\n        bitRateAndFrameSizeTable[18][1][0][1] = 1280;\n\n        // 44.1 kHz\n        bitRateAndFrameSizeTable[0][0][1][0] = 32;\n        bitRateAndFrameSizeTable[0][1][1][0] = 32;\n        bitRateAndFrameSizeTable[0][0][1][1] = 69;\n        bitRateAndFrameSizeTable[0][1][1][1] = 70;\n        bitRateAndFrameSizeTable[1][0][1][0] = 40;\n        bitRateAndFrameSizeTable[1][1][1][0] = 40;\n        bitRateAndFrameSizeTable[1][0][1][1] = 87;\n        bitRateAndFrameSizeTable[1][1][1][1] = 88;\n        bitRateAndFrameSizeTable[2][0][1][0] = 48;\n        bitRateAndFrameSizeTable[2][1][1][0] = 48;\n        bitRateAndFrameSizeTable[2][0][1][1] = 104;\n        bitRateAndFrameSizeTable[2][1][1][1] = 105;\n        bitRateAndFrameSizeTable[3][0][1][0] = 56;\n        bitRateAndFrameSizeTable[3][1][1][0] = 56;\n        bitRateAndFrameSizeTable[3][0][1][1] = 121;\n        bitRateAndFrameSizeTable[3][1][1][1] = 122;\n        bitRateAndFrameSizeTable[4][0][1][0] = 64;\n        bitRateAndFrameSizeTable[4][1][1][0] = 64;\n        bitRateAndFrameSizeTable[4][0][1][1] = 139;\n        bitRateAndFrameSizeTable[4][1][1][1] = 140;\n        bitRateAndFrameSizeTable[5][0][1][0] = 80;\n        bitRateAndFrameSizeTable[5][1][1][0] = 80;\n        bitRateAndFrameSizeTable[5][0][1][1] = 174;\n        bitRateAndFrameSizeTable[5][1][1][1] = 175;\n        bitRateAndFrameSizeTable[6][0][1][0] = 96;\n        bitRateAndFrameSizeTable[6][1][1][0] = 96;\n        bitRateAndFrameSizeTable[6][0][1][1] = 208;\n        bitRateAndFrameSizeTable[6][1][1][1] = 209;\n        bitRateAndFrameSizeTable[7][0][1][0] = 112;\n        bitRateAndFrameSizeTable[7][1][1][0] = 112;\n        bitRateAndFrameSizeTable[7][0][1][1] = 243;\n        bitRateAndFrameSizeTable[7][1][1][1] = 244;\n        bitRateAndFrameSizeTable[8][0][1][0] = 128;\n        bitRateAndFrameSizeTable[8][1][1][0] = 128;\n        bitRateAndFrameSizeTable[8][0][1][1] = 278;\n        bitRateAndFrameSizeTable[8][1][1][1] = 279;\n        bitRateAndFrameSizeTable[9][0][1][0] = 160;\n        bitRateAndFrameSizeTable[9][1][1][0] = 160;\n        bitRateAndFrameSizeTable[9][0][1][1] = 348;\n        bitRateAndFrameSizeTable[9][1][1][1] = 349;\n        bitRateAndFrameSizeTable[10][0][1][0] = 192;\n        bitRateAndFrameSizeTable[10][1][1][0] = 192;\n        bitRateAndFrameSizeTable[10][0][1][1] = 417;\n        bitRateAndFrameSizeTable[10][1][1][1] = 418;\n        bitRateAndFrameSizeTable[11][0][1][0] = 224;\n        bitRateAndFrameSizeTable[11][1][1][0] = 224;\n        bitRateAndFrameSizeTable[11][0][1][1] = 487;\n        bitRateAndFrameSizeTable[11][1][1][1] = 488;\n        bitRateAndFrameSizeTable[12][0][1][0] = 256;\n        bitRateAndFrameSizeTable[12][1][1][0] = 256;\n        bitRateAndFrameSizeTable[12][0][1][1] = 557;\n        bitRateAndFrameSizeTable[12][1][1][1] = 558;\n        bitRateAndFrameSizeTable[13][0][1][0] = 320;\n        bitRateAndFrameSizeTable[13][1][1][0] = 320;\n        bitRateAndFrameSizeTable[13][0][1][1] = 696;\n        bitRateAndFrameSizeTable[13][1][1][1] = 697;\n        bitRateAndFrameSizeTable[14][0][1][0] = 384;\n        bitRateAndFrameSizeTable[14][1][1][0] = 384;\n        bitRateAndFrameSizeTable[14][0][1][1] = 835;\n        bitRateAndFrameSizeTable[14][1][1][1] = 836;\n        bitRateAndFrameSizeTable[15][0][1][0] = 448;\n        bitRateAndFrameSizeTable[15][1][1][0] = 448;\n        bitRateAndFrameSizeTable[15][0][1][1] = 975;\n        bitRateAndFrameSizeTable[15][1][1][1] = 975;\n        bitRateAndFrameSizeTable[16][0][1][0] = 512;\n        bitRateAndFrameSizeTable[16][1][1][0] = 512;\n        bitRateAndFrameSizeTable[16][0][1][1] = 1114;\n        bitRateAndFrameSizeTable[16][1][1][1] = 1115;\n        bitRateAndFrameSizeTable[17][0][1][0] = 576;\n        bitRateAndFrameSizeTable[17][1][1][0] = 576;\n        bitRateAndFrameSizeTable[17][0][1][1] = 1253;\n        bitRateAndFrameSizeTable[17][1][1][1] = 1254;\n        bitRateAndFrameSizeTable[18][0][1][0] = 640;\n        bitRateAndFrameSizeTable[18][1][1][0] = 640;\n        bitRateAndFrameSizeTable[18][0][1][1] = 1393;\n        bitRateAndFrameSizeTable[18][1][1][1] = 1394;\n\n        // 32kHz\n        bitRateAndFrameSizeTable[0][0][2][0] = 32;\n        bitRateAndFrameSizeTable[0][1][2][0] = 32;\n        bitRateAndFrameSizeTable[0][0][2][1] = 96;\n        bitRateAndFrameSizeTable[0][1][2][1] = 96;\n        bitRateAndFrameSizeTable[1][0][2][0] = 40;\n        bitRateAndFrameSizeTable[1][1][2][0] = 40;\n        bitRateAndFrameSizeTable[1][0][2][1] = 120;\n        bitRateAndFrameSizeTable[1][1][2][1] = 120;\n        bitRateAndFrameSizeTable[2][0][2][0] = 48;\n        bitRateAndFrameSizeTable[2][1][2][0] = 48;\n        bitRateAndFrameSizeTable[2][0][2][1] = 144;\n        bitRateAndFrameSizeTable[2][1][2][1] = 144;\n        bitRateAndFrameSizeTable[3][0][2][0] = 56;\n        bitRateAndFrameSizeTable[3][1][2][0] = 56;\n        bitRateAndFrameSizeTable[3][0][2][1] = 168;\n        bitRateAndFrameSizeTable[3][1][2][1] = 168;\n        bitRateAndFrameSizeTable[4][0][2][0] = 64;\n        bitRateAndFrameSizeTable[4][1][2][0] = 64;\n        bitRateAndFrameSizeTable[4][0][2][1] = 192;\n        bitRateAndFrameSizeTable[4][1][2][1] = 192;\n        bitRateAndFrameSizeTable[5][0][2][0] = 80;\n        bitRateAndFrameSizeTable[5][1][2][0] = 80;\n        bitRateAndFrameSizeTable[5][0][2][1] = 240;\n        bitRateAndFrameSizeTable[5][1][2][1] = 240;\n        bitRateAndFrameSizeTable[6][0][2][0] = 96;\n        bitRateAndFrameSizeTable[6][1][2][0] = 96;\n        bitRateAndFrameSizeTable[6][0][2][1] = 288;\n        bitRateAndFrameSizeTable[6][1][2][1] = 288;\n        bitRateAndFrameSizeTable[7][0][2][0] = 112;\n        bitRateAndFrameSizeTable[7][1][2][0] = 112;\n        bitRateAndFrameSizeTable[7][0][2][1] = 336;\n        bitRateAndFrameSizeTable[7][1][2][1] = 336;\n        bitRateAndFrameSizeTable[8][0][2][0] = 128;\n        bitRateAndFrameSizeTable[8][1][2][0] = 128;\n        bitRateAndFrameSizeTable[8][0][2][1] = 384;\n        bitRateAndFrameSizeTable[8][1][2][1] = 384;\n        bitRateAndFrameSizeTable[9][0][2][0] = 160;\n        bitRateAndFrameSizeTable[9][1][2][0] = 160;\n        bitRateAndFrameSizeTable[9][0][2][1] = 480;\n        bitRateAndFrameSizeTable[9][1][2][1] = 480;\n        bitRateAndFrameSizeTable[10][0][2][0] = 192;\n        bitRateAndFrameSizeTable[10][1][2][0] = 192;\n        bitRateAndFrameSizeTable[10][0][2][1] = 576;\n        bitRateAndFrameSizeTable[10][1][2][1] = 576;\n        bitRateAndFrameSizeTable[11][0][2][0] = 224;\n        bitRateAndFrameSizeTable[11][1][2][0] = 224;\n        bitRateAndFrameSizeTable[11][0][2][1] = 672;\n        bitRateAndFrameSizeTable[11][1][2][1] = 672;\n        bitRateAndFrameSizeTable[12][0][2][0] = 256;\n        bitRateAndFrameSizeTable[12][1][2][0] = 256;\n        bitRateAndFrameSizeTable[12][0][2][1] = 768;\n        bitRateAndFrameSizeTable[12][1][2][1] = 768;\n        bitRateAndFrameSizeTable[13][0][2][0] = 320;\n        bitRateAndFrameSizeTable[13][1][2][0] = 320;\n        bitRateAndFrameSizeTable[13][0][2][1] = 960;\n        bitRateAndFrameSizeTable[13][1][2][1] = 960;\n        bitRateAndFrameSizeTable[14][0][2][0] = 384;\n        bitRateAndFrameSizeTable[14][1][2][0] = 384;\n        bitRateAndFrameSizeTable[14][0][2][1] = 1152;\n        bitRateAndFrameSizeTable[14][1][2][1] = 1152;\n        bitRateAndFrameSizeTable[15][0][2][0] = 448;\n        bitRateAndFrameSizeTable[15][1][2][0] = 448;\n        bitRateAndFrameSizeTable[15][0][2][1] = 1344;\n        bitRateAndFrameSizeTable[15][1][2][1] = 1344;\n        bitRateAndFrameSizeTable[16][0][2][0] = 512;\n        bitRateAndFrameSizeTable[16][1][2][0] = 512;\n        bitRateAndFrameSizeTable[16][0][2][1] = 1536;\n        bitRateAndFrameSizeTable[16][1][2][1] = 1536;\n        bitRateAndFrameSizeTable[17][0][2][0] = 576;\n        bitRateAndFrameSizeTable[17][1][2][0] = 576;\n        bitRateAndFrameSizeTable[17][0][2][1] = 1728;\n        bitRateAndFrameSizeTable[17][1][2][1] = 1728;\n        bitRateAndFrameSizeTable[18][0][2][0] = 640;\n        bitRateAndFrameSizeTable[18][1][2][0] = 640;\n        bitRateAndFrameSizeTable[18][0][2][1] = 1920;\n        bitRateAndFrameSizeTable[18][1][2][1] = 1920;\n    }\n}"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/tracks/Amf0Track.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.authoring.tracks;\n\nimport com.coremedia.iso.boxes.*;\nimport com.googlecode.mp4parser.authoring.AbstractTrack;\nimport com.googlecode.mp4parser.authoring.TrackMetaData;\nimport com.googlecode.mp4parser.boxes.adobe.ActionMessageFormat0SampleEntryBox;\n\nimport java.nio.ByteBuffer;\nimport java.util.Collections;\nimport java.util.Date;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.SortedMap;\nimport java.util.TreeMap;\n\npublic class Amf0Track extends AbstractTrack {\n    SortedMap<Long, byte[]> rawSamples = new TreeMap<Long, byte[]>() {\n    };\n    private TrackMetaData trackMetaData = new TrackMetaData();\n\n\n    /**\n     * Creates a new AMF0 track from\n     *\n     * @param rawSamples\n     */\n    public Amf0Track(Map<Long, byte[]> rawSamples) {\n        this.rawSamples = new TreeMap<Long, byte[]>(rawSamples);\n        trackMetaData.setCreationTime(new Date());\n        trackMetaData.setModificationTime(new Date());\n        trackMetaData.setTimescale(1000); // Text tracks use millieseconds\n        trackMetaData.setLanguage(\"eng\");\n    }\n\n    public List<ByteBuffer> getSamples() {\n        LinkedList<ByteBuffer> samples = new LinkedList<ByteBuffer>();\n        for (byte[] bytes : rawSamples.values()) {\n            samples.add(ByteBuffer.wrap(bytes));\n        }\n        return samples;\n    }\n\n    public SampleDescriptionBox getSampleDescriptionBox() {\n        SampleDescriptionBox stsd = new SampleDescriptionBox();\n        ActionMessageFormat0SampleEntryBox amf0 = new ActionMessageFormat0SampleEntryBox();\n        amf0.setDataReferenceIndex(1);\n        stsd.addBox(amf0);\n        return stsd;\n    }\n\n    public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {\n        LinkedList<TimeToSampleBox.Entry> timesToSample = new LinkedList<TimeToSampleBox.Entry>();\n        LinkedList<Long> keys = new LinkedList<Long>(rawSamples.keySet());\n        Collections.sort(keys);\n        long lastTimeStamp = 0;\n        for (Long key : keys) {\n            long delta = key - lastTimeStamp;\n            if (timesToSample.size() > 0 && timesToSample.peek().getDelta() == delta) {\n                timesToSample.peek().setCount(timesToSample.peek().getCount() + 1);\n            } else {\n                timesToSample.add(new TimeToSampleBox.Entry(1, delta));\n            }\n            lastTimeStamp = key;\n        }\n        return timesToSample;\n    }\n\n    public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {\n        // AMF0 tracks do not have Composition Time\n        return null;\n    }\n\n    public long[] getSyncSamples() {\n        // AMF0 tracks do not have Sync Samples\n        return null;\n    }\n\n    public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {\n        // AMF0 tracks do not have Sample Dependencies\n        return null;\n    }\n\n    public TrackMetaData getTrackMetaData() {\n        return trackMetaData;  //To change body of implemented methods use File | Settings | File Templates.\n    }\n\n    public String getHandler() {\n        return \"data\";\n    }\n\n    public AbstractMediaHeaderBox getMediaHeaderBox() {\n        return new NullMediaHeaderBox();\n    }\n\n    public SubSampleInformationBox getSubsampleInformationBox() {\n        return null;\n    }\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/tracks/AppendTrack.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring.tracks;\n\nimport com.coremedia.iso.boxes.*;\nimport com.googlecode.mp4parser.authoring.AbstractTrack;\nimport com.googlecode.mp4parser.authoring.Track;\nimport com.googlecode.mp4parser.authoring.TrackMetaData;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.channels.Channels;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.LinkedList;\nimport java.util.List;\n\n/**\n * Appends two or more <code>Tracks</code> of the same type. No only that the type must be equal\n * also the decoder settings must be the same.\n */\npublic class AppendTrack extends AbstractTrack {\n    Track[] tracks;\n\n    public AppendTrack(Track... tracks) throws IOException {\n        this.tracks = tracks;\n        byte[] referenceSampleDescriptionBox = null;\n        for (Track track : tracks) {\n            ByteArrayOutputStream baos = new ByteArrayOutputStream();\n            track.getSampleDescriptionBox().getBox(Channels.newChannel(baos));\n            if (referenceSampleDescriptionBox == null) {\n                referenceSampleDescriptionBox = baos.toByteArray();\n            } else if (!Arrays.equals(referenceSampleDescriptionBox, baos.toByteArray())) {\n                throw new IOException(\"Cannot append \" + track + \" to \" + tracks[0] + \" since their Sample Description Boxes differ\");\n            }\n        }\n    }\n\n    public List<ByteBuffer> getSamples() {\n        ArrayList<ByteBuffer> lists = new ArrayList<ByteBuffer>();\n\n        for (Track track : tracks) {\n            lists.addAll(track.getSamples());\n        }\n\n        return lists;\n    }\n\n    public SampleDescriptionBox getSampleDescriptionBox() {\n        return tracks[0].getSampleDescriptionBox();\n    }\n\n    public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {\n        if (tracks[0].getDecodingTimeEntries() != null && !tracks[0].getDecodingTimeEntries().isEmpty()) {\n            List<long[]> lists = new LinkedList<long[]>();\n            for (Track track : tracks) {\n                lists.add(TimeToSampleBox.blowupTimeToSamples(track.getDecodingTimeEntries()));\n            }\n\n            LinkedList<TimeToSampleBox.Entry> returnDecodingEntries = new LinkedList<TimeToSampleBox.Entry>();\n            for (long[] list : lists) {\n                for (long nuDecodingTime : list) {\n                    if (returnDecodingEntries.isEmpty() || returnDecodingEntries.getLast().getDelta() != nuDecodingTime) {\n                        TimeToSampleBox.Entry e = new TimeToSampleBox.Entry(1, nuDecodingTime);\n                        returnDecodingEntries.add(e);\n                    } else {\n                        TimeToSampleBox.Entry e = returnDecodingEntries.getLast();\n                        e.setCount(e.getCount() + 1);\n                    }\n                }\n            }\n            return returnDecodingEntries;\n        } else {\n            return null;\n        }\n    }\n\n    public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {\n        if (tracks[0].getCompositionTimeEntries() != null && !tracks[0].getCompositionTimeEntries().isEmpty()) {\n            List<int[]> lists = new LinkedList<int[]>();\n            for (Track track : tracks) {\n                lists.add(CompositionTimeToSample.blowupCompositionTimes(track.getCompositionTimeEntries()));\n            }\n            LinkedList<CompositionTimeToSample.Entry> compositionTimeEntries = new LinkedList<CompositionTimeToSample.Entry>();\n            for (int[] list : lists) {\n                for (int compositionTime : list) {\n                    if (compositionTimeEntries.isEmpty() || compositionTimeEntries.getLast().getOffset() != compositionTime) {\n                        CompositionTimeToSample.Entry e = new CompositionTimeToSample.Entry(1, compositionTime);\n                        compositionTimeEntries.add(e);\n                    } else {\n                        CompositionTimeToSample.Entry e = compositionTimeEntries.getLast();\n                        e.setCount(e.getCount() + 1);\n                    }\n                }\n            }\n            return compositionTimeEntries;\n        } else {\n            return null;\n        }\n    }\n\n    public long[] getSyncSamples() {\n        if (tracks[0].getSyncSamples() != null && tracks[0].getSyncSamples().length > 0) {\n            int numSyncSamples = 0;\n            for (Track track : tracks) {\n                numSyncSamples += track.getSyncSamples().length;\n            }\n            long[] returnSyncSamples = new long[numSyncSamples];\n\n            int pos = 0;\n            long samplesBefore = 0;\n            for (Track track : tracks) {\n                for (long l : track.getSyncSamples()) {\n                    returnSyncSamples[pos++] = samplesBefore + l;\n                }\n                samplesBefore += track.getSamples().size();\n            }\n            return returnSyncSamples;\n        } else {\n            return null;\n        }\n    }\n\n    public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {\n        if (tracks[0].getSampleDependencies() != null && !tracks[0].getSampleDependencies().isEmpty()) {\n            List<SampleDependencyTypeBox.Entry> list = new LinkedList<SampleDependencyTypeBox.Entry>();\n            for (Track track : tracks) {\n                list.addAll(track.getSampleDependencies());\n            }\n            return list;\n        } else {\n            return null;\n        }\n    }\n\n    public TrackMetaData getTrackMetaData() {\n        return tracks[0].getTrackMetaData();\n    }\n\n    public String getHandler() {\n        return tracks[0].getHandler();\n    }\n\n    public AbstractMediaHeaderBox getMediaHeaderBox() {\n        return tracks[0].getMediaHeaderBox();\n    }\n\n    public SubSampleInformationBox getSubsampleInformationBox() {\n        return tracks[0].getSubsampleInformationBox();\n    }\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/tracks/ChangeTimeScaleTrack.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring.tracks;\n\nimport static java.lang.Math.round;\n\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.LinkedList;\nimport java.util.List;\n\nimport com.coremedia.iso.boxes.AbstractMediaHeaderBox;\nimport com.coremedia.iso.boxes.CompositionTimeToSample;\nimport com.coremedia.iso.boxes.SampleDependencyTypeBox;\nimport com.coremedia.iso.boxes.SampleDescriptionBox;\nimport com.coremedia.iso.boxes.SubSampleInformationBox;\nimport com.coremedia.iso.boxes.TimeToSampleBox;\nimport com.googlecode.mp4parser.authoring.Track;\nimport com.googlecode.mp4parser.authoring.TrackMetaData;\n\n/**\n * Changes the timescale of a track by wrapping the track.\n */\npublic class ChangeTimeScaleTrack implements Track {\n    Track source;\n    List<CompositionTimeToSample.Entry> ctts;\n    List<TimeToSampleBox.Entry> tts;\n    long timeScale;\n\n    /**\n     * Changes the time scale of the source track to the target time scale and makes sure\n     * that any rounding errors that may have summed are corrected exactly before the syncSamples.\n     *\n     * @param source          the source track\n     * @param targetTimeScale the resulting time scale of this track.\n     * @param syncSamples     at these sync points where rounding error are corrected.\n     */\n    public ChangeTimeScaleTrack(Track source, long targetTimeScale, long[] syncSamples) {\n        this.source = source;\n        this.timeScale = targetTimeScale;\n        double timeScaleFactor = (double) targetTimeScale / source.getTrackMetaData().getTimescale();\n        ctts = adjustCtts(source.getCompositionTimeEntries(), timeScaleFactor);\n        tts = adjustTts(source.getDecodingTimeEntries(), timeScaleFactor, syncSamples);\n    }\n\n    public SampleDescriptionBox getSampleDescriptionBox() {\n        return source.getSampleDescriptionBox();\n    }\n\n    public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {\n        return tts;\n    }\n\n    public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {\n        return ctts;\n    }\n\n    public long[] getSyncSamples() {\n        return source.getSyncSamples();\n    }\n\n    public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {\n        return source.getSampleDependencies();\n    }\n\n    public TrackMetaData getTrackMetaData() {\n        TrackMetaData trackMetaData = (TrackMetaData) source.getTrackMetaData().clone();\n        trackMetaData.setTimescale(timeScale);\n        return trackMetaData;\n    }\n\n    public String getHandler() {\n        return source.getHandler();\n    }\n\n    public boolean isEnabled() {\n        return source.isEnabled();\n    }\n\n    public boolean isInMovie() {\n        return source.isInMovie();\n    }\n\n    public boolean isInPreview() {\n        return source.isInPreview();\n    }\n\n    public boolean isInPoster() {\n        return source.isInPoster();\n    }\n\n    public List<ByteBuffer> getSamples() {\n        return source.getSamples();\n    }\n\n\n    /**\n     * Adjusting the composition times is easy. Just scale it by the factor - that's it. There is no rounding\n     * error summing up.\n     *\n     * @param source\n     * @param timeScaleFactor\n     * @return\n     */\n    static List<CompositionTimeToSample.Entry> adjustCtts(List<CompositionTimeToSample.Entry> source, double timeScaleFactor) {\n        if (source != null) {\n            List<CompositionTimeToSample.Entry> entries2 = new ArrayList<CompositionTimeToSample.Entry>(source.size());\n            for (CompositionTimeToSample.Entry entry : source) {\n                entries2.add(new CompositionTimeToSample.Entry(entry.getCount(), (int) Math.round(timeScaleFactor * entry.getOffset())));\n            }\n            return entries2;\n        } else {\n            return null;\n        }\n    }\n\n    static List<TimeToSampleBox.Entry> adjustTts(List<TimeToSampleBox.Entry> source, double timeScaleFactor, long[] syncSample) {\n        double deviation = 0;\n        long[] sourceArray = TimeToSampleBox.blowupTimeToSamples(source);\n        LinkedList<TimeToSampleBox.Entry> entries2 = new LinkedList<TimeToSampleBox.Entry>();\n        for (int i = 0; i < sourceArray.length; i++) {\n            long duration = sourceArray[i];\n            double d = timeScaleFactor * duration;\n            long x = round(d);\n            deviation += d - x;\n            TimeToSampleBox.Entry last = entries2.getLast();\n            if (Arrays.binarySearch(syncSample, i + 1) >= 0) {\n                // apply correction here!\n                if (Math.abs(deviation) >= 1) {\n                    //System.err.println(\"Sample \" + i + \" corrected by adding + \" + Math.round(deviation) );\n                    x += Math.round(deviation);\n                    deviation = deviation - Math.round(deviation); // there is a rest!\n\n                }\n            }\n            if (last == null) {\n                entries2.add(new TimeToSampleBox.Entry(1, x));\n            } else if (last.getDelta() != x) {\n                entries2.add(new TimeToSampleBox.Entry(1, x));\n            } else {\n                last.setCount(last.getCount() + 1);\n            }\n\n        }\n        return entries2;\n    }\n\n    public AbstractMediaHeaderBox getMediaHeaderBox() {\n        return source.getMediaHeaderBox();\n    }\n\n    public SubSampleInformationBox getSubsampleInformationBox() {\n        return source.getSubsampleInformationBox();\n    }\n\n    @Override\n    public String toString() {\n        return \"ChangeTimeScaleTrack{\" +\n                \"source=\" + source +\n                '}';\n    }\n}"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/tracks/CroppedTrack.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring.tracks;\n\nimport com.coremedia.iso.boxes.*;\nimport com.googlecode.mp4parser.authoring.AbstractTrack;\nimport com.googlecode.mp4parser.authoring.Track;\nimport com.googlecode.mp4parser.authoring.TrackMetaData;\n\nimport java.nio.ByteBuffer;\nimport java.util.LinkedList;\nimport java.util.List;\n\n/**\n * Generates a Track that starts at fromSample and ends at toSample (exclusive). The user of this class\n * has to make sure that the fromSample is a random access sample.\n * <ul>\n * <li>In AAC this is every single sample</li>\n * <li>In H264 this is every sample that is marked in the SyncSampleBox</li>\n * </ul>\n */\npublic class CroppedTrack extends AbstractTrack {\n    Track origTrack;\n    private int fromSample;\n    private int toSample;\n    private long[] syncSampleArray;\n\n    public CroppedTrack(Track origTrack, long fromSample, long toSample) {\n        this.origTrack = origTrack;\n        assert fromSample <= Integer.MAX_VALUE;\n        assert toSample <= Integer.MAX_VALUE;\n        this.fromSample = (int) fromSample;\n        this.toSample = (int) toSample;\n    }\n\n    public List<ByteBuffer> getSamples() {\n        return origTrack.getSamples().subList(fromSample, toSample);\n    }\n\n    public SampleDescriptionBox getSampleDescriptionBox() {\n        return origTrack.getSampleDescriptionBox();\n    }\n\n    public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {\n        if (origTrack.getDecodingTimeEntries() != null && !origTrack.getDecodingTimeEntries().isEmpty()) {\n            long[] decodingTimes = TimeToSampleBox.blowupTimeToSamples(origTrack.getDecodingTimeEntries());\n            long[] nuDecodingTimes = new long[toSample - fromSample];\n            System.arraycopy(decodingTimes, fromSample, nuDecodingTimes, 0, toSample - fromSample);\n\n            LinkedList<TimeToSampleBox.Entry> returnDecodingEntries = new LinkedList<TimeToSampleBox.Entry>();\n\n            for (long nuDecodingTime : nuDecodingTimes) {\n                if (returnDecodingEntries.isEmpty() || returnDecodingEntries.getLast().getDelta() != nuDecodingTime) {\n                    TimeToSampleBox.Entry e = new TimeToSampleBox.Entry(1, nuDecodingTime);\n                    returnDecodingEntries.add(e);\n                } else {\n                    TimeToSampleBox.Entry e = returnDecodingEntries.getLast();\n                    e.setCount(e.getCount() + 1);\n                }\n            }\n            return returnDecodingEntries;\n        } else {\n            return null;\n        }\n    }\n\n    public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {\n        if (origTrack.getCompositionTimeEntries() != null && !origTrack.getCompositionTimeEntries().isEmpty()) {\n            int[] compositionTime = CompositionTimeToSample.blowupCompositionTimes(origTrack.getCompositionTimeEntries());\n            int[] nuCompositionTimes = new int[toSample - fromSample];\n            System.arraycopy(compositionTime, fromSample, nuCompositionTimes, 0, toSample - fromSample);\n\n            LinkedList<CompositionTimeToSample.Entry> returnDecodingEntries = new LinkedList<CompositionTimeToSample.Entry>();\n\n            for (int nuDecodingTime : nuCompositionTimes) {\n                if (returnDecodingEntries.isEmpty() || returnDecodingEntries.getLast().getOffset() != nuDecodingTime) {\n                    CompositionTimeToSample.Entry e = new CompositionTimeToSample.Entry(1, nuDecodingTime);\n                    returnDecodingEntries.add(e);\n                } else {\n                    CompositionTimeToSample.Entry e = returnDecodingEntries.getLast();\n                    e.setCount(e.getCount() + 1);\n                }\n            }\n            return returnDecodingEntries;\n        } else {\n            return null;\n        }\n    }\n\n    synchronized public long[] getSyncSamples() {\n        if (this.syncSampleArray == null) {\n            if (origTrack.getSyncSamples() != null && origTrack.getSyncSamples().length > 0) {\n                List<Long> syncSamples = new LinkedList<Long>();\n                for (long l : origTrack.getSyncSamples()) {\n                    if (l >= fromSample && l < toSample) {\n                        syncSamples.add(l - fromSample);\n                    }\n                }\n                syncSampleArray = new long[syncSamples.size()];\n                for (int i = 0; i < syncSampleArray.length; i++) {\n                    syncSampleArray[i] = syncSamples.get(i);\n\n                }\n                return syncSampleArray;\n            } else {\n                return null;\n            }\n        } else {\n            return this.syncSampleArray;\n        }\n    }\n\n    public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {\n        if (origTrack.getSampleDependencies() != null && !origTrack.getSampleDependencies().isEmpty()) {\n            return origTrack.getSampleDependencies().subList(fromSample, toSample);\n        } else {\n            return null;\n        }\n    }\n\n    public TrackMetaData getTrackMetaData() {\n        return origTrack.getTrackMetaData();\n    }\n\n    public String getHandler() {\n        return origTrack.getHandler();\n    }\n\n    public AbstractMediaHeaderBox getMediaHeaderBox() {\n        return origTrack.getMediaHeaderBox();\n    }\n\n    public SubSampleInformationBox getSubsampleInformationBox() {\n        return origTrack.getSubsampleInformationBox();\n    }\n\n}"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/tracks/DivideTimeScaleTrack.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring.tracks;\n\nimport com.coremedia.iso.boxes.AbstractMediaHeaderBox;\nimport com.coremedia.iso.boxes.CompositionTimeToSample;\nimport com.coremedia.iso.boxes.SampleDependencyTypeBox;\nimport com.coremedia.iso.boxes.SampleDescriptionBox;\nimport com.coremedia.iso.boxes.SubSampleInformationBox;\nimport com.coremedia.iso.boxes.TimeToSampleBox;\nimport com.googlecode.mp4parser.authoring.Track;\nimport com.googlecode.mp4parser.authoring.TrackMetaData;\n\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.LinkedList;\nimport java.util.List;\n\n/**\n * Changes the timescale of a track by wrapping the track.\n */\npublic class DivideTimeScaleTrack implements Track {\n    Track source;\n    private int timeScaleDivisor;\n\n    public DivideTimeScaleTrack(Track source, int timeScaleDivisor) {\n        this.source = source;\n        this.timeScaleDivisor = timeScaleDivisor;\n    }\n\n    public SampleDescriptionBox getSampleDescriptionBox() {\n        return source.getSampleDescriptionBox();\n    }\n\n    public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {\n        return adjustTts();\n    }\n\n    public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {\n        return adjustCtts();\n    }\n\n    public long[] getSyncSamples() {\n        return source.getSyncSamples();\n    }\n\n    public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {\n        return source.getSampleDependencies();\n    }\n\n    public TrackMetaData getTrackMetaData() {\n        TrackMetaData trackMetaData = (TrackMetaData) source.getTrackMetaData().clone();\n        trackMetaData.setTimescale(source.getTrackMetaData().getTimescale() / this.timeScaleDivisor);\n        return trackMetaData;\n    }\n\n    public String getHandler() {\n        return source.getHandler();\n    }\n\n    public boolean isEnabled() {\n        return source.isEnabled();\n    }\n\n    public boolean isInMovie() {\n        return source.isInMovie();\n    }\n\n    public boolean isInPreview() {\n        return source.isInPreview();\n    }\n\n    public boolean isInPoster() {\n        return source.isInPoster();\n    }\n\n    public List<ByteBuffer> getSamples() {\n        return source.getSamples();\n    }\n\n\n    List<CompositionTimeToSample.Entry> adjustCtts() {\n        List<CompositionTimeToSample.Entry> origCtts = this.source.getCompositionTimeEntries();\n        if (origCtts != null) {\n            List<CompositionTimeToSample.Entry> entries2 = new ArrayList<CompositionTimeToSample.Entry>(origCtts.size());\n            for (CompositionTimeToSample.Entry entry : origCtts) {\n                entries2.add(new CompositionTimeToSample.Entry(entry.getCount(), entry.getOffset() / timeScaleDivisor));\n            }\n            return entries2;\n        } else {\n            return null;\n        }\n    }\n\n    List<TimeToSampleBox.Entry> adjustTts() {\n        List<TimeToSampleBox.Entry> origTts = source.getDecodingTimeEntries();\n        LinkedList<TimeToSampleBox.Entry> entries2 = new LinkedList<TimeToSampleBox.Entry>();\n        for (TimeToSampleBox.Entry e : origTts) {\n            entries2.add(new TimeToSampleBox.Entry(e.getCount(), e.getDelta() / timeScaleDivisor));\n        }\n        return entries2;\n    }\n\n    public AbstractMediaHeaderBox getMediaHeaderBox() {\n        return source.getMediaHeaderBox();\n    }\n\n    public SubSampleInformationBox getSubsampleInformationBox() {\n        return source.getSubsampleInformationBox();\n    }\n\n    @Override\n    public String toString() {\n        return \"MultiplyTimeScaleTrack{\" +\n                \"source=\" + source +\n                '}';\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/tracks/EC3TrackImpl.java",
    "content": "package com.googlecode.mp4parser.authoring.tracks;\n\nimport com.coremedia.iso.boxes.*;\nimport com.coremedia.iso.boxes.sampleentry.AudioSampleEntry;\nimport com.googlecode.mp4parser.authoring.AbstractTrack;\nimport com.googlecode.mp4parser.authoring.TrackMetaData;\nimport com.googlecode.mp4parser.boxes.AC3SpecificBox;\nimport com.googlecode.mp4parser.boxes.EC3SpecificBox;\nimport com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitReaderBuffer;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.ByteBuffer;\nimport java.util.Date;\nimport java.util.LinkedList;\nimport java.util.List;\n\n/**\n * Created by IntelliJ IDEA.\n * User: magnus\n * Date: 2012-03-14\n * Time: 10:39\n * To change this template use File | Settings | File Templates.\n */\npublic class EC3TrackImpl extends AbstractTrack {\n    TrackMetaData trackMetaData = new TrackMetaData();\n    SampleDescriptionBox sampleDescriptionBox;\n\n    int samplerate;\n    int bitrate;\n    int frameSize;\n\n    List<BitStreamInfo> entries = new LinkedList<BitStreamInfo>();\n\n    private InputStream inputStream;\n    private List<ByteBuffer> samples;\n    List<TimeToSampleBox.Entry> stts = new LinkedList<TimeToSampleBox.Entry>();\n\n    public EC3TrackImpl(InputStream fin) throws IOException {\n        inputStream = fin;\n\n        boolean done = false;\n        while (!done) {\n            BitStreamInfo bsi = readVariables();\n            if (bsi == null) {\n                throw new IOException();\n            }\n            for (int i = 0; i < entries.size(); i++) {\n                if (bsi.strmtyp != 1 && entries.get(i).substreamid == bsi.substreamid) {\n                    done = true;\n                }\n            }\n            if (!done) {\n                entries.add(bsi);\n                inputStream.skip(bsi.frameSize);\n            }\n        }\n        for (BitStreamInfo bsi : entries) {\n            inputStream.skip(-1 * bsi.frameSize);\n        }\n\n        if (entries.size() == 0) {\n            throw new IOException();\n        }\n        samplerate = entries.get(0).samplerate;\n\n        sampleDescriptionBox = new SampleDescriptionBox();\n        AudioSampleEntry audioSampleEntry = new AudioSampleEntry(\"ec-3\");\n        audioSampleEntry.setChannelCount(2);\n        audioSampleEntry.setSampleRate(samplerate);\n        audioSampleEntry.setDataReferenceIndex(1);\n        audioSampleEntry.setSampleSize(16);\n\n        EC3SpecificBox ec3 = new EC3SpecificBox();\n        int[] deps = new int[entries.size()];\n        int[] chan_locs = new int[entries.size()];\n        for (BitStreamInfo bsi : entries) {\n            if (bsi.strmtyp == 1) {\n                deps[bsi.substreamid]++;\n                chan_locs[bsi.substreamid] = ((bsi.chanmap >> 6) & 0x100) | ((bsi.chanmap >> 5) & 0xff);\n            }\n        }\n        for (BitStreamInfo bsi : entries) {\n            if (bsi.strmtyp != 1) {\n                EC3SpecificBox.Entry e = new EC3SpecificBox.Entry();\n                e.fscod = bsi.fscod;\n                e.bsid = bsi.bsid;\n                e.bsmod = bsi.bsmod;\n                e.acmod = bsi.acmod;\n                e.lfeon = bsi.lfeon;\n                e.reserved = 0;\n                e.num_dep_sub = deps[bsi.substreamid];\n                e.chan_loc = chan_locs[bsi.substreamid];\n                e.reserved2 = 0;\n                ec3.addEntry(e);\n            }\n            bitrate += bsi.bitrate;\n            frameSize += bsi.frameSize;\n        }\n\n        ec3.setDataRate(bitrate / 1000);\n        audioSampleEntry.addBox(ec3);\n        sampleDescriptionBox.addBox(audioSampleEntry);\n\n        trackMetaData.setCreationTime(new Date());\n        trackMetaData.setModificationTime(new Date());\n        trackMetaData.setLanguage(\"eng\");\n        trackMetaData.setTimescale(samplerate); // Audio tracks always use samplerate as timescale\n\n        samples = new LinkedList<ByteBuffer>();\n        if (!readSamples()) {\n            throw new IOException();\n        }\n    }\n\n\n    public List<ByteBuffer> getSamples() {\n\n        return samples;\n    }\n\n    public SampleDescriptionBox getSampleDescriptionBox() {\n        return sampleDescriptionBox;\n    }\n\n    public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {\n        return stts;\n    }\n\n    public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {\n        return null;\n    }\n\n    public long[] getSyncSamples() {\n        return null;\n    }\n\n    public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {\n        return null;\n    }\n\n    public TrackMetaData getTrackMetaData() {\n        return trackMetaData;\n    }\n\n    public String getHandler() {\n        return \"soun\";\n    }\n\n    public AbstractMediaHeaderBox getMediaHeaderBox() {\n        return new SoundMediaHeaderBox();\n    }\n\n    public SubSampleInformationBox getSubsampleInformationBox() {\n        return null;\n    }\n\n    private BitStreamInfo readVariables() throws IOException {\n        byte[] data = new byte[200];\n        if (200 != inputStream.read(data, 0, 200)) {\n            return null;\n        }\n        inputStream.skip(-200); // Rewind\n        ByteBuffer bb = ByteBuffer.wrap(data);\n        BitReaderBuffer brb = new BitReaderBuffer(bb);\n        int syncword = brb.readBits(16);\n        if (syncword != 0xb77) {\n            return null;\n        }\n\n        BitStreamInfo entry = new BitStreamInfo();\n\n        entry.strmtyp = brb.readBits(2);\n        entry.substreamid = brb.readBits(3);\n        int frmsiz = brb.readBits(11);\n        entry.frameSize = 2 * (frmsiz + 1);\n\n        entry.fscod = brb.readBits(2);\n        int fscod2 = -1;\n        int numblkscod;\n        if (entry.fscod == 3) {\n            fscod2 = brb.readBits(2);\n            numblkscod = 3;\n        } else {\n            numblkscod = brb.readBits(2);\n        }\n        int numberOfBlocksPerSyncFrame = 0;\n        switch (numblkscod) {\n            case 0:\n                numberOfBlocksPerSyncFrame = 1;\n                break;\n\n            case 1:\n                numberOfBlocksPerSyncFrame = 2;\n                break;\n\n            case 2:\n                numberOfBlocksPerSyncFrame = 3;\n                break;\n\n            case 3:\n                numberOfBlocksPerSyncFrame = 6;\n                break;\n\n        }\n        entry.frameSize *= (6 / numberOfBlocksPerSyncFrame); // Not sure if this is the correct algorithm?\n\n        entry.acmod = brb.readBits(3);\n        entry.lfeon = brb.readBits(1);\n        entry.bsid = brb.readBits(5);\n        brb.readBits(5);\n        if (1 == brb.readBits(1)) {\n            brb.readBits(8); // compr\n        }\n        if (0 == entry.acmod) {\n            brb.readBits(5);\n            if (1 == brb.readBits(1)) {\n                brb.readBits(8);\n            }\n        }\n        if (1 == entry.strmtyp) {\n            if (1 == brb.readBits(1)) {\n                entry.chanmap = brb.readBits(16);\n            }\n        }\n        if (1 == brb.readBits(1)) {     // mixing metadata\n            if (entry.acmod > 2) {\n                brb.readBits(2);\n            }\n            if (1 == (entry.acmod & 1) && entry.acmod > 2) {\n                brb.readBits(3);\n                brb.readBits(3);\n            }\n            if (0 < (entry.acmod & 4)) {\n                brb.readBits(3);\n                brb.readBits(3);\n            }\n            if (1 == entry.lfeon) {\n                if (1 == brb.readBits(1)) {\n                    brb.readBits(5);\n                }\n            }\n            if (0 == entry.strmtyp) {\n                if (1 == brb.readBits(1)) {\n                    brb.readBits(6);\n                }\n                if (0 == entry.acmod) {\n                    if (1 == brb.readBits(1)) {\n                        brb.readBits(6);\n                    }\n                }\n                if (1 == brb.readBits(1)) {\n                    brb.readBits(6);\n                }\n                int mixdef = brb.readBits(2);\n                if (1 == mixdef) {\n                    brb.readBits(5);\n                } else if (2 == mixdef) {\n                    brb.readBits(12);\n                } else if (3 == mixdef) {\n                    int mixdeflen = brb.readBits(5);\n                    if (1 == brb.readBits(1)) {\n                        brb.readBits(5);\n                        if (1 == brb.readBits(1)) {\n                            brb.readBits(4);\n                        }\n                        if (1 == brb.readBits(1)) {\n                            brb.readBits(4);\n                        }\n                        if (1 == brb.readBits(1)) {\n                            brb.readBits(4);\n                        }\n                        if (1 == brb.readBits(1)) {\n                            brb.readBits(4);\n                        }\n                        if (1 == brb.readBits(1)) {\n                            brb.readBits(4);\n                        }\n                        if (1 == brb.readBits(1)) {\n                            brb.readBits(4);\n                        }\n                        if (1 == brb.readBits(1)) {\n                            brb.readBits(4);\n                        }\n                        if (1 == brb.readBits(1)) {\n                            if (1 == brb.readBits(1)) {\n                                brb.readBits(4);\n                            }\n                            if (1 == brb.readBits(1)) {\n                                brb.readBits(4);\n                            }\n                        }\n                    }\n                    if (1 == brb.readBits(1)) {\n                        brb.readBits(5);\n                        if (1 == brb.readBits(1)) {\n                            brb.readBits(7);\n                            if (1 == brb.readBits(1)) {\n                                brb.readBits(8);\n                            }\n                        }\n                    }\n                    for (int i = 0; i < (mixdeflen + 2); i++) {\n                        brb.readBits(8);\n                    }\n                    brb.byteSync();\n                }\n                if (entry.acmod < 2) {\n                    if (1 == brb.readBits(1)) {\n                        brb.readBits(14);\n                    }\n                    if (0 == entry.acmod) {\n                        if (1 == brb.readBits(1)) {\n                            brb.readBits(14);\n                        }\n                    }\n                    if (1 == brb.readBits(1)) {\n                        if (numblkscod == 0) {\n                            brb.readBits(5);\n                        } else {\n                            for (int i = 0; i < numberOfBlocksPerSyncFrame; i++) {\n                                if (1 == brb.readBits(1)) {\n                                    brb.readBits(5);\n                                }\n                            }\n                        }\n\n                    }\n                }\n            }\n        }\n        if (1 == brb.readBits(1)) { // infomdate\n            entry.bsmod = brb.readBits(3);\n        }\n\n        switch (entry.fscod) {\n            case 0:\n                entry.samplerate = 48000;\n                break;\n\n            case 1:\n                entry.samplerate = 44100;\n                break;\n\n            case 2:\n                entry.samplerate = 32000;\n                break;\n\n            case 3: {\n                switch (fscod2) {\n                    case 0:\n                        entry.samplerate = 24000;\n                        break;\n\n                    case 1:\n                        entry.samplerate = 22050;\n                        break;\n\n                    case 2:\n                        entry.samplerate = 16000;\n                        break;\n\n                    case 3:\n                        entry.samplerate = 0;\n                        break;\n                }\n                break;\n            }\n\n        }\n        if (entry.samplerate == 0) {\n            return null;\n        }\n\n        entry.bitrate = (int) (((double) entry.samplerate) / 1536.0 * entry.frameSize * 8);\n\n        return entry;\n    }\n\n    private boolean readSamples() throws IOException {\n        int read = frameSize;\n        boolean ret = false;\n        while (frameSize == read) {\n            ret = true;\n            byte[] data = new byte[frameSize];\n            read = inputStream.read(data);\n            if (read == frameSize) {\n                samples.add(ByteBuffer.wrap(data));\n                stts.add(new TimeToSampleBox.Entry(1, 1536));\n            }\n        }\n        return ret;\n    }\n\n    public static class BitStreamInfo extends EC3SpecificBox.Entry {\n        public int frameSize;\n        public int substreamid;\n        public int bitrate;\n        public int samplerate;\n        public int strmtyp;\n        public int chanmap;\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/tracks/H264TrackImpl.java",
    "content": "package com.googlecode.mp4parser.authoring.tracks;\n\nimport com.coremedia.iso.boxes.AbstractMediaHeaderBox;\nimport com.coremedia.iso.boxes.CompositionTimeToSample;\nimport com.coremedia.iso.boxes.SampleDependencyTypeBox;\nimport com.coremedia.iso.boxes.SampleDescriptionBox;\nimport com.coremedia.iso.boxes.SubSampleInformationBox;\nimport com.coremedia.iso.boxes.TimeToSampleBox;\nimport com.coremedia.iso.boxes.VideoMediaHeaderBox;\nimport com.coremedia.iso.boxes.h264.AvcConfigurationBox;\nimport com.coremedia.iso.boxes.sampleentry.VisualSampleEntry;\nimport com.googlecode.mp4parser.authoring.AbstractTrack;\nimport com.googlecode.mp4parser.authoring.TrackMetaData;\nimport com.googlecode.mp4parser.h264.model.PictureParameterSet;\nimport com.googlecode.mp4parser.h264.model.SeqParameterSet;\nimport com.googlecode.mp4parser.h264.read.CAVLCReader;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.Date;\nimport java.util.LinkedList;\nimport java.util.List;\n\n/**\n * The <code>H264TrackImpl</code> creates a <code>Track</code> from an H.264\n * Annex B file.\n */\npublic class H264TrackImpl extends AbstractTrack {\n    TrackMetaData trackMetaData = new TrackMetaData();\n    SampleDescriptionBox sampleDescriptionBox;\n\n    private ReaderWrapper reader;\n    private List<ByteBuffer> samples;\n    boolean readSamples = false;\n\n    List<TimeToSampleBox.Entry> stts;\n    List<CompositionTimeToSample.Entry> ctts;\n    List<SampleDependencyTypeBox.Entry> sdtp;\n    List<Integer> stss;\n\n    SeqParameterSet seqParameterSet = null;\n    PictureParameterSet pictureParameterSet = null;\n    LinkedList<byte[]> seqParameterSetList = new LinkedList<byte[]>();\n    LinkedList<byte[]> pictureParameterSetList = new LinkedList<byte[]>();\n\n    private int width;\n    private int height;\n    private int timescale;\n    private int frametick;\n\n    private SEIMessage seiMessage;\n    int frameNrInGop = 0;\n\n    public H264TrackImpl(InputStream inputStream) throws IOException {\n        this.reader = new ReaderWrapper(inputStream);\n        stts = new LinkedList<TimeToSampleBox.Entry>();\n        ctts = new LinkedList<CompositionTimeToSample.Entry>();\n        sdtp = new LinkedList<SampleDependencyTypeBox.Entry>();\n        stss = new LinkedList<Integer>();\n\n        samples = new LinkedList<ByteBuffer>();\n        if (!readSamples()) {\n            throw new IOException();\n        }\n\n        if (!readVariables()) {\n            throw new IOException();\n        }\n\n        sampleDescriptionBox = new SampleDescriptionBox();\n        VisualSampleEntry visualSampleEntry = new VisualSampleEntry(\"avc1\");\n        visualSampleEntry.setDataReferenceIndex(1);\n        visualSampleEntry.setDepth(24);\n        visualSampleEntry.setFrameCount(1);\n        visualSampleEntry.setHorizresolution(72);\n        visualSampleEntry.setVertresolution(72);\n        visualSampleEntry.setWidth(width);\n        visualSampleEntry.setHeight(height);\n        visualSampleEntry.setCompressorname(\"AVC Coding\");\n\n        AvcConfigurationBox avcConfigurationBox = new AvcConfigurationBox();\n\n        avcConfigurationBox.setSequenceParameterSets(seqParameterSetList);\n        avcConfigurationBox.setPictureParameterSets(pictureParameterSetList);\n        avcConfigurationBox.setAvcLevelIndication(seqParameterSet.level_idc);\n        avcConfigurationBox.setAvcProfileIndicaation(seqParameterSet.profile_idc);\n        avcConfigurationBox.setBitDepthLumaMinus8(seqParameterSet.bit_depth_luma_minus8);\n        avcConfigurationBox.setBitDepthChromaMinus8(seqParameterSet.bit_depth_chroma_minus8);\n        avcConfigurationBox.setChromaFormat(seqParameterSet.chroma_format_idc.getId());\n        avcConfigurationBox.setConfigurationVersion(1);\n        avcConfigurationBox.setLengthSizeMinusOne(3);\n        avcConfigurationBox.setProfileCompatibility(seqParameterSetList.get(0)[1]);\n\n        visualSampleEntry.addBox(avcConfigurationBox);\n        sampleDescriptionBox.addBox(visualSampleEntry);\n\n        trackMetaData.setCreationTime(new Date());\n        trackMetaData.setModificationTime(new Date());\n        trackMetaData.setLanguage(\"eng\");\n        trackMetaData.setTimescale(timescale); // Audio tracks always use samplerate as timescale\n        trackMetaData.setWidth(width);\n        trackMetaData.setHeight(height);\n    }\n\n    public SampleDescriptionBox getSampleDescriptionBox() {\n        return sampleDescriptionBox;\n    }\n\n    public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {\n        return stts;  //To change body of implemented methods use File | Settings | File Templates.\n    }\n\n    public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {\n        return ctts;\n    }\n\n    public long[] getSyncSamples() {\n        long[] returns = new long[stss.size()];\n        for (int i = 0; i < stss.size(); i++) {\n            returns[i] = stss.get(i);\n        }\n        return returns;\n    }\n\n    public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {\n        return sdtp;\n    }\n\n    public TrackMetaData getTrackMetaData() {\n        return trackMetaData;\n    }\n\n    public String getHandler() {\n        return \"vide\";\n    }\n\n    public List<ByteBuffer> getSamples() {\n        return samples;\n    }\n\n    public AbstractMediaHeaderBox getMediaHeaderBox() {\n        return new VideoMediaHeaderBox();\n    }\n\n    public SubSampleInformationBox getSubsampleInformationBox() {\n        return null;\n    }\n\n    private boolean readVariables() {\n        width = (seqParameterSet.pic_width_in_mbs_minus1 + 1) * 16;\n        int mult = 2;\n        if (seqParameterSet.frame_mbs_only_flag) {\n            mult = 1;\n        }\n        height = 16 * (seqParameterSet.pic_height_in_map_units_minus1 + 1) * mult;\n        if (seqParameterSet.frame_cropping_flag) {\n            int chromaArrayType = 0;\n            if (seqParameterSet.residual_color_transform_flag == false) {\n                chromaArrayType = seqParameterSet.chroma_format_idc.getId();\n            }\n            int cropUnitX = 1;\n            int cropUnitY = mult;\n            if (chromaArrayType != 0) {\n                cropUnitX = seqParameterSet.chroma_format_idc.getSubWidth();\n                cropUnitY = seqParameterSet.chroma_format_idc.getSubHeight() * mult;\n            }\n\n            width -= cropUnitX * (seqParameterSet.frame_crop_left_offset + seqParameterSet.frame_crop_right_offset);\n            height -= cropUnitY * (seqParameterSet.frame_crop_top_offset + seqParameterSet.frame_crop_bottom_offset);\n        }\n        return true;\n    }\n\n    private boolean findNextStartcode() throws IOException {\n        byte[] test = new byte[4];\n        while (4 == reader.read(test)) {\n            if (test[0] == 0 && test[1] == 0 && test[2] == 0 && test[3] == 1) {\n                return true;\n            }\n            reader.rewind(3);\n        }\n        return false;\n    }\n\n    private enum NALActions {\n        IGNORE, BUFFER, STORE, END\n    }\n\n    private boolean readSamples() throws IOException {\n        if (readSamples) {\n            return true;\n        }\n\n        readSamples = true;\n\n        long pos = reader.getPos();\n        findNextStartcode();\n\n        ArrayList<byte[]> buffered = new ArrayList<byte[]>();\n\n        int frameNr = 0;\n\n        while (findNextStartcode()) {\n            long newpos = reader.getPos() - 4;\n            int size = (int) (newpos - pos);\n            reader.rewind(size);\n            byte[] data = new byte[size - 4];\n            reader.read(data);\n            int type = data[0];\n            int nal_ref_idc = (type >> 5) & 3;\n            int nal_unit_type = type & 0x1f;\n            System.out.println(\"Found startcode at \" + pos + \" Type: \" + nal_unit_type + \" ref idc: \" + nal_ref_idc + \" (size \" + size + \")\");\n            NALActions action = handleNALUnit(nal_ref_idc, nal_unit_type, data);\n            switch (action) {\n                case IGNORE:\n                    break;\n\n                case BUFFER:\n                    buffered.add(data);\n                    break;\n\n                case STORE:\n                    int stdpValue = 22;\n                    frameNr++;\n                    buffered.add(data);\n                    ByteBuffer bb = createSample(buffered);\n                    boolean IdrPicFlag = false;\n                    if (nal_unit_type == 5) {\n                        stdpValue += 16;\n                        IdrPicFlag = true;\n                    }\n                    ByteArrayInputStream bs = cleanBuffer(buffered.get(buffered.size() - 1));\n                    SliceHeader sh = new SliceHeader(bs, seqParameterSet, pictureParameterSet, IdrPicFlag);\n                    if (sh.slice_type == SliceHeader.SliceType.B) {\n                        stdpValue += 4;\n                    }\n                    System.out.println(\"Adding sample with size \" + bb.capacity() + \" and header \" + sh);\n                    buffered.clear();\n                    samples.add(bb);\n                    stts.add(new TimeToSampleBox.Entry(1, frametick));\n                    if (nal_unit_type == 5) { // IDR Picture\n                        stss.add(frameNr);\n                    }\n                    if (seiMessage.n_frames == 0) {\n                        frameNrInGop = 0;\n                    }\n                    int offset = 0;\n                    if (seiMessage.clock_timestamp_flag) {\n                        offset = seiMessage.n_frames - frameNrInGop;\n                    } else if (seiMessage.removal_delay_flag) {\n                        offset = seiMessage.dpb_removal_delay / 2;\n                    }\n                    ctts.add(new CompositionTimeToSample.Entry(1, offset * frametick));\n                    sdtp.add(new SampleDependencyTypeBox.Entry(stdpValue));\n                    frameNrInGop++;\n                    break;\n\n                case END:\n                    return true;\n\n\n            }\n            pos = newpos;\n            reader.seek(4);\n        }\n        return true;\n    }\n\n    private ByteBuffer createSample(List<byte[]> buffers) {\n        int outsize = 0;\n        for (int i = 0; i < buffers.size(); i++) {\n            outsize += buffers.get(i).length + 4;\n        }\n        byte[] output = new byte[outsize];\n\n        ByteBuffer bb = ByteBuffer.wrap(output);\n        for (int i = 0; i < buffers.size(); i++) {\n            bb.putInt(buffers.get(i).length);\n            bb.put(buffers.get(i));\n        }\n        bb.rewind();\n        return bb;\n    }\n\n    private ByteArrayInputStream cleanBuffer(byte[] data) {\n        byte[] output = new byte[data.length];\n        int inPos = 0;\n        int outPos = 0;\n        while (inPos < data.length) {\n            if (data[inPos] == 0 && data[inPos + 1] == 0 && data[inPos + 2] == 3) {\n                output[outPos] = 0;\n                output[outPos + 1] = 0;\n                inPos += 3;\n                outPos += 2;\n            } else {\n                output[outPos] = data[inPos];\n                inPos++;\n                outPos++;\n            }\n        }\n        return new ByteArrayInputStream(output, 0, outPos);\n    }\n\n    private NALActions handleNALUnit(int nal_ref_idc, int nal_unit_type, byte[] data) throws IOException {\n        NALActions action;\n        switch (nal_unit_type) {\n            case 1:\n            case 2:\n            case 3:\n            case 4:\n            case 5:\n                action = NALActions.STORE; // Will only work in single slice per frame mode!\n                break;\n\n            case 6:\n                seiMessage = new SEIMessage(cleanBuffer(data), seqParameterSet);\n                action = NALActions.BUFFER;\n                break;\n\n            case 9:\n//                printAccessUnitDelimiter(data);\n                action = NALActions.BUFFER;\n                break;\n\n\n            case 7:\n                if (seqParameterSet == null) {\n                    ByteArrayInputStream is = new ByteArrayInputStream(data);\n                    is.read();\n                    seqParameterSet = SeqParameterSet.read(is);\n                    seqParameterSetList.add(data);\n                    if (seqParameterSet.vuiParams != null) {\n                        timescale = seqParameterSet.vuiParams.time_scale >> 1; // Not sure why, but I found this in several places, and it works...\n                        frametick = seqParameterSet.vuiParams.num_units_in_tick;\n                    } else {\n                        System.err.println(\"Warning: Can't determine frame rate. Guessing 25 fps\");\n                        timescale = 90000;\n                        frametick = 3600;\n                    }\n                }\n                action = NALActions.IGNORE;\n                break;\n\n            case 8:\n                if (pictureParameterSet == null) {\n                    ByteArrayInputStream is = new ByteArrayInputStream(data);\n                    is.read();\n                    pictureParameterSet = PictureParameterSet.read(is);\n                    pictureParameterSetList.add(data);\n                }\n                action = NALActions.IGNORE;\n                break;\n\n            case 10:\n            case 11:\n                action = NALActions.END;\n                break;\n\n            default:\n                System.err.println(\"Unknown NAL unit type: \" + nal_unit_type);\n                action = NALActions.IGNORE;\n\n        }\n\n        return action;\n    }\n\n    public void printAccessUnitDelimiter(byte[] data) {\n        System.out.println(\"Access unit delimiter: \" + (data[0] >> 5));\n    }\n\n    public static class SliceHeader {\n\n        public enum SliceType {\n            P, B, I, SP, SI\n        }\n\n        public int first_mb_in_slice;\n        public SliceType slice_type;\n        public int pic_parameter_set_id;\n        public int colour_plane_id;\n        public int frame_num;\n        public boolean field_pic_flag = false;\n        public boolean bottom_field_flag = false;\n        public int idr_pic_id;\n        public int pic_order_cnt_lsb;\n        public int delta_pic_order_cnt_bottom;\n\n        public SliceHeader(InputStream is, SeqParameterSet sps, PictureParameterSet pps, boolean IdrPicFlag) throws IOException {\n            is.read();\n            CAVLCReader reader = new CAVLCReader(is);\n            first_mb_in_slice = reader.readUE(\"SliceHeader: first_mb_in_slice\");\n            switch (reader.readUE(\"SliceHeader: slice_type\")) {\n                case 0:\n                case 5:\n                    slice_type = SliceType.P;\n                    break;\n\n                case 1:\n                case 6:\n                    slice_type = SliceType.B;\n                    break;\n\n                case 2:\n                case 7:\n                    slice_type = SliceType.I;\n                    break;\n\n                case 3:\n                case 8:\n                    slice_type = SliceType.SP;\n                    break;\n\n                case 4:\n                case 9:\n                    slice_type = SliceType.SI;\n                    break;\n\n            }\n            pic_parameter_set_id = reader.readUE(\"SliceHeader: pic_parameter_set_id\");\n            if (sps.residual_color_transform_flag) {\n                colour_plane_id = reader.readU(2, \"SliceHeader: colour_plane_id\");\n            }\n            frame_num = reader.readU(sps.log2_max_frame_num_minus4 + 4, \"SliceHeader: frame_num\");\n\n            if (!sps.frame_mbs_only_flag) {\n                field_pic_flag = reader.readBool(\"SliceHeader: field_pic_flag\");\n                if (field_pic_flag) {\n                    bottom_field_flag = reader.readBool(\"SliceHeader: bottom_field_flag\");\n                }\n            }\n            if (IdrPicFlag) {\n                idr_pic_id = reader.readUE(\"SliceHeader: idr_pic_id\");\n                if (sps.pic_order_cnt_type == 0) {\n                    pic_order_cnt_lsb = reader.readU(sps.log2_max_pic_order_cnt_lsb_minus4 + 4, \"SliceHeader: pic_order_cnt_lsb\");\n                    if (pps.pic_order_present_flag && !field_pic_flag) {\n                        delta_pic_order_cnt_bottom = reader.readSE(\"SliceHeader: delta_pic_order_cnt_bottom\");\n                    }\n                }\n            }\n        }\n\n        @Override\n        public String toString() {\n            return \"SliceHeader{\" +\n                    \"first_mb_in_slice=\" + first_mb_in_slice +\n                    \", slice_type=\" + slice_type +\n                    \", pic_parameter_set_id=\" + pic_parameter_set_id +\n                    \", colour_plane_id=\" + colour_plane_id +\n                    \", frame_num=\" + frame_num +\n                    \", field_pic_flag=\" + field_pic_flag +\n                    \", bottom_field_flag=\" + bottom_field_flag +\n                    \", idr_pic_id=\" + idr_pic_id +\n                    \", pic_order_cnt_lsb=\" + pic_order_cnt_lsb +\n                    \", delta_pic_order_cnt_bottom=\" + delta_pic_order_cnt_bottom +\n                    '}';\n        }\n    }\n\n    private class ReaderWrapper {\n        private InputStream inputStream;\n        private long pos = 0;\n\n        private ReaderWrapper(InputStream inputStream) {\n            this.inputStream = inputStream;\n        }\n\n        int read() throws IOException {\n            pos++;\n            return inputStream.read();\n        }\n\n        long read(byte[] data) throws IOException {\n            long read = inputStream.read(data);\n            pos += read;\n            return read;\n        }\n\n        long rewind(int dist) throws IOException {\n            long skipped = inputStream.skip(-dist);\n            pos += skipped;\n            return -skipped;\n        }\n\n        long seek(int dist) throws IOException {\n            long seeked = inputStream.skip(dist);\n            pos += seeked;\n            return seeked;\n        }\n\n        public long getPos() {\n            return pos;\n        }\n    }\n\n    public class SEIMessage {\n\n        int payloadType = 0;\n        int payloadSize = 0;\n\n        boolean removal_delay_flag;\n        int cpb_removal_delay;\n        int dpb_removal_delay;\n\n        boolean clock_timestamp_flag;\n        int pic_struct;\n        int ct_type;\n        int nuit_field_based_flag;\n        int counting_type;\n        int full_timestamp_flag;\n        int discontinuity_flag;\n        int cnt_dropped_flag;\n        int n_frames;\n        int seconds_value;\n        int minutes_value;\n        int hours_value;\n        int time_offset_length;\n        int time_offset;\n\n        SeqParameterSet sps;\n\n        public SEIMessage(InputStream is, SeqParameterSet sps) throws IOException {\n            this.sps = sps;\n            is.read();\n            int datasize = is.available();\n            int read = 0;\n            while (read < datasize) {\n                payloadType = 0;\n                payloadSize = 0;\n                int last_payload_type_bytes = is.read();\n                read++;\n                while (last_payload_type_bytes == 0xff) {\n                    payloadType += last_payload_type_bytes;\n                    last_payload_type_bytes = is.read();\n                    read++;\n                }\n                payloadType += last_payload_type_bytes;\n                int last_payload_size_bytes = is.read();\n                read++;\n\n                while (last_payload_size_bytes == 0xff) {\n                    payloadSize += last_payload_size_bytes;\n                    last_payload_size_bytes = is.read();\n                    read++;\n                }\n                payloadSize += last_payload_size_bytes;\n                if (datasize - read >= payloadSize) {\n                    if (payloadType == 1) { // pic_timing is what we are interested in!\n                        if (sps.vuiParams != null && (sps.vuiParams.nalHRDParams != null || sps.vuiParams.vclHRDParams != null || sps.vuiParams.pic_struct_present_flag)) {\n                            byte[] data = new byte[payloadSize];\n                            is.read(data);\n                            read += payloadSize;\n                            CAVLCReader reader = new CAVLCReader(new ByteArrayInputStream(data));\n                            if (sps.vuiParams.nalHRDParams != null || sps.vuiParams.vclHRDParams != null) {\n                                removal_delay_flag = true;\n                                cpb_removal_delay = reader.readU(sps.vuiParams.nalHRDParams.cpb_removal_delay_length_minus1 + 1, \"SEI: cpb_removal_delay\");\n                                dpb_removal_delay = reader.readU(sps.vuiParams.nalHRDParams.dpb_output_delay_length_minus1 + 1, \"SEI: dpb_removal_delay\");\n                            } else {\n                                removal_delay_flag = false;\n                            }\n                            if (sps.vuiParams.pic_struct_present_flag) {\n                                pic_struct = reader.readU(4, \"SEI: pic_struct\");\n                                int numClockTS;\n                                switch (pic_struct) {\n                                    case 0:\n                                    case 1:\n                                    case 2:\n                                    default:\n                                        numClockTS = 1;\n                                        break;\n\n                                    case 3:\n                                    case 4:\n                                    case 7:\n                                        numClockTS = 2;\n                                        break;\n\n                                    case 5:\n                                    case 6:\n                                    case 8:\n                                        numClockTS = 3;\n                                        break;\n                                }\n                                for (int i = 0; i < numClockTS; i++) {\n                                    clock_timestamp_flag = reader.readBool(\"pic_timing SEI: clock_timestamp_flag[\" + i + \"]\");\n                                    if (clock_timestamp_flag) {\n                                        ct_type = reader.readU(2, \"pic_timing SEI: ct_type\");\n                                        nuit_field_based_flag = reader.readU(1, \"pic_timing SEI: nuit_field_based_flag\");\n                                        counting_type = reader.readU(5, \"pic_timing SEI: counting_type\");\n                                        full_timestamp_flag = reader.readU(1, \"pic_timing SEI: full_timestamp_flag\");\n                                        discontinuity_flag = reader.readU(1, \"pic_timing SEI: discontinuity_flag\");\n                                        cnt_dropped_flag = reader.readU(1, \"pic_timing SEI: cnt_dropped_flag\");\n                                        n_frames = reader.readU(8, \"pic_timing SEI: n_frames\");\n                                        if (full_timestamp_flag == 1) {\n                                            seconds_value = reader.readU(6, \"pic_timing SEI: seconds_value\");\n                                            minutes_value = reader.readU(6, \"pic_timing SEI: minutes_value\");\n                                            hours_value = reader.readU(5, \"pic_timing SEI: hours_value\");\n                                        } else {\n                                            if (reader.readBool(\"pic_timing SEI: seconds_flag\")) {\n                                                seconds_value = reader.readU(6, \"pic_timing SEI: seconds_value\");\n                                                if (reader.readBool(\"pic_timing SEI: minutes_flag\")) {\n                                                    minutes_value = reader.readU(6, \"pic_timing SEI: minutes_value\");\n                                                    if (reader.readBool(\"pic_timing SEI: hours_flag\")) {\n                                                        hours_value = reader.readU(5, \"pic_timing SEI: hours_value\");\n                                                    }\n                                                }\n                                            }\n                                        }\n                                        if (true) {\n                                            if (sps.vuiParams.nalHRDParams != null) {\n                                                time_offset_length = sps.vuiParams.nalHRDParams.time_offset_length;\n                                            } else if (sps.vuiParams.vclHRDParams != null) {\n                                                time_offset_length = sps.vuiParams.vclHRDParams.time_offset_length;\n                                            } else {\n                                                time_offset_length = 24;\n                                            }\n                                            time_offset = reader.readU(24, \"pic_timing SEI: time_offset\");\n                                        }\n                                    }\n                                }\n                            }\n\n                        } else {\n                            for (int i = 0; i < payloadSize; i++) {\n                                is.read();\n                                read++;\n                            }\n                        }\n                    } else {\n                        for (int i = 0; i < payloadSize; i++) {\n                            is.read();\n                            read++;\n                        }\n                    }\n                } else {\n                    read = datasize;\n                }\n                System.out.println(this);\n            }\n        }\n\n        @Override\n        public String toString() {\n            String out = \"SEIMessage{\" +\n                    \"payloadType=\" + payloadType +\n                    \", payloadSize=\" + payloadSize;\n            if (payloadType == 1) {\n                if (sps.vuiParams.nalHRDParams != null || sps.vuiParams.vclHRDParams != null) {\n\n                    out += \", cpb_removal_delay=\" + cpb_removal_delay +\n                            \", dpb_removal_delay=\" + dpb_removal_delay;\n                }\n                if (sps.vuiParams.pic_struct_present_flag) {\n                    out += \", pic_struct=\" + pic_struct;\n                    if (clock_timestamp_flag) {\n                        out += \", ct_type=\" + ct_type +\n                                \", nuit_field_based_flag=\" + nuit_field_based_flag +\n                                \", counting_type=\" + counting_type +\n                                \", full_timestamp_flag=\" + full_timestamp_flag +\n                                \", discontinuity_flag=\" + discontinuity_flag +\n                                \", cnt_dropped_flag=\" + cnt_dropped_flag +\n                                \", n_frames=\" + n_frames +\n                                \", seconds_value=\" + seconds_value +\n                                \", minutes_value=\" + minutes_value +\n                                \", hours_value=\" + hours_value +\n                                \", time_offset_length=\" + time_offset_length +\n                                \", time_offset=\" + time_offset;\n                    }\n                }\n            }\n            out += '}';\n            return out;\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/tracks/MultiplyTimeScaleTrack.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring.tracks;\n\nimport com.coremedia.iso.boxes.AbstractMediaHeaderBox;\nimport com.coremedia.iso.boxes.CompositionTimeToSample;\nimport com.coremedia.iso.boxes.SampleDependencyTypeBox;\nimport com.coremedia.iso.boxes.SampleDescriptionBox;\nimport com.coremedia.iso.boxes.SubSampleInformationBox;\nimport com.coremedia.iso.boxes.TimeToSampleBox;\nimport com.googlecode.mp4parser.authoring.Movie;\nimport com.googlecode.mp4parser.authoring.Track;\nimport com.googlecode.mp4parser.authoring.TrackMetaData;\n\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.LinkedList;\nimport java.util.List;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\nimport static com.googlecode.mp4parser.util.Math.gcd;\nimport static com.googlecode.mp4parser.util.Math.lcm;\nimport static java.lang.Math.round;\n\n/**\n * Changes the timescale of a track by wrapping the track.\n */\npublic class MultiplyTimeScaleTrack implements Track {\n    Track source;\n    private int timeScaleFactor;\n\n    public MultiplyTimeScaleTrack(Track source, int timeScaleFactor) {\n        this.source = source;\n        this.timeScaleFactor = timeScaleFactor;\n    }\n\n    public SampleDescriptionBox getSampleDescriptionBox() {\n        return source.getSampleDescriptionBox();\n    }\n\n    public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {\n        return adjustTts(source.getDecodingTimeEntries(), timeScaleFactor);\n    }\n\n    public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {\n        return adjustCtts(source.getCompositionTimeEntries(), timeScaleFactor);\n    }\n\n    public long[] getSyncSamples() {\n        return source.getSyncSamples();\n    }\n\n    public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {\n        return source.getSampleDependencies();\n    }\n\n    public TrackMetaData getTrackMetaData() {\n        TrackMetaData trackMetaData = (TrackMetaData) source.getTrackMetaData().clone();\n        trackMetaData.setTimescale(source.getTrackMetaData().getTimescale() * this.timeScaleFactor);\n        return trackMetaData;\n    }\n\n    public String getHandler() {\n        return source.getHandler();\n    }\n\n    public boolean isEnabled() {\n        return source.isEnabled();\n    }\n\n    public boolean isInMovie() {\n        return source.isInMovie();\n    }\n\n    public boolean isInPreview() {\n        return source.isInPreview();\n    }\n\n    public boolean isInPoster() {\n        return source.isInPoster();\n    }\n\n    public List<ByteBuffer> getSamples() {\n        return source.getSamples();\n    }\n\n\n    static List<CompositionTimeToSample.Entry> adjustCtts(List<CompositionTimeToSample.Entry> source, int timeScaleFactor) {\n        if (source != null) {\n            List<CompositionTimeToSample.Entry> entries2 = new ArrayList<CompositionTimeToSample.Entry>(source.size());\n            for (CompositionTimeToSample.Entry entry : source) {\n                entries2.add(new CompositionTimeToSample.Entry(entry.getCount(), timeScaleFactor * entry.getOffset()));\n            }\n            return entries2;\n        } else {\n            return null;\n        }\n    }\n\n    static List<TimeToSampleBox.Entry> adjustTts(List<TimeToSampleBox.Entry> source, int timeScaleFactor) {\n        LinkedList<TimeToSampleBox.Entry> entries2 = new LinkedList<TimeToSampleBox.Entry>();\n        for (TimeToSampleBox.Entry e : source) {\n            entries2.add(new TimeToSampleBox.Entry(e.getCount(), timeScaleFactor * e.getDelta()));\n        }\n        return entries2;\n    }\n\n    public AbstractMediaHeaderBox getMediaHeaderBox() {\n        return source.getMediaHeaderBox();\n    }\n\n    public SubSampleInformationBox getSubsampleInformationBox() {\n        return source.getSubsampleInformationBox();\n    }\n\n    @Override\n    public String toString() {\n        return \"MultiplyTimeScaleTrack{\" +\n                \"source=\" + source +\n                '}';\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/authoring/tracks/TextTrackImpl.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.authoring.tracks;\n\nimport com.coremedia.iso.boxes.*;\nimport com.coremedia.iso.boxes.sampleentry.TextSampleEntry;\nimport com.googlecode.mp4parser.authoring.AbstractTrack;\nimport com.googlecode.mp4parser.authoring.TrackMetaData;\nimport com.googlecode.mp4parser.boxes.threegpp26245.FontTableBox;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.DataOutputStream;\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.util.Collections;\nimport java.util.Date;\nimport java.util.LinkedList;\nimport java.util.List;\n\n/**\n *\n */\npublic class TextTrackImpl extends AbstractTrack {\n    TrackMetaData trackMetaData = new TrackMetaData();\n    SampleDescriptionBox sampleDescriptionBox;\n    List<Line> subs = new LinkedList<Line>();\n\n    public List<Line> getSubs() {\n        return subs;\n    }\n\n    public TextTrackImpl() {\n        sampleDescriptionBox = new SampleDescriptionBox();\n        TextSampleEntry tx3g = new TextSampleEntry(\"tx3g\");\n        tx3g.setStyleRecord(new TextSampleEntry.StyleRecord());\n        tx3g.setBoxRecord(new TextSampleEntry.BoxRecord());\n        sampleDescriptionBox.addBox(tx3g);\n\n        FontTableBox ftab = new FontTableBox();\n        ftab.setEntries(Collections.singletonList(new FontTableBox.FontRecord(1, \"Serif\")));\n\n        tx3g.addBox(ftab);\n\n\n        trackMetaData.setCreationTime(new Date());\n        trackMetaData.setModificationTime(new Date());\n        trackMetaData.setTimescale(1000); // Text tracks use millieseconds\n\n\n    }\n\n\n    public List<ByteBuffer> getSamples() {\n        List<ByteBuffer> samples = new LinkedList<ByteBuffer>();\n        long lastEnd = 0;\n        for (Line sub : subs) {\n            long silentTime = sub.from - lastEnd;\n            if (silentTime > 0) {\n                samples.add(ByteBuffer.wrap(new byte[]{0, 0}));\n            } else if (silentTime < 0) {\n                throw new Error(\"Subtitle display times may not intersect\");\n            }\n            ByteArrayOutputStream baos = new ByteArrayOutputStream();\n            DataOutputStream dos = new DataOutputStream(baos);\n            try {\n                dos.writeShort(sub.text.getBytes(\"UTF-8\").length);\n                dos.write(sub.text.getBytes(\"UTF-8\"));\n                dos.close();\n            } catch (IOException e) {\n                throw new Error(\"VM is broken. Does not support UTF-8\");\n            }\n            samples.add(ByteBuffer.wrap(baos.toByteArray()));\n            lastEnd = sub.to;\n        }\n        return samples;\n    }\n\n    public SampleDescriptionBox getSampleDescriptionBox() {\n        return sampleDescriptionBox;\n    }\n\n    public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {\n        List<TimeToSampleBox.Entry> stts = new LinkedList<TimeToSampleBox.Entry>();\n        long lastEnd = 0;\n        for (Line sub : subs) {\n            long silentTime = sub.from - lastEnd;\n            if (silentTime > 0) {\n                stts.add(new TimeToSampleBox.Entry(1, silentTime));\n            } else if (silentTime < 0) {\n                throw new Error(\"Subtitle display times may not intersect\");\n            }\n            stts.add(new TimeToSampleBox.Entry(1, sub.to - sub.from));\n            lastEnd = sub.to;\n        }\n        return stts;\n    }\n\n    public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {\n        return null;\n    }\n\n    public long[] getSyncSamples() {\n        return null;\n    }\n\n    public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {\n        return null;\n    }\n\n    public TrackMetaData getTrackMetaData() {\n        return trackMetaData;\n    }\n\n    public String getHandler() {\n        return \"text\";\n    }\n\n\n    public static class Line {\n        long from;\n        long to;\n        String text;\n\n\n        public Line(long from, long to, String text) {\n            this.from = from;\n            this.to = to;\n            this.text = text;\n        }\n\n        public long getFrom() {\n            return from;\n        }\n\n        public String getText() {\n            return text;\n        }\n\n        public long getTo() {\n            return to;\n        }\n    }\n\n    public AbstractMediaHeaderBox getMediaHeaderBox() {\n        return new NullMediaHeaderBox();\n    }\n\n    public SubSampleInformationBox getSubsampleInformationBox() {\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/AC3SpecificBox.java",
    "content": "package com.googlecode.mp4parser.boxes;\n\nimport com.googlecode.mp4parser.AbstractBox;\nimport com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitReaderBuffer;\nimport com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitWriterBuffer;\n\nimport java.nio.ByteBuffer;\n\npublic class AC3SpecificBox extends AbstractBox {\n    int fscod;\n    int bsid;\n    int bsmod;\n    int acmod;\n    int lfeon;\n    int bitRateCode;\n    int reserved;\n\n    public AC3SpecificBox() {\n        super(\"dac3\");\n    }\n\n    @Override\n    protected long getContentSize() {\n        return 3;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        BitReaderBuffer brb = new BitReaderBuffer(content);\n        fscod = brb.readBits(2);\n        bsid = brb.readBits(5);\n        bsmod = brb.readBits(3);\n        acmod = brb.readBits(3);\n        lfeon = brb.readBits(1);\n        bitRateCode = brb.readBits(5);\n        reserved = brb.readBits(5);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        BitWriterBuffer bwb = new BitWriterBuffer(byteBuffer);\n        bwb.writeBits(fscod, 2);\n        bwb.writeBits(bsid, 5);\n        bwb.writeBits(bsmod, 3);\n        bwb.writeBits(acmod, 3);\n        bwb.writeBits(lfeon, 1);\n        bwb.writeBits(bitRateCode, 5);\n        bwb.writeBits(reserved, 5);\n    }\n\n    public int getFscod() {\n        return fscod;\n    }\n\n    public void setFscod(int fscod) {\n        this.fscod = fscod;\n    }\n\n    public int getBsid() {\n        return bsid;\n    }\n\n    public void setBsid(int bsid) {\n        this.bsid = bsid;\n    }\n\n    public int getBsmod() {\n        return bsmod;\n    }\n\n    public void setBsmod(int bsmod) {\n        this.bsmod = bsmod;\n    }\n\n    public int getAcmod() {\n        return acmod;\n    }\n\n    public void setAcmod(int acmod) {\n        this.acmod = acmod;\n    }\n\n    public int getLfeon() {\n        return lfeon;\n    }\n\n    public void setLfeon(int lfeon) {\n        this.lfeon = lfeon;\n    }\n\n    public int getBitRateCode() {\n        return bitRateCode;\n    }\n\n    public void setBitRateCode(int bitRateCode) {\n        this.bitRateCode = bitRateCode;\n    }\n\n    public int getReserved() {\n        return reserved;\n    }\n\n    public void setReserved(int reserved) {\n        this.reserved = reserved;\n    }\n\n    @Override\n    public String toString() {\n        return \"AC3SpecificBox{\" +\n                \"fscod=\" + fscod +\n                \", bsid=\" + bsid +\n                \", bsmod=\" + bsmod +\n                \", acmod=\" + acmod +\n                \", lfeon=\" + lfeon +\n                \", bitRateCode=\" + bitRateCode +\n                \", reserved=\" + reserved +\n                '}';\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/AbstractSampleEncryptionBox.java",
    "content": "package com.googlecode.mp4parser.boxes;\n\nimport com.coremedia.iso.Hex;\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.io.IOException;\nimport java.math.BigInteger;\nimport java.nio.ByteBuffer;\nimport java.nio.channels.WritableByteChannel;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.LinkedList;\nimport java.util.List;\n\n\npublic abstract class AbstractSampleEncryptionBox extends AbstractFullBox {\n    int algorithmId = -1;\n    int ivSize = -1;\n    byte[] kid = new byte[16];\n    List<Entry> entries = new LinkedList<Entry>();\n\n    protected AbstractSampleEncryptionBox(String type) {\n        super(type);\n    }\n\n    public int getOffsetToFirstIV() {\n        int offset = (getSize() > (1l << 32) ? 16 : 8);\n        offset += isOverrideTrackEncryptionBoxParameters() ? 20 : 0;\n        offset += 4; //num entries\n        return offset;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        if ((getFlags() & 0x1) > 0) {\n            algorithmId = IsoTypeReader.readUInt24(content);\n            ivSize = IsoTypeReader.readUInt8(content);\n            kid = new byte[16];\n            content.get(kid);\n        }\n        long numOfEntries = IsoTypeReader.readUInt32(content);\n        while (numOfEntries-- > 0) {\n            Entry e = new Entry();\n            e.iv = new byte[((getFlags() & 0x1) > 0) ? ivSize : 8];\n            content.get(e.iv);\n            if ((getFlags() & 0x2) > 0) {\n                int numOfPairs = IsoTypeReader.readUInt16(content);\n                e.pairs = new LinkedList<Entry.Pair>();\n                while (numOfPairs-- > 0) {\n                    e.pairs.add(e.createPair(IsoTypeReader.readUInt16(content), IsoTypeReader.readUInt32(content)));\n                }\n            }\n            entries.add(e);\n\n        }\n    }\n\n\n    public int getSampleCount() {\n        return entries.size();\n    }\n\n    public List<Entry> getEntries() {\n        return entries;\n    }\n\n    public void setEntries(List<Entry> entries) {\n        this.entries = entries;\n    }\n\n    public int getAlgorithmId() {\n        return algorithmId;\n    }\n\n    public void setAlgorithmId(int algorithmId) {\n        this.algorithmId = algorithmId;\n    }\n\n    public int getIvSize() {\n        return ivSize;\n    }\n\n    public void setIvSize(int ivSize) {\n        this.ivSize = ivSize;\n    }\n\n    public byte[] getKid() {\n        return kid;\n    }\n\n    public void setKid(byte[] kid) {\n        this.kid = kid;\n    }\n\n\n    public boolean isSubSampleEncryption() {\n        return (getFlags() & 0x2) > 0;\n    }\n\n    public boolean isOverrideTrackEncryptionBoxParameters() {\n        return (getFlags() & 0x1) > 0;\n    }\n\n    public void setSubSampleEncryption(boolean b) {\n        if (b) {\n            setFlags(getFlags() | 0x2);\n        } else {\n            setFlags(getFlags() & (0xffffff ^ 0x2));\n        }\n    }\n\n    public void setOverrideTrackEncryptionBoxParameters(boolean b) {\n        if (b) {\n            setFlags(getFlags() | 0x1);\n        } else {\n            setFlags(getFlags() & (0xffffff ^ 0x1));\n        }\n    }\n\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        if (isOverrideTrackEncryptionBoxParameters()) {\n            IsoTypeWriter.writeUInt24(byteBuffer, algorithmId);\n            IsoTypeWriter.writeUInt8(byteBuffer, ivSize);\n            byteBuffer.put(kid);\n        }\n        IsoTypeWriter.writeUInt32(byteBuffer, entries.size());\n        for (Entry entry : entries) {\n            if (isOverrideTrackEncryptionBoxParameters()) {\n                byte[] ivFull = new byte[ivSize];\n                System.arraycopy(entry.iv, 0, ivFull, ivSize - entry.iv.length, entry.iv.length);\n                byteBuffer.put(ivFull);\n            } else {\n                // just put the iv - i don't know any better\n                byteBuffer.put(entry.iv);\n            }\n            if (isSubSampleEncryption()) {\n                IsoTypeWriter.writeUInt16(byteBuffer, entry.pairs.size());\n                for (Entry.Pair pair : entry.pairs) {\n                    IsoTypeWriter.writeUInt16(byteBuffer, pair.clear);\n                    IsoTypeWriter.writeUInt32(byteBuffer, pair.encrypted);\n                }\n            }\n        }\n    }\n\n    @Override\n    protected long getContentSize() {\n        long contentSize = 4;\n        if (isOverrideTrackEncryptionBoxParameters()) {\n            contentSize += 4;\n            contentSize += kid.length;\n        }\n        contentSize += 4;\n        for (Entry entry : entries) {\n            contentSize += entry.getSize();\n        }\n        return contentSize;\n    }\n\n    @Override\n    public void getBox(WritableByteChannel os) throws IOException {\n        super.getBox(os);\n    }\n\n    public Entry createEntry() {\n        return new Entry();\n    }\n\n    public class Entry {\n        public byte[] iv;\n        public List<Pair> pairs = new LinkedList<Pair>();\n\n        public int getSize() {\n            int size = 0;\n            if (isOverrideTrackEncryptionBoxParameters()) {\n                size = ivSize;\n            } else {\n                size = iv.length;\n            }\n\n\n            if (isSubSampleEncryption()) {\n                size += 2;\n                for (Entry.Pair pair : pairs) {\n                    size += 6;\n                }\n            }\n            return size;\n        }\n\n        public Pair createPair(int clear, long encrypted) {\n            return new Pair(clear, encrypted);\n        }\n\n\n        public class Pair {\n            public int clear;\n            public long encrypted;\n\n            public Pair(int clear, long encrypted) {\n                this.clear = clear;\n                this.encrypted = encrypted;\n            }\n\n            @Override\n            public boolean equals(Object o) {\n                if (this == o) return true;\n                if (o == null || getClass() != o.getClass()) return false;\n\n                Pair pair = (Pair) o;\n\n                if (clear != pair.clear) return false;\n                if (encrypted != pair.encrypted) return false;\n\n                return true;\n            }\n\n            @Override\n            public int hashCode() {\n                int result = clear;\n                result = 31 * result + (int) (encrypted ^ (encrypted >>> 32));\n                return result;\n            }\n\n            @Override\n            public String toString() {\n                return \"clr:\" + clear + \" enc:\" + encrypted;\n            }\n        }\n\n\n        @Override\n        public boolean equals(Object o) {\n            if (this == o) return true;\n            if (o == null || getClass() != o.getClass()) return false;\n\n            Entry entry = (Entry) o;\n\n            if (!new BigInteger(iv).equals(new BigInteger(entry.iv))) return false;\n            if (pairs != null ? !pairs.equals(entry.pairs) : entry.pairs != null) return false;\n\n            return true;\n        }\n\n        @Override\n        public int hashCode() {\n            int result = iv != null ? Arrays.hashCode(iv) : 0;\n            result = 31 * result + (pairs != null ? pairs.hashCode() : 0);\n            return result;\n        }\n\n        @Override\n        public String toString() {\n            return \"Entry{\" +\n                    \"iv=\" + Hex.encodeHex(iv) +\n                    \", pairs=\" + pairs +\n                    '}';\n        }\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        AbstractSampleEncryptionBox that = (AbstractSampleEncryptionBox) o;\n\n        if (algorithmId != that.algorithmId) return false;\n        if (ivSize != that.ivSize) return false;\n        if (entries != null ? !entries.equals(that.entries) : that.entries != null) return false;\n        if (!Arrays.equals(kid, that.kid)) return false;\n\n        return true;\n    }\n\n    @Override\n    public int hashCode() {\n        int result = algorithmId;\n        result = 31 * result + ivSize;\n        result = 31 * result + (kid != null ? Arrays.hashCode(kid) : 0);\n        result = 31 * result + (entries != null ? entries.hashCode() : 0);\n        return result;\n    }\n\n    public List<Short> getEntrySizes() {\n        List<Short> entrySizes = new ArrayList<Short>(entries.size());\n        for (Entry entry : entries) {\n            short size = (short) entry.iv.length;\n            if (isSubSampleEncryption()) {\n                size += 2; //numPairs\n                size += entry.pairs.size() * 6;\n            }\n            entrySizes.add(size);\n        }\n        return entrySizes;\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/AbstractTrackEncryptionBox.java",
    "content": "package com.googlecode.mp4parser.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\nimport java.util.Arrays;\nimport java.util.UUID;\n\n/**\n *\n */\npublic abstract class AbstractTrackEncryptionBox extends AbstractFullBox {\n    int defaultAlgorithmId;\n    int defaultIvSize;\n    byte[] default_KID;\n\n    protected AbstractTrackEncryptionBox(String type) {\n        super(type);\n    }\n\n    public int getDefaultAlgorithmId() {\n        return defaultAlgorithmId;\n    }\n\n    public void setDefaultAlgorithmId(int defaultAlgorithmId) {\n        this.defaultAlgorithmId = defaultAlgorithmId;\n    }\n\n    public int getDefaultIvSize() {\n        return defaultIvSize;\n    }\n\n    public void setDefaultIvSize(int defaultIvSize) {\n        this.defaultIvSize = defaultIvSize;\n    }\n\n    public String getDefault_KID() {\n        ByteBuffer b = ByteBuffer.wrap(default_KID);\n        b.order(ByteOrder.BIG_ENDIAN);\n        return new UUID(b.getLong(), b.getLong()).toString();\n    }\n\n    public void setDefault_KID(byte[] default_KID) {\n        this.default_KID = default_KID;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        defaultAlgorithmId = IsoTypeReader.readUInt24(content);\n        defaultIvSize = IsoTypeReader.readUInt8(content);\n        default_KID = new byte[16];\n        content.get(default_KID);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt24(byteBuffer, defaultAlgorithmId);\n        IsoTypeWriter.writeUInt8(byteBuffer, defaultIvSize);\n        byteBuffer.put(default_KID);\n    }\n\n    @Override\n    protected long getContentSize() {\n        return 24;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        AbstractTrackEncryptionBox that = (AbstractTrackEncryptionBox) o;\n\n        if (defaultAlgorithmId != that.defaultAlgorithmId) return false;\n        if (defaultIvSize != that.defaultIvSize) return false;\n        if (!Arrays.equals(default_KID, that.default_KID)) return false;\n\n        return true;\n    }\n\n    @Override\n    public int hashCode() {\n        int result = defaultAlgorithmId;\n        result = 31 * result + defaultIvSize;\n        result = 31 * result + (default_KID != null ? Arrays.hashCode(default_KID) : 0);\n        return result;\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/DTSSpecificBox.java",
    "content": "package com.googlecode.mp4parser.boxes;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractBox;\nimport com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitReaderBuffer;\nimport com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitWriterBuffer;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Created by IntelliJ IDEA.\n * User: magnus\n * Date: 2012-03-09\n * Time: 16:11\n * To change this template use File | Settings | File Templates.\n */\npublic class DTSSpecificBox extends AbstractBox {\n    \n    long DTSSamplingFrequency;\n    long maxBitRate;\n    long avgBitRate;\n    int pcmSampleDepth;\n    int frameDuration;\n    int streamConstruction;\n    int coreLFEPresent;\n    int coreLayout;\n    int coreSize;\n    int stereoDownmix;\n    int representationType;\n    int channelLayout;\n    int multiAssetFlag;\n    int LBRDurationMod;\n    int reservedBoxPresent;\n    int reserved;\n\n    public DTSSpecificBox() {\n        super(\"ddts\");\n    }\n\n    @Override\n    protected long getContentSize() {\n        return 20;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        DTSSamplingFrequency = IsoTypeReader.readUInt32(content);\n        maxBitRate = IsoTypeReader.readUInt32(content);\n        avgBitRate = IsoTypeReader.readUInt32(content);\n        pcmSampleDepth = IsoTypeReader.readUInt8(content);\n        BitReaderBuffer brb = new BitReaderBuffer(content);\n        frameDuration = brb.readBits(2);\n        streamConstruction = brb.readBits(5);\n        coreLFEPresent = brb.readBits(1);\n        coreLayout = brb.readBits(6);\n        coreSize = brb.readBits(14);\n        stereoDownmix = brb.readBits(1);\n        representationType = brb.readBits(3);\n        channelLayout = brb.readBits(16);\n        multiAssetFlag = brb.readBits(1);\n        LBRDurationMod = brb.readBits(1);\n        reservedBoxPresent = brb.readBits(1);\n        reserved = brb.readBits(5);\n\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        IsoTypeWriter.writeUInt32(byteBuffer, DTSSamplingFrequency);\n        IsoTypeWriter.writeUInt32(byteBuffer, maxBitRate);\n        IsoTypeWriter.writeUInt32(byteBuffer, avgBitRate);\n        IsoTypeWriter.writeUInt8(byteBuffer, pcmSampleDepth);\n        BitWriterBuffer bwb = new BitWriterBuffer(byteBuffer);\n        bwb.writeBits(frameDuration, 2);\n        bwb.writeBits(streamConstruction, 5);\n        bwb.writeBits(coreLFEPresent, 1);\n        bwb.writeBits(coreLayout, 6);\n        bwb.writeBits(coreSize, 14);\n        bwb.writeBits(stereoDownmix, 1);\n        bwb.writeBits(representationType, 3);\n        bwb.writeBits(channelLayout, 16);\n        bwb.writeBits(multiAssetFlag, 1);\n        bwb.writeBits(LBRDurationMod, 1);\n        bwb.writeBits(reservedBoxPresent, 1);\n        bwb.writeBits(reserved, 5);\n\n    }\n\n    public long getAvgBitRate() {\n        return avgBitRate;\n    }\n\n    public void setAvgBitRate(long avgBitRate) {\n        this.avgBitRate = avgBitRate;\n    }\n\n    public long getDTSSamplingFrequency() {\n        return DTSSamplingFrequency;\n    }\n\n    public void setDTSSamplingFrequency(long DTSSamplingFrequency) {\n        this.DTSSamplingFrequency = DTSSamplingFrequency;\n    }\n\n    public long getMaxBitRate() {\n        return maxBitRate;\n    }\n\n    public void setMaxBitRate(long maxBitRate) {\n        this.maxBitRate = maxBitRate;\n    }\n\n    public int getPcmSampleDepth() {\n        return pcmSampleDepth;\n    }\n\n    public void setPcmSampleDepth(int pcmSampleDepth) {\n        this.pcmSampleDepth = pcmSampleDepth;\n    }\n\n    public int getFrameDuration() {\n        return frameDuration;\n    }\n\n    public void setFrameDuration(int frameDuration) {\n        this.frameDuration = frameDuration;\n    }\n\n    public int getStreamConstruction() {\n        return streamConstruction;\n    }\n\n    public void setStreamConstruction(int streamConstruction) {\n        this.streamConstruction = streamConstruction;\n    }\n\n    public int getCoreLFEPresent() {\n        return coreLFEPresent;\n    }\n\n    public void setCoreLFEPresent(int coreLFEPresent) {\n        this.coreLFEPresent = coreLFEPresent;\n    }\n\n    public int getCoreLayout() {\n        return coreLayout;\n    }\n\n    public void setCoreLayout(int coreLayout) {\n        this.coreLayout = coreLayout;\n    }\n\n    public int getCoreSize() {\n        return coreSize;\n    }\n\n    public void setCoreSize(int coreSize) {\n        this.coreSize = coreSize;\n    }\n\n    public int getStereoDownmix() {\n        return stereoDownmix;\n    }\n\n    public void setStereoDownmix(int stereoDownmix) {\n        this.stereoDownmix = stereoDownmix;\n    }\n\n    public int getRepresentationType() {\n        return representationType;\n    }\n\n    public void setRepresentationType(int representationType) {\n        this.representationType = representationType;\n    }\n\n    public int getChannelLayout() {\n        return channelLayout;\n    }\n\n    public void setChannelLayout(int channelLayout) {\n        this.channelLayout = channelLayout;\n    }\n\n    public int getMultiAssetFlag() {\n        return multiAssetFlag;\n    }\n\n    public void setMultiAssetFlag(int multiAssetFlag) {\n        this.multiAssetFlag = multiAssetFlag;\n    }\n\n    public int getLBRDurationMod() {\n        return LBRDurationMod;\n    }\n\n    public void setLBRDurationMod(int LBRDurationMod) {\n        this.LBRDurationMod = LBRDurationMod;\n    }\n\n    public int getReserved() {\n        return reserved;\n    }\n\n    public void setReserved(int reserved) {\n        this.reserved = reserved;\n    }\n\n    public int getReservedBoxPresent() {\n        return reservedBoxPresent;\n    }\n\n    public void setReservedBoxPresent(int reservedBoxPresent) {\n        this.reservedBoxPresent = reservedBoxPresent;\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/EC3SpecificBox.java",
    "content": "package com.googlecode.mp4parser.boxes;\n\nimport com.googlecode.mp4parser.AbstractBox;\nimport com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitReaderBuffer;\nimport com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitWriterBuffer;\n\nimport java.nio.ByteBuffer;\nimport java.util.LinkedList;\nimport java.util.List;\n\n/**\n *\n */\npublic class EC3SpecificBox extends AbstractBox {\n    List<Entry> entries = new LinkedList<Entry>();\n    int dataRate;\n    int numIndSub;\n    public EC3SpecificBox() {\n        super(\"dec3\");\n    }\n\n    @Override\n    protected long getContentSize() {\n        long size = 2;\n        for (Entry entry : entries) {\n            if (entry.num_dep_sub > 0) {\n                size += 4;\n            } else {\n                size += 3;\n            }\n        }\n        return size;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        BitReaderBuffer brb = new BitReaderBuffer(content);\n        dataRate = brb.readBits(13);\n        numIndSub = brb.readBits(3) + 1;\n        // This field indicates the number of independent substreams that are present in the Enhanced AC-3 bitstream. The value\n        // of this field is one less than the number of independent substreams present.\n\n\n        for (int i = 0; i < numIndSub; i++) {\n            Entry e = new Entry();\n            e.fscod = brb.readBits(2);\n            e.bsid = brb.readBits(5);\n            e.bsmod = brb.readBits(5);\n            e.acmod = brb.readBits(3);\n            e.lfeon = brb.readBits(1);\n            e.reserved = brb.readBits(3);\n            e.num_dep_sub = brb.readBits(4);\n            if (e.num_dep_sub > 0) {\n                e.chan_loc = brb.readBits(9);\n            } else {\n                e.reserved2 = brb.readBits(1);\n            }\n            entries.add(e);\n        }\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        BitWriterBuffer bwb = new BitWriterBuffer(byteBuffer);\n        bwb.writeBits(dataRate, 13);\n        bwb.writeBits(entries.size() - 1, 3);\n        for (Entry e : entries) {\n            bwb.writeBits(e.fscod, 2);\n            bwb.writeBits(e.bsid, 5);\n            bwb.writeBits(e.bsmod, 5);\n            bwb.writeBits(e.acmod, 3);\n            bwb.writeBits(e.lfeon, 1);\n            bwb.writeBits(e.reserved, 3);\n            bwb.writeBits(e.num_dep_sub, 4);\n            if (e.num_dep_sub > 0) {\n                bwb.writeBits(e.chan_loc, 9);\n            } else {\n                bwb.writeBits(e.reserved2, 1);\n            }\n        }\n    }\n\n\n    public List<Entry> getEntries() {\n        return entries;\n    }\n\n    public void setEntries(List<Entry> entries) {\n        this.entries = entries;\n    }\n\n    public void addEntry(Entry entry) {\n        this.entries.add(entry);\n    }\n\n    public int getDataRate() {\n        return dataRate;\n    }\n\n    public void setDataRate(int dataRate) {\n        this.dataRate = dataRate;\n    }\n\n    public int getNumIndSub() {\n        return numIndSub;\n    }\n\n    public void setNumIndSub(int numIndSub) {\n        this.numIndSub = numIndSub;\n    }\n\n    public static class Entry {\n        public int fscod;\n        public int bsid;\n        public int bsmod;\n        public int acmod;\n        public int lfeon;\n        public int reserved;\n        public int num_dep_sub;\n        public int chan_loc;\n        public int reserved2;\n\n\n        @Override\n        public String toString() {\n            return \"Entry{\" +\n                    \"fscod=\" + fscod +\n                    \", bsid=\" + bsid +\n                    \", bsmod=\" + bsmod +\n                    \", acmod=\" + acmod +\n                    \", lfeon=\" + lfeon +\n                    \", reserved=\" + reserved +\n                    \", num_dep_sub=\" + num_dep_sub +\n                    \", chan_loc=\" + chan_loc +\n                    \", reserved2=\" + reserved2 +\n                    '}';\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/MLPSpecificBox.java",
    "content": "package com.googlecode.mp4parser.boxes;\n\nimport com.googlecode.mp4parser.AbstractBox;\nimport com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitReaderBuffer;\nimport com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitWriterBuffer;\n\nimport java.nio.ByteBuffer;\n\n\npublic class MLPSpecificBox extends AbstractBox {\n\n    int format_info;\n    int peak_data_rate;\n    int reserved;\n    int reserved2;\n\n    public MLPSpecificBox() {\n        super(\"dmlp\");\n    }\n\n    @Override\n    protected long getContentSize() {\n        return 10;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        BitReaderBuffer brb = new BitReaderBuffer(content);\n        format_info = brb.readBits(32);\n        peak_data_rate = brb.readBits(15);\n        reserved = brb.readBits(1);\n        reserved2 = brb.readBits(32);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        BitWriterBuffer bwb = new BitWriterBuffer(byteBuffer);\n        bwb.writeBits(format_info, 32);\n        bwb.writeBits(peak_data_rate, 15);\n        bwb.writeBits(reserved, 1);\n        bwb.writeBits(reserved2, 32);\n        //To change body of implemented methods use File | Settings | File Templates.\n    }\n\n    public int getFormat_info() {\n        return format_info;\n    }\n\n    public void setFormat_info(int format_info) {\n        this.format_info = format_info;\n    }\n\n    public int getPeak_data_rate() {\n        return peak_data_rate;\n    }\n\n    public void setPeak_data_rate(int peak_data_rate) {\n        this.peak_data_rate = peak_data_rate;\n    }\n\n    public int getReserved() {\n        return reserved;\n    }\n\n    public void setReserved(int reserved) {\n        this.reserved = reserved;\n    }\n\n    public int getReserved2() {\n        return reserved2;\n    }\n\n    public void setReserved2(int reserved2) {\n        this.reserved2 = reserved2;\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/adobe/ActionMessageFormat0SampleEntryBox.java",
    "content": "package com.googlecode.mp4parser.boxes.adobe;\n\nimport com.coremedia.iso.boxes.Box;\nimport com.coremedia.iso.boxes.sampleentry.SampleEntry;\n\nimport java.nio.ByteBuffer;\n\n/**\n * Sample Entry as used for Action Message Format tracks.\n */\npublic class ActionMessageFormat0SampleEntryBox extends SampleEntry {\n    public ActionMessageFormat0SampleEntryBox() {\n        super(\"amf0\");\n    }\n\n    @Override\n    protected long getContentSize() {\n        long size = 8;\n        for (Box box : boxes) {\n            size += box.getSize();\n        }\n\n        return size;\n    }\n\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        _parseReservedAndDataReferenceIndex(content);\n        _parseChildBoxes(content);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        _writeReservedAndDataReferenceIndex(byteBuffer);\n        _writeChildBoxes(byteBuffer);\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/apple/TimeCodeBox.java",
    "content": "package com.googlecode.mp4parser.boxes.apple;\n\nimport com.coremedia.iso.boxes.Box;\nimport com.coremedia.iso.boxes.sampleentry.SampleEntry;\n\nimport java.nio.ByteBuffer;\n\npublic class TimeCodeBox extends SampleEntry {\n    byte[] data;\n\n\n    public TimeCodeBox() {\n        super(\"tmcd\");\n    }\n\n    @Override\n    protected long getContentSize() {\n        long size = 26;\n        for (Box box : boxes) {\n            size += box.getSize();\n        }\n        return size;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        _parseReservedAndDataReferenceIndex(content);\n        data = new byte[18];\n        content.get(data);\n        _parseChildBoxes(content);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        _writeReservedAndDataReferenceIndex(byteBuffer);\n        byteBuffer.put(data);\n        _writeChildBoxes(byteBuffer);\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/basemediaformat/AvcNalUnitStorageBox.java",
    "content": "/*\n * Copyright 2011 castLabs, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.boxes.basemediaformat;\n\nimport com.googlecode.mp4parser.AbstractBox;\nimport com.coremedia.iso.boxes.h264.AvcConfigurationBox;\n\nimport java.io.ByteArrayOutputStream;\nimport java.nio.ByteBuffer;\nimport java.util.Arrays;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\n/**\n * The AVC NAL Unit Storage Box SHALL contain an AVCDecoderConfigurationRecord,\n * as defined in section 5.2.4.1 of the ISO 14496-12.\n */\npublic class AvcNalUnitStorageBox extends AbstractBox {\n    byte[] data;\n\n    public AvcNalUnitStorageBox() {\n        super(\"avcn\");\n    }\n\n\n    public AvcNalUnitStorageBox(AvcConfigurationBox avcConfigurationBox) {\n        super(\"avcn\");\n        ByteArrayOutputStream baos = new ByteArrayOutputStream();\n\n        ByteBuffer content = ByteBuffer.allocate(l2i(avcConfigurationBox.getContentSize()));\n        avcConfigurationBox.getContent(content);\n        data = content.array();\n    }\n\n    @Override\n    protected long getContentSize() {\n        return data.length;\n    }\n\n\n    public void setData(byte[] data) {\n        this.data = data;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        data = new byte[content.remaining()];\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        byteBuffer.put(data);\n    }\n\n    @Override\n    public String toString() {\n        return \"AvcNalUnitStorageBox{\" +\n                \"data=\" + Arrays.toString(data) +\n                '}';\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/basemediaformat/SampleEncryptionBox.java",
    "content": "package com.googlecode.mp4parser.boxes.basemediaformat;\n\nimport com.googlecode.mp4parser.boxes.AbstractSampleEncryptionBox;\n\n/**\n * aligned(8) class AbstractSampleEncryptionBox extends FullBox(‘uuid’, extended_type= 0xA2394F52-5A9B-4f14-A244-6C427C648DF4, version=0, flags=0)\n * {\n * <p/>\n * unsigned int (32) sample_count;\n * {\n * unsigned int(16) InitializationVector;\n * }[ sample_count ]\n * }\n */\npublic class SampleEncryptionBox extends AbstractSampleEncryptionBox {\n\n    /**\n     * Creates a SampleEncryptionBox for non-h264 tracks.\n     */\n    public SampleEncryptionBox() {\n        super(\"senc\");\n\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/basemediaformat/TrackEncryptionBox.java",
    "content": "package com.googlecode.mp4parser.boxes.basemediaformat;\n\nimport com.googlecode.mp4parser.boxes.AbstractTrackEncryptionBox;\n\n/**\n *\n */\npublic class TrackEncryptionBox extends AbstractTrackEncryptionBox {\n    public TrackEncryptionBox() {\n        super(\"tenc\");\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/mp4/AbstractDescriptorBox.java",
    "content": "/*\n * Copyright 2011 castLabs, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.boxes.mp4;\n\nimport com.googlecode.mp4parser.AbstractFullBox;\nimport com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BaseDescriptor;\nimport com.googlecode.mp4parser.boxes.mp4.objectdescriptors.ObjectDescriptorFactory;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n/**\n * ES Descriptor Box.\n */\npublic class AbstractDescriptorBox extends AbstractFullBox {\n    private static Logger log = Logger.getLogger(AbstractDescriptorBox.class.getName());\n\n\n    public BaseDescriptor descriptor;\n    public ByteBuffer data;\n\n    public AbstractDescriptorBox(String type) {\n        super(type);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        data.rewind(); // has been fforwarded by parsing\n        byteBuffer.put(data);\n    }\n\n    @Override\n    protected long getContentSize() {\n        return 4 + data.limit();\n    }\n\n    public BaseDescriptor getDescriptor() {\n        return descriptor;\n    }\n\n    public String getDescriptorAsString() {\n        return descriptor.toString();\n    }\n\n    public void setData(ByteBuffer data) {\n        this.data = data;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        data = content.slice();\n        content.position(content.position() + content.remaining());\n        try {\n            data.rewind();\n            descriptor = ObjectDescriptorFactory.createFrom(-1, data);\n        } catch (IOException e) {\n            log.log(Level.WARNING, \"Error parsing ObjectDescriptor\", e);\n            //that's why we copied it ;)\n        } catch (IndexOutOfBoundsException e) {\n            log.log(Level.WARNING, \"Error parsing ObjectDescriptor\", e);\n            //that's why we copied it ;)\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/mp4/ESDescriptorBox.java",
    "content": "/*\n * Copyright 2011 castLabs, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.boxes.mp4;\n\nimport com.googlecode.mp4parser.boxes.mp4.objectdescriptors.ESDescriptor;\n\n/**\n * ES Descriptor Box.\n */\npublic class ESDescriptorBox extends AbstractDescriptorBox {\n    public static final String TYPE = \"esds\";\n\n    public ESDescriptorBox() {\n        super(TYPE);\n    }\n\n    public ESDescriptor getEsDescriptor() {\n        return (ESDescriptor) super.getDescriptor();\n    }\n\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/mp4/ObjectDescriptorBox.java",
    "content": "/*\n * Copyright 2011 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.boxes.mp4;\n\n/**\n * This object contains an Object Descriptor or an Initial Object Descriptor.\n * There are a number of possible file types based on usage, depending on the descriptor:\n * <ul>\n * <li>Presentation, contains IOD which contains a BIFS stream (MP4 file);\n * <li>Sub-part of a presentation, contains an IOD without a BIFS stream (MP4 file);</li>\n * <li>Sub-part of a presentation, contains an OD (MP4 file);</li>\n * <li>Free-form file, referenced by MP4 data references (free-format);</li>\n * <li>Sub-part of a presentation, referenced by an ES URL.</li>\n * </ul>\n * NOTE: <br/>\n * The first three are MP4 files, a file referenced by a data reference is not necessarily an MP4 file, as it is\n * free-format. Files referenced by ES URLs, by data references, or intended as input to an editing process, need not have\n * an Object Descriptor Box. <br/>\n * An OD URL may point to an MP4 file. Implicitly, the target of such a URL is the OD/IOD located in the 'iods'\n * atom in that file.</br/>\n * If an MP4 file contains several object descriptors, only the OD/IOD in the 'iods' atom can be addressed using\n * an OD URL from a remote MPEG-4 presentation.\n */\npublic class ObjectDescriptorBox extends AbstractDescriptorBox {\n    public static final String TYPE = \"iods\";\n\n    public ObjectDescriptorBox() {\n        super(TYPE);\n    }\n\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/mp4/objectdescriptors/AudioSpecificConfig.java",
    "content": "/*\n * Copyright 2011 castLabs, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.boxes.mp4.objectdescriptors;\n\nimport com.coremedia.iso.IsoTypeWriter;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.util.HashMap;\nimport java.util.Map;\n\n\n//\n//GetAudioObjectType()\n//{\n//audioObjectType; 5 uimsbf\n//if (audioObjectType == 31) {\n//audioObjectType = 32 + audioObjectTypeExt; 6 uimsbf\n//}\n//return audioObjectType;\n//}\n//AudioSpecificConfig ()\n//{\n//audioObjectType = GetAudioObjectType();\n//samplingFrequencyIndex; 4 bslbf\n//if ( samplingFrequencyIndex == 0xf ) {\n//samplingFrequency; 24 uimsbf\n//}\n//channelConfiguration; 4 bslbf\n//sbrPresentFlag = -1;\n//psPresentFlag = -1;\n//if ( audioObjectType == 5 ||\n//audioObjectType == 29 ) {\n//extensionAudioObjectType = 5;\n//sbrPresentFlag = 1;\n//if ( audioObjectType == 29 ) {\n//psPresentFlag = 1;\n//}\n//extensionSamplingFrequencyIndex; 4 uimsbf\n//if ( extensionSamplingFrequencyIndex == 0xf )\n//extensionSamplingFrequency; 24 uimsbf\n//audioObjectType = GetAudioObjectType();\n//if ( audioObjectType == 22 )\n//extensionChannelConfiguration; 4 uimsbf\n//}\n//else {\n//extensionAudioObjectType = 0;\n//}\n//switch (audioObjectType) {\n//case 1:\n//case 2:\n//case 3:\n//case 4:\n//case 6:\n//case 7:\n//case 17:\n//case 19:\n//case 20:\n//case 21:\n//case 22:\n//case 23:\n//GASpecificConfig();\n//break:\n//case 8:\n//CelpSpecificConfig();\n//break;\n//case 9:\n//HvxcSpecificConfig();\n//break:\n//case 12:\n//TTSSpecificConfig();\n//break;\n//case 13:\n//case 14:\n//case 15:\n//case 16:\n//StructuredAudioSpecificConfig();\n//break;\n//case 24:\n//ErrorResilientCelpSpecificConfig();\n//break;\n//case 25:\n//ErrorResilientHvxcSpecificConfig();\n//break;\n//case 26:\n//case 27:\n//ParametricSpecificConfig();\n//break;\n// case 28:\n//SSCSpecificConfig();\n//break;\n//case 30:\n//sacPayloadEmbedding; 1 uimsbf\n//SpatialSpecificConfig();\n//break;\n//case 32:\n//case 33:\n//case 34:\n//MPEG_1_2_SpecificConfig();\n//break;\n//case 35:\n//DSTSpecificConfig();\n//break;\n//case 36:\n//fillBits; 5 bslbf\n//ALSSpecificConfig();\n//break;\n//case 37:\n//case 38:\n//SLSSpecificConfig();\n//break;\n//case 39:\n//ELDSpecificConfig(channelConfiguration);\n//break:\n//case 40:\n//case 41:\n//SymbolicMusicSpecificConfig();\n//break;\n//default:\n///* reserved */\n//}\n//switch (audioObjectType) {\n//case 17:\n//case 19:\n//case 20:\n//case 21:\n//case 22:\n//case 23:\n//case 24:\n//case 25:\n//case 26:\n//case 27:\n//case 39:\n//epConfig; 2 bslbf\n//if ( epConfig == 2 || epConfig == 3 ) {\n//ErrorProtectionSpecificConfig();\n//}\n//if ( epConfig == 3 ) {\n//directMapping; 1 bslbf\n//if ( ! directMapping ) {\n///* tbd */\n//}\n//}\n//}\n//if ( extensionAudioObjectType != 5 && bits_to_decode() >= 16 ) {\n//syncExtensionType; 11 bslbf\n//if (syncExtensionType == 0x2b7) {\n//        extensionAudioObjectType = GetAudioObjectType();\n//if ( extensionAudioObjectType == 5 ) {\n//sbrPresentFlag; 1 uimsbf\n//if (sbrPresentFlag == 1) {\n//extensionSamplingFrequencyIndex; 4 uimsbf\n//if ( extensionSamplingFrequencyIndex == 0xf ) {\n//extensionSamplingFrequency; 24 uimsbf\n//}\n//if ( bits_to_decode() >= 12 ) {\n//syncExtensionType; 11 bslbf\n//if (syncExtesionType == 0x548) {\n//psPresentFlag; 1 uimsbf\n//}\n//}\n//}\n//}\n//if ( extensionAudioObjectType == 22 ) {\n//sbrPresentFlag; 1 uimsbf\n//if (sbrPresentFlag == 1) {\n//extensionSamplingFrequencyIndex; 4 uimsbf\n//if ( extensionSamplingFrequencyIndex == 0xf ) {\n//extensionSamplingFrequency; 24 uimsbf\n//}\n//}\n//extensionChannelConfiguration; 4 uimsbf\n//}\n//}\n//}\n//}\n//        }\n//\n// TFCodingType\n//0x0 AAC scaleable\n//0x1 BSAC\n//0x2 TwinVQ\n//0x3 AAC non scaleable (i.e. multichannel)\n//\n// class TFSpecificConfig( uint(4) samplingFrequencyIndex, uint(4) channelConfiguration ) {\n//uint(2) TFCodingType;\n//uint(1) frameLength;\n//uint(1) dependsOnCoreCoder;\n//if (dependsOnCoreCoder == 1){\n//uint(14)coreCoderDelay\n//}\n//if (TFCodingType==BSAC) {\n//uint(11) lslayer_length\n//}\n//uint (1) extensionFlag;\n//if (channelConfiguration == 0 ){\n//program_config_element();\n//}\n//if (extensionFlag==1){\n//<to be defined in mpeg4 phase 2>\n//}\n//}\n//\n//program_config_element()\n//{\n//element_instance_tag 4 uimsbf\n//profile 2 uimsbf\n//sampling_frequency_index 4 uimsbf\n//num_front_channel_elements 4 uimsbf\n//num_side_channel_elements 4 uimsbf\n//num_back_channel_elements 4 uimsbf\n// num_lfe_channel_elements 2 uimsbf\n//num_assoc_data_elements 3 uimsbf\n//num_valid_cc_elements 4 uimsbf\n//mono_mixdown_present 1 uimsbf\n//if ( mono_mixdown_present == 1 )\n//mono_mixdown_element_number 4 uimsbf\n//stereo_mixdown_present 1 uimsbf\n//if ( stereo_mixdown_present == 1 )\n//stereo_mixdown_element_number 4 uimsbf\n//matrix_mixdown_idx_present 1 uimsbf\n//if ( matrix_mixdown_idx_present == 1 ) {\n//matrix_mixdown_idx 2 uimsbf\n//pseudo_surround_enable 1 uimsbf\n//}\n//for ( i = 0; i < num_front_channel_elements; i++) {\n//front_element_is_cpe[i]; 1 bslbf\n//front_element_tag_select[i]; 4 uimsbf\n//}\n//for ( i = 0; i < num_side_channel_elements; i++) {\n//side_element_is_cpe[i]; 1 bslbf\n//side_element_tag_select[i]; 4 uimsbf\n//}\n//for ( i = 0; i < num_back_channel_elements; i++) {\n//back_element_is_cpe[i]; 1 bslbf\n//back_element_tag_select[i]; 4 uimsbf\n//}\n//for ( i = 0; i < num_lfe_channel_elements; i++)\n//lfe_element_tag_select[i]; 4 uimsbf\n//for ( i = 0; i < num_assoc_data_elements; i++)\n//assoc_data_element_tag_select[i]; 4 uimsbf\n//for ( i = 0; i < num_valid_cc_elements; i++) {\n//cc_element_is_ind_sw[i]; 1 uimsbf\n//valid_cc_element_tag_select[i]; 4 uimsbf\n//}\n//byte_alignment()\n//comment_field_bytes 8 uimsbf\n//for ( i = 0; i < comment_field_bytes; i++)\n//comment_field_data[i]; 8 uimsbf\n//}\n\n@Descriptor(tags = 0x5, objectTypeIndication = 0x40)\npublic class AudioSpecificConfig extends BaseDescriptor {\n    ByteBuffer configBytes;\n    long endPos;\n\n    public static Map<Integer, Integer> samplingFrequencyIndexMap = new HashMap<Integer, Integer>();\n    public static Map<Integer, String> audioObjectTypeMap = new HashMap<Integer, String>();\n    int audioObjectType;\n    int samplingFrequencyIndex;\n    int samplingFrequency;\n    int channelConfiguration;\n    int extensionAudioObjectType;\n    int sbrPresentFlag;\n    int psPresentFlag;\n    int extensionSamplingFrequencyIndex;\n    int extensionSamplingFrequency;\n    int extensionChannelConfiguration;\n    int sacPayloadEmbedding;\n    int fillBits;\n    int epConfig;\n    int directMapping;\n    int syncExtensionType;\n\n    //GASpecificConfig\n    int frameLengthFlag;\n    int dependsOnCoreCoder;\n    int coreCoderDelay;\n    int extensionFlag;\n    int layerNr;\n    int numOfSubFrame;\n    int layer_length;\n    int aacSectionDataResilienceFlag;\n    int aacScalefactorDataResilienceFlag;\n    int aacSpectralDataResilienceFlag;\n    int extensionFlag3;\n    boolean gaSpecificConfig;\n\n    //ParametricSpecificConfig\n    int isBaseLayer;\n    int paraMode;\n    int paraExtensionFlag;\n    int hvxcVarMode;\n    int hvxcRateMode;\n    int erHvxcExtensionFlag;\n    int var_ScalableFlag;\n    int hilnQuantMode;\n    int hilnMaxNumLine;\n    int hilnSampleRateCode;\n    int hilnFrameLength;\n    int hilnContMode;\n    int hilnEnhaLayer;\n    int hilnEnhaQuantMode;\n    boolean parametricSpecificConfig;\n\n    @Override\n    public void parseDetail(ByteBuffer bb) throws IOException {\n        configBytes = bb.slice();\n        configBytes.limit(sizeOfInstance);\n        bb.position(bb.position() + sizeOfInstance);\n\n\n        BitReaderBuffer bitReaderBuffer = new BitReaderBuffer(configBytes);\n        audioObjectType = getAudioObjectType(bitReaderBuffer);\n        samplingFrequencyIndex = bitReaderBuffer.readBits(4);\n\n        if (samplingFrequencyIndex == 0xf) {\n            samplingFrequency = bitReaderBuffer.readBits(24);\n        }\n\n        channelConfiguration = bitReaderBuffer.readBits(4);\n\n        if (audioObjectType == 5 ||\n                audioObjectType == 29) {\n            extensionAudioObjectType = 5;\n            sbrPresentFlag = 1;\n            if (audioObjectType == 29) {\n                psPresentFlag = 1;\n            }\n            extensionSamplingFrequencyIndex = bitReaderBuffer.readBits(4);\n            if (extensionSamplingFrequencyIndex == 0xf)\n                extensionSamplingFrequency = bitReaderBuffer.readBits(24);\n            audioObjectType = getAudioObjectType(bitReaderBuffer);\n            if (audioObjectType == 22)\n                extensionChannelConfiguration = bitReaderBuffer.readBits(4);\n        } else {\n            extensionAudioObjectType = 0;\n        }\n\n        switch (audioObjectType) {\n            case 1:\n            case 2:\n            case 3:\n            case 4:\n            case 6:\n            case 7:\n            case 17:\n            case 19:\n            case 20:\n            case 21:\n            case 22:\n            case 23:\n                parseGaSpecificConfig(samplingFrequencyIndex, channelConfiguration, audioObjectType, bitReaderBuffer);\n                //GASpecificConfig();\n                break;\n            case 8:\n                throw new UnsupportedOperationException(\"can't parse CelpSpecificConfig yet\");\n                //CelpSpecificConfig();\n                //break;\n            case 9:\n                throw new UnsupportedOperationException(\"can't parse HvxcSpecificConfig yet\");\n                //HvxcSpecificConfig();\n                //break;\n            case 12:\n                throw new UnsupportedOperationException(\"can't parse TTSSpecificConfig yet\");\n                //TTSSpecificConfig();\n                //break;\n            case 13:\n            case 14:\n            case 15:\n            case 16:\n                throw new UnsupportedOperationException(\"can't parse StructuredAudioSpecificConfig yet\");\n                //StructuredAudioSpecificConfig();\n                //break;\n            case 24:\n                throw new UnsupportedOperationException(\"can't parse ErrorResilientCelpSpecificConfig yet\");\n                //ErrorResilientCelpSpecificConfig();\n                //break;\n            case 25:\n                throw new UnsupportedOperationException(\"can't parse ErrorResilientHvxcSpecificConfig yet\");\n                //ErrorResilientHvxcSpecificConfig();\n                //break;\n            case 26:\n            case 27:\n                parseParametricSpecificConfig(samplingFrequencyIndex, channelConfiguration, audioObjectType, bitReaderBuffer);\n                //ParametricSpecificConfig();\n                break;\n            case 28:\n                throw new UnsupportedOperationException(\"can't parse SSCSpecificConfig yet\");\n                //SSCSpecificConfig();\n                //break;\n            case 30:\n                sacPayloadEmbedding = bitReaderBuffer.readBits(1);\n                throw new UnsupportedOperationException(\"can't parse SpatialSpecificConfig yet\");\n                //SpatialSpecificConfig();\n                //break;\n            case 32:\n            case 33:\n            case 34:\n                throw new UnsupportedOperationException(\"can't parse MPEG_1_2_SpecificConfig yet\");\n                //MPEG_1_2_SpecificConfig();\n                //break;\n            case 35:\n                throw new UnsupportedOperationException(\"can't parse DSTSpecificConfig yet\");\n                //DSTSpecificConfig();\n                //break;\n            case 36:\n                fillBits = bitReaderBuffer.readBits(5);\n                throw new UnsupportedOperationException(\"can't parse ALSSpecificConfig yet\");\n                //ALSSpecificConfig();\n                //break;\n            case 37:\n            case 38:\n                throw new UnsupportedOperationException(\"can't parse SLSSpecificConfig yet\");\n                //SLSSpecificConfig();\n                //break;\n            case 39:\n                throw new UnsupportedOperationException(\"can't parse ELDSpecificConfig yet\");\n                //ELDSpecificConfig(channelConfiguration);\n                //break;\n            case 40:\n            case 41:\n                throw new UnsupportedOperationException(\"can't parse SymbolicMusicSpecificConfig yet\");\n                //SymbolicMusicSpecificConfig();\n                //break;\n            default:\n                /* reserved */\n        }\n\n        switch (audioObjectType) {\n            case 17:\n            case 19:\n            case 20:\n            case 21:\n            case 22:\n            case 23:\n            case 24:\n            case 25:\n            case 26:\n            case 27:\n            case 39:\n                epConfig = bitReaderBuffer.readBits(2);\n                if (epConfig == 2 || epConfig == 3) {\n                    throw new UnsupportedOperationException(\"can't parse ErrorProtectionSpecificConfig yet\");\n                    //ErrorProtectionSpecificConfig();\n                }\n                if (epConfig == 3) {\n                    directMapping = bitReaderBuffer.readBits(1);\n                    if (directMapping == 0) {\n                        /* tbd */\n                        throw new RuntimeException(\"not implemented\");\n                    }\n                }\n        }\n\n        if (extensionAudioObjectType != 5 && bitReaderBuffer.remainingBits() >= 16) {\n            syncExtensionType = bitReaderBuffer.readBits(11);\n            if (syncExtensionType == 0x2b7) {\n                extensionAudioObjectType = getAudioObjectType(bitReaderBuffer);\n                if (extensionAudioObjectType == 5) {\n                    sbrPresentFlag = bitReaderBuffer.readBits(1);\n                    if (sbrPresentFlag == 1) {\n                        extensionSamplingFrequencyIndex = bitReaderBuffer.readBits(4);\n                        if (extensionSamplingFrequencyIndex == 0xf) {\n                            extensionSamplingFrequency = bitReaderBuffer.readBits(24);\n                        }\n                        if (bitReaderBuffer.remainingBits() >= 12) {\n                            syncExtensionType = bitReaderBuffer.readBits(11); //10101001000\n                            if (syncExtensionType == 0x548) {\n                                psPresentFlag = bitReaderBuffer.readBits(1);\n                            }\n                        }\n                    }\n                }\n                if (extensionAudioObjectType == 22) {\n                    sbrPresentFlag = bitReaderBuffer.readBits(1);\n                    if (sbrPresentFlag == 1) {\n                        extensionSamplingFrequencyIndex = bitReaderBuffer.readBits(4);\n                        if (extensionSamplingFrequencyIndex == 0xf) {\n                            extensionSamplingFrequency = bitReaderBuffer.readBits(24);\n                        }\n                    }\n                    extensionChannelConfiguration = bitReaderBuffer.readBits(4);\n                }\n            }\n        }\n    }\n\n    private int gaSpecificConfigSize() {\n        return 0;\n    }\n\n    public int serializedSize() {\n        int out = 4;\n        if (audioObjectType == 2) {\n            out += gaSpecificConfigSize();\n        } else {\n            throw new UnsupportedOperationException(\"can't serialize that yet\");\n        }\n        return out;\n    }\n\n    public ByteBuffer serialize() {\n        ByteBuffer out = ByteBuffer.allocate(serializedSize());\n        IsoTypeWriter.writeUInt8(out, 5);\n        IsoTypeWriter.writeUInt8(out, serializedSize() - 2);\n        BitWriterBuffer bwb = new BitWriterBuffer(out);\n        bwb.writeBits(audioObjectType, 5);\n        bwb.writeBits(samplingFrequencyIndex, 4);\n        if (samplingFrequencyIndex == 0xf) {\n            throw new UnsupportedOperationException(\"can't serialize that yet\");\n        }\n        bwb.writeBits(channelConfiguration, 4);\n\n        // Don't support any extensions, unusual GASpecificConfig other than the default or anything...\n\n        return out;\n    }\n\n    private int getAudioObjectType(BitReaderBuffer in) throws IOException {\n        int audioObjectType = in.readBits(5);\n        if (audioObjectType == 31) {\n            audioObjectType = 32 + in.readBits(6);\n        }\n        return audioObjectType;\n    }\n\n    private void parseGaSpecificConfig(int samplingFrequencyIndex, int channelConfiguration, int audioObjectType, BitReaderBuffer in) throws IOException {\n//    GASpecificConfig (samplingFrequencyIndex,\n//            channelConfiguration,\n//            audioObjectType)\n//    {\n        frameLengthFlag = in.readBits(1);\n        dependsOnCoreCoder = in.readBits(1);\n        if (dependsOnCoreCoder == 1) {\n            coreCoderDelay = in.readBits(14);\n        }\n        extensionFlag = in.readBits(1);\n        if (channelConfiguration == 0) {\n            throw new UnsupportedOperationException(\"can't parse program_config_element yet\");\n            //program_config_element ();\n        }\n        if ((audioObjectType == 6) || (audioObjectType == 20)) {\n            layerNr = in.readBits(3);\n        }\n        if (extensionFlag == 1) {\n            if (audioObjectType == 22) {\n                numOfSubFrame = in.readBits(5);\n                layer_length = in.readBits(11);\n            }\n            if (audioObjectType == 17 || audioObjectType == 19 ||\n                    audioObjectType == 20 || audioObjectType == 23) {\n                aacSectionDataResilienceFlag = in.readBits(1);\n                aacScalefactorDataResilienceFlag = in.readBits(1);\n                aacSpectralDataResilienceFlag = in.readBits(1);\n            }\n            extensionFlag3 = in.readBits(1);\n            if (extensionFlag3 == 1) {\n                /* tbd in version 3 */\n            }\n        }\n//    }\n        gaSpecificConfig = true;\n    }\n\n    private void parseParametricSpecificConfig(int samplingFrequencyIndex, int channelConfiguration, int audioObjectType, BitReaderBuffer in) throws IOException {\n        /*\n        ParametricSpecificConfig() {\n            isBaseLayer; 1 uimsbf\n            if (isBaseLayer) {\n                PARAconfig();\n            } else {\n                HILNenexConfig();\n            }\n        }\n        */\n        isBaseLayer = in.readBits(1);\n        if (isBaseLayer == 1) {\n            parseParaConfig(samplingFrequencyIndex, channelConfiguration, audioObjectType, in);\n        } else {\n            parseHilnEnexConfig(samplingFrequencyIndex, channelConfiguration, audioObjectType, in);\n        }\n    }\n\n    private void parseParaConfig(int samplingFrequencyIndex, int channelConfiguration, int audioObjectType, BitReaderBuffer in) throws IOException {\n        /*\n        PARAconfig()\n        {\n            PARAmode; 2 uimsbf\n            if (PARAmode != 1) {\n                ErHVXCconfig();\n            }\n            if (PARAmode != 0) {\n                HILNconfig();\n            }\n            PARAextensionFlag; 1 uimsbf\n            if (PARAextensionFlag) {\n                // to be defined in MPEG-4 Phase 3\n            }\n        }\n        */\n        paraMode = in.readBits(2);\n\n        if (paraMode != 1) {\n            parseErHvxcConfig(samplingFrequencyIndex, channelConfiguration, audioObjectType, in);\n        }\n        if (paraMode != 0) {\n            parseHilnConfig(samplingFrequencyIndex, channelConfiguration, audioObjectType, in);\n        }\n\n        paraExtensionFlag = in.readBits(1);\n        parametricSpecificConfig = true;\n    }\n\n    private void parseErHvxcConfig(int samplingFrequencyIndex, int channelConfiguration, int audioObjectType, BitReaderBuffer in) throws IOException {\n        /*\n        ErHVXCconfig()\n        {\n            HVXCvarMode; 1 uimsbf\n                HVXCrateMode; 2 uimsbf\n                extensionFlag; 1 uimsbf\n            if (extensionFlag) {\n                var_ScalableFlag; 1 uimsbf\n            }\n        }\n        */\n        hvxcVarMode = in.readBits(1);\n        hvxcRateMode = in.readBits(2);\n        erHvxcExtensionFlag = in.readBits(1);\n\n        if (erHvxcExtensionFlag == 1) {\n            var_ScalableFlag = in.readBits(1);\n        }\n    }\n\n    private void parseHilnConfig(int samplingFrequencyIndex, int channelConfiguration, int audioObjectType, BitReaderBuffer in) throws IOException {\n        /*\n        HILNconfig()\n        {\n            HILNquantMode; 1 uimsbf\n            HILNmaxNumLine; 8 uimsbf\n            HILNsampleRateCode; 4 uimsbf\n            HILNframeLength; 12 uimsbf\n            HILNcontMode; 2 uimsbf\n        }\n        */\n        hilnQuantMode = in.readBits(1);\n        hilnMaxNumLine = in.readBits(8);\n        hilnSampleRateCode = in.readBits(4);\n        hilnFrameLength = in.readBits(12);\n        hilnContMode = in.readBits(2);\n    }\n\n    private void parseHilnEnexConfig(int samplingFrequencyIndex, int channelConfiguration, int audioObjectType, BitReaderBuffer in) throws IOException {\n        /*\n        HILNenexConfig()\n        {\n            HILNenhaLayer; 1 uimsbf\n            if (HILNenhaLayer) {\n                HILNenhaQuantMode; 2 uimsbf\n            }\n        }\n        */\n        hilnEnhaLayer = in.readBits(1);\n        if (hilnEnhaLayer == 1) {\n            hilnEnhaQuantMode = in.readBits(2);\n        }\n    }\n\n    public ByteBuffer getConfigBytes() {\n        return configBytes;\n    }\n\n    public int getAudioObjectType() {\n        return audioObjectType;\n    }\n\n    public int getExtensionAudioObjectType() {\n        return extensionAudioObjectType;\n    }\n\n    public int getSbrPresentFlag() {\n        return sbrPresentFlag;\n    }\n\n    public int getPsPresentFlag() {\n        return psPresentFlag;\n    }\n\n    public void setAudioObjectType(int audioObjectType) {\n        this.audioObjectType = audioObjectType;\n    }\n\n    public void setSamplingFrequencyIndex(int samplingFrequencyIndex) {\n        this.samplingFrequencyIndex = samplingFrequencyIndex;\n    }\n\n    public void setSamplingFrequency(int samplingFrequency) {\n        this.samplingFrequency = samplingFrequency;\n    }\n\n    public void setChannelConfiguration(int channelConfiguration) {\n        this.channelConfiguration = channelConfiguration;\n    }\n\n    @Override\n    public String toString() {\n        final StringBuilder sb = new StringBuilder();\n        sb.append(\"AudioSpecificConfig\");\n        sb.append(\"{configBytes=\").append(configBytes);\n        sb.append(\", audioObjectType=\").append(audioObjectType).append(\" (\").append(audioObjectTypeMap.get(audioObjectType)).append(\")\");\n        sb.append(\", samplingFrequencyIndex=\").append(samplingFrequencyIndex).append(\" (\").append(samplingFrequencyIndexMap.get(samplingFrequencyIndex)).append(\")\");\n        sb.append(\", samplingFrequency=\").append(samplingFrequency);\n        sb.append(\", channelConfiguration=\").append(channelConfiguration);\n        if (extensionAudioObjectType > 0) {\n            sb.append(\", extensionAudioObjectType=\").append(extensionAudioObjectType).append(\" (\").append(audioObjectTypeMap.get(extensionAudioObjectType)).append(\")\");\n            sb.append(\", sbrPresentFlag=\").append(sbrPresentFlag);\n            sb.append(\", psPresentFlag=\").append(psPresentFlag);\n            sb.append(\", extensionSamplingFrequencyIndex=\").append(extensionSamplingFrequencyIndex).append(\" (\").append(samplingFrequencyIndexMap.get(extensionSamplingFrequencyIndex)).append(\")\");\n            sb.append(\", extensionSamplingFrequency=\").append(extensionSamplingFrequency);\n            sb.append(\", extensionChannelConfiguration=\").append(extensionChannelConfiguration);\n        }\n//    sb.append(\", sacPayloadEmbedding=\").append(sacPayloadEmbedding);\n//    sb.append(\", fillBits=\").append(fillBits);\n//    sb.append(\", epConfig=\").append(epConfig);\n//    sb.append(\", directMapping=\").append(directMapping);\n        sb.append(\", syncExtensionType=\").append(syncExtensionType);\n        if (gaSpecificConfig) {\n            sb.append(\", frameLengthFlag=\").append(frameLengthFlag);\n            sb.append(\", dependsOnCoreCoder=\").append(dependsOnCoreCoder);\n            sb.append(\", coreCoderDelay=\").append(coreCoderDelay);\n            sb.append(\", extensionFlag=\").append(extensionFlag);\n            sb.append(\", layerNr=\").append(layerNr);\n            sb.append(\", numOfSubFrame=\").append(numOfSubFrame);\n            sb.append(\", layer_length=\").append(layer_length);\n            sb.append(\", aacSectionDataResilienceFlag=\").append(aacSectionDataResilienceFlag);\n            sb.append(\", aacScalefactorDataResilienceFlag=\").append(aacScalefactorDataResilienceFlag);\n            sb.append(\", aacSpectralDataResilienceFlag=\").append(aacSpectralDataResilienceFlag);\n            sb.append(\", extensionFlag3=\").append(extensionFlag3);\n        }\n        if (parametricSpecificConfig) {\n            sb.append(\", isBaseLayer=\").append(isBaseLayer);\n            sb.append(\", paraMode=\").append(paraMode);\n            sb.append(\", paraExtensionFlag=\").append(paraExtensionFlag);\n            sb.append(\", hvxcVarMode=\").append(hvxcVarMode);\n            sb.append(\", hvxcRateMode=\").append(hvxcRateMode);\n            sb.append(\", erHvxcExtensionFlag=\").append(erHvxcExtensionFlag);\n            sb.append(\", var_ScalableFlag=\").append(var_ScalableFlag);\n            sb.append(\", hilnQuantMode=\").append(hilnQuantMode);\n            sb.append(\", hilnMaxNumLine=\").append(hilnMaxNumLine);\n            sb.append(\", hilnSampleRateCode=\").append(hilnSampleRateCode);\n            sb.append(\", hilnFrameLength=\").append(hilnFrameLength);\n            sb.append(\", hilnContMode=\").append(hilnContMode);\n            sb.append(\", hilnEnhaLayer=\").append(hilnEnhaLayer);\n            sb.append(\", hilnEnhaQuantMode=\").append(hilnEnhaQuantMode);\n        }\n        sb.append('}');\n        return sb.toString();\n    }\n\n    static {\n        // sampling_frequency_index sampling frequeny\n//0x0 96000\n//0x1 88200\n//0x2 64000\n//0x3 48000\n//0x4 44100\n//0x5 32000\n//0x6 24000\n//0x7 22050\n//0x8 16000\n//0x9 12000\n//0xa 11025\n//0xb 8000\n//0xc reserved\n//0xd reserved\n//0xe reserved\n//0xf reserved\n        samplingFrequencyIndexMap.put(0x0, 96000);\n        samplingFrequencyIndexMap.put(0x1, 88200);\n        samplingFrequencyIndexMap.put(0x2, 64000);\n        samplingFrequencyIndexMap.put(0x3, 48000);\n        samplingFrequencyIndexMap.put(0x4, 44100);\n        samplingFrequencyIndexMap.put(0x5, 32000);\n        samplingFrequencyIndexMap.put(0x6, 24000);\n        samplingFrequencyIndexMap.put(0x7, 22050);\n        samplingFrequencyIndexMap.put(0x8, 16000);\n        samplingFrequencyIndexMap.put(0x9, 12000);\n        samplingFrequencyIndexMap.put(0xa, 11025);\n        samplingFrequencyIndexMap.put(0xb, 8000);\n\n        /* audioObjectType IDs\n          0 Null\n        1 AAC main X X\n        2 AAC LC X X X X X X X\n        3 AAC SSR X X\n        4 AAC LTP X X X X\n        5 SBR X X\n        6 AAC Scalable X X X X\n        7 TwinVQ X X X\n        8 CELP X X X X X X\n        9 HVXC X X X X X\n        10 (reserved)\n        11 (reserved)\n        12 TTSI X X X X X X\n        13 Main synthetic X X\n        14 Wavetable synthesis X* X*\n        15 General MIDI X* X*\n        16 Algorithmic Synthesis and Audio FX X* X*\n        17 ER AAC LC X X X\n        18 (reserved)\n        19 ER AAC LTP X X\n        20 ER AAC Scalable X X X\n        21 ER TwinVQ X X\n        22 ER BSAC X X\n        23 ER AAC LD X X X X\n        24 ER CELP X X X\n        25 ER HVXC X X\n        26 ER HILN X\n        27 ER Parametric X\n        28 SSC\n        29 PS X\n        30 MPEG Surround\n        31 (escape)\n        32 Layer-1\n        33 Layer-2\n        34 Layer-3\n        35 DST\n        36 ALS\n        37 SLS\n        38 SLS non-core\n        39 ER AAC ELD\n        40 SMR Simple\n        41 SMR Main\n        */\n        audioObjectTypeMap.put(1, \"AAC main\");\n        audioObjectTypeMap.put(2, \"AAC LC\");\n        audioObjectTypeMap.put(3, \"AAC SSR\");\n        audioObjectTypeMap.put(4, \"AAC LTP\");\n        audioObjectTypeMap.put(5, \"SBR\");\n        audioObjectTypeMap.put(6, \"AAC Scalable\");\n        audioObjectTypeMap.put(7, \"TwinVQ\");\n        audioObjectTypeMap.put(8, \"CELP\");\n        audioObjectTypeMap.put(9, \"HVXC\");\n        audioObjectTypeMap.put(10, \"(reserved)\");\n        audioObjectTypeMap.put(11, \"(reserved)\");\n        audioObjectTypeMap.put(12, \"TTSI\");\n        audioObjectTypeMap.put(13, \"Main synthetic\");\n        audioObjectTypeMap.put(14, \"Wavetable synthesis\");\n        audioObjectTypeMap.put(15, \"General MIDI\");\n        audioObjectTypeMap.put(16, \"Algorithmic Synthesis and Audio FX\");\n        audioObjectTypeMap.put(17, \"ER AAC LC\");\n        audioObjectTypeMap.put(18, \"(reserved)\");\n        audioObjectTypeMap.put(19, \"ER AAC LTP\");\n        audioObjectTypeMap.put(20, \"ER AAC Scalable\");\n        audioObjectTypeMap.put(21, \"ER TwinVQ\");\n        audioObjectTypeMap.put(22, \"ER BSAC\");\n        audioObjectTypeMap.put(23, \"ER AAC LD\");\n        audioObjectTypeMap.put(24, \"ER CELP\");\n        audioObjectTypeMap.put(25, \"ER HVXC\");\n        audioObjectTypeMap.put(26, \"ER HILN\");\n        audioObjectTypeMap.put(27, \"ER Parametric\");\n        audioObjectTypeMap.put(28, \"SSC\");\n        audioObjectTypeMap.put(29, \"PS\");\n        audioObjectTypeMap.put(30, \"MPEG Surround\");\n        audioObjectTypeMap.put(31, \"(escape)\");\n        audioObjectTypeMap.put(32, \"Layer-1\");\n        audioObjectTypeMap.put(33, \"Layer-2\");\n        audioObjectTypeMap.put(34, \"Layer-3\");\n        audioObjectTypeMap.put(35, \"DST\");\n        audioObjectTypeMap.put(36, \"ALS\");\n        audioObjectTypeMap.put(37, \"SLS\");\n        audioObjectTypeMap.put(38, \"SLS non-core\");\n        audioObjectTypeMap.put(39, \"ER AAC ELD\");\n        audioObjectTypeMap.put(40, \"SMR Simple\");\n        audioObjectTypeMap.put(41, \"SMR Main\");\n\n        /* profileLevelIds\n       0x00 Reserved for ISO use -\n     0x01 Main Audio Profile L1\n     0x02 Main Audio Profile L2\n     0x03 Main Audio Profile L3\n     0x04 Main Audio Profile L4\n     0x05 Scalable Audio Profile L1\n     0x06 Scalable Audio Profile L2\n     0x07 Scalable Audio Profile L3\n     0x08 Scalable Audio Profile L4\n     0x09 Speech Audio Profile L1\n     0x0A Speech Audio Profile L2\n     0x0B Synthetic Audio Profile L1\n     0x0C Synthetic Audio Profile L2\n     0x0D Synthetic Audio Profile L3\n     0x0E High Quality Audio Profile L1\n     0x0F High Quality Audio Profile L2\n     0x10 High Quality Audio Profile L3\n     0x11 High Quality Audio Profile L4\n     0x12 High Quality Audio Profile L5\n     0x13 High Quality Audio Profile L6\n     0x14 High Quality Audio Profile L7\n     0x15 High Quality Audio Profile L8\n     0x16 Low Delay Audio Profile L1\n     0x17 Low Delay Audio Profile L2\n     0x18 Low Delay Audio Profile L3\n     0x19 Low Delay Audio Profile L4\n     0x1A Low Delay Audio Profile L5\n     0x1B Low Delay Audio Profile L6\n     0x1C Low Delay Audio Profile L7\n     0x1D Low Delay Audio Profile L8\n     0x1E Natural Audio Profile L1\n     0x1F Natural Audio Profile L2\n     0x20 Natural Audio Profile L3\n     0x21 Natural Audio Profile L4\n     0x22 Mobile Audio Internetworking Profile L1\n     0x23 Mobile Audio Internetworking Profile L2\n     0x24 Mobile Audio Internetworking Profile L3\n     0x25 Mobile Audio Internetworking Profile L4\n     0x26 Mobile Audio Internetworking Profile L5\n     0x27 Mobile Audio Internetworking Profile L6\n     0x28 AAC Profile L1\n     0x29 AAC Profile L2\n     0x2A AAC Profile L4\n     0x2B AAC Profile L5\n     0x2C High Efficiency AAC Profile L2\n     0x2D High Efficiency AAC Profile L3\n     0x2E High Efficiency AAC Profile L4\n     0x2F High Efficiency AAC Profile L5\n     0x30 High Efficiency AAC v2 Profile L2\n     0x31 High Efficiency AAC v2 Profile L3\n     0x32 High Efficiency AAC v2 Profile L4\n     0x33 High Efficiency AAC v2 Profile L5\n     0x34 Low Delay AAC Profile L1\n     0x35 Baseline MPEG Surround Profile (see ISO/IEC\n     23003-1)\n     L1\n     0x36 Baseline MPEG Surround Profile (see ISO/IEC\n     23003-1)\n     L2\n     0x37 Baseline MPEG Surround Profile (see ISO/IEC\n     23003-1)\n     L3\n     0x38 Baseline MPEG Surround Profile (see ISO/IEC\n     23003-1)\n     L4\n     0c39 Baseline MPEG Surround Profile (see ISO/IEC\n     23003-1)\n     L5\n     0x3A Baseline MPEG Surround Profile (see ISO/IEC\n     23003-1)\n     L6\n     0x3B - 0x7F reserved for ISO use -\n     0x80 - 0xFD user private -\n     0xFE no audio profile specified -\n     0xFF no audio capability required -\n\n        */\n    }\n\n\n    public int getSamplingFrequency() {\n        return samplingFrequencyIndex == 0xf ? samplingFrequency : samplingFrequencyIndexMap.get(samplingFrequencyIndex);\n    }\n\n    public int getChannelConfiguration() {\n        return channelConfiguration;\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/mp4/objectdescriptors/BaseDescriptor.java",
    "content": "/*\n * Copyright 2011 castLabs, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.boxes.mp4.objectdescriptors;\n\nimport com.coremedia.iso.IsoTypeReader;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\n\n/*\nabstract aligned(8) expandable(228-1) class BaseDescriptor : bit(8) tag=0 {\n// empty. To be filled by classes extending this class.\n}\n\nint sizeOfInstance = 0;\nbit(1) nextByte;\nbit(7) sizeOfInstance;\nwhile(nextByte) {\nbit(1) nextByte;\nbit(7) sizeByte;\nsizeOfInstance = sizeOfInstance<<7 | sizeByte;\n}\n */\n@Descriptor(tags = 0x00)\npublic abstract class BaseDescriptor {\n    int tag;\n    int sizeOfInstance;\n    int sizeBytes;\n\n    public BaseDescriptor() {\n    }\n\n    public int getTag() {\n        return tag;\n    }\n\n    public int getSize() {\n        return sizeOfInstance\n                + 1//1 for the tag\n                + sizeBytes;\n    }\n\n    public int getSizeOfInstance() {\n        return sizeOfInstance;\n    }\n\n    public int getSizeBytes() {\n        return sizeBytes;\n    }\n\n    public final void parse(int tag, ByteBuffer bb) throws IOException {\n        this.tag = tag;\n\n        int i = 0;\n        int tmp = IsoTypeReader.readUInt8(bb);\n        i++;\n        sizeOfInstance = tmp & 0x7f;\n        while (tmp >>> 7 == 1) { //nextbyte indicator bit\n            tmp = IsoTypeReader.readUInt8(bb);\n            i++;\n            //sizeOfInstance = sizeOfInstance<<7 | sizeByte;\n            sizeOfInstance = sizeOfInstance << 7 | tmp & 0x7f;\n        }\n        sizeBytes = i;\n        ByteBuffer detailSource = bb.slice();\n        detailSource.limit(sizeOfInstance);\n        parseDetail(detailSource);\n        assert detailSource.remaining() == 0: this.getClass().getSimpleName() + \" has not been fully parsed\";\n        bb.position(bb.position() + sizeOfInstance);\n    }\n    \n    public abstract void parseDetail(ByteBuffer bb) throws IOException;\n\n\n\n    @Override\n    public String toString() {\n        final StringBuilder sb = new StringBuilder();\n        sb.append(\"BaseDescriptor\");\n        sb.append(\"{tag=\").append(tag);\n        sb.append(\", sizeOfInstance=\").append(sizeOfInstance);\n        sb.append('}');\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/mp4/objectdescriptors/BitReaderBuffer.java",
    "content": "package com.googlecode.mp4parser.boxes.mp4.objectdescriptors;\n\nimport java.nio.ByteBuffer;\n\npublic class BitReaderBuffer {\n\n    private ByteBuffer buffer;\n    int initialPos;\n    int position;\n\n    public BitReaderBuffer(ByteBuffer buffer) {\n        this.buffer = buffer;\n        initialPos = buffer.position();\n    }\n\n    public int readBits(int i) {\n        byte b = buffer.get(initialPos + position / 8);\n        int v = b < 0 ? b + 256 : b;\n        int left = 8 - position % 8;\n        int rc;\n        if (i <= left) {\n            rc = (v << (position % 8) & 0xFF) >> ((position % 8) + (left - i));\n            position += i;\n        } else {\n            int now = left;\n            int then = i - left;\n            rc = readBits(now);\n            rc = rc << then;\n            rc += readBits(then);\n        }\n        buffer.position(initialPos + (int) Math.ceil((double) position / 8));\n        return rc;\n    }\n\n    public int getPosition() {\n        return position;\n    }\n\n    public int byteSync() {\n        int left = 8 - position % 8;\n        if (left == 8) {\n            left = 0;\n        }\n        readBits(left);\n        return left;\n    }\n\n    public int remainingBits() {\n        return buffer.limit() * 8 - position;\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/mp4/objectdescriptors/BitWriterBuffer.java",
    "content": "package com.googlecode.mp4parser.boxes.mp4.objectdescriptors;\n\nimport java.nio.ByteBuffer;\n\npublic class BitWriterBuffer {\n\n    private ByteBuffer buffer;\n    int initialPos;\n    int position = 0;\n\n    public BitWriterBuffer(ByteBuffer buffer) {\n        this.buffer = buffer;\n        this.initialPos = buffer.position();\n    }\n\n    public void writeBits(int i, int numBits) {\n        int left = 8 - position % 8;\n        if (numBits <= left) {\n            int current = (buffer.get(initialPos + position / 8));\n            current = current < 0 ? current + 256 : current;\n            current += i << (left - numBits);\n            buffer.put(initialPos + position / 8, (byte) (current > 127 ? current - 256 : current));\n            position += numBits;\n        } else {\n            int bitsSecondWrite = numBits - left;\n            writeBits(i >> bitsSecondWrite, left);\n            writeBits(i & (1 << bitsSecondWrite) - 1, bitsSecondWrite);\n        }\n        buffer.position(initialPos + position / 8 + ((position % 8 > 0) ? 1 : 0));\n    }\n\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/mp4/objectdescriptors/DecoderConfigDescriptor.java",
    "content": "/*\n * Copyright 2011 castLabs, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.boxes.mp4.objectdescriptors;\n\nimport com.coremedia.iso.Hex;\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.logging.Logger;\n\n/**\n * class DecoderConfigDescriptor extends BaseDescriptor : bit(8)\n * tag=DecoderConfigDescrTag {\n * bit(8) objectTypeIndication;\n * bit(6) streamType;\n * bit(1) upStream;\n * const bit(1) reserved=1;\n * bit(24) bufferSizeDB;\n * bit(32) maxBitrate;\n * bit(32) avgBitrate;\n * DecoderSpecificInfo decSpecificInfo[0 .. 1];\n * profileLevelIndicationIndexDescriptor profileLevelIndicationIndexDescr\n * [0..255];\n * }\n */\n@Descriptor(tags = {0x04})\npublic class DecoderConfigDescriptor extends BaseDescriptor {\n    private static Logger log = Logger.getLogger(DecoderConfigDescriptor.class.getName());\n\n\n    int objectTypeIndication;\n    int streamType;\n    int upStream;\n    int bufferSizeDB;\n    long maxBitRate;\n    long avgBitRate;\n\n    DecoderSpecificInfo decoderSpecificInfo;\n    AudioSpecificConfig audioSpecificInfo;\n    List<ProfileLevelIndicationDescriptor> profileLevelIndicationDescriptors = new ArrayList<ProfileLevelIndicationDescriptor>();\n    byte[] configDescriptorDeadBytes;\n\n    @Override\n    public void parseDetail(ByteBuffer bb) throws IOException {\n        objectTypeIndication = IsoTypeReader.readUInt8(bb);\n\n        int data = IsoTypeReader.readUInt8(bb);\n        streamType = data >>> 2;\n        upStream = (data >> 1) & 0x1;\n\n        bufferSizeDB = IsoTypeReader.readUInt24(bb);\n        maxBitRate = IsoTypeReader.readUInt32(bb);\n        avgBitRate = IsoTypeReader.readUInt32(bb);\n\n\n\n        BaseDescriptor descriptor;\n        if (bb.remaining() > 2) { //1byte tag + at least 1byte size\n            final int begin = bb.position();\n            descriptor = ObjectDescriptorFactory.createFrom(objectTypeIndication, bb);\n            final int read = bb.position() - begin;\n            log.finer(descriptor + \" - DecoderConfigDescr1 read: \" + read + \", size: \" + (descriptor != null ? descriptor.getSize() : null));\n            if (descriptor != null) {\n                final int size = descriptor.getSize();\n                if (read < size) {\n                    //skip\n                    configDescriptorDeadBytes = new byte[size - read];\n                    bb.get(configDescriptorDeadBytes);\n                }\n            }\n            if (descriptor instanceof DecoderSpecificInfo) {\n                decoderSpecificInfo = (DecoderSpecificInfo) descriptor;\n            }\n            if (descriptor instanceof AudioSpecificConfig) {\n                audioSpecificInfo = (AudioSpecificConfig) descriptor;\n            }\n        }\n\n        while (bb.remaining() > 2) {\n            final long begin = bb.position();\n            descriptor = ObjectDescriptorFactory.createFrom(objectTypeIndication, bb);\n            final long read = bb.position() - begin;\n            log.finer(descriptor + \" - DecoderConfigDescr2 read: \" + read + \", size: \" + (descriptor != null ? descriptor.getSize() : null));\n            if (descriptor instanceof ProfileLevelIndicationDescriptor) {\n                profileLevelIndicationDescriptors.add((ProfileLevelIndicationDescriptor) descriptor);\n            }\n        }\n    }\n    public int serializedSize() {\n        return 15 + audioSpecificInfo.serializedSize();\n    }\n\n    public ByteBuffer serialize() {\n        ByteBuffer out = ByteBuffer.allocate(serializedSize());\n        IsoTypeWriter.writeUInt8(out, 4);\n        IsoTypeWriter.writeUInt8(out, serializedSize() - 2);\n        IsoTypeWriter.writeUInt8(out, objectTypeIndication);\n        int flags = (streamType << 2) | (upStream << 1) | 1;\n        IsoTypeWriter.writeUInt8(out, flags);\n        IsoTypeWriter.writeUInt24(out, bufferSizeDB);\n        IsoTypeWriter.writeUInt32(out, maxBitRate);\n        IsoTypeWriter.writeUInt32(out, avgBitRate);\n        out.put(audioSpecificInfo.serialize().array());\n        return out;\n    }\n\n    public DecoderSpecificInfo getDecoderSpecificInfo() {\n        return decoderSpecificInfo;\n    }\n\n    public AudioSpecificConfig getAudioSpecificInfo() {\n        return audioSpecificInfo;\n    }\n\n    public void setAudioSpecificInfo(AudioSpecificConfig audioSpecificInfo) {\n        this.audioSpecificInfo = audioSpecificInfo;\n    }\n\n    public List<ProfileLevelIndicationDescriptor> getProfileLevelIndicationDescriptors() {\n        return profileLevelIndicationDescriptors;\n    }\n\n    public int getObjectTypeIndication() {\n        return objectTypeIndication;\n    }\n\n    public void setObjectTypeIndication(int objectTypeIndication) {\n        this.objectTypeIndication = objectTypeIndication;\n    }\n\n    public int getStreamType() {\n        return streamType;\n    }\n\n    public void setStreamType(int streamType) {\n        this.streamType = streamType;\n    }\n\n    public int getUpStream() {\n        return upStream;\n    }\n\n    public void setUpStream(int upStream) {\n        this.upStream = upStream;\n    }\n\n    public int getBufferSizeDB() {\n        return bufferSizeDB;\n    }\n\n    public void setBufferSizeDB(int bufferSizeDB) {\n        this.bufferSizeDB = bufferSizeDB;\n    }\n\n    public long getMaxBitRate() {\n        return maxBitRate;\n    }\n\n    public void setMaxBitRate(long maxBitRate) {\n        this.maxBitRate = maxBitRate;\n    }\n\n    public long getAvgBitRate() {\n        return avgBitRate;\n    }\n\n    public void setAvgBitRate(long avgBitRate) {\n        this.avgBitRate = avgBitRate;\n    }\n\n    @Override\n    public String toString() {\n        final StringBuilder sb = new StringBuilder();\n        sb.append(\"DecoderConfigDescriptor\");\n        sb.append(\"{objectTypeIndication=\").append(objectTypeIndication);\n        sb.append(\", streamType=\").append(streamType);\n        sb.append(\", upStream=\").append(upStream);\n        sb.append(\", bufferSizeDB=\").append(bufferSizeDB);\n        sb.append(\", maxBitRate=\").append(maxBitRate);\n        sb.append(\", avgBitRate=\").append(avgBitRate);\n        sb.append(\", decoderSpecificInfo=\").append(decoderSpecificInfo);\n        sb.append(\", audioSpecificInfo=\").append(audioSpecificInfo);\n        sb.append(\", configDescriptorDeadBytes=\").append(Hex.encodeHex(configDescriptorDeadBytes != null ? configDescriptorDeadBytes : new byte[]{}));\n        sb.append(\", profileLevelIndicationDescriptors=\").append(profileLevelIndicationDescriptors == null ? \"null\" : Arrays.asList(profileLevelIndicationDescriptors).toString());\n        sb.append('}');\n        return sb.toString();\n    }\n    /*objectTypeIndication values\n      0x00 Forbidden\n    0x01 Systems ISO/IEC 14496-1 a\n    0x02 Systems ISO/IEC 14496-1 b\n    0x03 Interaction Stream\n    0x04 Systems ISO/IEC 14496-1 Extended BIFS Configuration c\n    0x05 Systems ISO/IEC 14496-1 AFX d\n    0x06 Font Data Stream\n    0x07 Synthesized Texture Stream\n    0x08 Streaming Text Stream\n    0x09-0x1F reserved for ISO use\n    0x20 Visual ISO/IEC 14496-2 e\n    0x21 Visual ITU-T Recommendation H.264 | ISO/IEC 14496-10 f\n    0x22 Parameter Sets for ITU-T Recommendation H.264 | ISO/IEC 14496-10 f\n    0x23-0x3F reserved for ISO use\n    0x40 Audio ISO/IEC 14496-3 g\n    0x41-0x5F reserved for ISO use\n    0x60 Visual ISO/IEC 13818-2 Simple Profile\n    0x61 Visual ISO/IEC 13818-2 Main Profile\n    0x62 Visual ISO/IEC 13818-2 SNR Profile\n    0x63 Visual ISO/IEC 13818-2 Spatial Profile\n    0x64 Visual ISO/IEC 13818-2 High Profile\n    0x65 Visual ISO/IEC 13818-2 422 Profile\n    0x66 Audio ISO/IEC 13818-7 Main Profile\n    0x67 Audio ISO/IEC 13818-7 LowComplexity Profile\n    0x68 Audio ISO/IEC 13818-7 Scaleable Sampling Rate Profile\n    0x69 Audio ISO/IEC 13818-3\n    0x6A Visual ISO/IEC 11172-2\n    0x6B Audio ISO/IEC 11172-3\n    0x6C Visual ISO/IEC 10918-1\n    0x6D reserved for registration authority i\n    0x6E Visual ISO/IEC 15444-1\n    0x6F - 0x9F reserved for ISO use\n    0xA0 - 0xBF reserved for registration authority i\n    0xC0 - 0xE0 user private\n    0xE1 reserved for registration authority i\n    0xE2 - 0xFE user private\n    0xFF no object type specified h\n    */\n    /* streamType values\n      0x00 Forbidden\n    0x01 ObjectDescriptorStream (see 7.2.5)\n    0x02 ClockReferenceStream (see 7.3.2.5)\n    0x03 SceneDescriptionStream (see ISO/IEC 14496-11)\n    0x04 VisualStream\n    0x05 AudioStream\n    0x06 MPEG7Stream\n    0x07 IPMPStream (see 7.2.3.2)\n    0x08 ObjectContentInfoStream (see 7.2.4.2)\n    0x09 MPEGJStream\n    0x0A Interaction Stream\n    0x0B IPMPToolStream (see [ISO/IEC 14496-13])\n    0x0C - 0x1F reserved for ISO use\n    0x20 - 0x3F user private\n    */\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/mp4/objectdescriptors/DecoderSpecificInfo.java",
    "content": "/*\n * Copyright 2011 castLabs, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.boxes.mp4.objectdescriptors;\n\nimport com.coremedia.iso.Hex;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\n\n/**\n * abstract class DecoderSpecificInfo extends BaseDescriptor : bit(8)\n * tag=DecSpecificInfoTag\n * {\n * // empty. To be filled by classes extending this class.\n * }\n */\n@Descriptor(tags = 0x05)\npublic class DecoderSpecificInfo extends BaseDescriptor {\n    byte[] bytes;\n\n    @Override\n    public void parseDetail(ByteBuffer bb) throws IOException {\n        if (sizeOfInstance > 0) {\n            bytes = new byte[sizeOfInstance];\n            bb.get(bytes);\n        }\n    }\n\n    public int serializedSize() {\n        return bytes.length;\n    }\n\n    public ByteBuffer serialize() {\n        ByteBuffer out = ByteBuffer.wrap(bytes);\n\n        return out;\n    }\n\n    @Override\n    public String toString() {\n        final StringBuilder sb = new StringBuilder();\n        sb.append(\"DecoderSpecificInfo\");\n        sb.append(\"{bytes=\").append(bytes == null ? \"null\" : Hex.encodeHex(bytes));\n        sb.append('}');\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/mp4/objectdescriptors/Descriptor.java",
    "content": "/*\n * Copyright 2011 castLabs, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.boxes.mp4.objectdescriptors;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Created by IntelliJ IDEA.\n * User: mstattma\n * Date: 06.08.2010\n * Time: 06:54:58\n * To change this template use File | Settings | File Templates.\n */\n@Documented\n@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.RUNTIME)\npublic @interface Descriptor {\n    int[] tags();\n\n    int objectTypeIndication() default -1;\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/mp4/objectdescriptors/ESDescriptor.java",
    "content": "/*\n * Copyright 2011 castLabs, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.boxes.mp4.objectdescriptors;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.logging.Logger;\n\n/*\nclass ES_Descriptor extends BaseDescriptor : bit(8) tag=ES_DescrTag {\nbit(16) ES_ID;\nbit(1) streamDependenceFlag;\nbit(1) URL_Flag;\nbit(1) OCRstreamFlag;\nbit(5) streamPriority;\nif (streamDependenceFlag)\nbit(16) dependsOn_ES_ID;\nif (URL_Flag) {\nbit(8) URLlength;\nbit(8) URLstring[URLlength];\n}\nif (OCRstreamFlag)\nbit(16) OCR_ES_Id;\nDecoderConfigDescriptor decConfigDescr;\nif (ODProfileLevelIndication==0x01) //no SL extension.\n{\nSLConfigDescriptor slConfigDescr;\n}\nelse // SL extension is possible.\n{\nSLConfigDescriptor slConfigDescr;\n}\nIPI_DescrPointer ipiPtr[0 .. 1];\nIP_IdentificationDataSet ipIDS[0 .. 255];\nIPMP_DescriptorPointer ipmpDescrPtr[0 .. 255];\nLanguageDescriptor langDescr[0 .. 255];\nQoS_Descriptor qosDescr[0 .. 1];\nRegistrationDescriptor regDescr[0 .. 1];\nExtensionDescriptor extDescr[0 .. 255];\n}\n */\n@Descriptor(tags = {0x03})\npublic class ESDescriptor extends BaseDescriptor {\n    private static Logger log = Logger.getLogger(ESDescriptor.class.getName());\n\n    int esId;\n    int streamDependenceFlag;\n    int URLFlag;\n    int oCRstreamFlag;\n    int streamPriority;\n\n\n    int URLLength = 0;\n    String URLString;\n    int remoteODFlag;\n\n    int dependsOnEsId;\n    int oCREsId;\n\n    DecoderConfigDescriptor decoderConfigDescriptor;\n    SLConfigDescriptor slConfigDescriptor;\n    List<BaseDescriptor> otherDescriptors = new ArrayList<BaseDescriptor>();\n\n    @Override\n    public void parseDetail(ByteBuffer bb) throws IOException {\n        esId = IsoTypeReader.readUInt16(bb);\n\n        int data = IsoTypeReader.readUInt8(bb);\n        streamDependenceFlag = data >>> 7;\n        URLFlag = (data >>> 6) & 0x1;\n        oCRstreamFlag = (data >>> 5) & 0x1;\n        streamPriority = data & 0x1f;\n\n        if (streamDependenceFlag == 1) {\n            dependsOnEsId = IsoTypeReader.readUInt16(bb);\n        }\n        if (URLFlag == 1) {\n            URLLength = IsoTypeReader.readUInt8(bb);\n            URLString = IsoTypeReader.readString(bb, URLLength);\n        }\n        if (oCRstreamFlag == 1) {\n            oCREsId = IsoTypeReader.readUInt16(bb);\n        }\n\n        int baseSize = 1 /*tag*/ + getSizeBytes() + 2 + 1 + (streamDependenceFlag == 1 ? 2 : 0) + (URLFlag == 1 ? 1 + URLLength : 0) + (oCRstreamFlag == 1 ? 2 : 0);\n\n        int begin = bb.position();\n        if (getSize() > baseSize + 2) {\n            BaseDescriptor descriptor = ObjectDescriptorFactory.createFrom(-1, bb);\n            final long read = bb.position() - begin;\n            log.finer(descriptor + \" - ESDescriptor1 read: \" + read + \", size: \" + (descriptor != null ? descriptor.getSize() : null));\n            if (descriptor != null) {\n                final int size = descriptor.getSize();\n                bb.position(begin + size);\n                baseSize += size;\n            } else {\n                baseSize += read;\n            }\n            if (descriptor instanceof DecoderConfigDescriptor) {\n                decoderConfigDescriptor = (DecoderConfigDescriptor) descriptor;\n            }\n        }\n\n        begin = bb.position();\n        if (getSize() > baseSize + 2) {\n            BaseDescriptor descriptor = ObjectDescriptorFactory.createFrom(-1, bb);\n            final long read = bb.position() - begin;\n            log.finer(descriptor + \" - ESDescriptor2 read: \" + read + \", size: \" + (descriptor != null ? descriptor.getSize() : null));\n            if (descriptor != null) {\n                final int size = descriptor.getSize();\n                bb.position(begin + size);\n                baseSize += size;\n            } else {\n                baseSize += read;\n            }\n            if (descriptor instanceof SLConfigDescriptor) {\n                slConfigDescriptor = (SLConfigDescriptor) descriptor;\n            }\n        } else {\n            log.warning(\"SLConfigDescriptor is missing!\");\n        }\n\n        while (getSize() - baseSize > 2) {\n            begin = bb.position();\n            BaseDescriptor descriptor = ObjectDescriptorFactory.createFrom(-1, bb);\n            final long read = bb.position() - begin;\n            log.finer(descriptor + \" - ESDescriptor3 read: \" + read + \", size: \" + (descriptor != null ? descriptor.getSize() : null));\n            if (descriptor != null) {\n                final int size = descriptor.getSize();\n                bb.position(begin + size);\n                baseSize += size;\n            } else {\n                baseSize += read;\n            }\n            otherDescriptors.add(descriptor);\n        }\n    }\n    public int serializedSize() {\n        int out = 5;\n        if (streamDependenceFlag > 0) {\n            out += 2;\n        }\n        if (URLFlag > 0) {\n            out += 1 + URLLength;\n        }\n        if (oCRstreamFlag > 0) {\n            out += 2;\n        }\n\n        out += decoderConfigDescriptor.serializedSize();\n        out += slConfigDescriptor.serializedSize();\n\n        // Doesn't handle other descriptors yet\n\n        return out;\n    }\n\n    public ByteBuffer serialize() {\n        ByteBuffer out = ByteBuffer.allocate(serializedSize()); // Usually is around 30 bytes, so 200 should be enough...\n        IsoTypeWriter.writeUInt8(out, 3);\n        IsoTypeWriter.writeUInt8(out, serializedSize() - 2); // Not OK for longer sizes!\n        IsoTypeWriter.writeUInt16(out, esId);\n        int flags = (streamDependenceFlag << 7) | (URLFlag << 6) | (oCRstreamFlag << 5) | (streamPriority & 0x1f);\n        IsoTypeWriter.writeUInt8(out, flags);\n        if (streamDependenceFlag > 0) {\n            IsoTypeWriter.writeUInt16(out, dependsOnEsId);\n        }\n        if (URLFlag > 0) {\n            IsoTypeWriter.writeUInt8(out, URLLength);\n            IsoTypeWriter.writeUtf8String(out, URLString);\n        }\n        if (oCRstreamFlag > 0) {\n            IsoTypeWriter.writeUInt16(out, oCREsId);\n        }\n\n        ByteBuffer dec = decoderConfigDescriptor.serialize();\n        ByteBuffer sl = slConfigDescriptor.serialize();\n        out.put(dec.array());\n        out.put(sl.array());\n\n        // Doesn't handle other descriptors yet\n\n        return out;\n    }\n\n//  @Override\n//  public int getSize() {\n//    return 3 + (streamDependenceFlag == 1 ? 2 : 0) +\n//            (URLFlag == 1 ? 1 + 8 * URLLength : 0) +\n//            (oCRstreamFlag == 1 ? 2 : 0);\n//  }\n\n    public DecoderConfigDescriptor getDecoderConfigDescriptor() {\n        return decoderConfigDescriptor;\n    }\n\n    public SLConfigDescriptor getSlConfigDescriptor() {\n        return slConfigDescriptor;\n    }\n\n    public void setDecoderConfigDescriptor(DecoderConfigDescriptor decoderConfigDescriptor) {\n        this.decoderConfigDescriptor = decoderConfigDescriptor;\n    }\n\n    public void setSlConfigDescriptor(SLConfigDescriptor slConfigDescriptor) {\n        this.slConfigDescriptor = slConfigDescriptor;\n    }\n\n    public List<BaseDescriptor> getOtherDescriptors() {\n        return otherDescriptors;\n    }\n\n    public int getoCREsId() {\n        return oCREsId;\n    }\n\n    public void setoCREsId(int oCREsId) {\n        this.oCREsId = oCREsId;\n    }\n\n    public int getEsId() {\n        return esId;\n    }\n\n    public void setEsId(int esId) {\n        this.esId = esId;\n    }\n\n    public int getStreamDependenceFlag() {\n        return streamDependenceFlag;\n    }\n\n    public void setStreamDependenceFlag(int streamDependenceFlag) {\n        this.streamDependenceFlag = streamDependenceFlag;\n    }\n\n    public int getURLFlag() {\n        return URLFlag;\n    }\n\n    public void setURLFlag(int URLFlag) {\n        this.URLFlag = URLFlag;\n    }\n\n    public int getoCRstreamFlag() {\n        return oCRstreamFlag;\n    }\n\n    public void setoCRstreamFlag(int oCRstreamFlag) {\n        this.oCRstreamFlag = oCRstreamFlag;\n    }\n\n    public int getStreamPriority() {\n        return streamPriority;\n    }\n\n    public void setStreamPriority(int streamPriority) {\n        this.streamPriority = streamPriority;\n    }\n\n    public int getURLLength() {\n        return URLLength;\n    }\n\n    public void setURLLength(int URLLength) {\n        this.URLLength = URLLength;\n    }\n\n    public String getURLString() {\n        return URLString;\n    }\n\n    public void setURLString(String URLString) {\n        this.URLString = URLString;\n    }\n\n    public int getRemoteODFlag() {\n        return remoteODFlag;\n    }\n\n    public void setRemoteODFlag(int remoteODFlag) {\n        this.remoteODFlag = remoteODFlag;\n    }\n\n    public int getDependsOnEsId() {\n        return dependsOnEsId;\n    }\n\n    public void setDependsOnEsId(int dependsOnEsId) {\n        this.dependsOnEsId = dependsOnEsId;\n    }\n\n    @Override\n    public String toString() {\n        final StringBuilder sb = new StringBuilder();\n        sb.append(\"ESDescriptor\");\n        sb.append(\"{esId=\").append(esId);\n        sb.append(\", streamDependenceFlag=\").append(streamDependenceFlag);\n        sb.append(\", URLFlag=\").append(URLFlag);\n        sb.append(\", oCRstreamFlag=\").append(oCRstreamFlag);\n        sb.append(\", streamPriority=\").append(streamPriority);\n        sb.append(\", URLLength=\").append(URLLength);\n        sb.append(\", URLString='\").append(URLString).append('\\'');\n        sb.append(\", remoteODFlag=\").append(remoteODFlag);\n        sb.append(\", dependsOnEsId=\").append(dependsOnEsId);\n        sb.append(\", oCREsId=\").append(oCREsId);\n        sb.append(\", decoderConfigDescriptor=\").append(decoderConfigDescriptor);\n        sb.append(\", slConfigDescriptor=\").append(slConfigDescriptor);\n        sb.append('}');\n        return sb.toString();\n    }\n\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/mp4/objectdescriptors/ExtensionDescriptor.java",
    "content": "/*\n * Copyright 2011 castLabs, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.boxes.mp4.objectdescriptors;\n\nimport com.coremedia.iso.Hex;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.util.logging.Logger;\n\n/**\n * abstract class ExtensionDescriptor extends BaseDescriptor\n * : bit(8) tag = ExtensionProfileLevelDescrTag, ExtDescrTagStartRange ..\n * ExtDescrTagEndRange {\n * // empty. To be filled by classes extending this class.\n * }\n */\n@Descriptor(tags = {0x13, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253})\npublic class ExtensionDescriptor extends BaseDescriptor {\n    private static Logger log = Logger.getLogger(ExtensionDescriptor.class.getName());\n\n    byte[] bytes;\n\n\n    //todo: add this better to the tags list?\n    //14496-1:2010 p.20:\n    //0x6A-0xBF Reserved for ISO use\n    //0xC0-0xFE User private\n    //\n    //ExtDescrTagStartRange = 0x6A\n    //ExtDescrTagEndRange = 0xFE\n    static int[] allTags() {\n        int[] ints = new int[0xFE - 0x6A];\n\n        for (int i = 0x6A; i < 0xFE; i++) {\n            final int pos = i - 0x6A;\n            log.finest(\"pos:\" + pos);\n            ints[pos] = i;\n        }\n        return ints;\n    }\n\n    @Override\n    public void parseDetail(ByteBuffer bb) throws IOException {\n        if (getSize() > 0) {\n            bytes = new byte[sizeOfInstance];\n            bb.get(bytes);\n        }\n    }\n\n    @Override\n    public String toString() {\n        final StringBuilder sb = new StringBuilder();\n        sb.append(\"ExtensionDescriptor\");\n        sb.append(\"{bytes=\").append(bytes == null ? \"null\" : Hex.encodeHex(bytes));\n        sb.append('}');\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/mp4/objectdescriptors/ExtensionProfileLevelDescriptor.java",
    "content": "/*\n * Copyright 2011 castLabs, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.boxes.mp4.objectdescriptors;\n\nimport com.coremedia.iso.Hex;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\n\n/**\n * abstract class ExtensionDescriptor extends BaseDescriptor\n * : bit(8) tag = ExtensionProfileLevelDescrTag, ExtDescrTagStartRange ..\n * ExtDescrTagEndRange {\n * // empty. To be filled by classes extending this class.\n * }\n */\n@Descriptor(tags = {0x13})\npublic class ExtensionProfileLevelDescriptor extends BaseDescriptor {\n    byte[] bytes;\n\n    @Override\n    public void parseDetail(ByteBuffer bb) throws IOException {\n        if (getSize() > 0) {\n            bytes = new byte[getSize()];\n            bb.get(bytes);\n        }\n    }\n\n    @Override\n    public String toString() {\n        final StringBuilder sb = new StringBuilder();\n        sb.append(\"ExtensionDescriptor\");\n        sb.append(\"{bytes=\").append(bytes == null ? \"null\" : Hex.encodeHex(bytes));\n        sb.append('}');\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/mp4/objectdescriptors/InitialObjectDescriptor.java",
    "content": "/*\n * Copyright 2011 castLabs, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.boxes.mp4.objectdescriptors;\n\n\nimport com.coremedia.iso.IsoTypeReader;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/*\nclass InitialObjectDescriptor extends ObjectDescriptorBase : bit(8)\ntag=InitialObjectDescrTag {\nbit(10) ObjectDescriptorID;\nbit(1) URL_Flag;\nbit(1) includeInlineProfileLevelFlag;\nconst bit(4) reserved=0b1111;\nif (URL_Flag) {\nbit(8) URLlength;\nbit(8) URLstring[URLlength];\n} else {\nbit(8) ODProfileLevelIndication;\nbit(8) sceneProfileLevelIndication;\nbit(8) audioProfileLevelIndication;\nbit(8) visualProfileLevelIndication;\nbit(8) graphicsProfileLevelIndication;\nES_Descriptor esDescr[1 .. 255];\nOCI_Descriptor ociDescr[0 .. 255];\nIPMP_DescriptorPointer ipmpDescrPtr[0 .. 255];\nIPMP_Descriptor ipmpDescr [0 .. 255];\nIPMP_ToolListDescriptor toolListDescr[0 .. 1];\n}\nExtensionDescriptor extDescr[0 .. 255];\n}\n*/\n//@Descriptor(tags = {0x02, 0x10})\npublic class InitialObjectDescriptor extends ObjectDescriptorBase {\n    private int objectDescriptorId;\n    int urlFlag;\n    int includeInlineProfileLevelFlag;\n\n    int urlLength;\n    String urlString;\n\n    int oDProfileLevelIndication;\n    int sceneProfileLevelIndication;\n    int audioProfileLevelIndication;\n    int visualProfileLevelIndication;\n    int graphicsProfileLevelIndication;\n\n    List<ESDescriptor> esDescriptors = new ArrayList<ESDescriptor>();\n\n    List<ExtensionDescriptor> extensionDescriptors = new ArrayList<ExtensionDescriptor>();\n\n    List<BaseDescriptor> unknownDescriptors = new ArrayList<BaseDescriptor>();\n\n    @Override\n    public void parseDetail(ByteBuffer bb) throws IOException {\n        int data = IsoTypeReader.readUInt16(bb);\n        objectDescriptorId = (data & 0xFFC0) >> 6;\n\n        urlFlag = (data & 0x3F) >> 5;\n        includeInlineProfileLevelFlag = (data & 0x1F) >> 4;\n\n        int sizeLeft = getSize() - 2;\n        if (urlFlag == 1) {\n            urlLength = IsoTypeReader.readUInt8(bb);\n            urlString = IsoTypeReader.readString(bb, urlLength);\n            sizeLeft = sizeLeft - (1 + urlLength);\n        } else {\n            oDProfileLevelIndication = IsoTypeReader.readUInt8(bb);\n            sceneProfileLevelIndication = IsoTypeReader.readUInt8(bb);\n            audioProfileLevelIndication = IsoTypeReader.readUInt8(bb);\n            visualProfileLevelIndication = IsoTypeReader.readUInt8(bb);\n            graphicsProfileLevelIndication = IsoTypeReader.readUInt8(bb);\n\n            sizeLeft = sizeLeft - 5;\n\n            if (sizeLeft > 2) {\n                final BaseDescriptor descriptor = ObjectDescriptorFactory.createFrom(-1, bb);\n                sizeLeft = sizeLeft - descriptor.getSize();\n                if (descriptor instanceof ESDescriptor) {\n                    esDescriptors.add((ESDescriptor) descriptor);\n                } else {\n                    unknownDescriptors.add(descriptor);\n                }\n            }\n        }\n\n        if (sizeLeft > 2) {\n            final BaseDescriptor descriptor = ObjectDescriptorFactory.createFrom(-1, bb);\n            if (descriptor instanceof ExtensionDescriptor) {\n                extensionDescriptors.add((ExtensionDescriptor) descriptor);\n            } else {\n                unknownDescriptors.add(descriptor);\n            }\n        }\n    }\n\n    @Override\n    public String toString() {\n        final StringBuilder sb = new StringBuilder();\n        sb.append(\"InitialObjectDescriptor\");\n        sb.append(\"{objectDescriptorId=\").append(objectDescriptorId);\n        sb.append(\", urlFlag=\").append(urlFlag);\n        sb.append(\", includeInlineProfileLevelFlag=\").append(includeInlineProfileLevelFlag);\n        sb.append(\", urlLength=\").append(urlLength);\n        sb.append(\", urlString='\").append(urlString).append('\\'');\n        sb.append(\", oDProfileLevelIndication=\").append(oDProfileLevelIndication);\n        sb.append(\", sceneProfileLevelIndication=\").append(sceneProfileLevelIndication);\n        sb.append(\", audioProfileLevelIndication=\").append(audioProfileLevelIndication);\n        sb.append(\", visualProfileLevelIndication=\").append(visualProfileLevelIndication);\n        sb.append(\", graphicsProfileLevelIndication=\").append(graphicsProfileLevelIndication);\n        sb.append(\", esDescriptors=\").append(esDescriptors);\n        sb.append(\", extensionDescriptors=\").append(extensionDescriptors);\n        sb.append(\", unknownDescriptors=\").append(unknownDescriptors);\n        sb.append('}');\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/mp4/objectdescriptors/ObjectDescriptor.java_bak",
    "content": "/*\n * Copyright 2011 castLabs, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.boxes.mp4.objectdescriptors;\n\nimport com.coremedia.iso.IsoTypeReader;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/*\nclass ObjectDescriptor extends ObjectDescriptorBase : bit(8) tag=ObjectDescrTag {\nbit(10) ObjectDescriptorID;\nbit(1) URL_Flag;\nconst bit(5) reserved=0b1111.1;\nif (URL_Flag) {\nbit(8) URLlength;\nbit(8) URLstring[URLlength];\n} else {\nES_Descriptor esDescr[1 .. 255];\nOCI_Descriptor ociDescr[0 .. 255];\nIPMP_DescriptorPointer ipmpDescrPtr[0 .. 255];\nIPMP_Descriptor ipmpDescr [0 .. 255];\n}\nExtensionDescriptor extDescr[0 .. 255];\n}\n*/\n@Descriptor(tags = {0x01, 0x11})\npublic class ObjectDescriptor extends ObjectDescriptorBase {\n    private int objectDescriptorId;\n    int objectDescriptorUrlFlag;\n    int objectDescriptorUrlLength;\n    String objectDescriptorUrlString;\n\n\n    private int streamCount;\n    private int extensionFlag;\n    private List<ESDescriptor> esDescriptors = new ArrayList<ESDescriptor>();\n\n    private int descriptorLength;\n    private List<ExtensionDescriptor> extensionDescriptors = new ArrayList<ExtensionDescriptor>();\n\n    public static ObjectDescriptor createFrom(ByteBuffer in) throws IOException {\n/*\n    tmp = in.readUInt16();\n    esDescriptor.objectDescriptorId = tmp & 0x3f;\n    esDescriptor.objectDescriptorUrlFlag = (tmp >> 5) & 0x1;\n    if (esDescriptor.objectDescriptorUrlFlag == 1) {\n      esDescriptor.objectDescriptorUrlLength = in.readUInt8();\n      esDescriptor.objectDescriptorUrlString = new String(in.read(esDescriptor.objectDescriptorUrlLength));\n    }\n     */\n\n        ObjectDescriptor objectDescriptor = new ObjectDescriptor();\n\n        int data = IsoTypeReader.readUInt16(in);\n\n        objectDescriptor.objectDescriptorId = data & 0xFFC0;\n        objectDescriptor.streamCount = data & 0x3E;\n        objectDescriptor.extensionFlag = data & 0x1;\n\n//    for (int i = 0; i < objectDescriptor.streamCount; i++) {\n//      objectDescriptor.esDescriptors.add(ESDescriptor.createFrom(in));\n//    }\n//\n//    if (objectDescriptor.extensionFlag == 1) {\n//      objectDescriptor.descriptorLength = in.readUInt8();\n//      for (int i = 0; i < objectDescriptor.descriptorLength;) {\n//        ExtensionDescriptor extensionDescriptor = ExtensionDescriptor.createFrom(in);\n//        objectDescriptor.extensionDescriptors.add(extensionDescriptor);\n//        i = i + extensionDescriptor.descriptorDataLength + 1;\n//      }\n//    }\n\n        return objectDescriptor;\n    }\n\n    @Override\n    public String toString() {\n        return \"ObjectDescriptor{\" +\n                \"objectDescriptorId=\" + objectDescriptorId +\n                \", streamCount=\" + streamCount +\n                \", extensionFlag=\" + extensionFlag +\n                \", esDescriptors=\" + esDescriptors +\n                \", descriptorLength=\" + descriptorLength +\n                \", extensionDescriptors=\" + extensionDescriptors +\n                '}';\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/mp4/objectdescriptors/ObjectDescriptorBase.java",
    "content": "/*\n * Copyright 2011 castLabs, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.boxes.mp4.objectdescriptors;\n\n/*\nabstract class ObjectDescriptorBase extends BaseDescriptor : bit(8)\ntag=[ObjectDescrTag..InitialObjectDescrTag] {\n// empty. To be filled by classes extending this class.\n}\n */\n@Descriptor(tags = 0x00)\npublic abstract class ObjectDescriptorBase extends BaseDescriptor {\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/mp4/objectdescriptors/ObjectDescriptorFactory.java",
    "content": "/*\n * Copyright 2011 castLabs, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.boxes.mp4.objectdescriptors;\n\nimport com.coremedia.iso.IsoTypeReader;\n\nimport java.io.IOException;\nimport java.lang.reflect.Modifier;\nimport java.nio.ByteBuffer;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\n/* class tag values of 14496-1\n0x00 Forbidden\n0x01 ObjectDescrTag\n0x02 InitialObjectDescrTag\n0x03 ES_DescrTag\n0x04 DecoderConfigDescrTag\n0x05 DecSpecificInfoTag\n0x06 SLConfigDescrTag\n0x07 ContentIdentDescrTag\n0x08 SupplContentIdentDescrTag\n0x09 IPI_DescrPointerTag\n0x0A IPMP_DescrPointerTag\n0x0B IPMP_DescrTag\n0x0C QoS_DescrTag\n0x0D RegistrationDescrTag\n0x0E ES_ID_IncTag\n0x0F ES_ID_RefTag\n0x10 MP4_IOD_Tag\n0x11 MP4_OD_Tag\n0x12 IPL_DescrPointerRefTag\n0x13 ExtensionProfileLevelDescrTag\n0x14 profileLevelIndicationIndexDescrTag\n0x15-0x3F Reserved for ISO use\n0x40 ContentClassificationDescrTag\n0x41 KeyWordDescrTag\n0x42 RatingDescrTag\n0x43 LanguageDescrTag\n0x44 ShortTextualDescrTag\n0x45 ExpandedTextualDescrTag\n0x46 ContentCreatorNameDescrTag\n0x47 ContentCreationDateDescrTag\n0x48 OCICreatorNameDescrTag\n0x49 OCICreationDateDescrTag\n0x4A SmpteCameraPositionDescrTag\n0x4B SegmentDescrTag\n0x4C MediaTimeDescrTag\n0x4D-0x5F Reserved for ISO use (OCI extensions)\n0x60 IPMP_ToolsListDescrTag\n0x61 IPMP_ToolTag\n0x62 M4MuxTimingDescrTag\n0x63 M4MuxCodeTableDescrTag\n0x64 ExtSLConfigDescrTag\n0x65 M4MuxBufferSizeDescrTag\n0x66 M4MuxIdentDescrTag\n0x67 DependencyPointerTag\n0x68 DependencyMarkerTag\n0x69 M4MuxChannelDescrTag\n0x6A-0xBF Reserved for ISO use\n0xC0-0xFE User private\n0xFF Forbidden\n */\n\n/* objectTypeIndication as of 14496-1\n0x00 Forbidden\n0x01 Systems ISO/IEC 14496-1 a\n0x02 Systems ISO/IEC 14496-1 b\n0x03 Interaction Stream\n0x04 Systems ISO/IEC 14496-1 Extended BIFS Configuration c\n0x05 Systems ISO/IEC 14496-1 AFX d\n0x06 Font Data Stream\n0x07 Synthesized Texture Stream\n0x08 Streaming Text Stream\n0x09-0x1F reserved for ISO use\n0x20 Visual ISO/IEC 14496-2 e\n0x21 Visual ITU-T Recommendation H.264 | ISO/IEC 14496-10 f\n0x22 Parameter Sets for ITU-T Recommendation H.264 | ISO/IEC 14496-10 f\n0x23-0x3F reserved for ISO use\n0x40 Audio ISO/IEC 14496-3 g\n0x41-0x5F reserved for ISO use\n0x60 Visual ISO/IEC 13818-2 Simple Profile\n0x61 Visual ISO/IEC 13818-2 Main Profile\n0x62 Visual ISO/IEC 13818-2 SNR Profile\n0x63 Visual ISO/IEC 13818-2 Spatial Profile\n0x64 Visual ISO/IEC 13818-2 High Profile\n0x65 Visual ISO/IEC 13818-2 422 Profile\n0x66 Audio ISO/IEC 13818-7 Main Profile\n0x67 Audio ISO/IEC 13818-7 LowComplexity Profile\n0x68 Audio ISO/IEC 13818-7 Scaleable Sampling Rate Profile\n0x69 Audio ISO/IEC 13818-3\n0x6A Visual ISO/IEC 11172-2\n0x6B Audio ISO/IEC 11172-3\n0x6C Visual ISO/IEC 10918-1\n0x6D reserved for registration authority\n0x6E Visual ISO/IEC 15444-1\n0x6F - 0x9F reserved for ISO use\n0xA0 - 0xBF reserved for registration authority i\n0xC0 - 0xE0 user private\n0xE1 reserved for registration authority i\n0xE2 - 0xFE user private\n0xFF no object type specified h\n */\npublic class ObjectDescriptorFactory {\n    protected static Logger log = Logger.getLogger(ObjectDescriptorFactory.class.getName());\n\n    protected static Map<Integer, Map<Integer, Class<? extends BaseDescriptor>>> descriptorRegistry = new HashMap<Integer, Map<Integer, Class<? extends BaseDescriptor>>>();\n\n    static {\n        Set<Class<? extends BaseDescriptor>> annotated = new HashSet<Class<? extends BaseDescriptor>>();\n\n        annotated.add(DecoderSpecificInfo.class);\n        annotated.add(SLConfigDescriptor.class);\n        annotated.add(BaseDescriptor.class);\n        annotated.add(ExtensionDescriptor.class);\n        annotated.add(ObjectDescriptorBase.class);\n        annotated.add(ProfileLevelIndicationDescriptor.class);\n        annotated.add(AudioSpecificConfig.class);\n        annotated.add(ExtensionProfileLevelDescriptor.class);\n        annotated.add(ESDescriptor.class);\n        annotated.add(DecoderConfigDescriptor.class);\n        //annotated.add(ObjectDescriptor.class);\n\n        for (Class<? extends BaseDescriptor> clazz : annotated) {\n            final Descriptor descriptor = clazz.getAnnotation(Descriptor.class);\n            final int[] tags = descriptor.tags();\n            final int objectTypeInd = descriptor.objectTypeIndication();\n\n            Map<Integer, Class<? extends BaseDescriptor>> tagMap = descriptorRegistry.get(objectTypeInd);\n            if (tagMap == null) {\n                tagMap = new HashMap<Integer, Class<? extends BaseDescriptor>>();\n            }\n            for (int tag : tags) {\n                tagMap.put(tag, clazz);\n            }\n            descriptorRegistry.put(objectTypeInd, tagMap);\n        }\n    }\n\n    public static BaseDescriptor createFrom(int objectTypeIndication, ByteBuffer bb) throws IOException {\n        int tag = IsoTypeReader.readUInt8(bb);\n\n        Map<Integer, Class<? extends BaseDescriptor>> tagMap = descriptorRegistry.get(objectTypeIndication);\n        if (tagMap == null) {\n            tagMap = descriptorRegistry.get(-1);\n        }\n        Class<? extends BaseDescriptor> aClass = tagMap.get(tag);\n\n//    if (tag == 0x00) {\n//      log.warning(\"Found illegal tag 0x00! objectTypeIndication \" + Integer.toHexString(objectTypeIndication) +\n//              \" and tag \" + Integer.toHexString(tag) + \" using: \" + aClass);\n//      aClass = BaseDescriptor.class;\n//    }\n\n        BaseDescriptor baseDescriptor;\n        if (aClass == null || aClass.isInterface() || Modifier.isAbstract(aClass.getModifiers())) {\n            log.warning(\"No ObjectDescriptor found for objectTypeIndication \" + Integer.toHexString(objectTypeIndication) +\n                    \" and tag \" + Integer.toHexString(tag) + \" found: \" + aClass);\n            baseDescriptor = new UnknownDescriptor();\n        } else {\n            try {\n                baseDescriptor = aClass.newInstance();\n            } catch (Exception e) {\n                log.log(Level.SEVERE, \"Couldn't instantiate BaseDescriptor class \" + aClass + \" for objectTypeIndication \" + objectTypeIndication + \" and tag \" + tag, e);\n                throw new RuntimeException(e);\n            }\n        }\n        baseDescriptor.parse(tag, bb);\n        return baseDescriptor;\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/mp4/objectdescriptors/ProfileLevelIndicationDescriptor.java",
    "content": "/*\n * Copyright 2011 castLabs, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.boxes.mp4.objectdescriptors;\n\nimport com.coremedia.iso.IsoTypeReader;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\n\n/**\n * class ProfileLevelIndicationIndexDescriptor () extends BaseDescriptor\n * : bit(8) ProfileLevelIndicationIndexDescrTag {\n * bit(8) profileLevelIndicationIndex;\n * }\n */\n@Descriptor(tags = 0x14)\npublic class ProfileLevelIndicationDescriptor extends BaseDescriptor {\n    int profileLevelIndicationIndex;\n\n    @Override\n    public void parseDetail( ByteBuffer bb) throws IOException {\n        profileLevelIndicationIndex = IsoTypeReader.readUInt8(bb);\n    }\n\n    @Override\n    public String toString() {\n        final StringBuilder sb = new StringBuilder();\n        sb.append(\"ProfileLevelIndicationDescriptor\");\n        sb.append(\"{profileLevelIndicationIndex=\").append(Integer.toHexString(profileLevelIndicationIndex));\n        sb.append('}');\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/mp4/objectdescriptors/SLConfigDescriptor.java",
    "content": "/*\n * Copyright 2011 castLabs, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.boxes.mp4.objectdescriptors;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\n\n/**\n * class SLConfigDescriptor extends BaseDescriptor : bit(8) tag=SLConfigDescrTag {\n * bit(8) predefined;\n * if (predefined==0) {\n * bit(1) useAccessUnitStartFlag;\n * bit(1) useAccessUnitEndFlag;\n * bit(1) useRandomAccessPointFlag;\n * bit(1) hasRandomAccessUnitsOnlyFlag;\n * bit(1) usePaddingFlag;\n * bit(1) useTimeStampsFlag;\n * bit(1) useIdleFlag;\n * bit(1) durationFlag;\n * bit(32) timeStampResolution;\n * bit(32) OCRResolution;\n * bit(8) timeStampLength; // must be ≤ 64\n * bit(8) OCRLength; // must be ≤ 64\n * bit(8) AU_Length; // must be ≤ 32\n * bit(8) instantBitrateLength;\n * bit(4) degradationPriorityLength;\n * bit(5) AU_seqNumLength; // must be ≤ 16\n * bit(5) packetSeqNumLength; // must be ≤ 16\n * bit(2) reserved=0b11;\n * }\n * if (durationFlag) {\n * bit(32) timeScale;\n * bit(16) accessUnitDuration;\n * bit(16) compositionUnitDuration;\n * }\n * if (!useTimeStampsFlag) {\n * bit(timeStampLength) startDecodingTimeStamp;\n * bit(timeStampLength) startCompositionTimeStamp;\n * }\n * }\n */\n@Descriptor(tags = {0x06})\npublic class SLConfigDescriptor extends BaseDescriptor {\n    int predefined;\n\n    public int getPredefined() {\n        return predefined;\n    }\n\n    public void setPredefined(int predefined) {\n        this.predefined = predefined;\n    }\n\n    @Override\n    public void parseDetail(ByteBuffer bb) throws IOException {\n        predefined =  IsoTypeReader.readUInt8(bb);\n    }\n\n    public int serializedSize() {\n        return 3;\n    }\n\n    public ByteBuffer serialize() {\n        ByteBuffer out = ByteBuffer.allocate(3);\n        IsoTypeWriter.writeUInt8(out, 6);\n        IsoTypeWriter.writeUInt8(out, 1);\n        IsoTypeWriter.writeUInt8(out, predefined);\n        return out;\n    }\n\n    @Override\n    public String toString() {\n        final StringBuilder sb = new StringBuilder();\n        sb.append(\"SLConfigDescriptor\");\n        sb.append(\"{predefined=\").append(predefined);\n        sb.append('}');\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/mp4/objectdescriptors/UnknownDescriptor.java",
    "content": "/*\n * Copyright 2011 castLabs, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.boxes.mp4.objectdescriptors;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.util.logging.Logger;\n\npublic class UnknownDescriptor extends BaseDescriptor {\n    private ByteBuffer data;\n    private static Logger log = Logger.getLogger(UnknownDescriptor.class.getName());\n\n    @Override\n    public void parseDetail(ByteBuffer bb) throws IOException {\n        data = (ByteBuffer) bb.slice().limit(this.getSizeOfInstance());\n    }\n\n    @Override\n    public String toString() {\n        final StringBuilder sb = new StringBuilder();\n        sb.append(\"UnknownDescriptor\");\n        sb.append(\"{tag=\").append(tag);\n        sb.append(\", sizeOfInstance=\").append(sizeOfInstance);\n        sb.append(\", data=\").append(data);\n        sb.append('}');\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/piff/PiffSampleEncryptionBox.java",
    "content": "package com.googlecode.mp4parser.boxes.piff;\n\nimport com.googlecode.mp4parser.boxes.AbstractSampleEncryptionBox;\n\n/**\n * <pre>\n * aligned(8) class SampleEncryptionBox extends FullBox(‘uuid’, extended_type= 0xA2394F52-5A9B-4f14-A244-6C427C648DF4, version=0, flags=0)\n * {\n *  if (flags & 0x000001)\n *  {\n *   unsigned int(24) AlgorithmID;\n *   unsigned int(8) IV_size;\n *   unsigned int(8)[16] KID;\n *  }\n *  unsigned int (32) sample_count;\n *  {\n *   unsigned int(IV_size) InitializationVector;\n *   if (flags & 0x000002)\n *   {\n *    unsigned int(16) NumberOfEntries;\n *    {\n *     unsigned int(16) BytesOfClearData;\n *     unsigned int(32) BytesOfEncryptedData;\n *    } [ NumberOfEntries]\n *   }\n *  }[ sample_count ]\n * }\n * </pre>\n */\npublic class PiffSampleEncryptionBox extends AbstractSampleEncryptionBox {\n\n    /**\n     * Creates a AbstractSampleEncryptionBox for non-h264 tracks.\n     */\n    public PiffSampleEncryptionBox() {\n        super(\"uuid\");\n\n    }\n\n    @Override\n    public byte[] getUserType() {\n        return new byte[]{(byte) 0xA2, 0x39, 0x4F, 0x52, 0x5A, (byte) 0x9B, 0x4f, 0x14, (byte) 0xA2, 0x44, 0x6C, 0x42, 0x7C, 0x64, (byte) 0x8D, (byte) 0xF4};\n    }\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/piff/PiffTrackEncryptionBox.java",
    "content": "package com.googlecode.mp4parser.boxes.piff;\n\nimport com.googlecode.mp4parser.boxes.AbstractTrackEncryptionBox;\n\n/**\n * aligned(8) class TrackEncryptionBox extends FullBox(‘uuid’,\n * extended_type=0x8974dbce-7be7-4c51-84f9-7148f9882554, version=0,\n * flags=0)\n * {\n * unsigned int(24) default_AlgorithmID;\n * unsigned int(8) default_IV_size;\n * unsigned int(8)[16] default_KID;\n * }\n */\npublic class PiffTrackEncryptionBox extends AbstractTrackEncryptionBox {\n\n\n    public PiffTrackEncryptionBox() {\n        super(\"uuid\");\n    }\n\n    @Override\n    public byte[] getUserType() {\n        return new byte[]{(byte) 0x89, 0x74, (byte) 0xdb, (byte) 0xce, 0x7b, (byte) 0xe7, 0x4c, 0x51,\n                (byte) 0x84, (byte) 0xf9, 0x71, 0x48, (byte) 0xf9, (byte) 0x88, 0x25, 0x54};\n    }\n\n    @Override\n    public int getFlags() {\n        return 0;\n    }\n\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/piff/PlayReadyHeader.java",
    "content": "package com.googlecode.mp4parser.boxes.piff;\n\nimport com.coremedia.iso.IsoFile;\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.util.Path;\n\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.io.UnsupportedEncodingException;\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * Specifications > Microsoft PlayReady Format Specification > 2. PlayReady Media Format > 2.7. ASF GUIDs\n * <p/>\n * <p/>\n * ASF_Protection_System_Identifier_Object\n * 9A04F079-9840-4286-AB92E65BE0885F95\n * <p/>\n * ASF_Content_Protection_System_Microsoft_PlayReady\n * F4637010-03C3-42CD-B932B48ADF3A6A54\n * <p/>\n * ASF_StreamType_PlayReady_Encrypted_Command_Media\n * 8683973A-6639-463A-ABD764F1CE3EEAE0\n * <p/>\n * <p/>\n * Specifications > Microsoft PlayReady Format Specification > 2. PlayReady Media Format > 2.5. Data Objects > 2.5.1. Payload Extension for AES in Counter Mode\n * <p/>\n * The sample Id is used as the IV in CTR mode. Block offset, starting at 0 and incremented by 1 after every 16 bytes, from the beginning of the sample is used as the Counter.\n * <p/>\n * The sample ID for each sample (media object) is stored as an ASF payload extension system with the ID of ASF_Payload_Extension_Encryption_SampleID = {6698B84E-0AFA-4330-AEB2-1C0A98D7A44D}. The payload extension can be stored as a fixed size extension of 8 bytes.\n * <p/>\n * The sample ID is always stored in big-endian byte order.\n */\npublic class PlayReadyHeader extends ProtectionSpecificHeader {\n    private long length;\n    private List<PlayReadyRecord> records;\n\n    public PlayReadyHeader() {\n\n    }\n\n    @Override\n    public void parse(ByteBuffer byteBuffer) {\n        /*\n   Length DWORD 32\n\n   PlayReady Record Count WORD 16\n\n   PlayReady Records See Text Varies\n\n        */\n\n        length = IsoTypeReader.readUInt32BE(byteBuffer);\n        int recordCount = IsoTypeReader.readUInt16BE(byteBuffer);\n\n        records = PlayReadyRecord.createFor(byteBuffer, recordCount);\n    }\n\n    @Override\n    public ByteBuffer getData() {\n\n        int size = 4 + 2;\n        for (PlayReadyRecord record : records) {\n            size += 2 + 2;\n            size += record.getValue().rewind().limit();\n        }\n        ByteBuffer byteBuffer = ByteBuffer.allocate(size);\n\n        IsoTypeWriter.writeUInt32BE(byteBuffer, size);\n        IsoTypeWriter.writeUInt16BE(byteBuffer, records.size());\n        for (PlayReadyRecord record : records) {\n            IsoTypeWriter.writeUInt16BE(byteBuffer, record.type);\n            IsoTypeWriter.writeUInt16BE(byteBuffer, record.getValue().limit());\n            ByteBuffer tmp4debug = record.getValue();\n            byteBuffer.put(tmp4debug);\n        }\n\n        return byteBuffer;\n    }\n\n    public void setRecords(List<PlayReadyRecord> records) {\n        this.records = records;\n    }\n\n    public List<PlayReadyRecord> getRecords() {\n        return Collections.unmodifiableList(records);\n    }\n\n    @Override\n    public String toString() {\n        final StringBuilder sb = new StringBuilder();\n        sb.append(\"PlayReadyHeader\");\n        sb.append(\"{length=\").append(length);\n        sb.append(\", recordCount=\").append(records.size());\n        sb.append(\", records=\").append(records);\n        sb.append('}');\n        return sb.toString();\n    }\n\n    public static abstract class PlayReadyRecord {\n        int type;\n\n\n        public PlayReadyRecord(int type) {\n            this.type = type;\n        }\n\n        public static List<PlayReadyRecord> createFor(ByteBuffer byteBuffer, int recordCount) {\n            List<PlayReadyRecord> records = new ArrayList<PlayReadyRecord>(recordCount);\n\n            for (int i = 0; i < recordCount; i++) {\n                PlayReadyRecord record;\n                int type = IsoTypeReader.readUInt16BE(byteBuffer);\n                int length = IsoTypeReader.readUInt16BE(byteBuffer);\n                switch (type) {\n                    case 0x1:\n                        record = new RMHeader();\n                        break;\n                    case 0x2:\n                        record = new DefaulPlayReadyRecord(0x02);\n                        break;\n                    case 0x3:\n                        record = new EmeddedLicenseStore();\n                        break;\n                    default:\n                        record = new DefaulPlayReadyRecord(type);\n                }\n                record.parse((ByteBuffer) byteBuffer.slice().limit(length));\n                byteBuffer.position(byteBuffer.position() + length);\n                records.add(record);\n            }\n\n            return records;\n        }\n\n        public abstract void parse(ByteBuffer bytes);\n\n        @Override\n        public String toString() {\n            final StringBuilder sb = new StringBuilder();\n            sb.append(\"PlayReadyRecord\");\n            sb.append(\"{type=\").append(type);\n            sb.append(\", length=\").append(getValue().limit());\n//            sb.append(\", value=\").append(Hex.encodeHex(getValue())).append('\\'');\n            sb.append('}');\n            return sb.toString();\n        }\n\n        public abstract ByteBuffer getValue();\n\n        public static class RMHeader extends PlayReadyRecord {\n            String header;\n\n            public RMHeader() {\n                super(0x01);\n            }\n\n            @Override\n            public void parse(ByteBuffer bytes) {\n                try {\n                    byte[] str = new byte[bytes.slice().limit()];\n                    bytes.get(str);\n                    header = new String(str, \"UTF-16LE\");\n                } catch (UnsupportedEncodingException e) {\n                    throw new RuntimeException(e);\n                }\n            }\n\n            @Override\n            public ByteBuffer getValue() {\n                byte[] headerBytes;\n                try {\n                    headerBytes = header.getBytes(\"UTF-16LE\");\n                } catch (UnsupportedEncodingException e) {\n                    throw new RuntimeException(e);\n                }\n                return ByteBuffer.wrap(headerBytes);\n            }\n\n            public void setHeader(String header) {\n                this.header = header;\n            }\n\n            public String getHeader() {\n                return header;\n            }\n\n            @Override\n            public String toString() {\n                final StringBuilder sb = new StringBuilder();\n                sb.append(\"RMHeader\");\n                sb.append(\"{length=\").append(getValue().limit());\n                sb.append(\", header='\").append(header).append('\\'');\n                sb.append('}');\n                return sb.toString();\n            }\n        }\n\n        public static class EmeddedLicenseStore extends PlayReadyRecord {\n            ByteBuffer value;\n\n            public EmeddedLicenseStore() {\n                super(0x03);\n            }\n\n            @Override\n            public void parse(ByteBuffer bytes) {\n                this.value = bytes.duplicate();\n            }\n\n            @Override\n            public ByteBuffer getValue() {\n                return value;\n            }\n\n            @Override\n            public String toString() {\n                final StringBuilder sb = new StringBuilder();\n                sb.append(\"EmeddedLicenseStore\");\n                sb.append(\"{length=\").append(getValue().limit());\n                //sb.append(\", value='\").append(Hex.encodeHex(getValue())).append('\\'');\n                sb.append('}');\n                return sb.toString();\n            }\n        }\n\n        public static class DefaulPlayReadyRecord extends PlayReadyRecord {\n            ByteBuffer value;\n\n            public DefaulPlayReadyRecord(int type) {\n                super(type);\n            }\n\n            @Override\n            public void parse(ByteBuffer bytes) {\n                this.value = bytes.duplicate();\n            }\n\n            @Override\n            public ByteBuffer getValue() {\n                return value;\n            }\n\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/piff/ProtectionSpecificHeader.java",
    "content": "package com.googlecode.mp4parser.boxes.piff;\n\n\nimport com.coremedia.iso.Hex;\n\nimport java.lang.Class;\nimport java.lang.IllegalAccessException;\nimport java.lang.InstantiationException;\nimport java.lang.Object;\nimport java.lang.Override;\nimport java.lang.RuntimeException;\nimport java.lang.String;\nimport java.lang.StringBuilder;\nimport java.nio.ByteBuffer;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.UUID;\n\n\npublic class ProtectionSpecificHeader {\n    protected static Map<UUID, Class<? extends ProtectionSpecificHeader>> uuidRegistry = new HashMap<UUID, Class<? extends ProtectionSpecificHeader>>();\n    ByteBuffer data;\n\n    static {\n        uuidRegistry.put(UUID.fromString(\"9A04F079-9840-4286-AB92-E65BE0885F95\"), PlayReadyHeader.class);\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (obj instanceof ProtectionSpecificHeader) {\n            if (this.getClass().equals(obj.getClass())) {\n                return data.equals(((ProtectionSpecificHeader) obj).data);\n            }\n        }\n        return false;\n    }\n\n    public static ProtectionSpecificHeader createFor(UUID systemId, ByteBuffer bufferWrapper) {\n        final Class<? extends ProtectionSpecificHeader> aClass = uuidRegistry.get(systemId);\n\n        ProtectionSpecificHeader protectionSpecificHeader = new ProtectionSpecificHeader();\n        if (aClass != null) {\n            try {\n                protectionSpecificHeader = aClass.newInstance();\n\n            } catch (InstantiationException e) {\n                throw new RuntimeException(e);\n            } catch (IllegalAccessException e) {\n                throw new RuntimeException(e);\n            }\n        }\n        protectionSpecificHeader.parse(bufferWrapper);\n        return protectionSpecificHeader;\n\n    }\n\n    public void parse(ByteBuffer buffer) {\n        data = buffer;\n\n    }\n\n    public ByteBuffer getData() {\n        return data;\n    }\n\n    @Override\n    public String toString() {\n        final StringBuilder sb = new StringBuilder();\n        sb.append(\"ProtectionSpecificHeader\");\n        sb.append(\"{data=\");\n        ByteBuffer data = getData().duplicate();\n        data.rewind();\n        byte[] bytes = new byte[data.limit()];\n        data.get(bytes);\n        sb.append(Hex.encodeHex(bytes));\n        sb.append('}');\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/piff/TfrfBox.java",
    "content": "package com.googlecode.mp4parser.boxes.piff;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * The syntax of the fields defined in this section, specified in ABNF [RFC5234], is as follows:\n * TfrfBox = TfrfBoxLength TfrfBoxType [TfrfBoxLongLength] TfrfBoxUUID TfrfBoxFields\n * TfrfBoxChildren\n * TfrfBoxType = \"u\" \"u\" \"i\" \"d\"\n * TfrfBoxLength = BoxLength\n * TfrfBoxLongLength = LongBoxLength\n * TfrfBoxUUID = %xD4 %x80 %x7E %xF2 %xCA %x39 %x46 %x95\n * %x8E %x54 %x26 %xCB %x9E %x46 %xA7 %x9F\n * TfrfBoxFields = TfrfBoxVersion\n * TfrfBoxFlags\n * FragmentCount\n * (1* TfrfBoxDataFields32) / (1* TfrfBoxDataFields64)\n * TfrfBoxVersion = %x00 / %x01\n * TfrfBoxFlags = 24*24 RESERVED_BIT\n * FragmentCount = UINT8\n * TfrfBoxDataFields32 = FragmentAbsoluteTime32\n * FragmentDuration32\n * TfrfBoxDataFields64 = FragmentAbsoluteTime64\n * FragmentDuration64\n * FragmentAbsoluteTime64 = UNSIGNED_INT32\n * FragmentDuration64 = UNSIGNED_INT32\n * FragmentAbsoluteTime64 = UNSIGNED_INT64\n * FragmentDuration64 = UNSIGNED_INT64\n * TfrfBoxChildren = *( VendorExtensionUUIDBox )\n */\npublic class TfrfBox extends AbstractFullBox {\n    public List<Entry> entries = new ArrayList<Entry>();\n\n    public TfrfBox() {\n        super(\"uuid\");\n    }\n\n    @Override\n    public byte[] getUserType() {\n        return new byte[]{(byte) 0xd4, (byte) 0x80, (byte) 0x7e, (byte) 0xf2, (byte) 0xca, (byte) 0x39, (byte) 0x46,\n                (byte) 0x95, (byte) 0x8e, (byte) 0x54, 0x26, (byte) 0xcb, (byte) 0x9e, (byte) 0x46, (byte) 0xa7, (byte) 0x9f};\n    }\n\n    @Override\n    protected long getContentSize() {\n        return 5 + entries.size() * (getVersion() == 0x01 ? 16 : 8);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt8(byteBuffer, entries.size());\n\n        for (Entry entry : entries) {\n            if (getVersion() == 0x01) {\n                IsoTypeWriter.writeUInt64(byteBuffer, entry.fragmentAbsoluteTime);\n                IsoTypeWriter.writeUInt64(byteBuffer, entry.fragmentAbsoluteDuration);\n            } else {\n                IsoTypeWriter.writeUInt32(byteBuffer, entry.fragmentAbsoluteTime);\n                IsoTypeWriter.writeUInt32(byteBuffer, entry.fragmentAbsoluteDuration);\n            }\n        }\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        int fragmentCount = IsoTypeReader.readUInt8(content);\n\n        for (int i = 0; i < fragmentCount; i++) {\n            Entry entry = new Entry();\n            if (getVersion() == 0x01) {\n                entry.fragmentAbsoluteTime = IsoTypeReader.readUInt64(content);\n                entry.fragmentAbsoluteDuration = IsoTypeReader.readUInt64(content);\n            } else {\n                entry.fragmentAbsoluteTime = IsoTypeReader.readUInt32(content);\n                entry.fragmentAbsoluteDuration = IsoTypeReader.readUInt32(content);\n            }\n            entries.add(entry);\n        }\n    }\n\n\n    public long getFragmentCount() {\n        return entries.size();\n    }\n\n    public List<Entry> getEntries() {\n        return entries;\n    }\n\n    @Override\n    public String toString() {\n        final StringBuilder sb = new StringBuilder();\n        sb.append(\"TfrfBox\");\n        sb.append(\"{entries=\").append(entries);\n        sb.append('}');\n        return sb.toString();\n    }\n\n    public class Entry {\n        long fragmentAbsoluteTime;\n        long fragmentAbsoluteDuration;\n\n        public long getFragmentAbsoluteTime() {\n            return fragmentAbsoluteTime;\n        }\n\n        public long getFragmentAbsoluteDuration() {\n            return fragmentAbsoluteDuration;\n        }\n\n        @Override\n        public String toString() {\n            final StringBuilder sb = new StringBuilder();\n            sb.append(\"Entry\");\n            sb.append(\"{fragmentAbsoluteTime=\").append(fragmentAbsoluteTime);\n            sb.append(\", fragmentAbsoluteDuration=\").append(fragmentAbsoluteDuration);\n            sb.append('}');\n            return sb.toString();\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/piff/TfxdBox.java",
    "content": "package com.googlecode.mp4parser.boxes.piff;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * The syntax of the fields defined in this section, specified in ABNF [RFC5234], is as follows:\n * TfxdBox = TfxdBoxLength TfxdBoxType [TfxdBoxLongLength] TfxdBoxUUID TfxdBoxFields\n * TfxdBoxChildren\n * TfxdBoxType = \"u\" \"u\" \"i\" \"d\"\n * TfxdBoxLength = BoxLength\n * TfxdBoxLongLength = LongBoxLength\n * TfxdBoxUUID = %x6D %x1D %x9B %x05 %x42 %xD5 %x44 %xE6\n * %x80 %xE2 %x14 %x1D %xAF %xF7 %x57 %xB2\n * TfxdBoxFields = TfxdBoxVersion\n * TfxdBoxFlags\n * TfxdBoxDataFields32 / TfxdBoxDataFields64\n * TfxdBoxVersion = %x00 / %x01\n * TfxdBoxFlags = 24*24 RESERVED_BIT\n * TfxdBoxDataFields32 = FragmentAbsoluteTime32\n * FragmentDuration32\n * TfxdBoxDataFields64 = FragmentAbsoluteTime64\n * FragmentDuration64\n * FragmentAbsoluteTime64 = UNSIGNED_INT32\n * FragmentDuration64 = UNSIGNED_INT32\n * FragmentAbsoluteTime64 = UNSIGNED_INT64\n * FragmentDuration64 = UNSIGNED_INT64\n * TfxdBoxChildren = *( VendorExtensionUUIDBox )\n */\n//@ExtendedUserType(uuid = \"6d1d9b05-42d5-44e6-80e2-141daff757b2\")\npublic class TfxdBox extends AbstractFullBox {\n    public long fragmentAbsoluteTime;\n    public long fragmentAbsoluteDuration;\n\n    public TfxdBox() {\n        super(\"uuid\");\n    }\n\n    @Override\n    public byte[] getUserType() {\n        return new byte[]{(byte) 0x6d, (byte) 0x1d, (byte) 0x9b, (byte) 0x05, (byte) 0x42, (byte) 0xd5, (byte) 0x44,\n                (byte) 0xe6, (byte) 0x80, (byte) 0xe2, 0x14, (byte) 0x1d, (byte) 0xaf, (byte) 0xf7, (byte) 0x57, (byte) 0xb2};\n    }\n\n    @Override\n    protected long getContentSize() {\n        return getVersion() == 0x01 ? 20 : 12;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n\n        if (getVersion() == 0x01) {\n            fragmentAbsoluteTime = IsoTypeReader.readUInt64(content);\n            fragmentAbsoluteDuration = IsoTypeReader.readUInt64(content);\n        } else {\n            fragmentAbsoluteTime = IsoTypeReader.readUInt32(content);\n            fragmentAbsoluteDuration = IsoTypeReader.readUInt32(content);\n        }\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        if (getVersion() == 0x01) {\n            IsoTypeWriter.writeUInt64(byteBuffer, fragmentAbsoluteTime);\n            IsoTypeWriter.writeUInt64(byteBuffer, fragmentAbsoluteDuration);\n        } else {\n            IsoTypeWriter.writeUInt32(byteBuffer, fragmentAbsoluteTime);\n            IsoTypeWriter.writeUInt32(byteBuffer, fragmentAbsoluteDuration);\n        }\n    }\n\n    public long getFragmentAbsoluteTime() {\n        return fragmentAbsoluteTime;\n    }\n\n    public long getFragmentAbsoluteDuration() {\n        return fragmentAbsoluteDuration;\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/piff/UuidBasedProtectionSystemSpecificHeaderBox.java",
    "content": "package com.googlecode.mp4parser.boxes.piff;\n\nimport com.coremedia.iso.IsoFile;\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.googlecode.mp4parser.AbstractFullBox;\nimport com.googlecode.mp4parser.util.Path;\nimport com.googlecode.mp4parser.util.UUIDConverter;\n\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.lang.Override;import java.lang.String;import java.lang.StringBuilder;import java.nio.ByteBuffer;\nimport java.util.UUID;\n\nimport static com.googlecode.mp4parser.util.CastUtils.l2i;\n\n/**\n * aligned(8) class UuidBasedProtectionSystemSpecificHeaderBox extends FullBox(‘uuid’,\n * extended_type=0xd08a4f18-10f3-4a82-b6c8-32d8aba183d3,\n * version=0, flags=0)\n * {\n * unsigned int(8)[16] SystemID;\n * unsigned int(32) DataSize;\n * unsigned int(8)[DataSize] Data;\n * }\n */\npublic class UuidBasedProtectionSystemSpecificHeaderBox extends AbstractFullBox {\n    public static byte[] USER_TYPE = new byte[]{(byte) 0xd0, (byte) 0x8a, 0x4f, 0x18, 0x10, (byte) 0xf3, 0x4a, (byte) 0x82,\n                (byte) 0xb6, (byte) 0xc8, 0x32, (byte) 0xd8, (byte) 0xab, (byte) 0xa1, (byte) 0x83, (byte) 0xd3};\n\n    UUID systemId;\n\n    ProtectionSpecificHeader protectionSpecificHeader;\n\n    public UuidBasedProtectionSystemSpecificHeaderBox() {\n        super(\"uuid\", USER_TYPE);\n    }\n\n    @Override\n    protected long getContentSize() {\n        return 24 + protectionSpecificHeader.getData().limit();\n    }\n\n    @Override\n    public byte[] getUserType() {\n        return USER_TYPE;\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        IsoTypeWriter.writeUInt64(byteBuffer, systemId.getMostSignificantBits());\n        IsoTypeWriter.writeUInt64(byteBuffer, systemId.getLeastSignificantBits());\n        ByteBuffer data = protectionSpecificHeader.getData();\n        data.rewind();\n        IsoTypeWriter.writeUInt32(byteBuffer, data.limit());\n        byteBuffer.put(data);\n    }\n\n    @Override\n    protected void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        byte[] systemIdBytes = new byte[16];\n        content.get(systemIdBytes);\n        systemId = UUIDConverter.convert(systemIdBytes);\n        int dataSize = l2i(IsoTypeReader.readUInt32(content));\n        protectionSpecificHeader = ProtectionSpecificHeader.createFor(systemId, content);\n    }\n\n    public UUID getSystemId() {\n        return systemId;\n    }\n\n    public void setSystemId(UUID systemId) {\n        this.systemId = systemId;\n    }\n\n    public String getSystemIdString() {\n        return systemId.toString();\n    }\n\n    public ProtectionSpecificHeader getProtectionSpecificHeader() {\n        return protectionSpecificHeader;\n    }\n\n    public String getProtectionSpecificHeaderString() {\n        return protectionSpecificHeader.toString();\n    }\n\n    public void setProtectionSpecificHeader(ProtectionSpecificHeader protectionSpecificHeader) {\n        this.protectionSpecificHeader = protectionSpecificHeader;\n    }\n\n    @Override\n    public String toString() {\n        final StringBuilder sb = new StringBuilder();\n        sb.append(\"UuidBasedProtectionSystemSpecificHeaderBox\");\n        sb.append(\"{systemId=\").append(systemId.toString());\n        sb.append(\", dataSize=\").append(protectionSpecificHeader.getData().limit());\n        sb.append('}');\n        return sb.toString();\n    }\n\n\n    public static void main(String[] args) throws IOException {\n        IsoFile isoFile = new IsoFile(new FileInputStream(\"/home/sannies/aaa/FBW_fixedres_B_640x360_400.ismv\").getChannel());\n        Path p = new Path(isoFile);\n        UuidBasedProtectionSystemSpecificHeaderBox pssh = (UuidBasedProtectionSystemSpecificHeaderBox) p.getPath(\"/moov/uuid\");\n        pssh.getSystemIdString();\n    }\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/threegpp26245/FontTableBox.java",
    "content": "package com.googlecode.mp4parser.boxes.threegpp26245;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.IsoTypeWriter;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractBox;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.util.LinkedList;\nimport java.util.List;\n\n/**\n *\n */\npublic class FontTableBox extends AbstractBox {\n    List<FontRecord> entries = new LinkedList<FontRecord>();\n\n    public FontTableBox() {\n        super(\"ftab\");\n    }\n\n    @Override\n    protected long getContentSize() {\n        int size = 2;\n        for (FontRecord fontRecord : entries) {\n            size += fontRecord.getSize();\n        }\n        return size;\n    }\n\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        int numberOfRecords = IsoTypeReader.readUInt16(content);\n        for (int i = 0; i < numberOfRecords; i++) {\n            FontRecord fr = new FontRecord();\n            fr.parse(content);\n            entries.add(fr);\n        }\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        IsoTypeWriter.writeUInt16(byteBuffer, entries.size());\n        for (FontRecord record : entries) {\n            record.getContent(byteBuffer);\n        }\n    }\n\n    public List<FontRecord> getEntries() {\n        return entries;\n    }\n\n    public void setEntries(List<FontRecord> entries) {\n        this.entries = entries;\n    }\n\n    public static class FontRecord {\n        int fontId;\n        String fontname;\n\n        public FontRecord() {\n        }\n\n        public FontRecord(int fontId, String fontname) {\n            this.fontId = fontId;\n            this.fontname = fontname;\n        }\n\n        public void parse(ByteBuffer bb) {\n            fontId = IsoTypeReader.readUInt16(bb);\n            int length = IsoTypeReader.readUInt8(bb);\n            fontname = IsoTypeReader.readString(bb, length);\n        }\n\n        public void getContent(ByteBuffer bb) {\n            IsoTypeWriter.writeUInt16(bb, fontId);\n            IsoTypeWriter.writeUInt8(bb, fontname.length());\n            bb.put(Utf8.convert(fontname));\n        }\n\n        public int getSize() {\n            return Utf8.utf8StringLengthInBytes(fontname) + 3;\n        }\n\n        @Override\n        public String toString() {\n            return \"FontRecord{\" +\n                    \"fontId=\" + fontId +\n                    \", fontname='\" + fontname + '\\'' +\n                    '}';\n        }\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/ultraviolet/AssetInformationBox.java",
    "content": "/*\n * Copyright 2011 castLabs, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.boxes.ultraviolet;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n * AssetInformationBox as defined Common File Format Spec.\n */\npublic class AssetInformationBox extends AbstractFullBox {\n    String apid = \"\";\n    String profileVersion = \"0000\";\n\n    public AssetInformationBox() {\n        super(\"ainf\");\n    }\n\n    @Override\n    protected long getContentSize() {\n        return Utf8.utf8StringLengthInBytes(apid) + 9;\n    }\n\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        byteBuffer.put(Utf8.convert(profileVersion), 0, 4);\n        byteBuffer.put(Utf8.convert(apid));\n        byteBuffer.put((byte) 0);\n    }\n\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        profileVersion = IsoTypeReader.readString(content, 4);\n        apid = IsoTypeReader.readString(content);\n        content = null;\n    }\n\n    public String getApid() {\n        return apid;\n    }\n\n    public void setApid(String apid) {\n        this.apid = apid;\n    }\n\n    public String getProfileVersion() {\n        return profileVersion;\n    }\n\n    public void setProfileVersion(String profileVersion) {\n        assert profileVersion != null && profileVersion.length() == 4;\n        this.profileVersion = profileVersion;\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/boxes/ultraviolet/BaseLocationBox.java",
    "content": "/*\n * Copyright 2011 castLabs, Berlin\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.googlecode.mp4parser.boxes.ultraviolet;\n\nimport com.coremedia.iso.IsoTypeReader;\nimport com.coremedia.iso.Utf8;\nimport com.googlecode.mp4parser.AbstractFullBox;\n\nimport java.nio.ByteBuffer;\n\n/**\n *\n */\npublic class BaseLocationBox extends AbstractFullBox {\n    String baseLocation = \"\";\n    String purchaseLocation = \"\";\n\n    public BaseLocationBox() {\n        super(\"bloc\");\n    }\n\n    public BaseLocationBox(String baseLocation, String purchaseLocation) {\n        super(\"bloc\");\n        this.baseLocation = baseLocation;\n        this.purchaseLocation = purchaseLocation;\n    }\n\n    public String getBaseLocation() {\n        return baseLocation;\n    }\n\n    public void setBaseLocation(String baseLocation) {\n        this.baseLocation = baseLocation;\n    }\n\n    public String getPurchaseLocation() {\n        return purchaseLocation;\n    }\n\n    public void setPurchaseLocation(String purchaseLocation) {\n        this.purchaseLocation = purchaseLocation;\n    }\n\n    @Override\n    protected long getContentSize() {\n        return 1028;\n    }\n\n    @Override\n    public void _parseDetails(ByteBuffer content) {\n        parseVersionAndFlags(content);\n        baseLocation = IsoTypeReader.readString(content);\n        content.get(new byte[256 - Utf8.utf8StringLengthInBytes(baseLocation) - 1]);\n        purchaseLocation = IsoTypeReader.readString(content);\n        content.get(new byte[256 - Utf8.utf8StringLengthInBytes(purchaseLocation) - 1]);\n        content.get(new byte[512]);\n    }\n\n    @Override\n    protected void getContent(ByteBuffer byteBuffer) {\n        writeVersionAndFlags(byteBuffer);\n        byteBuffer.put(Utf8.convert(baseLocation));\n        byteBuffer.put(new byte[256 - Utf8.utf8StringLengthInBytes(baseLocation)]); // string plus term zero\n        byteBuffer.put(Utf8.convert(purchaseLocation));\n        byteBuffer.put(new byte[256 - Utf8.utf8StringLengthInBytes(purchaseLocation)]); // string plus term zero\n        byteBuffer.put(new byte[512]);\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        BaseLocationBox that = (BaseLocationBox) o;\n\n        if (baseLocation != null ? !baseLocation.equals(that.baseLocation) : that.baseLocation != null) return false;\n        if (purchaseLocation != null ? !purchaseLocation.equals(that.purchaseLocation) : that.purchaseLocation != null)\n            return false;\n\n        return true;\n    }\n\n    @Override\n    public int hashCode() {\n        int result = baseLocation != null ? baseLocation.hashCode() : 0;\n        result = 31 * result + (purchaseLocation != null ? purchaseLocation.hashCode() : 0);\n        return result;\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/h264/BTree.java",
    "content": "/*\nCopyright (c) 2011 Stanislav Vitvitskiy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this\nsoftware and associated documentation files (the \"Software\"), to deal in the Software\nwithout restriction, including without limitation the rights to use, copy, modify,\nmerge, publish, distribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or\nsubstantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\nPURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\nFOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE\nOR OTHER DEALINGS IN THE SOFTWARE.\n*/\npackage com.googlecode.mp4parser.h264;\n\n\n/**\n * Simple BTree implementation needed for haffman tables\n *\n * @author Stanislav Vitvitskiy\n */\npublic class BTree {\n    private BTree zero;\n    private BTree one;\n    private Object value;\n\n    /**\n     * Adds a leaf value to a binary path specified by path\n     *\n     * @param str\n     * @param value\n     */\n    public void addString(String path, Object value) {\n        if (path.length() == 0) {\n            this.value = value;\n            return;\n        }\n        char charAt = path.charAt(0);\n        BTree branch;\n        if (charAt == '0') {\n            if (zero == null)\n                zero = new BTree();\n            branch = zero;\n        } else {\n            if (one == null)\n                one = new BTree();\n            branch = one;\n        }\n        branch.addString(path.substring(1), value);\n    }\n\n    public BTree down(int b) {\n        if (b == 0)\n            return zero;\n        else\n            return one;\n    }\n\n    public Object getValue() {\n        return value;\n    }\n}"
  },
  {
    "path": "src/com/googlecode/mp4parser/h264/CharCache.java",
    "content": "/*\nCopyright (c) 2011 Stanislav Vitvitskiy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this\nsoftware and associated documentation files (the \"Software\"), to deal in the Software\nwithout restriction, including without limitation the rights to use, copy, modify,\nmerge, publish, distribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or\nsubstantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\nPURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\nFOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE\nOR OTHER DEALINGS IN THE SOFTWARE.\n*/\npackage com.googlecode.mp4parser.h264;\n\npublic class CharCache {\n    private char[] cache;\n    private int pos;\n\n    public CharCache(int capacity) {\n        cache = new char[capacity];\n    }\n\n    public void append(String str) {\n        char[] chars = str.toCharArray();\n        int available = cache.length - pos;\n        int toWrite = chars.length < available ? chars.length : available;\n        System.arraycopy(chars, 0, cache, pos, toWrite);\n        pos += toWrite;\n    }\n\n    public String toString() {\n        return new String(cache, 0, pos);\n    }\n\n    public void clear() {\n        pos = 0;\n    }\n\n    public void append(char c) {\n        if (pos < cache.length - 1) {\n            cache[pos] = c;\n            pos++;\n        }\n    }\n\n    public int length() {\n        return pos;\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/h264/Debug.java",
    "content": "/*\nCopyright (c) 2011 Stanislav Vitvitskiy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this\nsoftware and associated documentation files (the \"Software\"), to deal in the Software\nwithout restriction, including without limitation the rights to use, copy, modify,\nmerge, publish, distribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or\nsubstantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\nPURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\nFOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE\nOR OTHER DEALINGS IN THE SOFTWARE.\n*/\npackage com.googlecode.mp4parser.h264;\n\nimport java.nio.ShortBuffer;\n\npublic class Debug {\n    public final static void print8x8(int[] output) {\n        int i = 0;\n        for (int x = 0; x < 8; x++) {\n            for (int y = 0; y < 8; y++) {\n                System.out.printf(\"%3d, \", output[i]);\n                i++;\n            }\n            System.out.println();\n        }\n    }\n\n    public final static void print8x8(short[] output) {\n        int i = 0;\n        for (int x = 0; x < 8; x++) {\n            for (int y = 0; y < 8; y++) {\n                System.out.printf(\"%3d, \", output[i]);\n                i++;\n            }\n            System.out.println();\n        }\n    }\n\n    public final static void print8x8(ShortBuffer output) {\n        for (int x = 0; x < 8; x++) {\n            for (int y = 0; y < 8; y++) {\n                System.out.printf(\"%3d, \", output.get());\n            }\n            System.out.println();\n        }\n    }\n\n    public static void print(short[] table) {\n        int i = 0;\n        for (int x = 0; x < 8; x++) {\n            for (int y = 0; y < 8; y++) {\n                System.out.printf(\"%3d, \", table[i]);\n                i++;\n            }\n            System.out.println();\n        }\n    }\n\n    public static void trace(String format, Object... args) {\n        // System.out.printf(\"> \" + format + \"\\n\", args);\n    }\n\n    public final static boolean debug = false;\n\n    public static void print(int i) {\n        if (debug)\n            System.out.print(i);\n    }\n\n    public static void print(String string) {\n        if (debug)\n            System.out.print(string);\n    }\n\n    public static void println(String string) {\n        if (debug)\n            System.out.println(string);\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/h264/model/AspectRatio.java",
    "content": "/*\nCopyright (c) 2011 Stanislav Vitvitskiy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this\nsoftware and associated documentation files (the \"Software\"), to deal in the Software\nwithout restriction, including without limitation the rights to use, copy, modify,\nmerge, publish, distribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or\nsubstantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\nPURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\nFOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE\nOR OTHER DEALINGS IN THE SOFTWARE.\n*/\npackage com.googlecode.mp4parser.h264.model;\n\n/**\n * Aspect ratio\n * <p/>\n * dynamic enum\n *\n * @author Stanislav Vitvitskiy\n */\npublic class AspectRatio {\n\n    public static final AspectRatio Extended_SAR = new AspectRatio(255);\n\n    private int value;\n\n    private AspectRatio(int value) {\n        this.value = value;\n    }\n\n    public static AspectRatio fromValue(int value) {\n        if (value == Extended_SAR.value) {\n            return Extended_SAR;\n        }\n        return new AspectRatio(value);\n    }\n\n    public int getValue() {\n        return value;\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/h264/model/BitstreamElement.java",
    "content": "/*\nCopyright (c) 2011 Stanislav Vitvitskiy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this\nsoftware and associated documentation files (the \"Software\"), to deal in the Software\nwithout restriction, including without limitation the rights to use, copy, modify,\nmerge, publish, distribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or\nsubstantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\nPURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\nFOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE\nOR OTHER DEALINGS IN THE SOFTWARE.\n*/\npackage com.googlecode.mp4parser.h264.model;\n\nimport java.io.IOException;\nimport java.io.OutputStream;\n\npublic abstract class BitstreamElement {\n\n    public abstract void write(OutputStream out) throws IOException;\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/h264/model/ChromaFormat.java",
    "content": "/*\nCopyright (c) 2011 Stanislav Vitvitskiy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this\nsoftware and associated documentation files (the \"Software\"), to deal in the Software\nwithout restriction, including without limitation the rights to use, copy, modify,\nmerge, publish, distribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or\nsubstantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\nPURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\nFOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE\nOR OTHER DEALINGS IN THE SOFTWARE.\n*/\npackage com.googlecode.mp4parser.h264.model;\n\n/**\n * Chroma format enum\n *\n * @author Stanislav Vitvitskiy\n */\npublic class ChromaFormat {\n    public static ChromaFormat MONOCHROME = new ChromaFormat(0, 0, 0);\n    public static ChromaFormat YUV_420 = new ChromaFormat(1, 2, 2);\n    public static ChromaFormat YUV_422 = new ChromaFormat(2, 2, 1);\n    public static ChromaFormat YUV_444 = new ChromaFormat(3, 1, 1);\n\n    private int id;\n    private int subWidth;\n    private int subHeight;\n\n    public ChromaFormat(int id, int subWidth, int subHeight) {\n        this.id = id;\n        this.subWidth = subWidth;\n        this.subHeight = subHeight;\n    }\n\n    public static ChromaFormat fromId(int id) {\n        if (id == MONOCHROME.id) {\n            return MONOCHROME;\n        } else if (id == YUV_420.id) {\n            return YUV_420;\n        } else if (id == YUV_422.id) {\n            return YUV_422;\n        } else if (id == YUV_444.id) {\n            return YUV_444;\n        }\n        return null;\n    }\n\n    public int getId() {\n        return id;\n    }\n\n    public int getSubWidth() {\n        return subWidth;\n    }\n\n    public int getSubHeight() {\n        return subHeight;\n    }\n\n    @Override\n    public String toString() {\n        return \"ChromaFormat{\" + \"\\n\" +\n                \"id=\" + id + \",\\n\" +\n                \" subWidth=\" + subWidth + \",\\n\" +\n                \" subHeight=\" + subHeight +\n                '}';\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/h264/model/HRDParameters.java",
    "content": "/*\nCopyright (c) 2011 Stanislav Vitvitskiy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this\nsoftware and associated documentation files (the \"Software\"), to deal in the Software\nwithout restriction, including without limitation the rights to use, copy, modify,\nmerge, publish, distribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or\nsubstantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\nPURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\nFOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE\nOR OTHER DEALINGS IN THE SOFTWARE.\n*/\npackage com.googlecode.mp4parser.h264.model;\n\nimport java.util.Arrays;\n\npublic class HRDParameters {\n\n    public int cpb_cnt_minus1;\n    public int bit_rate_scale;\n    public int cpb_size_scale;\n    public int[] bit_rate_value_minus1;\n    public int[] cpb_size_value_minus1;\n    public boolean[] cbr_flag;\n    public int initial_cpb_removal_delay_length_minus1;\n    public int cpb_removal_delay_length_minus1;\n    public int dpb_output_delay_length_minus1;\n    public int time_offset_length;\n\n    @Override\n    public String toString() {\n        return \"HRDParameters{\" +\n                \"cpb_cnt_minus1=\" + cpb_cnt_minus1 +\n                \", bit_rate_scale=\" + bit_rate_scale +\n                \", cpb_size_scale=\" + cpb_size_scale +\n                \", bit_rate_value_minus1=\" + Arrays.toString(bit_rate_value_minus1) +\n                \", cpb_size_value_minus1=\" + Arrays.toString(cpb_size_value_minus1) +\n                \", cbr_flag=\" + Arrays.toString(cbr_flag) +\n                \", initial_cpb_removal_delay_length_minus1=\" + initial_cpb_removal_delay_length_minus1 +\n                \", cpb_removal_delay_length_minus1=\" + cpb_removal_delay_length_minus1 +\n                \", dpb_output_delay_length_minus1=\" + dpb_output_delay_length_minus1 +\n                \", time_offset_length=\" + time_offset_length +\n                '}';\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/h264/model/PictureParameterSet.java",
    "content": "/*\nCopyright (c) 2011 Stanislav Vitvitskiy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this\nsoftware and associated documentation files (the \"Software\"), to deal in the Software\nwithout restriction, including without limitation the rights to use, copy, modify,\nmerge, publish, distribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or\nsubstantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\nPURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\nFOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE\nOR OTHER DEALINGS IN THE SOFTWARE.\n*/\npackage com.googlecode.mp4parser.h264.model;\n\nimport com.googlecode.mp4parser.h264.read.CAVLCReader;\nimport com.googlecode.mp4parser.h264.write.CAVLCWriter;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.util.Arrays;\n\n/**\n * Picture Parameter Set entity of H264 bitstream\n * <p/>\n * capable to serialize / deserialize with CAVLC bitstream\n *\n * @author Stanislav Vitvitskiy\n */\npublic class PictureParameterSet extends BitstreamElement {\n\n    public static class PPSExt {\n        public boolean transform_8x8_mode_flag;\n        public ScalingMatrix scalindMatrix = new ScalingMatrix();\n        public int second_chroma_qp_index_offset;\n        public boolean[] pic_scaling_list_present_flag;\n\n        @Override\n        public String toString() {\n            return \"PPSExt{\" +\n                    \"transform_8x8_mode_flag=\" + transform_8x8_mode_flag +\n                    \", scalindMatrix=\" + scalindMatrix +\n                    \", second_chroma_qp_index_offset=\" + second_chroma_qp_index_offset +\n                    \", pic_scaling_list_present_flag=\" + pic_scaling_list_present_flag +\n                    '}';\n        }\n    }\n\n    public boolean entropy_coding_mode_flag;\n    public int num_ref_idx_l0_active_minus1;\n    public int num_ref_idx_l1_active_minus1;\n    public int slice_group_change_rate_minus1;\n    public int pic_parameter_set_id;\n    public int seq_parameter_set_id;\n    public boolean pic_order_present_flag;\n    public int num_slice_groups_minus1;\n    public int slice_group_map_type;\n    public boolean weighted_pred_flag;\n    public int weighted_bipred_idc;\n    public int pic_init_qp_minus26;\n    public int pic_init_qs_minus26;\n    public int chroma_qp_index_offset;\n    public boolean deblocking_filter_control_present_flag;\n    public boolean constrained_intra_pred_flag;\n    public boolean redundant_pic_cnt_present_flag;\n    public int[] top_left;\n    public int[] bottom_right;\n    public int[] run_length_minus1;\n    public boolean slice_group_change_direction_flag;\n    public int[] slice_group_id;\n    public PPSExt extended;\n\n    public static PictureParameterSet read(byte[] b) throws IOException {\n        return read(new ByteArrayInputStream(b));\n    }\n\n    public static PictureParameterSet read(InputStream is) throws IOException {\n        CAVLCReader reader = new CAVLCReader(is);\n        PictureParameterSet pps = new PictureParameterSet();\n\n        pps.pic_parameter_set_id = reader.readUE(\"PPS: pic_parameter_set_id\");\n        pps.seq_parameter_set_id = reader.readUE(\"PPS: seq_parameter_set_id\");\n        pps.entropy_coding_mode_flag = reader\n                .readBool(\"PPS: entropy_coding_mode_flag\");\n        pps.pic_order_present_flag = reader\n                .readBool(\"PPS: pic_order_present_flag\");\n        pps.num_slice_groups_minus1 = reader\n                .readUE(\"PPS: num_slice_groups_minus1\");\n        if (pps.num_slice_groups_minus1 > 0) {\n            pps.slice_group_map_type = reader\n                    .readUE(\"PPS: slice_group_map_type\");\n            pps.top_left = new int[pps.num_slice_groups_minus1 + 1];\n            pps.bottom_right = new int[pps.num_slice_groups_minus1 + 1];\n            pps.run_length_minus1 = new int[pps.num_slice_groups_minus1 + 1];\n            if (pps.slice_group_map_type == 0)\n                for (int iGroup = 0; iGroup <= pps.num_slice_groups_minus1; iGroup++)\n                    pps.run_length_minus1[iGroup] = reader\n                            .readUE(\"PPS: run_length_minus1\");\n            else if (pps.slice_group_map_type == 2)\n                for (int iGroup = 0; iGroup < pps.num_slice_groups_minus1; iGroup++) {\n                    pps.top_left[iGroup] = reader.readUE(\"PPS: top_left\");\n                    pps.bottom_right[iGroup] = reader\n                            .readUE(\"PPS: bottom_right\");\n                }\n            else if (pps.slice_group_map_type == 3\n                    || pps.slice_group_map_type == 4\n                    || pps.slice_group_map_type == 5) {\n                pps.slice_group_change_direction_flag = reader\n                        .readBool(\"PPS: slice_group_change_direction_flag\");\n                pps.slice_group_change_rate_minus1 = reader\n                        .readUE(\"PPS: slice_group_change_rate_minus1\");\n            } else if (pps.slice_group_map_type == 6) {\n                int NumberBitsPerSliceGroupId;\n                if (pps.num_slice_groups_minus1 + 1 > 4)\n                    NumberBitsPerSliceGroupId = 3;\n                else if (pps.num_slice_groups_minus1 + 1 > 2)\n                    NumberBitsPerSliceGroupId = 2;\n                else\n                    NumberBitsPerSliceGroupId = 1;\n                int pic_size_in_map_units_minus1 = reader\n                        .readUE(\"PPS: pic_size_in_map_units_minus1\");\n                pps.slice_group_id = new int[pic_size_in_map_units_minus1 + 1];\n                for (int i = 0; i <= pic_size_in_map_units_minus1; i++) {\n                    pps.slice_group_id[i] = reader.readU(\n                            NumberBitsPerSliceGroupId, \"PPS: slice_group_id [\"\n                            + i + \"]f\");\n                }\n            }\n        }\n        pps.num_ref_idx_l0_active_minus1 = reader\n                .readUE(\"PPS: num_ref_idx_l0_active_minus1\");\n        pps.num_ref_idx_l1_active_minus1 = reader\n                .readUE(\"PPS: num_ref_idx_l1_active_minus1\");\n        pps.weighted_pred_flag = reader.readBool(\"PPS: weighted_pred_flag\");\n        pps.weighted_bipred_idc = (int) reader.readNBit(2,\n                \"PPS: weighted_bipred_idc\");\n        pps.pic_init_qp_minus26 = reader.readSE(\"PPS: pic_init_qp_minus26\");\n        pps.pic_init_qs_minus26 = reader.readSE(\"PPS: pic_init_qs_minus26\");\n        pps.chroma_qp_index_offset = reader\n                .readSE(\"PPS: chroma_qp_index_offset\");\n        pps.deblocking_filter_control_present_flag = reader\n                .readBool(\"PPS: deblocking_filter_control_present_flag\");\n        pps.constrained_intra_pred_flag = reader\n                .readBool(\"PPS: constrained_intra_pred_flag\");\n        pps.redundant_pic_cnt_present_flag = reader\n                .readBool(\"PPS: redundant_pic_cnt_present_flag\");\n        if (reader.moreRBSPData()) {\n            pps.extended = new PictureParameterSet.PPSExt();\n            pps.extended.transform_8x8_mode_flag = reader\n                    .readBool(\"PPS: transform_8x8_mode_flag\");\n            boolean pic_scaling_matrix_present_flag = reader\n                    .readBool(\"PPS: pic_scaling_matrix_present_flag\");\n            if (pic_scaling_matrix_present_flag) {\n                for (int i = 0; i < 6 + 2 * (pps.extended.transform_8x8_mode_flag ? 1\n                        : 0); i++) {\n                    boolean pic_scaling_list_present_flag = reader\n                            .readBool(\"PPS: pic_scaling_list_present_flag\");\n                    if (pic_scaling_list_present_flag) {\n                        pps.extended.scalindMatrix.ScalingList4x4 = new ScalingList[8];\n                        pps.extended.scalindMatrix.ScalingList8x8 = new ScalingList[8];\n                        if (i < 6) {\n                            pps.extended.scalindMatrix.ScalingList4x4[i] = ScalingList\n                                    .read(reader, 16);\n                        } else {\n                            pps.extended.scalindMatrix.ScalingList8x8[i - 6] = ScalingList\n                                    .read(reader, 64);\n                        }\n                    }\n                }\n            }\n            pps.extended.second_chroma_qp_index_offset = reader\n                    .readSE(\"PPS: second_chroma_qp_index_offset\");\n        }\n\n        reader.readTrailingBits();\n\n        return pps;\n    }\n\n    public void write(OutputStream out) throws IOException {\n        CAVLCWriter writer = new CAVLCWriter(out);\n\n        writer.writeUE(pic_parameter_set_id, \"PPS: pic_parameter_set_id\");\n        writer.writeUE(seq_parameter_set_id, \"PPS: seq_parameter_set_id\");\n        writer.writeBool(entropy_coding_mode_flag,\n                \"PPS: entropy_coding_mode_flag\");\n        writer.writeBool(pic_order_present_flag, \"PPS: pic_order_present_flag\");\n        writer.writeUE(num_slice_groups_minus1, \"PPS: num_slice_groups_minus1\");\n        if (num_slice_groups_minus1 > 0) {\n            writer.writeUE(slice_group_map_type, \"PPS: slice_group_map_type\");\n            int[] top_left = new int[1];\n            int[] bottom_right = new int[1];\n            int[] run_length_minus1 = new int[1];\n            if (slice_group_map_type == 0) {\n                for (int iGroup = 0; iGroup <= num_slice_groups_minus1; iGroup++) {\n                    writer.writeUE(run_length_minus1[iGroup], \"PPS: \");\n                }\n            } else if (slice_group_map_type == 2) {\n                for (int iGroup = 0; iGroup < num_slice_groups_minus1; iGroup++) {\n                    writer.writeUE(top_left[iGroup], \"PPS: \");\n                    writer.writeUE(bottom_right[iGroup], \"PPS: \");\n                }\n            } else if (slice_group_map_type == 3 || slice_group_map_type == 4\n                    || slice_group_map_type == 5) {\n                writer.writeBool(slice_group_change_direction_flag,\n                        \"PPS: slice_group_change_direction_flag\");\n                writer.writeUE(slice_group_change_rate_minus1,\n                        \"PPS: slice_group_change_rate_minus1\");\n            } else if (slice_group_map_type == 6) {\n                int NumberBitsPerSliceGroupId;\n                if (num_slice_groups_minus1 + 1 > 4)\n                    NumberBitsPerSliceGroupId = 3;\n                else if (num_slice_groups_minus1 + 1 > 2)\n                    NumberBitsPerSliceGroupId = 2;\n                else\n                    NumberBitsPerSliceGroupId = 1;\n                writer.writeUE(slice_group_id.length, \"PPS: \");\n                for (int i = 0; i <= slice_group_id.length; i++) {\n                    writer.writeU(slice_group_id[i], NumberBitsPerSliceGroupId);\n                }\n            }\n        }\n        writer.writeUE(num_ref_idx_l0_active_minus1,\n                \"PPS: num_ref_idx_l0_active_minus1\");\n        writer.writeUE(num_ref_idx_l1_active_minus1,\n                \"PPS: num_ref_idx_l1_active_minus1\");\n        writer.writeBool(weighted_pred_flag, \"PPS: weighted_pred_flag\");\n        writer.writeNBit(weighted_bipred_idc, 2, \"PPS: weighted_bipred_idc\");\n        writer.writeSE(pic_init_qp_minus26, \"PPS: pic_init_qp_minus26\");\n        writer.writeSE(pic_init_qs_minus26, \"PPS: pic_init_qs_minus26\");\n        writer.writeSE(chroma_qp_index_offset, \"PPS: chroma_qp_index_offset\");\n        writer.writeBool(deblocking_filter_control_present_flag,\n                \"PPS: deblocking_filter_control_present_flag\");\n        writer.writeBool(constrained_intra_pred_flag,\n                \"PPS: constrained_intra_pred_flag\");\n        writer.writeBool(redundant_pic_cnt_present_flag,\n                \"PPS: redundant_pic_cnt_present_flag\");\n        if (extended != null) {\n            writer.writeBool(extended.transform_8x8_mode_flag,\n                    \"PPS: transform_8x8_mode_flag\");\n            writer.writeBool(extended.scalindMatrix != null,\n                    \"PPS: scalindMatrix\");\n            if (extended.scalindMatrix != null) {\n                for (int i = 0; i < 6 + 2 * (extended.transform_8x8_mode_flag ? 1\n                        : 0); i++) {\n                    if (i < 6) {\n                        writer\n                                .writeBool(\n                                        extended.scalindMatrix.ScalingList4x4[i] != null,\n                                        \"PPS: \");\n                        if (extended.scalindMatrix.ScalingList4x4[i] != null) {\n                            extended.scalindMatrix.ScalingList4x4[i]\n                                    .write(writer);\n                        }\n\n                    } else {\n                        writer\n                                .writeBool(\n                                        extended.scalindMatrix.ScalingList8x8[i - 6] != null,\n                                        \"PPS: \");\n                        if (extended.scalindMatrix.ScalingList8x8[i - 6] != null) {\n                            extended.scalindMatrix.ScalingList8x8[i - 6]\n                                    .write(writer);\n                        }\n                    }\n                }\n            }\n            writer.writeSE(extended.second_chroma_qp_index_offset, \"PPS: \");\n        }\n\n        writer.writeTrailingBits();\n    }\n\n    @Override\n    public int hashCode() {\n        final int prime = 31;\n        int result = 1;\n        result = prime * result + Arrays.hashCode(bottom_right);\n        result = prime * result + chroma_qp_index_offset;\n        result = prime * result + (constrained_intra_pred_flag ? 1231 : 1237);\n        result = prime * result\n                + (deblocking_filter_control_present_flag ? 1231 : 1237);\n        result = prime * result + (entropy_coding_mode_flag ? 1231 : 1237);\n        result = prime * result\n                + ((extended == null) ? 0 : extended.hashCode());\n        result = prime * result + num_ref_idx_l0_active_minus1;\n        result = prime * result + num_ref_idx_l1_active_minus1;\n        result = prime * result + num_slice_groups_minus1;\n        result = prime * result + pic_init_qp_minus26;\n        result = prime * result + pic_init_qs_minus26;\n        result = prime * result + (pic_order_present_flag ? 1231 : 1237);\n        result = prime * result + pic_parameter_set_id;\n        result = prime * result\n                + (redundant_pic_cnt_present_flag ? 1231 : 1237);\n        result = prime * result + Arrays.hashCode(run_length_minus1);\n        result = prime * result + seq_parameter_set_id;\n        result = prime * result\n                + (slice_group_change_direction_flag ? 1231 : 1237);\n        result = prime * result + slice_group_change_rate_minus1;\n        result = prime * result + Arrays.hashCode(slice_group_id);\n        result = prime * result + slice_group_map_type;\n        result = prime * result + Arrays.hashCode(top_left);\n        result = prime * result + weighted_bipred_idc;\n        result = prime * result + (weighted_pred_flag ? 1231 : 1237);\n        return result;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (this == obj)\n            return true;\n        if (obj == null)\n            return false;\n        if (getClass() != obj.getClass())\n            return false;\n        PictureParameterSet other = (PictureParameterSet) obj;\n        if (!Arrays.equals(bottom_right, other.bottom_right))\n            return false;\n        if (chroma_qp_index_offset != other.chroma_qp_index_offset)\n            return false;\n        if (constrained_intra_pred_flag != other.constrained_intra_pred_flag)\n            return false;\n        if (deblocking_filter_control_present_flag != other.deblocking_filter_control_present_flag)\n            return false;\n        if (entropy_coding_mode_flag != other.entropy_coding_mode_flag)\n            return false;\n        if (extended == null) {\n            if (other.extended != null)\n                return false;\n        } else if (!extended.equals(other.extended))\n            return false;\n        if (num_ref_idx_l0_active_minus1 != other.num_ref_idx_l0_active_minus1)\n            return false;\n        if (num_ref_idx_l1_active_minus1 != other.num_ref_idx_l1_active_minus1)\n            return false;\n        if (num_slice_groups_minus1 != other.num_slice_groups_minus1)\n            return false;\n        if (pic_init_qp_minus26 != other.pic_init_qp_minus26)\n            return false;\n        if (pic_init_qs_minus26 != other.pic_init_qs_minus26)\n            return false;\n        if (pic_order_present_flag != other.pic_order_present_flag)\n            return false;\n        if (pic_parameter_set_id != other.pic_parameter_set_id)\n            return false;\n        if (redundant_pic_cnt_present_flag != other.redundant_pic_cnt_present_flag)\n            return false;\n        if (!Arrays.equals(run_length_minus1, other.run_length_minus1))\n            return false;\n        if (seq_parameter_set_id != other.seq_parameter_set_id)\n            return false;\n        if (slice_group_change_direction_flag != other.slice_group_change_direction_flag)\n            return false;\n        if (slice_group_change_rate_minus1 != other.slice_group_change_rate_minus1)\n            return false;\n        if (!Arrays.equals(slice_group_id, other.slice_group_id))\n            return false;\n        if (slice_group_map_type != other.slice_group_map_type)\n            return false;\n        if (!Arrays.equals(top_left, other.top_left))\n            return false;\n        if (weighted_bipred_idc != other.weighted_bipred_idc)\n            return false;\n        if (weighted_pred_flag != other.weighted_pred_flag)\n            return false;\n        return true;\n    }\n\n    @Override\n    public String toString() {\n        return \"PictureParameterSet{\" +\n                \"\\n       entropy_coding_mode_flag=\" + entropy_coding_mode_flag +\n                \",\\n       num_ref_idx_l0_active_minus1=\" + num_ref_idx_l0_active_minus1 +\n                \",\\n       num_ref_idx_l1_active_minus1=\" + num_ref_idx_l1_active_minus1 +\n                \",\\n       slice_group_change_rate_minus1=\" + slice_group_change_rate_minus1 +\n                \",\\n       pic_parameter_set_id=\" + pic_parameter_set_id +\n                \",\\n       seq_parameter_set_id=\" + seq_parameter_set_id +\n                \",\\n       pic_order_present_flag=\" + pic_order_present_flag +\n                \",\\n       num_slice_groups_minus1=\" + num_slice_groups_minus1 +\n                \",\\n       slice_group_map_type=\" + slice_group_map_type +\n                \",\\n       weighted_pred_flag=\" + weighted_pred_flag +\n                \",\\n       weighted_bipred_idc=\" + weighted_bipred_idc +\n                \",\\n       pic_init_qp_minus26=\" + pic_init_qp_minus26 +\n                \",\\n       pic_init_qs_minus26=\" + pic_init_qs_minus26 +\n                \",\\n       chroma_qp_index_offset=\" + chroma_qp_index_offset +\n                \",\\n       deblocking_filter_control_present_flag=\" + deblocking_filter_control_present_flag +\n                \",\\n       constrained_intra_pred_flag=\" + constrained_intra_pred_flag +\n                \",\\n       redundant_pic_cnt_present_flag=\" + redundant_pic_cnt_present_flag +\n                \",\\n       top_left=\" + top_left +\n                \",\\n       bottom_right=\" + bottom_right +\n                \",\\n       run_length_minus1=\" + run_length_minus1 +\n                \",\\n       slice_group_change_direction_flag=\" + slice_group_change_direction_flag +\n                \",\\n       slice_group_id=\" + slice_group_id +\n                \",\\n       extended=\" + extended +\n                '}';\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/h264/model/ScalingList.java",
    "content": "/*\nCopyright (c) 2011 Stanislav Vitvitskiy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this\nsoftware and associated documentation files (the \"Software\"), to deal in the Software\nwithout restriction, including without limitation the rights to use, copy, modify,\nmerge, publish, distribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or\nsubstantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\nPURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\nFOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE\nOR OTHER DEALINGS IN THE SOFTWARE.\n*/\npackage com.googlecode.mp4parser.h264.model;\n\nimport com.googlecode.mp4parser.h264.read.CAVLCReader;\nimport com.googlecode.mp4parser.h264.write.CAVLCWriter;\n\nimport java.io.IOException;\n\n/**\n * Scaling list entity\n * <p/>\n * capable to serialize / deserialize with CAVLC bitstream\n *\n * @author Stanislav Vitvitskiy\n */\npublic class ScalingList {\n\n    public int[] scalingList;\n    public boolean useDefaultScalingMatrixFlag;\n\n    public void write(CAVLCWriter out) throws IOException {\n        if (useDefaultScalingMatrixFlag) {\n            out.writeSE(0, \"SPS: \");\n            return;\n        }\n\n        int lastScale = 8;\n        int nextScale = 8;\n        for (int j = 0; j < scalingList.length; j++) {\n            if (nextScale != 0) {\n                int deltaScale = scalingList[j] - lastScale - 256;\n                out.writeSE(deltaScale, \"SPS: \");\n            }\n            lastScale = scalingList[j];\n        }\n    }\n\n    public static ScalingList read(CAVLCReader is, int sizeOfScalingList)\n            throws IOException {\n\n        ScalingList sl = new ScalingList();\n        sl.scalingList = new int[sizeOfScalingList];\n        int lastScale = 8;\n        int nextScale = 8;\n        for (int j = 0; j < sizeOfScalingList; j++) {\n            if (nextScale != 0) {\n                int deltaScale = is.readSE(\"deltaScale\");\n                nextScale = (lastScale + deltaScale + 256) % 256;\n                sl.useDefaultScalingMatrixFlag = (j == 0 && nextScale == 0);\n            }\n            sl.scalingList[j] = nextScale == 0 ? lastScale : nextScale;\n            lastScale = sl.scalingList[j];\n        }\n        return sl;\n    }\n\n    @Override\n    public String toString() {\n        return \"ScalingList{\" +\n                \"scalingList=\" + scalingList +\n                \", useDefaultScalingMatrixFlag=\" + useDefaultScalingMatrixFlag +\n                '}';\n    }\n}"
  },
  {
    "path": "src/com/googlecode/mp4parser/h264/model/ScalingMatrix.java",
    "content": "/*\nCopyright (c) 2011 Stanislav Vitvitskiy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this\nsoftware and associated documentation files (the \"Software\"), to deal in the Software\nwithout restriction, including without limitation the rights to use, copy, modify,\nmerge, publish, distribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or\nsubstantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\nPURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\nFOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE\nOR OTHER DEALINGS IN THE SOFTWARE.\n*/\npackage com.googlecode.mp4parser.h264.model;\n\nimport java.util.Arrays;\n\npublic class ScalingMatrix {\n\n    public ScalingList[] ScalingList4x4;\n    public ScalingList[] ScalingList8x8;\n\n    @Override\n    public String toString() {\n        return \"ScalingMatrix{\" +\n                \"ScalingList4x4=\" + (ScalingList4x4 == null ? null : Arrays.asList(ScalingList4x4)) + \"\\n\" +\n                \", ScalingList8x8=\" + (ScalingList8x8 == null ? null : Arrays.asList(ScalingList8x8)) + \"\\n\" +\n                '}';\n    }\n}"
  },
  {
    "path": "src/com/googlecode/mp4parser/h264/model/SeqParameterSet.java",
    "content": "/*\nCopyright (c) 2011 Stanislav Vitvitskiy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this\nsoftware and associated documentation files (the \"Software\"), to deal in the Software\nwithout restriction, including without limitation the rights to use, copy, modify,\nmerge, publish, distribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or\nsubstantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\nPURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\nFOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE\nOR OTHER DEALINGS IN THE SOFTWARE.\n*/\npackage com.googlecode.mp4parser.h264.model;\n\nimport com.googlecode.mp4parser.h264.read.CAVLCReader;\nimport com.googlecode.mp4parser.h264.write.CAVLCWriter;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\n\n/**\n * Sequence Parameter Set structure of h264 bitstream\n * <p/>\n * capable to serialize and deserialize with CAVLC bitstream\n *\n * @author Stanislav Vitvitskiy\n */\npublic class SeqParameterSet extends BitstreamElement {\n    public int pic_order_cnt_type;\n    public boolean field_pic_flag;\n    public boolean delta_pic_order_always_zero_flag;\n    public boolean weighted_pred_flag;\n    public int weighted_bipred_idc;\n    public boolean entropy_coding_mode_flag;\n    public boolean mb_adaptive_frame_field_flag;\n    public boolean direct_8x8_inference_flag;\n    public ChromaFormat chroma_format_idc;\n    public int log2_max_frame_num_minus4;\n    public int log2_max_pic_order_cnt_lsb_minus4;\n    public int pic_height_in_map_units_minus1;\n    public int pic_width_in_mbs_minus1;\n    public int bit_depth_luma_minus8;\n    public int bit_depth_chroma_minus8;\n    public boolean qpprime_y_zero_transform_bypass_flag;\n    public int profile_idc;\n    public boolean constraint_set_0_flag;\n    public boolean constraint_set_1_flag;\n    public boolean constraint_set_2_flag;\n    public boolean constraint_set_3_flag;\n    public int level_idc;\n    public int seq_parameter_set_id;\n    public boolean residual_color_transform_flag;\n    public int offset_for_non_ref_pic;\n    public int offset_for_top_to_bottom_field;\n    public int num_ref_frames;\n    public boolean gaps_in_frame_num_value_allowed_flag;\n    public boolean frame_mbs_only_flag;\n    public boolean frame_cropping_flag;\n    public int frame_crop_left_offset;\n    public int frame_crop_right_offset;\n    public int frame_crop_top_offset;\n    public int frame_crop_bottom_offset;\n    public int[] offsetForRefFrame;\n    public VUIParameters vuiParams;\n    public ScalingMatrix scalingMatrix;\n    public int num_ref_frames_in_pic_order_cnt_cycle;\n\n    public static SeqParameterSet read(InputStream is) throws IOException {\n        CAVLCReader reader = new CAVLCReader(is);\n        SeqParameterSet sps = new SeqParameterSet();\n\n        sps.profile_idc = (int) reader.readNBit(8, \"SPS: profile_idc\");\n        sps.constraint_set_0_flag = reader\n                .readBool(\"SPS: constraint_set_0_flag\");\n        sps.constraint_set_1_flag = reader\n                .readBool(\"SPS: constraint_set_1_flag\");\n        sps.constraint_set_2_flag = reader\n                .readBool(\"SPS: constraint_set_2_flag\");\n        sps.constraint_set_3_flag = reader\n                .readBool(\"SPS: constraint_set_3_flag\");\n        reader.readNBit(4, \"SPS: reserved_zero_4bits\");\n        sps.level_idc = (int) reader.readNBit(8, \"SPS: level_idc\");\n        sps.seq_parameter_set_id = reader.readUE(\"SPS: seq_parameter_set_id\");\n\n        if (sps.profile_idc == 100 || sps.profile_idc == 110\n                || sps.profile_idc == 122 || sps.profile_idc == 144) {\n            sps.chroma_format_idc = ChromaFormat.fromId(reader\n                    .readUE(\"SPS: chroma_format_idc\"));\n            if (sps.chroma_format_idc == ChromaFormat.YUV_444) {\n                sps.residual_color_transform_flag = reader\n                        .readBool(\"SPS: residual_color_transform_flag\");\n            }\n            sps.bit_depth_luma_minus8 = reader\n                    .readUE(\"SPS: bit_depth_luma_minus8\");\n            sps.bit_depth_chroma_minus8 = reader\n                    .readUE(\"SPS: bit_depth_chroma_minus8\");\n            sps.qpprime_y_zero_transform_bypass_flag = reader\n                    .readBool(\"SPS: qpprime_y_zero_transform_bypass_flag\");\n            boolean seqScalingMatrixPresent = reader\n                    .readBool(\"SPS: seq_scaling_matrix_present_lag\");\n            if (seqScalingMatrixPresent) {\n                readScalingListMatrix(reader, sps);\n            }\n        } else {\n            sps.chroma_format_idc = ChromaFormat.YUV_420;\n        }\n        sps.log2_max_frame_num_minus4 = reader\n                .readUE(\"SPS: log2_max_frame_num_minus4\");\n        sps.pic_order_cnt_type = reader.readUE(\"SPS: pic_order_cnt_type\");\n        if (sps.pic_order_cnt_type == 0) {\n            sps.log2_max_pic_order_cnt_lsb_minus4 = reader\n                    .readUE(\"SPS: log2_max_pic_order_cnt_lsb_minus4\");\n        } else if (sps.pic_order_cnt_type == 1) {\n            sps.delta_pic_order_always_zero_flag = reader\n                    .readBool(\"SPS: delta_pic_order_always_zero_flag\");\n            sps.offset_for_non_ref_pic = reader\n                    .readSE(\"SPS: offset_for_non_ref_pic\");\n            sps.offset_for_top_to_bottom_field = reader\n                    .readSE(\"SPS: offset_for_top_to_bottom_field\");\n            sps.num_ref_frames_in_pic_order_cnt_cycle = reader\n                    .readUE(\"SPS: num_ref_frames_in_pic_order_cnt_cycle\");\n            sps.offsetForRefFrame = new int[sps.num_ref_frames_in_pic_order_cnt_cycle];\n            for (int i = 0; i < sps.num_ref_frames_in_pic_order_cnt_cycle; i++) {\n                sps.offsetForRefFrame[i] = reader\n                        .readSE(\"SPS: offsetForRefFrame [\" + i + \"]\");\n            }\n        }\n        sps.num_ref_frames = reader.readUE(\"SPS: num_ref_frames\");\n        sps.gaps_in_frame_num_value_allowed_flag = reader\n                .readBool(\"SPS: gaps_in_frame_num_value_allowed_flag\");\n        sps.pic_width_in_mbs_minus1 = reader\n                .readUE(\"SPS: pic_width_in_mbs_minus1\");\n        sps.pic_height_in_map_units_minus1 = reader\n                .readUE(\"SPS: pic_height_in_map_units_minus1\");\n        sps.frame_mbs_only_flag = reader.readBool(\"SPS: frame_mbs_only_flag\");\n        if (!sps.frame_mbs_only_flag) {\n            sps.mb_adaptive_frame_field_flag = reader\n                    .readBool(\"SPS: mb_adaptive_frame_field_flag\");\n        }\n        sps.direct_8x8_inference_flag = reader\n                .readBool(\"SPS: direct_8x8_inference_flag\");\n        sps.frame_cropping_flag = reader.readBool(\"SPS: frame_cropping_flag\");\n        if (sps.frame_cropping_flag) {\n            sps.frame_crop_left_offset = reader\n                    .readUE(\"SPS: frame_crop_left_offset\");\n            sps.frame_crop_right_offset = reader\n                    .readUE(\"SPS: frame_crop_right_offset\");\n            sps.frame_crop_top_offset = reader\n                    .readUE(\"SPS: frame_crop_top_offset\");\n            sps.frame_crop_bottom_offset = reader\n                    .readUE(\"SPS: frame_crop_bottom_offset\");\n        }\n        boolean vui_parameters_present_flag = reader\n                .readBool(\"SPS: vui_parameters_present_flag\");\n        if (vui_parameters_present_flag)\n            sps.vuiParams = ReadVUIParameters(reader);\n\n        reader.readTrailingBits();\n\n        return sps;\n    }\n\n    private static void readScalingListMatrix(CAVLCReader reader,\n                                              SeqParameterSet sps) throws IOException {\n        sps.scalingMatrix = new ScalingMatrix();\n        for (int i = 0; i < 8; i++) {\n            boolean seqScalingListPresentFlag = reader\n                    .readBool(\"SPS: seqScalingListPresentFlag\");\n            if (seqScalingListPresentFlag) {\n                sps.scalingMatrix.ScalingList4x4 = new ScalingList[8];\n                sps.scalingMatrix.ScalingList8x8 = new ScalingList[8];\n                if (i < 6) {\n                    sps.scalingMatrix.ScalingList4x4[i] = ScalingList.read(\n                            reader, 16);\n                } else {\n                    sps.scalingMatrix.ScalingList8x8[i - 6] = ScalingList.read(\n                            reader, 64);\n                }\n            }\n        }\n    }\n\n    private static VUIParameters ReadVUIParameters(CAVLCReader reader)\n            throws IOException {\n        VUIParameters vuip = new VUIParameters();\n        vuip.aspect_ratio_info_present_flag = reader\n                .readBool(\"VUI: aspect_ratio_info_present_flag\");\n        if (vuip.aspect_ratio_info_present_flag) {\n            vuip.aspect_ratio = AspectRatio.fromValue((int) reader.readNBit(8,\n                    \"VUI: aspect_ratio\"));\n            if (vuip.aspect_ratio == AspectRatio.Extended_SAR) {\n                vuip.sar_width = (int) reader.readNBit(16, \"VUI: sar_width\");\n                vuip.sar_height = (int) reader.readNBit(16, \"VUI: sar_height\");\n            }\n        }\n        vuip.overscan_info_present_flag = reader\n                .readBool(\"VUI: overscan_info_present_flag\");\n        if (vuip.overscan_info_present_flag) {\n            vuip.overscan_appropriate_flag = reader\n                    .readBool(\"VUI: overscan_appropriate_flag\");\n        }\n        vuip.video_signal_type_present_flag = reader\n                .readBool(\"VUI: video_signal_type_present_flag\");\n        if (vuip.video_signal_type_present_flag) {\n            vuip.video_format = (int) reader.readNBit(3, \"VUI: video_format\");\n            vuip.video_full_range_flag = reader\n                    .readBool(\"VUI: video_full_range_flag\");\n            vuip.colour_description_present_flag = reader\n                    .readBool(\"VUI: colour_description_present_flag\");\n            if (vuip.colour_description_present_flag) {\n                vuip.colour_primaries = (int) reader.readNBit(8,\n                        \"VUI: colour_primaries\");\n                vuip.transfer_characteristics = (int) reader.readNBit(8,\n                        \"VUI: transfer_characteristics\");\n                vuip.matrix_coefficients = (int) reader.readNBit(8,\n                        \"VUI: matrix_coefficients\");\n            }\n        }\n        vuip.chroma_loc_info_present_flag = reader\n                .readBool(\"VUI: chroma_loc_info_present_flag\");\n        if (vuip.chroma_loc_info_present_flag) {\n            vuip.chroma_sample_loc_type_top_field = reader\n                    .readUE(\"VUI chroma_sample_loc_type_top_field\");\n            vuip.chroma_sample_loc_type_bottom_field = reader\n                    .readUE(\"VUI chroma_sample_loc_type_bottom_field\");\n        }\n        vuip.timing_info_present_flag = reader\n                .readBool(\"VUI: timing_info_present_flag\");\n        if (vuip.timing_info_present_flag) {\n            vuip.num_units_in_tick = (int) reader.readNBit(32,\n                    \"VUI: num_units_in_tick\");\n            vuip.time_scale = (int) reader.readNBit(32, \"VUI: time_scale\");\n            vuip.fixed_frame_rate_flag = reader\n                    .readBool(\"VUI: fixed_frame_rate_flag\");\n        }\n        boolean nal_hrd_parameters_present_flag = reader\n                .readBool(\"VUI: nal_hrd_parameters_present_flag\");\n        if (nal_hrd_parameters_present_flag)\n            vuip.nalHRDParams = readHRDParameters(reader);\n        boolean vcl_hrd_parameters_present_flag = reader\n                .readBool(\"VUI: vcl_hrd_parameters_present_flag\");\n        if (vcl_hrd_parameters_present_flag)\n            vuip.vclHRDParams = readHRDParameters(reader);\n        if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) {\n            vuip.low_delay_hrd_flag = reader\n                    .readBool(\"VUI: low_delay_hrd_flag\");\n        }\n        vuip.pic_struct_present_flag = reader\n                .readBool(\"VUI: pic_struct_present_flag\");\n        boolean bitstream_restriction_flag = reader\n                .readBool(\"VUI: bitstream_restriction_flag\");\n        if (bitstream_restriction_flag) {\n            vuip.bitstreamRestriction = new VUIParameters.BitstreamRestriction();\n            vuip.bitstreamRestriction.motion_vectors_over_pic_boundaries_flag = reader\n                    .readBool(\"VUI: motion_vectors_over_pic_boundaries_flag\");\n            vuip.bitstreamRestriction.max_bytes_per_pic_denom = reader\n                    .readUE(\"VUI max_bytes_per_pic_denom\");\n            vuip.bitstreamRestriction.max_bits_per_mb_denom = reader\n                    .readUE(\"VUI max_bits_per_mb_denom\");\n            vuip.bitstreamRestriction.log2_max_mv_length_horizontal = reader\n                    .readUE(\"VUI log2_max_mv_length_horizontal\");\n            vuip.bitstreamRestriction.log2_max_mv_length_vertical = reader\n                    .readUE(\"VUI log2_max_mv_length_vertical\");\n            vuip.bitstreamRestriction.num_reorder_frames = reader\n                    .readUE(\"VUI num_reorder_frames\");\n            vuip.bitstreamRestriction.max_dec_frame_buffering = reader\n                    .readUE(\"VUI max_dec_frame_buffering\");\n        }\n\n        return vuip;\n    }\n\n    private static HRDParameters readHRDParameters(CAVLCReader reader)\n            throws IOException {\n        HRDParameters hrd = new HRDParameters();\n        hrd.cpb_cnt_minus1 = reader.readUE(\"SPS: cpb_cnt_minus1\");\n        hrd.bit_rate_scale = (int) reader.readNBit(4, \"HRD: bit_rate_scale\");\n        hrd.cpb_size_scale = (int) reader.readNBit(4, \"HRD: cpb_size_scale\");\n        hrd.bit_rate_value_minus1 = new int[hrd.cpb_cnt_minus1 + 1];\n        hrd.cpb_size_value_minus1 = new int[hrd.cpb_cnt_minus1 + 1];\n        hrd.cbr_flag = new boolean[hrd.cpb_cnt_minus1 + 1];\n\n        for (int SchedSelIdx = 0; SchedSelIdx <= hrd.cpb_cnt_minus1; SchedSelIdx++) {\n            hrd.bit_rate_value_minus1[SchedSelIdx] = reader\n                    .readUE(\"HRD: bit_rate_value_minus1\");\n            hrd.cpb_size_value_minus1[SchedSelIdx] = reader\n                    .readUE(\"HRD: cpb_size_value_minus1\");\n            hrd.cbr_flag[SchedSelIdx] = reader.readBool(\"HRD: cbr_flag\");\n        }\n        hrd.initial_cpb_removal_delay_length_minus1 = (int) reader.readNBit(5,\n                \"HRD: initial_cpb_removal_delay_length_minus1\");\n        hrd.cpb_removal_delay_length_minus1 = (int) reader.readNBit(5,\n                \"HRD: cpb_removal_delay_length_minus1\");\n        hrd.dpb_output_delay_length_minus1 = (int) reader.readNBit(5,\n                \"HRD: dpb_output_delay_length_minus1\");\n        hrd.time_offset_length = (int) reader.readNBit(5,\n                \"HRD: time_offset_length\");\n        return hrd;\n    }\n\n    public void write(OutputStream out) throws IOException {\n        CAVLCWriter writer = new CAVLCWriter(out);\n\n        writer.writeNBit(profile_idc, 8, \"SPS: profile_idc\");\n        writer.writeBool(constraint_set_0_flag, \"SPS: constraint_set_0_flag\");\n        writer.writeBool(constraint_set_1_flag, \"SPS: constraint_set_1_flag\");\n        writer.writeBool(constraint_set_2_flag, \"SPS: constraint_set_2_flag\");\n        writer.writeBool(constraint_set_3_flag, \"SPS: constraint_set_3_flag\");\n        writer.writeNBit(0, 4, \"SPS: reserved\");\n        writer.writeNBit(level_idc, 8, \"SPS: level_idc\");\n        writer.writeUE(seq_parameter_set_id, \"SPS: seq_parameter_set_id\");\n\n        if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122\n                || profile_idc == 144) {\n            writer.writeUE(chroma_format_idc.getId(), \"SPS: chroma_format_idc\");\n            if (chroma_format_idc == ChromaFormat.YUV_444) {\n                writer.writeBool(residual_color_transform_flag,\n                        \"SPS: residual_color_transform_flag\");\n            }\n            writer.writeUE(bit_depth_luma_minus8, \"SPS: \");\n            writer.writeUE(bit_depth_chroma_minus8, \"SPS: \");\n            writer.writeBool(qpprime_y_zero_transform_bypass_flag,\n                    \"SPS: qpprime_y_zero_transform_bypass_flag\");\n            writer.writeBool(scalingMatrix != null, \"SPS: \");\n            if (scalingMatrix != null) {\n                for (int i = 0; i < 8; i++) {\n                    if (i < 6) {\n                        writer.writeBool(\n                                scalingMatrix.ScalingList4x4[i] != null,\n                                \"SPS: \");\n                        if (scalingMatrix.ScalingList4x4[i] != null) {\n                            scalingMatrix.ScalingList4x4[i].write(writer);\n                        }\n                    } else {\n                        writer.writeBool(\n                                scalingMatrix.ScalingList8x8[i - 6] != null,\n                                \"SPS: \");\n                        if (scalingMatrix.ScalingList8x8[i - 6] != null) {\n                            scalingMatrix.ScalingList8x8[i - 6].write(writer);\n                        }\n                    }\n                }\n            }\n        }\n        writer.writeUE(log2_max_frame_num_minus4,\n                \"SPS: log2_max_frame_num_minus4\");\n        writer.writeUE(pic_order_cnt_type, \"SPS: pic_order_cnt_type\");\n        if (pic_order_cnt_type == 0) {\n            writer.writeUE(log2_max_pic_order_cnt_lsb_minus4,\n                    \"SPS: log2_max_pic_order_cnt_lsb_minus4\");\n        } else if (pic_order_cnt_type == 1) {\n            writer.writeBool(delta_pic_order_always_zero_flag,\n                    \"SPS: delta_pic_order_always_zero_flag\");\n            writer.writeSE(offset_for_non_ref_pic,\n                    \"SPS: offset_for_non_ref_pic\");\n            writer.writeSE(offset_for_top_to_bottom_field,\n                    \"SPS: offset_for_top_to_bottom_field\");\n            writer.writeUE(offsetForRefFrame.length, \"SPS: \");\n            for (int i = 0; i < offsetForRefFrame.length; i++)\n                writer.writeSE(offsetForRefFrame[i], \"SPS: \");\n        }\n        writer.writeUE(num_ref_frames, \"SPS: num_ref_frames\");\n        writer.writeBool(gaps_in_frame_num_value_allowed_flag,\n                \"SPS: gaps_in_frame_num_value_allowed_flag\");\n        writer.writeUE(pic_width_in_mbs_minus1, \"SPS: pic_width_in_mbs_minus1\");\n        writer.writeUE(pic_height_in_map_units_minus1,\n                \"SPS: pic_height_in_map_units_minus1\");\n        writer.writeBool(frame_mbs_only_flag, \"SPS: frame_mbs_only_flag\");\n        if (!frame_mbs_only_flag) {\n            writer.writeBool(mb_adaptive_frame_field_flag,\n                    \"SPS: mb_adaptive_frame_field_flag\");\n        }\n        writer.writeBool(direct_8x8_inference_flag,\n                \"SPS: direct_8x8_inference_flag\");\n        writer.writeBool(frame_cropping_flag, \"SPS: frame_cropping_flag\");\n        if (frame_cropping_flag) {\n            writer.writeUE(frame_crop_left_offset,\n                    \"SPS: frame_crop_left_offset\");\n            writer.writeUE(frame_crop_right_offset,\n                    \"SPS: frame_crop_right_offset\");\n            writer.writeUE(frame_crop_top_offset, \"SPS: frame_crop_top_offset\");\n            writer.writeUE(frame_crop_bottom_offset,\n                    \"SPS: frame_crop_bottom_offset\");\n        }\n        writer.writeBool(vuiParams != null, \"SPS: \");\n        if (vuiParams != null)\n            writeVUIParameters(vuiParams, writer);\n\n        writer.writeTrailingBits();\n    }\n\n    private void writeVUIParameters(VUIParameters vuip, CAVLCWriter writer)\n            throws IOException {\n        writer.writeBool(vuip.aspect_ratio_info_present_flag,\n                \"VUI: aspect_ratio_info_present_flag\");\n        if (vuip.aspect_ratio_info_present_flag) {\n            writer.writeNBit(vuip.aspect_ratio.getValue(), 8,\n                    \"VUI: aspect_ratio\");\n            if (vuip.aspect_ratio == AspectRatio.Extended_SAR) {\n                writer.writeNBit(vuip.sar_width, 16, \"VUI: sar_width\");\n                writer.writeNBit(vuip.sar_height, 16, \"VUI: sar_height\");\n            }\n        }\n        writer.writeBool(vuip.overscan_info_present_flag,\n                \"VUI: overscan_info_present_flag\");\n        if (vuip.overscan_info_present_flag) {\n            writer.writeBool(vuip.overscan_appropriate_flag,\n                    \"VUI: overscan_appropriate_flag\");\n        }\n        writer.writeBool(vuip.video_signal_type_present_flag,\n                \"VUI: video_signal_type_present_flag\");\n        if (vuip.video_signal_type_present_flag) {\n            writer.writeNBit(vuip.video_format, 3, \"VUI: video_format\");\n            writer.writeBool(vuip.video_full_range_flag,\n                    \"VUI: video_full_range_flag\");\n            writer.writeBool(vuip.colour_description_present_flag,\n                    \"VUI: colour_description_present_flag\");\n            if (vuip.colour_description_present_flag) {\n                writer.writeNBit(vuip.colour_primaries, 8,\n                        \"VUI: colour_primaries\");\n                writer.writeNBit(vuip.transfer_characteristics, 8,\n                        \"VUI: transfer_characteristics\");\n                writer.writeNBit(vuip.matrix_coefficients, 8,\n                        \"VUI: matrix_coefficients\");\n            }\n        }\n        writer.writeBool(vuip.chroma_loc_info_present_flag,\n                \"VUI: chroma_loc_info_present_flag\");\n        if (vuip.chroma_loc_info_present_flag) {\n            writer.writeUE(vuip.chroma_sample_loc_type_top_field,\n                    \"VUI: chroma_sample_loc_type_top_field\");\n            writer.writeUE(vuip.chroma_sample_loc_type_bottom_field,\n                    \"VUI: chroma_sample_loc_type_bottom_field\");\n        }\n        writer.writeBool(vuip.timing_info_present_flag,\n                \"VUI: timing_info_present_flag\");\n        if (vuip.timing_info_present_flag) {\n            writer.writeNBit(vuip.num_units_in_tick, 32,\n                    \"VUI: num_units_in_tick\");\n            writer.writeNBit(vuip.time_scale, 32, \"VUI: time_scale\");\n            writer.writeBool(vuip.fixed_frame_rate_flag,\n                    \"VUI: fixed_frame_rate_flag\");\n        }\n        writer.writeBool(vuip.nalHRDParams != null, \"VUI: \");\n        if (vuip.nalHRDParams != null) {\n            writeHRDParameters(vuip.nalHRDParams, writer);\n        }\n        writer.writeBool(vuip.vclHRDParams != null, \"VUI: \");\n        if (vuip.vclHRDParams != null) {\n            writeHRDParameters(vuip.vclHRDParams, writer);\n        }\n\n        if (vuip.nalHRDParams != null || vuip.vclHRDParams != null) {\n            writer\n                    .writeBool(vuip.low_delay_hrd_flag,\n                            \"VUI: low_delay_hrd_flag\");\n        }\n        writer.writeBool(vuip.pic_struct_present_flag,\n                \"VUI: pic_struct_present_flag\");\n        writer.writeBool(vuip.bitstreamRestriction != null, \"VUI: \");\n        if (vuip.bitstreamRestriction != null) {\n            writer\n                    .writeBool(\n                            vuip.bitstreamRestriction.motion_vectors_over_pic_boundaries_flag,\n                            \"VUI: motion_vectors_over_pic_boundaries_flag\");\n            writer.writeUE(vuip.bitstreamRestriction.max_bytes_per_pic_denom,\n                    \"VUI: max_bytes_per_pic_denom\");\n            writer.writeUE(vuip.bitstreamRestriction.max_bits_per_mb_denom,\n                    \"VUI: max_bits_per_mb_denom\");\n            writer.writeUE(\n                    vuip.bitstreamRestriction.log2_max_mv_length_horizontal,\n                    \"VUI: log2_max_mv_length_horizontal\");\n            writer.writeUE(\n                    vuip.bitstreamRestriction.log2_max_mv_length_vertical,\n                    \"VUI: log2_max_mv_length_vertical\");\n            writer.writeUE(vuip.bitstreamRestriction.num_reorder_frames,\n                    \"VUI: num_reorder_frames\");\n            writer.writeUE(vuip.bitstreamRestriction.max_dec_frame_buffering,\n                    \"VUI: max_dec_frame_buffering\");\n        }\n\n    }\n\n    private void writeHRDParameters(HRDParameters hrd, CAVLCWriter writer)\n            throws IOException {\n        writer.writeUE(hrd.cpb_cnt_minus1, \"HRD: cpb_cnt_minus1\");\n        writer.writeNBit(hrd.bit_rate_scale, 4, \"HRD: bit_rate_scale\");\n        writer.writeNBit(hrd.cpb_size_scale, 4, \"HRD: cpb_size_scale\");\n\n        for (int SchedSelIdx = 0; SchedSelIdx <= hrd.cpb_cnt_minus1; SchedSelIdx++) {\n            writer.writeUE(hrd.bit_rate_value_minus1[SchedSelIdx], \"HRD: \");\n            writer.writeUE(hrd.cpb_size_value_minus1[SchedSelIdx], \"HRD: \");\n            writer.writeBool(hrd.cbr_flag[SchedSelIdx], \"HRD: \");\n        }\n        writer.writeNBit(hrd.initial_cpb_removal_delay_length_minus1, 5,\n                \"HRD: initial_cpb_removal_delay_length_minus1\");\n        writer.writeNBit(hrd.cpb_removal_delay_length_minus1, 5,\n                \"HRD: cpb_removal_delay_length_minus1\");\n        writer.writeNBit(hrd.dpb_output_delay_length_minus1, 5,\n                \"HRD: dpb_output_delay_length_minus1\");\n        writer.writeNBit(hrd.time_offset_length, 5, \"HRD: time_offset_length\");\n    }\n\n    @Override\n    public String toString() {\n        return \"SeqParameterSet{ \" +\n                \"\\n        pic_order_cnt_type=\" + pic_order_cnt_type +\n                \", \\n        field_pic_flag=\" + field_pic_flag +\n                \", \\n        delta_pic_order_always_zero_flag=\" + delta_pic_order_always_zero_flag +\n                \", \\n        weighted_pred_flag=\" + weighted_pred_flag +\n                \", \\n        weighted_bipred_idc=\" + weighted_bipred_idc +\n                \", \\n        entropy_coding_mode_flag=\" + entropy_coding_mode_flag +\n                \", \\n        mb_adaptive_frame_field_flag=\" + mb_adaptive_frame_field_flag +\n                \", \\n        direct_8x8_inference_flag=\" + direct_8x8_inference_flag +\n                \", \\n        chroma_format_idc=\" + chroma_format_idc +\n                \", \\n        log2_max_frame_num_minus4=\" + log2_max_frame_num_minus4 +\n                \", \\n        log2_max_pic_order_cnt_lsb_minus4=\" + log2_max_pic_order_cnt_lsb_minus4 +\n                \", \\n        pic_height_in_map_units_minus1=\" + pic_height_in_map_units_minus1 +\n                \", \\n        pic_width_in_mbs_minus1=\" + pic_width_in_mbs_minus1 +\n                \", \\n        bit_depth_luma_minus8=\" + bit_depth_luma_minus8 +\n                \", \\n        bit_depth_chroma_minus8=\" + bit_depth_chroma_minus8 +\n                \", \\n        qpprime_y_zero_transform_bypass_flag=\" + qpprime_y_zero_transform_bypass_flag +\n                \", \\n        profile_idc=\" + profile_idc +\n                \", \\n        constraint_set_0_flag=\" + constraint_set_0_flag +\n                \", \\n        constraint_set_1_flag=\" + constraint_set_1_flag +\n                \", \\n        constraint_set_2_flag=\" + constraint_set_2_flag +\n                \", \\n        constraint_set_3_flag=\" + constraint_set_3_flag +\n                \", \\n        level_idc=\" + level_idc +\n                \", \\n        seq_parameter_set_id=\" + seq_parameter_set_id +\n                \", \\n        residual_color_transform_flag=\" + residual_color_transform_flag +\n                \", \\n        offset_for_non_ref_pic=\" + offset_for_non_ref_pic +\n                \", \\n        offset_for_top_to_bottom_field=\" + offset_for_top_to_bottom_field +\n                \", \\n        num_ref_frames=\" + num_ref_frames +\n                \", \\n        gaps_in_frame_num_value_allowed_flag=\" + gaps_in_frame_num_value_allowed_flag +\n                \", \\n        frame_mbs_only_flag=\" + frame_mbs_only_flag +\n                \", \\n        frame_cropping_flag=\" + frame_cropping_flag +\n                \", \\n        frame_crop_left_offset=\" + frame_crop_left_offset +\n                \", \\n        frame_crop_right_offset=\" + frame_crop_right_offset +\n                \", \\n        frame_crop_top_offset=\" + frame_crop_top_offset +\n                \", \\n        frame_crop_bottom_offset=\" + frame_crop_bottom_offset +\n                \", \\n        offsetForRefFrame=\" + offsetForRefFrame +\n                \", \\n        vuiParams=\" + vuiParams +\n                \", \\n        scalingMatrix=\" + scalingMatrix +\n                \", \\n        num_ref_frames_in_pic_order_cnt_cycle=\" + num_ref_frames_in_pic_order_cnt_cycle +\n                '}';\n    }\n}"
  },
  {
    "path": "src/com/googlecode/mp4parser/h264/model/VUIParameters.java",
    "content": "/*\nCopyright (c) 2011 Stanislav Vitvitskiy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this\nsoftware and associated documentation files (the \"Software\"), to deal in the Software\nwithout restriction, including without limitation the rights to use, copy, modify,\nmerge, publish, distribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or\nsubstantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\nPURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\nFOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE\nOR OTHER DEALINGS IN THE SOFTWARE.\n*/\npackage com.googlecode.mp4parser.h264.model;\n\npublic class VUIParameters {\n\n    public static class BitstreamRestriction {\n\n        public boolean motion_vectors_over_pic_boundaries_flag;\n        public int max_bytes_per_pic_denom;\n        public int max_bits_per_mb_denom;\n        public int log2_max_mv_length_horizontal;\n        public int log2_max_mv_length_vertical;\n        public int num_reorder_frames;\n        public int max_dec_frame_buffering;\n\n    }\n\n    public boolean aspect_ratio_info_present_flag;\n    public int sar_width;\n    public int sar_height;\n    public boolean overscan_info_present_flag;\n    public boolean overscan_appropriate_flag;\n    public boolean video_signal_type_present_flag;\n    public int video_format;\n    public boolean video_full_range_flag;\n    public boolean colour_description_present_flag;\n    public int colour_primaries;\n    public int transfer_characteristics;\n    public int matrix_coefficients;\n    public boolean chroma_loc_info_present_flag;\n    public int chroma_sample_loc_type_top_field;\n    public int chroma_sample_loc_type_bottom_field;\n    public boolean timing_info_present_flag;\n    public int num_units_in_tick;\n    public int time_scale;\n    public boolean fixed_frame_rate_flag;\n    public boolean low_delay_hrd_flag;\n    public boolean pic_struct_present_flag;\n    public HRDParameters nalHRDParams;\n    public HRDParameters vclHRDParams;\n\n    public BitstreamRestriction bitstreamRestriction;\n    public AspectRatio aspect_ratio;\n\n    @Override\n    public String toString() {\n        return \"VUIParameters{\" + \"\\n\" +\n                \"aspect_ratio_info_present_flag=\" + aspect_ratio_info_present_flag + \"\\n\" +\n                \", sar_width=\" + sar_width + \"\\n\" +\n                \", sar_height=\" + sar_height + \"\\n\" +\n                \", overscan_info_present_flag=\" + overscan_info_present_flag + \"\\n\" +\n                \", overscan_appropriate_flag=\" + overscan_appropriate_flag + \"\\n\" +\n                \", video_signal_type_present_flag=\" + video_signal_type_present_flag + \"\\n\" +\n                \", video_format=\" + video_format + \"\\n\" +\n                \", video_full_range_flag=\" + video_full_range_flag + \"\\n\" +\n                \", colour_description_present_flag=\" + colour_description_present_flag + \"\\n\" +\n                \", colour_primaries=\" + colour_primaries + \"\\n\" +\n                \", transfer_characteristics=\" + transfer_characteristics + \"\\n\" +\n                \", matrix_coefficients=\" + matrix_coefficients + \"\\n\" +\n                \", chroma_loc_info_present_flag=\" + chroma_loc_info_present_flag + \"\\n\" +\n                \", chroma_sample_loc_type_top_field=\" + chroma_sample_loc_type_top_field + \"\\n\" +\n                \", chroma_sample_loc_type_bottom_field=\" + chroma_sample_loc_type_bottom_field + \"\\n\" +\n                \", timing_info_present_flag=\" + timing_info_present_flag + \"\\n\" +\n                \", num_units_in_tick=\" + num_units_in_tick + \"\\n\" +\n                \", time_scale=\" + time_scale + \"\\n\" +\n                \", fixed_frame_rate_flag=\" + fixed_frame_rate_flag + \"\\n\" +\n                \", low_delay_hrd_flag=\" + low_delay_hrd_flag + \"\\n\" +\n                \", pic_struct_present_flag=\" + pic_struct_present_flag + \"\\n\" +\n                \", nalHRDParams=\" + nalHRDParams + \"\\n\" +\n                \", vclHRDParams=\" + vclHRDParams + \"\\n\" +\n                \", bitstreamRestriction=\" + bitstreamRestriction + \"\\n\" +\n                \", aspect_ratio=\" + aspect_ratio + \"\\n\" +\n                '}';\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/h264/read/BitstreamReader.java",
    "content": "/*\nCopyright (c) 2011 Stanislav Vitvitskiy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this\nsoftware and associated documentation files (the \"Software\"), to deal in the Software\nwithout restriction, including without limitation the rights to use, copy, modify,\nmerge, publish, distribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or\nsubstantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\nPURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\nFOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE\nOR OTHER DEALINGS IN THE SOFTWARE.\n*/\npackage com.googlecode.mp4parser.h264.read;\n\nimport com.googlecode.mp4parser.h264.CharCache;\n\nimport java.io.IOException;\nimport java.io.InputStream;\n\n/**\n * A dummy implementation of H264 RBSP reading\n *\n * @author Stanislav Vitvitskiy\n */\npublic class BitstreamReader {\n    private InputStream is;\n    private int curByte;\n    private int nextByte;\n    int nBit;\n    protected static int bitsRead;\n\n    protected CharCache debugBits = new CharCache(50);\n\n    public BitstreamReader(InputStream is) throws IOException {\n        this.is = is;\n        curByte = is.read();\n        nextByte = is.read();\n    }\n\n    /*\n      * (non-Javadoc)\n      *\n      * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#read1Bit()\n      */\n    public int read1Bit() throws IOException {\n        if (nBit == 8) {\n            advance();\n            if (curByte == -1) {\n                return -1;\n            }\n        }\n        int res = (curByte >> (7 - nBit)) & 1;\n        nBit++;\n\n        debugBits.append(res == 0 ? '0' : '1');\n        ++bitsRead;\n\n        return res;\n    }\n\n    /*\n      * (non-Javadoc)\n      *\n      * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#readNBit(int)\n      */\n    public long readNBit(int n) throws IOException {\n        if (n > 64)\n            throw new IllegalArgumentException(\"Can not readByte more then 64 bit\");\n\n        long val = 0;\n\n        for (int i = 0; i < n; i++) {\n            val <<= 1;\n            val |= read1Bit();\n        }\n\n        return val;\n    }\n\n    private void advance() throws IOException {\n        curByte = nextByte;\n        nextByte = is.read();\n        nBit = 0;\n    }\n\n    /*\n      * (non-Javadoc)\n      *\n      * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#readByte()\n      */\n    public int readByte() throws IOException {\n        if (nBit > 0) {\n            advance();\n        }\n\n        int res = curByte;\n\n        advance();\n\n        return res;\n    }\n\n    /*\n      * (non-Javadoc)\n      *\n      * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#moreRBSPData()\n      */\n    public boolean moreRBSPData() throws IOException {\n        if (nBit == 8) {\n            advance();\n        }\n        int tail = 1 << (8 - nBit - 1);\n        int mask = ((tail << 1) - 1);\n        boolean hasTail = (curByte & mask) == tail;\n\n        return !(curByte == -1 || (nextByte == -1 && hasTail));\n    }\n\n    public long getBitPosition() {\n        return (bitsRead * 8 + (nBit % 8));\n    }\n\n    /*\n      * (non-Javadoc)\n      *\n      * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#readRemainingByte()\n      */\n    public long readRemainingByte() throws IOException {\n        return readNBit(8 - nBit);\n    }\n\n    /*\n      * (non-Javadoc)\n      *\n      * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#next_bits(int)\n      */\n    public int peakNextBits(int n) throws IOException {\n        if (n > 8)\n            throw new IllegalArgumentException(\"N should be less then 8\");\n        if (nBit == 8) {\n            advance();\n            if (curByte == -1) {\n                return -1;\n            }\n        }\n        int[] bits = new int[16 - nBit];\n\n        int cnt = 0;\n        for (int i = nBit; i < 8; i++) {\n            bits[cnt++] = (curByte >> (7 - i)) & 0x1;\n        }\n\n        for (int i = 0; i < 8; i++) {\n            bits[cnt++] = (nextByte >> (7 - i)) & 0x1;\n        }\n\n        int result = 0;\n        for (int i = 0; i < n; i++) {\n            result <<= 1;\n            result |= bits[i];\n        }\n\n        return result;\n    }\n\n    /*\n      * (non-Javadoc)\n      *\n      * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#byte_aligned()\n      */\n    public boolean isByteAligned() {\n        return (nBit % 8) == 0;\n    }\n\n    /*\n      * (non-Javadoc)\n      *\n      * @see ua.org.jplayer.javcodec.h264.RBSPInputStream#close()\n      */\n    public void close() throws IOException {\n    }\n\n    public int getCurBit() {\n        return nBit;\n    }\n}"
  },
  {
    "path": "src/com/googlecode/mp4parser/h264/read/CAVLCReader.java",
    "content": "/*\nCopyright (c) 2011 Stanislav Vitvitskiy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this\nsoftware and associated documentation files (the \"Software\"), to deal in the Software\nwithout restriction, including without limitation the rights to use, copy, modify,\nmerge, publish, distribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or\nsubstantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\nPURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\nFOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE\nOR OTHER DEALINGS IN THE SOFTWARE.\n*/\npackage com.googlecode.mp4parser.h264.read;\n\n\nimport com.googlecode.mp4parser.h264.BTree;\n\nimport java.io.IOException;\nimport java.io.InputStream;\n\nimport static com.googlecode.mp4parser.h264.Debug.println;\n\n\npublic class CAVLCReader extends BitstreamReader {\n\n    public CAVLCReader(InputStream is) throws IOException {\n        super(is);\n    }\n\n    public long readNBit(int n, String message) throws IOException {\n        long val = readNBit(n);\n\n        trace(message, String.valueOf(val));\n\n        return val;\n    }\n\n    /**\n     * Read unsigned exp-golomb code\n     *\n     * @return\n     * @throws java.io.IOException\n     * @throws java.io.IOException\n     */\n    private int readUE() throws IOException {\n        int cnt = 0;\n        while (read1Bit() == 0)\n            cnt++;\n\n        int res = 0;\n        if (cnt > 0) {\n            long val = readNBit(cnt);\n\n            res = (int) ((1 << cnt) - 1 + val);\n        }\n\n        return res;\n    }\n\n    /*\n      * (non-Javadoc)\n      *\n      * @see\n      * ua.org.jplayer.javcodec.h264.H264BitInputStream#readUE(java.lang.String)\n      */\n    public int readUE(String message) throws IOException {\n        int res = readUE();\n\n        trace(message, String.valueOf(res));\n\n        return res;\n    }\n\n    public int readSE(String message) throws IOException {\n        int val = readUE();\n\n        int sign = ((val & 0x1) << 1) - 1;\n        val = ((val >> 1) + (val & 0x1)) * sign;\n\n        trace(message, String.valueOf(val));\n\n        return val;\n    }\n\n    public boolean readBool(String message) throws IOException {\n\n        boolean res = read1Bit() == 0 ? false : true;\n\n        trace(message, res ? \"1\" : \"0\");\n\n        return res;\n    }\n\n    public int readU(int i, String string) throws IOException {\n        return (int) readNBit(i, string);\n    }\n\n    public byte[] read(int payloadSize) throws IOException {\n        byte[] result = new byte[payloadSize];\n        for (int i = 0; i < payloadSize; i++) {\n            result[i] = (byte) readByte();\n        }\n        return result;\n    }\n\n    public boolean readAE() {\n        // TODO: do it!!\n        throw new UnsupportedOperationException(\"Stan\");\n    }\n\n    public int readTE(int max) throws IOException {\n        if (max > 1)\n            return readUE();\n        return ~read1Bit() & 0x1;\n    }\n\n    public int readAEI() {\n        // TODO: do it!!\n        throw new UnsupportedOperationException(\"Stan\");\n    }\n\n    public int readME(String string) throws IOException {\n        return readUE(string);\n    }\n\n    public Object readCE(BTree bt, String message) throws IOException {\n        while (true) {\n            int bit = read1Bit();\n            bt = bt.down(bit);\n            if (bt == null) {\n                throw new RuntimeException(\"Illegal code\");\n            }\n            Object i = bt.getValue();\n            if (i != null) {\n                trace(message, i.toString());\n                return i;\n            }\n        }\n    }\n\n    public int readZeroBitCount(String message) throws IOException {\n        int count = 0;\n        while (read1Bit() == 0)\n            count++;\n\n        trace(message, String.valueOf(count));\n\n        return count;\n    }\n\n    public void readTrailingBits() throws IOException {\n        read1Bit();\n        readRemainingByte();\n    }\n\n    private void trace(String message, String val) {\n        StringBuilder traceBuilder = new StringBuilder();\n        int spaces;\n        String pos = String.valueOf(bitsRead - debugBits.length());\n        spaces = 8 - pos.length();\n\n        traceBuilder.append(\"@\" + pos);\n\n        for (int i = 0; i < spaces; i++)\n            traceBuilder.append(' ');\n\n        traceBuilder.append(message);\n        spaces = 100 - traceBuilder.length() - debugBits.length();\n        for (int i = 0; i < spaces; i++)\n            traceBuilder.append(' ');\n        traceBuilder.append(debugBits);\n        traceBuilder.append(\" (\" + val + \")\");\n        debugBits.clear();\n\n        println(traceBuilder.toString());\n    }\n}"
  },
  {
    "path": "src/com/googlecode/mp4parser/h264/write/BitstreamWriter.java",
    "content": "/*\nCopyright (c) 2011 Stanislav Vitvitskiy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this\nsoftware and associated documentation files (the \"Software\"), to deal in the Software\nwithout restriction, including without limitation the rights to use, copy, modify,\nmerge, publish, distribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or\nsubstantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\nPURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\nFOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE\nOR OTHER DEALINGS IN THE SOFTWARE.\n*/\npackage com.googlecode.mp4parser.h264.write;\n\nimport com.googlecode.mp4parser.h264.Debug;\n\nimport java.io.IOException;\nimport java.io.OutputStream;\n\n/**\n * A dummy implementation of H264 RBSP output stream\n *\n * @author Stanislav Vitvitskiy\n */\npublic class BitstreamWriter {\n\n    private final OutputStream os;\n    private int[] curByte = new int[8];\n    private int curBit;\n\n    public BitstreamWriter(OutputStream out) {\n        this.os = out;\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see ua.org.jplayer.javcodec.h264.H264BitOutputStream#flush()\n     */\n    public void flush() throws IOException {\n        for (int i = curBit; i < 8; i++) {\n            curByte[i] = 0;\n        }\n        curBit = 0;\n        writeCurByte();\n    }\n\n    private void writeCurByte() throws IOException {\n        int toWrite = (curByte[0] << 7) | (curByte[1] << 6) | (curByte[2] << 5)\n                | (curByte[3] << 4) | (curByte[4] << 3) | (curByte[5] << 2)\n                | (curByte[6] << 1) | curByte[7];\n        os.write(toWrite);\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see ua.org.jplayer.javcodec.h264.H264BitOutputStream#write1Bit(int)\n     */\n    public void write1Bit(int value) throws IOException {\n        Debug.print(value);\n        if (curBit == 8) {\n            curBit = 0;\n            writeCurByte();\n        }\n        curByte[curBit++] = value;\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see ua.org.jplayer.javcodec.h264.H264BitOutputStream#writeNBit(long,\n     * int)\n     */\n    public void writeNBit(long value, int n) throws IOException {\n        for (int i = 0; i < n; i++) {\n            write1Bit((int) (value >> (n - i - 1)) & 0x1);\n        }\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see\n     * ua.org.jplayer.javcodec.h264.H264BitOutputStream#writeRemainingZero()\n     */\n    public void writeRemainingZero() throws IOException {\n        writeNBit(0, 8 - curBit);\n    }\n\n    /*\n     * (non-Javadoc)\n     * \n     * @see ua.org.jplayer.javcodec.h264.H264BitOutputStream#writeByte(int)\n     */\n    public void writeByte(int b) throws IOException {\n        os.write(b);\n\n    }\n}"
  },
  {
    "path": "src/com/googlecode/mp4parser/h264/write/CAVLCWriter.java",
    "content": "/*\nCopyright (c) 2011 Stanislav Vitvitskiy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this\nsoftware and associated documentation files (the \"Software\"), to deal in the Software\nwithout restriction, including without limitation the rights to use, copy, modify,\nmerge, publish, distribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or\nsubstantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\nPURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\nFOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE\nOR OTHER DEALINGS IN THE SOFTWARE.\n*/\npackage com.googlecode.mp4parser.h264.write;\n\nimport com.googlecode.mp4parser.h264.Debug;\n\nimport java.io.IOException;\nimport java.io.OutputStream;\n\n\n/**\n * A class responsible for outputting exp-Golumb values into binary stream\n *\n * @author Stanislav Vitvitskiy\n */\npublic class CAVLCWriter extends BitstreamWriter {\n\n    public CAVLCWriter(OutputStream out) {\n        super(out);\n    }\n\n    public void writeU(int value, int n, String string) throws IOException {\n        Debug.print(string + \"\\t\");\n        writeNBit(value, n);\n        Debug.println(\"\\t\" + value);\n    }\n\n    public void writeUE(int value) throws IOException {\n        int bits = 0;\n        int cumul = 0;\n        for (int i = 0; i < 15; i++) {\n            if (value < cumul + (1 << i)) {\n                bits = i;\n                break;\n            }\n            cumul += (1 << i);\n        }\n        writeNBit(0, bits);\n        write1Bit(1);\n        writeNBit(value - cumul, bits);\n    }\n\n    public void writeUE(int value, String string) throws IOException {\n        Debug.print(string + \"\\t\");\n        writeUE(value);\n        Debug.println(\"\\t\" + value);\n    }\n\n    public void writeSE(int value, String string) throws IOException {\n        Debug.print(string + \"\\t\");\n        writeUE((value << 1) * (value < 0 ? -1 : 1) + (value > 0 ? 1 : 0));\n        Debug.println(\"\\t\" + value);\n    }\n\n    public void writeBool(boolean value, String string) throws IOException {\n        Debug.print(string + \"\\t\");\n        write1Bit(value ? 1 : 0);\n        Debug.println(\"\\t\" + value);\n    }\n\n    public void writeU(int i, int n) throws IOException {\n        writeNBit(i, n);\n    }\n\n    public void writeNBit(long value, int n, String string) throws IOException {\n        Debug.print(string + \"\\t\");\n        for (int i = 0; i < n; i++) {\n            write1Bit((int) (value >> (n - i - 1)) & 0x1);\n        }\n        Debug.println(\"\\t\" + value);\n    }\n\n    public void writeTrailingBits() throws IOException {\n        write1Bit(1);\n        writeRemainingZero();\n        flush();\n    }\n\n    public void writeSliceTrailingBits() {\n        throw new IllegalStateException(\"todo\");\n    }\n}"
  },
  {
    "path": "src/com/googlecode/mp4parser/srt/SrtParser.java",
    "content": "/*\n * Copyright 2011 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.srt;\n\nimport com.googlecode.mp4parser.authoring.tracks.TextTrackImpl;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.io.LineNumberReader;\n\n/**\n * Parses a .srt file and creates a Track for it.\n */\npublic class SrtParser {\n    public static TextTrackImpl parse(InputStream is) throws IOException {\n        LineNumberReader r = new LineNumberReader(new InputStreamReader(is, \"UTF-8\"));\n        TextTrackImpl track = new TextTrackImpl();\n        String numberString;\n        while ((numberString = r.readLine()) != null) {\n            String timeString = r.readLine();\n            String lineString = \"\";\n            String s;\n            while (!((s = r.readLine()) == null || s.trim().equals(\"\"))) {\n                lineString += s + \"\\n\";\n            }\n\n            long startTime = parse(timeString.split(\"-->\")[0]);\n            long endTime = parse(timeString.split(\"-->\")[1]);\n\n            track.getSubs().add(new TextTrackImpl.Line(startTime, endTime, lineString));\n\n        }\n        return track;\n    }\n\n    private static long parse(String in) {\n        long hours = Long.parseLong(in.split(\":\")[0].trim());\n        long minutes = Long.parseLong(in.split(\":\")[1].trim());\n        long seconds = Long.parseLong(in.split(\":\")[2].split(\",\")[0].trim());\n        long millies = Long.parseLong(in.split(\":\")[2].split(\",\")[1].trim());\n\n        return hours * 60 * 60 * 1000 + minutes * 60 * 1000 + seconds * 1000 + millies;\n\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/util/ByteBufferByteChannel.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.util;\n\nimport java.io.EOFException;\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.channels.ByteChannel;\n\n/**\n * Creates a <code>ReadableByteChannel</code> that is backed by a <code>ByteBuffer</code>.\n */\npublic class ByteBufferByteChannel implements ByteChannel {\n    ByteBuffer byteBuffer;\n\n    public ByteBufferByteChannel(ByteBuffer byteBuffer) {\n        this.byteBuffer = byteBuffer;\n    }\n\n    public int read(ByteBuffer dst) throws IOException {\n        byte[] b = dst.array();\n        int r = dst.remaining();\n        if (byteBuffer.remaining() >= r) {\n            byteBuffer.get(b, dst.position(), r);\n            return r;\n        } else {\n            throw new EOFException(\"Reading beyond end of stream\");\n        }\n    }\n\n    public boolean isOpen() {\n        return true;\n    }\n\n    public void close() throws IOException {\n    }\n\n    public int write(ByteBuffer src) throws IOException {\n        int r = src.remaining();\n        byteBuffer.put(src);\n        return r;\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/util/CastUtils.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.util;\n\n\npublic class CastUtils {\n    /**\n     * Casts a long to an int. In many cases I use a long for a UInt32 but this cannot be used to allocate\n     * ByteBuffers or arrays since they restricted to <code>Integer.MAX_VALUE</code> this cast-method will throw\n     * a RuntimeException if the cast would cause a loss of information.\n     *\n     * @param l the long value\n     * @return the long value as int\n     */\n    public static int l2i(long l) {\n        if (l > Integer.MAX_VALUE || l < Integer.MIN_VALUE) {\n            throw new RuntimeException(\"A cast to int has gone wrong. Please contact the mp4parser discussion group (\" + l + \")\");\n        }\n        return (int) l;\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/util/Math.java",
    "content": "package com.googlecode.mp4parser.util;\n\npublic class Math {\n    public static long gcd(long a, long b) {\n        while (b > 0) {\n            long temp = b;\n            b = a % b; // % is remainder\n            a = temp;\n        }\n        return a;\n    }\n\n    public static int gcd(int a, int b) {\n        while (b > 0) {\n            int temp = b;\n            b = a % b; // % is remainder\n            a = temp;\n        }\n        return a;\n    }\n\n    public static long lcm(long a, long b) {\n        return a * (b / gcd(a, b));\n    }\n\n    public static int lcm(int a, int b) {\n        return a * (b / gcd(a, b));\n    }\n\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/util/Path.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.util;\n\n\nimport java.util.Collections;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport com.coremedia.iso.IsoFile;\nimport com.coremedia.iso.boxes.Box;\nimport com.coremedia.iso.boxes.ContainerBox;\n\npublic class Path {\n\n    IsoFile isoFile;\n\n    public Path(IsoFile isoFile) {\n        this.isoFile = isoFile;\n    }\n\n    private static Pattern component = Pattern.compile(\"(....)(\\\\[(.*)\\\\])?\");\n\n    public String createPath(Box box) {\n        return createPath(box, \"\");\n    }\n\n    private String createPath(Box box, String path) {\n        if (box instanceof IsoFile) {\n            assert box == isoFile;\n            return path;\n        } else {\n            List<?> boxesOfBoxType = box.getParent().getBoxes(box.getClass());\n            int index = boxesOfBoxType.indexOf(box);\n            path = String.format(\"/%s[%d]\", box.getType(), index) + path;\n\n            return createPath(box.getParent(), path);\n        }\n    }\n\n    public Box getPath(String path) {\n        List<Box> all = getPath(isoFile, path);\n        return all.isEmpty() ?null:all.get(0);\n    }\n\n    public List<Box> getPaths(String path) {\n        return getPath(isoFile, path);\n    }\n\n    public boolean isContained(Box box, String path) {\n        return getPath(isoFile, path).contains(box);\n    }\n\n    private List<Box> getPath(Box box, String path) {\n        if (path.startsWith(\"/\")) {\n            path = path.substring(1);\n        }\n        if (path.length() == 0) {\n            return Collections.singletonList(box);\n        } else {\n            String later;\n            String now;\n            if (path.contains(\"/\")) {\n                later = path.substring(path.indexOf('/'));\n                now = path.substring(0, path.indexOf('/'));\n            } else {\n                now = path;\n                later = \"\";\n            }\n\n            Matcher m = component.matcher(now);\n            if (m.matches()) {\n                String type = m.group(1);\n                int index = -1;\n                if (m.group(2) != null) {\n                    // we have a specific index\n                    String indexString = m.group(3);\n                    index = Integer.parseInt(indexString);\n                }\n                List<Box> children = new LinkedList<Box>();\n                int currentIndex = 0;\n                for (Box box1 : ((ContainerBox) box).getBoxes()) {\n                    if (box1.getType().equals(type)) {\n                        if (index == -1 || index == currentIndex) {\n                            children.addAll(getPath(box1, later));\n                        }\n                        currentIndex++;\n                    }\n                }\n                return children;\n\n            } else {\n                throw new RuntimeException(\"invalid path.\");\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "src/com/googlecode/mp4parser/util/UUIDConverter.java",
    "content": "/*\n * Copyright 2012 Sebastian Annies, Hamburg\n *\n * Licensed under the Apache License, Version 2.0 (the License);\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an AS IS BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.googlecode.mp4parser.util;\n\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\nimport java.util.UUID;\n\n/**\n * UUID from/to byte array.\n */\npublic class UUIDConverter {\n    public static byte[] convert(UUID uuid) {\n\n        long msb = uuid.getMostSignificantBits();\n        long lsb = uuid.getLeastSignificantBits();\n        byte[] buffer = new byte[16];\n\n        for (int i = 0; i < 8; i++) {\n            buffer[i] = (byte) (msb >>> 8 * (7 - i));\n        }\n        for (int i = 8; i < 16; i++) {\n            buffer[i] = (byte) (lsb >>> 8 * (7 - i));\n        }\n\n        return buffer;\n\n    }\n\n    public static UUID convert(byte[] uuidBytes) {\n        ByteBuffer b = ByteBuffer.wrap(uuidBytes);\n        b.order(ByteOrder.BIG_ENDIAN);\n        return new UUID(b.getLong(), b.getLong());\n    }\n}\n"
  },
  {
    "path": "src/com/todoroo/aacenc/AACEncoder.java",
    "content": "package com.todoroo.aacenc;\n\npublic class AACEncoder {\n\n    /**\n     * Native JNI - initialize AAC encoder\n     *\n     */\n    public native void init(int bitrate, int channels,\n            int sampleRate, int bitsPerSample, String outputFile);\n\n    /**\n     * Native JNI - encode one or more frames\n     *\n     */\n    public native void encode(byte[] inputArray);\n\n    /**\n     * Native JNI - uninitialize AAC encoder and flush file\n     *\n     */\n    public native void uninit();\n\n    static {\n        System.loadLibrary(\"aac-encoder\");\n    }\n\n}\n"
  },
  {
    "path": "src/com/todoroo/aacenc/AACToM4A.java",
    "content": "package com.todoroo.aacenc;\n\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.PushbackInputStream;\n\nimport android.content.Context;\n\nimport com.coremedia.iso.IsoFile;\nimport com.googlecode.mp4parser.authoring.Movie;\nimport com.googlecode.mp4parser.authoring.Track;\nimport com.googlecode.mp4parser.authoring.builder.DefaultMp4Builder;\nimport com.googlecode.mp4parser.authoring.tracks.AACTrackImpl;\n\npublic class AACToM4A {\n\n    private static Context context;\n\n    public static Context getContext() {\n        return context;\n    }\n\n    public void convert(Context context, String infile, String outfile) throws IOException {\n        AACToM4A.context = context;\n\n        InputStream input = new FileInputStream(infile);\n\n        PushbackInputStream pbi = new PushbackInputStream(input, 100);\n\n        System.err.println(\"well you got \" + input.available());\n        Movie movie = new Movie();\n\n        Track audioTrack = new AACTrackImpl(pbi);\n        movie.addTrack(audioTrack);\n\n        IsoFile out = new DefaultMp4Builder().build(movie);\n        FileOutputStream output = new FileOutputStream(outfile);\n        out.getBox(output.getChannel());\n        output.close();\n    }\n\n}\n"
  },
  {
    "path": "src/com/todoroo/aacenc/ContextManager.java",
    "content": "/**\n * See the file \"LICENSE\" for the full license governing this code.\n */\npackage com.todoroo.aacenc;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android.content.res.Resources;\n\n/**\n * Singleton class to manage current application context\n * b\n * @author Tim Su <tim@todoroo.com>\n *\n */\npublic final class ContextManager {\n\n    /**\n     * Global application context\n     */\n    private static Context context = null;\n\n    /**\n     * Sets the global context\n     *\n     * @param context\n     */\n    public static void setContext(Context context) {\n        if(context == null || context.getApplicationContext() == null)\n            return;\n        if(ContextManager.context != null && !(context instanceof Activity))\n            return;\n        ContextManager.context = context;\n    }\n\n    /**\n     * Gets the global context\n     */\n    public static Context getContext() {\n        return context;\n    }\n\n    /**\n     * Convenience method to read a string from the resources\n     *\n     * @param resId resource\n     * @param parameters % arguments\n     * @return resource string\n     */\n    public static String getString(int resId, Object... formatArgs) {\n        return context.getString(resId, formatArgs);\n    }\n\n    /**\n     * Convenience method to read resources\n     *\n     * @return resources object\n     */\n    public static Resources getResources() {\n        return context.getResources();\n    }\n\n}\n"
  },
  {
    "path": "src/com/todoroo/aacenc/Main.java",
    "content": "package com.todoroo.aacenc;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\n\nimport android.app.Activity;\nimport android.app.ProgressDialog;\nimport android.content.DialogInterface;\nimport android.content.DialogInterface.OnCancelListener;\nimport android.content.Intent;\nimport android.media.MediaPlayer;\nimport android.os.Bundle;\nimport android.speech.RecognitionListener;\nimport android.speech.RecognizerIntent;\nimport android.speech.SpeechRecognizer;\nimport android.util.Log;\nimport android.view.View;\nimport android.view.View.OnClickListener;\nimport android.widget.TextView;\nimport android.widget.Toast;\n\npublic class Main extends Activity implements RecognitionListener {\n\n    private String AAC_FILE;\n    private String M4A_FILE = \"/sdcard/audio.m4a\";\n\n    /** Called when the activity is first created. */\n    @Override\n    public void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.main);\n\n        File dir = getFilesDir();\n        AAC_FILE = dir.toString() + \"/audio.aac\";\n\n\n        findViewById(R.id.write).setOnClickListener(new OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                write();\n            }\n        });\n\n        findViewById(R.id.play).setOnClickListener(new OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                play();\n            }\n        });\n\n        sr = SpeechRecognizer.createSpeechRecognizer(this);\n    }\n\n    private void play() {\n        MediaPlayer mediaPlayer = new MediaPlayer();\n\n        try {\n            mediaPlayer.setDataSource(M4A_FILE);\n            mediaPlayer.prepare();\n            mediaPlayer.start();\n        } catch (IllegalArgumentException e) {\n            throw new RuntimeException(e);\n        } catch (IllegalStateException e) {\n            throw new RuntimeException(e);\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n\n        Toast.makeText(Main.this, \"Playing Audio\", Toast.LENGTH_LONG).show();\n    }\n\n    private AACEncoder encoder = new AACEncoder();\n    private long speechStarted = 0;\n    private SpeechRecognizer sr;\n    private ProgressDialog pd;\n\n    private void write() {\n        sr.setRecognitionListener(this);\n\n        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);\n        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,\n                RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);\n        intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, \"com.domain.app\");\n\n        speechStarted = 0;\n        baos.reset();\n\n        pd = new ProgressDialog(this);\n        pd.setMessage(\"Speak now...\");\n        pd.setIndeterminate(true);\n        pd.setCancelable(true);\n        pd.setOnCancelListener(new OnCancelListener() {\n            @Override\n            public void onCancel(DialogInterface dialog) {\n                sr.cancel();\n                onEndOfSpeech();\n            }\n        });\n\n        pd.show();\n        sr.startListening(intent);\n\n        speechStarted = System.currentTimeMillis();\n    }\n\n    @Override\n    public void onBeginningOfSpeech() {\n        System.err.println(\"beginning\");\n\n    }\n\n    ByteArrayOutputStream baos = new ByteArrayOutputStream();\n\n    @Override\n    public void onBufferReceived(byte[] buffer) {\n        if(speechStarted > 0) {\n            try {\n                baos.write(buffer);\n            } catch (IOException e) {\n                //\n            }\n        }\n    }\n\n    @Override\n    protected void onStop() {\n        super.onStop();\n        sr.destroy();\n    }\n\n    @Override\n    public void onEndOfSpeech() {\n        pd.dismiss();\n\n        if(speechStarted == 0)\n            return;\n\n        long delta = System.currentTimeMillis() - speechStarted;\n\n        int sampleRate = (int) (baos.size() * 1000 / delta);\n        sampleRate = 8000; // THIS IS A MAGIC NUMBER@?!!?!?!\n        // can i has calculate?\n\n        System.err.println(\"computed sample rate: \" + sampleRate);\n\n        encoder.init(64000, 1, sampleRate, 16, AAC_FILE);\n\n        encoder.encode(baos.toByteArray());\n\n        System.err.println(\"end\");\n\n        encoder.uninit();\n\n        try {\n            new AACToM4A().convert(this, AAC_FILE, M4A_FILE);\n\n            Toast.makeText(Main.this, \"File Saved!\", Toast.LENGTH_LONG).show();\n        } catch (IOException e) {\n            Toast.makeText(Main.this, \"Error :(\", Toast.LENGTH_LONG).show();\n            Log.e(\"ERROR\", \"error converting\", e);\n        }\n    }\n\n    @Override\n    public void onError(int error) {\n        Log.w(\"Speech Error\", \"Error code: \" + error);\n    }\n\n    @Override\n    public void onEvent(int arg0, Bundle arg1) {\n        //\n    }\n\n    @Override\n    public void onPartialResults(Bundle partialResults) {\n        onResults(partialResults);\n    }\n\n    @Override\n    public void onReadyForSpeech(Bundle arg0) {\n    }\n\n    @Override\n    public void onResults(Bundle results) {\n        ArrayList<String> strings = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);\n        ((TextView)findViewById(R.id.text)).setText(\n                strings.size() == 0 ? \"\" : strings.get(0));\n    }\n\n    @Override\n    public void onRmsChanged(float arg0) {\n    }\n}"
  }
]