diff options
Diffstat (limited to 'src/libffmpeg/libavcodec/mjpeg.c')
-rw-r--r-- | src/libffmpeg/libavcodec/mjpeg.c | 68 |
1 files changed, 58 insertions, 10 deletions
diff --git a/src/libffmpeg/libavcodec/mjpeg.c b/src/libffmpeg/libavcodec/mjpeg.c index df7415b81..1103e11d0 100644 --- a/src/libffmpeg/libavcodec/mjpeg.c +++ b/src/libffmpeg/libavcodec/mjpeg.c @@ -16,8 +16,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <stdlib.h> -#include <stdio.h> #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" @@ -423,12 +421,20 @@ void mjpeg_encode_mb(MpegEncContext *s, //#define DEBUG +#ifndef CONFIG_WIN32 + #ifdef DEBUG #define dprintf(fmt,args...) printf(fmt, ## args) #else #define dprintf(fmt,args...) #endif +#else + +inline void dprintf(const char* fmt,...) {} + +#endif + /* compressed picture size */ #define PICTURE_BUFFER_SIZE 100000 @@ -443,6 +449,12 @@ typedef struct MJpegDecodeContext { int mpeg_enc_ctx_allocated; /* true if decoding context allocated */ INT16 quant_matrixes[4][64]; VLC vlcs[2][4]; + + int org_width, org_height; /* size given at codec init */ + int first_picture; /* true if decoding first picture */ + int interlaced; /* true if interlaced */ + int bottom_field; /* true if bottom field */ + int width, height; int nb_components; int component_id[MAX_COMPONENTS]; @@ -479,6 +491,9 @@ static int mjpeg_decode_init(AVCodecContext *avctx) account FF 00 case */ s->start_code = -1; s->buf_ptr = s->buffer; + s->first_picture = 1; + s->org_width = avctx->width; + s->org_height = avctx->height; build_vlc(&s->vlcs[0][0], bits_dc_luminance, val_dc_luminance, 12); build_vlc(&s->vlcs[0][1], bits_dc_chrominance, val_dc_chrominance, 12); @@ -611,6 +626,14 @@ static int mjpeg_decode_sof0(MJpegDecodeContext *s, } s->width = width; s->height = height; + /* test interlaced mode */ + if (s->first_picture && + s->org_height != 0 && + s->height < ((s->org_height * 3) / 4)) { + s->interlaced = 1; + s->bottom_field = 0; + } + for(i=0;i<nb_components;i++) { int w, h, hh, vv; hh = s->h_max / s->h_count[i]; @@ -619,12 +642,15 @@ static int mjpeg_decode_sof0(MJpegDecodeContext *s, h = (s->height + 8 * vv - 1) / (8 * vv); w = w * 8; h = h * 8; + if (s->interlaced) + w *= 2; s->linesize[i] = w; /* memory test is done in mjpeg_decode_sos() */ s->current_picture[i] = av_mallocz(w * h); } + s->first_picture = 0; } - + return 0; } @@ -704,7 +730,7 @@ static int decode_block(MJpegDecodeContext *s, DCTELEM *block, static int mjpeg_decode_sos(MJpegDecodeContext *s, UINT8 *buf, int buf_size) { - int len, nb_components, i, j, n, h, v; + int len, nb_components, i, j, n, h, v, ret; int mb_width, mb_height, mb_x, mb_y, vmax, hmax, index, id; int comp_index[4]; int dc_index[4]; @@ -781,12 +807,15 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s, dc_index[i], ac_index[i], s->quant_index[c]) < 0) { dprintf("error %d %d\n", mb_y, mb_x); - return -1; + ret = -1; + goto the_end; } ff_idct (s->block); 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]); if (++x == h) { x = 0; @@ -796,7 +825,10 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s, } } } - return 0; + ret = 0; + the_end: + emms_c(); + return ret; } /* return the 8 bit start code value and update the search @@ -843,11 +875,11 @@ static int mjpeg_decode_frame(AVCodecContext *avctx, int len, code, start_code, input_size, i; AVPicture *picture = data; + *data_size = 0; + /* no supplementary picture */ - if (buf_size == 0) { - *data_size = 0; + if (buf_size == 0) return 0; - } buf_ptr = buf; buf_end = buf + buf_size; @@ -874,6 +906,7 @@ static int mjpeg_decode_frame(AVCodecContext *avctx, start_code = s->start_code; s->buf_ptr = s->buffer; s->start_code = code; + dprintf("marker=%x\n", start_code); switch(start_code) { case SOI: /* nothing to do on SOI */ @@ -890,12 +923,24 @@ static int mjpeg_decode_frame(AVCodecContext *avctx, case SOS: mjpeg_decode_sos(s, s->buffer, input_size); if (s->start_code == EOI) { + int l; + if (s->interlaced) { + s->bottom_field ^= 1; + /* if not bottom field, do not output image yet */ + if (s->bottom_field) + goto the_end; + } for(i=0;i<3;i++) { picture->data[i] = s->current_picture[i]; - picture->linesize[i] = s->linesize[i]; + l = s->linesize[i]; + if (s->interlaced) + l >>= 1; + picture->linesize[i] = l; } *data_size = sizeof(AVPicture); avctx->height = s->height; + if (s->interlaced) + avctx->height *= 2; avctx->width = s->width; /* XXX: not complete test ! */ switch((s->h_count[0] << 4) | s->v_count[0]) { @@ -910,6 +955,9 @@ static int mjpeg_decode_frame(AVCodecContext *avctx, avctx->pix_fmt = PIX_FMT_YUV420P; break; } + /* dummy quality */ + /* XXX: infer it with matrix */ + avctx->quality = 3; goto the_end; } break; |