mirror of https://git.ffmpeg.org/ffmpeg.git
reworked decode_frame marker searching, fixes many non-working samples
Originally committed as revision 1079 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
060f89b328
commit
109362cbf4
|
@ -17,10 +17,10 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Support for external huffman table, various fixes (AVID workaround),
|
||||
* aspecting and various markers support
|
||||
* aspecting and new decode_frame mechanism
|
||||
* by Alex Beregszaszi <alex@naxine.org>
|
||||
*/
|
||||
//#define DEBUG
|
||||
#define DEBUG
|
||||
#include "avcodec.h"
|
||||
#include "dsputil.h"
|
||||
#include "mpegvideo.h"
|
||||
|
@ -29,7 +29,7 @@
|
|||
#include "fastmemcpy.h"
|
||||
#endif
|
||||
|
||||
/* use two quantizer table (one for luminance and one for chrominance) */
|
||||
/* use two quantizer tables (one for luminance and one for chrominance) */
|
||||
/* not yet working */
|
||||
#undef TWOMATRIXES
|
||||
|
||||
|
@ -590,11 +590,12 @@ void mjpeg_encode_mb(MpegEncContext *s,
|
|||
typedef struct MJpegDecodeContext {
|
||||
AVCodecContext *avctx;
|
||||
GetBitContext gb;
|
||||
UINT32 header_state;
|
||||
int start_code; /* current start code */
|
||||
UINT8 *buf_ptr;
|
||||
int buffer_size;
|
||||
int mpeg_enc_ctx_allocated; /* true if decoding context allocated */
|
||||
|
||||
int start_code; /* current start code */
|
||||
int buffer_size;
|
||||
UINT8 *buffer;
|
||||
|
||||
INT16 quant_matrixes[4][64];
|
||||
VLC vlcs[2][4];
|
||||
|
||||
|
@ -614,7 +615,6 @@ typedef struct MJpegDecodeContext {
|
|||
UINT8 *current_picture[MAX_COMPONENTS]; /* picture structure */
|
||||
int linesize[MAX_COMPONENTS];
|
||||
DCTELEM block[64] __align8;
|
||||
UINT8 buffer[PICTURE_BUFFER_SIZE];
|
||||
|
||||
int buggy_avid;
|
||||
int restart_interval;
|
||||
|
@ -624,13 +624,7 @@ typedef struct MJpegDecodeContext {
|
|||
void (*idct_put)(UINT8 *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/);
|
||||
} 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 int mjpeg_decode_dht(MJpegDecodeContext *s);
|
||||
|
||||
static void build_vlc(VLC *vlc, const UINT8 *bits_table, const UINT8 *val_table,
|
||||
int nb_codes)
|
||||
|
@ -664,12 +658,11 @@ static int mjpeg_decode_init(AVCodecContext *avctx)
|
|||
s->idct_put= s2.idct_put;
|
||||
MPV_common_end(&s2);
|
||||
|
||||
s->header_state = 0;
|
||||
s->mpeg_enc_ctx_allocated = 0;
|
||||
s->buffer_size = PICTURE_BUFFER_SIZE - 1; /* minus 1 to take into
|
||||
account FF 00 case */
|
||||
s->buffer = av_malloc(s->buffer_size);
|
||||
s->start_code = -1;
|
||||
s->buf_ptr = s->buffer;
|
||||
s->first_picture = 1;
|
||||
s->org_width = avctx->width;
|
||||
s->org_height = avctx->height;
|
||||
|
@ -682,18 +675,18 @@ static int mjpeg_decode_init(AVCodecContext *avctx)
|
|||
if (avctx->flags & CODEC_FLAG_EXTERN_HUFF)
|
||||
{
|
||||
printf("mjpeg: using external huffman table\n");
|
||||
mjpeg_decode_dht(s, avctx->extradata, avctx->extradata_size);
|
||||
init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size);
|
||||
mjpeg_decode_dht(s);
|
||||
/* should check for error - but dunno */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* quantize tables */
|
||||
static int mjpeg_decode_dqt(MJpegDecodeContext *s,
|
||||
UINT8 *buf, int buf_size)
|
||||
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) - 2;
|
||||
|
||||
|
@ -716,23 +709,17 @@ static int mjpeg_decode_dqt(MJpegDecodeContext *s,
|
|||
len -= 65;
|
||||
}
|
||||
|
||||
SKIP_REMAINING(&s->gb, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* decode huffman tables and build VLC decoders */
|
||||
static int mjpeg_decode_dht(MJpegDecodeContext *s,
|
||||
UINT8 *buf, int buf_size)
|
||||
static int mjpeg_decode_dht(MJpegDecodeContext *s)
|
||||
{
|
||||
int len, index, i, class, n, v, code_max;
|
||||
UINT8 bits_table[17];
|
||||
UINT8 val_table[256];
|
||||
|
||||
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 > 0) {
|
||||
if (len < 17)
|
||||
|
@ -770,13 +757,10 @@ static int mjpeg_decode_dht(MJpegDecodeContext *s,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int mjpeg_decode_sof0(MJpegDecodeContext *s,
|
||||
UINT8 *buf, int buf_size)
|
||||
static int mjpeg_decode_sof0(MJpegDecodeContext *s)
|
||||
{
|
||||
int len, nb_components, i, width, height;
|
||||
|
||||
init_get_bits(&s->gb, buf, buf_size);
|
||||
|
||||
/* XXX: verify len field validity */
|
||||
len = get_bits(&s->gb, 16);
|
||||
/* only 8 bits/component accepted */
|
||||
|
@ -851,8 +835,12 @@ static int mjpeg_decode_sof0(MJpegDecodeContext *s,
|
|||
static inline int mjpeg_decode_dc(MJpegDecodeContext *s, int dc_index)
|
||||
{
|
||||
int code, diff;
|
||||
|
||||
#if 0
|
||||
code = get_vlc2(&s->gb, s->vlc[0][dc_index].table,
|
||||
s->vlc[0][dc_index].bits, 1);
|
||||
#else
|
||||
code = get_vlc(&s->gb, &s->vlcs[0][dc_index]);
|
||||
#endif
|
||||
if (code < 0)
|
||||
{
|
||||
dprintf("mjpeg_decode_dc: bad vlc: %d:%d (%p)\n", 0, dc_index,
|
||||
|
@ -892,7 +880,12 @@ static int decode_block(MJpegDecodeContext *s, DCTELEM *block,
|
|||
ac_vlc = &s->vlcs[1][ac_index];
|
||||
i = 1;
|
||||
for(;;) {
|
||||
#if 0
|
||||
code = get_vlc2(&s->gb, s->vlcs[1][ac_index].table,
|
||||
s->vlcs[1][ac_index].bits, 2);
|
||||
#else
|
||||
code = get_vlc(&s->gb, ac_vlc);
|
||||
#endif
|
||||
if (code < 0) {
|
||||
dprintf("error ac\n");
|
||||
return -1;
|
||||
|
@ -923,8 +916,7 @@ static int decode_block(MJpegDecodeContext *s, DCTELEM *block,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int mjpeg_decode_sos(MJpegDecodeContext *s,
|
||||
UINT8 *buf, int buf_size)
|
||||
static int mjpeg_decode_sos(MJpegDecodeContext *s)
|
||||
{
|
||||
int len, nb_components, i, j, n, h, v, ret;
|
||||
int mb_width, mb_height, mb_x, mb_y, vmax, hmax, index, id;
|
||||
|
@ -935,10 +927,14 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s,
|
|||
int h_count[4];
|
||||
int v_count[4];
|
||||
|
||||
init_get_bits(&s->gb, buf, buf_size);
|
||||
/* XXX: verify len field validity */
|
||||
len = get_bits(&s->gb, 16);
|
||||
nb_components = get_bits(&s->gb, 8);
|
||||
if (len != 6+2*nb_components)
|
||||
{
|
||||
dprintf("decode_sos: invalid len (%d)\n", len);
|
||||
return -1;
|
||||
}
|
||||
/* XXX: only interleaved scan accepted */
|
||||
if (nb_components != 3)
|
||||
{
|
||||
|
@ -1061,11 +1057,8 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s,
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int mjpeg_decode_dri(MJpegDecodeContext *s,
|
||||
UINT8 *buf, int buf_size)
|
||||
static int mjpeg_decode_dri(MJpegDecodeContext *s)
|
||||
{
|
||||
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);
|
||||
|
@ -1075,13 +1068,10 @@ static int mjpeg_decode_dri(MJpegDecodeContext *s,
|
|||
}
|
||||
|
||||
#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)
|
||||
static int mjpeg_decode_app(MJpegDecodeContext *s, 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)
|
||||
|
@ -1164,20 +1154,16 @@ static int mjpeg_decode_app(MJpegDecodeContext *s,
|
|||
|
||||
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)
|
||||
static int mjpeg_decode_com(MJpegDecodeContext *s)
|
||||
{
|
||||
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);
|
||||
|
@ -1195,8 +1181,8 @@ static int mjpeg_decode_com(MJpegDecodeContext *s,
|
|||
if (!strcmp(cbuf, "AVID"))
|
||||
{
|
||||
s->buggy_avid = 1;
|
||||
if (s->first_picture)
|
||||
printf("mjpeg: workarounding buggy AVID\n");
|
||||
// if (s->first_picture)
|
||||
// printf("mjpeg: workarounding buggy AVID\n");
|
||||
}
|
||||
|
||||
av_free(cbuf);
|
||||
|
@ -1204,41 +1190,58 @@ static int mjpeg_decode_com(MJpegDecodeContext *s,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int valid_marker_list[] =
|
||||
{
|
||||
/* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f */
|
||||
/* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 1 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 2 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 3 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 4 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 5 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 6 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 7 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* a */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* b */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* c */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
/* d */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
/* e */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
/* f */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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,
|
||||
UINT32 *header_state)
|
||||
static int find_marker(UINT8 **pbuf_ptr, UINT8 *buf_end)
|
||||
{
|
||||
UINT8 *buf_ptr;
|
||||
unsigned int state, v;
|
||||
unsigned int v, v2;
|
||||
int val;
|
||||
#ifdef DEBUG
|
||||
int skipped=0;
|
||||
#endif
|
||||
|
||||
state = *header_state;
|
||||
buf_ptr = *pbuf_ptr;
|
||||
retry:
|
||||
if (state) {
|
||||
/* get marker */
|
||||
found:
|
||||
if (buf_ptr < buf_end) {
|
||||
val = *buf_ptr++;
|
||||
state = 0;
|
||||
if ((val >= RST0) && (val <= RST7))
|
||||
goto retry;
|
||||
} else {
|
||||
val = -1;
|
||||
}
|
||||
} else {
|
||||
while (buf_ptr < buf_end) {
|
||||
v = *buf_ptr++;
|
||||
if (v == 0xff) {
|
||||
state = 1;
|
||||
v2 = *buf_ptr;
|
||||
if ((v == 0xff) && (v2 >= 0xc0) && (v2 <= 0xfe)) {
|
||||
val = *buf_ptr++;
|
||||
goto found;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
skipped++;
|
||||
#endif
|
||||
}
|
||||
val = -1;
|
||||
}
|
||||
found:
|
||||
#ifdef DEBUG
|
||||
dprintf("find_marker skipped %d bytes\n", skipped);
|
||||
#endif
|
||||
*pbuf_ptr = buf_ptr;
|
||||
*header_state = state;
|
||||
return val;
|
||||
}
|
||||
|
||||
|
@ -1247,10 +1250,9 @@ static int mjpeg_decode_frame(AVCodecContext *avctx,
|
|||
UINT8 *buf, int buf_size)
|
||||
{
|
||||
MJpegDecodeContext *s = avctx->priv_data;
|
||||
UINT8 *buf_end, *buf_ptr, *buf_start;
|
||||
int len, code, input_size, i;
|
||||
UINT8 *buf_end, *buf_ptr;
|
||||
int i, start_code;
|
||||
AVPicture *picture = data;
|
||||
unsigned int start_code;
|
||||
|
||||
*data_size = 0;
|
||||
|
||||
|
@ -1261,49 +1263,78 @@ static int mjpeg_decode_frame(AVCodecContext *avctx,
|
|||
buf_ptr = buf;
|
||||
buf_end = buf + buf_size;
|
||||
while (buf_ptr < buf_end) {
|
||||
buf_start = buf_ptr;
|
||||
/* find start next marker */
|
||||
code = find_marker(&buf_ptr, buf_end, &s->header_state);
|
||||
/* copy to buffer */
|
||||
len = buf_ptr - buf_start;
|
||||
if (len + (s->buf_ptr - s->buffer) > s->buffer_size) {
|
||||
/* data too big : flush */
|
||||
s->buf_ptr = s->buffer;
|
||||
if (code > 0)
|
||||
s->start_code = code;
|
||||
start_code = find_marker(&buf_ptr, buf_end);
|
||||
{
|
||||
/* EOF */
|
||||
if (start_code < 0) {
|
||||
goto the_end;
|
||||
} else {
|
||||
memcpy(s->buf_ptr, buf_start, len);
|
||||
s->buf_ptr += len;
|
||||
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 {
|
||||
/* prepare data for next start code */
|
||||
input_size = s->buf_ptr - s->buffer;
|
||||
start_code = s->start_code;
|
||||
s->buf_ptr = s->buffer;
|
||||
s->start_code = code;
|
||||
dprintf("marker=%x\n", start_code);
|
||||
dprintf("marker=%x avail_size_in_buf=%d\n", start_code, buf_end - buf_ptr);
|
||||
|
||||
if ((buf_end - buf_ptr) > s->buffer_size)
|
||||
{
|
||||
av_free(s->buffer);
|
||||
s->buffer_size = buf_end-buf_ptr;
|
||||
s->buffer = av_malloc(s->buffer_size);
|
||||
}
|
||||
|
||||
/* unescape buffer of SOS */
|
||||
if (start_code == SOS)
|
||||
{
|
||||
UINT8 *src = buf_ptr;
|
||||
UINT8 *dst = s->buffer;
|
||||
|
||||
while (src<buf_end)
|
||||
{
|
||||
unsigned char *x = *(src++);
|
||||
|
||||
*(dst++) = x;
|
||||
if (x == 0xff)
|
||||
{
|
||||
x = *(src++);
|
||||
if (x >= 0xd0 && x <= 0xd7)
|
||||
*(dst++) = x;
|
||||
else if (x)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
memcpy(s->buffer, buf_ptr, buf_end - buf_ptr);
|
||||
init_get_bits(&s->gb, s->buffer, s->buffer_size);
|
||||
|
||||
s->start_code = start_code;
|
||||
|
||||
/* process markers */
|
||||
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, start_code);
|
||||
/* Comment */
|
||||
else if (start_code == COM)
|
||||
mjpeg_decode_com(s);
|
||||
}
|
||||
|
||||
switch(start_code) {
|
||||
case SOI:
|
||||
s->restart_interval = 0;
|
||||
/* nothing to do on SOI */
|
||||
break;
|
||||
case DQT:
|
||||
mjpeg_decode_dqt(s, s->buffer, input_size);
|
||||
mjpeg_decode_dqt(s);
|
||||
break;
|
||||
case DHT:
|
||||
mjpeg_decode_dht(s, s->buffer, input_size);
|
||||
mjpeg_decode_dht(s);
|
||||
break;
|
||||
case SOF0:
|
||||
mjpeg_decode_sof0(s, s->buffer, input_size);
|
||||
mjpeg_decode_sof0(s);
|
||||
break;
|
||||
case SOS:
|
||||
mjpeg_decode_sos(s, s->buffer, input_size);
|
||||
if (s->start_code == EOI || s->buggy_avid || s->restart_interval) {
|
||||
case EOI:
|
||||
eoi_parser:
|
||||
{
|
||||
int l;
|
||||
if (s->interlaced) {
|
||||
s->bottom_field ^= 1;
|
||||
|
@ -1313,10 +1344,15 @@ static int mjpeg_decode_frame(AVCodecContext *avctx,
|
|||
}
|
||||
for(i=0;i<3;i++) {
|
||||
picture->data[i] = s->current_picture[i];
|
||||
#if 1
|
||||
l = s->linesize[i];
|
||||
if (s->interlaced)
|
||||
l >>= 1;
|
||||
picture->linesize[i] = l;
|
||||
#else
|
||||
picture->linesize[i] = (s->interlaced) ?
|
||||
s->linesize[i] >> 1 : s->linesize[i];
|
||||
#endif
|
||||
}
|
||||
*data_size = sizeof(AVPicture);
|
||||
avctx->height = s->height;
|
||||
|
@ -1342,8 +1378,15 @@ static int mjpeg_decode_frame(AVCodecContext *avctx,
|
|||
goto the_end;
|
||||
}
|
||||
break;
|
||||
case SOS:
|
||||
mjpeg_decode_sos(s);
|
||||
/* buggy avid puts EOI every 10-20th frame */
|
||||
/* if restart period is over process EOI */
|
||||
if ((s->buggy_avid && !s->interlaced) || s->restart_interval)
|
||||
goto eoi_parser;
|
||||
break;
|
||||
case DRI:
|
||||
mjpeg_decode_dri(s, s->buffer, input_size);
|
||||
mjpeg_decode_dri(s);
|
||||
break;
|
||||
case SOF1:
|
||||
case SOF2:
|
||||
|
@ -1359,26 +1402,24 @@ static int mjpeg_decode_frame(AVCodecContext *avctx,
|
|||
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
|
||||
}
|
||||
break;
|
||||
// default:
|
||||
// printf("mjpeg: unsupported marker (%x)\n", start_code);
|
||||
// break;
|
||||
}
|
||||
|
||||
not_the_end:
|
||||
;
|
||||
/* eof process start code */
|
||||
buf_ptr += (get_bits_count(&s->gb)+7)/8;
|
||||
dprintf("marker parser used %d bytes (%d bits)\n",
|
||||
(get_bits_count(&s->gb)+7)/8, get_bits_count(&s->gb));
|
||||
}
|
||||
}
|
||||
}
|
||||
the_end:
|
||||
|
||||
dprintf("mjpeg decode frame unused %d bytes\n", buf_end - buf_ptr);
|
||||
// return buf_end - buf_ptr;
|
||||
return buf_ptr - buf;
|
||||
}
|
||||
|
||||
|
@ -1387,6 +1428,7 @@ static int mjpeg_decode_end(AVCodecContext *avctx)
|
|||
MJpegDecodeContext *s = avctx->priv_data;
|
||||
int i, j;
|
||||
|
||||
av_free(s->buffer);
|
||||
for(i=0;i<MAX_COMPONENTS;i++)
|
||||
av_free(s->current_picture[i]);
|
||||
for(i=0;i<2;i++) {
|
||||
|
|
Loading…
Reference in New Issue