Android ndk 使用NDK MediaCodec访问解码视频的裁剪边界

Android ndk 使用NDK MediaCodec访问解码视频的裁剪边界,android-ndk,android-mediacodec,Android Ndk,Android Mediacodec,我试图通过NDK的MediaCodec API读取裁剪边界 我阅读的价值观如下: AMediaFormat* fmt = initialized(); if (AMediaFormat_getInt32(fmt, "crop-left", &cropLeft)) { LOGI("crop-left: %d", cropLeft); } 然而,我无法读取我尝试过的各种视频的cropLeft值。我试着在第一帧之后以及在检测到格式更改之后读取它 我在base中看到过类似的代码 正在查

我试图通过NDK的MediaCodec API读取裁剪边界

我阅读的价值观如下:

AMediaFormat* fmt = initialized();
if (AMediaFormat_getInt32(fmt, "crop-left", &cropLeft)) {
    LOGI("crop-left: %d", cropLeft);
}
然而,我无法读取我尝试过的各种视频的cropLeft值。我试着在第一帧之后以及在检测到格式更改之后读取它

我在base中看到过类似的代码


正在查找此处可能存在的错误。

您没有说出代码中的
initialized()
。请记住,实际输出的
MediaFormat
不能立即使用,但是当您从解码器中获得
INFO\u output\u FORMAT\u更改后的
时,您应该使用
MediaCodec.getOutputFormat()
获得它。您无法预先获取
MediaFormat
对象,并在获取返回值时从旧对象中读取,您需要再次调用
getOutputFormat()

还无法读取裁剪值。 在引擎盖下,AMediaFormat包含一个消息结构(AMessage),由stagefright发送,其中包含所有裁剪值。裁剪值是特殊类型Rect,除了在AMediaFormat(int32、int64、string、buffer)中已经定义的读取方法外,还需要一个新的读取方法。 不幸的是,Rect类型甚至不由AMediaFormat\u toString方法处理。我们可以将输出视为“作物:未知(9)”而不是作物值的读取

更新:

这是一个丑陋的黑客,我正在使用Android 7.0的Galaxy S6上。 它不能在生产代码中使用。这只是为了测试和演示。它将在其他Android版本和厂商手机上崩溃。 在其他Android版本中,结构预计会发生变化,因此偏移量、填充和其他值需要固定。 无论如何,AMediaFormat是一个结构,它有一个指向AMessage的指针。预计这是在前4个字节中。AMessage是RefBase的一个子类,通过mainfostate[24],我们将一些字节前进到AMessage类中的Items数组。我们希望Items结构的大小为32字节,并且它有一个指向“crop”字符串的char指针。找到裁剪项目后,我们可以读取裁剪值

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

抱歉说不清楚。我确实调用了一个函数,在我得到格式更改后解析裁剪值。部分代码如下所示:
。。。。如果(bufId==AMEDIACODEC\u INFO\u OUTPUT\u FORMAT\u CHANGED){…AMediaFormat*FORMAT=AMEDIACODEC\u getOutputFormat(track.codec);getrawmageinfo(FORMAT,\u rawmageinfo)
。但是,我使用原始格式进行编解码器配置,并在调用getRawImageInfo后实际销毁新格式。是否还需要执行其他操作?这与我发现的非常接近。API 28中将提供AMediaFormat_getRect: