ijkplayer-添加播放截图功能

2023-05-16

应用播放的时候需要截图,可以在上层使用TexturView来使用截图,不过太具有局限性呢,还是在底层处理比较好。
那么先分析下可以在哪里加截图呢?看到网上很多做的都不能支持硬解截图,这样肯定是不行的。

所以我们可以选择在video_image_display2中来做截屏处理。

添加shot_screen.h

#ifndef _SHOT_SCREEN_H
#define _SHOT_SCREEN_H

#include <jni.h>
#include "ff_ffplay_def.h"
#include "ijkplayer.h"

int do_shot(VideoState *videoState, uint8_t *frameFuf, int destWidth, int destHeight,
            SDL_VoutOverlay *bmp);

jobject start_shot(JNIEnv *env, IjkMediaPlayer *mp, int width, int height, jobject config);

#endif

添加shot_screen.c文件

#include <jni.h>
#include <android/bitmap.h>
#include "ff_ffplay_def.h"
#include "ijkplayer.h"
#include "ijkplayer_internal.h"
#include "shot_screen.h"

void fill_bitmap(int lineSize, uint8_t *data, uint8_t *frameFuf, int width, int height) {
    int size = width * 4;
    for (int i = 0; i < height; i++) {
        memcpy(frameFuf + i * size, data + i * lineSize, (size_t) size);
    }
}

int scale_and_fill_bitmap(VideoState *videoState, uint8_t *frameFuf, int destWidth, int destHeight,
                          SDL_VoutOverlay *bmp, enum AVPixelFormat pixelFormat) {
    int ret = 0;
    int height = bmp->h;
    int width = bmp->w;

    struct SwsContext *swsContext = sws_getCachedContext(videoState->img_convert_ctx, width,
                                                         height,
                                                         pixelFormat, destWidth,
                                                         destHeight,
                                                         AV_PIX_FMT_RGBA, SWS_FAST_BILINEAR,
                                                         NULL, NULL, NULL);
    AVFrame *rgbFrame = av_frame_alloc();
    uint8_t *outBuffer = av_malloc(
            (size_t) av_image_get_buffer_size(AV_PIX_FMT_RGBA, destWidth, destHeight, 1));
    if (outBuffer == NULL) {
        ret = -1;
        goto end;
    }
    if (av_image_fill_arrays(rgbFrame->data, rgbFrame->linesize, outBuffer, AV_PIX_FMT_RGBA,
                             destWidth, destHeight, 1) < 0) {
        ret = -1;
        goto end;
    }
    int result = sws_scale(swsContext, (const uint8_t *const *) bmp->pixels,
                           (const int *) bmp->pitches, 0,
                           height, &frameFuf,
                           rgbFrame->linesize);
    if (result <= 0) {
        ret = -1;
        goto end;
    }
    end:
    av_frame_free(&rgbFrame);
    sws_freeContext(swsContext);
    if (outBuffer != NULL) {
        av_free(outBuffer);
    }
    return ret;
}

int do_shot(VideoState *videoState, uint8_t *frameFuf, int destWidth, int destHeight,
            SDL_VoutOverlay *bmp) {
    int height = bmp->h;
    int width = bmp->w;
    enum AVPixelFormat dst_format;
    int needScale = 0;
    switch (bmp->format) {
        case SDL_FCC_YV12:
        case SDL_FCC_I420:
            dst_format = AV_PIX_FMT_YUV420P;
            needScale = 1;
            break;
        case SDL_FCC_I444P10LE:
            dst_format = AV_PIX_FMT_YUV444P10LE;
            needScale = 1;
            break;
        case SDL_FCC_RV32:
            dst_format = AV_PIX_FMT_0BGR32;
            break;
        case SDL_FCC_RV24:
            dst_format = AV_PIX_FMT_RGB24;
            needScale = 1;
            break;
        case SDL_FCC_RV16:
            dst_format = AV_PIX_FMT_RGB565;
            break;
        default:
            return -1;
    }
    if (destWidth != width || destHeight != height || needScale) {
        return scale_and_fill_bitmap(videoState, frameFuf, destWidth, destHeight, bmp, dst_format);
    }
    int lineSize = bmp->pitches[0];
    uint8_t *data = bmp->pixels[0];
    fill_bitmap(lineSize, data, frameFuf, width, height);
    return 0;
}

SDL_VoutOverlay *get_last_bmp(FFPlayer *ffp) {
    VideoState *is = ffp->is;
    Frame *vp = &is->pictq.queue[is->pictq.rindex];
    return vp->bmp;
}

