// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  TW5864 driver - H.264 headers generation functions
 *
 *  Copyright (C) 2016 Bluecherry, LLC <maintainers@bluecherrydvr.com>
 */

#include <linux/log2.h>

#include "tw5864.h"

static u8 marker[] = { 0x00, 0x00, 0x00, 0x01 };

/*
 * Exponential-Golomb coding functions
 *
 * These functions are used for generation of H.264 bitstream headers.
 *
 * This code is derived from tw5864 reference driver by manufacturers, which
 * itself apparently was derived from x264 project.
 */

/* Bitstream writing context */
struct bs {
	u8 *buf; /* pointer to buffer beginning */
	u8 *buf_end; /* pointer to buffer end */
	u8 *ptr; /* pointer to current byte in buffer */
	unsigned int bits_left; /* number of available bits in current byte */
};

static void bs_init(struct bs *s, void *buf, int size)
{
	s->buf = buf;
	s->ptr = buf;
	s->buf_end = s->ptr + size;
	s->bits_left = 8;
}

static int bs_len(struct bs *s)
{
	return s->ptr - s->buf;
}

static void bs_write(struct bs *s, int count, u32 bits)
{
	if (s->ptr >= s->buf_end - 4)
		return;
	while (count > 0) {
		if (count < 32)
			bits &= (1 << count) - 1;
		if (count < s->bits_left) {
			*s->ptr = (*s->ptr << count) | bits;
			s->bits_left -= count;
			break;
		}
		*s->ptr = (*s->ptr << s->bits_left) |
			(bits >> (count - s->bits_left));
		count -= s->bits_left;
		s->ptr++;
		s->bits_left = 8;
	}
}

static void bs_write1(struct bs *s, u32 bit)
{
	if (s->ptr < s->buf_end) {
		*s->ptr <<= 1;
		*s->ptr |= bit;
		s->bits_left--;
		if (s->bits_left == 0) {
			s->ptr++;
			s->bits_left = 8;
		}
	}
}

static void bs_write_ue(struct bs *s, u32 val)
{
	if (val == 0) {
		bs_write1(s, 1);
	} else {
		val++;
		bs_write(s, 2 * fls(val) - 1, val);
	}
}

static void bs_write_se(struct bs *s, int val)
{
	bs_write_ue(s, val <= 0 ? -val * 2 : val * 2 - 1);
}

static void bs_rbsp_trailing(struct bs *s)
{
	bs_write1(s, 1);
	if (s->bits_left != 8)
		bs_write(s, s->bits_left, 0x00);
}

/* H.264 headers generation functions */

static int tw5864_h264_gen_sps_rbsp(u8 *buf, size_t size, int width, int height)
{
	struct bs bs, *s;

	s = &bs;
	bs_init(s, buf, size);
	bs_write(s, 8, 0x42); /* profile_idc, baseline */
	bs_write(s, 1, 1); /* constraint_set0_flag */
	bs_write(s, 1, 1); /* constraint_set1_flag */
	bs_write(s, 1, 0); /* constraint_set2_flag */
	bs_write(s, 5, 0); /* reserved_zero_5bits */
	bs_write(s, 8, 0x1e); /* level_idc */
	bs_write_ue(s, 0); /* seq_parameter_set_id */
	bs_write_ue(s, ilog2(MAX_GOP_SIZE) - 4); /* log2_max_frame_num_minus4 */
	bs_write_ue(s, 0); /* pic_order_cnt_type */
	/* log2_max_pic_order_cnt_lsb_minus4 */
	bs_write_ue(s, ilog2(MAX_GOP_SIZE) - 4);
	bs_write_ue(s, 1); /* num_ref_frames */
	bs_write(s, 1, 0); /* gaps_in_frame_num_value_allowed_flag */
	bs_write_ue(s, width / 16 - 1); /* pic_width_in_mbs_minus1 */
	bs_write_ue(s, height / 16 - 1); /* pic_height_in_map_units_minus1 */
	bs_write(s, 1, 1); /* frame_mbs_only_flag */
	bs_write(s, 1, 0); /* direct_8x8_inference_flag */
	bs_write(s, 1, 0); /* frame_cropping_flag */
	bs_write(s, 1, 0); /* vui_parameters_present_flag */
	bs_rbsp_trailing(s);
	return bs_len(s);
}

