diff options
Diffstat (limited to 'src/libffmpeg/libavcodec/mjpeg.c')
-rw-r--r-- | src/libffmpeg/libavcodec/mjpeg.c | 489 |
1 files changed, 427 insertions, 62 deletions
diff --git a/src/libffmpeg/libavcodec/mjpeg.c b/src/libffmpeg/libavcodec/mjpeg.c index 1eb35d2b8..577e9d884 100644 --- a/src/libffmpeg/libavcodec/mjpeg.c +++ b/src/libffmpeg/libavcodec/mjpeg.c @@ -1,28 +1,36 @@ /* * MJPEG encoder and decoder - * Copyright (c) 2000, 2001 Gerard Lantau. + * Copyright (c) 2000, 2001 Fabrice Bellard. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Support for external huffman table and various fixes (AVID workaround) by + * Alex Beregszaszi <alex@naxine.org> */ //#define DEBUG -#include "config.h" - #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" -#include "xine-utils/xineutils.h" + +#ifdef USE_FASTMEMCPY +#include "fastmemcpy.h" +#endif + +/* use two quantizer table (one for luminance and one for chrominance) */ +/* not yet working */ +#undef TWOMATRIXES typedef struct MJpegContext { UINT8 huff_size_dc_luminance[12]; @@ -36,12 +44,87 @@ typedef struct MJpegContext { UINT16 huff_code_ac_chrominance[256]; } MJpegContext; -#define SOF0 0xc0 -#define SOI 0xd8 -#define EOI 0xd9 -#define DQT 0xdb -#define DHT 0xc4 -#define SOS 0xda +/* JPEG marker codes */ +typedef enum { + /* start of frame */ + SOF0 = 0xc0, /* baseline */ + SOF1 = 0xc1, /* extended sequential, huffman */ + SOF2 = 0xc2, /* progressive, huffman */ + SOF3 = 0xc3, /* lossless, huffman */ + + SOF5 = 0xc5, /* differential sequential, huffman */ + SOF6 = 0xc6, /* differential progressive, huffman */ + SOF7 = 0xc7, /* differential lossless, huffman */ + JPG = 0xc8, /* reserved for JPEG extension */ + SOF9 = 0xc9, /* extended sequential, arithmetic */ + SOF10 = 0xca, /* progressive, arithmetic */ + SOF11 = 0xcb, /* lossless, arithmetic */ + + SOF13 = 0xcd, /* differential sequential, arithmetic */ + SOF14 = 0xce, /* differential progressive, arithmetic */ + SOF15 = 0xcf, /* differential lossless, arithmetic */ + + DHT = 0xc4, /* define huffman tables */ + + DAC = 0xcc, /* define arithmetic-coding conditioning */ + + /* restart with modulo 8 count "m" */ + RST0 = 0xd0, + RST1 = 0xd1, + RST2 = 0xd2, + RST3 = 0xd3, + RST4 = 0xd4, + RST5 = 0xd5, + RST6 = 0xd6, + RST7 = 0xd7, + + SOI = 0xd8, /* start of image */ + EOI = 0xd9, /* end of image */ + SOS = 0xda, /* start of scan */ + DQT = 0xdb, /* define quantization tables */ + DNL = 0xdc, /* define number of lines */ + DRI = 0xdd, /* define restart interval */ + DHP = 0xde, /* define hierarchical progression */ + EXP = 0xdf, /* expand reference components */ + + APP0 = 0xe0, + APP1 = 0xe1, + APP2 = 0xe2, + APP3 = 0xe3, + APP4 = 0xe4, + APP5 = 0xe5, + APP6 = 0xe6, + APP7 = 0xe7, + APP8 = 0xe8, + APP9 = 0xe9, + APP10 = 0xea, + APP11 = 0xeb, + APP12 = 0xec, + APP13 = 0xed, + APP14 = 0xee, + APP15 = 0xef, + + JPG0 = 0xf0, + JPG1 = 0xf1, + JPG2 = 0xf2, + JPG3 = 0xf3, + JPG4 = 0xf4, + JPG5 = 0xf5, + JPG6 = 0xf6, + JPG7 = 0xf7, + JPG8 = 0xf8, + JPG9 = 0xf9, + JPG10 = 0xfa, + JPG11 = 0xfb, + JPG12 = 0xfc, + JPG13 = 0xfd, + + COM = 0xfe, /* comment */ + + TEM = 0x01, /* temporary private use for arithmetic coding */ + + /* 0x02 -> 0xbf reserved */ +} JPEG_MARKER; #if 0 /* These are the sample quantization tables given in JPEG spec section K.1. @@ -135,7 +218,6 @@ static const UINT8 val_ac_chrominance[] = 0xf9, 0xfa }; - /* isn't this function nicer than the one in the libjpeg ? */ static void build_huffman_codes(UINT8 *huff_size, UINT16 *huff_code, const UINT8 *bits_table, const UINT8 *val_table) @@ -160,9 +242,13 @@ int mjpeg_init(MpegEncContext *s) { MJpegContext *m; - m = malloc(sizeof(MJpegContext)); + m = av_malloc(sizeof(MJpegContext)); if (!m) return -1; + + s->min_qcoeff=-1023; + s->max_qcoeff= 1023; + s->intra_quant_bias= 1<<(QUANT_BIAS_SHIFT-1); //(a + x/2)/x /* build all the huffman tables */ build_huffman_codes(m->huff_size_dc_luminance, @@ -188,7 +274,7 @@ int mjpeg_init(MpegEncContext *s) void mjpeg_close(MpegEncContext *s) { - free(s->mjpeg_ctx); + av_free(s->mjpeg_ctx); } static inline void put_marker(PutBitContext *p, int code) @@ -227,14 +313,18 @@ static void jpeg_table_header(MpegEncContext *s) /* quant matrixes */ put_marker(p, DQT); +#ifdef TWOMATRIXES + put_bits(p, 16, 2 + 2 * (1 + 64)); +#else put_bits(p, 16, 2 + 1 * (1 + 64)); +#endif put_bits(p, 4, 0); /* 8 bit precision */ put_bits(p, 4, 0); /* table 0 */ for(i=0;i<64;i++) { j = zigzag_direct[i]; put_bits(p, 8, s->intra_matrix[j]); } -#if 0 +#ifdef TWOMATRIXES put_bits(p, 4, 0); /* 8 bit precision */ put_bits(p, 4, 1); /* table 1 */ for(i=0;i<64;i++) { @@ -258,10 +348,46 @@ static void jpeg_table_header(MpegEncContext *s) ptr[1] = size; } +static void jpeg_put_comments(MpegEncContext *s) +{ + PutBitContext *p = &s->pb; + int size; + UINT8 *ptr; + +#if 0 + /* JFIF header */ + put_marker(p, APP0); + put_bits(p, 16, 16); + put_string(p, "JFIF"); /* this puts the trailing zero-byte too */ + put_bits(p, 16, 0x101); + put_bits(p, 8, 0); /* units type: 0 - aspect ratio */ + put_bits(p, 16, 1); /* aspect: 1:1 */ + put_bits(p, 16, 1); + put_bits(p, 8, 0); /* thumbnail width */ + put_bits(p, 8, 0); /* thumbnail height */ +#endif + + /* comment */ + put_marker(p, COM); + flush_put_bits(p); + ptr = pbBufPtr(p); + put_bits(p, 16, 0); /* patched later */ +#define VERSION "FFmpeg" LIBAVCODEC_VERSION "b" LIBAVCODEC_BUILD_STR + put_string(p, VERSION); + size = strlen(VERSION)+3; +#undef VERSION + ptr[0] = size >> 8; + ptr[1] = size; +} + void mjpeg_picture_header(MpegEncContext *s) { put_marker(&s->pb, SOI); + if (!s->mjpeg_data_only_frames) + { + jpeg_put_comments(s); + if (s->mjpeg_write_tables) jpeg_table_header(s); put_marker(&s->pb, SOF0); @@ -282,13 +408,22 @@ void mjpeg_picture_header(MpegEncContext *s) put_bits(&s->pb, 8, 2); /* component number */ put_bits(&s->pb, 4, s->mjpeg_hsample[1]); /* H factor */ put_bits(&s->pb, 4, s->mjpeg_vsample[1]); /* V factor */ +#ifdef TWOMATRIXES + put_bits(&s->pb, 8, 1); /* select matrix */ +#else put_bits(&s->pb, 8, 0); /* select matrix */ +#endif /* Cr component */ put_bits(&s->pb, 8, 3); /* component number */ put_bits(&s->pb, 4, s->mjpeg_hsample[2]); /* H factor */ put_bits(&s->pb, 4, s->mjpeg_vsample[2]); /* V factor */ +#ifdef TWOMATRIXES + put_bits(&s->pb, 8, 1); /* select matrix */ +#else put_bits(&s->pb, 8, 0); /* select matrix */ +#endif + } /* scan header */ put_marker(&s->pb, SOS); @@ -312,7 +447,7 @@ void mjpeg_picture_header(MpegEncContext *s) put_bits(&s->pb, 8, 0); /* Ss (not used) */ put_bits(&s->pb, 8, 63); /* Se (not used) */ - put_bits(&s->pb, 8, 0); /* (not used) */ + put_bits(&s->pb, 8, 0); /* Ah/Al (not used) */ } void mjpeg_picture_trailer(MpegEncContext *s) @@ -321,8 +456,8 @@ void mjpeg_picture_trailer(MpegEncContext *s) put_marker(&s->pb, EOI); } -static inline void encode_dc(MpegEncContext *s, int val, - UINT8 *huff_size, UINT16 *huff_code) +static inline void mjpeg_encode_dc(MpegEncContext *s, int val, + UINT8 *huff_size, UINT16 *huff_code) { int mant, nbits; @@ -361,11 +496,11 @@ static void encode_block(MpegEncContext *s, DCTELEM *block, int n) dc = block[0]; /* overflow is impossible */ val = dc - s->last_dc[component]; if (n < 4) { - encode_dc(s, val, m->huff_size_dc_luminance, m->huff_code_dc_luminance); + mjpeg_encode_dc(s, val, m->huff_size_dc_luminance, m->huff_code_dc_luminance); huff_size_ac = m->huff_size_ac_luminance; huff_code_ac = m->huff_code_ac_luminance; } else { - encode_dc(s, val, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); + mjpeg_encode_dc(s, val, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); huff_size_ac = m->huff_size_ac_chrominance; huff_code_ac = m->huff_code_ac_chrominance; } @@ -429,6 +564,7 @@ void mjpeg_encode_mb(MpegEncContext *s, #define MAX_COMPONENTS 4 typedef struct MJpegDecodeContext { + AVCodecContext *avctx; GetBitContext gb; UINT32 header_state; int start_code; /* current start code */ @@ -455,8 +591,21 @@ typedef struct MJpegDecodeContext { int linesize[MAX_COMPONENTS]; DCTELEM block[64] __align8; UINT8 buffer[PICTURE_BUFFER_SIZE]; + + int buggy_avid; + int restart_interval; + int restart_count; + int interleaved_rows; } MJpegDecodeContext; +#define SKIP_REMAINING(gb, len) { \ + dprintf("reamining %d bytes in marker\n", len); \ + if (len) while (--len) \ + skip_bits(gb, 8); \ +} + +static int mjpeg_decode_dht(MJpegDecodeContext *s, UINT8 *buf, int buf_size); + static void build_vlc(VLC *vlc, const UINT8 *bits_table, const UINT8 *val_table, int nb_codes) { @@ -473,6 +622,8 @@ static int mjpeg_decode_init(AVCodecContext *avctx) { MJpegDecodeContext *s = avctx->priv_data; + s->avctx = avctx; + s->header_state = 0; s->mpeg_enc_ctx_allocated = 0; s->buffer_size = PICTURE_BUFFER_SIZE - 1; /* minus 1 to take into @@ -487,6 +638,13 @@ static int mjpeg_decode_init(AVCodecContext *avctx) build_vlc(&s->vlcs[0][1], bits_dc_chrominance, val_dc_chrominance, 12); build_vlc(&s->vlcs[1][0], bits_ac_luminance, val_ac_luminance, 251); build_vlc(&s->vlcs[1][1], bits_ac_chrominance, val_ac_chrominance, 251); + + if (avctx->flags & CODEC_FLAG_EXTERN_HUFF) + { + printf("mjpeg: using external huffman table\n"); + mjpeg_decode_dht(s, avctx->extradata, avctx->extradata_size); + /* should check for error - but dunno */ + } return 0; } @@ -496,14 +654,16 @@ static int mjpeg_decode_dqt(MJpegDecodeContext *s, { int len, index, i, j; init_get_bits(&s->gb, buf, buf_size); - - len = get_bits(&s->gb, 16); - len -= 2; + + len = get_bits(&s->gb, 16) - 2; while (len >= 65) { /* only 8 bit precision handled */ if (get_bits(&s->gb, 4) != 0) + { + dprintf("dqt: 16bit precision\n"); return -1; + } index = get_bits(&s->gb, 4); if (index >= 4) return -1; @@ -511,10 +671,13 @@ static int mjpeg_decode_dqt(MJpegDecodeContext *s, /* read quant table */ for(i=0;i<64;i++) { j = zigzag_direct[i]; - s->quant_matrixes[index][j] = get_bits(&s->gb, 8); + s->quant_matrixes[index][j] = get_bits(&s->gb, 8); } len -= 65; } + + SKIP_REMAINING(&s->gb, len); + return 0; } @@ -581,6 +744,7 @@ static int mjpeg_decode_sof0(MJpegDecodeContext *s, return -1; height = get_bits(&s->gb, 16); width = get_bits(&s->gb, 16); + dprintf("sof0: picture: %dx%d\n", width, height); nb_components = get_bits(&s->gb, 8); if (nb_components <= 0 || @@ -602,16 +766,15 @@ static int mjpeg_decode_sof0(MJpegDecodeContext *s, s->quant_index[i] = get_bits(&s->gb, 8); if (s->quant_index[i] >= 4) return -1; - dprintf("component %d %d:%d\n", i, s->h_count[i], s->v_count[i]); + dprintf("component %d %d:%d id: %d quant:%d\n", i, s->h_count[i], + s->v_count[i], s->component_id[i], s->quant_index[i]); } /* if different size, realloc/alloc picture */ /* XXX: also check h_count and v_count */ if (width != s->width || height != s->height) { - for(i=0;i<MAX_COMPONENTS;i++) { - free(s->current_picture[i]); - s->current_picture[i] = NULL; - } + for(i=0;i<MAX_COMPONENTS;i++) + av_freep(&s->current_picture[i]); s->width = width; s->height = height; /* test interlaced mode */ @@ -619,7 +782,7 @@ static int mjpeg_decode_sof0(MJpegDecodeContext *s, s->org_height != 0 && s->height < ((s->org_height * 3) / 4)) { s->interlaced = 1; - s->bottom_field = 0; + s->bottom_field = 0; } for(i=0;i<nb_components;i++) { @@ -636,19 +799,26 @@ static int mjpeg_decode_sof0(MJpegDecodeContext *s, } s->first_picture = 0; } + + if (len != (8+(3*nb_components))) + { + dprintf("decode_sof0: error, len(%d) mismatch\n", len); + } return 0; } -static inline int decode_dc(MJpegDecodeContext *s, int dc_index) +static inline int mjpeg_decode_dc(MJpegDecodeContext *s, int dc_index) { - VLC *dc_vlc; int code, diff; - dc_vlc = &s->vlcs[0][dc_index]; - code = get_vlc(&s->gb, dc_vlc); + code = get_vlc(&s->gb, &s->vlcs[0][dc_index]); if (code < 0) + { + dprintf("mjpeg_decode_dc: bad vlc: %d:%d (%p)\n", 0, dc_index, + &s->vlcs[0][dc_index]); return 0xffff; + } if (code == 0) { diff = 0; } else { @@ -668,13 +838,13 @@ static int decode_block(MJpegDecodeContext *s, DCTELEM *block, VLC *ac_vlc; INT16 *quant_matrix; - quant_matrix = s->quant_matrixes[quant_index]; /* DC coef */ - val = decode_dc(s, dc_index); + val = mjpeg_decode_dc(s, dc_index); if (val == 0xffff) { dprintf("error dc\n"); return -1; } + quant_matrix = s->quant_matrixes[quant_index]; val = val * quant_matrix[0] + s->last_dc[component]; s->last_dc[component] = val; block[0] = val; @@ -731,17 +901,24 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s, nb_components = get_bits(&s->gb, 8); /* XXX: only interleaved scan accepted */ if (nb_components != 3) + { + dprintf("decode_sos: components(%d) mismatch\n", nb_components); return -1; + } vmax = 0; hmax = 0; for(i=0;i<nb_components;i++) { id = get_bits(&s->gb, 8) - 1; + dprintf("component: %d\n", id); /* find component index */ for(index=0;index<s->nb_components;index++) if (id == s->component_id[index]) break; if (index == s->nb_components) + { + dprintf("decode_sos: index(%d) out of components\n", index); return -1; + } comp_index[i] = index; nb_blocks[i] = s->h_count[index] * s->v_count[index]; @@ -749,15 +926,31 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s, v_count[i] = s->v_count[index]; dc_index[i] = get_bits(&s->gb, 4); - if (dc_index[i] >= 4) - return -1; ac_index[i] = get_bits(&s->gb, 4); - if (ac_index[i] >= 4) - return -1; + + if (dc_index[i] < 0 || ac_index[i] < 0 || + dc_index[i] >= 4 || ac_index[i] >= 4) + goto out_of_range; + switch(s->start_code) + { + case SOF0: + if (dc_index[i] > 1 || ac_index[i] > 1) + goto out_of_range; + break; + case SOF1: + case SOF2: + if (dc_index[i] > 3 || ac_index[i] > 3) + goto out_of_range; + break; + case SOF3: + if (dc_index[i] > 3 || ac_index[i] != 0) + goto out_of_range; + break; + } } - get_bits(&s->gb, 8); /* Ss */ - get_bits(&s->gb, 8); /* Se */ - get_bits(&s->gb, 8); /* not used */ + skip_bits(&s->gb, 8); /* Ss */ + skip_bits(&s->gb, 8); /* Se */ + skip_bits(&s->gb, 8); /* Ah and Al (each are 4 bits) */ for(i=0;i<nb_components;i++) s->last_dc[i] = 1024; @@ -787,22 +980,24 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s, v = v_count[i]; x = 0; y = 0; + if (s->restart_interval && !s->restart_count) + s->restart_count = s->restart_interval; for(j=0;j<n;j++) { memset(s->block, 0, sizeof(s->block)); if (decode_block(s, s->block, i, dc_index[i], ac_index[i], s->quant_index[c]) < 0) { - dprintf("error %d %d\n", mb_y, mb_x); + dprintf("error y=%d x=%d\n", mb_y, mb_x); ret = -1; goto the_end; } - ff_idct (s->block); +// dprintf("mb: %d %d processed\n", mb_y, mb_x); ptr = s->current_picture[c] + (s->linesize[c] * (v * mb_y + y) * 8) + (h * mb_x + x) * 8; if (s->interlaced && s->bottom_field) ptr += s->linesize[c] >> 1; - put_pixels_clamped(s->block, ptr, s->linesize[c]); + ff_idct_put(ptr, s->linesize[c], s->block); if (++x == h) { x = 0; y++; @@ -815,6 +1010,139 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s, the_end: emms_c(); return ret; + out_of_range: + dprintf("decode_sos: ac/dc index out of range\n"); + return -1; +} + +static int mjpeg_decode_dri(MJpegDecodeContext *s, + UINT8 *buf, int buf_size) +{ + init_get_bits(&s->gb, buf, buf_size); + + if (get_bits(&s->gb, 16) != 4) + return -1; + s->restart_interval = get_bits(&s->gb, 16); + printf("restart interval: %d\n", s->restart_interval); + + return 0; +} + +#define FOURCC(a,b,c,d) ((a << 24) | (b << 16) | (c << 8) | d) +static int mjpeg_decode_app(MJpegDecodeContext *s, + UINT8 *buf, int buf_size, int start_code) +{ + int len, id; + + init_get_bits(&s->gb, buf, buf_size); + + /* XXX: verify len field validity */ + len = get_bits(&s->gb, 16); + if (len < 5) + return -1; + + id = (get_bits(&s->gb, 16) << 16) | get_bits(&s->gb, 16); + len -= 6; + + /* buggy AVID, it puts EOI only at every 10th frame */ + /* also this fourcc is used by non-avid files too, it means + interleaving, but it's always present in AVID files */ + if (id == FOURCC('A','V','I','1')) + { + /* structure: + 4bytes AVI1 + 1bytes polarity + 1bytes always zero + 4bytes field_size + 4bytes field_size_less_padding + */ + s->buggy_avid = 1; + if (s->first_picture) + printf("mjpeg: workarounding buggy AVID\n"); + s->interleaved_rows = get_bits(&s->gb, 8); +#if 0 + skip_bits(&s->gb, 8); + skip_bits(&s->gb, 32); + skip_bits(&s->gb, 32); + len -= 10; +#endif + if (s->interleaved_rows) + printf("mjpeg: interleaved rows: %d\n", s->interleaved_rows); + goto out; + } + + len -= 2; + + if (id == FOURCC('J','F','I','F')) + { + skip_bits(&s->gb, 8); /* the trailing zero-byte */ + printf("mjpeg: JFIF header found (version: %x.%x)\n", + get_bits(&s->gb, 8), get_bits(&s->gb, 8)); + goto out; + } + + /* Apple MJPEG-A */ + if ((start_code == APP1) && (len > (0x28 - 8))) + { + id = (get_bits(&s->gb, 16) << 16) | get_bits(&s->gb, 16); + len -= 4; + if (id == FOURCC('m','j','p','g')) /* Apple MJPEG-A */ + { +#if 0 + skip_bits(&s->gb, 32); /* field size */ + skip_bits(&s->gb, 32); /* pad field size */ + skip_bits(&s->gb, 32); /* next off */ + skip_bits(&s->gb, 32); /* quant off */ + skip_bits(&s->gb, 32); /* huff off */ + skip_bits(&s->gb, 32); /* image off */ + skip_bits(&s->gb, 32); /* scan off */ + skip_bits(&s->gb, 32); /* data off */ +#endif + if (s->first_picture) + printf("mjpeg: Apple MJPEG-A header found\n"); + } + } + +out: + /* should check for further values.. */ + SKIP_REMAINING(&s->gb, len); + + return 0; +} +#undef FOURCC + +static int mjpeg_decode_com(MJpegDecodeContext *s, + UINT8 *buf, int buf_size) +{ + int len, i; + UINT8 *cbuf; + + init_get_bits(&s->gb, buf, buf_size); + + /* XXX: verify len field validity */ + len = get_bits(&s->gb, 16)-2; + cbuf = av_malloc(len+1); + + for (i = 0; i < len; i++) + cbuf[i] = get_bits(&s->gb, 8); + if (cbuf[i-1] == '\n') + cbuf[i-1] = 0; + else + cbuf[i] = 0; + + printf("mjpeg comment: '%s'\n", cbuf); + + /* buggy avid, it puts EOI only at every 10th frame */ + if (!strcmp(cbuf, "AVID")) + { + s->buggy_avid = 1; + if (s->first_picture) + printf("mjpeg: workarounding buggy AVID\n"); + } + + av_free(cbuf); + + return 0; } /* return the 8 bit start code value and update the search @@ -858,8 +1186,9 @@ static int mjpeg_decode_frame(AVCodecContext *avctx, { MJpegDecodeContext *s = avctx->priv_data; UINT8 *buf_end, *buf_ptr, *buf_start; - int len, code, start_code, input_size, i; + int len, code, input_size, i; AVPicture *picture = data; + unsigned int start_code; *data_size = 0; @@ -883,10 +1212,13 @@ static int mjpeg_decode_frame(AVCodecContext *avctx, } else { memcpy(s->buf_ptr, buf_start, len); s->buf_ptr += len; - /* if we got FF 00, we copy FF to the stream to unescape FF 00 */ - if (code == 0) { + if (code < 0) { + /* nothing to do: wait next marker */ + } else if (code == 0 || code == 0xff) { + /* if we got FF 00, we copy FF to the stream to unescape FF 00 */ + /* valid marker code is between 00 and ff - alex */ s->buf_ptr--; - } else if (code > 0) { + } else { /* prepare data for next start code */ input_size = s->buf_ptr - s->buffer; start_code = s->start_code; @@ -895,6 +1227,7 @@ static int mjpeg_decode_frame(AVCodecContext *avctx, dprintf("marker=%x\n", start_code); switch(start_code) { case SOI: + s->restart_interval = 0; /* nothing to do on SOI */ break; case DQT: @@ -908,7 +1241,7 @@ static int mjpeg_decode_frame(AVCodecContext *avctx, break; case SOS: mjpeg_decode_sos(s, s->buffer, input_size); - if (s->start_code == EOI) { + if (s->start_code == EOI || s->buggy_avid || s->restart_interval) { int l; if (s->interlaced) { s->bottom_field ^= 1; @@ -943,11 +1276,41 @@ static int mjpeg_decode_frame(AVCodecContext *avctx, } /* dummy quality */ /* XXX: infer it with matrix */ - avctx->quality = 3; + avctx->quality = 3; goto the_end; } break; + case DRI: + mjpeg_decode_dri(s, s->buffer, input_size); + break; + case SOF1: + case SOF2: + case SOF3: + case SOF5: + case SOF6: + case SOF7: + case SOF9: + case SOF10: + case SOF11: + case SOF13: + case SOF14: + case SOF15: + case JPG: + printf("mjpeg: unsupported coding type (%x)\n", start_code); + return -1; } +#if 1 + if (start_code >= 0xd0 && start_code <= 0xd7) { + dprintf("restart marker: %d\n", start_code&0x0f); + } else if (s->first_picture) { + /* APP fields */ + if (start_code >= 0xe0 && start_code <= 0xef) + mjpeg_decode_app(s, s->buffer, input_size, start_code); + /* Comment */ + else if (start_code == COM) + mjpeg_decode_com(s, s->buffer, input_size); + } +#endif } } } @@ -961,7 +1324,7 @@ static int mjpeg_decode_end(AVCodecContext *avctx) int i, j; for(i=0;i<MAX_COMPONENTS;i++) - free(s->current_picture[i]); + av_free(s->current_picture[i]); for(i=0;i<2;i++) { for(j=0;j<4;j++) free_vlc(&s->vlcs[i][j]); @@ -978,4 +1341,6 @@ AVCodec mjpeg_decoder = { NULL, mjpeg_decode_end, mjpeg_decode_frame, + 0, + NULL }; |