我如何在Android NDK中进行表面视图缩放



早上好。

我正在使用FFMPEG制作相机视频播放器。

在生产过程中,我们面临一个问题。

如果您通过FFMPEG乘坐一个框架,解码框架并符合屏幕尺寸,则需要太长,相机图像将负担。

例如,当传入输入分辨率为1920 * 1080,而我的手机的分辨率为2550 * 1440时,SWS_SCALE的速度约为6倍。[更改为相同尺寸时的对比度]

当前,NDK将SWS_SCALE转换为相机输入的分辨率,因此速度得到提高并且图像不会中断。

但是,表面视图是全屏,但输入分辨率低于完整分辨率。

比例avframe

ctx->m_SwsCtx = sws_getContext(
        ctx->m_CodecCtx->width,
        ctx->m_CodecCtx->height,
        ctx->m_CodecCtx->pix_fmt,
        //width,                  // 2550 (SurfaceView)
        //height,                 // 1440
        ctx->m_CodecCtx->width,   // 1920 (Camera)
        ctx->m_CodecCtx->height,  // 1080
        AV_PIX_FMT_RGBA,
        SWS_FAST_BILINEAR,
        NULL, NULL, NULL);
if(ctx->m_SwsCtx == NULL)
{
    __android_log_print(
        ANDROID_LOG_DEBUG,
        "[ VideoStream::SetResolution Fail ] ",
        "[ Error Message : %s ]",
            "SwsContext Alloc fail");
    SET_FIELD_TO_INT(pEnv, ob, err, 0x40);
    return ob;
}
sws_scale(
    ctx->m_SwsCtx,
    (const uint8_t * const *)ctx->m_SrcFrame->data,
    ctx->m_SrcFrame->linesize,
    0,
    ctx->m_CodecCtx->height,
    ctx->m_DstFrame->data,
    ctx->m_DstFrame->linesize);
    PDRAWOBJECT drawObj = (PDRAWOBJECT)malloc(sizeof(DRAWOBJECT));
    if(drawObj != NULL)
    {
        drawObj->m_Width = ctx->m_Width;
        drawObj->m_Height = ctx->m_Height;
        drawObj->m_Format = WINDOW_FORMAT_RGBA_8888;
        drawObj->m_Frame = ctx->m_DstFrame;
        SET_FIELD_TO_INT(pEnv, ob, err, -1);
        SET_FIELD_TO_LONG(pEnv, ob, addr, (jlong)drawObj);
    }

绘制SurfaceView;

PDRAWOBJECT d = (PDRAWOBJECT)drawObj;
long long curr1 = CurrentTimeInMilli();
ANativeWindow *window = ANativeWindow_fromSurface(pEnv, surface);
ANativeWindow_setBuffersGeometry(window, 0, 0, WINDOW_FORMAT_RGBA_8888);
ANativeWindow_setBuffersGeometry(
        window,
        d->m_Width,
        d->m_Height,
        WINDOW_FORMAT_RGBA_8888);
ANativeWindow_Buffer windowBuffer;
ANativeWindow_lock(window, &windowBuffer, 0);
uint8_t * dst = (uint8_t*)windowBuffer.bits;
int  dstStride = windowBuffer.stride * 4;
uint8_t * src = (uint8_t*) (d->m_Frame->data[0]);
int srcStride = d->m_Frame->linesize[0];
for(int h = 0; h < d->m_Height; ++h)
{
    // Draw SurfaceView;
    memcpy(dst + h * dstStride, src + h * srcStride, srcStride);
}
ANativeWindow_unlockAndPost(window);
ANativeWindow_release(window);

结果;

在此处输入图像描述

我想将整个屏幕从全屏更改为全屏。有没有一种方法可以更改NDK或Android中的表面视图的大小,而不是SWS_SCALE?

谢谢。

您不需要扩展视频。实际上,您甚至不需要将其转换为RGB(这也是CPU的重大负担(。

诀窍是将开放式渲染与使用YUV输入的着色器一起使用,并显示此纹理缩放的屏幕。

从此解决方案开始(从Android系统重复使用代码(: https://stackoverflow.com/a/14999912/192373

最新更新