Files
hardware_samsung_slsi-linar…/videocodec/osal/ExynosVideo_OSAL.c
Sam Protsenko d70d919c01 Add original Samsung hardware projects
Change-Id: I79380bc91acf57ca5f3e56fb64af76f4c45f6566
Signed-off-by: Sam Protsenko <joe.skb7@gmail.com>
2023-09-09 08:33:16 +02:00

2164 lines
96 KiB
C

/*
*
* Copyright 2016 Samsung Electronics S.LSI Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* @file ExynosVideo_OSAL.c
* @brief ExynosVideo OSAL
* @author SeungBeom Kim (sbcrux.kim@samsung.com)
* Taehwan Kim (t_h.kim@samsung.com)
* @version 1.0.0
* @history
* 2016.01.07 : Create
*/
#include <string.h>
#include <sys/mman.h>
#include "ExynosVideo_OSAL.h"
#include "ExynosVideo_OSAL_Dec.h"
#include "ExynosVideo_OSAL_Enc.h"
#include "ExynosVideoDec.h"
#include "ExynosVideoEnc.h"
/* #define LOG_NDEBUG 0 */
#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "ExynosVideoOSAL"
#define GET_16BIT_HIGH(x) ((x >> 16) & 0xFFFF)
#define GET_16BIT_LOW(x) (x & 0xFFFF)
#define SET_16BIT_TO_HIGH(x) ((0xFFFF & x) << 16)
static struct {
int primaries;
int transfer;
int coeff;
} ColorSpaceToColorAspects[] =
{
{PRIMARIES_UNSPECIFIED, TRANSFER_UNSPECIFIED, MATRIX_COEFF_UNSPECIFIED}, /* Unknown */
{PRIMARIES_BT601_6_525, TRANSFER_SMPTE_170M, MATRIX_COEFF_SMPTE170M}, /* Rec. ITU-R BT.601-7 */
{PRIMARIES_BT709_5, TRANSFER_SMPTE_170M, MATRIX_COEFF_REC709}, /* Rec. ITU-R BT.709-6 */
{PRIMARIES_BT601_6_525, TRANSFER_SMPTE_170M, MATRIX_COEFF_SMPTE170M}, /* SMPTE-170 */
{PRIMARIES_BT601_6_525, TRANSFER_SMPTE_240M, MATRIX_COEFF_SMPTE240M}, /* SMPTE-240 */
{PRIMARIES_BT2020, TRANSFER_SMPTE_170M, MATRIX_COEFF_BT2020}, /* Rec. ITU-R BT.2020-2 */
{PRIMARIES_RESERVED, TRANSFER_RESERVED, MATRIX_COEFF_IDENTITY}, /* Reserved */
{PRIMARIES_RESERVED, TRANSFER_SMPTE_170M, MATRIX_COEFF_REC709}, /* sRGB (IEC 61966-2-1) */
};
int Codec_OSAL_VideoMemoryToSystemMemory(
ExynosVideoMemoryType eMemoryType)
{
if (eMemoryType == VIDEO_MEMORY_DMABUF)
return V4L2_MEMORY_DMABUF;
if (eMemoryType == VIDEO_MEMORY_USERPTR)
return V4L2_MEMORY_USERPTR;
return V4L2_MEMORY_MMAP;
}
unsigned int Codec_OSAL_CodingTypeToCompressdFormat(
ExynosVideoCodingType eCodingType)
{
unsigned int nCompressdFormat = V4L2_PIX_FMT_H264;
switch (eCodingType) {
case VIDEO_CODING_AVC:
nCompressdFormat = V4L2_PIX_FMT_H264;
break;
case VIDEO_CODING_MPEG4:
nCompressdFormat = V4L2_PIX_FMT_MPEG4;
break;
case VIDEO_CODING_VP8:
nCompressdFormat = V4L2_PIX_FMT_VP8;
break;
case VIDEO_CODING_H263:
nCompressdFormat = V4L2_PIX_FMT_H263;
break;
case VIDEO_CODING_VC1:
nCompressdFormat = V4L2_PIX_FMT_VC1_ANNEX_G;
break;
case VIDEO_CODING_VC1_RCV:
nCompressdFormat = V4L2_PIX_FMT_VC1_ANNEX_L;
break;
case VIDEO_CODING_MPEG2:
nCompressdFormat = V4L2_PIX_FMT_MPEG2;
break;
case VIDEO_CODING_HEVC:
nCompressdFormat = V4L2_PIX_FMT_HEVC;
break;
case VIDEO_CODING_VP9:
nCompressdFormat = V4L2_PIX_FMT_VP9;
break;
default:
nCompressdFormat = V4L2_PIX_FMT_H264;
break;
}
return nCompressdFormat;
}
ExynosVideoColorFormatType Codec_OSAL_PixelFormatToColorFormat(
unsigned int nPixelFormat)
{
ExynosVideoColorFormatType eColorFormat = VIDEO_COLORFORMAT_NV12_TILED;
switch (nPixelFormat) {
case V4L2_PIX_FMT_NV12M:
eColorFormat = VIDEO_COLORFORMAT_NV12M;
break;
case V4L2_PIX_FMT_NV12M_S10B:
eColorFormat = VIDEO_COLORFORMAT_NV12M_S10B;
break;
case V4L2_PIX_FMT_NV12M_P010:
eColorFormat = VIDEO_COLORFORMAT_NV12M_P010;
break;
case V4L2_PIX_FMT_NV21M:
eColorFormat = VIDEO_COLORFORMAT_NV21M;
break;
case V4L2_PIX_FMT_NV21M_S10B:
eColorFormat = VIDEO_COLORFORMAT_NV21M_S10B;
break;
case V4L2_PIX_FMT_NV21M_P010:
eColorFormat = VIDEO_COLORFORMAT_NV21M_P010;
break;
case V4L2_PIX_FMT_YUV420M:
eColorFormat = VIDEO_COLORFORMAT_I420M;
break;
case V4L2_PIX_FMT_YVU420M:
eColorFormat = VIDEO_COLORFORMAT_YV12M;
break;
case V4L2_PIX_FMT_NV12M_SBWC_8B:
eColorFormat = VIDEO_COLORFORMAT_NV12M_SBWC;
break;
case V4L2_PIX_FMT_NV12M_SBWC_10B:
eColorFormat = VIDEO_COLORFORMAT_NV12M_10B_SBWC;
break;
case V4L2_PIX_FMT_NV21M_SBWC_8B:
eColorFormat = VIDEO_COLORFORMAT_NV21M_SBWC;
break;
case V4L2_PIX_FMT_NV21M_SBWC_10B:
eColorFormat = VIDEO_COLORFORMAT_NV21M_10B_SBWC;
break;
#ifdef USE_SINGLE_PALNE_SUPPORT
case V4L2_PIX_FMT_NV12N:
eColorFormat = VIDEO_COLORFORMAT_NV12;
break;
case V4L2_PIX_FMT_NV12N_10B:
eColorFormat = VIDEO_COLORFORMAT_NV12_S10B;
break;
case V4L2_PIX_FMT_YUV420N:
eColorFormat = VIDEO_COLORFORMAT_I420;
break;
case V4L2_PIX_FMT_NV12NT:
eColorFormat = VIDEO_COLORFORMAT_NV12_TILED;
break;
case V4L2_PIX_FMT_NV12N_SBWC_8B:
eColorFormat = VIDEO_COLORFORMAT_NV12_SBWC;
break;
case V4L2_PIX_FMT_NV12N_SBWC_10B:
eColorFormat = VIDEO_COLORFORMAT_NV12_10B_SBWC;
break;
#endif
case V4L2_PIX_FMT_ARGB32:
eColorFormat = VIDEO_COLORFORMAT_ARGB8888;
break;
case V4L2_PIX_FMT_BGR32:
eColorFormat = VIDEO_COLORFORMAT_BGRA8888;
break;
case V4L2_PIX_FMT_RGB32X:
eColorFormat = VIDEO_COLORFORMAT_RGBA8888;
break;
case V4L2_PIX_FMT_NV12MT:
case V4L2_PIX_FMT_NV12MT_16X16:
default:
eColorFormat = VIDEO_COLORFORMAT_NV12M_TILED;
break;
}
return eColorFormat;
}
unsigned int Codec_OSAL_ColorFormatToPixelFormat(
ExynosVideoColorFormatType eColorFormat,
int nHwVersion)
{
unsigned int nPixelFormat = V4L2_PIX_FMT_NV12M;
switch (eColorFormat) {
case VIDEO_COLORFORMAT_NV12M:
nPixelFormat = V4L2_PIX_FMT_NV12M;
break;
case VIDEO_COLORFORMAT_NV12M_S10B:
nPixelFormat = V4L2_PIX_FMT_NV12M_S10B;
break;
case VIDEO_COLORFORMAT_NV12M_P010:
nPixelFormat = V4L2_PIX_FMT_NV12M_P010;
break;
case VIDEO_COLORFORMAT_NV21M:
nPixelFormat = V4L2_PIX_FMT_NV21M;
break;
case VIDEO_COLORFORMAT_NV21M_S10B:
nPixelFormat = V4L2_PIX_FMT_NV21M_S10B;
break;
case VIDEO_COLORFORMAT_NV21M_P010:
nPixelFormat = V4L2_PIX_FMT_NV21M_P010;
break;
case VIDEO_COLORFORMAT_I420M:
nPixelFormat = V4L2_PIX_FMT_YUV420M;
break;
case VIDEO_COLORFORMAT_YV12M:
nPixelFormat = V4L2_PIX_FMT_YVU420M;
break;
case VIDEO_COLORFORMAT_NV12M_SBWC:
nPixelFormat = V4L2_PIX_FMT_NV12M_SBWC_8B;
break;
case VIDEO_COLORFORMAT_NV12M_10B_SBWC:
nPixelFormat = V4L2_PIX_FMT_NV12M_SBWC_10B;
break;
case VIDEO_COLORFORMAT_NV21M_SBWC:
nPixelFormat = V4L2_PIX_FMT_NV21M_SBWC_8B;
break;
case VIDEO_COLORFORMAT_NV21M_10B_SBWC:
nPixelFormat = V4L2_PIX_FMT_NV21M_SBWC_10B;
break;
case VIDEO_COLORFORMAT_NV12M_SBWC_L50:
case VIDEO_COLORFORMAT_NV12M_SBWC_L75:
nPixelFormat = V4L2_PIX_FMT_NV12M_SBWCL_8B;
break;
case VIDEO_COLORFORMAT_NV12M_10B_SBWC_L40:
case VIDEO_COLORFORMAT_NV12M_10B_SBWC_L60:
case VIDEO_COLORFORMAT_NV12M_10B_SBWC_L80:
nPixelFormat = V4L2_PIX_FMT_NV12M_SBWCL_10B;
break;
#ifdef USE_SINGLE_PALNE_SUPPORT
case VIDEO_COLORFORMAT_NV12:
nPixelFormat = V4L2_PIX_FMT_NV12N;
break;
case VIDEO_COLORFORMAT_NV12_S10B:
nPixelFormat = V4L2_PIX_FMT_NV12N_10B;
break;
case VIDEO_COLORFORMAT_I420:
nPixelFormat = V4L2_PIX_FMT_YUV420N;
break;
case VIDEO_COLORFORMAT_NV12_TILED:
nPixelFormat = V4L2_PIX_FMT_NV12NT;
break;
case VIDEO_COLORFORMAT_NV12_SBWC:
nPixelFormat = V4L2_PIX_FMT_NV12N_SBWC_8B;
break;
case VIDEO_COLORFORMAT_NV12_10B_SBWC:
nPixelFormat = V4L2_PIX_FMT_NV12N_SBWC_10B;
break;
case VIDEO_COLORFORMAT_NV12_SBWC_L50:
case VIDEO_COLORFORMAT_NV12_SBWC_L75:
nPixelFormat = V4L2_PIX_FMT_NV12N_SBWCL_8B;
break;
case VIDEO_COLORFORMAT_NV12_10B_SBWC_L40:
case VIDEO_COLORFORMAT_NV12_10B_SBWC_L60:
case VIDEO_COLORFORMAT_NV12_10B_SBWC_L80:
nPixelFormat = V4L2_PIX_FMT_NV12N_SBWCL_10B;
break;
#endif
case VIDEO_COLORFORMAT_ARGB8888:
nPixelFormat = V4L2_PIX_FMT_ARGB32;
break;
case VIDEO_COLORFORMAT_BGRA8888:
nPixelFormat = V4L2_PIX_FMT_BGR32;
break;
case VIDEO_COLORFORMAT_RGBA8888:
nPixelFormat = V4L2_PIX_FMT_RGB32X;
break;
case VIDEO_COLORFORMAT_NV12M_TILED:
if (nHwVersion == (int)MFC_51)
nPixelFormat = V4L2_PIX_FMT_NV12MT;
else
nPixelFormat = V4L2_PIX_FMT_NV12MT_16X16;
break;
default:
nPixelFormat = V4L2_PIX_FMT_NV12M;
break;
}
return nPixelFormat;
}
int Codec_OSAL_DevOpen(
const char *sDevName,
int nFlag,
CodecOSALVideoContext *pCtx)
{
if ((sDevName != NULL) &&
(pCtx != NULL)) {
pCtx->videoCtx.hDevice = exynos_v4l2_open_devname(sDevName, nFlag, 0);
return pCtx->videoCtx.hDevice;
}
return -1;
}
void Codec_OSAL_DevClose(CodecOSALVideoContext *pCtx)
{
if ((pCtx != NULL) &&
(pCtx->videoCtx.hDevice >= 0)) {
exynos_v4l2_close(pCtx->videoCtx.hDevice);
}
return;
}
int Codec_OSAL_QueryCap(CodecOSALVideoContext *pCtx)
{
int needCaps = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING);
if ((pCtx != NULL) &&
(pCtx->videoCtx.hDevice >= 0)) {
if (exynos_v4l2_querycap(pCtx->videoCtx.hDevice, needCaps))
return 0;
}
return -1;
}
int Codec_OSAL_EnqueueBuf(
CodecOSALVideoContext *pCtx,
CodecOSAL_Buffer *pBuf)
{
if ((pCtx != NULL) &&
(pBuf != NULL) &&
(pCtx->videoCtx.hDevice >= 0)) {
struct v4l2_buffer buf;
struct v4l2_plane planes[VIDEO_BUFFER_MAX_PLANES];
int i;
unsigned int nCID;
memset(&buf, 0, sizeof(buf));
memset(&planes, 0, sizeof(planes));
buf.type = pBuf->type;
buf.m.planes = planes;
buf.length = pBuf->nPlane;
buf.memory = pBuf->memory;
buf.index = pBuf->index;
if (pCtx->videoCtx.bShareInbuf == VIDEO_TRUE) {
for (i = 0; i < pBuf->nPlane; i++) {
if ((unsigned int)buf.memory == (unsigned int)CODEC_OSAL_MEM_TYPE_USERPTR)
buf.m.planes[i].m.userptr = (unsigned long)pBuf->planes[i].addr;
else
buf.m.planes[i].m.fd = (int)(unsigned long)pBuf->planes[i].addr;
buf.m.planes[i].length = pBuf->planes[i].bufferSize;
buf.m.planes[i].bytesused = pBuf->planes[i].dataLen;
buf.m.planes[i].data_offset = 0;
}
} else {
for (i = 0; i < pBuf->nPlane; i++) {
buf.m.planes[i].bytesused = pBuf->planes[i].dataLen;
buf.m.planes[i].data_offset = 0;
}
}
#ifdef USE_ORIGINAL_HEADER
if (pCtx->videoCtx.bVideoBufFlagCtrl == VIDEO_TRUE) {
nCID = (buf.type == CODEC_OSAL_BUF_TYPE_SRC)? CODEC_OSAL_CID_VIDEO_SRC_BUF_FLAG:CODEC_OSAL_CID_VIDEO_DST_BUF_FLAG;
Codec_OSAL_SetControl(pCtx, nCID, pBuf->flags);
} else {
buf.reserved2 = pBuf->flags;
}
#else
buf.input = pBuf->flags;
#endif
memcpy(&(buf.timestamp), &(pBuf->timestamp), sizeof(struct timeval));
return exynos_v4l2_qbuf(pCtx->videoCtx.hDevice, &buf);
}
return -1;
}
int Codec_OSAL_DequeueBuf(
CodecOSALVideoContext *pCtx,
CodecOSAL_Buffer *pBuf)
{
if ((pCtx != NULL) &&
(pBuf != NULL) &&
(pCtx->videoCtx.hDevice >= 0)) {
struct v4l2_buffer buf;
struct v4l2_plane planes[VIDEO_BUFFER_MAX_PLANES];
int i;
unsigned int nCID;
memset(&buf, 0, sizeof(buf));
memset(&planes, 0, sizeof(planes));
buf.type = pBuf->type;
buf.m.planes = planes;
buf.length = pBuf->nPlane;
buf.memory = pBuf->memory;
if (exynos_v4l2_dqbuf(pCtx->videoCtx.hDevice, &buf) == 0) {
pBuf->index = buf.index;
#ifdef USE_ORIGINAL_HEADER
if (pCtx->videoCtx.bVideoBufFlagCtrl == VIDEO_TRUE) {
nCID = (buf.type == CODEC_OSAL_BUF_TYPE_SRC)? CODEC_OSAL_CID_VIDEO_SRC_BUF_FLAG:CODEC_OSAL_CID_VIDEO_DST_BUF_FLAG;
Codec_OSAL_GetControl(pCtx, nCID, (int*)&pBuf->flags);
} else {
pBuf->flags = buf.reserved2;
}
#else
pBuf->flags = buf.input;
#endif
pBuf->field = buf.field;
pBuf->timestamp = buf.timestamp;
for (i = 0; i < pBuf->nPlane; i++)
pBuf->planes[i].dataLen = buf.m.planes[i].bytesused;
switch (buf.flags & (0x7 << 3)) {
case V4L2_BUF_FLAG_KEYFRAME:
pBuf->frameType = VIDEO_FRAME_I;
break;
case V4L2_BUF_FLAG_PFRAME:
pBuf->frameType = VIDEO_FRAME_P;
break;
case V4L2_BUF_FLAG_BFRAME:
pBuf->frameType = VIDEO_FRAME_B;
break;
default:
pBuf->frameType = VIDEO_FRAME_OTHERS;
break;
};
if (buf.flags & V4L2_BUF_FLAG_ERROR)
pBuf->frameType |= VIDEO_FRAME_CORRUPT;
return 0;
}
}
return -1;
}
int Codec_OSAL_GetControls(
CodecOSALVideoContext *pCtx,
unsigned int nCID,
void *pInfo)
{
int ret = -1;
if ((pCtx != NULL) &&
(pInfo != NULL) &&
(pCtx->videoCtx.hDevice >= 0)) {
ret = 0;
switch (nCID) {
case CODEC_OSAL_CID_DEC_SEI_INFO:
{
ExynosVideoFramePacking *pFramePacking = (ExynosVideoFramePacking *)pInfo;
struct v4l2_ext_control ext_ctrl[FRAME_PACK_SEI_INFO_NUM];
struct v4l2_ext_controls ext_ctrls;
int seiAvailable, seiInfo, seiGridPos, i;
unsigned int seiArgmtId;
memset(pFramePacking, 0, sizeof(*pFramePacking));
memset(ext_ctrl, 0, sizeof(ext_ctrl));
ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
ext_ctrls.count = FRAME_PACK_SEI_INFO_NUM;
ext_ctrls.controls = ext_ctrl;
ext_ctrl[0].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL;
ext_ctrl[1].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRGMENT_ID;
ext_ctrl[2].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_INFO;
ext_ctrl[3].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_GRID_POS;
if (exynos_v4l2_g_ext_ctrl(pCtx->videoCtx.hDevice, &ext_ctrls) != 0) {
ret = -1;
goto EXIT;
}
seiAvailable = ext_ctrl[0].value;
seiArgmtId = ext_ctrl[1].value;
seiInfo = ext_ctrl[2].value;
seiGridPos = ext_ctrl[3].value;
pFramePacking->available = seiAvailable;
pFramePacking->arrangement_id = seiArgmtId;
pFramePacking->arrangement_cancel_flag = OPERATE_BIT(seiInfo, 0x1, 0);
pFramePacking->arrangement_type = OPERATE_BIT(seiInfo, 0x3f, 1);
pFramePacking->quincunx_sampling_flag = OPERATE_BIT(seiInfo, 0x1, 8);
pFramePacking->content_interpretation_type = OPERATE_BIT(seiInfo, 0x3f, 9);
pFramePacking->spatial_flipping_flag = OPERATE_BIT(seiInfo, 0x1, 15);
pFramePacking->frame0_flipped_flag = OPERATE_BIT(seiInfo, 0x1, 16);
pFramePacking->field_views_flag = OPERATE_BIT(seiInfo, 0x1, 17);
pFramePacking->current_frame_is_frame0_flag = OPERATE_BIT(seiInfo, 0x1, 18);
pFramePacking->frame0_grid_pos_x = OPERATE_BIT(seiGridPos, 0xf, 0);
pFramePacking->frame0_grid_pos_y = OPERATE_BIT(seiGridPos, 0xf, 4);
pFramePacking->frame1_grid_pos_x = OPERATE_BIT(seiGridPos, 0xf, 8);
pFramePacking->frame1_grid_pos_y = OPERATE_BIT(seiGridPos, 0xf, 12);
}
break;
case CODEC_OSAL_CID_DEC_HDR_INFO:
{
ExynosVideoHdrInfo *pHdrInfo = (ExynosVideoHdrInfo *)pInfo;
struct v4l2_ext_control ext_ctrl[HDR_INFO_NUM];
struct v4l2_ext_controls ext_ctrls;
int infoType = pHdrInfo->eValidType;
int i = 0;
memset(ext_ctrl, 0, (sizeof(struct v4l2_ext_control) * HDR_INFO_NUM));
ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
ext_ctrls.controls = ext_ctrl;
if (infoType & HDR_INFO_LIGHT) {
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_SEI_MAX_PIC_AVERAGE_LIGHT;
ext_ctrl[i + 1].id = V4L2_CID_MPEG_VIDEO_SEI_MAX_CONTENT_LIGHT;
i += 2;
}
if (infoType & HDR_INFO_LUMINANCE) {
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_SEI_MAX_DISPLAY_LUMINANCE;
ext_ctrl[i + 1].id = V4L2_CID_MPEG_VIDEO_SEI_MIN_DISPLAY_LUMINANCE;
ext_ctrl[i + 2].id = V4L2_CID_MPEG_VIDEO_SEI_WHITE_POINT;
ext_ctrl[i + 3].id = V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_0;
ext_ctrl[i + 4].id = V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_1;
ext_ctrl[i + 5].id = V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_2;
i += 6;
}
if (infoType & HDR_INFO_COLOR_ASPECTS) {
if (pCtx->videoCtx.instInfo.eCodecType == VIDEO_CODING_VP9) {
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES;
i++;
} else {
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_MATRIX_COEFFICIENTS;
ext_ctrl[i + 1].id = V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES;
ext_ctrl[i + 2].id = V4L2_CID_MPEG_VIDEO_TRANSFER_CHARACTERISTICS;
i += 3;
}
} else if (infoType & HDR_INFO_MATRIX_COEFF_ONLY) {
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_MATRIX_COEFFICIENTS;
i++;
}
if (infoType & HDR_INFO_RANGE) {
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG;
i++;
}
ext_ctrls.count = i;
if (exynos_v4l2_g_ext_ctrl(pCtx->videoCtx.hDevice, &ext_ctrls) != 0) {
ret = VIDEO_ERROR_APIFAIL;
goto EXIT;
}
i = 0;
pHdrInfo->eChangedType = HDR_INFO_NO_CHANGES | (pHdrInfo->eChangedType & HDR_INFO_DYNAMIC_META);
/* eType will be set when value is changed */
if (infoType & HDR_INFO_LIGHT) {
if ((pHdrInfo->sHdrStatic.max_pic_average_light != ext_ctrl[i].value) ||
(pHdrInfo->sHdrStatic.max_content_light != ext_ctrl[i + 1].value)) {
pHdrInfo->eChangedType |= HDR_INFO_LIGHT;
}
pHdrInfo->sHdrStatic.max_pic_average_light = ext_ctrl[i].value;
pHdrInfo->sHdrStatic.max_content_light = ext_ctrl[i + 1].value;
i += 2;
}
if (infoType & HDR_INFO_LUMINANCE) {
if ((pHdrInfo->sHdrStatic.max_display_luminance != ext_ctrl[i].value) ||
(pHdrInfo->sHdrStatic.min_display_luminance != ext_ctrl[i + 1].value) ||
(pHdrInfo->sHdrStatic.white.x != GET_16BIT_HIGH(ext_ctrl[i + 2].value)) ||
(pHdrInfo->sHdrStatic.white.y != GET_16BIT_LOW(ext_ctrl[i + 2].value)) ||
(pHdrInfo->sHdrStatic.green.x != GET_16BIT_HIGH(ext_ctrl[i + 3].value)) ||
(pHdrInfo->sHdrStatic.green.y != GET_16BIT_LOW(ext_ctrl[i + 3].value)) ||
(pHdrInfo->sHdrStatic.blue.x != GET_16BIT_HIGH(ext_ctrl[i + 4].value)) ||
(pHdrInfo->sHdrStatic.blue.y != GET_16BIT_LOW(ext_ctrl[i + 4].value)) ||
(pHdrInfo->sHdrStatic.red.x != GET_16BIT_HIGH(ext_ctrl[i + 5].value)) ||
(pHdrInfo->sHdrStatic.red.y != GET_16BIT_LOW(ext_ctrl[i + 5].value))) {
pHdrInfo->eChangedType |= HDR_INFO_LUMINANCE;
}
pHdrInfo->sHdrStatic.max_display_luminance = ext_ctrl[i].value;
pHdrInfo->sHdrStatic.min_display_luminance = ext_ctrl[i + 1].value;
pHdrInfo->sHdrStatic.white.x = GET_16BIT_HIGH(ext_ctrl[i + 2].value); /* [31:16] */
pHdrInfo->sHdrStatic.white.y = GET_16BIT_LOW(ext_ctrl[i + 2].value); /* [15:0] */
pHdrInfo->sHdrStatic.green.x = GET_16BIT_HIGH(ext_ctrl[i + 3].value);
pHdrInfo->sHdrStatic.green.y = GET_16BIT_LOW(ext_ctrl[i + 3].value);
pHdrInfo->sHdrStatic.blue.x = GET_16BIT_HIGH(ext_ctrl[i + 4].value);
pHdrInfo->sHdrStatic.blue.y = GET_16BIT_LOW(ext_ctrl[i + 4].value);
pHdrInfo->sHdrStatic.red.x = GET_16BIT_HIGH(ext_ctrl[i + 5].value);
pHdrInfo->sHdrStatic.red.y = GET_16BIT_LOW(ext_ctrl[i + 5].value);
i += 6;
}
if (infoType & HDR_INFO_COLOR_ASPECTS) {
if (pCtx->videoCtx.instInfo.eCodecType == VIDEO_CODING_VP9) {
if (((int)pHdrInfo->sColorAspects.eCoeffType != ColorSpaceToColorAspects[ext_ctrl[i].value].coeff) ||
((int)pHdrInfo->sColorAspects.ePrimariesType != ColorSpaceToColorAspects[ext_ctrl[i].value].primaries) ||
((int)pHdrInfo->sColorAspects.eTransferType != ColorSpaceToColorAspects[ext_ctrl[i].value].transfer)) {
pHdrInfo->eChangedType |= HDR_INFO_COLOR_ASPECTS;
}
pHdrInfo->sColorAspects.eCoeffType = (ExynosMatrixCoeffType)ColorSpaceToColorAspects[ext_ctrl[i].value].coeff;
pHdrInfo->sColorAspects.ePrimariesType = (ExynosPrimariesType)ColorSpaceToColorAspects[ext_ctrl[i].value].primaries;
pHdrInfo->sColorAspects.eTransferType = (ExynosTransferType)ColorSpaceToColorAspects[ext_ctrl[i].value].transfer;
i++;
} else {
if (((int)pHdrInfo->sColorAspects.eCoeffType != ext_ctrl[i].value) ||
((int)pHdrInfo->sColorAspects.ePrimariesType != ext_ctrl[i + 1].value) ||
((int)pHdrInfo->sColorAspects.eTransferType != ext_ctrl[i + 2].value)) {
pHdrInfo->eChangedType |= HDR_INFO_COLOR_ASPECTS;
}
pHdrInfo->sColorAspects.eCoeffType = (ExynosMatrixCoeffType)ext_ctrl[i].value;
pHdrInfo->sColorAspects.ePrimariesType = (ExynosPrimariesType)ext_ctrl[i + 1].value;
pHdrInfo->sColorAspects.eTransferType = (ExynosTransferType)ext_ctrl[i + 2].value;
i += 3;
}
} else if (infoType & HDR_INFO_MATRIX_COEFF_ONLY) {
if ((int)pHdrInfo->sColorAspects.eCoeffType != ext_ctrl[i].value) {
pHdrInfo->eChangedType |= HDR_INFO_MATRIX_COEFF_ONLY;
}
pHdrInfo->sColorAspects.eCoeffType = (ExynosMatrixCoeffType)ext_ctrl[i].value;
i++;
}
if (infoType & HDR_INFO_RANGE) {
ExynosRangeType eRangeType = RANGE_UNSPECIFIED;
eRangeType = (ExynosRangeType)((ext_ctrl[i].value == 0)? RANGE_LIMITED:RANGE_FULL);
if (pHdrInfo->sColorAspects.eRangeType != eRangeType) {
pHdrInfo->eChangedType |= HDR_INFO_RANGE;
}
pHdrInfo->sColorAspects.eRangeType = eRangeType;
i++;
}
}
break;
default:
{
ALOGE("%s: unsupported type(%x)", __FUNCTION__, nCID);
ret = -1;
}
break;
}
}
EXIT:
return ret;
}
int Codec_OSAL_SetControls(
CodecOSALVideoContext *pCtx,
unsigned int nCID,
void *pInfo)
{
int ret = -1;
if ((pCtx != NULL) &&
(pInfo != NULL) &&
(pCtx->videoCtx.hDevice >= 0)) {
ret = 0;
switch (nCID) {
case CODEC_OSAL_CID_ENC_SET_PARAMS:
{
ExynosVideoEncParam *pEncParam = (ExynosVideoEncParam *)pInfo;
ExynosVideoEncInitParam *pInitParam = &pEncParam->initParam;
ExynosVideoEncCommonParam *pCommonParam = &pEncParam->commonParam;
int i;
struct v4l2_ext_control ext_ctrl[MAX_CTRL_NUM];
struct v4l2_ext_controls ext_ctrls;
/* common parameters */
ext_ctrl[0].id = V4L2_CID_MPEG_VIDEO_GOP_SIZE;
ext_ctrl[0].value = (pCommonParam->IDRPeriod < 0)? 0:pCommonParam->IDRPeriod;
ext_ctrl[1].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
if ((pCtx->videoCtx.instInfo.supportInfo.enc.bFixedSliceSupport == VIDEO_TRUE) &&
(pCommonParam->bFixedSlice == VIDEO_TRUE) &&
(pCommonParam->SliceMode != 0)) {
ext_ctrl[1].value = 4; /* fixed bytes */
} else {
ext_ctrl[1].value = pCommonParam->SliceMode; /* 0: one, 1: fixed #mb, 2: fixed #bytes */
}
ext_ctrl[2].id = V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB;
ext_ctrl[2].value = pCommonParam->RandomIntraMBRefresh;
ext_ctrl[3].id = V4L2_CID_MPEG_MFC51_VIDEO_PADDING;
ext_ctrl[3].value = pCommonParam->PadControlOn;
ext_ctrl[4].id = V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV;
ext_ctrl[4].value = pCommonParam->CrPadVal;
ext_ctrl[4].value |= (pCommonParam->CbPadVal << 8);
ext_ctrl[4].value |= (pCommonParam->LumaPadVal << 16);
ext_ctrl[5].id = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE;
ext_ctrl[5].value = pCommonParam->EnableFRMRateControl;
ext_ctrl[6].id = V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE;
ext_ctrl[6].value = pCommonParam->EnableMBRateControl;
ext_ctrl[7].id = V4L2_CID_MPEG_VIDEO_BITRATE;
/* FIXME temporary fix */
if (pCommonParam->Bitrate)
ext_ctrl[7].value = pCommonParam->Bitrate;
else
ext_ctrl[7].value = 1; /* just for testing Movie studio */
/* codec specific parameters */
switch (pEncParam->eCompressionFormat) {
case VIDEO_CODING_AVC:
{
ExynosVideoEncH264Param *pH264Param = &pEncParam->codecParam.h264;
/* common parameters but id is depends on codec */
ext_ctrl[8].id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
ext_ctrl[8].value = pCommonParam->FrameQp;
ext_ctrl[9].id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
ext_ctrl[9].value = pCommonParam->FrameQp_P;
ext_ctrl[10].id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP; /* QP range : I frame */
ext_ctrl[10].value = GET_H264_QP_VALUE(pCommonParam->QpRange.QpMax_I);
ext_ctrl[11].id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
ext_ctrl[11].value = GET_H264_QP_VALUE(pCommonParam->QpRange.QpMin_I);
ext_ctrl[12].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
ext_ctrl[12].value = pCommonParam->CBRPeriodRf;
/* H.264 specific parameters */
switch (pCommonParam->SliceMode) {
case 0:
ext_ctrl[13].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
ext_ctrl[13].value = 1; /* default */
ext_ctrl[14].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
ext_ctrl[14].value = 2800; /* based on MFC6.x */
break;
case 1:
ext_ctrl[13].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
ext_ctrl[13].value = pH264Param->SliceArgument;
ext_ctrl[14].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
ext_ctrl[14].value = 2800; /* based on MFC6.x */
break;
case 2:
ext_ctrl[13].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
ext_ctrl[13].value = 1; /* default */
ext_ctrl[14].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
ext_ctrl[14].value = pH264Param->SliceArgument;
break;
default:
break;
}
ext_ctrl[15].id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
ext_ctrl[15].value = pH264Param->ProfileIDC;
ext_ctrl[16].id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
ext_ctrl[16].value = pH264Param->LevelIDC;
ext_ctrl[17].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P;
ext_ctrl[17].value = pH264Param->NumberRefForPframes;
/*
* It should be set using h264Param->NumberBFrames after being handled by appl.
*/
ext_ctrl[18].id = V4L2_CID_MPEG_VIDEO_B_FRAMES;
ext_ctrl[18].value = pH264Param->NumberBFrames;
ext_ctrl[19].id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE;
ext_ctrl[19].value = pH264Param->LoopFilterDisable;
ext_ctrl[20].id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA;
ext_ctrl[20].value = pH264Param->LoopFilterAlphaC0Offset;
ext_ctrl[21].id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA;
ext_ctrl[21].value = pH264Param->LoopFilterBetaOffset;
ext_ctrl[22].id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
ext_ctrl[22].value = pH264Param->SymbolMode;
ext_ctrl[23].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE;
ext_ctrl[23].value = pH264Param->PictureInterlace;
ext_ctrl[24].id = V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM;
ext_ctrl[24].value = pH264Param->Transform8x8Mode;
ext_ctrl[25].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE;
ext_ctrl[25].value = pH264Param->FrameRate;
ext_ctrl[26].id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
ext_ctrl[26].value = pH264Param->FrameQp_B;
ext_ctrl[27].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK;
ext_ctrl[27].value = pH264Param->DarkDisable;
ext_ctrl[28].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH;
ext_ctrl[28].value = pH264Param->SmoothDisable;
ext_ctrl[29].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC;
ext_ctrl[29].value = pH264Param->StaticDisable;
ext_ctrl[30].id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY;
ext_ctrl[30].value = pH264Param->ActivityDisable;
/* doesn't have to be set */
ext_ctrl[31].id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE;
ext_ctrl[31].value = 1;
ext_ctrl[32].id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD;
ext_ctrl[32].value = 0;
ext_ctrl[33].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
ext_ctrl[33].value = 0;
ext_ctrl[34].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
if (pH264Param->HeaderWithIFrame == 0) {
/* default */
ext_ctrl[34].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE; /* 0: seperated header */
} else {
ext_ctrl[34].value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME; /* 1: header + first frame */
}
ext_ctrl[35].id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE;
ext_ctrl[35].value = pH264Param->SarEnable;
ext_ctrl[36].id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC;
ext_ctrl[36].value = pH264Param->SarIndex;
ext_ctrl[37].id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH;
ext_ctrl[37].value = pH264Param->SarWidth;
ext_ctrl[38].id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT;
ext_ctrl[38].value = pH264Param->SarHeight;
/* Initial parameters : Frame Skip */
switch (pInitParam->FrameSkip) {
case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
ext_ctrl[39].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
ext_ctrl[39].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
break;
case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT:
ext_ctrl[39].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
ext_ctrl[39].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT;
break;
default:
/* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
ext_ctrl[39].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
ext_ctrl[39].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED;
break;
}
/* SVC is not supported yet */
ext_ctrl[40].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING;
ext_ctrl[40].value = 0;
switch (pH264Param->HierarType) {
case 1:
ext_ctrl[41].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE;
ext_ctrl[41].value = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B;
break;
case 0:
default:
ext_ctrl[41].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE;
ext_ctrl[41].value = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P;
break;
}
ext_ctrl[42].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER;
ext_ctrl[42].value = pH264Param->TemporalSVC.nTemporalLayerCount;
ext_ctrl[43].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP;
ext_ctrl[43].value = ((unsigned int)0 << 16 | 29);
ext_ctrl[44].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP;
ext_ctrl[44].value = ((unsigned int)1 << 16 | 29);
ext_ctrl[45].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP;
ext_ctrl[45].value = ((unsigned int)2 << 16 | 29);
ext_ctrl[46].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING;
ext_ctrl[46].value = 0;
ext_ctrl[47].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0;
ext_ctrl[47].value = 0;
ext_ctrl[48].id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE;
ext_ctrl[48].value = V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_SIDE_BY_SIDE;
/* FMO is not supported yet */
ext_ctrl[49].id = V4L2_CID_MPEG_VIDEO_H264_FMO;
ext_ctrl[49].value = 0;
ext_ctrl[50].id = V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE;
ext_ctrl[50].value = V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES;
ext_ctrl[51].id = V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP;
ext_ctrl[51].value = 4;
ext_ctrl[52].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
ext_ctrl[52].value = ((unsigned int)0 << 30 | 0);
ext_ctrl[53].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
ext_ctrl[53].value = ((unsigned int)1 << 30 | 0);
ext_ctrl[54].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
ext_ctrl[54].value = ((unsigned int)2 << 30 | 0);
ext_ctrl[55].id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH;
ext_ctrl[55].value = ((unsigned int)3 << 30 | 0);
ext_ctrl[56].id = V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION;
ext_ctrl[56].value = V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT;
ext_ctrl[57].id = V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE;
ext_ctrl[57].value = 0;
/* ASO is not supported yet */
ext_ctrl[58].id = V4L2_CID_MPEG_VIDEO_H264_ASO;
ext_ctrl[58].value = 0;
for (i = 0; i < 32; i++) {
ext_ctrl[59 + i].id = V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER;
ext_ctrl[59 + i].value = ((unsigned int)i << 16 | 0);
}
/* VUI RESRICTION ENABLE */
ext_ctrl[91].id = V4L2_CID_MPEG_MFC_H264_VUI_RESTRICTION_ENABLE;
ext_ctrl[91].value = pH264Param->VuiRestrictionEnable;
ext_ctrls.count = H264_CTRL_NUM;
if (pCtx->videoCtx.instInfo.supportInfo.enc.bTemporalSvcSupport == VIDEO_TRUE) {
i = ext_ctrls.count;
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT0;
ext_ctrl[i].value = pH264Param->TemporalSVC.nTemporalLayerBitrateRatio[0];
ext_ctrl[i + 1].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT1;
ext_ctrl[i + 1].value = pH264Param->TemporalSVC.nTemporalLayerBitrateRatio[1];
ext_ctrl[i + 2].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT2;
ext_ctrl[i + 2].value = pH264Param->TemporalSVC.nTemporalLayerBitrateRatio[2];
ext_ctrl[i + 3].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT3;
ext_ctrl[i + 3].value = pH264Param->TemporalSVC.nTemporalLayerBitrateRatio[3];
ext_ctrl[i + 4].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT4;
ext_ctrl[i + 4].value = pH264Param->TemporalSVC.nTemporalLayerBitrateRatio[4];
ext_ctrl[i + 5].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT5;
ext_ctrl[i + 5].value = pH264Param->TemporalSVC.nTemporalLayerBitrateRatio[5];
ext_ctrl[i + 6].id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT6;
ext_ctrl[i + 6].value = pH264Param->TemporalSVC.nTemporalLayerBitrateRatio[6];
ext_ctrls.count += 7;
}
if (pCtx->videoCtx.instInfo.supportInfo.enc.bSkypeSupport == VIDEO_TRUE) {
i = ext_ctrls.count;
/* H264 LTR FRAMES (0: disable, LTRFrames > 0: enable) */
ext_ctrl[i].id = V4L2_CID_MPEG_MFC_H264_NUM_OF_LTR;
ext_ctrl[i].value = pH264Param->LTRFrames;
/* FRAME LEVEL QP ENABLE */
ext_ctrl[i + 1].id = V4L2_CID_MPEG_MFC_CONFIG_QP_ENABLE;
ext_ctrl[i + 1].value = pCommonParam->EnableFRMQpControl;
/* CONFIG QP VALUE */
ext_ctrl[i + 2].id = V4L2_CID_MPEG_MFC_CONFIG_QP;
ext_ctrl[i + 2].value = pCommonParam->FrameQp;
/* MAX LAYER COUNT for SHORT TERM */
ext_ctrl[i + 3].id = V4L2_CID_MPEG_VIDEO_TEMPORAL_SHORTTERM_MAX_LAYER;
ext_ctrl[i + 3].value = pH264Param->MaxTemporalLayerCount;
ext_ctrls.count += 4;
}
if (pCtx->videoCtx.instInfo.supportInfo.enc.bRoiInfoSupport == VIDEO_TRUE) {
i = ext_ctrls.count;
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_ROI_ENABLE;
ext_ctrl[i].value = pH264Param->ROIEnable;
ext_ctrls.count += 1;
}
/* optional : if these are not set, set value are same as I frame */
if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
i = ext_ctrls.count;
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP_P; /* P frame */
ext_ctrl[i].value = GET_H264_QP_VALUE(pCommonParam->QpRange.QpMin_P);
ext_ctrl[i + 1].id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P;
ext_ctrl[i + 1].value = GET_H264_QP_VALUE(pCommonParam->QpRange.QpMax_P);
ext_ctrl[i + 2].id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP_B; /* B frame */
ext_ctrl[i + 2].value = GET_H264_QP_VALUE(pCommonParam->QpRange.QpMin_B);
ext_ctrl[i + 3].id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP_B;
ext_ctrl[i + 3].value = GET_H264_QP_VALUE(pCommonParam->QpRange.QpMax_B);
ext_ctrls.count += 4;
}
if (pCtx->videoCtx.instInfo.supportInfo.enc.bPVCSupport == VIDEO_TRUE) {
i = ext_ctrls.count;
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_RC_PVC_ENABLE;
ext_ctrl[i].value = pCommonParam->PerceptualMode;
ext_ctrls.count += 1;
}
if (pCtx->videoCtx.instInfo.supportInfo.enc.bChromaQpSupport == VIDEO_TRUE) {
i = ext_ctrls.count;
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_CHROMA_QP_OFFSET_CB;
ext_ctrl[i].value = pH264Param->chromaQPOffset.Cb;
ext_ctrl[i + 1].id = V4L2_CID_MPEG_VIDEO_CHROMA_QP_OFFSET_CR;
ext_ctrl[i + 1].value = pH264Param->chromaQPOffset.Cr;
ext_ctrls.count +=2;
}
}
break;
case VIDEO_CODING_MPEG4:
{
ExynosVideoEncMpeg4Param *pMpeg4Param = &pEncParam->codecParam.mpeg4;
/* common parameters but id is depends on codec */
ext_ctrl[8].id = V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP;
ext_ctrl[8].value = pCommonParam->FrameQp;
ext_ctrl[9].id = V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP;
ext_ctrl[9].value = pCommonParam->FrameQp_P;
ext_ctrl[10].id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP; /* I frame */
ext_ctrl[10].value = GET_MPEG4_QP_VALUE(pCommonParam->QpRange.QpMax_I);
ext_ctrl[11].id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP;
ext_ctrl[11].value = GET_MPEG4_QP_VALUE(pCommonParam->QpRange.QpMin_I);
ext_ctrl[12].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
ext_ctrl[12].value = pCommonParam->CBRPeriodRf;
/* MPEG4 specific parameters */
switch (pCommonParam->SliceMode) {
case 0:
ext_ctrl[13].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
ext_ctrl[13].value = 1; /* default */
ext_ctrl[14].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
ext_ctrl[14].value = 2800; /* based on MFC6.x */
break;
case 1:
ext_ctrl[13].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
ext_ctrl[13].value = pMpeg4Param->SliceArgument;
ext_ctrl[14].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
ext_ctrl[14].value = 2800; /* based on MFC6.x */
break;
case 2:
ext_ctrl[13].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
ext_ctrl[13].value = 1; /* default */
ext_ctrl[14].id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
ext_ctrl[14].value = pMpeg4Param->SliceArgument;
break;
default:
break;
}
ext_ctrl[15].id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE;
ext_ctrl[15].value = pMpeg4Param->ProfileIDC;
ext_ctrl[16].id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL;
ext_ctrl[16].value = pMpeg4Param->LevelIDC;
ext_ctrl[17].id = V4L2_CID_MPEG_VIDEO_MPEG4_QPEL;
ext_ctrl[17].value = pMpeg4Param->DisableQpelME;
/*
* It should be set using mpeg4Param->NumberBFrames after being handled by appl.
*/
ext_ctrl[18].id = V4L2_CID_MPEG_VIDEO_B_FRAMES;
ext_ctrl[18].value = pMpeg4Param->NumberBFrames;
ext_ctrl[19].id = V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_TIME_RES;
ext_ctrl[19].value = pMpeg4Param->TimeIncreamentRes;
ext_ctrl[20].id = V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_FRM_DELTA;
ext_ctrl[20].value = pMpeg4Param->VopTimeIncreament;
ext_ctrl[21].id = V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP;
ext_ctrl[21].value = pMpeg4Param->FrameQp_B;
ext_ctrl[22].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
ext_ctrl[22].value = 0;
ext_ctrl[23].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
ext_ctrl[23].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
ext_ctrl[24].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT;
ext_ctrl[24].value = 1;
/* Initial parameters : Frame Skip */
switch (pInitParam->FrameSkip) {
case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
ext_ctrl[25].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
ext_ctrl[25].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
break;
case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT:
ext_ctrl[25].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
ext_ctrl[25].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT;
break;
default:
/* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
ext_ctrl[25].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
ext_ctrl[25].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED;
break;
}
ext_ctrls.count = MPEG4_CTRL_NUM;
/* optional : if these are not set, set value are same as I frame */
if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
i = ext_ctrls.count;
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_P; /* P frame */
ext_ctrl[i].value = GET_MPEG4_QP_VALUE(pCommonParam->QpRange.QpMin_P);
ext_ctrl[i + 1].id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_P;
ext_ctrl[i + 1].value = GET_MPEG4_QP_VALUE(pCommonParam->QpRange.QpMax_P);
ext_ctrl[i + 2].id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_B; /* B frame */
ext_ctrl[i + 2].value = GET_MPEG4_QP_VALUE(pCommonParam->QpRange.QpMin_B);
ext_ctrl[i + 3].id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_B;
ext_ctrl[i + 3].value = GET_MPEG4_QP_VALUE(pCommonParam->QpRange.QpMax_B);
ext_ctrls.count += 4;
}
}
break;
case VIDEO_CODING_H263:
{
ExynosVideoEncH263Param *pH263Param = &pEncParam->codecParam.h263;
/* common parameters but id is depends on codec */
ext_ctrl[8].id = V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP;
ext_ctrl[8].value = pCommonParam->FrameQp;
ext_ctrl[9].id = V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP;
ext_ctrl[9].value = pCommonParam->FrameQp_P;
ext_ctrl[10].id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP; /* I frame */
ext_ctrl[10].value = GET_H263_QP_VALUE(pCommonParam->QpRange.QpMax_I);
ext_ctrl[11].id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP;
ext_ctrl[11].value = GET_H263_QP_VALUE(pCommonParam->QpRange.QpMin_I);
ext_ctrl[12].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
ext_ctrl[12].value = pCommonParam->CBRPeriodRf;
/* H263 specific parameters */
ext_ctrl[13].id = V4L2_CID_MPEG_MFC51_VIDEO_H263_RC_FRAME_RATE;
ext_ctrl[13].value = pH263Param->FrameRate;
ext_ctrl[14].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
ext_ctrl[14].value = 0;
ext_ctrl[15].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
ext_ctrl[15].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
ext_ctrl[16].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT;
ext_ctrl[16].value = 1;
/* Initial parameters : Frame Skip */
switch (pInitParam->FrameSkip) {
case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
ext_ctrl[17].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
ext_ctrl[17].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
break;
case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT:
ext_ctrl[17].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
ext_ctrl[17].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT;
break;
default:
/* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
ext_ctrl[17].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
ext_ctrl[17].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED;
break;
}
ext_ctrls.count = H263_CTRL_NUM;
/* optional : if these are not set, set value are same as I frame */
if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
i = ext_ctrls.count;
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP_P; /* P frame */
ext_ctrl[i].value = GET_H263_QP_VALUE(pCommonParam->QpRange.QpMin_P);
ext_ctrl[i + 1].id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP_P;
ext_ctrl[i + 1].value = GET_H263_QP_VALUE(pCommonParam->QpRange.QpMax_P);
ext_ctrls.count += 2;
}
}
break;
case VIDEO_CODING_VP8:
{
ExynosVideoEncVp8Param *pVp8Param = &pEncParam->codecParam.vp8;
/* common parameters but id is depends on codec */
ext_ctrl[8].id = V4L2_CID_MPEG_VIDEO_VP8_I_FRAME_QP;
ext_ctrl[8].value = pCommonParam->FrameQp;
ext_ctrl[9].id = V4L2_CID_MPEG_VIDEO_VP8_P_FRAME_QP;
ext_ctrl[9].value = pCommonParam->FrameQp_P;
ext_ctrl[10].id = V4L2_CID_MPEG_VIDEO_VP8_MAX_QP; /* I frame */
ext_ctrl[10].value = GET_VP8_QP_VALUE(pCommonParam->QpRange.QpMax_I);
ext_ctrl[11].id = V4L2_CID_MPEG_VIDEO_VP8_MIN_QP;
ext_ctrl[11].value = GET_VP8_QP_VALUE(pCommonParam->QpRange.QpMin_I);
ext_ctrl[12].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
ext_ctrl[12].value = pCommonParam->CBRPeriodRf;
/* VP8 specific parameters */
ext_ctrl[13].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_RC_FRAME_RATE;
ext_ctrl[13].value = pVp8Param->FrameRate;
ext_ctrl[14].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
ext_ctrl[14].value = 0;
ext_ctrl[15].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
ext_ctrl[15].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
ext_ctrl[16].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT;
ext_ctrl[16].value = 1;
/* Initial parameters : Frame Skip */
switch (pInitParam->FrameSkip) {
case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
ext_ctrl[17].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
ext_ctrl[17].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
break;
case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT:
ext_ctrl[17].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
ext_ctrl[17].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT;
break;
default:
/* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
ext_ctrl[17].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
ext_ctrl[17].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED;
break;
}
ext_ctrl[18].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_VERSION;
ext_ctrl[18].value = pVp8Param->Vp8Version;
ext_ctrl[19].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_NUM_OF_PARTITIONS;
ext_ctrl[19].value = pVp8Param->Vp8NumberOfPartitions;
ext_ctrl[20].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_FILTER_LEVEL;
ext_ctrl[20].value = pVp8Param->Vp8FilterLevel;
ext_ctrl[21].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_FILTER_SHARPNESS;
ext_ctrl[21].value = pVp8Param->Vp8FilterSharpness;
ext_ctrl[22].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_GOLDEN_FRAMESEL;
ext_ctrl[22].value = pVp8Param->Vp8GoldenFrameSel;
ext_ctrl[23].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_ENABLE;
ext_ctrl[23].value = 0;
ext_ctrl[24].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_LAYER0;
ext_ctrl[24].value = ((unsigned int)0 << 16 | 37);
ext_ctrl[25].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_LAYER1;
ext_ctrl[25].value = ((unsigned int)1 << 16 | 37);
ext_ctrl[26].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_LAYER2;
ext_ctrl[26].value = ((unsigned int)2 << 16 | 37);
ext_ctrl[27].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_REF_NUMBER_FOR_PFRAMES;
ext_ctrl[27].value = pVp8Param->RefNumberForPFrame;
ext_ctrl[28].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_DISABLE_INTRA_MD4X4;
ext_ctrl[28].value = pVp8Param->DisableIntraMd4x4;
ext_ctrl[29].id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_NUM_TEMPORAL_LAYER;
ext_ctrl[29].value = pVp8Param->TemporalSVC.nTemporalLayerCount;
ext_ctrls.count = VP8_CTRL_NUM;
if (pCtx->videoCtx.instInfo.supportInfo.enc.bTemporalSvcSupport == VIDEO_TRUE) {
i = ext_ctrls.count;
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT0;
ext_ctrl[i].value = pVp8Param->TemporalSVC.nTemporalLayerBitrateRatio[0];
ext_ctrl[i + 1].id = V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT1;
ext_ctrl[i + 1].value = pVp8Param->TemporalSVC.nTemporalLayerBitrateRatio[1];
ext_ctrl[i + 2].id = V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT2;
ext_ctrl[i + 2].value = pVp8Param->TemporalSVC.nTemporalLayerBitrateRatio[2];
ext_ctrls.count += 3;
}
/* optional : if these are not set, set value are same as I frame */
if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
i = ext_ctrls.count;
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_VP8_MIN_QP_P; /* P frame */
ext_ctrl[i].value = GET_VP8_QP_VALUE(pCommonParam->QpRange.QpMin_P);
ext_ctrl[i + 1].id = V4L2_CID_MPEG_VIDEO_VP8_MAX_QP_P;
ext_ctrl[i + 1].value = GET_VP8_QP_VALUE(pCommonParam->QpRange.QpMax_P);
ext_ctrls.count += 2;
}
if (pCtx->videoCtx.instInfo.supportInfo.enc.bPVCSupport == VIDEO_TRUE) {
i = ext_ctrls.count;
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_RC_PVC_ENABLE;
ext_ctrl[i].value = pCommonParam->PerceptualMode;
ext_ctrls.count += 1;
}
}
break;
case VIDEO_CODING_HEVC:
{
ExynosVideoEncHevcParam *pHevcParam = &pEncParam->codecParam.hevc;
/* common parameters but id is depends on codec */
ext_ctrl[8].id = V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP;
ext_ctrl[8].value = pCommonParam->FrameQp;
ext_ctrl[9].id = V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP;
ext_ctrl[9].value = pCommonParam->FrameQp_P;
ext_ctrl[10].id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP; /* I frame */
ext_ctrl[10].value = GET_HEVC_QP_VALUE(pCommonParam->QpRange.QpMax_I,
pCtx->videoCtx.instInfo.HwVersion);
ext_ctrl[11].id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP;
ext_ctrl[11].value = GET_HEVC_QP_VALUE(pCommonParam->QpRange.QpMin_I,
pCtx->videoCtx.instInfo.HwVersion);
ext_ctrl[12].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
ext_ctrl[12].value = pCommonParam->CBRPeriodRf;
/* HEVC specific parameters */
ext_ctrl[13].id = V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP;
ext_ctrl[13].value = pHevcParam->FrameQp_B;
ext_ctrl[14].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_RC_FRAME_RATE;
ext_ctrl[14].value = pHevcParam->FrameRate;
/* Initial parameters : Frame Skip */
switch (pInitParam->FrameSkip) {
case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
ext_ctrl[15].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
ext_ctrl[15].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
break;
case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT:
ext_ctrl[15].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
ext_ctrl[15].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT;
break;
default:
/* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
ext_ctrl[15].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
ext_ctrl[15].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED;
break;
}
ext_ctrl[16].id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE;
ext_ctrl[16].value = pHevcParam->ProfileIDC;
ext_ctrl[17].id = V4L2_CID_MPEG_VIDEO_HEVC_LEVEL;
ext_ctrl[17].value = pHevcParam->LevelIDC;
ext_ctrl[18].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_TIER_FLAG;
ext_ctrl[18].value = pHevcParam->TierIDC;
ext_ctrl[19].id = V4L2_CID_MPEG_VIDEO_B_FRAMES;
ext_ctrl[19].value = pHevcParam->NumberBFrames;
ext_ctrl[20].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_MAX_PARTITION_DEPTH;
ext_ctrl[20].value = pHevcParam->MaxPartitionDepth;
ext_ctrl[21].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_REF_NUMBER_FOR_PFRAMES;
ext_ctrl[21].value = pHevcParam->NumberRefForPframes;
ext_ctrl[22].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_DISABLE;
ext_ctrl[22].value = pHevcParam->LoopFilterDisable;
ext_ctrl[23].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_SLICE_BOUNDARY;
ext_ctrl[23].value = pHevcParam->LoopFilterSliceFlag;
ext_ctrl[24].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_TC_OFFSET_DIV2;
ext_ctrl[24].value = pHevcParam->LoopFilterTcOffset;
ext_ctrl[25].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_BETA_OFFSET_DIV2;
ext_ctrl[25].value = pHevcParam->LoopFilterBetaOffset;
ext_ctrl[26].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LTR_ENABLE;
ext_ctrl[26].value = pHevcParam->LongtermRefEnable;
ext_ctrl[27].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_USER_REF;
ext_ctrl[27].value = pHevcParam->LongtermUserRef;
ext_ctrl[28].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_STORE_REF;
ext_ctrl[28].value = pHevcParam->LongtermStoreRef;
/* should be set V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE first */
ext_ctrl[29].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_DARK;
ext_ctrl[29].value = pHevcParam->DarkDisable;
ext_ctrl[30].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_SMOOTH;
ext_ctrl[30].value = pHevcParam->SmoothDisable;
ext_ctrl[31].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_STATIC;
ext_ctrl[31].value = pHevcParam->StaticDisable;
ext_ctrl[32].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_ACTIVITY;
ext_ctrl[32].value = pHevcParam->ActivityDisable;
/* doesn't have to be set */
ext_ctrl[33].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_REFRESH_TYPE;
ext_ctrl[33].value = 2;
ext_ctrl[34].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_REFRESH_PERIOD;
ext_ctrl[34].value = 0;
ext_ctrl[35].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LOSSLESS_CU_ENABLE;
ext_ctrl[35].value = 0;
ext_ctrl[36].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_CONST_INTRA_PRED_ENABLE;
ext_ctrl[36].value = 0;
ext_ctrl[37].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_WAVEFRONT_ENABLE;
ext_ctrl[37].value = 0;
ext_ctrl[38].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_SIGN_DATA_HIDING;
ext_ctrl[38].value = 1;
ext_ctrl[39].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_GENERAL_PB_ENABLE;
ext_ctrl[39].value = pHevcParam->GPBEnable;
ext_ctrl[40].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_TEMPORAL_ID_ENABLE;
ext_ctrl[40].value = 1;
ext_ctrl[41].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_STRONG_SMOTHING_FLAG;
ext_ctrl[41].value = 1;
ext_ctrl[42].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1;
ext_ctrl[42].value = 4;
ext_ctrl[43].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_DISABLE_INTRA_PU_SPLIT;
ext_ctrl[43].value = 0;
ext_ctrl[44].id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_DISABLE_TMV_PREDICTION;
ext_ctrl[44].value = 0;
ext_ctrl[45].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
ext_ctrl[45].value = 0;
ext_ctrl[46].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
ext_ctrl[46].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
/* SVC is not supported yet */
ext_ctrl[47].id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_QP_ENABLE;
ext_ctrl[47].value = 0;
switch (pHevcParam->HierarType) {
case 1:
ext_ctrl[48].id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_TYPE;
ext_ctrl[48].value = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B;
break;
case 0:
default:
ext_ctrl[48].id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_TYPE;
ext_ctrl[48].value = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P;
break;
}
ext_ctrl[49].id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER;
ext_ctrl[49].value = pHevcParam->TemporalSVC.nTemporalLayerCount;
ext_ctrl[50].id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_QP;
ext_ctrl[50].value = ((unsigned int)0 << 16 | 29);
ext_ctrl[51].id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_QP;
ext_ctrl[51].value = ((unsigned int)1 << 16 | 29);
ext_ctrl[52].id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_QP;
ext_ctrl[52].value = ((unsigned int)2 << 16 | 29);
ext_ctrls.count = HEVC_CTRL_NUM;
if (pCtx->videoCtx.instInfo.supportInfo.enc.bTemporalSvcSupport == VIDEO_TRUE) {
i = ext_ctrls.count;
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT0;
ext_ctrl[i].value = pHevcParam->TemporalSVC.nTemporalLayerBitrateRatio[0];
ext_ctrl[i + 1].id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT1;
ext_ctrl[i + 1].value = pHevcParam->TemporalSVC.nTemporalLayerBitrateRatio[1];
ext_ctrl[i + 2].id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT2;
ext_ctrl[i + 2].value = pHevcParam->TemporalSVC.nTemporalLayerBitrateRatio[2];
ext_ctrl[i + 3].id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT3;
ext_ctrl[i + 3].value = pHevcParam->TemporalSVC.nTemporalLayerBitrateRatio[3];
ext_ctrl[i + 4].id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT4;
ext_ctrl[i + 4].value = pHevcParam->TemporalSVC.nTemporalLayerBitrateRatio[4];
ext_ctrl[i + 5].id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT5;
ext_ctrl[i + 5].value = pHevcParam->TemporalSVC.nTemporalLayerBitrateRatio[5];
ext_ctrl[i + 6].id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT6;
ext_ctrl[i + 6].value = pHevcParam->TemporalSVC.nTemporalLayerBitrateRatio[6];
ext_ctrls.count += 7;
}
if (pCtx->videoCtx.instInfo.supportInfo.enc.bSkypeSupport == VIDEO_TRUE) {
i = ext_ctrls.count;
/* MAX LAYER COUNT */
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_TEMPORAL_SHORTTERM_MAX_LAYER;
ext_ctrl[i].value = pHevcParam->MaxTemporalLayerCount;
ext_ctrls.count += 1;
}
if (pCtx->videoCtx.instInfo.supportInfo.enc.bRoiInfoSupport == VIDEO_TRUE) {
i = ext_ctrls.count;
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_ROI_ENABLE;
ext_ctrl[i].value = pHevcParam->ROIEnable;
ext_ctrls.count += 1;
}
/* optional : if these are not set, set value are same as I frame */
if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
i = ext_ctrls.count;
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_P; /* P frame */
ext_ctrl[i].value = GET_HEVC_QP_VALUE(pCommonParam->QpRange.QpMin_P,
pCtx->videoCtx.instInfo.HwVersion);
ext_ctrl[i + 1].id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_P;
ext_ctrl[i + 1].value = GET_HEVC_QP_VALUE(pCommonParam->QpRange.QpMax_P,
pCtx->videoCtx.instInfo.HwVersion);
ext_ctrl[i + 2].id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_B; /* B frame */
ext_ctrl[i + 2].value = GET_HEVC_QP_VALUE(pCommonParam->QpRange.QpMin_B,
pCtx->videoCtx.instInfo.HwVersion);
ext_ctrl[i + 3].id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_B;
ext_ctrl[i + 3].value = GET_HEVC_QP_VALUE(pCommonParam->QpRange.QpMax_B,
pCtx->videoCtx.instInfo.HwVersion);
ext_ctrls.count += 4;
}
if (pCtx->videoCtx.instInfo.supportInfo.enc.bPVCSupport == VIDEO_TRUE) {
i = ext_ctrls.count;
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_RC_PVC_ENABLE;
ext_ctrl[i].value = pCommonParam->PerceptualMode;
ext_ctrls.count += 1;
}
if (pCtx->videoCtx.instInfo.supportInfo.enc.bChromaQpSupport == VIDEO_TRUE) {
i = ext_ctrls.count;
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_CHROMA_QP_OFFSET_CB;
ext_ctrl[i].value = pHevcParam->chromaQPOffset.Cb;
ext_ctrl[i + 1].id = V4L2_CID_MPEG_VIDEO_CHROMA_QP_OFFSET_CR;
ext_ctrl[i + 1].value = pHevcParam->chromaQPOffset.Cr;
ext_ctrls.count +=2;
}
}
break;
case VIDEO_CODING_VP9:
{
ExynosVideoEncVp9Param *pVp9Param = &pEncParam->codecParam.vp9;
/* VP9 specific parameters */
ext_ctrl[8].id = V4L2_CID_MPEG_VIDEO_VP9_I_FRAME_QP;
ext_ctrl[8].value = pCommonParam->FrameQp;
ext_ctrl[9].id = V4L2_CID_MPEG_VIDEO_VP9_P_FRAME_QP;
ext_ctrl[9].value = pCommonParam->FrameQp_P;
ext_ctrl[10].id = V4L2_CID_MPEG_VIDEO_VP9_MAX_QP; /* I frame */
ext_ctrl[10].value = GET_VP9_QP_VALUE(pCommonParam->QpRange.QpMax_I);
ext_ctrl[11].id = V4L2_CID_MPEG_VIDEO_VP9_MIN_QP;
ext_ctrl[11].value = GET_VP9_QP_VALUE(pCommonParam->QpRange.QpMin_I);
ext_ctrl[12].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
ext_ctrl[12].value = pCommonParam->CBRPeriodRf;
ext_ctrl[13].id = V4L2_CID_MPEG_VIDEO_VP9_RC_FRAME_RATE;
ext_ctrl[13].value = pVp9Param->FrameRate;
ext_ctrl[14].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
ext_ctrl[14].value = 0;
ext_ctrl[15].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
ext_ctrl[15].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
ext_ctrl[16].id = V4L2_CID_MPEG_VIDEO_VP9_DISABLE_INTRA_PU_SPLIT;
ext_ctrl[16].value = 0;
/* Initial parameters : Frame Skip */
switch (pInitParam->FrameSkip) {
case VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT:
ext_ctrl[17].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
ext_ctrl[17].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT;
break;
case VIDEO_FRAME_SKIP_MODE_BUF_LIMIT:
ext_ctrl[17].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
ext_ctrl[17].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT;
break;
default:
/* VIDEO_FRAME_SKIP_MODE_DISABLE (default) */
ext_ctrl[17].id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE;
ext_ctrl[17].value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED;
break;
}
ext_ctrl[18].id = V4L2_CID_MPEG_VIDEO_VP9_VERSION;
ext_ctrl[18].value = pVp9Param->Vp9Profile;
/* TODO */
//ext_ctrl[18].id = V4L2_CID_MPEG_VIDEO_VP9_LEVEL;
//ext_ctrl[18].value = pVp9Param->Vp9Level;
ext_ctrl[19].id = V4L2_CID_MPEG_VIDEO_VP9_MAX_PARTITION_DEPTH;
ext_ctrl[19].value = pVp9Param->MaxPartitionDepth;
ext_ctrl[20].id = V4L2_CID_MPEG_VIDEO_VP9_GOLDEN_FRAMESEL;
ext_ctrl[20].value = pVp9Param->Vp9GoldenFrameSel;
ext_ctrl[21].id = V4L2_CID_MPEG_VIDEO_VP9_GF_REFRESH_PERIOD;
ext_ctrl[21].value = pVp9Param->Vp9GFRefreshPeriod;
ext_ctrl[22].id = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHY_QP_ENABLE;
ext_ctrl[22].value = 0;
ext_ctrl[23].id = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_QP;
ext_ctrl[23].value = ((unsigned int)0 << 16 | 90);
ext_ctrl[24].id = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_QP;
ext_ctrl[24].value = ((unsigned int)1 << 16 | 90);
ext_ctrl[25].id = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_QP;
ext_ctrl[25].value = ((unsigned int)2 << 16 | 90);
ext_ctrl[26].id = V4L2_CID_MPEG_VIDEO_VP9_REF_NUMBER_FOR_PFRAMES;
ext_ctrl[26].value = pVp9Param->RefNumberForPFrame;
ext_ctrl[27].id = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER;
ext_ctrl[27].value = pVp9Param->TemporalSVC.nTemporalLayerCount;
ext_ctrl[28].id = V4L2_CID_MPEG_VIDEO_DISABLE_IVF_HEADER;
ext_ctrl[28].value = 1;
ext_ctrls.count = VP9_CTRL_NUM;
if (pCtx->videoCtx.instInfo.supportInfo.enc.bTemporalSvcSupport == VIDEO_TRUE) {
i = ext_ctrls.count;
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT0;
ext_ctrl[i].value = pVp9Param->TemporalSVC.nTemporalLayerBitrateRatio[0];
ext_ctrl[i + 1].id = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT1;
ext_ctrl[i + 1].value = pVp9Param->TemporalSVC.nTemporalLayerBitrateRatio[1];
ext_ctrl[i + 2].id = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT2;
ext_ctrl[i + 2].value = pVp9Param->TemporalSVC.nTemporalLayerBitrateRatio[2];
ext_ctrls.count += 3;
}
/* optional : if these are not set, set value are same as I frame */
if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
i = ext_ctrls.count;
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_VP9_MIN_QP_P; /* P frame */
ext_ctrl[i].value = GET_VP9_QP_VALUE(pCommonParam->QpRange.QpMin_P);
ext_ctrl[i + 1].id = V4L2_CID_MPEG_VIDEO_VP9_MAX_QP_P;
ext_ctrl[i + 1].value = GET_VP9_QP_VALUE(pCommonParam->QpRange.QpMax_P);
ext_ctrls.count += 2;
}
if (pCtx->videoCtx.instInfo.supportInfo.enc.bPVCSupport == VIDEO_TRUE) {
i = ext_ctrls.count;
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_RC_PVC_ENABLE;
ext_ctrl[i].value = pCommonParam->PerceptualMode;
ext_ctrls.count += 1;
}
}
break;
default:
{
ALOGE("[%s] Undefined codec type",__FUNCTION__);
ret = -1;
goto EXIT;
}
break;
}
/* extra common parameters */
if (pCtx->videoCtx.instInfo.supportInfo.enc.bDropControlSupport == VIDEO_TRUE) {
i = ext_ctrls.count;
ext_ctrl[i].id = V4L2_CID_MPEG_VIDEO_DROP_CONTROL;
ext_ctrl[i].value = pCommonParam->bDropControl;
ext_ctrls.count += 1;
}
ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
ext_ctrls.controls = ext_ctrl;
if (exynos_v4l2_s_ext_ctrl(pCtx->videoCtx.hDevice, &ext_ctrls) != 0) {
ret = -1;
goto EXIT;
}
}
break; // CODEC_OSAL_CID_ENC_SET_PARAMS
case CODEC_OSAL_CID_ENC_QP_RANGE:
{
ExynosVideoQPRange *pQpRange = (ExynosVideoQPRange *)pInfo;
int cids[3][2], values[3][2]; /* I, P, B : min & max */
int i;
memset(cids, 0, sizeof(cids));
memset(values, 0, sizeof(values));
/* codec specific parameters */
/* common parameters but id is depends on codec */
switch (pCtx->videoCtx.instInfo.eCodecType) {
case VIDEO_CODING_AVC:
{
cids[0][0] = V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
cids[0][1] = V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
values[0][0] = GET_H264_QP_VALUE(pQpRange->QpMin_I);
values[0][1] = GET_H264_QP_VALUE(pQpRange->QpMax_I);
if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
if (pQpRange->QpMin_P > pQpRange->QpMax_P) {
ALOGE("%s: QP(P) range(%d, %d) is wrong", __FUNCTION__, pQpRange->QpMin_P, pQpRange->QpMax_P);
ret = -1;
goto EXIT;
}
if (pQpRange->QpMin_B > pQpRange->QpMax_B) {
ALOGE("%s: QP(B) range(%d, %d) is wrong", __FUNCTION__, pQpRange->QpMin_B, pQpRange->QpMax_B);
ret = -1;
goto EXIT;
}
cids[1][0] = V4L2_CID_MPEG_VIDEO_H264_MIN_QP_P;
cids[1][1] = V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P;
cids[2][0] = V4L2_CID_MPEG_VIDEO_H264_MIN_QP_B;
cids[2][1] = V4L2_CID_MPEG_VIDEO_H264_MAX_QP_B;
values[1][0] = GET_H264_QP_VALUE(pQpRange->QpMin_P);
values[1][1] = GET_H264_QP_VALUE(pQpRange->QpMax_P);
values[2][0] = GET_H264_QP_VALUE(pQpRange->QpMin_B);
values[2][1] = GET_H264_QP_VALUE(pQpRange->QpMax_B);
}
}
break;
case VIDEO_CODING_MPEG4:
{
cids[0][0] = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP;
cids[0][1] = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP;
values[0][0] = GET_MPEG4_QP_VALUE(pQpRange->QpMin_I);
values[0][1] = GET_MPEG4_QP_VALUE(pQpRange->QpMax_I);
if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
if (pQpRange->QpMin_P > pQpRange->QpMax_P) {
ALOGE("%s: QP(P) range(%d, %d) is wrong", __FUNCTION__, pQpRange->QpMin_P, pQpRange->QpMax_P);
ret = -1;
goto EXIT;
}
if (pQpRange->QpMin_B > pQpRange->QpMax_B) {
ALOGE("%s: QP(B) range(%d, %d) is wrong", __FUNCTION__, pQpRange->QpMin_B, pQpRange->QpMax_B);
ret = -1;
goto EXIT;
}
cids[1][0] = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_P;
cids[1][1] = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_P;
cids[2][0] = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_B;
cids[2][1] = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_B;
values[1][0] = GET_MPEG4_QP_VALUE(pQpRange->QpMin_P);
values[1][1] = GET_MPEG4_QP_VALUE(pQpRange->QpMax_P);
values[2][0] = GET_MPEG4_QP_VALUE(pQpRange->QpMin_B);
values[2][1] = GET_MPEG4_QP_VALUE(pQpRange->QpMax_B);
}
}
break;
case VIDEO_CODING_H263:
{
cids[0][0] = V4L2_CID_MPEG_VIDEO_H263_MIN_QP;
cids[0][1] = V4L2_CID_MPEG_VIDEO_H263_MAX_QP;
values[0][0] = GET_H263_QP_VALUE(pQpRange->QpMin_I);
values[0][1] = GET_H263_QP_VALUE(pQpRange->QpMax_I);
if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
if (pQpRange->QpMin_P > pQpRange->QpMax_P) {
ALOGE("%s: QP(P) range(%d, %d) is wrong", __FUNCTION__, pQpRange->QpMin_P, pQpRange->QpMax_P);
ret = -1;
goto EXIT;
}
cids[1][0] = V4L2_CID_MPEG_VIDEO_H263_MIN_QP_P;
cids[1][1] = V4L2_CID_MPEG_VIDEO_H263_MAX_QP_P;
values[1][0] = GET_H263_QP_VALUE(pQpRange->QpMin_P);
values[1][1] = GET_H263_QP_VALUE(pQpRange->QpMax_P);
}
}
break;
case VIDEO_CODING_VP8:
{
cids[0][0] = V4L2_CID_MPEG_VIDEO_VP8_MIN_QP;
cids[0][1] = V4L2_CID_MPEG_VIDEO_VP8_MAX_QP;
values[0][0] = GET_VP8_QP_VALUE(pQpRange->QpMin_I);
values[0][1] = GET_VP8_QP_VALUE(pQpRange->QpMax_I);
if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
if (pQpRange->QpMin_P > pQpRange->QpMax_P) {
ALOGE("%s: QP(P) range(%d, %d) is wrong", __FUNCTION__, pQpRange->QpMin_P, pQpRange->QpMax_P);
ret = -1;
goto EXIT;
}
cids[1][0] = V4L2_CID_MPEG_VIDEO_VP8_MIN_QP_P;
cids[1][1] = V4L2_CID_MPEG_VIDEO_VP8_MAX_QP_P;
values[1][0] = GET_VP8_QP_VALUE(pQpRange->QpMin_P);
values[1][1] = GET_VP8_QP_VALUE(pQpRange->QpMax_P);
}
}
break;
case VIDEO_CODING_HEVC:
{
cids[0][0] = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP;
cids[0][1] = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP;
values[0][0] = GET_HEVC_QP_VALUE(pQpRange->QpMin_I,
pCtx->videoCtx.instInfo.HwVersion);
values[0][1] = GET_HEVC_QP_VALUE(pQpRange->QpMax_I,
pCtx->videoCtx.instInfo.HwVersion);
if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
if (pQpRange->QpMin_P > pQpRange->QpMax_P) {
ALOGE("%s: QP(P) range(%d, %d) is wrong", __FUNCTION__, pQpRange->QpMin_P, pQpRange->QpMax_P);
ret = -1;
goto EXIT;
}
if (pQpRange->QpMin_B > pQpRange->QpMax_B) {
ALOGE("%s: QP(B) range(%d, %d) is wrong", __FUNCTION__, pQpRange->QpMin_B, pQpRange->QpMax_B);
ret = -1;
goto EXIT;
}
cids[1][0] = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_P;
cids[1][1] = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_P;
cids[2][0] = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_B;
cids[2][1] = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_B;
values[1][0] = GET_HEVC_QP_VALUE(pQpRange->QpMin_P,
pCtx->videoCtx.instInfo.HwVersion);
values[1][1] = GET_HEVC_QP_VALUE(pQpRange->QpMax_P,
pCtx->videoCtx.instInfo.HwVersion);
values[2][0] = GET_HEVC_QP_VALUE(pQpRange->QpMin_B,
pCtx->videoCtx.instInfo.HwVersion);
values[2][1] = GET_HEVC_QP_VALUE(pQpRange->QpMax_B,
pCtx->videoCtx.instInfo.HwVersion);
}
}
break;
case VIDEO_CODING_VP9:
{
cids[0][0] = V4L2_CID_MPEG_VIDEO_VP9_MIN_QP;
cids[0][1] = V4L2_CID_MPEG_VIDEO_VP9_MAX_QP;
values[0][0] = GET_VP9_QP_VALUE(pQpRange->QpMin_I);
values[0][1] = GET_VP9_QP_VALUE(pQpRange->QpMax_I);
if (pCtx->videoCtx.instInfo.supportInfo.enc.bQpRangePBSupport == VIDEO_TRUE) {
cids[1][0] = V4L2_CID_MPEG_VIDEO_VP9_MIN_QP_P;
cids[1][1] = V4L2_CID_MPEG_VIDEO_VP9_MAX_QP_P;
values[1][0] = GET_VP9_QP_VALUE(pQpRange->QpMin_P);
values[1][1] = GET_VP9_QP_VALUE(pQpRange->QpMax_P);
}
}
break;
default:
{
ALOGE("[%s] Undefined codec type", __FUNCTION__);
ret = -1;
goto EXIT;
}
break;
}
for (i = 0; i < (int)(sizeof(cids)/sizeof(cids[0])); i++) {
if (cids[i][0] == 0)
break;
ALOGV("%s: QP[%d] range (%d / %d)", __FUNCTION__, i, values[i][0], values[i][1]);
/* keep a calling sequence as Max->Min because dirver has a restriction */
if (exynos_v4l2_s_ctrl(pCtx->videoCtx.hDevice, cids[i][1], values[i][1]) != 0) {
ALOGE("%s: Failed to s_ctrl for max value", __FUNCTION__);
ret = -1;
goto EXIT;
}
if (exynos_v4l2_s_ctrl(pCtx->videoCtx.hDevice, cids[i][0], values[i][0]) != 0) {
ALOGE("%s: Failed to s_ctrl for min value", __FUNCTION__);
ret = -1;
goto EXIT;
}
}
}
break;
case CODEC_OSAL_CID_ENC_COLOR_ASPECTS:
{
ExynosVideoColorAspects *pColorAspects = (ExynosVideoColorAspects *)pInfo;
struct v4l2_ext_control ext_ctrl[4]; /* range, primaries, transfer, matrix coeff */
struct v4l2_ext_controls ext_ctrls;
ext_ctrl[0].id = V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG;
ext_ctrl[0].value = (pColorAspects->eRangeType == RANGE_FULL)? 1:0;
if (pCtx->videoCtx.instInfo.eCodecType == VIDEO_CODING_VP9) {
int i;
ext_ctrl[1].id = V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES;
ext_ctrl[1].value = 0;
/* PRIMARIES_BT601_6_625 is supposed to be used as same as PRIMARIES_BT601_6_525 based on MFC.
* And ColorSpace matrix doesn't have PRIMARIES_BT601_6_625 case
*/
if (pColorAspects->ePrimariesType == PRIMARIES_BT601_6_625)
pColorAspects->ePrimariesType = PRIMARIES_BT601_6_525;
/* TRANSFER_SMPTE_170M is supposed to be used as same as TRANSFER_BT709 based on spec.
* And ColorSpace doesn't support TRANSFER_BT709
*/
if (pColorAspects->eTransferType == TRANSFER_BT709)
pColorAspects->eTransferType = TRANSFER_SMPTE_170M;
for (i = 0; i < (int)(sizeof(ColorSpaceToColorAspects)/sizeof(ColorSpaceToColorAspects[0])); i++) {
if ((ColorSpaceToColorAspects[i].primaries == pColorAspects->ePrimariesType) &&
(ColorSpaceToColorAspects[i].transfer == pColorAspects->eTransferType) &&
(ColorSpaceToColorAspects[i].coeff == pColorAspects->eCoeffType)) {
ext_ctrl[1].value = i;
break;
}
}
ext_ctrls.count = 2;
} else {
ext_ctrl[1].id = V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES;
ext_ctrl[1].value = pColorAspects->ePrimariesType;
ext_ctrl[2].id = V4L2_CID_MPEG_VIDEO_TRANSFER_CHARACTERISTICS;
ext_ctrl[2].value = pColorAspects->eTransferType;
ext_ctrl[3].id = V4L2_CID_MPEG_VIDEO_MATRIX_COEFFICIENTS;
ext_ctrl[3].value = pColorAspects->eCoeffType;
ext_ctrls.count = 4;
}
ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
ext_ctrls.controls = ext_ctrl;
if (exynos_v4l2_s_ext_ctrl(pCtx->videoCtx.hDevice, &ext_ctrls) != 0) {
ret = -1;
goto EXIT;
}
}
break;
case CODEC_OSAL_CID_ENC_HDR_STATIC_INFO:
{
ExynosVideoHdrStatic *pHDRStaticInfo = (ExynosVideoHdrStatic *)pInfo;
struct v4l2_ext_control ext_ctrl[9];
struct v4l2_ext_controls ext_ctrls;
ExynosVideoHdrStatic invalidHDR;
/* check a validation */
memset(&invalidHDR, 0, sizeof(ExynosVideoHdrStatic));
if (memcmp(&invalidHDR, pHDRStaticInfo, sizeof(ExynosVideoHdrStatic)) == 0) {
/* all values are invalid */
ALOGD("%s: HDRStaticInfo is unspecified. HDRStaticInfo won't be set", __FUNCTION__);
goto EXIT;
}
ext_ctrl[0].id = V4L2_CID_MPEG_VIDEO_STATIC_INFO_ENABLE;
ext_ctrl[0].value = 1;
ext_ctrl[1].id = V4L2_CID_MPEG_VIDEO_SEI_MAX_PIC_AVERAGE_LIGHT;
ext_ctrl[1].value = pHDRStaticInfo->max_pic_average_light;
ALOGE("%s: value = %u", __FUNCTION__, ext_ctrl[1].value);
ext_ctrl[2].id = V4L2_CID_MPEG_VIDEO_SEI_MAX_CONTENT_LIGHT;
ext_ctrl[2].value = pHDRStaticInfo->max_content_light;
ALOGE("%s: value = %u", __FUNCTION__, ext_ctrl[2].value);
ext_ctrl[3].id = V4L2_CID_MPEG_VIDEO_SEI_MAX_DISPLAY_LUMINANCE;
ext_ctrl[3].value = pHDRStaticInfo->max_display_luminance;
ALOGE("%s: value = %u", __FUNCTION__, ext_ctrl[3].value);
ext_ctrl[4].id = V4L2_CID_MPEG_VIDEO_SEI_MIN_DISPLAY_LUMINANCE;
ext_ctrl[4].value = pHDRStaticInfo->min_display_luminance;
ALOGE("%s: value = %u", __FUNCTION__, ext_ctrl[4].value);
ext_ctrl[5].id = V4L2_CID_MPEG_VIDEO_SEI_WHITE_POINT;
ext_ctrl[5].value = SET_16BIT_TO_HIGH(pHDRStaticInfo->white.x) | GET_16BIT_LOW(pHDRStaticInfo->white.y);
ALOGE("%s: value = %u", __FUNCTION__, ext_ctrl[5].value);
ext_ctrl[6].id = V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_0;
ext_ctrl[6].value = SET_16BIT_TO_HIGH(pHDRStaticInfo->green.x) | GET_16BIT_LOW(pHDRStaticInfo->green.y);
ALOGE("%s: value = %u", __FUNCTION__, ext_ctrl[6].value);
ext_ctrl[7].id = V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_1;
ext_ctrl[7].value = SET_16BIT_TO_HIGH(pHDRStaticInfo->blue.x) | GET_16BIT_LOW(pHDRStaticInfo->blue.y);
ALOGE("%s: value = %u", __FUNCTION__, ext_ctrl[7].value);
ext_ctrl[8].id = V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_2;
ext_ctrl[8].value = SET_16BIT_TO_HIGH(pHDRStaticInfo->red.x) | GET_16BIT_LOW(pHDRStaticInfo->red.y);
ALOGE("%s: value = %u", __FUNCTION__, ext_ctrl[8].value);
ext_ctrls.count = 9;
ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
ext_ctrls.controls = ext_ctrl;
if (exynos_v4l2_s_ext_ctrl(pCtx->videoCtx.hDevice, &ext_ctrls) != 0) {
ret = -1;
goto EXIT;
}
}
break;
default:
{
ALOGE("%s: unsupported CID(%x)", __FUNCTION__, nCID);
ret = -1;
}
break;
}
}
EXIT:
return ret;
}
int Codec_OSAL_GetControl(
CodecOSALVideoContext *pCtx,
unsigned int uCID,
int *pValue)
{
if ((pCtx != NULL) &&
(pValue != NULL) &&
(pCtx->videoCtx.hDevice >= 0)) {
return exynos_v4l2_g_ctrl(pCtx->videoCtx.hDevice, uCID, pValue);
}
return -1;
}
int Codec_OSAL_SetControl(
CodecOSALVideoContext *pCtx,
unsigned int uCID,
unsigned long nValue)
{
if ((pCtx != NULL) &&
(pCtx->videoCtx.hDevice >= 0)) {
return exynos_v4l2_s_ctrl(pCtx->videoCtx.hDevice, uCID, nValue);
}
return -1;
}
int Codec_OSAL_GetCrop(
CodecOSALVideoContext *pCtx,
CodecOSAL_Crop *pCrop)
{
if ((pCtx != NULL) &&
(pCrop != NULL) &&
(pCtx->videoCtx.hDevice >= 0)) {
struct v4l2_crop crop;
memset(&crop, 0, sizeof(crop));
crop.type = pCrop->type;
if (exynos_v4l2_g_crop(pCtx->videoCtx.hDevice, &crop) == 0) {
pCrop->top = crop.c.top;
pCrop->left = crop.c.left;
pCrop->width = crop.c.width;
pCrop->height = crop.c.height;
return 0;
}
}
return -1;
}
int Codec_OSAL_GetFormat(
CodecOSALVideoContext *pCtx,
CodecOSAL_Format *pFmt)
{
if ((pCtx != NULL) &&
(pFmt != NULL) &&
(pCtx->videoCtx.hDevice >= 0)) {
struct v4l2_format fmt;
int i;
memset(&fmt, 0, sizeof(fmt));
fmt.type = pFmt->type;
if (exynos_v4l2_g_fmt(pCtx->videoCtx.hDevice, &fmt) == 0) {
pFmt->format = fmt.fmt.pix_mp.pixelformat;
pFmt->width = fmt.fmt.pix_mp.width;
pFmt->height = fmt.fmt.pix_mp.height;
pFmt->stride = fmt.fmt.pix_mp.plane_fmt[0].bytesperline;
pFmt->nPlane = fmt.fmt.pix_mp.num_planes;
pFmt->field = fmt.fmt.pix_mp.field;
for (i = 0; i < fmt.fmt.pix_mp.num_planes; i++)
pFmt->planeSize[i] = fmt.fmt.pix_mp.plane_fmt[i].sizeimage;
return 0;
}
}
return -1;
}
int Codec_OSAL_SetFormat(
CodecOSALVideoContext *pCtx,
CodecOSAL_Format *pFmt)
{
if ((pCtx != NULL) &&
(pFmt != NULL) &&
(pCtx->videoCtx.hDevice >= 0)) {
struct v4l2_format fmt;
int i;
memset(&fmt, 0, sizeof(fmt));
fmt.type = pFmt->type;
fmt.fmt.pix_mp.pixelformat = pFmt->format;
fmt.fmt.pix_mp.width = pFmt->width;
fmt.fmt.pix_mp.height = pFmt->height;
fmt.fmt.pix_mp.plane_fmt[0].bytesperline = pFmt->stride;
fmt.fmt.pix_mp.num_planes = pFmt->nPlane;
fmt.fmt.pix_mp.flags = pFmt->field;
for (i = 0; i < pFmt->nPlane; i++)
fmt.fmt.pix_mp.plane_fmt[i].sizeimage = pFmt->planeSize[i];
return exynos_v4l2_s_fmt(pCtx->videoCtx.hDevice, &fmt);
}
return -1;
}
int Codec_OSAL_RequestBuf(
CodecOSALVideoContext *pCtx,
CodecOSAL_ReqBuf *pReqBuf)
{
if ((pCtx != NULL) &&
(pReqBuf != NULL) &&
(pCtx->videoCtx.hDevice >= 0)) {
return exynos_v4l2_reqbufs(pCtx->videoCtx.hDevice, pReqBuf);
}
return -1;
}
int Codec_OSAL_QueryBuf(
CodecOSALVideoContext *pCtx,
CodecOSAL_Buffer *pBuf)
{
if ((pCtx != NULL) &&
(pBuf != NULL) &&
(pCtx->videoCtx.hDevice >= 0)) {
struct v4l2_buffer buf;
struct v4l2_plane planes[VIDEO_BUFFER_MAX_PLANES];
int i;
memset(&buf, 0, sizeof(buf));
memset(&planes, 0, sizeof(planes));
buf.type = pBuf->type;
buf.m.planes = planes;
buf.length = pBuf->nPlane;
buf.memory = pBuf->memory;
if (exynos_v4l2_querybuf(pCtx->videoCtx.hDevice, &buf) == 0) {
for (i = 0; i < (int)buf.length; i++) {
pBuf->planes[i].bufferSize = buf.m.planes[i].length;
pBuf->planes[i].offset = buf.m.planes[i].m.mem_offset;
}
return 0;
}
}
return -1;
}
int Codec_OSAL_SetStreamOn(
CodecOSALVideoContext *pCtx,
int nPort)
{
if ((pCtx != NULL) &&
(pCtx->videoCtx.hDevice >= 0)) {
return exynos_v4l2_streamon(pCtx->videoCtx.hDevice, nPort);
}
return -1;
}
int Codec_OSAL_SetStreamOff(
CodecOSALVideoContext *pCtx,
int nPort)
{
if ((pCtx != NULL) &&
(pCtx->videoCtx.hDevice >= 0)) {
return exynos_v4l2_streamoff(pCtx->videoCtx.hDevice, nPort);
}
return -1;
}
void *Codec_OSAL_MemoryMap(void *addr, size_t len, int prot, int flags, unsigned long fd, off_t offset)
{
return mmap(addr, len, prot, flags, fd, offset);
}
int Codec_OSAL_MemoryUnmap(void *addr, size_t len)
{
return munmap(addr, len);
}