gpt4 book ai didi

android - 为什么不同设备的 ANativeWindow_Buffer.stride 不同

转载 作者:行者123 更新时间:2023-12-04 22:54:54 27 4
gpt4 key购买 nike

我正在使用 ffmpeg for android 编写简单的视频播放器。以下是我遵循的步骤

  • 从文件
  • 中读取 AVFrame
  • 使用 sws_scale 将 AVFrame 转换为 RGB565 格式
  • 使用 av_image_copy_to_buffer 获取缓冲区
  • 将此缓冲区显示到 SurfaceView通过将缓冲区复制到 ANativeWindow_Buffer

  • 大多数视频都可以正常播放,但是分辨率低于窗口的视频存在问题。例如,当我在我的 OnePlus 7T (2206x1080) 上播放 656x480 视频时,视频看起来失真。相同的视频在模拟器 (2160x1080) 上播放良好。
    当我调试整个管道时,我发现在OP7T上,锁定 ANativeWindow后, ANativeWindow_Buffer.stride设置为 704 而不是 656。对于所有正常播放的视频,步幅与缓冲区的宽度相同。 Android模拟器并非如此。
    我做了一些试验并尝试将宽度缩放到 600,然后步幅跳到 640,视频失真了。当我将宽度缩放到 640 时,视频垂直显示一半正确。
    谁能帮我理解,步幅是如何计算的?错误计算步幅的原因是什么?
    我在这里发现了一个同样的问题: Simple FFMpeg player for Android
    OP 提到视频适用于 640、1280、1920。

    最佳答案

    似乎因为我的设备是 arm64-v8a,所以步幅总是与 64 对齐。为了克服这个问题,我在锁定窗口并使用 ANative_WindowBuffer 后获得了步幅.然后我用这个windowbuffer.stride计算 sws_scale 的 dst_slice .

    AVFrame dummy;

    if ((ret = ANativeWindow_lock(window, &windowBuffer, nullptr)) < 0) {
    log_error("cannot lock window: %d", ret);
    } else {
    dummy.data[0] = (uint8_t *) windowBuffer.bits;
    dummy.linesize[0] = windowBuffer.stride * 2 // For RGB565;
    }
    接着:
    sws_scale(renderer->sws_ctx,
    (const uint8_t* const *) frame->data,
    frame->linesize,
    0,
    codecpar->height,
    dummy.data,
    dummy.linesize)
    这将直接将缩放的帧数据渲染到窗口缓冲区。

    关于android - 为什么不同设备的 ANativeWindow_Buffer.stride 不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63340751/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com