static int tw5864_h264_gen_pps_rbsp(u8 *buf, size_t size, int qp)
{
	struct bs bs, *s;

	s = &bs;
	bs_init(s, buf, size);
	bs_write_ue(s, 0); /* pic_parameter_set_id */
	bs_write_ue(s, 0); /* seq_parameter_set_id */
	bs_write(s, 1, 0); /* entropy_coding_mode_flag */
	bs_write(s, 1, 0); /* pic_order_present_flag */
	bs_write_ue(s, 0); /* num_slice_groups_minus1 */
	bs_write_ue(s, 0); /* i_num_ref_idx_l0_active_minus1 */
	bs_write_ue(s, 0); /* i_num_ref_idx_l1_active_minus1 */
	bs_write(s, 1, 0); /* weighted_pred_flag */
	bs_write(s, 2, 0); /* weighted_bipred_idc */
	bs_write_se(s, qp - 26); /* pic_init_qp_minus26 */
	bs_write_se(s, qp - 26); /* pic_init_qs_minus26 */
	bs_write_se(s, 0); /* chroma_qp_index_offset */
	bs_write(s, 1, 0); /* deblocking_filter_control_present_flag */
	bs_write(s, 1, 0); /* constrained_intra_pred_flag */
	bs_write(s, 1, 0); /* redundant_pic_cnt_present_flag */
	bs_rbsp_trailing(s);
	return bs_len(s);
}

static int tw5864_h264_gen_slice_head(u8 *buf, size_t size,
				      unsigned int idr_pic_id,
				      unsigned int frame_gop_seqno,
				      int *tail_nb_bits, u8 *tail)
{
	struct bs bs, *s;
	int is_i_frame = frame_gop_seqno == 0;

	s = &bs;
	bs_init(s, buf, size);
	bs_write_ue(s, 0); /* first_mb_in_slice */
	bs_write_ue(s, is_i_frame ? 2 : 5); /* slice_type - I or P */
	bs_write_ue(s, 0); /* pic_parameter_set_id */
	bs_write(s, ilog2(MAX_GOP_SIZE), frame_gop_seqno); /* frame_num */
	if (is_i_frame)
		bs_write_ue(s, idr_pic_id);

	/* pic_order_cnt_lsb */
	bs_write(s, ilog2(MAX_GOP_SIZE), frame_gop_seqno);

	if (is_i_frame) {
		bs_write1(s, 0); /* no_output_of_prior_pics_flag */
		bs_write1(s, 0); /* long_term_reference_flag */
	} else {
		bs_write1(s, 0); /* num_ref_idx_active_override_flag */
		bs_write1(s, 0); /* ref_pic_list_reordering_flag_l0 */
		bs_write1(s, 0); /* adaptive_ref_pic_marking_mode_flag */
	}

	bs_write_se(s, 0); /* slice_qp_delta */

	if (s->bits_left != 8) {
		*tail = ((s->ptr[0]) << s->bits_left);
		*tail_nb_bits = 8 - s->bits_left;
	} else {
		*tail = 0;
		*tail_nb_bits = 0;
	}

	return bs_len(s);
}

void tw5864_h264_put_stream_header(u8 **buf, size_t *space_left, int qp,
				   int width, int height)
{
	int nal_len;

	/* SPS */
	memcpy(*buf, marker, sizeof(marker));
	*buf += 4;
	*space_left -= 4;

	**buf = 0x67; /* SPS NAL header */
	*buf += 1;
	*space_left -= 1;

	nal_len = tw5864_h264_gen_sps_rbsp(*buf, *space_left, width, height);
	*buf += nal_len;
	*space_left -= nal_len;

	/* PPS */
	memcpy(*buf, marker, sizeof(marker));
	*buf += 4;
	*space_left -= 4;

	**buf = 0x68; /* PPS NAL header */
	*buf += 1;
	*space_left -= 1;

	nal_len = tw5864_h264_gen_pps_rbsp(*buf, *space_left, qp);
	*buf += nal_len;
	*space_left -= nal_len;
}

void tw5864_h264_put_slice_header(u8 **buf, size_t *space_left,
				  unsigned int idr_pic_id,
				  unsigned int frame_gop_seqno,
				  int *tail_nb_bits, u8 *tail)
{
	int nal_len;

	memcpy(*buf, marker, sizeof(marker));
	*buf += 4;
	*space_left -= 4;

	/* Frame NAL header */
	**buf = (frame_gop_seqno == 0) ? 0x25 : 0x21;
	*buf += 1;
	*space_left -= 1;

	nal_len = tw5864_h264_gen_slice_head(*buf, *space_left, idr_pic_id,
					     frame_gop_seqno, tail_nb_bits,
					     tail);
	*buf += nal_len;
	*space_left -= nal_len;
}
