summaryrefslogtreecommitdiff
path: root/src/libffmpeg/libavcodec/mjpeg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libffmpeg/libavcodec/mjpeg.c')
-rw-r--r--src/libffmpeg/libavcodec/mjpeg.c68
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;