# HG changeset patch # User arpi_esp # Date 1020443680 0 # Node ID 167aa21aa250d044da6bcd0cc788390023245255 # Parent 386f430e93f4ada08dcdefa005383afeca186df6 patch by Alex Beregszaszi - AVID (AVRn) support (workaround) - print error instead of failing for unsupported SOF - fixed the 0 */ //#define DEBUG @@ -24,6 +24,10 @@ #include "dsputil.h" #include "mpegvideo.h" +#ifdef USE_FASTMEMCPY +#include "fastmemcpy.h" +#endif + typedef struct MJpegContext { UINT8 huff_size_dc_luminance[12]; UINT16 huff_code_dc_luminance[12]; @@ -533,6 +537,8 @@ int linesize[MAX_COMPONENTS]; DCTELEM block[64] __align8; UINT8 buffer[PICTURE_BUFFER_SIZE]; + + int buggy_avid; } MJpegDecodeContext; static void build_vlc(VLC *vlc, const UINT8 *bits_table, const UINT8 *val_table, @@ -725,8 +731,10 @@ s->first_picture = 0; } - if (len != 8+(3*nb_components)) + if (len != (8+(3*nb_components))) + { dprintf("decode_sof0: error, len(%d) mismatch\n", len); + } return 0; } @@ -936,6 +944,39 @@ return -1; } +#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 len, id; + + init_get_bits(&s->gb, buf, buf_size); + + /* XXX: verify len field validity */ + len = get_bits(&s->gb, 16)-2; + if (len < 5) + return -1; + id = (get_bits(&s->gb, 16) << 16) | get_bits(&s->gb, 16); + if (get_bits(&s->gb, 8) != 0) + return -1; + + /* buggy avid, it puts EOI only at every 10th frame */ + if (id == FOURCC('A','V','I','1')) + { + s->buggy_avid = 1; + if (s->first_picture) + printf("mjpeg: workarounding buggy AVID\n"); + } + + /* if id == JFIF, we can extract some infos (aspect ratio), others + are useless */ + + /* should check for further values.. */ + + return 0; +} +#undef FOURCC + /* return the 8 bit start code value and update the search state. Return -1 if no start code found */ static int find_marker(UINT8 **pbuf_ptr, UINT8 *buf_end, @@ -1005,9 +1046,9 @@ s->buf_ptr += len; /* if we got FF 00, we copy FF to the stream to unescape FF 00 */ /* valid marker code is between 00 and ff - alex */ - if (code == 0 || code == 0xff) { + if (code <= 0 || code >= 0xff) { 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; @@ -1029,7 +1070,7 @@ break; case SOS: mjpeg_decode_sos(s, s->buffer, input_size); - if (s->start_code == EOI) { + if (s->start_code == EOI || s->buggy_avid) { int l; if (s->interlaced) { s->bottom_field ^= 1; @@ -1068,6 +1109,24 @@ goto the_end; } break; + case APP0: + mjpeg_decode_app(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; } } }