tw5864-h264.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * TW5864 driver - H.264 headers generation functions
  4. *
  5. * Copyright (C) 2016 Bluecherry, LLC <[email protected]>
  6. */
  7. #include <linux/log2.h>
  8. #include "tw5864.h"
  9. static u8 marker[] = { 0x00, 0x00, 0x00, 0x01 };
  10. /*
  11. * Exponential-Golomb coding functions
  12. *
  13. * These functions are used for generation of H.264 bitstream headers.
  14. *
  15. * This code is derived from tw5864 reference driver by manufacturers, which
  16. * itself apparently was derived from x264 project.
  17. */
  18. /* Bitstream writing context */
  19. struct bs {
  20. u8 *buf; /* pointer to buffer beginning */
  21. u8 *buf_end; /* pointer to buffer end */
  22. u8 *ptr; /* pointer to current byte in buffer */
  23. unsigned int bits_left; /* number of available bits in current byte */
  24. };
  25. static void bs_init(struct bs *s, void *buf, int size)
  26. {
  27. s->buf = buf;
  28. s->ptr = buf;
  29. s->buf_end = s->ptr + size;
  30. s->bits_left = 8;
  31. }
  32. static int bs_len(struct bs *s)
  33. {
  34. return s->ptr - s->buf;
  35. }
  36. static void bs_write(struct bs *s, int count, u32 bits)
  37. {
  38. if (s->ptr >= s->buf_end - 4)
  39. return;
  40. while (count > 0) {
  41. if (count < 32)
  42. bits &= (1 << count) - 1;
  43. if (count < s->bits_left) {
  44. *s->ptr = (*s->ptr << count) | bits;
  45. s->bits_left -= count;
  46. break;
  47. }
  48. *s->ptr = (*s->ptr << s->bits_left) |
  49. (bits >> (count - s->bits_left));
  50. count -= s->bits_left;
  51. s->ptr++;
  52. s->bits_left = 8;
  53. }
  54. }
  55. static void bs_write1(struct bs *s, u32 bit)
  56. {
  57. if (s->ptr < s->buf_end) {
  58. *s->ptr <<= 1;
  59. *s->ptr |= bit;
  60. s->bits_left--;
  61. if (s->bits_left == 0) {
  62. s->ptr++;
  63. s->bits_left = 8;
  64. }
  65. }
  66. }
  67. static void bs_write_ue(struct bs *s, u32 val)
  68. {
  69. if (val == 0) {
  70. bs_write1(s, 1);
  71. } else {
  72. val++;
  73. bs_write(s, 2 * fls(val) - 1, val);
  74. }
  75. }
  76. static void bs_write_se(struct bs *s, int val)
  77. {
  78. bs_write_ue(s, val <= 0 ? -val * 2 : val * 2 - 1);
  79. }
  80. static void bs_rbsp_trailing(struct bs *s)
  81. {
  82. bs_write1(s, 1);
  83. if (s->bits_left != 8)
  84. bs_write(s, s->bits_left, 0x00);
  85. }
  86. /* H.264 headers generation functions */
  87. static int tw5864_h264_gen_sps_rbsp(u8 *buf, size_t size, int width, int height)
  88. {
  89. struct bs bs, *s;
  90. s = &bs;
  91. bs_init(s, buf, size);
  92. bs_write(s, 8, 0x42); /* profile_idc, baseline */
  93. bs_write(s, 1, 1); /* constraint_set0_flag */
  94. bs_write(s, 1, 1); /* constraint_set1_flag */
  95. bs_write(s, 1, 0); /* constraint_set2_flag */
  96. bs_write(s, 5, 0); /* reserved_zero_5bits */
  97. bs_write(s, 8, 0x1e); /* level_idc */
  98. bs_write_ue(s, 0); /* seq_parameter_set_id */
  99. bs_write_ue(s, ilog2(MAX_GOP_SIZE) - 4); /* log2_max_frame_num_minus4 */
  100. bs_write_ue(s, 0); /* pic_order_cnt_type */
  101. /* log2_max_pic_order_cnt_lsb_minus4 */
  102. bs_write_ue(s, ilog2(MAX_GOP_SIZE) - 4);
  103. bs_write_ue(s, 1); /* num_ref_frames */
  104. bs_write(s, 1, 0); /* gaps_in_frame_num_value_allowed_flag */
  105. bs_write_ue(s, width / 16 - 1); /* pic_width_in_mbs_minus1 */
  106. bs_write_ue(s, height / 16 - 1); /* pic_height_in_map_units_minus1 */
  107. bs_write(s, 1, 1); /* frame_mbs_only_flag */
  108. bs_write(s, 1, 0); /* direct_8x8_inference_flag */
  109. bs_write(s, 1, 0); /* frame_cropping_flag */
  110. bs_write(s, 1, 0); /* vui_parameters_present_flag */
  111. bs_rbsp_trailing(s);
  112. return bs_len(s);
  113. }
  114. static int tw5864_h264_gen_pps_rbsp(u8 *buf, size_t size, int qp)
  115. {
  116. struct bs bs, *s;
  117. s = &bs;
  118. bs_init(s, buf, size);
  119. bs_write_ue(s, 0); /* pic_parameter_set_id */
  120. bs_write_ue(s, 0); /* seq_parameter_set_id */
  121. bs_write(s, 1, 0); /* entropy_coding_mode_flag */
  122. bs_write(s, 1, 0); /* pic_order_present_flag */
  123. bs_write_ue(s, 0); /* num_slice_groups_minus1 */
  124. bs_write_ue(s, 0); /* i_num_ref_idx_l0_active_minus1 */
  125. bs_write_ue(s, 0); /* i_num_ref_idx_l1_active_minus1 */
  126. bs_write(s, 1, 0); /* weighted_pred_flag */
  127. bs_write(s, 2, 0); /* weighted_bipred_idc */
  128. bs_write_se(s, qp - 26); /* pic_init_qp_minus26 */
  129. bs_write_se(s, qp - 26); /* pic_init_qs_minus26 */
  130. bs_write_se(s, 0); /* chroma_qp_index_offset */
  131. bs_write(s, 1, 0); /* deblocking_filter_control_present_flag */
  132. bs_write(s, 1, 0); /* constrained_intra_pred_flag */
  133. bs_write(s, 1, 0); /* redundant_pic_cnt_present_flag */
  134. bs_rbsp_trailing(s);
  135. return bs_len(s);
  136. }
  137. static int tw5864_h264_gen_slice_head(u8 *buf, size_t size,
  138. unsigned int idr_pic_id,
  139. unsigned int frame_gop_seqno,
  140. int *tail_nb_bits, u8 *tail)
  141. {
  142. struct bs bs, *s;
  143. int is_i_frame = frame_gop_seqno == 0;
  144. s = &bs;
  145. bs_init(s, buf, size);
  146. bs_write_ue(s, 0); /* first_mb_in_slice */
  147. bs_write_ue(s, is_i_frame ? 2 : 5); /* slice_type - I or P */
  148. bs_write_ue(s, 0); /* pic_parameter_set_id */
  149. bs_write(s, ilog2(MAX_GOP_SIZE), frame_gop_seqno); /* frame_num */
  150. if (is_i_frame)
  151. bs_write_ue(s, idr_pic_id);
  152. /* pic_order_cnt_lsb */
  153. bs_write(s, ilog2(MAX_GOP_SIZE), frame_gop_seqno);
  154. if (is_i_frame) {
  155. bs_write1(s, 0); /* no_output_of_prior_pics_flag */
  156. bs_write1(s, 0); /* long_term_reference_flag */
  157. } else {
  158. bs_write1(s, 0); /* num_ref_idx_active_override_flag */
  159. bs_write1(s, 0); /* ref_pic_list_reordering_flag_l0 */
  160. bs_write1(s, 0); /* adaptive_ref_pic_marking_mode_flag */
  161. }
  162. bs_write_se(s, 0); /* slice_qp_delta */
  163. if (s->bits_left != 8) {
  164. *tail = ((s->ptr[0]) << s->bits_left);
  165. *tail_nb_bits = 8 - s->bits_left;
  166. } else {
  167. *tail = 0;
  168. *tail_nb_bits = 0;
  169. }
  170. return bs_len(s);
  171. }
  172. void tw5864_h264_put_stream_header(u8 **buf, size_t *space_left, int qp,
  173. int width, int height)
  174. {
  175. int nal_len;
  176. /* SPS */
  177. memcpy(*buf, marker, sizeof(marker));
  178. *buf += 4;
  179. *space_left -= 4;
  180. **buf = 0x67; /* SPS NAL header */
  181. *buf += 1;
  182. *space_left -= 1;
  183. nal_len = tw5864_h264_gen_sps_rbsp(*buf, *space_left, width, height);
  184. *buf += nal_len;
  185. *space_left -= nal_len;
  186. /* PPS */
  187. memcpy(*buf, marker, sizeof(marker));
  188. *buf += 4;
  189. *space_left -= 4;
  190. **buf = 0x68; /* PPS NAL header */
  191. *buf += 1;
  192. *space_left -= 1;
  193. nal_len = tw5864_h264_gen_pps_rbsp(*buf, *space_left, qp);
  194. *buf += nal_len;
  195. *space_left -= nal_len;
  196. }
  197. void tw5864_h264_put_slice_header(u8 **buf, size_t *space_left,
  198. unsigned int idr_pic_id,
  199. unsigned int frame_gop_seqno,
  200. int *tail_nb_bits, u8 *tail)
  201. {
  202. int nal_len;
  203. memcpy(*buf, marker, sizeof(marker));
  204. *buf += 4;
  205. *space_left -= 4;
  206. /* Frame NAL header */
  207. **buf = (frame_gop_seqno == 0) ? 0x25 : 0x21;
  208. *buf += 1;
  209. *space_left -= 1;
  210. nal_len = tw5864_h264_gen_slice_head(*buf, *space_left, idr_pic_id,
  211. frame_gop_seqno, tail_nb_bits,
  212. tail);
  213. *buf += nal_len;
  214. *space_left -= nal_len;
  215. }