summaryrefslogtreecommitdiff
path: root/drivers/amvdec_ports/decoder/aml_mpeg12_parser.c (plain)
blob: 748a83f2ff7cd81eb49fb4f3b663f743b1909e1f
1#include <linux/kernel.h>
2#include <linux/types.h>
3#include <linux/vmalloc.h>
4#include <linux/mm.h>
5#include <linux/string.h>
6
7#include "aml_mpeg12_parser.h"
8#include "../utils/get_bits.h"
9#include "../utils/put_bits.h"
10#include "../utils/golomb.h"
11#include "../utils/common.h"
12#include "utils.h"
13
14const struct AVRational ff_mpeg12_frame_rate_tab[16] = {
15 { 0, 0},
16 {24000, 1001},
17 { 24, 1},
18 { 25, 1},
19 {30000, 1001},
20 { 30, 1},
21 { 50, 1},
22 {60000, 1001},
23 { 60, 1},
24 // Xing's 15fps: (9)
25 { 15, 1},
26 // libmpeg3's "Unofficial economy rates": (10-13)
27 { 5, 1},
28 { 10, 1},
29 { 12, 1},
30 { 15, 1},
31 { 0, 0},
32};
33
34const u8 *avpriv_find_start_code(const u8 *p, const u8 *end, u32 *state)
35{
36 int i;
37
38 if (p >= end)
39 return end;
40
41 for (i = 0; i < 3; i++) {
42 u32 tmp = *state << 8;
43 *state = tmp + *(p++);
44 if (tmp == 0x100 || p == end)
45 return p;
46 }
47
48 while (p < end) {
49 if (p[-1] > 1 ) p += 3;
50 else if (p[-2] ) p += 2;
51 else if (p[-3]|(p[-1]-1)) p++;
52 else {
53 p++;
54 break;
55 }
56 }
57
58 p = FFMIN(p, end) - 4;
59 *state = AV_RB32(p);
60
61 return p + 4;
62}
63
64static void mpegvideo_extract_headers(const u8 *buf, int buf_size,
65 struct mpeg12_param_sets *ps)
66{
67 struct MpvParseContext *pc = &ps->dec_ps;
68 const u8 *buf_end = buf + buf_size;
69 u32 start_code;
70 int frame_rate_index, ext_type, bytes_left;
71 int frame_rate_ext_n, frame_rate_ext_d;
72 int top_field_first, repeat_first_field, progressive_frame;
73 int horiz_size_ext, vert_size_ext, bit_rate_ext;
74 int bit_rate = 0;
75 int vbv_delay = 0;
76 int chroma_format;
77 enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE;
78 //FIXME replace the crap with get_bits()
79 pc->repeat_pict = 0;
80
81 while (buf < buf_end) {
82 start_code= -1;
83 buf= avpriv_find_start_code(buf, buf_end, &start_code);
84 bytes_left = buf_end - buf;
85 switch (start_code) {
86 case PICTURE_START_CODE:
87 if (bytes_left >= 2) {
88 pc->pict_type = (buf[1] >> 3) & 7;
89 if (bytes_left >= 4)
90 vbv_delay = ((buf[1] & 0x07) << 13) | (buf[2] << 5) | (buf[3] >> 3);
91 }
92 break;
93 case SEQ_START_CODE:
94 if (bytes_left >= 7) {
95 pc->width = (buf[0] << 4) | (buf[1] >> 4);
96 pc->height = ((buf[1] & 0x0f) << 8) | buf[2];
97
98 pix_fmt = AV_PIX_FMT_YUV420P;
99 frame_rate_index = buf[3] & 0xf;
100 pc->frame_rate = ff_mpeg12_frame_rate_tab[frame_rate_index];
101 bit_rate = (buf[4]<<10) | (buf[5]<<2) | (buf[6]>>6);
102 pc->ticks_per_frame = 1;
103 }
104 break;
105 case EXT_START_CODE:
106 if (bytes_left >= 1) {
107 ext_type = (buf[0] >> 4);
108 switch (ext_type) {
109 case 0x1: /* sequence extension */
110 if (bytes_left >= 6) {
111 horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7);
112 vert_size_ext = (buf[2] >> 5) & 3;
113 bit_rate_ext = ((buf[2] & 0x1F)<<7) | (buf[3]>>1);
114 frame_rate_ext_n = (buf[5] >> 5) & 3;
115 frame_rate_ext_d = (buf[5] & 0x1f);
116 pc->progressive_sequence = buf[1] & (1 << 3);
117 pc->has_b_frames= !(buf[5] >> 7);
118
119 chroma_format = (buf[1] >> 1) & 3;
120 switch (chroma_format) {
121 case 1: pix_fmt = AV_PIX_FMT_YUV420P; break;
122 case 2: pix_fmt = AV_PIX_FMT_YUV422P; break;
123 case 3: pix_fmt = AV_PIX_FMT_YUV444P; break;
124 }
125
126 pc->width = (pc->width & 0xFFF) | (horiz_size_ext << 12);
127 pc->height = (pc->height& 0xFFF) | ( vert_size_ext << 12);
128 bit_rate = (bit_rate&0x3FFFF) | (bit_rate_ext << 18);
129 //if(did_set_size)
130 //set_dim_ret = ff_set_dimensions(avctx, pc->width, pc->height);
131 pc->framerate.num = pc->frame_rate.num * (frame_rate_ext_n + 1);
132 pc->framerate.den = pc->frame_rate.den * (frame_rate_ext_d + 1);
133 pc->ticks_per_frame = 2;
134 }
135 break;
136 case 0x8: /* picture coding extension */
137 if (bytes_left >= 5) {
138 top_field_first = buf[3] & (1 << 7);
139 repeat_first_field = buf[3] & (1 << 1);
140 progressive_frame = buf[4] & (1 << 7);
141
142 /* check if we must repeat the frame */
143 pc->repeat_pict = 1;
144 if (repeat_first_field) {
145 if (pc->progressive_sequence) {
146 if (top_field_first)
147 pc->repeat_pict = 5;
148 else
149 pc->repeat_pict = 3;
150 } else if (progressive_frame) {
151 pc->repeat_pict = 2;
152 }
153 }
154
155 if (!pc->progressive_sequence && !progressive_frame) {
156 if (top_field_first)
157 pc->field_order = AV_FIELD_TT;
158 else
159 pc->field_order = AV_FIELD_BB;
160 } else
161 pc->field_order = AV_FIELD_PROGRESSIVE;
162 }
163 break;
164 }
165 }
166 break;
167 case -1:
168 goto the_end;
169 default:
170 /* we stop parsing when we encounter a slice. It ensures
171 that this function takes a negligible amount of time */
172 if (start_code >= SLICE_MIN_START_CODE &&
173 start_code <= SLICE_MAX_START_CODE)
174 goto the_end;
175 break;
176 }
177 }
178the_end:
179
180 if (pix_fmt != AV_PIX_FMT_NONE) {
181 pc->format = pix_fmt;
182 pc->coded_width = ALIGN(pc->width, 16);
183 pc->coded_height = ALIGN(pc->height, 16);
184 }
185}
186
187int mpeg12_decode_extradata_ps(u8 *buf, int size, struct mpeg12_param_sets *ps)
188{
189 ps->head_parsed = false;
190
191 mpegvideo_extract_headers(buf, size, ps);
192
193 if (ps->dec_ps.width && ps->dec_ps.height)
194 ps->head_parsed = true;
195
196 return 0;
197}
198
199