gpt4 book ai didi

android - 获取 MediaCodec 解码器以 RGBA 格式提供视频帧

转载 作者:行者123 更新时间:2023-11-29 02:34:56 24 4
gpt4 key购买 nike

我正在尝试使用 MediaCodec 解码器(通过 NDK API)从 .mp4 文件中获取视频帧(用于进一步处理)。以下是设置解码器以呈现到表面(由 ImageReader 拥有)的示例代码:

// Omitting most error handling for clarity

AMediaExtractor* ex = AMediaExtractor_new();
media_status_t err = AMediaExtractor_setDataSourceFd(ex, fd /*opened previously*/, outStart, outLen);
close(fd);

int numtracks = AMediaExtractor_getTrackCount(ex);
AMediaCodec* decoder = NULL;

for (int i = 0; i < numtracks; i++) {
AMediaFormat *format = AMediaExtractor_getTrackFormat(ex, i);
const char *s = AMediaFormat_toString(format);
LOGV("track %d format: %s", i, s);
const char *mime;
if (!AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime)) {
LOGV("no mime type");
return JNI_FALSE;
} else if (!strncmp(mime, "video/", 6)) {
AMediaExtractor_selectTrack(ex, i);
decoder = AMediaCodec_createDecoderByType(mime);

AImageReader* imageReader;
ANativeWindow* surface;

// This setting doesn’t works
media_status_t status = AImageReader_new(480, 360, AIMAGE_FORMAT_RGBA_8888, 1, &imageReader);

// This setting works
//media_status_t status = AImageReader_new(480, 360, AIMAGE_FORMAT_YUV_420_888, 1, &imageReader);

status = AImageReader_getWindow(imageReader, &surface);

// Configure the decoder to render to a surface
AMediaCodec_configure(codec, format, surface, NULL, 0);

AMediaCodec_start(codec);
}

AMediaFormat_delete(format);
}

在其他地方,下面是我如何为 ImageReader 设置回调:

AImageReader_ImageListener* imageListener = new AImageReader_ImageListener();
imageListener->onImageAvailable = &imageCallback;
AImageReader_setImageListener(imageReader, imageListener);

最后,下面是回调的样子:

void imageCallback(void *context, AImageReader *reader) {

int32_t format;
media_status_t status = AImageReader_getFormat (reader, &format);

AImage* image;
status = AImageReader_acquireLatestImage(reader, &image);

status = AImage_getFormat(image, &format);

// further processing to follow
...
}

我一直面临的问题是,如果我用 RGBA 格式配置 ImageReader,回调中的 image 总是出现 NULL:

// Always NULL for ImageReader configured with RGBA
// OK for ImageReader configured with YUV_420_888
AImage* image;
status = AImageReader_acquireLatestImage(reader, &image);

我在这里正确使用了 NDK API 吗?我想提及的一件事是 RGBA 没有出现在通过以下 API 获取的解码器功能列表中(不是通过 NDK 提供,在 Java 层中尝试过):

 getCodecInfo().getCapabilitiesForType(…).colorFormats

最佳答案

视频解码器通常不支持以 RGB 格式输出(正如您在颜色格式编解码器信息中注意到的那样),所以这就是它不起作用的原因。

如果您使用表面纹理作为解码器的输出,则视频解码器输出可以透明地转换为 RGB - 然后解码后的视频数据可在 OpenGL 上下文中使用。如果您随后只是对表面纹理进行简单的 1:1 复制/渲染,并将 OpenGL 上下文设置为渲染到 ImageReader,我希望您能获得所需的 RGB 数据。

这有点迂回(而且我不确定在 native 代码上下文中访问所有 API 有多容易),但据我所知应该是可行的。

关于android - 获取 MediaCodec 解码器以 RGBA 格式提供视频帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47627544/

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