tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

hwcontext_mediacodec.c (3553B)


      1 /*
      2 * This file is part of FFmpeg.
      3 *
      4 * FFmpeg is free software; you can redistribute it and/or
      5 * modify it under the terms of the GNU Lesser General Public
      6 * License as published by the Free Software Foundation; either
      7 * version 2.1 of the License, or (at your option) any later version.
      8 *
      9 * FFmpeg is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12 * Lesser General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU Lesser General Public
     15 * License along with FFmpeg; if not, write to the Free Software
     16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     17 */
     18 
     19 #include "config.h"
     20 
     21 #include <android/native_window.h>
     22 #include <dlfcn.h>
     23 #include <media/NdkMediaCodec.h>
     24 
     25 #include "buffer.h"
     26 #include "common.h"
     27 #include "hwcontext.h"
     28 #include "hwcontext_internal.h"
     29 #include "hwcontext_mediacodec.h"
     30 
     31 typedef struct MediaCodecDeviceContext {
     32    AVMediaCodecDeviceContext ctx;
     33 
     34    void *libmedia;
     35    media_status_t (*create_surface)(ANativeWindow **surface);
     36 } MediaCodecDeviceContext;
     37 
     38 
     39 static int mc_device_create(AVHWDeviceContext *ctx, const char *device,
     40                            AVDictionary *opts, int flags)
     41 {
     42    const AVDictionaryEntry *entry = NULL;
     43    MediaCodecDeviceContext *s = ctx->hwctx;
     44    AVMediaCodecDeviceContext *dev = &s->ctx;
     45 
     46    if (device && device[0]) {
     47        av_log(ctx, AV_LOG_ERROR, "Device selection unsupported.\n");
     48        return AVERROR_UNKNOWN;
     49    }
     50 
     51    while ((entry = av_dict_iterate(opts, entry))) {
     52        if (!strcmp(entry->key, "create_window"))
     53            dev->create_window = atoi(entry->value);
     54    }
     55 
     56    av_log(ctx, AV_LOG_DEBUG, "%s createPersistentInputSurface\n",
     57            dev->create_window ? "Enable" : "Disable");
     58 
     59    return 0;
     60 }
     61 
     62 static int mc_device_init(AVHWDeviceContext *ctx)
     63 {
     64    MediaCodecDeviceContext *s = ctx->hwctx;
     65    AVMediaCodecDeviceContext *dev = (AVMediaCodecDeviceContext *)s;
     66    ANativeWindow *native_window = NULL;
     67 
     68    if (dev->surface)
     69        return 0;
     70 
     71    if (dev->native_window)
     72        return 0;
     73 
     74    // For backward compatibility, don't return error for a dummy
     75    // AVHWDeviceContext without surface or native_window.
     76    if (!dev->create_window)
     77        return 0;
     78 
     79    s->libmedia = dlopen("libmediandk.so", RTLD_NOW);
     80    if (!s->libmedia)
     81        return AVERROR_UNKNOWN;
     82 
     83    s->create_surface = dlsym(s->libmedia, "AMediaCodec_createPersistentInputSurface");
     84    if (!s->create_surface)
     85        return AVERROR_UNKNOWN;
     86 
     87    s->create_surface(&native_window);
     88    dev->native_window = native_window;
     89    return 0;
     90 }
     91 
     92 static void mc_device_uninit(AVHWDeviceContext *ctx)
     93 {
     94    MediaCodecDeviceContext *s = ctx->hwctx;
     95    AVMediaCodecDeviceContext *dev = ctx->hwctx;
     96    if (!s->libmedia)
     97        return;
     98 
     99    if (dev->native_window) {
    100        ANativeWindow_release(dev->native_window);
    101        dev->native_window = NULL;
    102    }
    103    dlclose(s->libmedia);
    104    s->libmedia = NULL;
    105 }
    106 
    107 const HWContextType ff_hwcontext_type_mediacodec = {
    108    .type                 = AV_HWDEVICE_TYPE_MEDIACODEC,
    109    .name                 = "mediacodec",
    110 
    111    .device_hwctx_size    = sizeof(MediaCodecDeviceContext),
    112 
    113    .device_create        = mc_device_create,
    114    .device_init          = mc_device_init,
    115    .device_uninit        = mc_device_uninit,
    116 
    117    .pix_fmts = (const enum AVPixelFormat[]){
    118        AV_PIX_FMT_MEDIACODEC,
    119        AV_PIX_FMT_NONE
    120    },
    121 };