SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------*/

void omx_video::init_vendor_extensions(VendorExtensionStore &store) {

    //TODO: add extensions based on Codec, m_platform and/or other capability queries

    ADD_EXTENSION("qti-ext-enc-preprocess-rotate", OMX_IndexConfigCommonRotate, OMX_DirOutput)
    ADD_PARAM_END("angle", OMX_AndroidVendorValueInt32)

    ADD_EXTENSION("qti-ext-enc-avc-intra-period", OMX_IndexConfigVideoAVCIntraPeriod, OMX_DirOutput)
    ADD_PARAM    ("n-pframes",    OMX_AndroidVendorValueInt32)
    ADD_PARAM_END("n-idr-period", OMX_AndroidVendorValueInt32)

    ADD_EXTENSION("qti-ext-enc-error-correction", OMX_IndexParamVideoErrorCorrection, OMX_DirOutput)
    ADD_PARAM_END("resync-marker-spacing-bits", OMX_AndroidVendorValueInt32)

    ADD_EXTENSION("qti-ext-enc-custom-profile-level", OMX_IndexParamVideoProfileLevelCurrent, OMX_DirOutput)
    ADD_PARAM    ("profile", OMX_AndroidVendorValueInt32)
    ADD_PARAM_END("level",   OMX_AndroidVendorValueInt32)

    ADD_EXTENSION("qti-ext-enc-timestamp-source-avtimer", OMX_QTIIndexParamEnableAVTimerTimestamps, OMX_DirInput)
    ADD_PARAM_END("enable", OMX_AndroidVendorValueInt32)
}

OMX_ERRORTYPE omx_video::get_vendor_extension_config(
                OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext) {
int main(int argc, char *argv[]) {
	const char *filename = getFilename(argv[0]);

	std::string target, compilerCommand;
	splitCompilerName(filename, &target, &compilerCommand);

	std::string compilerBaseDir = getBaseDir(compilerCommand);
	if (compilerBaseDir.size() && compilerBaseDir[compilerBaseDir.size() - 1] != '/') {
		compilerBaseDir += '/';
	}
	compilerCommand = compilerBaseDir + "bin/" + compilerCommand;

	// Determine SDK and deployment settings.
	const char *sdkPath   = getenvd("IOS_SDK", IOS_SDK_DEFAULT);
	const char *iOSMinVer = getenvd("IPHONEOS_DEPLOYMENT_TARGET", IOS_MIN_VER_DEFAULT);
	unsetenv("IPHONEOS_DEPLOYMENT_TARGET");

	std::string iOSMinVerParam = "-miphoneos-version-min=";
	iOSMinVerParam += iOSMinVer;

	// Set default archtitecture based on minimum iOS version.
	int major = -1, minor = -1;
	if (sscanf(iOSMinVer, "%d.%d", &major, &minor) != 2) {
		abort();
	}

	// armv6 devices only support up to iOS 4.2.1. If we deploy for such an
	// old version, we default that architecture.
	const char *arch;
	if (major <= 4) {
		arch = "armv6";
	} else {
		arch = "armv7";
	}

	// Make sure all program binaries created are automatically signed.
	std::string codesign = target + "-codesign_allocate";
	setenv("CODESIGN_ALLOCATE", codesign.c_str(), 1);
	setenv("IOS_FAKE_CODE_SIGN", "1", 1);

	// Setup environment for proper execution.
	std::string newLdLibraryPath = compilerBaseDir;
	newLdLibraryPath += "lib";

	char *ldLibraryPath = getenv(LIBRARY_PATH);
	if (ldLibraryPath && *ldLibraryPath) {
		newLdLibraryPath += ':';
		newLdLibraryPath += ldLibraryPath;
	}
	setenv(LIBRARY_PATH, newLdLibraryPath.c_str(), 1);

	// Setup command line arguments for compiler.
	char **params = (char **)malloc(sizeof(char *) * (argc + 9));

	bool hasArch = false;
	bool hasIPhoneOSVersionMin = false;
	for (int i = 1; i < argc; ++i) {
		if (hasPrefix(argv[i], "-arch")) {
			hasArch = true;
			break;
		} else if (hasPrefix(argv[i], "-miphoneos-version-min")) {
			hasIPhoneOSVersionMin = true;
			break;
		}
	}

	int param = 0;
#define ADD_PARAM(x) params[param++] = strdup((x))
	ADD_PARAM(compilerCommand.c_str());
	ADD_PARAM("-target");
	ADD_PARAM(target.c_str());

	if (!hasArch) {
		ADD_PARAM("-arch");
		ADD_PARAM(arch);
	}

	ADD_PARAM("-isysroot");
	ADD_PARAM(sdkPath);

	if (!hasIPhoneOSVersionMin) {
		ADD_PARAM(iOSMinVerParam.c_str());
	}

	ADD_PARAM("-mlinker-version=" LINKER_VERSION);
#undef ADD_PARAM

	for (int i = 1; i < argc; ++i) {
		params[param++] = argv[i];
	}

	params[param] = 0;

	execvp(compilerCommand.c_str(), params);

	abort();
}