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
31 typedef struct MXpegDecodeContext
{
32 MJpegDecodeContext jpg
;
33 AVFrame picture
[2]; /* pictures array */
34 int picture_index
; /* index of current picture */
35 int got_sof_data
; /* true if SOF data successfully parsed */
36 int got_mxm_bitmask
; /* true if MXM bitmask available */
37 uint8_t *mxm_bitmask
; /* bitmask buffer */
38 unsigned bitmask_size
; /* size of bitmask */
39 int has_complete_frame
; /* true if has complete frame */
40 uint8_t *completion_bitmask
; /* completion bitmask of macroblocks */
41 unsigned mb_width
, mb_height
; /* size of picture in MB's from MXM header */
44 static av_cold
int mxpeg_decode_init(AVCodecContext
*avctx
)
46 MXpegDecodeContext
*s
= avctx
->priv_data
;
48 s
->picture
[0].reference
= s
->picture
[1].reference
= 3;
49 s
->jpg
.picture_ptr
= &s
->picture
[0];
50 ff_mjpeg_decode_init(avctx
);
55 static int mxpeg_decode_app(MXpegDecodeContext
*s
,
56 const uint8_t *buf_ptr
, int buf_size
)
61 len
= AV_RB16(buf_ptr
);
62 skip_bits(&s
->jpg
.gb
, 8*FFMIN(len
,buf_size
));
67 static int mxpeg_decode_mxm(MXpegDecodeContext
*s
,
68 const uint8_t *buf_ptr
, int buf_size
)
70 unsigned bitmask_size
, mb_count
;
73 s
->mb_width
= AV_RL16(buf_ptr
+4);
74 s
->mb_height
= AV_RL16(buf_ptr
+6);
75 mb_count
= s
->mb_width
* s
->mb_height
;
77 bitmask_size
= (mb_count
+ 7) >> 3;
78 if (bitmask_size
> buf_size
- 12) {
79 av_log(s
->jpg
.avctx
, AV_LOG_ERROR
,
80 "MXM bitmask is not complete\n");
81 return AVERROR(EINVAL
);
84 if (s
->bitmask_size
!= bitmask_size
) {
85 av_freep(&s
->mxm_bitmask
);
86 s
->mxm_bitmask
= av_malloc(bitmask_size
);
87 if (!s
->mxm_bitmask
) {
88 av_log(s
->jpg
.avctx
, AV_LOG_ERROR
,
89 "MXM bitmask memory allocation error\n");
90 return AVERROR(ENOMEM
);
93 av_freep(&s
->completion_bitmask
);
94 s
->completion_bitmask
= av_mallocz(bitmask_size
);
95 if (!s
->completion_bitmask
) {
96 av_log(s
->jpg
.avctx
, AV_LOG_ERROR
,
97 "Completion bitmask memory allocation error\n");
98 return AVERROR(ENOMEM
);
101 s
->bitmask_size
= bitmask_size
;
104 memcpy(s
->mxm_bitmask
, buf_ptr
+ 12, bitmask_size
);
105 s
->got_mxm_bitmask
= 1;
107 if (!s
->has_complete_frame
) {
108 uint8_t completion_check
= 0xFF;
109 for (i
= 0; i
< bitmask_size
; ++i
) {
110 s
->completion_bitmask
[i
] |= s
->mxm_bitmask
[i
];
111 completion_check
&= s
->completion_bitmask
[i
];
113 s
->has_complete_frame
= !(completion_check
^ 0xFF);
119 static int mxpeg_decode_com(MXpegDecodeContext
*s
,
120 const uint8_t *buf_ptr
, int buf_size
)
125 len
= AV_RB16(buf_ptr
);
126 if (len
> 14 && len
<= buf_size
&& !strncmp(buf_ptr
+ 2, "MXM", 3)) {
127 ret
= mxpeg_decode_mxm(s
, buf_ptr
+ 2, len
- 2);
129 skip_bits(&s
->jpg
.gb
, 8*FFMIN(len
,buf_size
));
134 static int mxpeg_check_dimensions(MXpegDecodeContext
*s
, MJpegDecodeContext
*jpg
,
135 AVFrame
*reference_ptr
)
137 if ((jpg
->width
+ 0x0F)>>4 != s
->mb_width
||
138 (jpg
->height
+ 0x0F)>>4 != s
->mb_height
) {
139 av_log(jpg
->avctx
, AV_LOG_ERROR
,
140 "Picture dimensions stored in SOF and MXM mismatch\n");
141 return AVERROR(EINVAL
);
144 if (reference_ptr
->data
[0]) {
146 for (i
= 0; i
< MAX_COMPONENTS
; ++i
) {
147 if ( (!reference_ptr
->data
[i
] ^ !jpg
->picture_ptr
->data
[i
]) ||
148 reference_ptr
->linesize
[i
] != jpg
->picture_ptr
->linesize
[i
]) {
149 av_log(jpg
->avctx
, AV_LOG_ERROR
,
150 "Dimensions of current and reference picture mismatch\n");
151 return AVERROR(EINVAL
);
159 static int mxpeg_decode_frame(AVCodecContext
*avctx
,
160 void *data
, int *data_size
,
163 const uint8_t *buf
= avpkt
->data
;
164 int buf_size
= avpkt
->size
;
165 MXpegDecodeContext
*s
= avctx
->priv_data
;
166 MJpegDecodeContext
*jpg
= &s
->jpg
;
167 const uint8_t *buf_end
, *buf_ptr
;
168 const uint8_t *unescaped_buf_ptr
;
169 int unescaped_buf_size
;
171 AVFrame
*picture
= data
;
175 buf_end
= buf
+ buf_size
;
176 jpg
->got_picture
= 0;
177 s
->got_mxm_bitmask
= 0;
178 while (buf_ptr
< buf_end
) {
179 start_code
= ff_mjpeg_find_marker(jpg
, &buf_ptr
, buf_end
,
180 &unescaped_buf_ptr
, &unescaped_buf_size
);
184 init_get_bits(&jpg
->gb
, unescaped_buf_ptr
, unescaped_buf_size
*8);
186 if (start_code
>= APP0
&& start_code
<= APP15
) {
187 mxpeg_decode_app(s
, unescaped_buf_ptr
, unescaped_buf_size
);
190 switch (start_code
) {
192 if (jpg
->got_picture
) //emulating EOI
198 ret
= ff_mjpeg_decode_dqt(jpg
);
200 av_log(avctx
, AV_LOG_ERROR
,
201 "quantization table decode error\n");
206 ret
= ff_mjpeg_decode_dht(jpg
);
208 av_log(avctx
, AV_LOG_ERROR
,
209 "huffman table decode error\n");
214 ret
= mxpeg_decode_com(s
, unescaped_buf_ptr
,
221 ret
= ff_mjpeg_decode_sof(jpg
);
223 av_log(avctx
, AV_LOG_ERROR
,
224 "SOF data decode error\n");
227 if (jpg
->interlaced
) {
228 av_log(avctx
, AV_LOG_ERROR
,
229 "Interlaced mode not supported in MxPEG\n");
230 return AVERROR(EINVAL
);
235 if (!s
->got_sof_data
) {
236 av_log(avctx
, AV_LOG_WARNING
,
237 "Can not process SOS without SOF data, skipping\n");
240 if (!jpg
->got_picture
) {
241 if (jpg
->first_picture
) {
242 av_log(avctx
, AV_LOG_WARNING
,
243 "First picture has no SOF, skipping\n");
246 if (!s
->got_mxm_bitmask
){
247 av_log(avctx
, AV_LOG_WARNING
,
248 "Non-key frame has no MXM, skipping\n");
251 /* use stored SOF data to allocate current picture */
252 if (jpg
->picture_ptr
->data
[0])
253 avctx
->release_buffer(avctx
, jpg
->picture_ptr
);
254 if (avctx
->get_buffer(avctx
, jpg
->picture_ptr
) < 0) {
255 av_log(avctx
, AV_LOG_ERROR
, "get_buffer() failed\n");
256 return AVERROR(ENOMEM
);
258 jpg
->picture_ptr
->pict_type
= FF_P_TYPE
;
259 jpg
->picture_ptr
->key_frame
= 0;
260 jpg
->got_picture
= 1;
262 jpg
->picture_ptr
->pict_type
= FF_I_TYPE
;
263 jpg
->picture_ptr
->key_frame
= 1;
266 if (s
->got_mxm_bitmask
) {
267 AVFrame
*reference_ptr
= &s
->picture
[s
->picture_index
^ 1];
268 if (mxpeg_check_dimensions(s
, jpg
, reference_ptr
) < 0)
271 /* allocate dummy reference picture if needed */
272 if (!reference_ptr
->data
[0] &&
273 avctx
->get_buffer(avctx
, reference_ptr
) < 0) {
274 av_log(avctx
, AV_LOG_ERROR
, "get_buffer() failed\n");
275 return AVERROR(ENOMEM
);
278 ff_mjpeg_decode_sos(jpg
, s
->mxm_bitmask
, reference_ptr
);
280 ff_mjpeg_decode_sos(jpg
, NULL
, NULL
);
286 buf_ptr
+= (get_bits_count(&jpg
->gb
)+7) >> 3;
292 if (jpg
->got_picture
) {
293 *data_size
= sizeof(AVFrame
);
294 *picture
= *jpg
->picture_ptr
;
295 s
->picture_index
^= 1;
296 jpg
->picture_ptr
= &s
->picture
[s
->picture_index
];
298 if (!s
->has_complete_frame
) {
299 if (!s
->got_mxm_bitmask
)
300 s
->has_complete_frame
= 1;
306 return buf_ptr
- buf
;
309 static av_cold
int mxpeg_decode_end(AVCodecContext
*avctx
)
311 MXpegDecodeContext
*s
= avctx
->priv_data
;
312 MJpegDecodeContext
*jpg
= &s
->jpg
;
315 jpg
->picture_ptr
= NULL
;
316 ff_mjpeg_decode_end(avctx
);
318 for (i
= 0; i
< 2; ++i
) {
319 if (s
->picture
[i
].data
[0])
320 avctx
->release_buffer(avctx
, &s
->picture
[i
]);
323 av_freep(&s
->mxm_bitmask
);
324 av_freep(&s
->completion_bitmask
);
329 AVCodec ff_mxpeg_decoder
= {
331 .long_name
= NULL_IF_CONFIG_SMALL("Mobotix MxPEG video"),
332 .type
= AVMEDIA_TYPE_VIDEO
,
333 .id
= CODEC_ID_MXPEG
,
334 .priv_data_size
= sizeof(MXpegDecodeContext
),
335 .init
= mxpeg_decode_init
,
336 .close
= mxpeg_decode_end
,
337 .decode
= mxpeg_decode_frame
,
338 .capabilities
= CODEC_CAP_DR1
,