使用NDK MediaCodec获取已解码视频的作物边界
我试图通过NDK的MediaCodec API读取作物边界。使用NDK MediaCodec获取已解码视频的作物边界
我读值如下:
AMediaFormat* fmt = initialized();
if (AMediaFormat_getInt32(fmt, "crop-left", &cropLeft)) {
LOGI("crop-left: %d", cropLeft);
}
然而,我无法读取cropLeft值,我尝试过各种视频。我试图在第一帧之后读取它,并且一旦检测到格式改变。
我已经在vlc code基地看到过类似的代码。
寻找什么可能在这里可能是错误的。
目前还不可能读取作物数值。 AMediaFormat包含一个消息struct(AMessage),它由stagefright发送,并带有所有的裁切值。裁切值是特殊类型的Rect,除了已经在AMediaFormat(int32,int64,string,buffer)中定义的值之外,还需要一个新的读取方法。 不幸的是,Rect类型甚至没有被AMediaFormat_toString方法处理。我们可以看到输出为“作物:未知(9)”作物值的未读数。
UPDATE:
这里是一个丑陋的黑客攻击我使用的Galaxy S6与Android 7.0。 它不能用于生产代码。它仅用于测试和演示。它会在其他Android版本和供应商手机上崩溃。 结构预计会在其他Android版本中发生变化,因此需要修正偏移量,填充和其他值。 无论如何,AMediaFormat是一个具有指向AMessage的指针的结构。预计这是在前4个字节。 AMessage是RefBase的一个子类,在mainoffset [24]中,我们正在向AMessage类中的Items数组转发一些字节。我们期待Items结构的大小为32字节,并且它有一个指向“裁剪”字符串的字符指针。当我们找到作物项目时,我们可以读出作物值。
AMediaFormat* format = AMediaCodec_getOutputFormat(_codec);
typedef struct {
char mainoffset[24];
struct {
char itemoffset[8];
int32_t cropLeft;
int32_t cropTop;
int32_t cropRight;
int32_t cropBottom;
unsigned char* name;
char padding[4];
}items[64];
}AMessage;
AMessage* amessage = *((AMessage**)format);
int n = 0;
while (amessage->items[n].name) {
if (!strcmp((const char*)amessage->items[n].name, "crop")) {
int32_t width = amessage->items[n].cropRight - amessage->items[n].cropLeft + 1;
int32_t height = amessage->items[n].cropBottom - amessage->items[n].cropTop + 1;
__android_log_print(ANDROID_LOG_VERBOSE, "FORMAT", "width=%d height=%d", width, height);
break;
}
n++;
}
你不说什么initialized()
在你的代码中。请记住,实际输出MediaFormat
不立即可用,但当您从解码器获得INFO_OUTPUT_FORMAT_CHANGED
时,应该使用MediaCodec.getOutputFormat()
。您无法事先获取MediaFormat
对象,并在获取该返回值时从旧对象中读取,您需要再次调用getOutputFormat()
。
对不起,不清楚。我在调整格式之后调用函数来分析农作物的价值。部分代码如下所示:'.... else if(bufId == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED){... AMediaFormat * format = AMediaCodec_getOutputFormat(track.codec); getRawImageInfo(format,_rawImageInfo); ..'。但是,我使用原始格式来执行编解码器配置,并在调用getRawImageInfo后实际销毁新格式。还有其他事情要做吗? – Ketan
这就是我所发现的。 – Ketan