Android mediacodec 如何从给定的缓冲区解码视频?(媒体编解码器)

Android mediacodec 如何从给定的缓冲区解码视频?(媒体编解码器),android-mediacodec,Android Mediacodec,我需要解码交织流中的数据(如AVI) 所以,这意味着我有一个容器,以这样的形状(序列)构建 目前,我有一个基本的MediaCodec解码器实现。我有一个MediaExtractor,在这里我调用setDataSource(),它将mp4文件uri作为参数获取。然后为了得到解码结果,我需要队列/出列缓冲区 因此,这意味着字节生成器是MediaExtractor,它知道如何从uri提取字节 但在我的目的中,我有一个文件(容器),它按顺序包含几种类型的数据 我想做的是——我将只读取一个mp4块(一个

我需要解码交织流中的数据(如AVI)

所以,这意味着我有一个容器,以这样的形状(序列)构建


目前,我有一个基本的
MediaCodec
解码器实现。我有一个
MediaExtractor
,在这里我调用
setDataSource()
,它将mp4文件uri作为参数获取。然后为了得到解码结果,我需要队列/出列缓冲区

因此,这意味着字节生成器是
MediaExtractor
,它知道如何从uri提取字节

但在我的目的中,我有一个文件(容器),它按顺序包含几种类型的数据

我想做的是——我将只读取一个mp4块(一个视频帧),然后我需要将该块(帧)传递到
MediaCodec
进行解码。我想自己成为一个供应商

所以,问题是如何将字节缓冲区传递给
MediaCodec
,以便进行解码处理

另外,我们还没有决定我们的交错容器是否将每个mp4块作为单独的mp4文件(包括头文件),或者只是序列中的第一帧

或者出于这个原因,我需要使用ffmpeg lib

我希望我没有错过任何东西。请随便问

编辑

同时我找到了这样的解决方案(不是最终的)

setDataSourceFd()
此方法知道如何使用文件描述符。他得到了提取器、描述符、偏移量和数据大小等参数

在我的例子中,正如我所说,我有这样的数据序列

mp4 --> other data --> mp4 --> other data --> so on...
让我们先来看看第一个mp4数据是从begging开始的,所以它意味着没有偏移量,所以
setDataSourceFd(ex,fileno(fp),0,dataSize),让我们来看看第二个mp4数据是在5000字节之后开始的。。。so
setDataSourceFd(例如,文件号(fp),5000,数据大小)

这意味着,如果您每次需要创建新的
MediaExtractor
setDataSourceFd()
时都有3000个mp4部件作为示例


我不确定这是否是一个正确的方法,以使它…

我不清楚。听起来像是从MediaExtractor中输入MediaCodec,这很常见。你在做什么,这与典型的.MP4播放不同?@fadden我的意思是,如果你想播放MP4文件,你需要创建extactor对象,将其传递给编解码器,提取器将为你逐个提取帧,但在我的情况下,我将自己从文件中读取字节,不知何故,我需要将这些字节传递给编解码器进行解码。。。你明白我的意思了吗?因为现在我没有标准的mp4容器,我有我自己的类似AVI的容器(音频视频帧按顺序逐个构建)…@fadden所以,实际上我首先看到了两种可能的解决方案-不知何故调整提取器,让它知道如何读取mp4块,然后自己读取所需的字节,并将这些字节传递给编解码器。。。我认为第二种解决方案更好……听起来您正在定义一种用于存储视频和其他数据的自定义格式。因此,您要么需要自定义格式来定义数据包边界的位置,要么需要克隆一个类似MediaExtractor的解析器,以了解如何从.mp4文件中选择流,然后将流切分为NAL单元以馈送到MediaCodec。保留.mp4格式并将自定义数据编码为单独的交错流可能更容易。这里可能有有用的信息:@fadden我觉得我没有用正确的方式解释我的问题。为了简化,问题是:是否可以将字节缓冲区传递给编解码器(以便解码),而不是文件路径?这就是问题所在。因为我没有找到任何关于它的信息,但对我来说,这应该是一个微不足道的任务。。。将字节缓冲区传递给编解码器以便解码。。。
AMediaExtractor *ex = AMediaExtractor_new();

FILE *fp = fopen(filename.c_str(), "rb");
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
fseek(fp, 0, SEEK_SET);
auto err = AMediaExtractor_setDataSourceFd(ex, fileno(fp), 0, size);
mp4 --> other data --> mp4 --> other data --> so on...