jobject start_shot(JNIEnv *env, IjkMediaPlayer *mp, int width, int height, jobject config) {
    SDL_VoutOverlay *bmp = get_last_bmp(mp->ffplayer);
	if (bmp == NULL) {
        return NULL;
    }
    jclass bitmapClass = (*env)->FindClass(env, "android/graphics/Bitmap");
    jmethodID createBitmapMethodId = (*env)->GetStaticMethodID(env, bitmapClass, "createBitmap",
                                                               "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
    int destWidth = bmp->w;
    if (width > 0) {
        destWidth = width >= destWidth ? destWidth : width;
    }
    int destHeight = bmp->h;
    if (height > 0) {
        destHeight = height >= destHeight ? destHeight : height;
    }
    jobject bitmap = (*env)->CallStaticObjectMethod(env, bitmapClass, createBitmapMethodId,
                                                    destWidth,
                                                    destHeight, config);
    uint8_t *frameBuffer = NULL;
    if (0 > AndroidBitmap_lockPixels(env, bitmap, (void **) &frameBuffer)) {
        return NULL;
    }
    int ret = do_shot(mp->ffplayer->is, frameBuffer, destWidth, destHeight, bmp);
    if (0 > AndroidBitmap_unlockPixels(env, bitmap)) {
        return NULL;
    }
    ijkmp_dec_ref_p(&mp);
    if (ret < 0) {
        return NULL;
    }
    return bitmap;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ijkplayer-添加播放截图功能 的相关文章

  • java String 最长长度和占用内存大小

    一 序 String在内存中的最大长度理论上是int型变量的最大值 xff0c Integer MAX VALUE String的字面常量的最大长度为CONSTANT Utf8 info表决定 xff0c 一般为65535 二 介绍 1 S
  • Android常用检查判断方法

    自己工作中比较常用的一些判断检测 span class hljs keyword import span android app ActivityManager span class hljs keyword import span and
  • 小米、魅族状态栏字体变色整理

    span class hljs javadoc 设置小米手机状态栏字体图标颜色模式 xff0c 需要MIUIV6以上 span class hljs javadoctag 64 param span window 需要设置的窗口 span
  • C语言学习:初接触

    C程序结构 C程序结构主要包括以下部分 xff1a 预处理指令器 函数 变量 语句 amp 函数体 注释 用一个简单的 Hello World 代码说明 xff1a span class hljs preprocessor include
  • C语言学习:基本语法

    分号 如果你有其它编程语言的基础 xff0c 相信你已经明白了分号的意义 分号在C语言中与多数语言相同 xff0c 它代表了语句的结束 也就是说 xff0c 一个完整的语句必须以分号结尾 注释 注释就像是帮助文件一样 xff0c 它可以帮助
  • C语言学习:数据类型

    在C语言中 xff0c 数据类型可以分为以下几种 xff1a 类型描述基本类型C语言中的算术类型 xff0c 包含整数型和浮点型枚举类型C语言中的算术类型 xff0c 用来定义在程序中只能赋予其一定的离散整数值的变量 void类型类型说明符
  • 典型相关分析(CCA)

    CCA是数据挖掘中重要的算法 xff0c 可以挖掘出数据间的关联关系的算法 基础知识 如何衡量两个变量之间的相关性呢 xff1f 我们有相关系数 xff0c 如下所示 xff1a X Y 61 c o v X Y D X D Y X
  • Android 按键模拟输入事件和Monitor工具的使用

    有时候 xff0c 进行Android开发 xff0c 会遇到屏幕会失灵的情况 xff0c 但是显示无问题 xff0c 这时候可以使用一些工具 手段 xff0c 在电脑端控制模拟屏幕输入 xff0c 或者使用adb 相关命令模拟按键事件输入
  • Android APK获取平台系统签名权限

    1 修改AndroidManifest xml xff0c 改变uid为android uid system xff0c 使之与Settings能够共享数据空间 lt xml version 61 34 1 0 34 encoding 61
  • gradlew编译时出现Unsupported major.minor version 52.0

    Android apk命令行编译时 xff0c 出现如下错误 xff1a Unsupported major minor version 52 0 先摆上结论 xff1a 1 有可能是compileSdkVersion和buildToolV
  • Android NE发生定位辅助之addr2line

    当发生NE时 xff0c 可以通过addr2line来辅助定位发生点 举个例子 Exception Class Native NE Exception Type SIGABRT Current Executing Process pid 3
  • Android N编译之Out of memory error

    之前本地环境编译一直是正常的 xff0c 后来更新代码后 xff0c 出现编译不过 提示out of memory 但是查看swap和内存都还是够的 里面有个提示 xff0c try increasing heap size with ja

随机推荐

  • Android R源码Settings之NFC与Tap&pay

    Android R 又对 Tap amp pay菜单 进行了更新 xff0c 变得更加合理化 xff0c 人性化了 编辑于2020 4 20 12 24 10 xff09 Android R Tap amp pay菜单 如图可知 xff0c
  • [NOTE]Android N SmartLock缺少很多功能

    有个Android项目刚启动不久时 xff0c 测试SmartLock时 xff0c 发现里面只有On body detection xff0c Trusted places Trusted devices Trusted face和Tru
  • Launcher壁纸来源

    Launcher是个特殊APK xff0c 但说到底还是个应用 xff0c 想要在上面展示壁纸 xff0c 自然是来自应用本身 xff0c 要么就是Framework public资源 首先 xff0c 根据长按Launcher主界面空白处
  • Android N之hasSystemFeature

    当我们判断某一功能打开与否时 xff0c 一般会有个确认本功能是否支持的过程 xff0c 以便与为相关的功能初始化其他的环境 xff0c 例如 xff1a 蓝牙 NFC 例如 NFC HCE 两个的声明如下 xff1a Feature fo
  • Android Go项目预置应用Google GTS测试testPreloadedAppsTargetSdkVersion失败

    Android GO项目中预置的一个Weather应用 xff0c GTS测试通不过 据log提示 xff0c 是兼容的SDK目标版本过低导致 xff0c GO版本要求必须为API 26 43 含26 xff09 LOG如下 xff1a 0
  • 多维缩放算法(MDS)

    算法思想 MDS算法思想很简单 xff0c 一句话就是保持样本在原空间和低维空间的距离不变 因为距离是样本之间一个很好的分离属性 xff0c 对于大多数聚类算法来说 xff0c 距离是将样本分类的重要属性 xff0c 因此当我们降维后 xf
  • Gerrit 安装lfs插件

    一 下载lfs插件 https gerrit ci gerritforge com job plugin lfs bazel stable 2 16 这个是直接编译好的 二 安装插件 将下载的插件放在 GERRIT SITE plugins
  • 反编译so库破解so

    所需工具 1 IDA Pro v6 8 and Hex Rays Decompiler 2 WinHex 3 ARM ASM 背景 xff1a I2C通讯时报log CameraHal Marvin HAL MOCKUP HalReadI2
  • 长虹官方刷机包和刷机教程

    为了解决部分朋友因应用引起的电视死机 无法开机 系统被破坏等情形 xff0c 长虹电视团队特开此帖为朋友们提供刷机方法 xff0c 但刷机有风险 xff0c 如完全不懂刷机技巧的朋友需要谨慎操作哦 xff0c 如有疑问可以微信留言给我们 下
  • Android终端通过adb 配置静态IP和DNS

    有时我们需要使用命令行来配置eth0的IP信息 xff0c 这在linux系统是非常简单的 xff0c 网上也有很多资料 但是在Android系统 xff0c 就非常困难 xff0c 因为Android精简掉了很多linux命令 xff0c
  • 【官方】下载最新adb及安装驱动的方法

    Only adb 驱动 xff1a https adbdriver com downloads adb工具 xff1a https adbshell com upload adb zip https adbshell com downloa
  • 中芯微随身WIFI破解实体SIM卡槽(不拆机,无需切卡密码)

    目前网上卖的一些随身WIFI是中芯微的方案 MF782 部分产品限制用户使用实体SIM卡 只能使用内置eSIM 下面谈谈解决方案 1 中沃的没有限制 实体SIM卡优先 检测到插的有实体SIM卡 就使用实体SIM卡网络 2 另外一部分网上提供
  • 高通Android随身WIFI屏蔽商家远程控制断网

    nbsp nbsp nbsp nbsp 部分随身WIFI商家后台会监测用户是否使用的是自家的eSIM 若使用了外置卡槽或eSIM的ICCID改变就会断网 主要表现是先联网后突然变成飞行模式 或联网后开热点变飞行模式 这就是商家后台做了监测
  • Linux kernel make clean时忽略部分文件(不被删除)

    有时我们在运行make clean 时 xff0c 需要保留某些 o 文件 xff0c 这就需要我们修改 Makefile 文件 xff0c 下面以 linux 2 6 18 的 Makefile 为例 xff1a Files to ign
  • Audio参数讲解

    一 音频基础参数 frame bits 一帧数据的位数比如 xff1a 16bits 2ch frame bits 61 16 2 sample bits 采样位数 比如16bit 24bit 32bit period size 指一个周期
  • linux ALSA 驱动架构

    一 kernel Audio驱动架构主流有两大类 xff0c 一类是SOC Machine架构 xff0c 另一类是simple card架构 MTK QCom主要采用machine架构 xff0c rockchip采用simple car
  • adaboost提升算法

    引言 俗话说得好 xff0c 三个臭皮匠赛过诸葛亮 更主要的是三个臭皮匠好找 xff0c 一个诸葛亮太难找了 在机器学习里面也是一样的 我们可以设计出各种分类器 xff0c 然而分类器的效果确实不一而同的 xff0c 相对而言 xff0c
  • 长虹电视刷机固件包汇总

    为了解决部分朋友因应用引起的电视死机 无法开机 系统被破坏等情形 xff0c 快客服务特开此帖为朋友们提供刷机方法 xff0c 但刷机有风险 xff0c 如完全不懂刷机技巧的朋友需要谨慎操作 xff0c 用户自行刷机所产生问题自行负责 xf
  • WebRTC-集成qsv硬解码实现

    1 Window下QSV硬解码配置 在libavcodec codec list c下添加 amp ff h264 qsv decoder 在ffmpeg generate gni下加入 34 libavcodec h264idct c 3
  • ijkplayer-添加播放截图功能

    应用播放的时候需要截图 xff0c 可以在上层使用TexturView来使用截图 xff0c 不过太具有局限性呢 xff0c 还是在底层处理比较好 那么先分析下可以在哪里加截图呢 xff1f 看到网上很多做的都不能支持硬解截图 xff0c