1 /*
2 * MxPEG decoder
3 * Copyright (c) 2011 Anatoly Nenashev
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22
23 /**
24 * @file
25 * MxPEG decoder
26 */
27
34
47
49 {
52
54
55 for (
i = 0;
i < 2; ++
i)
57
61
62 return 0;
63 }
64
66 {
69
72
75 if (!
s->picture[0] || !
s->picture[1])
77
78 s->jpg.picture_ptr =
s->picture[0];
80 }
81
83 const uint8_t *buf_ptr, int buf_size)
84 {
86 if (buf_size < 2)
87 return 0;
90
91 return 0;
92 }
93
95 const uint8_t *buf_ptr, int buf_size)
96 {
97 unsigned bitmask_size, mb_count;
99
102 mb_count =
s->mb_width *
s->mb_height;
103
104 bitmask_size = (mb_count + 7) >> 3;
105 if (bitmask_size > buf_size - 12) {
107 "MXM bitmask is not complete\n");
109 }
110
111 if (
s->bitmask_size != bitmask_size) {
115 if (!
s->mxm_bitmask) {
117 "MXM bitmask memory allocation error\n");
119 }
120
123 if (!
s->completion_bitmask) {
125 "Completion bitmask memory allocation error\n");
127 }
128
129 s->bitmask_size = bitmask_size;
130 }
131
132 memcpy(
s->mxm_bitmask, buf_ptr + 12, bitmask_size);
133 s->got_mxm_bitmask = 1;
134
135 if (!
s->has_complete_frame) {
136 uint8_t completion_check = 0xFF;
137 for (
i = 0;
i < bitmask_size; ++
i) {
138 s->completion_bitmask[
i] |=
s->mxm_bitmask[
i];
139 completion_check &=
s->completion_bitmask[
i];
140 }
141 s->has_complete_frame = !(completion_check ^ 0xFF);
142 }
143
144 return 0;
145 }
146
148 const uint8_t *buf_ptr, int buf_size)
149 {
151 if (buf_size < 2)
152 return 0;
154 if (
len > 14 &&
len <= buf_size && !strncmp(buf_ptr + 2,
"MXM", 3)) {
156 }
158
160 }
161
164 {
165 if ((jpg->
width + 0x0F)>>4 !=
s->mb_width ||
166 (jpg->
height + 0x0F)>>4 !=
s->mb_height) {
168 "Picture dimensions stored in SOF and MXM mismatch\n");
170 }
171
172 if (reference_ptr->
data[0]) {
178 "Dimensions of current and reference picture mismatch\n");
180 }
181 }
187 }
188 }
189
190 return 0;
191 }
192
195 {
196 const uint8_t *buf = avpkt->
data;
197 int buf_size = avpkt->
size;
200 const uint8_t *buf_end, *buf_ptr;
201 const uint8_t *unescaped_buf_ptr;
202 int unescaped_buf_size;
205
208
209 buf_ptr = buf;
210 buf_end = buf + buf_size;
212 s->got_mxm_bitmask = 0;
213 s->got_sof_data = !!
s->got_sof_data;
214 while (buf_ptr < buf_end) {
216 &unescaped_buf_ptr, &unescaped_buf_size);
218 goto the_end;
219 {
221
224 }
225
229 goto the_end;
230 break;
232 goto the_end;
237 "quantization table decode error\n");
239 }
240 break;
245 "huffman table decode error\n");
247 }
248 break;
251 unescaped_buf_size);
254 break;
256 if (
s->got_sof_data > 1) {
258 "Multiple SOF in a frame\n");
260 }
264 "SOF data decode error\n");
267 }
270 "Interlaced mode not supported in MxPEG\n");
273 }
275 break;
277 if (!
s->got_sof_data) {
279 "Can not process SOS without SOF data, skipping\n");
280 break;
281 }
285 "First picture has no SOF, skipping\n");
286 break;
287 }
288 if (!
s->got_mxm_bitmask){
290 "Non-key frame has no MXM, skipping\n");
291 break;
292 }
293 /* use stored SOF data to allocate current picture */
301 } else {
304 }
305
306 if (
s->got_mxm_bitmask) {
307 AVFrame *reference_ptr =
s->picture[
s->picture_index ^ 1];
309 break;
310
311 /* allocate dummy reference picture if needed */
312 if (!reference_ptr->
data[0] &&
316
320 } else {
324 }
325
326 break;
327 }
328
330 }
331
332 }
333
334 the_end:
339 *got_frame = 1;
340
341 s->picture_index ^= 1;
343
344 if (!
s->has_complete_frame) {
345 if (!
s->got_mxm_bitmask)
346 s->has_complete_frame = 1;
347 else
348 *got_frame = 0;
349 }
350 }
351
352 return buf_ptr - buf;
353 }
354
365 .p.max_lowres = 3,
367 };