0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/log2.h>
0009
0010 #include "tw5864.h"
0011
0012 static u8 marker[] = { 0x00, 0x00, 0x00, 0x01 };
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 struct bs {
0025 u8 *buf;
0026 u8 *buf_end;
0027 u8 *ptr;
0028 unsigned int bits_left;
0029 };
0030
0031 static void bs_init(struct bs *s, void *buf, int size)
0032 {
0033 s->buf = buf;
0034 s->ptr = buf;
0035 s->buf_end = s->ptr + size;
0036 s->bits_left = 8;
0037 }
0038
0039 static int bs_len(struct bs *s)
0040 {
0041 return s->ptr - s->buf;
0042 }
0043
0044 static void bs_write(struct bs *s, int count, u32 bits)
0045 {
0046 if (s->ptr >= s->buf_end - 4)
0047 return;
0048 while (count > 0) {
0049 if (count < 32)
0050 bits &= (1 << count) - 1;
0051 if (count < s->bits_left) {
0052 *s->ptr = (*s->ptr << count) | bits;
0053 s->bits_left -= count;
0054 break;
0055 }
0056 *s->ptr = (*s->ptr << s->bits_left) |
0057 (bits >> (count - s->bits_left));
0058 count -= s->bits_left;
0059 s->ptr++;
0060 s->bits_left = 8;
0061 }
0062 }
0063
0064 static void bs_write1(struct bs *s, u32 bit)
0065 {
0066 if (s->ptr < s->buf_end) {
0067 *s->ptr <<= 1;
0068 *s->ptr |= bit;
0069 s->bits_left--;
0070 if (s->bits_left == 0) {
0071 s->ptr++;
0072 s->bits_left = 8;
0073 }
0074 }
0075 }
0076
0077 static void bs_write_ue(struct bs *s, u32 val)
0078 {
0079 if (val == 0) {
0080 bs_write1(s, 1);
0081 } else {
0082 val++;
0083 bs_write(s, 2 * fls(val) - 1, val);
0084 }
0085 }
0086
0087 static void bs_write_se(struct bs *s, int val)
0088 {
0089 bs_write_ue(s, val <= 0 ? -val * 2 : val * 2 - 1);
0090 }
0091
0092 static void bs_rbsp_trailing(struct bs *s)
0093 {
0094 bs_write1(s, 1);
0095 if (s->bits_left != 8)
0096 bs_write(s, s->bits_left, 0x00);
0097 }
0098
0099
0100
0101 static int tw5864_h264_gen_sps_rbsp(u8 *buf, size_t size, int width, int height)
0102 {
0103 struct bs bs, *s;
0104
0105 s = &bs;
0106 bs_init(s, buf, size);
0107 bs_write(s, 8, 0x42);
0108 bs_write(s, 1, 1);
0109 bs_write(s, 1, 1);
0110 bs_write(s, 1, 0);
0111 bs_write(s, 5, 0);
0112 bs_write(s, 8, 0x1e);
0113 bs_write_ue(s, 0);
0114 bs_write_ue(s, ilog2(MAX_GOP_SIZE) - 4);
0115 bs_write_ue(s, 0);
0116
0117 bs_write_ue(s, ilog2(MAX_GOP_SIZE) - 4);
0118 bs_write_ue(s, 1);
0119 bs_write(s, 1, 0);
0120 bs_write_ue(s, width / 16 - 1);
0121 bs_write_ue(s, height / 16 - 1);
0122 bs_write(s, 1, 1);
0123 bs_write(s, 1, 0);
0124 bs_write(s, 1, 0);
0125 bs_write(s, 1, 0);
0126 bs_rbsp_trailing(s);
0127 return bs_len(s);
0128 }
0129
0130 static int tw5864_h264_gen_pps_rbsp(u8 *buf, size_t size, int qp)
0131 {
0132 struct bs bs, *s;
0133
0134 s = &bs;
0135 bs_init(s, buf, size);
0136 bs_write_ue(s, 0);
0137 bs_write_ue(s, 0);
0138 bs_write(s, 1, 0);
0139 bs_write(s, 1, 0);
0140 bs_write_ue(s, 0);
0141 bs_write_ue(s, 0);
0142 bs_write_ue(s, 0);
0143 bs_write(s, 1, 0);
0144 bs_write(s, 2, 0);
0145 bs_write_se(s, qp - 26);
0146 bs_write_se(s, qp - 26);
0147 bs_write_se(s, 0);
0148 bs_write(s, 1, 0);
0149 bs_write(s, 1, 0);
0150 bs_write(s, 1, 0);
0151 bs_rbsp_trailing(s);
0152 return bs_len(s);
0153 }
0154
0155 static int tw5864_h264_gen_slice_head(u8 *buf, size_t size,
0156 unsigned int idr_pic_id,
0157 unsigned int frame_gop_seqno,
0158 int *tail_nb_bits, u8 *tail)
0159 {
0160 struct bs bs, *s;
0161 int is_i_frame = frame_gop_seqno == 0;
0162
0163 s = &bs;
0164 bs_init(s, buf, size);
0165 bs_write_ue(s, 0);
0166 bs_write_ue(s, is_i_frame ? 2 : 5);
0167 bs_write_ue(s, 0);
0168 bs_write(s, ilog2(MAX_GOP_SIZE), frame_gop_seqno);
0169 if (is_i_frame)
0170 bs_write_ue(s, idr_pic_id);
0171
0172
0173 bs_write(s, ilog2(MAX_GOP_SIZE), frame_gop_seqno);
0174
0175 if (is_i_frame) {
0176 bs_write1(s, 0);
0177 bs_write1(s, 0);
0178 } else {
0179 bs_write1(s, 0);
0180 bs_write1(s, 0);
0181 bs_write1(s, 0);
0182 }
0183
0184 bs_write_se(s, 0);
0185
0186 if (s->bits_left != 8) {
0187 *tail = ((s->ptr[0]) << s->bits_left);
0188 *tail_nb_bits = 8 - s->bits_left;
0189 } else {
0190 *tail = 0;
0191 *tail_nb_bits = 0;
0192 }
0193
0194 return bs_len(s);
0195 }
0196
0197 void tw5864_h264_put_stream_header(u8 **buf, size_t *space_left, int qp,
0198 int width, int height)
0199 {
0200 int nal_len;
0201
0202
0203 memcpy(*buf, marker, sizeof(marker));
0204 *buf += 4;
0205 *space_left -= 4;
0206
0207 **buf = 0x67;
0208 *buf += 1;
0209 *space_left -= 1;
0210
0211 nal_len = tw5864_h264_gen_sps_rbsp(*buf, *space_left, width, height);
0212 *buf += nal_len;
0213 *space_left -= nal_len;
0214
0215
0216 memcpy(*buf, marker, sizeof(marker));
0217 *buf += 4;
0218 *space_left -= 4;
0219
0220 **buf = 0x68;
0221 *buf += 1;
0222 *space_left -= 1;
0223
0224 nal_len = tw5864_h264_gen_pps_rbsp(*buf, *space_left, qp);
0225 *buf += nal_len;
0226 *space_left -= nal_len;
0227 }
0228
0229 void tw5864_h264_put_slice_header(u8 **buf, size_t *space_left,
0230 unsigned int idr_pic_id,
0231 unsigned int frame_gop_seqno,
0232 int *tail_nb_bits, u8 *tail)
0233 {
0234 int nal_len;
0235
0236 memcpy(*buf, marker, sizeof(marker));
0237 *buf += 4;
0238 *space_left -= 4;
0239
0240
0241 **buf = (frame_gop_seqno == 0) ? 0x25 : 0x21;
0242 *buf += 1;
0243 *space_left -= 1;
0244
0245 nal_len = tw5864_h264_gen_slice_head(*buf, *space_left, idr_pic_id,
0246 frame_gop_seqno, tail_nb_bits,
0247 tail);
0248 *buf += nal_len;
0249 *space_left -= nal_len;
0250 }