2017-08-10 31 views
0

NDKのMediaCodec APIを使用してクロップ境界を読み取ろうとしています。NDK MediaCodecを使用してデコードされたビデオのクロップ境界にアクセスする

私は以下のように値を読んでいます:

AMediaFormat* fmt = initialized(); 
if (AMediaFormat_getInt32(fmt, "crop-left", &cropLeft)) { 
    LOGI("crop-left: %d", cropLeft); 
} 

はしかし、私は私が試した様々なビデオのためにcropLeft値を読み取ることができません。私は最初のフレームの後でそれを読み込もうとしましたが、一度フォーマットの変更が検出されました。

vlc codeベースでも同様のコードが使用されています。

ここで間違っている可能性があるものをお探しください。

答えて

1

まだクロップ値を読み取ることはできません。 フードの下では、AMediaFormatには、すべてのクロップ値を含むstagefrightによって送信されるメッセージ構造体(AMessage)が含まれています。トリミング値は特別な型のRect型で、AMediaFormat(int32、int64、string、buffer)で既に定義されているもの以外にも新しいreadメソッドが必要です。 残念ながら、Rect型はAMediaFormat_toStringメソッドでも扱われません。我々は、作物価値の「収穫物:不明(9)」の産地としての産出を見ることができる。

UPDATE:ここ

は、私は、Android 7.0でのGalaxy S6に使用しています醜いハックです。 実動コードでは使用できません。テストとデモのためのものです。他のAndroidバージョンとベンダーの携帯電話でクラッシュします。 構造体は他のAndroidバージョンでは変更される予定であるため、オフセット、パディングなどの値を修正する必要があります。 とにかく、AMediaFormatは、AMessageへのポインタを持つ構造体です。これは最初の4バイトにあると予想されます。 AMessageはRefBaseのサブクラスであり、mainoffset [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++; 
} 
+0

それは私が見つけたものに近いです。 – Ketan

1

コードにinitialized()が含まれているとは限りません。実際の出力MediaFormatはすぐには利用できませんが、デコーダからINFO_OUTPUT_FORMAT_CHANGEDが返ってきたら、MediaCodec.getOutputFormat()で取得する必要があります。 MediaFormatオブジェクトを事前にフェッチして、その戻り値を取得したときに古いオブジェクトから読み取ることはできません。getOutputFormat()に再度呼び出す必要があります。

+0

ご迷惑をおかけして申し訳ありません。私はフォーマットの変更を取得した後、作物の値を解析する関数を呼び出します。部分コードは以下のようになります: '.... else if(bufId == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED){... AMediaFormat * format = AMediaCodec_getOutputFormat(track.codec); getRawImageInfo(format、_rawImageInfo); .. '。しかし、私は元のフォーマットを使ってコーデックの設定を行い、実際にはgetRawImageInfoを呼び出して新しいフォーマットを破棄します。他に何かをする必要がありますか? – Ketan

関連する問題