summaryrefslogtreecommitdiff
path: root/src/libffmpeg/libavcodec/mpeg12.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libffmpeg/libavcodec/mpeg12.c')
-rw-r--r--src/libffmpeg/libavcodec/mpeg12.c279
1 files changed, 147 insertions, 132 deletions
diff --git a/src/libffmpeg/libavcodec/mpeg12.c b/src/libffmpeg/libavcodec/mpeg12.c
index 11a8ea9c9..c31a711c7 100644
--- a/src/libffmpeg/libavcodec/mpeg12.c
+++ b/src/libffmpeg/libavcodec/mpeg12.c
@@ -316,13 +316,6 @@ static void common_init(MpegEncContext *s)
s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
}
-void ff_mpeg1_clean_buffers(MpegEncContext *s){
- s->last_dc[0] = 1 << (7 + s->intra_dc_precision);
- s->last_dc[1] = s->last_dc[0];
- s->last_dc[2] = s->last_dc[0];
- memset(s->last_mv, 0, sizeof(s->last_mv));
-}
-
#ifdef CONFIG_ENCODERS
void ff_mpeg1_encode_slice_header(MpegEncContext *s){
@@ -331,6 +324,13 @@ void ff_mpeg1_encode_slice_header(MpegEncContext *s){
put_bits(&s->pb, 1, 0); /* slice extra information */
}
+void ff_mpeg1_clean_buffers(MpegEncContext *s){
+ s->last_dc[0] = 1 << (7 + s->intra_dc_precision);
+ s->last_dc[1] = s->last_dc[0];
+ s->last_dc[2] = s->last_dc[0];
+ memset(s->last_mv, 0, sizeof(s->last_mv));
+}
+
void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number)
{
mpeg1_encode_sequence_header(s);
@@ -852,16 +852,13 @@ static inline int get_dmv(MpegEncContext *s)
static inline int get_qscale(MpegEncContext *s)
{
- int qscale;
+ int qscale = get_bits(&s->gb, 5);
if (s->mpeg2) {
if (s->q_scale_type) {
- qscale = non_linear_qscale[get_bits(&s->gb, 5)];
+ return non_linear_qscale[qscale];
} else {
- qscale = get_bits(&s->gb, 5) << 1;
+ return qscale << 1;
}
- } else {
- /* for mpeg1, we use the generic unquant code */
- qscale = get_bits(&s->gb, 5);
}
return qscale;
}
@@ -1179,7 +1176,7 @@ static int mpeg_decode_mb(MpegEncContext *s,
/* as h263, but only 17 codes */
static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred)
{
- int code, sign, val, m, l, shift;
+ int code, sign, val, l, shift;
code = get_vlc2(&s->gb, mv_vlc.table, MV_VLC_BITS, 2);
if (code == 0) {
@@ -1191,22 +1188,19 @@ static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred)
sign = get_bits1(&s->gb);
shift = fcode - 1;
- val = (code - 1) << shift;
- if (shift > 0)
+ val = code;
+ if (shift) {
+ val = (val - 1) << shift;
val |= get_bits(&s->gb, shift);
- val++;
+ val++;
+ }
if (sign)
val = -val;
val += pred;
/* modulo decoding */
l = 1 << (shift+4);
- m = 2 * l;
- if (val < -l) {
- val += m;
- } else if (val >= l) {
- val -= m;
- }
+ val = ((val + l)&(l*2-1)) - l;
return val;
}
@@ -1226,9 +1220,7 @@ static inline int decode_dc(MpegEncContext *s, int component)
if (code == 0) {
diff = 0;
} else {
- diff = get_bits(&s->gb, code);
- if ((diff & (1 << (code - 1))) == 0)
- diff = (-1 << code) | (diff + 1);
+ diff = get_xbits(&s->gb, code);
}
return diff;
}
@@ -1543,16 +1535,8 @@ static inline int mpeg2_decode_block_intra(MpegEncContext *s,
return 0;
}
-/* compressed picture size */
-#define PICTURE_BUFFER_SIZE 100000
-
typedef struct Mpeg1Context {
MpegEncContext mpeg_enc_ctx;
- uint32_t header_state;
- int start_code; /* current start code */
- uint8_t buffer[PICTURE_BUFFER_SIZE];
- uint8_t *buf_ptr;
- int buffer_size;
int mpeg_enc_ctx_allocated; /* true if decoding context allocated */
int repeat_field; /* true if we must repeat the field */
} Mpeg1Context;
@@ -1565,11 +1549,7 @@ static int mpeg_decode_init(AVCodecContext *avctx)
common_init(&s->mpeg_enc_ctx);
init_vlcs(&s->mpeg_enc_ctx);
- s->header_state = 0xff;
s->mpeg_enc_ctx_allocated = 0;
- s->buffer_size = PICTURE_BUFFER_SIZE;
- s->start_code = -1;
- s->buf_ptr = s->buffer;
s->mpeg_enc_ctx.picture_number = 0;
s->repeat_field = 0;
s->mpeg_enc_ctx.codec_id= avctx->codec->id;
@@ -1578,14 +1558,12 @@ static int mpeg_decode_init(AVCodecContext *avctx)
/* return the 8 bit start code value and update the search
state. Return -1 if no start code found */
-static int find_start_code(uint8_t **pbuf_ptr, uint8_t *buf_end,
- uint32_t *header_state)
+static int find_start_code(uint8_t **pbuf_ptr, uint8_t *buf_end)
{
uint8_t *buf_ptr;
- unsigned int state, v;
+ unsigned int state=0xFFFFFFFF, v;
int val;
- state = *header_state;
buf_ptr = *pbuf_ptr;
while (buf_ptr < buf_end) {
v = *buf_ptr++;
@@ -1599,7 +1577,6 @@ static int find_start_code(uint8_t **pbuf_ptr, uint8_t *buf_end,
val = -1;
found:
*pbuf_ptr = buf_ptr;
- *header_state = state;
return val;
}
@@ -1744,15 +1721,15 @@ static void mpeg_decode_picture_coding_extension(MpegEncContext *s)
}
if(s->alternate_scan){
- ff_init_scantable(s, &s->inter_scantable , ff_alternate_vertical_scan);
- ff_init_scantable(s, &s->intra_scantable , ff_alternate_vertical_scan);
- ff_init_scantable(s, &s->intra_h_scantable, ff_alternate_vertical_scan);
- ff_init_scantable(s, &s->intra_v_scantable, ff_alternate_vertical_scan);
+ ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_alternate_vertical_scan);
+ ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_alternate_vertical_scan);
+ ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_vertical_scan);
+ ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
}else{
- ff_init_scantable(s, &s->inter_scantable , ff_zigzag_direct);
- ff_init_scantable(s, &s->intra_scantable , ff_zigzag_direct);
- ff_init_scantable(s, &s->intra_h_scantable, ff_alternate_horizontal_scan);
- ff_init_scantable(s, &s->intra_v_scantable, ff_alternate_vertical_scan);
+ ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_zigzag_direct);
+ ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_zigzag_direct);
+ ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan);
+ ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
}
/* composite display not parsed */
@@ -1793,33 +1770,33 @@ static void mpeg_decode_extension(AVCodecContext *avctx,
}
}
-#define DECODE_SLICE_MB_ADDR_ERROR -3 //we faild decoding the mb_x/y info
#define DECODE_SLICE_FATAL_ERROR -2
#define DECODE_SLICE_ERROR -1
#define DECODE_SLICE_OK 0
-#define DECODE_SLICE_EOP 1
/**
* decodes a slice.
* @return DECODE_SLICE_FATAL_ERROR if a non recoverable error occured<br>
* DECODE_SLICE_ERROR if the slice is damaged<br>
* DECODE_SLICE_OK if this slice is ok<br>
- * DECODE_SLICE_EOP if the end of the picture is reached
*/
static int mpeg_decode_slice(AVCodecContext *avctx,
AVFrame *pict,
int start_code,
- uint8_t *buf, int buf_size)
+ uint8_t **buf, int buf_size)
{
Mpeg1Context *s1 = avctx->priv_data;
MpegEncContext *s = &s1->mpeg_enc_ctx;
int ret;
const int field_pic= s->picture_structure != PICT_FRAME;
+ s->resync_mb_x= s->mb_x =
+ s->resync_mb_y= s->mb_y = -1;
+
start_code = (start_code - 1) & 0xff;
if (start_code >= s->mb_height){
fprintf(stderr, "slice below image (%d >= %d)\n", start_code, s->mb_height);
- return DECODE_SLICE_MB_ADDR_ERROR;
+ return -1;
}
ff_mpeg1_clean_buffers(s);
@@ -1874,12 +1851,12 @@ static int mpeg_decode_slice(AVCodecContext *avctx,
}
s->first_slice = 0;
- init_get_bits(&s->gb, buf, buf_size*8);
+ init_get_bits(&s->gb, *buf, buf_size*8);
s->qscale = get_qscale(s);
if(s->qscale == 0){
fprintf(stderr, "qscale == 0\n");
- return DECODE_SLICE_MB_ADDR_ERROR;
+ return -1;
}
/* extra slice info */
@@ -1893,7 +1870,7 @@ static int mpeg_decode_slice(AVCodecContext *avctx,
int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2);
if (code < 0){
fprintf(stderr, "first mb_incr damaged\n");
- return DECODE_SLICE_MB_ADDR_ERROR;
+ return -1;
}
if (code >= 33) {
if (code == 33) {
@@ -1924,11 +1901,12 @@ static int mpeg_decode_slice(AVCodecContext *avctx,
const int xy = s->mb_x*2 + 1 + (s->mb_y*2 +1)*wrap;
int motion_x, motion_y;
- if (s->mb_intra || s->mv_type == MV_TYPE_16X16) {
+ if (s->mb_intra) {
+ motion_x = motion_y = 0;
+ }else if (s->mv_type == MV_TYPE_16X16) {
motion_x = s->mv[0][0][0];
motion_y = s->mv[0][0][1];
} else /*if (s->mv_type == MV_TYPE_FIELD)*/ {
- int i;
motion_x = s->mv[0][0][0] + s->mv[0][1][0];
motion_y = s->mv[0][0][1] + s->mv[0][1][1];
motion_x = (motion_x>>1) | (motion_x&1);
@@ -1956,6 +1934,17 @@ static int mpeg_decode_slice(AVCodecContext *avctx,
s->mb_x = 0;
s->mb_y++;
+
+ if(s->mb_y<<field_pic >= s->mb_height){
+ int left= s->gb.size_in_bits - get_bits_count(&s->gb);
+
+ if(left < 0 || (left && show_bits(&s->gb, FFMIN(left, 23)))
+ || (avctx->error_resilience >= FF_ER_AGGRESSIVE && left>8)){
+ fprintf(stderr, "end missmatch left=%d\n", left);
+ return -1;
+ }else
+ goto eos;
+ }
}
/* skip mb handling */
@@ -1985,24 +1974,31 @@ static int mpeg_decode_slice(AVCodecContext *avctx,
}
}
}
- if(s->mb_y<<field_pic >= s->mb_height){
- fprintf(stderr, "slice too long\n");
- return DECODE_SLICE_ERROR;
- }
}
-eos: //end of slice
+eos: // end of slice
+ *buf += get_bits_count(&s->gb)/8 - 1;
//printf("y %d %d %d %d\n", s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y);
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END);
+ return 0;
+}
- emms_c();
-
-//intf("%d %d %d %d\n", s->mb_y, s->mb_height, s->pict_type, s->picture_number);
+/**
+ * handles slice ends.
+ * @return 1 if it seems to be the last slice of
+ */
+static int slice_end(AVCodecContext *avctx, AVFrame *pict)
+{
+ Mpeg1Context *s1 = avctx->priv_data;
+ MpegEncContext *s = &s1->mpeg_enc_ctx;
+
/* end of slice reached */
- if (s->mb_y<<field_pic == s->mb_height && !s->first_field) {
+ if (/*s->mb_y<<field_pic == s->mb_height &&*/ !s->first_field) {
/* end of image */
- if(s->mpeg2)
- s->qscale >>=1;
+ if(s->mpeg2){
+ s->current_picture_ptr->qscale_type= FF_QSCALE_TYPE_MPEG2;
+ }else
+ s->current_picture_ptr->qscale_type= FF_QSCALE_TYPE_MPEG1;
+
ff_er_frame_end(s);
MPV_frame_end(s);
@@ -2014,16 +2010,14 @@ eos: //end of slice
s->picture_number++;
/* latency of 1 frame for I and P frames */
/* XXX: use another variable than picture_number */
- if (s->last_picture_ptr == NULL) {
- return DECODE_SLICE_OK;
- } else {
+ if (s->last_picture_ptr != NULL) {
*pict= *(AVFrame*)&s->last_picture;
ff_print_debug_info(s, s->last_picture_ptr);
}
}
- return DECODE_SLICE_EOP;
+ return 1;
} else {
- return DECODE_SLICE_OK;
+ return 0;
}
}
@@ -2167,17 +2161,55 @@ static void mpeg_decode_user_data(AVCodecContext *avctx,
}
}
+/**
+ * finds the end of the current frame in the bitstream.
+ * @return the position of the first byte of the next frame, or -1
+ */
+static int mpeg1_find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){
+ ParseContext *pc= &s->parse_context;
+ int i;
+ uint32_t state;
+
+ state= pc->state;
+
+ i=0;
+ if(!pc->frame_start_found){
+ for(i=0; i<buf_size; i++){
+ state= (state<<8) | buf[i];
+ if(state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE){
+ i++;
+ pc->frame_start_found=1;
+ break;
+ }
+ }
+ }
+
+ if(pc->frame_start_found){
+ for(; i<buf_size; i++){
+ state= (state<<8) | buf[i];
+ if((state&0xFFFFFF00) == 0x100){
+ if(state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE){
+ pc->frame_start_found=0;
+ pc->state=-1;
+ return i-3;
+ }
+ }
+ }
+ }
+ pc->state= state;
+ return END_NOT_FOUND;
+}
+
/* handle buffering and image synchronisation */
static int mpeg_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
uint8_t *buf, int buf_size)
{
Mpeg1Context *s = avctx->priv_data;
- uint8_t *buf_end, *buf_ptr, *buf_start;
- int len, start_code_found, ret, code, start_code, input_size;
+ uint8_t *buf_end, *buf_ptr;
+ int ret, start_code, input_size;
AVFrame *picture = data;
MpegEncContext *s2 = &s->mpeg_enc_ctx;
-
dprintf("fill_buffer\n");
*data_size = 0;
@@ -2192,6 +2224,13 @@ static int mpeg_decode_frame(AVCodecContext *avctx,
return 0;
}
+ if(s2->flags&CODEC_FLAG_TRUNCATED){
+ int next= mpeg1_find_frame_end(s2, buf, buf_size);
+
+ if( ff_combine_frame(s2, next, &buf, &buf_size) < 0 )
+ return buf_size;
+ }
+
buf_ptr = buf;
buf_end = buf + buf_size;
@@ -2206,60 +2245,42 @@ static int mpeg_decode_frame(AVCodecContext *avctx,
}
}
#endif
- while (buf_ptr < buf_end) {
- buf_start = buf_ptr;
+ for(;;) {
/* find start next code */
- code = find_start_code(&buf_ptr, buf_end, &s->header_state);
- if (code >= 0) {
- start_code_found = 1;
- } else {
- start_code_found = 0;
- }
- /* 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 (start_code_found)
- s->start_code = code;
- } else {
- memcpy(s->buf_ptr, buf_start, len);
- s->buf_ptr += len;
- if( (!(s2->flags&CODEC_FLAG_TRUNCATED)) && (!start_code_found)
- && s->buf_ptr+4<s->buffer+s->buffer_size){
- start_code_found= 1;
- code= 0x1FF;
- s->header_state=0xFF;
- s->buf_ptr[0]=0;
- s->buf_ptr[1]=0;
- s->buf_ptr[2]=1;
- s->buf_ptr[3]=0xFF;
- s->buf_ptr+=4;
+ start_code = find_start_code(&buf_ptr, buf_end);
+ if (start_code < 0){
+ if (slice_end(avctx, picture)) {
+ if(s2->last_picture_ptr) //FIXME merge with the stuff in mpeg_decode_slice
+ *data_size = sizeof(AVPicture);
}
- if (start_code_found) {
+ return FFMAX(0, buf_ptr - buf - s2->parse_context.last_index);
+ }
+
+ input_size = buf_end - buf_ptr;
+
+ if(avctx->debug & FF_DEBUG_STARTCODE){
+ printf("%3X at %d left %d\n", start_code, buf_ptr-buf, input_size);
+ }
+
/* 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;
switch(start_code) {
case SEQ_START_CODE:
- mpeg1_decode_sequence(avctx, s->buffer,
+ mpeg1_decode_sequence(avctx, buf_ptr,
input_size);
break;
case PICTURE_START_CODE:
/* we have a complete image : we try to decompress it */
mpeg1_decode_picture(avctx,
- s->buffer, input_size);
+ buf_ptr, input_size);
break;
case EXT_START_CODE:
mpeg_decode_extension(avctx,
- s->buffer, input_size);
+ buf_ptr, input_size);
break;
case USER_START_CODE:
mpeg_decode_user_data(avctx,
- s->buffer, input_size);
+ buf_ptr, input_size);
break;
default:
if (start_code >= SLICE_MIN_START_CODE &&
@@ -2271,30 +2292,24 @@ static int mpeg_decode_frame(AVCodecContext *avctx,
if(avctx->hurry_up && s2->pict_type==B_TYPE) break;
/* skip everything if we are in a hurry>=5 */
if(avctx->hurry_up>=5) break;
-
+
if (!s->mpeg_enc_ctx_allocated) break;
ret = mpeg_decode_slice(avctx, picture,
- start_code, s->buffer, input_size);
+ start_code, &buf_ptr, input_size);
+ emms_c();
- if (ret == DECODE_SLICE_EOP) {
- *data_size = sizeof(AVPicture);
- goto the_end;
- }else if(ret < 0){
- if(ret == DECODE_SLICE_ERROR)
+ if(ret < 0){
+ if(s2->resync_mb_x>=0 && s2->resync_mb_y>=0)
ff_er_add_slice(s2, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x, s2->mb_y, AC_ERROR|DC_ERROR|MV_ERROR);
-
- fprintf(stderr,"Error while decoding slice\n");
- if(ret==DECODE_SLICE_FATAL_ERROR) return -1;
+ if(ret==DECODE_SLICE_FATAL_ERROR) return -1;
+ }else{
+ ff_er_add_slice(s2, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x-1, s2->mb_y, AC_END|DC_END|MV_END);
}
}
break;
}
- }
- }
}
- the_end:
- return buf_ptr - buf;
}
static int mpeg_decode_end(AVCodecContext *avctx)