NV21, NV12, YV12, RGB, YUV, RGBA и RGBX8888 — это распространенные форматы кодирования цвета изображения. Основное различие между ними заключается в цветовом пространстве и расположении данных.
В этой статье в качестве примера рассматривается модуль RTMP Live Push платформы Android. Дизайн интерфейса перед кодированием видеоизображения выглядит следующим образом:
/*
* SmartPublisherJniV2.java
* SmartPublisherJniV2
*
* Author: daniusdk.com
* Created by DaniuLive on 2015/09/20.
*/
/**
* Уровень доставки изображения YUV420888, Интерфейс, специально предназначенный для формата android.graphics.ImageFormat.YUV_420_888 android.media.Image.
*
* @param index: индекс слоя, Должно быть больше или равно 0
*
* @param left: Координаты верхнего левого угла наложения слоя, Для слоя 0 передайте 0
*
* @param top: Координаты верхнего левого угла наложения слоя, Для слоя 0 передайте 0
*
* @param y_plane: Соответствует android.media.Image.Plane[0].getBuffer()
*
* @param y_offset: смещение изображения, Основная цель этого — создание клипов. Обычно передается 0.
*
* @param y_row_stride: Соответствует android.media.Image.Plane[0].getRowStride()
*
* @param u_plane: android.media.Image.Plane[1].getBuffer()
*
* @param u_offset: смещение изображения, Основная цель этого — создание клипов. Обычно передается 0.
*
* @param u_row_stride: android.media.Image.Plane[1].getRowStride()
*
* @param v_plane: Соответствует android.media.Image.Plane[2].getBuffer()
*
* @param v_offset: смещение изображения, Основная цель этого — создание клипов. Обычно передается 0.
*
* @param v_row_stride: Соответствует android.media.Image.Plane[2].getRowStride()
*
* @param uv_pixel_stride: Соответствует android.media.Image.Plane[1].getPixelStride()
*
* @param width: width, Должно быть больше 1, и должно быть четное число
*
* @param height: height, Должно быть больше 1, и должно быть четное число
*
* @param is_vertical_flip: Стоит ли переворачивать вертикально, 0 не переворачивается, 1 флип
*
* @param is_horizontal_flip: переворачивать ли по горизонтали, 0 не переворачивается, 1 флип
*
* @param scale_width: Ширина шкалы должна быть четным числом, 0 или отрицательные числа не масштабируются
*
* @param scale_height: увеличить масштаб, Должно быть четное число, 0 или отрицательные числа не масштабируются
*
* @param scale_filter_mode: качество масштабирования, Введите 0 и используйте скорость по умолчанию. Дополнительный диапазон уровней: [1,3]. Чем больше значение, тем лучше качество масштабирования. Но чем медленнее скорость
*
* @param rotation_degree: вращать по часовой стрелке, Должно быть 0, 90, 180, 270, Примечание. Вращение масштабирует, Сделайте это после вертикальной/водной инверсии, Пожалуйста, обратите внимание на заказ
*
* @return {0} if successful
*/
public native int PostLayerImageYUV420888ByteBuffer(long handle, int index, int left, int top,
ByteBuffer y_plane, int y_offset, int y_row_stride,
ByteBuffer u_plane, int u_offset, int u_row_stride,
ByteBuffer v_plane, int v_offset, int v_row_stride, int uv_pixel_stride,
int width, int height, int is_vertical_flip, int is_horizontal_flip,
int scale_width, int scale_height, int scale_filter_mode,
int rotation_degree);
Интерфейс данных YV12 в основном используется для стыковки со сторонними устройствами. u_stride и v_stride этого интерфейса равны (width+1)/2 соответственно. Если исходящие данные необходимо повернуть, угол поворота можно контролировать с помощью Rotate_grade. .
/**
* Интерфейс данных YV12
*
* @param data: YV12 data
*
* @param width: ширина изображения
*
* @param height: высота изображения
*
* @param y_stride: размер шага в сторону
*
* @param v_stride: размер шага v-стороны
*
* @param u_stride: длина шага U-образного лица
*
* rotation_degree: вращать по часовой стрелке, Должно быть 0, 90, 180, 270
*
* @return {0} if successful
*/
public native int SmartPublisherOnYV12Data(long handle, byte[] data, int width, int height, int y_stride, int v_stride, int u_stride, int rotation_degree);
Поддерживает стандартную стыковку интерфейса данных I420, нет необходимости вдаваться в подробности:
/**
* Уровень доставки изображения I420
*
* @param index: индекс слоя, Должно быть больше или равно 0
*
* @param left: Координаты верхнего левого угла наложения слоя, Для слоя 0 передайте 0
*
* @param top: Координаты верхнего левого угла наложения слоя, Для слоя 0 передайте 0
*
* @param y_plane: данные изображения в плоскости Y
*
* @param y_offset: смещение изображения, Основная цель этого — создание клипов. Обычно передается 0.
*
* @param y_row_stride: stride information
*
* @param u_plane: данные изображения самолета u
*
* @param u_offset: смещение изображения, Основная цель этого — создание клипов. Обычно передается 0.
*
* @param u_row_stride: stride information
* *
* @param v_plane: данные изображения v плоскости
*
* @param v_offset: смещение изображения, Основная цель этого — создание клипов. Обычно передается 0.
*
* @param v_row_stride: stride information
*
* @param width: width, Должно быть больше 1, и должно быть четное число
*
* @param height: height, Должно быть больше 1, и должно быть четное число
*
* @param is_vertical_flip: Стоит ли переворачивать вертикально, 0 не переворачивается, 1 флип
*
* @param is_horizontal_flip: переворачивать ли по горизонтали, 0 не переворачивается, 1 флип
*
* @param scale_width: Ширина шкалы должна быть четным числом, 0 или отрицательные числа не масштабируются
*
* @param scale_height: увеличить масштаб, Должно быть четное число, 0 или отрицательные числа не масштабируются
*
* @param scale_filter_mode: качество масштабирования, Введите 0 и используйте скорость по умолчанию. Дополнительный диапазон уровней: [1,3]. Чем больше значение, тем лучше качество масштабирования. Но чем медленнее скорость
*
* @param rotation_degree: вращать по часовой стрелке, Должно быть 0, 90, 180, 270, Примечание. Вращение масштабирует, Сделайте это после вертикальной/водной инверсии, Пожалуйста, обратите внимание на заказ
*
* @return {0} if successful
*/
public native int PostLayerImageI420ByteBuffer(long handle, int index, int left, int top,
ByteBuffer y_plane, int y_offset, int y_row_stride,
ByteBuffer u_plane, int u_offset, int u_row_stride,
ByteBuffer v_plane, int v_offset, int v_row_stride,
int width, int height, int is_vertical_flip, int is_horizontal_flip,
int scale_width, int scale_height, int scale_filter_mode,
int rotation_degree);
Этот интерфейс также в основном используется для стыковки определенных типов данных. Данные NV21 можно напрямую передавать в I420, а затем стыковать. Параметры интерфейса относительно просты и не будут описываться подробно.
/**
* NV21 преобразован в I420 и повернут
*
* @param src: nv21 data
*
* @param dst: Выход I420 data
*
* @param width: ширина изображения
*
* @param height: высота изображения
*
* rotation_degree: вращать по часовой стрелке, Должно быть 0, 90, 180, 270
*
* @return {0} if successful
*/
public native int SmartPublisherNV21ToI420Rotate(long handle, byte[] src, int src_y_stride, int src_uv_stride, byte[] dst,
int dst_y_stride, int dst_u_stride, int dst_v_stride,
int width, int height,
int rotation_degree);
RGBA в основном используется в сценариях совместного использования экрана.
/**
* Set live video data(no encoded data).
*
* @param data: RGBA data
*
* @param rowStride: stride information
*
* @param width: width
*
* @param height: height
*
* @return {0} if successful
*/
public native int SmartPublisherOnCaptureVideoRGBAData(long handle, ByteBuffer data, int rowStride, int width, int height);
/**
* Доставка обрезанных данных RGBA
*
* @param data: RGBA data
*
* @param rowStride: stride information
*
* @param width: width
*
* @param height: height
*
* @param clipedLeft: левый; clipedTop: начальство; clipedwidth: Ширина после обрезки; clipedHeight: Высота после обрезки; Убедитесь, что ширина и высота после обрезки являются четными числами.
*
* @return {0} if successful
*/
public native int SmartPublisherOnCaptureVideoClipedRGBAData(long handle, ByteBuffer data, int rowStride, int width, int height, int clipedLeft, int clipedTop, int clipedWidth, int clipedHeight);
/**
* Set live video data(no encoded data).
*
* @param data: ABGR flip вертикальный (перевернуть вертикально) data
*
* @param rowStride: stride information
*
* @param width: width
*
* @param height: height
*
* @return {0} if successful
*/
public native int SmartPublisherOnCaptureVideoABGRFlipVerticalData(long handle, ByteBuffer data, int rowStride, int width, int height);
Тип данных RGB565 также в основном используется для захвата экрана.
/**
* Set live video data(no encoded data).
*
* @param data: RGB565 data
*
* @param row_stride: stride information
*
* @param width: width
*
* @param height: height
*
* @return {0} if successful
*/
public native int SmartPublisherOnCaptureVideoRGB565Data(long handle,ByteBuffer data, int row_stride, int width, int height);
/**
* Уровень доставки изображения NV21
*
* @param index: индекс слоя, Должно быть больше или равно 0
*
* @param left: Координаты верхнего левого угла наложения слоя, Для слоя 0 передайте 0
*
* @param top: Координаты верхнего левого угла наложения слоя, Для слоя 0 передайте 0
*
* @param y_plane: данные изображения в плоскости Y
*
* @param y_offset: смещение изображения, Основная цель этого — создание клипов. Обычно передается 0.
*
* @param y_row_stride: stride information
*
* @param uv_plane: uданные изображения v плоскости
*
* @param uv_offset: смещение изображения, Основная цель этого — создание клипов. Обычно передается 0.
*
* @param uv_row_stride: stride information
*
* @param width: width, Должно быть больше 1, и должно быть четное число
*
* @param height: height, Должно быть больше 1, и должно быть четное число
*
* @param is_vertical_flip: Стоит ли переворачивать вертикально, 0 не переворачивается, 1 флип
*
* @param is_horizontal_flip: переворачивать ли по горизонтали, 0 не переворачивается, 1 флип
*
* @param scale_width: Ширина шкалы должна быть четным числом, 0 или отрицательные числа не масштабируются
*
* @param scale_height: увеличить масштаб, Должно быть четное число, 0 или отрицательные числа не масштабируются
*
* @param scale_filter_mode: качество масштабирования, Введите 0 и используйте скорость по умолчанию. Дополнительный диапазон уровней: [1,3]. Чем больше значение, тем лучше качество масштабирования. Но чем медленнее скорость
*
* @param rotation_degree: вращать по часовой стрелке, Должно быть 0, 90, 180, 270, Примечание. Вращение масштабирует, Сделайте это после вертикальной/водной инверсии, Пожалуйста, обратите внимание на заказ
*
* @return {0} if successful
*/
public native int PostLayerImageNV21ByteBuffer(long handle, int index, int left, int top,
ByteBuffer y_plane, int y_offset, int y_row_stride,
ByteBuffer uv_plane, int uv_offset, int uv_row_stride,
int width, int height, int is_vertical_flip, int is_horizontal_flip,
int scale_width, int scale_height, int scale_filter_mode,
int rotation_degree);
/**
* Уровень доставки изображения NV21, Подробные инструкции см. в PostLayerImageNV21ByteBuffer.
*
* @return {0} if successful
*/
public native int PostLayerImageNV21ByteArray(long handle, int index, int left, int top,
byte[] y_plane, int y_offset, int y_row_stride,
byte[] uv_plane, int uv_offset, int uv_row_stride,
int width, int height, int is_vertical_flip, int is_horizontal_flip,
int scale_width, int scale_height, int scale_filter_mode,
int rotation_degree);
/**
* Образ уровня доставки NV12, Подробные инструкции см. в PostLayerImageNV21ByteBuffer.
*
* @return {0} if successful
*/
public native int PostLayerImageNV12ByteBuffer(long handle, int index, int left, int top,
ByteBuffer y_plane, int y_offset, int y_row_stride,
ByteBuffer uv_plane, int uv_offset, int uv_row_stride,
int width, int height, int is_vertical_flip, int is_horizontal_flip,
int scale_width, int scale_height, int scale_filter_mode,
int rotation_degree);
/**
* Образ уровня доставки NV12, Подробные инструкции см. в PostLayerImageNV21ByteBuffer.
*
* @return {0} if successful
*/
public native int PostLayerImageNV12ByteArray(long handle, int index, int left, int top,
byte[] y_plane, int y_offset, int y_row_stride,
byte[] uv_plane, int uv_offset, int uv_row_stride,
int width, int height, int is_vertical_flip, int is_horizontal_flip,
int scale_width, int scale_height, int scale_filter_mode,
int rotation_degree);
/**
* Изображение слоя доставки RGBA8888, если альфа-канал не требуется, Пожалуйста, используйте интерфейс RGBX8888, Высокая эффективность
*
* @param index: индекс слоя, Должно быть больше или равно 0, Примечание. Если индекс равен 0, альфа-канал будет игнорироваться.
*
* @param left: Координаты верхнего левого угла наложения слоя, Для слоя 0 передайте 0
*
* @param top: Координаты верхнего левого угла наложения слоя, Для слоя 0 передайте 0
*
* @param rgba_plane: rgba данные изображения
*
* @param offset: смещение изображения, Основная цель - создание клипов. Обычно проходит 0
*
* @param row_stride: stride information
*
* @param width: width, Должно быть больше 1, Если это нечетное число, будет уменьшено на 1
*
* @param height: height, Должно быть больше 1, Если это нечетное число, будет уменьшено на 1
*
* @param is_vertical_flip: Стоит ли переворачивать вертикально, 0 не переворачивается, 1 флип
*
* @param is_horizontal_flip: переворачивать ли по горизонтали, 0 не переворачивается, 1 флип
*
* @param scale_width: Ширина шкалы должна быть четным числом, 0 или отрицательные числа не масштабируются
*
* @param scale_height: увеличить масштаб, Должно быть четное число, 0 или отрицательные числа не масштабируются
*
* @param scale_filter_mode: качество масштабирования, Введите 0 и используйте скорость по умолчанию. Дополнительный диапазон уровней: [1,3]. Чем больше значение, тем лучше качество масштабирования. Но чем медленнее скорость
*
* @param rotation_degree: вращать по часовой стрелке, Должно быть 0, 90, 180, 270, Примечание. Вращение масштабирует, Сделайте это после вертикальной/водной инверсии, Пожалуйста, обратите внимание на заказ
*
* @return {0} if successful
*/
public native int PostLayerImageRGBA8888ByteBuffer(long handle, int index, int left, int top,
ByteBuffer rgba_plane, int offset, int row_stride, int width, int height,
int is_vertical_flip, int is_horizontal_flip,
int scale_width, int scale_height, int scale_filter_mode,
int rotation_degree);
/**
* Уровень доставки изображения RGBA8888, Подробные инструкции см. в PostLayerImageRGBA8888ByteBuffer.
*
* @return {0} if successful
*/
public native int PostLayerImageRGBA8888ByteArray(long handle, int index, int left, int top,
byte[] rgba_plane, int offset, int row_stride, int width, int height,
int is_vertical_flip, int is_horizontal_flip,
int scale_width, int scale_height, int scale_filter_mode,
int rotation_degree);
/**
* Уровень доставки изображения RGBA8888, Подробные инструкции см. в PostLayerImageRGBA8888ByteBuffer.
*
* @return {0} if successful
*/
public native int PostLayerImageRGBA8888Native(long handle, int index, int left, int top,
long rgba_plane, int offset, int row_stride, int width, int height,
int is_vertical_flip, int is_horizontal_flip,
int scale_width, int scale_height, int scale_filter_mode,
int rotation_degree);
/**
* Уровень доставки изображения RGBX8888
*
* @param index: индекс слоя, Должно быть больше или равно 0
*
* @param left: Координаты верхнего левого угла наложения слоя, Для слоя 0 передайте 0
*
* @param top: Координаты верхнего левого угла наложения слоя, Для слоя 0 передайте 0
*
* @param rgbx_plane: rgbx данные изображения
*
* @param offset: смещение изображения, Основная цель этого — создание клипов. Обычно передается 0.
*
* @param row_stride: stride information
*
* @param width: width, Должно быть больше 1, Если это нечетное число, будет уменьшено на 1
*
* @param height: height, Должно быть больше 1, Если это нечетное число, будет уменьшено на 1
*
* @param is_vertical_flip: Стоит ли переворачивать вертикально, 0 не переворачивается, 1 флип
*
* @param is_horizontal_flip: переворачивать ли по горизонтали, 0 не переворачивается, 1 флип
*
* @param scale_width: Ширина шкалы должна быть четным числом, 0 или отрицательные числа не масштабируются
*
* @param scale_height: увеличить масштаб, Должно быть четное число, 0 или отрицательные числа не масштабируются
*
* @param scale_filter_mode: качество масштабирования, Введите 0 и используйте скорость по умолчанию. Дополнительный диапазон уровней: [1,3]. Чем больше значение, тем лучше качество масштабирования. Но чем медленнее скорость
*
* @param rotation_degree: вращать по часовой стрелке, Должно быть 0, 90, 180, 270, Примечание. Вращение масштабирует, Сделайте это после вертикальной/водной инверсии, Пожалуйста, обратите внимание на заказ
*
* @return {0} if successful
*/
public native int PostLayerImageRGBX8888ByteBuffer(long handle, int index, int left, int top,
ByteBuffer rgbx_plane, int offset, int row_stride, int width, int height,
int is_vertical_flip, int is_horizontal_flip,
int scale_width, int scale_height, int scale_filter_mode,
int rotation_degree);
/**
* Уровень доставки изображения RGBX8888, Подробные инструкции см. в PostLayerImageRGBX8888ByteBuffer.
*
* @return {0} if successful
*/
public native int PostLayerImageRGBX8888ByteArray(long handle, int index, int left, int top,
byte[] rgbx_plane, int offset, int row_stride, int width, int height,
int is_vertical_flip, int is_horizontal_flip,
int scale_width, int scale_height, int scale_filter_mode,
int rotation_degree);
/**
* Уровень доставки изображения RGBX8888, Подробные инструкции см. в PostLayerImageRGBX8888ByteBuffer.
*
* @return {0} if successful
*/
public native int PostLayerImageRGBX8888Native(long handle, int index, int left, int top,
long rgbx_plane, int offset, int row_stride, int width, int height,
int is_vertical_flip, int is_horizontal_flip,
int scale_width, int scale_height, int scale_filter_mode,
int rotation_degree);
/**
* Уровень доставки изображения RGB888
*
* @param index: индекс слоя, Должно быть больше или равно 0
*
* @param left: Координаты верхнего левого угла наложения слоя, Для слоя 0 передайте 0
*
* @param top: Координаты верхнего левого угла наложения слоя, Для слоя 0 передайте 0
*
* @param rgb_plane: rgb888 данные изображения
*
* @param offset: смещение изображения, Основная цель этого — создание клипов. Обычно передается 0.
*
* @param row_stride: stride information
*
* @param width: width, Должно быть больше 1, Если это нечетное число, будет уменьшено на 1
*
* @param height: height, Должно быть больше 1, Если это нечетное число, будет уменьшено на 1
*
* @param is_vertical_flip: Стоит ли переворачивать вертикально, 0 не переворачивается, 1 флип
*
* @param is_horizontal_flip: переворачивать ли по горизонтали, 0 не переворачивается, 1 флип
*
* @param scale_width: Ширина шкалы должна быть четным числом, 0 или отрицательные числа не масштабируются
*
* @param scale_height: увеличить масштаб, Должно быть четное число, 0 или отрицательные числа не масштабируются
*
* @param scale_filter_mode: качество масштабирования, Введите 0 и используйте скорость по умолчанию. Дополнительный диапазон уровней: [1,3]. Чем больше значение, тем лучше качество масштабирования. Но чем медленнее скорость
*
* @param rotation_degree: вращать по часовой стрелке, Должно быть 0, 90, 180, 270, Примечание. Вращение масштабирует, Сделайте это после вертикальной/водной инверсии, Пожалуйста, обратите внимание на заказ
*
* @return {0} if successful
*/
public native int PostLayerImageRGB888Native(long handle, int index, int left, int top,
long rgb_plane, int offset, int row_stride, int width, int height,
int is_vertical_flip, int is_horizontal_flip,
int scale_width, int scale_height, int scale_filter_mode,
int rotation_degree);