[h264e]: Separate h264 encoder stream writing

Separate h264 encoder stream writing to a new module.

Change-Id: Ibf55a20ac73e4eb2e3a3d744573eded3ebd92662
Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
This commit is contained in:
Herman Chen
2019-04-17 11:13:19 +08:00
parent a1ae919a33
commit ef9d577baf
5 changed files with 304 additions and 242 deletions

View File

@@ -10,6 +10,7 @@ set(HAL_H264E_HDR
# hal h264 encoder sourse # hal h264 encoder sourse
set(HAL_H264E_SRC set(HAL_H264E_SRC
h264e_stream.c
hal_h264e_com.c hal_h264e_com.c
hal_h264e_api.c hal_h264e_api.c
) )

View File

@@ -0,0 +1,248 @@
/*
* Copyright 2015 - 2017 Rockchip Electronics 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.
*/
#include <stdio.h>
#include <string.h>
#include "mpp_log.h"
#include "mpp_mem.h"
#include "h264e_stream.h"
void hal_h264e_vpu_swap_endian(RK_U32 *buf, RK_S32 size_bytes)
{
RK_U32 i = 0;
RK_S32 words = size_bytes / 4;
RK_U32 val, val2, tmp, tmp2;
mpp_assert((size_bytes % 8) == 0);
while (words > 0) {
val = buf[i];
tmp = 0;
tmp |= (val & 0xFF) << 24;
tmp |= (val & 0xFF00) << 8;
tmp |= (val & 0xFF0000) >> 8;
tmp |= (val & 0xFF000000) >> 24;
{
val2 = buf[i + 1];
tmp2 = 0;
tmp2 |= (val2 & 0xFF) << 24;
tmp2 |= (val2 & 0xFF00) << 8;
tmp2 |= (val2 & 0xFF0000) >> 8;
tmp2 |= (val2 & 0xFF000000) >> 24;
buf[i] = tmp2;
words--;
i++;
}
buf[i] = tmp;
words--;
i++;
}
}
MPP_RET hal_h264e_vpu_stream_buffer_status(H264eVpuStream *stream)
{
if (stream->byte_cnt + 5 > stream->size) {
stream->overflow = 1;
return MPP_NOK;
}
return MPP_OK;
}
MPP_RET hal_h264e_vpu_stream_buffer_reset(H264eVpuStream *strmbuf)
{
strmbuf->stream = strmbuf->buffer;
strmbuf->byte_cnt = 0;
strmbuf->overflow = 0;
strmbuf->byte_buffer = 0;
strmbuf->buffered_bits = 0;
strmbuf->zero_bytes = 0;
strmbuf->emul_cnt = 0;
return MPP_OK;
}
MPP_RET hal_h264e_vpu_stream_buffer_init(H264eVpuStream *strmbuf, RK_S32 size)
{
strmbuf->buffer = mpp_calloc(RK_U8, size);
if (strmbuf->buffer == NULL) {
mpp_err("allocate stream buffer failed\n");
return MPP_NOK;
}
strmbuf->stream = strmbuf->buffer;
strmbuf->size = size;
strmbuf->byte_cnt = 0;
strmbuf->overflow = 0;
strmbuf->byte_buffer = 0;
strmbuf->buffered_bits = 0;
strmbuf->zero_bytes = 0;
strmbuf->emul_cnt = 0;
if (MPP_OK != hal_h264e_vpu_stream_buffer_status(strmbuf)) {
mpp_err("stream buffer is overflow, while init");
return MPP_NOK;
}
return MPP_OK;
}
void hal_h264e_vpu_stream_put_bits(H264eVpuStream *buffer,
RK_S32 value, RK_S32 number,
const char *name)
{
RK_S32 bits;
RK_U32 byte_buffer = buffer->byte_buffer;
RK_U8*stream = buffer->stream;
(void)name;
if (hal_h264e_vpu_stream_buffer_status(buffer) != 0)
return;
mpp_assert(value < (1 << number)); //opposite to 'BUG_ON' in kernel
mpp_assert(number < 25);
bits = number + buffer->buffered_bits;
value <<= (32 - bits);
byte_buffer = byte_buffer | value;
while (bits > 7) {
*stream = (RK_U8)(byte_buffer >> 24);
bits -= 8;
byte_buffer <<= 8;
stream++;
buffer->byte_cnt++;
}
buffer->byte_buffer = byte_buffer;
buffer->buffered_bits = (RK_U8)bits;
buffer->stream = stream;
return;
}
void hal_h264e_vpu_stream_put_bits_with_detect(H264eVpuStream * buffer,
RK_S32 value, RK_S32 number,
const char *name)
{
RK_S32 bits;
RK_U8 *stream = buffer->stream;
RK_U32 byte_buffer = buffer->byte_buffer;
(void)name;
if (value) {
mpp_assert(value < (1 << number));
mpp_assert(number < 25);
}
bits = number + buffer->buffered_bits;
byte_buffer = byte_buffer | ((RK_U32) value << (32 - bits));
while (bits > 7) {
RK_S32 zeroBytes = buffer->zero_bytes;
RK_S32 byteCnt = buffer->byte_cnt;
if (hal_h264e_vpu_stream_buffer_status(buffer) != MPP_OK)
return;
*stream = (RK_U8) (byte_buffer >> 24);
byteCnt++;
if ((zeroBytes == 2) && (*stream < 4)) {
*stream++ = 3;
*stream = (RK_U8) (byte_buffer >> 24);
byteCnt++;
zeroBytes = 0;
buffer->emul_cnt++;
}
if (*stream == 0)
zeroBytes++;
else
zeroBytes = 0;
bits -= 8;
byte_buffer <<= 8;
stream++;
buffer->zero_bytes = zeroBytes;
buffer->byte_cnt = byteCnt;
buffer->stream = stream;
}
buffer->buffered_bits = (RK_U8) bits;
buffer->byte_buffer = byte_buffer;
}
void hal_h264e_vpu_rbsp_trailing_bits(H264eVpuStream * stream)
{
hal_h264e_vpu_stream_put_bits_with_detect(stream, 1, 1,
"rbsp_stop_one_bit");
if (stream->buffered_bits > 0)
hal_h264e_vpu_stream_put_bits_with_detect(stream, 0,
8 - stream->buffered_bits,
"bsp_alignment_zero_bit(s)");
}
void hal_h264e_vpu_write_ue(H264eVpuStream *fifo, RK_U32 val, const char *name)
{
RK_U32 num_bits = 0;
val++;
while (val >> ++num_bits);
if (num_bits > 12) {
RK_U32 tmp;
tmp = num_bits - 1;
if (tmp > 24) {
tmp -= 24;
hal_h264e_vpu_stream_put_bits_with_detect(fifo, 0, 24, name);
}
hal_h264e_vpu_stream_put_bits_with_detect(fifo, 0, tmp, name);
if (num_bits > 24) {
num_bits -= 24;
hal_h264e_vpu_stream_put_bits_with_detect(fifo, val >> num_bits,
24, name);
val = val >> num_bits;
}
hal_h264e_vpu_stream_put_bits_with_detect(fifo, val, num_bits, name);
} else {
hal_h264e_vpu_stream_put_bits_with_detect(fifo, val,
2 * num_bits - 1, name);
}
}
void hal_h264e_vpu_write_se(H264eVpuStream *fifo, RK_S32 val, const char *name)
{
RK_U32 tmp;
if (val > 0)
tmp = (RK_U32)(2 * val - 1);
else
tmp = (RK_U32)(-2 * val);
hal_h264e_vpu_write_ue(fifo, tmp, name);
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2015 - 2017 Rockchip Electronics 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.
*/
#ifndef __H264E_PUTBIT_H__
#define __H264E_PUTBIT_H__
#include "rk_type.h"
#include "mpp_err.h"
/* struct for assemble bitstream */
typedef struct H264eVpuStream_t {
RK_U8 *buffer; /* point to first byte of stream */
RK_U8 *stream; /* Pointer to next byte of stream */
RK_U32 size; /* Byte size of stream buffer */
RK_U32 byte_cnt; /* Byte counter */
RK_U32 bit_cnt; /* Bit counter */
RK_U32 byte_buffer; /* Byte buffer */
RK_U32 buffered_bits; /* Amount of bits in byte buffer, [0-7] */
RK_U32 zero_bytes; /* Amount of consecutive zero bytes */
RK_S32 overflow; /* This will signal a buffer overflow */
RK_U32 emul_cnt; /* Counter for emulation_3_byte, needed in SEI */
} H264eVpuStream;
void hal_h264e_vpu_swap_endian(RK_U32 *buf, RK_S32 size_bytes);
MPP_RET hal_h264e_vpu_stream_buffer_status(H264eVpuStream *stream);
MPP_RET hal_h264e_vpu_stream_buffer_reset(H264eVpuStream *strmbuf);
MPP_RET hal_h264e_vpu_stream_buffer_init(H264eVpuStream *strmbuf, RK_S32 size);
void hal_h264e_vpu_stream_put_bits(H264eVpuStream *buffer,
RK_S32 value, RK_S32 number,
const char *name);
void hal_h264e_vpu_stream_put_bits_with_detect(H264eVpuStream * buffer,
RK_S32 value, RK_S32 number,
const char *name);
void hal_h264e_vpu_rbsp_trailing_bits(H264eVpuStream * stream);
void hal_h264e_vpu_write_ue(H264eVpuStream *fifo, RK_U32 val, const char *name);
void hal_h264e_vpu_write_se(H264eVpuStream *fifo, RK_S32 val, const char *name);
RK_S32 exp_golomb_signed(RK_S32 val);
#endif /* __H264E_PUTBIT_H__ */

View File

@@ -27,40 +27,7 @@
#include "hal_h264e_vpu_tbl.h" #include "hal_h264e_vpu_tbl.h"
#include "hal_h264e_header.h" #include "hal_h264e_header.h"
static void hal_h264e_vpu_swap_endian(RK_U32 *buf, RK_S32 size_bytes) #include "h264e_stream.h"
{
RK_U32 i = 0;
RK_S32 words = size_bytes / 4;
RK_U32 val, val2, tmp, tmp2;
mpp_assert((size_bytes % 8) == 0);
while (words > 0) {
val = buf[i];
tmp = 0;
tmp |= (val & 0xFF) << 24;
tmp |= (val & 0xFF00) << 8;
tmp |= (val & 0xFF0000) >> 8;
tmp |= (val & 0xFF000000) >> 24;
{
val2 = buf[i + 1];
tmp2 = 0;
tmp2 |= (val2 & 0xFF) << 24;
tmp2 |= (val2 & 0xFF00) << 8;
tmp2 |= (val2 & 0xFF0000) >> 8;
tmp2 |= (val2 & 0xFF000000) >> 24;
buf[i] = tmp2;
words--;
i++;
}
buf[i] = tmp;
words--;
i++;
}
}
static void hal_h264e_vpu_write_cabac_table(MppBuffer hw_cabac_tab_buf, static void hal_h264e_vpu_write_cabac_table(MppBuffer hw_cabac_tab_buf,
RK_S32 cabac_init_idc) RK_S32 cabac_init_idc)
@@ -103,200 +70,6 @@ static void hal_h264e_vpu_write_cabac_table(MppBuffer hw_cabac_tab_buf,
h264e_hal_leave(); h264e_hal_leave();
} }
static MPP_RET hal_h264e_vpu_stream_buffer_status(H264eVpuStream *stream)
{
if (stream->byte_cnt + 5 > stream->size) {
stream->overflow = 1;
return MPP_NOK;
}
return MPP_OK;
}
static MPP_RET hal_h264e_vpu_stream_buffer_reset(H264eVpuStream *strmbuf)
{
strmbuf->stream = strmbuf->buffer;
strmbuf->byte_cnt = 0;
strmbuf->overflow = 0;
strmbuf->byte_buffer = 0;
strmbuf->buffered_bits = 0;
strmbuf->zero_bytes = 0;
strmbuf->emul_cnt = 0;
return MPP_OK;
}
static MPP_RET hal_h264e_vpu_stream_buffer_init(H264eVpuStream *strmbuf,
RK_S32 size)
{
strmbuf->buffer = mpp_calloc(RK_U8, size);
if (strmbuf->buffer == NULL) {
mpp_err("allocate stream buffer failed\n");
return MPP_NOK;
}
strmbuf->stream = strmbuf->buffer;
strmbuf->size = size;
strmbuf->byte_cnt = 0;
strmbuf->overflow = 0;
strmbuf->byte_buffer = 0;
strmbuf->buffered_bits = 0;
strmbuf->zero_bytes = 0;
strmbuf->emul_cnt = 0;
if (MPP_OK != hal_h264e_vpu_stream_buffer_status(strmbuf)) {
mpp_err("stream buffer is overflow, while init");
return MPP_NOK;
}
return MPP_OK;
}
static void hal_h264e_vpu_stream_put_bits(H264eVpuStream *buffer,
RK_S32 value, RK_S32 number,
const char *name)
{
RK_S32 bits;
RK_U32 byte_buffer = buffer->byte_buffer;
RK_U8*stream = buffer->stream;
(void)name;
if (hal_h264e_vpu_stream_buffer_status(buffer) != 0)
return;
mpp_assert(value < (1 << number)); //opposite to 'BUG_ON' in kernel
mpp_assert(number < 25);
bits = number + buffer->buffered_bits;
value <<= (32 - bits);
byte_buffer = byte_buffer | value;
while (bits > 7) {
*stream = (RK_U8)(byte_buffer >> 24);
bits -= 8;
byte_buffer <<= 8;
stream++;
buffer->byte_cnt++;
}
buffer->byte_buffer = byte_buffer;
buffer->buffered_bits = (RK_U8)bits;
buffer->stream = stream;
return;
}
static void
hal_h264e_vpu_stream_put_bits_with_detect(H264eVpuStream * buffer,
RK_S32 value, RK_S32 number,
const char *name)
{
RK_S32 bits;
RK_U8 *stream = buffer->stream;
RK_U32 byte_buffer = buffer->byte_buffer;
(void)name;
if (value) {
mpp_assert(value < (1 << number));
mpp_assert(number < 25);
}
bits = number + buffer->buffered_bits;
byte_buffer = byte_buffer | ((RK_U32) value << (32 - bits));
while (bits > 7) {
RK_S32 zeroBytes = buffer->zero_bytes;
RK_S32 byteCnt = buffer->byte_cnt;
if (hal_h264e_vpu_stream_buffer_status(buffer) != MPP_OK)
return;
*stream = (RK_U8) (byte_buffer >> 24);
byteCnt++;
if ((zeroBytes == 2) && (*stream < 4)) {
*stream++ = 3;
*stream = (RK_U8) (byte_buffer >> 24);
byteCnt++;
zeroBytes = 0;
buffer->emul_cnt++;
}
if (*stream == 0)
zeroBytes++;
else
zeroBytes = 0;
bits -= 8;
byte_buffer <<= 8;
stream++;
buffer->zero_bytes = zeroBytes;
buffer->byte_cnt = byteCnt;
buffer->stream = stream;
}
buffer->buffered_bits = (RK_U8) bits;
buffer->byte_buffer = byte_buffer;
}
static void hal_h264e_vpu_rbsp_trailing_bits(H264eVpuStream * stream)
{
hal_h264e_vpu_stream_put_bits_with_detect(stream, 1, 1,
"rbsp_stop_one_bit");
if (stream->buffered_bits > 0)
hal_h264e_vpu_stream_put_bits_with_detect(stream, 0,
8 - stream->buffered_bits,
"bsp_alignment_zero_bit(s)");
}
static void hal_h264e_vpu_write_ue(H264eVpuStream *fifo, RK_U32 val,
const char *name)
{
RK_U32 num_bits = 0;
val++;
while (val >> ++num_bits);
if (num_bits > 12) {
RK_U32 tmp;
tmp = num_bits - 1;
if (tmp > 24) {
tmp -= 24;
hal_h264e_vpu_stream_put_bits_with_detect(fifo, 0, 24, name);
}
hal_h264e_vpu_stream_put_bits_with_detect(fifo, 0, tmp, name);
if (num_bits > 24) {
num_bits -= 24;
hal_h264e_vpu_stream_put_bits_with_detect(fifo, val >> num_bits,
24, name);
val = val >> num_bits;
}
hal_h264e_vpu_stream_put_bits_with_detect(fifo, val, num_bits, name);
} else {
hal_h264e_vpu_stream_put_bits_with_detect(fifo, val,
2 * num_bits - 1, name);
}
}
static void hal_h264e_vpu_write_se(H264eVpuStream *fifo,
RK_S32 val, const char *name)
{
RK_U32 tmp;
if (val > 0)
tmp = (RK_U32)(2 * val - 1);
else
tmp = (RK_U32)(-2 * val);
hal_h264e_vpu_write_ue(fifo, tmp, name);
}
static MPP_RET h264e_vpu_nal_start(H264eVpuStream * stream, static MPP_RET h264e_vpu_nal_start(H264eVpuStream * stream,
RK_S32 nalRefIdc, RK_S32 nalRefIdc,
H264eNalUnitType nalUnitType) H264eNalUnitType nalUnitType)

View File

@@ -18,6 +18,7 @@
#define __HAL_H264E_VEPU_H__ #define __HAL_H264E_VEPU_H__
#include "hal_h264e_com.h" #include "hal_h264e_com.h"
#include "h264e_stream.h"
#define HAL_VPU_H264E_DBG_FUNCTION (0x00000001) #define HAL_VPU_H264E_DBG_FUNCTION (0x00000001)
#define HAL_VPU_H264E_DBG_QP (0x00000010) #define HAL_VPU_H264E_DBG_QP (0x00000010)
@@ -41,20 +42,6 @@ typedef enum H264eVpuFrameType_t {
H264E_VPU_FRAME_I = 1 H264E_VPU_FRAME_I = 1
} H264eVpuFrameType; } H264eVpuFrameType;
/* struct for assemble bitstream */
typedef struct H264eVpuStream_t {
RK_U8 *buffer; /* point to first byte of stream */
RK_U8 *stream; /* Pointer to next byte of stream */
RK_U32 size; /* Byte size of stream buffer */
RK_U32 byte_cnt; /* Byte counter */
RK_U32 bit_cnt; /* Bit counter */
RK_U32 byte_buffer; /* Byte buffer */
RK_U32 buffered_bits; /* Amount of bits in byte buffer, [0-7] */
RK_U32 zero_bytes; /* Amount of consecutive zero bytes */
RK_S32 overflow; /* This will signal a buffer overflow */
RK_U32 emul_cnt; /* Counter for emulation_3_byte, needed in SEI */
} H264eVpuStream;
typedef struct H264eVpuExtraInfo_t { typedef struct H264eVpuExtraInfo_t {
H264eVpuStream sps_stream; H264eVpuStream sps_stream;
H264eVpuStream pps_stream; H264eVpuStream pps_stream;