1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <linux/videodev2.h>
17#include <coda.h>
18
19static const u8 coda_filler_size[8] = { 0, 7, 14, 13, 12, 11, 10, 9 };
20
21static const u8 *coda_find_nal_header(const u8 *buf, const u8 *end)
22{
23 u32 val = 0xffffffff;
24
25 do {
26 val = val << 8 | *buf++;
27 if (buf >= end)
28 return NULL;
29 } while (val != 0x00000001);
30
31 return buf;
32}
33
34int coda_sps_parse_profile(struct coda_ctx *ctx, struct vb2_buffer *vb)
35{
36 const u8 *buf = vb2_plane_vaddr(vb, 0);
37 const u8 *end = buf + vb2_get_plane_payload(vb, 0);
38
39
40 do {
41 buf = coda_find_nal_header(buf, end);
42 if (!buf)
43 return -EINVAL;
44 } while ((*buf++ & 0x1f) != 0x7);
45
46 ctx->params.h264_profile_idc = buf[0];
47 ctx->params.h264_level_idc = buf[2];
48
49 return 0;
50}
51
52int coda_h264_filler_nal(int size, char *p)
53{
54 if (size < 6)
55 return -EINVAL;
56
57 p[0] = 0x00;
58 p[1] = 0x00;
59 p[2] = 0x00;
60 p[3] = 0x01;
61 p[4] = 0x0c;
62 memset(p + 5, 0xff, size - 6);
63
64 p[size - 1] = 0x80;
65
66 return 0;
67}
68
69int coda_h264_padding(int size, char *p)
70{
71 int nal_size;
72 int diff;
73
74 diff = size - (size & ~0x7);
75 if (diff == 0)
76 return 0;
77
78 nal_size = coda_filler_size[diff];
79 coda_h264_filler_nal(nal_size, p);
80
81 return nal_size;
82}
83
84int coda_h264_profile(int profile_idc)
85{
86 switch (profile_idc) {
87 case 66: return V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
88 case 77: return V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
89 case 88: return V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED;
90 case 100: return V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
91 default: return -EINVAL;
92 }
93}
94
95int coda_h264_level(int level_idc)
96{
97 switch (level_idc) {
98 case 10: return V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
99 case 9: return V4L2_MPEG_VIDEO_H264_LEVEL_1B;
100 case 11: return V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
101 case 12: return V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
102 case 13: return V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
103 case 20: return V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
104 case 21: return V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
105 case 22: return V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
106 case 30: return V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
107 case 31: return V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
108 case 32: return V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
109 case 40: return V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
110 case 41: return V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
111 default: return -EINVAL;
112 }
113}
114