This source file includes following definitions.
- bs_init
- bs_len
- bs_write
- bs_write1
- bs_write_ue
- bs_write_se
- bs_rbsp_trailing
- tw5864_h264_gen_sps_rbsp
- tw5864_h264_gen_pps_rbsp
- tw5864_h264_gen_slice_head
- tw5864_h264_put_stream_header
- tw5864_h264_put_slice_header
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 #include <linux/log2.h>
   9 
  10 #include "tw5864.h"
  11 
  12 static u8 marker[] = { 0x00, 0x00, 0x00, 0x01 };
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 struct bs {
  25         u8 *buf; 
  26         u8 *buf_end; 
  27         u8 *ptr; 
  28         unsigned int bits_left; 
  29 };
  30 
  31 static void bs_init(struct bs *s, void *buf, int size)
  32 {
  33         s->buf = buf;
  34         s->ptr = buf;
  35         s->buf_end = s->ptr + size;
  36         s->bits_left = 8;
  37 }
  38 
  39 static int bs_len(struct bs *s)
  40 {
  41         return s->ptr - s->buf;
  42 }
  43 
  44 static void bs_write(struct bs *s, int count, u32 bits)
  45 {
  46         if (s->ptr >= s->buf_end - 4)
  47                 return;
  48         while (count > 0) {
  49                 if (count < 32)
  50                         bits &= (1 << count) - 1;
  51                 if (count < s->bits_left) {
  52                         *s->ptr = (*s->ptr << count) | bits;
  53                         s->bits_left -= count;
  54                         break;
  55                 }
  56                 *s->ptr = (*s->ptr << s->bits_left) |
  57                         (bits >> (count - s->bits_left));
  58                 count -= s->bits_left;
  59                 s->ptr++;
  60                 s->bits_left = 8;
  61         }
  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 
  77 static void bs_write_ue(struct bs *s, u32 val)
  78 {
  79         if (val == 0) {
  80                 bs_write1(s, 1);
  81         } else {
  82                 val++;
  83                 bs_write(s, 2 * fls(val) - 1, val);
  84         }
  85 }
  86 
  87 static void bs_write_se(struct bs *s, int val)
  88 {
  89         bs_write_ue(s, val <= 0 ? -val * 2 : val * 2 - 1);
  90 }
  91 
  92 static void bs_rbsp_trailing(struct bs *s)
  93 {
  94         bs_write1(s, 1);
  95         if (s->bits_left != 8)
  96                 bs_write(s, s->bits_left, 0x00);
  97 }
  98 
  99 
 100 
 101 static int tw5864_h264_gen_sps_rbsp(u8 *buf, size_t size, int width, int height)
 102 {
 103         struct bs bs, *s;
 104 
 105         s = &bs;
 106         bs_init(s, buf, size);
 107         bs_write(s, 8, 0x42); 
 108         bs_write(s, 1, 1); 
 109         bs_write(s, 1, 1); 
 110         bs_write(s, 1, 0); 
 111         bs_write(s, 5, 0); 
 112         bs_write(s, 8, 0x1e); 
 113         bs_write_ue(s, 0); 
 114         bs_write_ue(s, ilog2(MAX_GOP_SIZE) - 4); 
 115         bs_write_ue(s, 0); 
 116         
 117         bs_write_ue(s, ilog2(MAX_GOP_SIZE) - 4);
 118         bs_write_ue(s, 1); 
 119         bs_write(s, 1, 0); 
 120         bs_write_ue(s, width / 16 - 1); 
 121         bs_write_ue(s, height / 16 - 1); 
 122         bs_write(s, 1, 1); 
 123         bs_write(s, 1, 0); 
 124         bs_write(s, 1, 0); 
 125         bs_write(s, 1, 0); 
 126         bs_rbsp_trailing(s);
 127         return bs_len(s);
 128 }
 129 
 130 static int tw5864_h264_gen_pps_rbsp(u8 *buf, size_t size, int qp)
 131 {
 132         struct bs bs, *s;
 133 
 134         s = &bs;
 135         bs_init(s, buf, size);
 136         bs_write_ue(s, 0); 
 137         bs_write_ue(s, 0); 
 138         bs_write(s, 1, 0); 
 139         bs_write(s, 1, 0); 
 140         bs_write_ue(s, 0); 
 141         bs_write_ue(s, 0); 
 142         bs_write_ue(s, 0); 
 143         bs_write(s, 1, 0); 
 144         bs_write(s, 2, 0); 
 145         bs_write_se(s, qp - 26); 
 146         bs_write_se(s, qp - 26); 
 147         bs_write_se(s, 0); 
 148         bs_write(s, 1, 0); 
 149         bs_write(s, 1, 0); 
 150         bs_write(s, 1, 0); 
 151         bs_rbsp_trailing(s);
 152         return bs_len(s);
 153 }
 154 
 155 static int tw5864_h264_gen_slice_head(u8 *buf, size_t size,
 156                                       unsigned int idr_pic_id,
 157                                       unsigned int frame_gop_seqno,
 158                                       int *tail_nb_bits, u8 *tail)
 159 {
 160         struct bs bs, *s;
 161         int is_i_frame = frame_gop_seqno == 0;
 162 
 163         s = &bs;
 164         bs_init(s, buf, size);
 165         bs_write_ue(s, 0); 
 166         bs_write_ue(s, is_i_frame ? 2 : 5); 
 167         bs_write_ue(s, 0); 
 168         bs_write(s, ilog2(MAX_GOP_SIZE), frame_gop_seqno); 
 169         if (is_i_frame)
 170                 bs_write_ue(s, idr_pic_id);
 171 
 172         
 173         bs_write(s, ilog2(MAX_GOP_SIZE), frame_gop_seqno);
 174 
 175         if (is_i_frame) {
 176                 bs_write1(s, 0); 
 177                 bs_write1(s, 0); 
 178         } else {
 179                 bs_write1(s, 0); 
 180                 bs_write1(s, 0); 
 181                 bs_write1(s, 0); 
 182         }
 183 
 184         bs_write_se(s, 0); 
 185 
 186         if (s->bits_left != 8) {
 187                 *tail = ((s->ptr[0]) << s->bits_left);
 188                 *tail_nb_bits = 8 - s->bits_left;
 189         } else {
 190                 *tail = 0;
 191                 *tail_nb_bits = 0;
 192         }
 193 
 194         return bs_len(s);
 195 }
 196 
 197 void tw5864_h264_put_stream_header(u8 **buf, size_t *space_left, int qp,
 198                                    int width, int height)
 199 {
 200         int nal_len;
 201 
 202         
 203         memcpy(*buf, marker, sizeof(marker));
 204         *buf += 4;
 205         *space_left -= 4;
 206 
 207         **buf = 0x67; 
 208         *buf += 1;
 209         *space_left -= 1;
 210 
 211         nal_len = tw5864_h264_gen_sps_rbsp(*buf, *space_left, width, height);
 212         *buf += nal_len;
 213         *space_left -= nal_len;
 214 
 215         
 216         memcpy(*buf, marker, sizeof(marker));
 217         *buf += 4;
 218         *space_left -= 4;
 219 
 220         **buf = 0x68; 
 221         *buf += 1;
 222         *space_left -= 1;
 223 
 224         nal_len = tw5864_h264_gen_pps_rbsp(*buf, *space_left, qp);
 225         *buf += nal_len;
 226         *space_left -= nal_len;
 227 }
 228 
 229 void tw5864_h264_put_slice_header(u8 **buf, size_t *space_left,
 230                                   unsigned int idr_pic_id,
 231                                   unsigned int frame_gop_seqno,
 232                                   int *tail_nb_bits, u8 *tail)
 233 {
 234         int nal_len;
 235 
 236         memcpy(*buf, marker, sizeof(marker));
 237         *buf += 4;
 238         *space_left -= 4;
 239 
 240         
 241         **buf = (frame_gop_seqno == 0) ? 0x25 : 0x21;
 242         *buf += 1;
 243         *space_left -= 1;
 244 
 245         nal_len = tw5864_h264_gen_slice_head(*buf, *space_left, idr_pic_id,
 246                                              frame_gop_seqno, tail_nb_bits,
 247                                              tail);
 248         *buf += nal_len;
 249         *space_left -= nal_len;
 250 }