mxpegdec.c
Go to the documentation of this file.
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 
28 #include "internal.h"
29 #include "mjpeg.h"
30 #include "mjpegdec.h"
31 
32 typedef struct MXpegDecodeContext {
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 */
44 
46 {
47  MXpegDecodeContext *s = avctx->priv_data;
48 
49  s->jpg.picture_ptr = &s->picture[0];
50  return ff_mjpeg_decode_init(avctx);
51 }
52 
54  const uint8_t *buf_ptr, int buf_size)
55 {
56  int len;
57  if (buf_size < 2)
58  return 0;
59  len = AV_RB16(buf_ptr);
60  skip_bits(&s->jpg.gb, 8*FFMIN(len,buf_size));
61 
62  return 0;
63 }
64 
66  const uint8_t *buf_ptr, int buf_size)
67 {
68  unsigned bitmask_size, mb_count;
69  int i;
70 
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;
74 
75  bitmask_size = (mb_count + 7) >> 3;
76  if (bitmask_size > buf_size - 12) {
78  "MXM bitmask is not complete\n");
79  return AVERROR(EINVAL);
80  }
81 
82  if (s->bitmask_size != bitmask_size) {
83  s->bitmask_size = 0;
84  av_freep(&s->mxm_bitmask);
85  s->mxm_bitmask = av_malloc(bitmask_size);
86  if (!s->mxm_bitmask) {
88  "MXM bitmask memory allocation error\n");
89  return AVERROR(ENOMEM);
90  }
91 
93  s->completion_bitmask = av_mallocz(bitmask_size);
94  if (!s->completion_bitmask) {
96  "Completion bitmask memory allocation error\n");
97  return AVERROR(ENOMEM);
98  }
99 
101  }
102 
103  memcpy(s->mxm_bitmask, buf_ptr + 12, bitmask_size);
104  s->got_mxm_bitmask = 1;
105 
106  if (!s->has_complete_frame) {
107  uint8_t completion_check = 0xFF;
108  for (i = 0; i < bitmask_size; ++i) {
109  s->completion_bitmask[i] |= s->mxm_bitmask[i];
110  completion_check &= s->completion_bitmask[i];
111  }
112  s->has_complete_frame = !(completion_check ^ 0xFF);
113  }
114 
115  return 0;
116 }
117 
119  const uint8_t *buf_ptr, int buf_size)
120 {
121  int len, ret = 0;
122  if (buf_size < 2)
123  return 0;
124  len = AV_RB16(buf_ptr);
125  if (len > 14 && len <= buf_size && !strncmp(buf_ptr + 2, "MXM", 3)) {
126  ret = mxpeg_decode_mxm(s, buf_ptr + 2, len - 2);
127  }
128  skip_bits(&s->jpg.gb, 8*FFMIN(len,buf_size));
129 
130  return ret;
131 }
132 
134  AVFrame *reference_ptr)
135 {
136  if ((jpg->width + 0x0F)>>4 != s->mb_width ||
137  (jpg->height + 0x0F)>>4 != s->mb_height) {
138  av_log(jpg->avctx, AV_LOG_ERROR,
139  "Picture dimensions stored in SOF and MXM mismatch\n");
140  return AVERROR(EINVAL);
141  }
142 
143  if (reference_ptr->data[0]) {
144  int i;
145  for (i = 0; i < MAX_COMPONENTS; ++i) {
146  if ( (!reference_ptr->data[i] ^ !jpg->picture_ptr->data[i]) ||
147  reference_ptr->linesize[i] != jpg->picture_ptr->linesize[i]) {
148  av_log(jpg->avctx, AV_LOG_ERROR,
149  "Dimensions of current and reference picture mismatch\n");
150  return AVERROR(EINVAL);
151  }
152  }
153  }
154 
155  return 0;
156 }
157 
159  void *data, int *got_frame,
160  AVPacket *avpkt)
161 {
162  const uint8_t *buf = avpkt->data;
163  int buf_size = avpkt->size;
164  MXpegDecodeContext *s = avctx->priv_data;
165  MJpegDecodeContext *jpg = &s->jpg;
166  const uint8_t *buf_end, *buf_ptr;
167  const uint8_t *unescaped_buf_ptr;
168  int unescaped_buf_size;
169  int start_code;
170  int ret;
171 
172  buf_ptr = buf;
173  buf_end = buf + buf_size;
174  jpg->got_picture = 0;
175  s->got_mxm_bitmask = 0;
176  while (buf_ptr < buf_end) {
177  start_code = ff_mjpeg_find_marker(jpg, &buf_ptr, buf_end,
178  &unescaped_buf_ptr, &unescaped_buf_size);
179  if (start_code < 0)
180  goto the_end;
181  {
182  init_get_bits(&jpg->gb, unescaped_buf_ptr, unescaped_buf_size*8);
183 
184  if (start_code >= APP0 && start_code <= APP15) {
185  mxpeg_decode_app(s, unescaped_buf_ptr, unescaped_buf_size);
186  }
187 
188  switch (start_code) {
189  case SOI:
190  if (jpg->got_picture) //emulating EOI
191  goto the_end;
192  break;
193  case EOI:
194  goto the_end;
195  case DQT:
196  ret = ff_mjpeg_decode_dqt(jpg);
197  if (ret < 0) {
198  av_log(avctx, AV_LOG_ERROR,
199  "quantization table decode error\n");
200  return ret;
201  }
202  break;
203  case DHT:
204  ret = ff_mjpeg_decode_dht(jpg);
205  if (ret < 0) {
206  av_log(avctx, AV_LOG_ERROR,
207  "huffman table decode error\n");
208  return ret;
209  }
210  break;
211  case COM:
212  ret = mxpeg_decode_com(s, unescaped_buf_ptr,
213  unescaped_buf_size);
214  if (ret < 0)
215  return ret;
216  break;
217  case SOF0:
218  s->got_sof_data = 0;
219  ret = ff_mjpeg_decode_sof(jpg);
220  if (ret < 0) {
221  av_log(avctx, AV_LOG_ERROR,
222  "SOF data decode error\n");
223  return ret;
224  }
225  if (jpg->interlaced) {
226  av_log(avctx, AV_LOG_ERROR,
227  "Interlaced mode not supported in MxPEG\n");
228  return AVERROR(EINVAL);
229  }
230  s->got_sof_data = 1;
231  break;
232  case SOS:
233  if (!s->got_sof_data) {
234  av_log(avctx, AV_LOG_WARNING,
235  "Can not process SOS without SOF data, skipping\n");
236  break;
237  }
238  if (!jpg->got_picture) {
239  if (jpg->first_picture) {
240  av_log(avctx, AV_LOG_WARNING,
241  "First picture has no SOF, skipping\n");
242  break;
243  }
244  if (!s->got_mxm_bitmask){
245  av_log(avctx, AV_LOG_WARNING,
246  "Non-key frame has no MXM, skipping\n");
247  break;
248  }
249  /* use stored SOF data to allocate current picture */
251  if ((ret = ff_get_buffer(avctx, jpg->picture_ptr,
253  return ret;
255  jpg->picture_ptr->key_frame = 0;
256  jpg->got_picture = 1;
257  } else {
259  jpg->picture_ptr->key_frame = 1;
260  }
261 
262  if (s->got_mxm_bitmask) {
263  AVFrame *reference_ptr = &s->picture[s->picture_index ^ 1];
264  if (mxpeg_check_dimensions(s, jpg, reference_ptr) < 0)
265  break;
266 
267  /* allocate dummy reference picture if needed */
268  if (!reference_ptr->data[0] &&
269  (ret = ff_get_buffer(avctx, reference_ptr,
271  return ret;
272 
273  ret = ff_mjpeg_decode_sos(jpg, s->mxm_bitmask, reference_ptr);
274  if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
275  return ret;
276  } else {
277  ret = ff_mjpeg_decode_sos(jpg, NULL, NULL);
278  if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
279  return ret;
280  }
281 
282  break;
283  }
284 
285  buf_ptr += (get_bits_count(&jpg->gb)+7) >> 3;
286  }
287 
288  }
289 
290 the_end:
291  if (jpg->got_picture) {
292  int ret = av_frame_ref(data, jpg->picture_ptr);
293  if (ret < 0)
294  return ret;
295  *got_frame = 1;
296 
297  s->picture_index ^= 1;
298  jpg->picture_ptr = &s->picture[s->picture_index];
299 
300  if (!s->has_complete_frame) {
301  if (!s->got_mxm_bitmask)
302  s->has_complete_frame = 1;
303  else
304  *got_frame = 0;
305  }
306  }
307 
308  return buf_ptr - buf;
309 }
310 
312 {
313  MXpegDecodeContext *s = avctx->priv_data;
314  MJpegDecodeContext *jpg = &s->jpg;
315  int i;
316 
317  jpg->picture_ptr = NULL;
318  ff_mjpeg_decode_end(avctx);
319 
320  for (i = 0; i < 2; ++i)
321  av_frame_unref(&s->picture[i]);
322 
323  av_freep(&s->mxm_bitmask);
325 
326  return 0;
327 }
328 
330  .name = "mxpeg",
331  .long_name = NULL_IF_CONFIG_SMALL("Mobotix MxPEG video"),
332  .type = AVMEDIA_TYPE_VIDEO,
333  .id = AV_CODEC_ID_MXPEG,
334  .priv_data_size = sizeof(MXpegDecodeContext),
338  .capabilities = CODEC_CAP_DR1,
339  .max_lowres = 3,
340 };
uint8_t * completion_bitmask
Definition: mxpegdec.c:41
Definition: mjpeg.h:115
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
const char * s
Definition: avisynth_c.h:668
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
uint8_t * mxm_bitmask
Definition: mxpegdec.c:38
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:154
int ff_mjpeg_decode_dqt(MJpegDecodeContext *s)
Definition: mjpegdec.c:126
Definition: mjpeg.h:74
#define AV_RL16
static int mxpeg_check_dimensions(MXpegDecodeContext *s, MJpegDecodeContext *jpg, AVFrame *reference_ptr)
Definition: mxpegdec.c:133
int ff_mjpeg_decode_dht(MJpegDecodeContext *s)
Definition: mjpegdec.c:159
MJPEG encoder and decoder.
static int mxpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: mxpegdec.c:158
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
uint8_t
#define av_cold
Definition: attributes.h:78
AVCodec ff_mxpeg_decoder
Definition: mxpegdec.c:329
#define CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
AVFrame * picture_ptr
Definition: mjpegdec.h:91
uint8_t * data
#define MAX_COMPONENTS
Definition: mjpegdec.h:39
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:193
Definition: mjpeg.h:77
Definition: mjpeg.h:83
static int mxpeg_decode_mxm(MXpegDecodeContext *s, const uint8_t *buf_ptr, int buf_size)
Definition: mxpegdec.c:65
#define AV_EF_EXPLODE
#define AV_RB16
Definition: mjpeg.h:43
av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx)
Definition: mjpegdec.c:1867
unsigned bitmask_size
Definition: mxpegdec.c:39
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Spectrum Plot time data
Definition: mjpeg.h:60
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
const char * name
Name of the codec implementation.
unsigned mb_width
Definition: mxpegdec.c:42
int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
Definition: mjpegdec.c:213
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:144
int err_recognition
Error recognition; may misdetect some more or less valid parts as errors.
#define FFMIN(a, b)
Definition: common.h:58
Definition: mjpeg.h:76
ret
Definition: avfilter.c:821
GetBitContext gb
Definition: mjpegdec.h:44
Definition: mjpeg.h:75
static av_cold int mxpeg_decode_init(AVCodecContext *avctx)
Definition: mxpegdec.c:45
NULL
Definition: eval.c:55
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:101
int has_complete_frame
Definition: mxpegdec.c:40
main external API structure.
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:375
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
void * buf
Definition: avisynth_c.h:594
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:265
synthesis window for stochastic i
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:379
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:330
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
MJpegDecodeContext jpg
Definition: mxpegdec.c:33
int av_frame_ref(AVFrame *dst, AVFrame *src)
Setup a new reference to the data described by an given frame.
Definition: frame.c:228
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
static int mxpeg_decode_com(MXpegDecodeContext *s, const uint8_t *buf_ptr, int buf_size)
Definition: mxpegdec.c:118
av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx)
Definition: mjpegdec.c:83
int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask, const AVFrame *reference)
Definition: mjpegdec.c:1177
unsigned mb_height
Definition: mxpegdec.c:42
common internal api header.
static av_cold int mxpeg_decode_end(AVCodecContext *avctx)
Definition: mxpegdec.c:311
AVCodecContext * avctx
Definition: mjpegdec.h:43
static int mxpeg_decode_app(MXpegDecodeContext *s, const uint8_t *buf_ptr, int buf_size)
Definition: mxpegdec.c:53
AVFrame picture[2]
Definition: mxpegdec.c:34
int got_picture
we found a SOF and picture is valid, too.
Definition: mjpegdec.h:92
int len
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:139
static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: crystalhd.c:868
int ff_mjpeg_find_marker(MJpegDecodeContext *s, const uint8_t **buf_ptr, const uint8_t *buf_end, const uint8_t **unescaped_buf_ptr, int *unescaped_buf_size)
Definition: mjpegdec.c:1541
struct MXpegDecodeContext MXpegDecodeContext
MJPEG decoder.
This structure stores compressed data.
#define AV_GET_BUFFER_FLAG_REF
The decoder will keep a reference to the frame and may reuse it later.
Predicted.
Definition: avutil.h:217
Definition: mjpeg.h:98