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