Android 为什么不同设备的ANativeWindow_Buffer.stride不同

Android 为什么不同设备的ANativeWindow_Buffer.stride不同,android,ffmpeg,libav,android-ffmpeg,Android,Ffmpeg,Libav,Android Ffmpeg,我正在为android编写使用ffmpeg的简单视频播放器。以下是我遵循的步骤 从文件中读取AVFrame 使用sws\U比例将AVFrame转换为RGB565格式 使用av\u image\u copy\u到\u buffer获取缓冲区 通过将缓冲区复制到ANativeWindow\u buffer 大多数视频都播放得很好,但分辨率低于window的视频存在问题。例如,当我在OnePlus 7T(2206x1080)上播放656x480视频时,视频看起来失真了。相同的视频在emulator(2

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

  • 从文件中读取AVFrame
  • 使用
    sws\U比例将AVFrame转换为RGB565格式
  • 使用
    av\u image\u copy\u到\u buffer获取缓冲区
  • 通过将缓冲区复制到
    ANativeWindow\u buffer
  • 大多数视频都播放得很好,但分辨率低于window的视频存在问题。例如,当我在OnePlus 7T(2206x1080)上播放656x480视频时,视频看起来失真了。相同的视频在emulator(2160x1080)上可以正常播放

    当我调试整个管道时,我发现在OP7T上,锁定
    ANativeWindow
    后,
    ANativeWindow\u Buffer.stride
    被设置为704,而不是656。对于所有正常播放的视频,步幅与缓冲区的宽度相同。Android emulator的情况并非如此

    我做了一些试验,尝试将宽度缩放到600,然后步幅跳到640,视频失真。当我将宽度缩放到640时,视频垂直显示半正确

    谁能帮我理解,步幅是如何计算的?步幅计算错误的原因是什么

    我在这里发现了一个相同的问题:
    OP提到视频在640、1280、1920都可以正常工作。

    似乎因为我的设备是arm64-v8a,所以步幅总是与64对齐。为了克服这个问题,我在锁定窗口并使用
    ANative\u WindowBuffer
    后获得了步幅。然后我使用这个
    windowbuffer.stride
    来计算
    sws\u scale
    的dst\u切片

    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;
    }
    

    这将直接将缩放后的帧数据渲染到windowbuffer。

    谢谢,除了行大小[0]以外,其他都是以字节为单位的跨距。这一切现在都是有道理的,但在得到这个答案之前,我完全感到困惑。
    sws_scale(renderer->sws_ctx,
                            (const uint8_t* const *) frame->data,
                            frame->linesize,
                            0,
                            codecpar->height,
                            dummy.data,
                            dummy.linesize)