3 * Copyright (c) 2011 Anatoly Nenashev
5 * This file is part of Libav.
7 * Libav 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.
12 * Libav 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.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
32 typedef struct MXpegDecodeContext
{
33 MJpegDecodeContext jpg
;
34 AVFrame picture
[2]; /* pictures array */
35 int picture_index
; /* index of current picture */
36 int got_sof_data
; /* true if SOF data successfully parsed */
37 int got_mxm_bitmask
; /* true if MXM bitmask available */
38 uint8_t *mxm_bitmask
; /* bitmask buffer */
39 unsigned bitmask_size
; /* size of bitmask */
40 int has_complete_frame
; /* true if has complete frame */
41 uint8_t *completion_bitmask
; /* completion bitmask of macroblocks */
42 unsigned mb_width
, mb_height
; /* size of picture in MB's from MXM header */
45 static av_cold
int mxpeg_decode_init(AVCodecContext
*avctx
)
47 MXpegDecodeContext
*s
= avctx
->priv_data
;
49 s
->jpg
.picture_ptr
= &s
->picture
[0];
50 return ff_mjpeg_decode_init(avctx
);
53 static int mxpeg_decode_app(MXpegDecodeContext
*s
,
54 const uint8_t *buf_ptr
, int buf_size
)
59 len
= AV_RB16(buf_ptr
);
60 skip_bits(&s
->jpg
.gb
, 8*FFMIN(len
,buf_size
));
65 static int mxpeg_decode_mxm(MXpegDecodeContext
*s
,
66 const uint8_t *buf_ptr
, int buf_size
)
68 unsigned bitmask_size
, mb_count
;
71 s
->mb_width
= AV_RL16(buf_ptr
+4);
72 s
->mb_height
= AV_RL16(buf_ptr
+6);
73 mb_count
= s
->mb_width
* s
->mb_height
;
75 bitmask_size
= (mb_count
+ 7) >> 3;
76 if (bitmask_size
> buf_size
- 12) {
77 av_log(s
->jpg
.avctx
, AV_LOG_ERROR
,
78 "MXM bitmask is not complete\n");
79 return AVERROR(EINVAL
);
82 if (s
->bitmask_size
!= bitmask_size
) {
83 av_freep(&s
->mxm_bitmask
);
84 s
->mxm_bitmask
= av_malloc(bitmask_size
);
85 if (!s
->mxm_bitmask
) {
86 av_log(s
->jpg
.avctx
, AV_LOG_ERROR
,
87 "MXM bitmask memory allocation error\n");
88 return AVERROR(ENOMEM
);
91 av_freep(&s
->completion_bitmask
);
92 s
->completion_bitmask
= av_mallocz(bitmask_size
);
93 if (!s
->completion_bitmask
) {
94 av_log(s
->jpg
.avctx
, AV_LOG_ERROR
,
95 "Completion bitmask memory allocation error\n");
96 return AVERROR(ENOMEM
);
99 s
->bitmask_size
= bitmask_size
;
102 memcpy(s
->mxm_bitmask
, buf_ptr
+ 12, bitmask_size
);
103 s
->got_mxm_bitmask
= 1;
105 if (!s
->has_complete_frame
) {
106 uint8_t completion_check
= 0xFF;
107 for (i
= 0; i
< bitmask_size
; ++i
) {
108 s
->completion_bitmask
[i
] |= s
->mxm_bitmask
[i
];
109 completion_check
&= s
->completion_bitmask
[i
];
111 s
->has_complete_frame
= !(completion_check
^ 0xFF);
117 static int mxpeg_decode_com(MXpegDecodeContext
*s
,
118 const uint8_t *buf_ptr
, int buf_size
)
123 len
= AV_RB16(buf_ptr
);
124 if (len
> 14 && len
<= buf_size
&& !strncmp(buf_ptr
+ 2, "MXM", 3)) {
125 ret
= mxpeg_decode_mxm(s
, buf_ptr
+ 2, len
- 2);
127 skip_bits(&s
->jpg
.gb
, 8*FFMIN(len
,buf_size
));
132 static int mxpeg_check_dimensions(MXpegDecodeContext
*s
, MJpegDecodeContext
*jpg
,
133 AVFrame
*reference_ptr
)
135 if ((jpg
->width
+ 0x0F)>>4 != s
->mb_width
||
136 (jpg
->height
+ 0x0F)>>4 != s
->mb_height
) {
137 av_log(jpg
->avctx
, AV_LOG_ERROR
,
138 "Picture dimensions stored in SOF and MXM mismatch\n");
139 return AVERROR(EINVAL
);
142 if (reference_ptr
->data
[0]) {
144 for (i
= 0; i
< MAX_COMPONENTS
; ++i
) {
145 if ( (!reference_ptr
->data
[i
] ^ !jpg
->picture_ptr
->data
[i
]) ||
146 reference_ptr
->linesize
[i
] != jpg
->picture_ptr
->linesize
[i
]) {
147 av_log(jpg
->avctx
, AV_LOG_ERROR
,
148 "Dimensions of current and reference picture mismatch\n");
149 return AVERROR(EINVAL
);
157 static int mxpeg_decode_frame(AVCodecContext
*avctx
,
158 void *data
, int *got_frame
,
161 const uint8_t *buf
= avpkt
->data
;
162 int buf_size
= avpkt
->size
;
163 MXpegDecodeContext
*s
= avctx
->priv_data
;
164 MJpegDecodeContext
*jpg
= &s
->jpg
;
165 const uint8_t *buf_end
, *buf_ptr
;
166 const uint8_t *unescaped_buf_ptr
;
167 int unescaped_buf_size
;
172 buf_end
= buf
+ buf_size
;
173 jpg
->got_picture
= 0;
174 s
->got_mxm_bitmask
= 0;
175 while (buf_ptr
< buf_end
) {
176 start_code
= ff_mjpeg_find_marker(jpg
, &buf_ptr
, buf_end
,
177 &unescaped_buf_ptr
, &unescaped_buf_size
);
181 init_get_bits(&jpg
->gb
, unescaped_buf_ptr
, unescaped_buf_size
*8);
183 if (start_code
>= APP0
&& start_code
<= APP15
) {
184 mxpeg_decode_app(s
, unescaped_buf_ptr
, unescaped_buf_size
);
187 switch (start_code
) {
189 if (jpg
->got_picture
) //emulating EOI
195 ret
= ff_mjpeg_decode_dqt(jpg
);
197 av_log(avctx
, AV_LOG_ERROR
,
198 "quantization table decode error\n");
203 ret
= ff_mjpeg_decode_dht(jpg
);
205 av_log(avctx
, AV_LOG_ERROR
,
206 "huffman table decode error\n");
211 ret
= mxpeg_decode_com(s
, unescaped_buf_ptr
,
218 ret
= ff_mjpeg_decode_sof(jpg
);
220 av_log(avctx
, AV_LOG_ERROR
,
221 "SOF data decode error\n");
224 if (jpg
->interlaced
) {
225 av_log(avctx
, AV_LOG_ERROR
,
226 "Interlaced mode not supported in MxPEG\n");
227 return AVERROR(EINVAL
);
232 if (!s
->got_sof_data
) {
233 av_log(avctx
, AV_LOG_WARNING
,
234 "Can not process SOS without SOF data, skipping\n");
237 if (!jpg
->got_picture
) {
238 if (jpg
->first_picture
) {
239 av_log(avctx
, AV_LOG_WARNING
,
240 "First picture has no SOF, skipping\n");
243 if (!s
->got_mxm_bitmask
){
244 av_log(avctx
, AV_LOG_WARNING
,
245 "Non-key frame has no MXM, skipping\n");
248 /* use stored SOF data to allocate current picture */
249 av_frame_unref(jpg
->picture_ptr
);
250 if (ff_get_buffer(avctx
, jpg
->picture_ptr
,
251 AV_GET_BUFFER_FLAG_REF
) < 0) {
252 av_log(avctx
, AV_LOG_ERROR
, "get_buffer() failed\n");
253 return AVERROR(ENOMEM
);
255 jpg
->picture_ptr
->pict_type
= AV_PICTURE_TYPE_P
;
256 jpg
->picture_ptr
->key_frame
= 0;
257 jpg
->got_picture
= 1;
259 jpg
->picture_ptr
->pict_type
= AV_PICTURE_TYPE_I
;
260 jpg
->picture_ptr
->key_frame
= 1;
263 if (s
->got_mxm_bitmask
) {
264 AVFrame
*reference_ptr
= &s
->picture
[s
->picture_index
^ 1];
265 if (mxpeg_check_dimensions(s
, jpg
, reference_ptr
) < 0)
268 /* allocate dummy reference picture if needed */
269 if (!reference_ptr
->data
[0] &&
270 ff_get_buffer(avctx
, reference_ptr
,
271 AV_GET_BUFFER_FLAG_REF
) < 0) {
272 av_log(avctx
, AV_LOG_ERROR
, "get_buffer() failed\n");
273 return AVERROR(ENOMEM
);
276 ret
= ff_mjpeg_decode_sos(jpg
, s
->mxm_bitmask
, reference_ptr
);
277 if (ret
< 0 && (avctx
->err_recognition
& AV_EF_EXPLODE
))
280 ret
= ff_mjpeg_decode_sos(jpg
, NULL
, NULL
);
281 if (ret
< 0 && (avctx
->err_recognition
& AV_EF_EXPLODE
))
288 buf_ptr
+= (get_bits_count(&jpg
->gb
)+7) >> 3;
294 if (jpg
->got_picture
) {
295 int ret
= av_frame_ref(data
, jpg
->picture_ptr
);
300 s
->picture_index
^= 1;
301 jpg
->picture_ptr
= &s
->picture
[s
->picture_index
];
303 if (!s
->has_complete_frame
) {
304 if (!s
->got_mxm_bitmask
)
305 s
->has_complete_frame
= 1;
311 return buf_ptr
- buf
;
314 static av_cold
int mxpeg_decode_end(AVCodecContext
*avctx
)
316 MXpegDecodeContext
*s
= avctx
->priv_data
;
317 MJpegDecodeContext
*jpg
= &s
->jpg
;
320 jpg
->picture_ptr
= NULL
;
321 ff_mjpeg_decode_end(avctx
);
323 for (i
= 0; i
< 2; ++i
)
324 av_frame_unref(&s
->picture
[i
]);
326 av_freep(&s
->mxm_bitmask
);
327 av_freep(&s
->completion_bitmask
);
332 AVCodec ff_mxpeg_decoder
= {
334 .long_name
= NULL_IF_CONFIG_SMALL("Mobotix MxPEG video"),
335 .type
= AVMEDIA_TYPE_VIDEO
,
336 .id
= AV_CODEC_ID_MXPEG
,
337 .priv_data_size
= sizeof(MXpegDecodeContext
),
338 .init
= mxpeg_decode_init
,
339 .close
= mxpeg_decode_end
,
340 .decode
= mxpeg_decode_frame
,
341 .capabilities
= CODEC_CAP_DR1
,