NV21 на I420 в андроиде

EDIT: я наткнулся на этот libyuv, который выполняет преобразование NV21 в I420, но я действительно не понимаю, как это назвать.

// Convert NV21 to I420.  Same as NV12 but u and v pointers swapped.
LIBYUV_API
int NV21ToI420(const uint8* src_y, int src_stride_y,
           const uint8* src_vu, int src_stride_vu,
           uint8* dst_y, int dst_stride_y,
           uint8* dst_u, int dst_stride_u,
           uint8* dst_v, int dst_stride_v,
           int width, int height) 

Я передаю байт [] NV21, полученный из обратного вызова камеры, на слой jni и преобразовываю его в беззнаковый char *, как показано ниже.

int yuvBufLen = env->GetArrayLength(yuvNV21);
unsigned char* yuvNV21Buf = new unsigned char[yuvBufLen];
env->GetByteArrayRegion(yuvNV21, 0, yuvBufLen,reinterpret_cast<jbyte*>(yuvNV21Buf));

Теперь мне непонятно, как мне получить разные параметры, необходимые для вызова функции libyuv NV21ToI420. Что представляет собой каждый из следующих параметров и как их получить из имеющегося у меня unsigned char* yuvNV21Buf ??

const uint8* src_y,
int src_stride_y,
const uint8* src_vu,
int src_stride_vu,
uint8* dst_y,
int dst_stride_y,
uint8* dst_u,
int dst_stride_u ,
uint8* dst_v,
int dst_stride_v

Я проверил это получить yuv420 в ios, в котором объясняется, как получить все необходимые параметры для вызова libyuv::NV12ToI420.

Может кто-нибудь объяснить мне, как этого добиться??

Я захватываю байт кадра [] с камеры с помощью обратного вызова предварительного просмотра ниже

@Override
        public void onPreviewFrame(byte[] frameData, Camera camera) {

FrameData, который я получаю, находится в формате NV21, и я пытаюсь преобразовать NV21 в I420.


person zenith    schedule 03.11.2014    source источник
comment
Зачем нужно конвертировать в I420? Что ты пытаешься сделать?   -  person fadden    schedule 03.11.2014
comment
работает над приложением для видеоконференций, а серверу нужен формат I420. Когда я передаю NV21 с Android, он выглядит искаженным на сервере.   -  person zenith    schedule 04.11.2014
comment
Точно так же... мое изображение выглядит искаженным, как показано в приведенной выше ссылке (2-е изображение)... это происходит потому, что мой сервер обрабатывает его как I420, поэтому мне нужно преобразовать его в I420, чтобы заставить его работать... есть идеи, как конвертировать NV21 в I420??   -  person zenith    schedule 04.11.2014
comment
Если я правильно понял форматы, то NV21 полуплоский, а I420 плоский. Так что это не простой вопрос замены U и V местами. Вы должны преобразовать все значения U, а затем все значения V в чередующиеся значения U и V.   -  person fadden    schedule 04.11.2014
comment
так нет ли каких-либо средств, с помощью которых я могу достичь желаемого I420 ??   -  person zenith    schedule 06.11.2014
comment
У вас есть данные кадра. Измените свой код, чтобы перетасовать байты цвета. Это более сложно, чем простая замена U/V, но вы просто меняете его с YYYYYYYYUUUUVVVV на YYYYYYYYVUVUVUVU.   -  person fadden    schedule 06.11.2014


Ответы (2)


Я не мог заставить работать метод, который я разместил в вопросе, он продолжал падать.

Но благодаря Питеру я нашел это преобразование NV21ToI420. и это сработало идеально для меня.

Просто нужен NV21 и указатель I420.

unsigned char* yuvPtr; //NV21 data
unsigned char* I420 = new unsigned char[sourceWidth*sourceHeight*1.5]; //destination I420 pointer where the converted yuv will be stored 
NV21toI420(yuvPtr, I420, sourceWidth, sourceHeight);

Это все....

person zenith    schedule 10.12.2014

добавив к этому (поскольку срок действия ссылки в ответе истек). Можно использовать этот код для преобразования YUV отформатировать в NV21.

Поэтому я изменил код таким образом, чтобы преобразовать его в I420. Код здесь. Теперь он отлично работает для видео, созданного mediaEncoder.

person Monster Brain    schedule 01.04.2021