0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kernel.h>
0011 #include <linux/string.h>
0012 #include <linux/videodev2.h>
0013
0014 #include "coda.h"
0015
0016 static const u8 coda_filler_size[8] = { 0, 7, 14, 13, 12, 11, 10, 9 };
0017
0018 static const u8 *coda_find_nal_header(const u8 *buf, const u8 *end)
0019 {
0020 u32 val = 0xffffffff;
0021
0022 do {
0023 val = val << 8 | *buf++;
0024 if (buf >= end)
0025 return NULL;
0026 } while (val != 0x00000001);
0027
0028 return buf;
0029 }
0030
0031 int coda_sps_parse_profile(struct coda_ctx *ctx, struct vb2_buffer *vb)
0032 {
0033 const u8 *buf = vb2_plane_vaddr(vb, 0);
0034 const u8 *end = buf + vb2_get_plane_payload(vb, 0);
0035
0036
0037 do {
0038 buf = coda_find_nal_header(buf, end);
0039 if (!buf)
0040 return -EINVAL;
0041 } while ((*buf++ & 0x1f) != 0x7);
0042
0043 ctx->params.h264_profile_idc = buf[0];
0044 ctx->params.h264_level_idc = buf[2];
0045
0046 return 0;
0047 }
0048
0049 int coda_h264_filler_nal(int size, char *p)
0050 {
0051 if (size < 6)
0052 return -EINVAL;
0053
0054 p[0] = 0x00;
0055 p[1] = 0x00;
0056 p[2] = 0x00;
0057 p[3] = 0x01;
0058 p[4] = 0x0c;
0059 memset(p + 5, 0xff, size - 6);
0060
0061 p[size - 1] = 0x80;
0062
0063 return 0;
0064 }
0065
0066 int coda_h264_padding(int size, char *p)
0067 {
0068 int nal_size;
0069 int diff;
0070
0071 diff = size - (size & ~0x7);
0072 if (diff == 0)
0073 return 0;
0074
0075 nal_size = coda_filler_size[diff];
0076 coda_h264_filler_nal(nal_size, p);
0077
0078 return nal_size;
0079 }
0080
0081 int coda_h264_profile(int profile_idc)
0082 {
0083 switch (profile_idc) {
0084 case 66: return V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
0085 case 77: return V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
0086 case 88: return V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED;
0087 case 100: return V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
0088 default: return -EINVAL;
0089 }
0090 }
0091
0092 int coda_h264_level(int level_idc)
0093 {
0094 switch (level_idc) {
0095 case 10: return V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
0096 case 9: return V4L2_MPEG_VIDEO_H264_LEVEL_1B;
0097 case 11: return V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
0098 case 12: return V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
0099 case 13: return V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
0100 case 20: return V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
0101 case 21: return V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
0102 case 22: return V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
0103 case 30: return V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
0104 case 31: return V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
0105 case 32: return V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
0106 case 40: return V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
0107 case 41: return V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
0108 case 42: return V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
0109 case 50: return V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
0110 case 51: return V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
0111 default: return -EINVAL;
0112 }
0113 }
0114
0115 struct rbsp {
0116 char *buf;
0117 int size;
0118 int pos;
0119 };
0120
0121 static inline int rbsp_read_bit(struct rbsp *rbsp)
0122 {
0123 int shift = 7 - (rbsp->pos % 8);
0124 int ofs = rbsp->pos++ / 8;
0125
0126 if (ofs >= rbsp->size)
0127 return -EINVAL;
0128
0129 return (rbsp->buf[ofs] >> shift) & 1;
0130 }
0131
0132 static inline int rbsp_write_bit(struct rbsp *rbsp, int bit)
0133 {
0134 int shift = 7 - (rbsp->pos % 8);
0135 int ofs = rbsp->pos++ / 8;
0136
0137 if (ofs >= rbsp->size)
0138 return -EINVAL;
0139
0140 rbsp->buf[ofs] &= ~(1 << shift);
0141 rbsp->buf[ofs] |= bit << shift;
0142
0143 return 0;
0144 }
0145
0146 static inline int rbsp_read_bits(struct rbsp *rbsp, int num, int *val)
0147 {
0148 int i, ret;
0149 int tmp = 0;
0150
0151 if (num > 32)
0152 return -EINVAL;
0153
0154 for (i = 0; i < num; i++) {
0155 ret = rbsp_read_bit(rbsp);
0156 if (ret < 0)
0157 return ret;
0158 tmp |= ret << (num - i - 1);
0159 }
0160
0161 if (val)
0162 *val = tmp;
0163
0164 return 0;
0165 }
0166
0167 static int rbsp_write_bits(struct rbsp *rbsp, int num, int value)
0168 {
0169 int ret;
0170
0171 while (num--) {
0172 ret = rbsp_write_bit(rbsp, (value >> num) & 1);
0173 if (ret)
0174 return ret;
0175 }
0176
0177 return 0;
0178 }
0179
0180 static int rbsp_read_uev(struct rbsp *rbsp, unsigned int *val)
0181 {
0182 int leading_zero_bits = 0;
0183 unsigned int tmp = 0;
0184 int ret;
0185
0186 while ((ret = rbsp_read_bit(rbsp)) == 0)
0187 leading_zero_bits++;
0188 if (ret < 0)
0189 return ret;
0190
0191 if (leading_zero_bits > 0) {
0192 ret = rbsp_read_bits(rbsp, leading_zero_bits, &tmp);
0193 if (ret)
0194 return ret;
0195 }
0196
0197 if (val)
0198 *val = (1 << leading_zero_bits) - 1 + tmp;
0199
0200 return 0;
0201 }
0202
0203 static int rbsp_write_uev(struct rbsp *rbsp, unsigned int value)
0204 {
0205 int i;
0206 int ret;
0207 int tmp = value + 1;
0208 int leading_zero_bits = fls(tmp) - 1;
0209
0210 for (i = 0; i < leading_zero_bits; i++) {
0211 ret = rbsp_write_bit(rbsp, 0);
0212 if (ret)
0213 return ret;
0214 }
0215
0216 return rbsp_write_bits(rbsp, leading_zero_bits + 1, tmp);
0217 }
0218
0219 static int rbsp_read_sev(struct rbsp *rbsp, int *val)
0220 {
0221 unsigned int tmp;
0222 int ret;
0223
0224 ret = rbsp_read_uev(rbsp, &tmp);
0225 if (ret)
0226 return ret;
0227
0228 if (val) {
0229 if (tmp & 1)
0230 *val = (tmp + 1) / 2;
0231 else
0232 *val = -(tmp / 2);
0233 }
0234
0235 return 0;
0236 }
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250 int coda_h264_sps_fixup(struct coda_ctx *ctx, int width, int height, char *buf,
0251 int *size, int max_size)
0252 {
0253 int profile_idc;
0254 unsigned int pic_order_cnt_type;
0255 int pic_width_in_mbs_minus1, pic_height_in_map_units_minus1;
0256 int frame_mbs_only_flag, frame_cropping_flag;
0257 int vui_parameters_present_flag;
0258 unsigned int crop_right, crop_bottom;
0259 struct rbsp sps;
0260 int pos;
0261 int ret;
0262
0263 if (*size < 8 || *size >= max_size)
0264 return -EINVAL;
0265
0266 sps.buf = buf + 5;
0267 sps.size = *size - 5;
0268
0269 profile_idc = sps.buf[0];
0270
0271
0272 sps.pos = 24;
0273
0274
0275 ret = rbsp_read_uev(&sps, NULL);
0276 if (ret)
0277 return ret;
0278
0279 if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 ||
0280 profile_idc == 244 || profile_idc == 44 || profile_idc == 83 ||
0281 profile_idc == 86 || profile_idc == 118 || profile_idc == 128 ||
0282 profile_idc == 138 || profile_idc == 139 || profile_idc == 134 ||
0283 profile_idc == 135) {
0284 dev_err(ctx->fh.vdev->dev_parent,
0285 "%s: Handling profile_idc %d not implemented\n",
0286 __func__, profile_idc);
0287 return -EINVAL;
0288 }
0289
0290
0291 ret = rbsp_read_uev(&sps, NULL);
0292 if (ret)
0293 return ret;
0294
0295 ret = rbsp_read_uev(&sps, &pic_order_cnt_type);
0296 if (ret)
0297 return ret;
0298
0299 if (pic_order_cnt_type == 0) {
0300
0301 ret = rbsp_read_uev(&sps, NULL);
0302 if (ret)
0303 return ret;
0304 } else if (pic_order_cnt_type == 1) {
0305 unsigned int i, num_ref_frames_in_pic_order_cnt_cycle;
0306
0307
0308 ret = rbsp_read_bit(&sps);
0309 if (ret < 0)
0310 return ret;
0311
0312 ret = rbsp_read_sev(&sps, NULL);
0313 if (ret)
0314 return ret;
0315
0316 ret = rbsp_read_sev(&sps, NULL);
0317 if (ret)
0318 return ret;
0319
0320 ret = rbsp_read_uev(&sps,
0321 &num_ref_frames_in_pic_order_cnt_cycle);
0322 if (ret)
0323 return ret;
0324 for (i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) {
0325
0326 ret = rbsp_read_sev(&sps, NULL);
0327 if (ret)
0328 return ret;
0329 }
0330 }
0331
0332
0333 ret = rbsp_read_uev(&sps, NULL);
0334 if (ret)
0335 return ret;
0336
0337
0338 ret = rbsp_read_bit(&sps);
0339 if (ret < 0)
0340 return ret;
0341 ret = rbsp_read_uev(&sps, &pic_width_in_mbs_minus1);
0342 if (ret)
0343 return ret;
0344 ret = rbsp_read_uev(&sps, &pic_height_in_map_units_minus1);
0345 if (ret)
0346 return ret;
0347 frame_mbs_only_flag = ret = rbsp_read_bit(&sps);
0348 if (ret < 0)
0349 return ret;
0350 if (!frame_mbs_only_flag) {
0351
0352 ret = rbsp_read_bit(&sps);
0353 if (ret < 0)
0354 return ret;
0355 }
0356
0357 ret = rbsp_read_bit(&sps);
0358 if (ret < 0)
0359 return ret;
0360
0361
0362 pos = sps.pos;
0363 frame_cropping_flag = ret = rbsp_read_bit(&sps);
0364 if (ret < 0)
0365 return ret;
0366 if (frame_cropping_flag) {
0367 unsigned int crop_left, crop_top;
0368
0369 ret = rbsp_read_uev(&sps, &crop_left);
0370 if (ret)
0371 return ret;
0372 ret = rbsp_read_uev(&sps, &crop_right);
0373 if (ret)
0374 return ret;
0375 ret = rbsp_read_uev(&sps, &crop_top);
0376 if (ret)
0377 return ret;
0378 ret = rbsp_read_uev(&sps, &crop_bottom);
0379 if (ret)
0380 return ret;
0381 }
0382 vui_parameters_present_flag = ret = rbsp_read_bit(&sps);
0383 if (ret < 0)
0384 return ret;
0385 if (vui_parameters_present_flag) {
0386 dev_err(ctx->fh.vdev->dev_parent,
0387 "%s: Handling vui_parameters not implemented\n",
0388 __func__);
0389 return -EINVAL;
0390 }
0391
0392 crop_right = round_up(width, 16) - width;
0393 crop_bottom = round_up(height, 16) - height;
0394 crop_right /= 2;
0395 if (frame_mbs_only_flag)
0396 crop_bottom /= 2;
0397 else
0398 crop_bottom /= 4;
0399
0400
0401 sps.size = max_size - 5;
0402 sps.pos = pos;
0403 frame_cropping_flag = 1;
0404 ret = rbsp_write_bit(&sps, frame_cropping_flag);
0405 if (ret)
0406 return ret;
0407 ret = rbsp_write_uev(&sps, 0);
0408 if (ret)
0409 return ret;
0410 ret = rbsp_write_uev(&sps, crop_right);
0411 if (ret)
0412 return ret;
0413 ret = rbsp_write_uev(&sps, 0);
0414 if (ret)
0415 return ret;
0416 ret = rbsp_write_uev(&sps, crop_bottom);
0417 if (ret)
0418 return ret;
0419 ret = rbsp_write_bit(&sps, 0);
0420 if (ret)
0421 return ret;
0422 ret = rbsp_write_bit(&sps, 1);
0423 if (ret)
0424 return ret;
0425
0426 *size = 5 + DIV_ROUND_UP(sps.pos, 8);
0427
0428 return 0;
0429 }