/** * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include "../includes/memutils.h" #include "vpx/vp8cx.h" #include "vpx/vpx_codec.h" #include "vpx/vpx_encoder.h" #define ENCODE_WIDTH 11 #define ENCODE_HEIGHT 10000 #define LIBNAME "/system/apex/com.android.media.swcodec/lib64/libvpx.so" #define LIBNAME_APEX "/apex/com.android.media.swcodec/lib64/libvpx.so" char enable_selective_overload = ENABLE_NONE; int main() { enable_selective_overload = ENABLE_ALL; void *libHandle = dlopen(LIBNAME, RTLD_NOW | RTLD_LOCAL); if (!libHandle) { libHandle = dlopen(LIBNAME_APEX, RTLD_NOW | RTLD_LOCAL); if (!libHandle) { return EXIT_FAILURE; } } vpx_codec_err_t codec_return = VPX_CODEC_OK; vpx_codec_enc_cfg_t mCodecConfiguration; vpx_image_t raw_frame; uint32_t framerate = (30 << 16); vpx_codec_iface_t *(*func_ptr1)() = (vpx_codec_iface_t * (*)()) dlsym(libHandle, "vpx_codec_vp8_cx"); if (!func_ptr1) { dlclose(libHandle); return EXIT_FAILURE; } vpx_codec_iface_t *mCodecInterface = (*func_ptr1)(); if (!mCodecInterface) { dlclose(libHandle); return EXIT_FAILURE; } vpx_codec_err_t (*func_ptr2)(vpx_codec_iface_t *, vpx_codec_enc_cfg_t *, unsigned int) = (vpx_codec_err_t(*)(vpx_codec_iface_t *, vpx_codec_enc_cfg_t *, unsigned int))dlsym( libHandle, "vpx_codec_enc_config_default"); if (!func_ptr2) { dlclose(libHandle); return EXIT_FAILURE; } codec_return = (*func_ptr2)(mCodecInterface, &mCodecConfiguration, 0); mCodecConfiguration.g_w = ENCODE_WIDTH; mCodecConfiguration.g_h = ENCODE_HEIGHT; vpx_codec_ctx_t mCodecContext; vpx_codec_err_t (*func_ptr3)(vpx_codec_ctx_t *, vpx_codec_iface_t *, vpx_codec_enc_cfg_t *, vpx_codec_flags_t, int) = (vpx_codec_err_t(*)(vpx_codec_ctx_t *, vpx_codec_iface_t *, vpx_codec_enc_cfg_t *, vpx_codec_flags_t, int))dlsym(libHandle, "vpx_codec_enc_init_ver"); if (!func_ptr3) { dlclose(libHandle); return EXIT_FAILURE; } codec_return = (*func_ptr3)(&mCodecContext, mCodecInterface, &mCodecConfiguration, 0, VPX_ENCODER_ABI_VERSION); if (codec_return != VPX_CODEC_OK) { return EXIT_FAILURE; } unsigned char *source = (unsigned char *)memalign(16, (ENCODE_WIDTH * ENCODE_HEIGHT * 3 / 2)); if (!source) { return EXIT_FAILURE; } memset(source, 0, (ENCODE_WIDTH * ENCODE_HEIGHT * 3 / 2)); vpx_image_t (*func_ptr4)(vpx_image_t *, vpx_img_fmt_t, unsigned int, unsigned int, unsigned int, unsigned char *) = (vpx_image(*)(vpx_image *, vpx_img_fmt, unsigned int, unsigned int, unsigned int, unsigned char *))dlsym(libHandle, "vpx_img_wrap"); if (!func_ptr4) { dlclose(libHandle); free(source); return EXIT_FAILURE; } (*func_ptr4)(&raw_frame, VPX_IMG_FMT_I420, ENCODE_WIDTH, ENCODE_HEIGHT, 1, source); vpx_codec_err_t (*func_ptr5)(vpx_codec_ctx_t *, const vpx_image_t *, vpx_codec_pts_t, unsigned long, vpx_enc_frame_flags_t, unsigned long) = (vpx_codec_err_t(*)(vpx_codec_ctx *, const vpx_image *, long, unsigned long, long, unsigned long))dlsym(libHandle, "vpx_codec_encode"); if (!func_ptr5) { dlclose(libHandle); free(source); return EXIT_FAILURE; } codec_return = (*func_ptr5)(&mCodecContext, &raw_frame, framerate, (uint32_t)(((uint64_t)1000000 << 16) / framerate), 0, VPX_DL_REALTIME); if (codec_return != VPX_CODEC_OK) { free(source); return EXIT_FAILURE; } vpx_codec_err_t (*func_ptr6)(vpx_codec_ctx_t *) = (vpx_codec_err_t(*)(vpx_codec_ctx *))dlsym(libHandle, "vpx_codec_destroy"); if (!func_ptr6) { dlclose(libHandle); free(source); return EXIT_FAILURE; } (*func_ptr6)(&mCodecContext); enable_selective_overload = ENABLE_NONE; dlclose(libHandle); free(source); return EXIT_SUCCESS; }