Android 为什么不同设备的ANativeWindow_Buffer.stride不同
我正在为android编写使用ffmpeg的简单视频播放器。以下是我遵循的步骤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
sws\U比例将AVFrame转换为RGB565格式
av\u image\u copy\u到\u buffer获取缓冲区
ANativeWindow\u buffer
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)