tw5864-h264.c 6.7 KB

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