00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00028 #include "mjpeg.h"
00029 #include "mjpegdec.h"
00030
00031 typedef struct MXpegDecodeContext {
00032 MJpegDecodeContext jpg;
00033 AVFrame picture[2];
00034 int picture_index;
00035 int got_sof_data;
00036 int got_mxm_bitmask;
00037 uint8_t *mxm_bitmask;
00038 unsigned bitmask_size;
00039 int has_complete_frame;
00040 uint8_t *completion_bitmask;
00041 unsigned mb_width, mb_height;
00042 } MXpegDecodeContext;
00043
00044 static av_cold int mxpeg_decode_init(AVCodecContext *avctx)
00045 {
00046 MXpegDecodeContext *s = avctx->priv_data;
00047
00048 s->picture[0].reference = s->picture[1].reference = 3;
00049 s->jpg.picture_ptr = &s->picture[0];
00050 return ff_mjpeg_decode_init(avctx);
00051 }
00052
00053 static int mxpeg_decode_app(MXpegDecodeContext *s,
00054 const uint8_t *buf_ptr, int buf_size)
00055 {
00056 int len;
00057 if (buf_size < 2)
00058 return 0;
00059 len = AV_RB16(buf_ptr);
00060 skip_bits(&s->jpg.gb, 8*FFMIN(len,buf_size));
00061
00062 return 0;
00063 }
00064
00065 static int mxpeg_decode_mxm(MXpegDecodeContext *s,
00066 const uint8_t *buf_ptr, int buf_size)
00067 {
00068 unsigned bitmask_size, mb_count;
00069 int i;
00070
00071 s->mb_width = AV_RL16(buf_ptr+4);
00072 s->mb_height = AV_RL16(buf_ptr+6);
00073 mb_count = s->mb_width * s->mb_height;
00074
00075 bitmask_size = (mb_count + 7) >> 3;
00076 if (bitmask_size > buf_size - 12) {
00077 av_log(s->jpg.avctx, AV_LOG_ERROR,
00078 "MXM bitmask is not complete\n");
00079 return AVERROR(EINVAL);
00080 }
00081
00082 if (s->bitmask_size != bitmask_size) {
00083 s->bitmask_size = 0;
00084 av_freep(&s->mxm_bitmask);
00085 s->mxm_bitmask = av_malloc(bitmask_size);
00086 if (!s->mxm_bitmask) {
00087 av_log(s->jpg.avctx, AV_LOG_ERROR,
00088 "MXM bitmask memory allocation error\n");
00089 return AVERROR(ENOMEM);
00090 }
00091
00092 av_freep(&s->completion_bitmask);
00093 s->completion_bitmask = av_mallocz(bitmask_size);
00094 if (!s->completion_bitmask) {
00095 av_log(s->jpg.avctx, AV_LOG_ERROR,
00096 "Completion bitmask memory allocation error\n");
00097 return AVERROR(ENOMEM);
00098 }
00099
00100 s->bitmask_size = bitmask_size;
00101 }
00102
00103 memcpy(s->mxm_bitmask, buf_ptr + 12, bitmask_size);
00104 s->got_mxm_bitmask = 1;
00105
00106 if (!s->has_complete_frame) {
00107 uint8_t completion_check = 0xFF;
00108 for (i = 0; i < bitmask_size; ++i) {
00109 s->completion_bitmask[i] |= s->mxm_bitmask[i];
00110 completion_check &= s->completion_bitmask[i];
00111 }
00112 s->has_complete_frame = !(completion_check ^ 0xFF);
00113 }
00114
00115 return 0;
00116 }
00117
00118 static int mxpeg_decode_com(MXpegDecodeContext *s,
00119 const uint8_t *buf_ptr, int buf_size)
00120 {
00121 int len, ret = 0;
00122 if (buf_size < 2)
00123 return 0;
00124 len = AV_RB16(buf_ptr);
00125 if (len > 14 && len <= buf_size && !strncmp(buf_ptr + 2, "MXM", 3)) {
00126 ret = mxpeg_decode_mxm(s, buf_ptr + 2, len - 2);
00127 }
00128 skip_bits(&s->jpg.gb, 8*FFMIN(len,buf_size));
00129
00130 return ret;
00131 }
00132
00133 static int mxpeg_check_dimensions(MXpegDecodeContext *s, MJpegDecodeContext *jpg,
00134 AVFrame *reference_ptr)
00135 {
00136 if ((jpg->width + 0x0F)>>4 != s->mb_width ||
00137 (jpg->height + 0x0F)>>4 != s->mb_height) {
00138 av_log(jpg->avctx, AV_LOG_ERROR,
00139 "Picture dimensions stored in SOF and MXM mismatch\n");
00140 return AVERROR(EINVAL);
00141 }
00142
00143 if (reference_ptr->data[0]) {
00144 int i;
00145 for (i = 0; i < MAX_COMPONENTS; ++i) {
00146 if ( (!reference_ptr->data[i] ^ !jpg->picture_ptr->data[i]) ||
00147 reference_ptr->linesize[i] != jpg->picture_ptr->linesize[i]) {
00148 av_log(jpg->avctx, AV_LOG_ERROR,
00149 "Dimensions of current and reference picture mismatch\n");
00150 return AVERROR(EINVAL);
00151 }
00152 }
00153 }
00154
00155 return 0;
00156 }
00157
00158 static int mxpeg_decode_frame(AVCodecContext *avctx,
00159 void *data, int *data_size,
00160 AVPacket *avpkt)
00161 {
00162 const uint8_t *buf = avpkt->data;
00163 int buf_size = avpkt->size;
00164 MXpegDecodeContext *s = avctx->priv_data;
00165 MJpegDecodeContext *jpg = &s->jpg;
00166 const uint8_t *buf_end, *buf_ptr;
00167 const uint8_t *unescaped_buf_ptr;
00168 int unescaped_buf_size;
00169 int start_code;
00170 AVFrame *picture = data;
00171 int ret;
00172
00173 buf_ptr = buf;
00174 buf_end = buf + buf_size;
00175 jpg->got_picture = 0;
00176 s->got_mxm_bitmask = 0;
00177 while (buf_ptr < buf_end) {
00178 start_code = ff_mjpeg_find_marker(jpg, &buf_ptr, buf_end,
00179 &unescaped_buf_ptr, &unescaped_buf_size);
00180 if (start_code < 0)
00181 goto the_end;
00182 {
00183 init_get_bits(&jpg->gb, unescaped_buf_ptr, unescaped_buf_size*8);
00184
00185 if (start_code >= APP0 && start_code <= APP15) {
00186 mxpeg_decode_app(s, unescaped_buf_ptr, unescaped_buf_size);
00187 }
00188
00189 switch (start_code) {
00190 case SOI:
00191 if (jpg->got_picture)
00192 goto the_end;
00193 break;
00194 case EOI:
00195 goto the_end;
00196 case DQT:
00197 ret = ff_mjpeg_decode_dqt(jpg);
00198 if (ret < 0) {
00199 av_log(avctx, AV_LOG_ERROR,
00200 "quantization table decode error\n");
00201 return ret;
00202 }
00203 break;
00204 case DHT:
00205 ret = ff_mjpeg_decode_dht(jpg);
00206 if (ret < 0) {
00207 av_log(avctx, AV_LOG_ERROR,
00208 "huffman table decode error\n");
00209 return ret;
00210 }
00211 break;
00212 case COM:
00213 ret = mxpeg_decode_com(s, unescaped_buf_ptr,
00214 unescaped_buf_size);
00215 if (ret < 0)
00216 return ret;
00217 break;
00218 case SOF0:
00219 s->got_sof_data = 0;
00220 ret = ff_mjpeg_decode_sof(jpg);
00221 if (ret < 0) {
00222 av_log(avctx, AV_LOG_ERROR,
00223 "SOF data decode error\n");
00224 return ret;
00225 }
00226 if (jpg->interlaced) {
00227 av_log(avctx, AV_LOG_ERROR,
00228 "Interlaced mode not supported in MxPEG\n");
00229 return AVERROR(EINVAL);
00230 }
00231 s->got_sof_data = 1;
00232 break;
00233 case SOS:
00234 if (!s->got_sof_data) {
00235 av_log(avctx, AV_LOG_WARNING,
00236 "Can not process SOS without SOF data, skipping\n");
00237 break;
00238 }
00239 if (!jpg->got_picture) {
00240 if (jpg->first_picture) {
00241 av_log(avctx, AV_LOG_WARNING,
00242 "First picture has no SOF, skipping\n");
00243 break;
00244 }
00245 if (!s->got_mxm_bitmask){
00246 av_log(avctx, AV_LOG_WARNING,
00247 "Non-key frame has no MXM, skipping\n");
00248 break;
00249 }
00250
00251 if (jpg->picture_ptr->data[0])
00252 avctx->release_buffer(avctx, jpg->picture_ptr);
00253 if (avctx->get_buffer(avctx, jpg->picture_ptr) < 0) {
00254 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00255 return AVERROR(ENOMEM);
00256 }
00257 jpg->picture_ptr->pict_type = AV_PICTURE_TYPE_P;
00258 jpg->picture_ptr->key_frame = 0;
00259 jpg->got_picture = 1;
00260 } else {
00261 jpg->picture_ptr->pict_type = AV_PICTURE_TYPE_I;
00262 jpg->picture_ptr->key_frame = 1;
00263 }
00264
00265 if (s->got_mxm_bitmask) {
00266 AVFrame *reference_ptr = &s->picture[s->picture_index ^ 1];
00267 if (mxpeg_check_dimensions(s, jpg, reference_ptr) < 0)
00268 break;
00269
00270
00271 if (!reference_ptr->data[0] &&
00272 avctx->get_buffer(avctx, reference_ptr) < 0) {
00273 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00274 return AVERROR(ENOMEM);
00275 }
00276
00277 ret = ff_mjpeg_decode_sos(jpg, s->mxm_bitmask, reference_ptr);
00278 if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
00279 return ret;
00280 } else {
00281 ret = ff_mjpeg_decode_sos(jpg, NULL, NULL);
00282 if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
00283 return ret;
00284 }
00285
00286 break;
00287 }
00288
00289 buf_ptr += (get_bits_count(&jpg->gb)+7) >> 3;
00290 }
00291
00292 }
00293
00294 the_end:
00295 if (jpg->got_picture) {
00296 *data_size = sizeof(AVFrame);
00297 *picture = *jpg->picture_ptr;
00298 s->picture_index ^= 1;
00299 jpg->picture_ptr = &s->picture[s->picture_index];
00300
00301 if (!s->has_complete_frame) {
00302 if (!s->got_mxm_bitmask)
00303 s->has_complete_frame = 1;
00304 else
00305 *data_size = 0;
00306 }
00307 }
00308
00309 return buf_ptr - buf;
00310 }
00311
00312 static av_cold int mxpeg_decode_end(AVCodecContext *avctx)
00313 {
00314 MXpegDecodeContext *s = avctx->priv_data;
00315 MJpegDecodeContext *jpg = &s->jpg;
00316 int i;
00317
00318 jpg->picture_ptr = NULL;
00319 ff_mjpeg_decode_end(avctx);
00320
00321 for (i = 0; i < 2; ++i) {
00322 if (s->picture[i].data[0])
00323 avctx->release_buffer(avctx, &s->picture[i]);
00324 }
00325
00326 av_freep(&s->mxm_bitmask);
00327 av_freep(&s->completion_bitmask);
00328
00329 return 0;
00330 }
00331
00332 AVCodec ff_mxpeg_decoder = {
00333 .name = "mxpeg",
00334 .long_name = NULL_IF_CONFIG_SMALL("Mobotix MxPEG video"),
00335 .type = AVMEDIA_TYPE_VIDEO,
00336 .id = AV_CODEC_ID_MXPEG,
00337 .priv_data_size = sizeof(MXpegDecodeContext),
00338 .init = mxpeg_decode_init,
00339 .close = mxpeg_decode_end,
00340 .decode = mxpeg_decode_frame,
00341 .capabilities = CODEC_CAP_DR1,
00342 .max_lowres = 3,
00343 };