| /** |
| * 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 <dlfcn.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <sys/time.h> |
| #include <sys/types.h> |
| #include <sys/wait.h> |
| #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; |
| } |