Commit df92fb78 authored by michaelni's avatar michaelni

better/cleaner error resilience (done in a 2nd pass after decoding)

h263/mpeg4 out of order slice decoding


git-svn-id: file:///var/local/repositories/ffmpeg/trunk@1030 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent f771529f
...@@ -114,8 +114,9 @@ static int b_frames = 0; ...@@ -114,8 +114,9 @@ static int b_frames = 0;
static int use_hq = 0; static int use_hq = 0;
static int use_4mv = 0; static int use_4mv = 0;
static int do_deinterlace = 0; static int do_deinterlace = 0;
static int workaround_bugs = 0; static int workaround_bugs = FF_BUG_AUTODETECT;
static int error_resilience = 0; static int error_resilience = 2;
static int error_concealment = 3;
static int dct_algo = 0; static int dct_algo = 0;
static int idct_algo = 0; static int idct_algo = 0;
static int use_part = 0; static int use_part = 0;
...@@ -1462,6 +1463,12 @@ void opt_error_resilience(const char *arg) ...@@ -1462,6 +1463,12 @@ void opt_error_resilience(const char *arg)
error_resilience = atoi(arg); error_resilience = atoi(arg);
} }
void opt_error_concealment(const char *arg)
{
error_concealment = atoi(arg);
}
void opt_frame_rate(const char *arg) void opt_frame_rate(const char *arg)
{ {
frame_rate = (int)(strtod(arg, 0) * FRAME_RATE_BASE); frame_rate = (int)(strtod(arg, 0) * FRAME_RATE_BASE);
...@@ -1823,6 +1830,7 @@ void opt_input_file(const char *filename) ...@@ -1823,6 +1830,7 @@ void opt_input_file(const char *filename)
rfps = ic->streams[i]->r_frame_rate; rfps = ic->streams[i]->r_frame_rate;
enc->workaround_bugs = workaround_bugs; enc->workaround_bugs = workaround_bugs;
enc->error_resilience = error_resilience; enc->error_resilience = error_resilience;
enc->error_concealment = error_concealment;
enc->idct_algo= idct_algo; enc->idct_algo= idct_algo;
if (enc->frame_rate != rfps) { if (enc->frame_rate != rfps) {
fprintf(stderr,"\nSeems that stream %d comes from film source: %2.2f->%2.2f\n", fprintf(stderr,"\nSeems that stream %d comes from film source: %2.2f->%2.2f\n",
...@@ -2394,6 +2402,7 @@ const OptionDef options[] = { ...@@ -2394,6 +2402,7 @@ const OptionDef options[] = {
{ "dct_algo", HAS_ARG | OPT_EXPERT, {(void*)opt_dct_algo}, "set dct algo", "algo" }, { "dct_algo", HAS_ARG | OPT_EXPERT, {(void*)opt_dct_algo}, "set dct algo", "algo" },
{ "idct_algo", HAS_ARG | OPT_EXPERT, {(void*)opt_idct_algo}, "set idct algo", "algo" }, { "idct_algo", HAS_ARG | OPT_EXPERT, {(void*)opt_idct_algo}, "set idct algo", "algo" },
{ "er", HAS_ARG | OPT_EXPERT, {(void*)opt_error_resilience}, "set error resilience", "" }, { "er", HAS_ARG | OPT_EXPERT, {(void*)opt_error_resilience}, "set error resilience", "" },
{ "ec", HAS_ARG | OPT_EXPERT, {(void*)opt_error_resilience}, "set error concealment", "" },
{ "bf", HAS_ARG | OPT_EXPERT, {(void*)opt_b_frames}, "use 'frames' B frames (only MPEG-4)", "frames" }, { "bf", HAS_ARG | OPT_EXPERT, {(void*)opt_b_frames}, "use 'frames' B frames (only MPEG-4)", "frames" },
{ "hq", OPT_BOOL | OPT_EXPERT, {(void*)&use_hq}, "activate high quality settings" }, { "hq", OPT_BOOL | OPT_EXPERT, {(void*)&use_hq}, "activate high quality settings" },
{ "4mv", OPT_BOOL | OPT_EXPERT, {(void*)&use_4mv}, "use four motion vector by macroblock (only MPEG-4)" }, { "4mv", OPT_BOOL | OPT_EXPERT, {(void*)&use_4mv}, "use four motion vector by macroblock (only MPEG-4)" },
......
...@@ -15,7 +15,7 @@ OBJS= common.o utils.o mem.o allcodecs.o \ ...@@ -15,7 +15,7 @@ OBJS= common.o utils.o mem.o allcodecs.o \
mpegaudio.o ac3enc.o mjpeg.o resample.o dsputil.o \ mpegaudio.o ac3enc.o mjpeg.o resample.o dsputil.o \
motion_est.o imgconvert.o imgresample.o msmpeg4.o \ motion_est.o imgconvert.o imgresample.o msmpeg4.o \
mpeg12.o h263dec.o svq1.o rv10.o mpegaudiodec.o pcm.o simple_idct.o \ mpeg12.o h263dec.o svq1.o rv10.o mpegaudiodec.o pcm.o simple_idct.o \
ratecontrol.o adpcm.o eval.o dv.o ratecontrol.o adpcm.o eval.o dv.o error_resilience.o
ASM_OBJS= ASM_OBJS=
# currently using liba52 for ac3 decoding # currently using liba52 for ac3 decoding
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
#define LIBAVCODEC_VERSION_INT 0x000406 #define LIBAVCODEC_VERSION_INT 0x000406
#define LIBAVCODEC_VERSION "0.4.6" #define LIBAVCODEC_VERSION "0.4.6"
#define LIBAVCODEC_BUILD 4630 #define LIBAVCODEC_BUILD 4631
#define LIBAVCODEC_BUILD_STR "4630" #define LIBAVCODEC_BUILD_STR "4631"
enum CodecID { enum CodecID {
CODEC_ID_NONE, CODEC_ID_NONE,
...@@ -414,11 +414,18 @@ typedef struct AVCodecContext { ...@@ -414,11 +414,18 @@ typedef struct AVCodecContext {
unsigned int codec_tag; /* codec tag, only used if unknown codec */ unsigned int codec_tag; /* codec tag, only used if unknown codec */
/** /**
* workaround bugs in encoders which cannot be detected automatically * workaround bugs in encoders which sometimes cannot be detected automatically
* encoding: unused * encoding: unused
* decoding: set by user * decoding: set by user
*/ */
int workaround_bugs; int workaround_bugs;
#define FF_BUG_AUTODETECT 1 //autodetection
#define FF_BUG_OLD_MSMPEG4 2
#define FF_BUG_XVID_ILACE 4
#define FF_BUG_UMP4 8
#define FF_BUG_NO_PADDING 16
#define FF_BUG_AC_VLC 32
//#define FF_BUG_FAKE_SCALABILITY 16 //autodetection should work 100%
/** /**
* encoding: set by user * encoding: set by user
...@@ -715,6 +722,15 @@ typedef struct AVCodecContext { ...@@ -715,6 +722,15 @@ typedef struct AVCodecContext {
*/ */
int *slice_offset; int *slice_offset;
/**
* error concealment flags
* encoding: unused
* decoding: set by user
*/
int error_concealment;
#define FF_EC_GUESS_MVS 1
#define FF_EC_DEBLOCK 2
//FIXME this should be reordered after kabis API is finished ... //FIXME this should be reordered after kabis API is finished ...
//TODO kill kabi //TODO kill kabi
/* /*
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -166,4 +166,6 @@ UINT8 ff_mpeg4_c_dc_scale_table[32]={ ...@@ -166,4 +166,6 @@ UINT8 ff_mpeg4_c_dc_scale_table[32]={
0, 8, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,20,21,22,23,24,25 0, 8, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,20,21,22,23,24,25
}; };
const UINT16 ff_mpeg4_resync_prefix[8]={
0x7F00, 0x7E00, 0x7C00, 0x7800, 0x7000, 0x6000, 0x4000, 0x0000
};
This diff is collapsed.
...@@ -322,16 +322,20 @@ typedef struct MpegEncContext { ...@@ -322,16 +322,20 @@ typedef struct MpegEncContext {
int last_bits; //temp var used for calculating the above vars int last_bits; //temp var used for calculating the above vars
/* error concealment / resync */ /* error concealment / resync */
UINT8 *error_status_table; /* table of the error status of each MB */
#define VP_START 1 /* current MB is the first after a resync marker */
#define AC_ERROR 2
#define DC_ERROR 4
#define MV_ERROR 8
#define AC_END 16
#define DC_END 32
#define MV_END 64
//FIXME some prefix?
int resync_mb_x; /* x position of last resync marker */ int resync_mb_x; /* x position of last resync marker */
int resync_mb_y; /* y position of last resync marker */ int resync_mb_y; /* y position of last resync marker */
int mb_num_left; /* number of MBs left in this video packet */ GetBitContext last_resync_gb; /* used to serach for the next resync marker */
GetBitContext next_resync_gb; /* starts at the next resync marker */ int mb_num_left; /* number of MBs left in this video packet (for partitioned Slices only)*/
int next_resync_qscale; /* qscale of next resync marker */
int next_resync_pos; /* bitstream position of next resync marker */
#define DECODING_AC_LOST -1
#define DECODING_ACDC_LOST -2
#define DECODING_DESYNC -3
int decoding_error;
int next_p_frame_damaged; /* set if the next p frame is damaged, to avoid showing trashed b frames */ int next_p_frame_damaged; /* set if the next p frame is damaged, to avoid showing trashed b frames */
int error_resilience; int error_resilience;
...@@ -381,7 +385,8 @@ typedef struct MpegEncContext { ...@@ -381,7 +385,8 @@ typedef struct MpegEncContext {
int aspected_height; int aspected_height;
int sprite_warping_accuracy; int sprite_warping_accuracy;
int low_latency_sprite; int low_latency_sprite;
int data_partitioning; int data_partitioning; /* data partitioning flag from header */
int partitioned_frame; /* is current frame partitioned */
int rvlc; /* reversible vlc */ int rvlc; /* reversible vlc */
int resync_marker; /* could this stream contain resync markers*/ int resync_marker; /* could this stream contain resync markers*/
int low_delay; /* no reordering needed / has no b-frames */ int low_delay; /* no reordering needed / has no b-frames */
...@@ -407,6 +412,10 @@ typedef struct MpegEncContext { ...@@ -407,6 +412,10 @@ typedef struct MpegEncContext {
UINT8 *bitstream_buffer; //Divx 5.01 puts several frames in a single one, this is used to reorder them UINT8 *bitstream_buffer; //Divx 5.01 puts several frames in a single one, this is used to reorder them
int bitstream_buffer_size; int bitstream_buffer_size;
/* lavc specific stuff, used to workaround bugs in libavcodec */
int ffmpeg_version;
int lavc_build;
/* RV10 specific */ /* RV10 specific */
int rv10_version; /* RV10 version: 0 or 3 */ int rv10_version; /* RV10 version: 0 or 3 */
int rv10_first_dc_coded[3]; int rv10_first_dc_coded[3];
...@@ -475,6 +484,12 @@ typedef struct MpegEncContext { ...@@ -475,6 +484,12 @@ typedef struct MpegEncContext {
DCTELEM (*block)[64]; /* points to one of the following blocks */ DCTELEM (*block)[64]; /* points to one of the following blocks */
DCTELEM blocks[2][6][64] __align8; // for HQ mode we need to keep the best block DCTELEM blocks[2][6][64] __align8; // for HQ mode we need to keep the best block
int (*decode_mb)(struct MpegEncContext *s, DCTELEM block[6][64]); // used by some codecs to avoid a switch()
#define SLICE_OK 0
#define SLICE_ERROR -1
#define SLICE_END -2 //end marker found
#define SLICE_NOEND -3 //no end marker or error found but mb count exceeded
void (*dct_unquantize_mpeg1)(struct MpegEncContext *s, void (*dct_unquantize_mpeg1)(struct MpegEncContext *s,
DCTELEM *block, int n, int qscale); DCTELEM *block, int n, int qscale);
void (*dct_unquantize_mpeg2)(struct MpegEncContext *s, void (*dct_unquantize_mpeg2)(struct MpegEncContext *s,
...@@ -489,6 +504,7 @@ typedef struct MpegEncContext { ...@@ -489,6 +504,7 @@ typedef struct MpegEncContext {
void (*idct_add)(UINT8 *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); void (*idct_add)(UINT8 *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/);
} MpegEncContext; } MpegEncContext;
int DCT_common_init(MpegEncContext *s); int DCT_common_init(MpegEncContext *s);
int MPV_common_init(MpegEncContext *s); int MPV_common_init(MpegEncContext *s);
void MPV_common_end(MpegEncContext *s); void MPV_common_end(MpegEncContext *s);
...@@ -512,9 +528,30 @@ void ff_conceal_past_errors(MpegEncContext *s, int conceal_all); ...@@ -512,9 +528,30 @@ void ff_conceal_past_errors(MpegEncContext *s, int conceal_all);
void ff_copy_bits(PutBitContext *pb, UINT8 *src, int length); void ff_copy_bits(PutBitContext *pb, UINT8 *src, int length);
void ff_clean_intra_table_entries(MpegEncContext *s); void ff_clean_intra_table_entries(MpegEncContext *s);
void ff_init_scantable(MpegEncContext *s, ScanTable *st, const UINT8 *src_scantable); void ff_init_scantable(MpegEncContext *s, ScanTable *st, const UINT8 *src_scantable);
void ff_error_resilience(MpegEncContext *s);
void ff_draw_horiz_band(MpegEncContext *s);
extern int ff_bit_exact; extern int ff_bit_exact;
static inline void ff_init_block_index(MpegEncContext *s){
s->block_index[0]= s->block_wrap[0]*(s->mb_y*2 + 1) - 1 + s->mb_x*2;
s->block_index[1]= s->block_wrap[0]*(s->mb_y*2 + 1) + s->mb_x*2;
s->block_index[2]= s->block_wrap[0]*(s->mb_y*2 + 2) - 1 + s->mb_x*2;
s->block_index[3]= s->block_wrap[0]*(s->mb_y*2 + 2) + s->mb_x*2;
s->block_index[4]= s->block_wrap[4]*(s->mb_y + 1) + s->block_wrap[0]*(s->mb_height*2 + 2) + s->mb_x;
s->block_index[5]= s->block_wrap[4]*(s->mb_y + 1 + s->mb_height + 2) + s->block_wrap[0]*(s->mb_height*2 + 2) + s->mb_x;
}
static inline void ff_update_block_index(MpegEncContext *s){
s->block_index[0]+=2;
s->block_index[1]+=2;
s->block_index[2]+=2;
s->block_index[3]+=2;
s->block_index[4]++;
s->block_index[5]++;
}
/* motion_est.c */ /* motion_est.c */
void ff_estimate_p_frame_motion(MpegEncContext * s, void ff_estimate_p_frame_motion(MpegEncContext * s,
int mb_x, int mb_y); int mb_x, int mb_y);
...@@ -524,6 +561,7 @@ int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type); ...@@ -524,6 +561,7 @@ int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type);
void ff_fix_long_p_mvs(MpegEncContext * s); void ff_fix_long_p_mvs(MpegEncContext * s);
void ff_fix_long_b_mvs(MpegEncContext * s, int16_t (*mv_table)[2], int f_code, int type); void ff_fix_long_b_mvs(MpegEncContext * s, int16_t (*mv_table)[2], int f_code, int type);
/* mpeg12.c */ /* mpeg12.c */
extern const INT16 ff_mpeg1_default_intra_matrix[64]; extern const INT16 ff_mpeg1_default_intra_matrix[64];
extern const INT16 ff_mpeg1_default_non_intra_matrix[64]; extern const INT16 ff_mpeg1_default_non_intra_matrix[64];
...@@ -535,6 +573,7 @@ void mpeg1_encode_mb(MpegEncContext *s, ...@@ -535,6 +573,7 @@ void mpeg1_encode_mb(MpegEncContext *s,
int motion_x, int motion_y); int motion_x, int motion_y);
void ff_mpeg1_encode_init(MpegEncContext *s); void ff_mpeg1_encode_init(MpegEncContext *s);
/* h263enc.c */ /* h263enc.c */
typedef struct RLTable { typedef struct RLTable {
int n; /* number of entries of table_vlc minus 1 */ int n; /* number of entries of table_vlc minus 1 */
...@@ -567,7 +606,6 @@ extern UINT8 ff_mpeg4_y_dc_scale_table[32]; ...@@ -567,7 +606,6 @@ extern UINT8 ff_mpeg4_y_dc_scale_table[32];
extern UINT8 ff_mpeg4_c_dc_scale_table[32]; extern UINT8 ff_mpeg4_c_dc_scale_table[32];
extern const INT16 ff_mpeg4_default_intra_matrix[64]; extern const INT16 ff_mpeg4_default_intra_matrix[64];
extern const INT16 ff_mpeg4_default_non_intra_matrix[64]; extern const INT16 ff_mpeg4_default_non_intra_matrix[64];
void h263_encode_mb(MpegEncContext *s, void h263_encode_mb(MpegEncContext *s,
DCTELEM block[6][64], DCTELEM block[6][64],
int motion_x, int motion_y); int motion_x, int motion_y);
...@@ -583,30 +621,32 @@ void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n, ...@@ -583,30 +621,32 @@ void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n,
void ff_set_mpeg4_time(MpegEncContext * s, int picture_number); void ff_set_mpeg4_time(MpegEncContext * s, int picture_number);
void mpeg4_encode_picture_header(MpegEncContext *s, int picture_number); void mpeg4_encode_picture_header(MpegEncContext *s, int picture_number);
void h263_encode_init(MpegEncContext *s); void h263_encode_init(MpegEncContext *s);
void h263_decode_init_vlc(MpegEncContext *s); void h263_decode_init_vlc(MpegEncContext *s);
int h263_decode_picture_header(MpegEncContext *s); int h263_decode_picture_header(MpegEncContext *s);
int h263_decode_gob_header(MpegEncContext *s); int ff_h263_decode_gob_header(MpegEncContext *s);
int mpeg4_decode_picture_header(MpegEncContext * s); int mpeg4_decode_picture_header(MpegEncContext * s);
int intel_h263_decode_picture_header(MpegEncContext *s); int intel_h263_decode_picture_header(MpegEncContext *s);
int h263_decode_mb(MpegEncContext *s, int ff_h263_decode_mb(MpegEncContext *s,
DCTELEM block[6][64]); DCTELEM block[6][64]);
int h263_get_picture_format(int width, int height); int h263_get_picture_format(int width, int height);
int ff_mpeg4_decode_video_packet_header(MpegEncContext *s);
int ff_mpeg4_resync(MpegEncContext *s);
void ff_mpeg4_encode_video_packet_header(MpegEncContext *s); void ff_mpeg4_encode_video_packet_header(MpegEncContext *s);
void ff_mpeg4_clean_buffers(MpegEncContext *s); void ff_mpeg4_clean_buffers(MpegEncContext *s);
void ff_mpeg4_stuffing(PutBitContext * pbc); void ff_mpeg4_stuffing(PutBitContext * pbc);
void ff_mpeg4_init_partitions(MpegEncContext *s); void ff_mpeg4_init_partitions(MpegEncContext *s);
void ff_mpeg4_merge_partitions(MpegEncContext *s); void ff_mpeg4_merge_partitions(MpegEncContext *s);
extern inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, UINT16 **dc_val_ptr, int *dir_ptr);
void ff_clean_mpeg4_qscales(MpegEncContext *s); void ff_clean_mpeg4_qscales(MpegEncContext *s);
void ff_clean_h263_qscales(MpegEncContext *s); void ff_clean_h263_qscales(MpegEncContext *s);
int ff_mpeg4_decode_partitions(MpegEncContext *s);
int ff_mpeg4_get_video_packet_prefix_length(MpegEncContext *s);
int ff_h263_resync(MpegEncContext *s);
int ff_h263_get_gob_height(MpegEncContext *s);
/* rv10.c */ /* rv10.c */
void rv10_encode_picture_header(MpegEncContext *s, int picture_number); void rv10_encode_picture_header(MpegEncContext *s, int picture_number);
int rv_decode_dc(MpegEncContext *s, int n); int rv_decode_dc(MpegEncContext *s, int n);
/* msmpeg4.c */ /* msmpeg4.c */
void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number); void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number);
void msmpeg4_encode_ext_header(MpegEncContext * s); void msmpeg4_encode_ext_header(MpegEncContext * s);
...@@ -615,13 +655,11 @@ void msmpeg4_encode_mb(MpegEncContext * s, ...@@ -615,13 +655,11 @@ void msmpeg4_encode_mb(MpegEncContext * s,
int motion_x, int motion_y); int motion_x, int motion_y);
int msmpeg4_decode_picture_header(MpegEncContext * s); int msmpeg4_decode_picture_header(MpegEncContext * s);
int msmpeg4_decode_ext_header(MpegEncContext * s, int buf_size); int msmpeg4_decode_ext_header(MpegEncContext * s, int buf_size);
int msmpeg4_decode_mb(MpegEncContext *s,
DCTELEM block[6][64]);
int ff_msmpeg4_decode_init(MpegEncContext *s); int ff_msmpeg4_decode_init(MpegEncContext *s);
void ff_msmpeg4_encode_init(MpegEncContext *s); void ff_msmpeg4_encode_init(MpegEncContext *s);
/* mjpegenc.c */
/* mjpegenc.c */
int mjpeg_init(MpegEncContext *s); int mjpeg_init(MpegEncContext *s);
void mjpeg_close(MpegEncContext *s); void mjpeg_close(MpegEncContext *s);
void mjpeg_encode_mb(MpegEncContext *s, void mjpeg_encode_mb(MpegEncContext *s,
...@@ -629,6 +667,7 @@ void mjpeg_encode_mb(MpegEncContext *s, ...@@ -629,6 +667,7 @@ void mjpeg_encode_mb(MpegEncContext *s,
void mjpeg_picture_header(MpegEncContext *s); void mjpeg_picture_header(MpegEncContext *s);
void mjpeg_picture_trailer(MpegEncContext *s); void mjpeg_picture_trailer(MpegEncContext *s);
/* rate control */ /* rate control */
int ff_rate_control_init(MpegEncContext *s); int ff_rate_control_init(MpegEncContext *s);
float ff_rate_estimate_qscale(MpegEncContext *s); float ff_rate_estimate_qscale(MpegEncContext *s);
......
...@@ -61,7 +61,8 @@ static void msmpeg4v2_encode_motion(MpegEncContext * s, int val); ...@@ -61,7 +61,8 @@ static void msmpeg4v2_encode_motion(MpegEncContext * s, int val);
static void init_h263_dc_for_msmpeg4(void); static void init_h263_dc_for_msmpeg4(void);
static inline void msmpeg4_memsetw(short *tab, int val, int n); static inline void msmpeg4_memsetw(short *tab, int val, int n);
static int get_size_of_code(MpegEncContext * s, RLTable *rl, int last, int run, int level, int intra); static int get_size_of_code(MpegEncContext * s, RLTable *rl, int last, int run, int level, int intra);
static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64]);
static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64]);
extern UINT32 inverse[256]; extern UINT32 inverse[256];
...@@ -504,26 +505,7 @@ static inline void handle_slices(MpegEncContext *s){ ...@@ -504,26 +505,7 @@ static inline void handle_slices(MpegEncContext *s){
if (s->mb_x == 0) { if (s->mb_x == 0) {
if (s->slice_height && (s->mb_y % s->slice_height) == 0) { if (s->slice_height && (s->mb_y % s->slice_height) == 0) {
if(s->msmpeg4_version != 4){ if(s->msmpeg4_version != 4){
int wrap; ff_mpeg4_clean_buffers(s);
/* reset DC pred (set previous line to 1024) */
wrap = 2 * s->mb_width + 2;
msmpeg4_memsetw(&s->dc_val[0][(1) + (2 * s->mb_y) * wrap],
1024, 2 * s->mb_width);
wrap = s->mb_width + 2;
msmpeg4_memsetw(&s->dc_val[1][(1) + (s->mb_y) * wrap],
1024, s->mb_width);
msmpeg4_memsetw(&s->dc_val[2][(1) + (s->mb_y) * wrap],
1024, s->mb_width);
/* reset AC pred (set previous line to 0) */
wrap = s->mb_width * 2 + 2;
msmpeg4_memsetw(s->ac_val[0][0] + (1 + (2 * s->mb_y) * wrap)*16,
0, 2 * s->mb_width*16);
wrap = s->mb_width + 2;
msmpeg4_memsetw(s->ac_val[1][0] + (1 + (s->mb_y) * wrap)*16,
0, s->mb_width*16);
msmpeg4_memsetw(s->ac_val[2][0] + (1 + (s->mb_y) * wrap)*16,
0, s->mb_width*16);
} }
s->first_slice_line = 1; s->first_slice_line = 1;
} else { } else {
...@@ -711,6 +693,10 @@ static inline int msmpeg4_pred_dc(MpegEncContext * s, int n, ...@@ -711,6 +693,10 @@ static inline int msmpeg4_pred_dc(MpegEncContext * s, int n,
b = dc_val[ - 1 - wrap]; b = dc_val[ - 1 - wrap];
c = dc_val[ - wrap]; c = dc_val[ - wrap];
if(s->first_slice_line && (n&2)==0){
b=c=1024;
}
/* XXX: the following solution consumes divisions, but it does not /* XXX: the following solution consumes divisions, but it does not
necessitate to modify mpegvideo.c. The problem comes from the necessitate to modify mpegvideo.c. The problem comes from the
fact they decided to store the quantized DC (which would lead fact they decided to store the quantized DC (which would lead
...@@ -941,6 +927,7 @@ static inline void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int ...@@ -941,6 +927,7 @@ static inline void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int
for(last_index=63; last_index>=0; last_index--){ for(last_index=63; last_index>=0; last_index--){
if(block[scantable[last_index]]) break; if(block[scantable[last_index]]) break;
} }
s->block_last_index[n]= last_index;
}else }else
last_index = s->block_last_index[n]; last_index = s->block_last_index[n];
/* AC coefs */ /* AC coefs */
...@@ -1170,6 +1157,18 @@ int ff_msmpeg4_decode_init(MpegEncContext *s) ...@@ -1170,6 +1157,18 @@ int ff_msmpeg4_decode_init(MpegEncContext *s)
&table_inter_intra[0][1], 2, 1, &table_inter_intra[0][1], 2, 1,
&table_inter_intra[0][0], 2, 1); &table_inter_intra[0][0], 2, 1);
} }
switch(s->msmpeg4_version){
case 1:
case 2:
s->decode_mb= msmpeg4v12_decode_mb;
break;
case 3:
case 4:
s->decode_mb= msmpeg4v34_decode_mb;
break;
}
return 0; return 0;
} }
...@@ -1444,11 +1443,12 @@ static int msmpeg4v2_decode_motion(MpegEncContext * s, int pred, int f_code) ...@@ -1444,11 +1443,12 @@ static int msmpeg4v2_decode_motion(MpegEncContext * s, int pred, int f_code)
return val; return val;
} }
static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
static int msmpeg4v12_decode_mb(MpegEncContext *s,
DCTELEM block[6][64])
{ {
int cbp, code, i; int cbp, code, i;
s->error_status_table[s->mb_x + s->mb_y*s->mb_width]= 0;
if (s->pict_type == P_TYPE) { if (s->pict_type == P_TYPE) {
if (s->use_skip_mb_code) { if (s->use_skip_mb_code) {
if (get_bits1(&s->gb)) { if (get_bits1(&s->gb)) {
...@@ -1530,8 +1530,7 @@ static int msmpeg4v12_decode_mb(MpegEncContext *s, ...@@ -1530,8 +1530,7 @@ static int msmpeg4v12_decode_mb(MpegEncContext *s,
return 0; return 0;
} }
int msmpeg4_decode_mb(MpegEncContext *s, static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
DCTELEM block[6][64])
{ {
int cbp, code, i; int cbp, code, i;
UINT8 *coded_val; UINT8 *coded_val;
...@@ -1542,10 +1541,8 @@ if(s->mb_x==0){ ...@@ -1542,10 +1541,8 @@ if(s->mb_x==0){
if(s->mb_y==0) printf("\n"); if(s->mb_y==0) printf("\n");
} }
#endif #endif
/* special slice handling */
handle_slices(s);
if(s->msmpeg4_version<=2) return msmpeg4v12_decode_mb(s, block); //FIXME export function & call from outside perhaps s->error_status_table[s->mb_x + s->mb_y*s->mb_width]= 0;
if (s->pict_type == P_TYPE) { if (s->pict_type == P_TYPE) {
set_stat(ST_INTER_MB); set_stat(ST_INTER_MB);
...@@ -1866,7 +1863,7 @@ static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, ...@@ -1866,7 +1863,7 @@ static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
i-= 192; i-= 192;
if(i&(~63)){ if(i&(~63)){
const int left= s->gb.size*8 - get_bits_count(&s->gb); const int left= s->gb.size*8 - get_bits_count(&s->gb);
if(((i+192 == 64 && level/qmul==-1) || s->error_resilience<0) && left>=0){ if(((i+192 == 64 && level/qmul==-1) || s->error_resilience<=1) && left>=0){
fprintf(stderr, "ignoring overflow at %d %d\n", s->mb_x, s->mb_y); fprintf(stderr, "ignoring overflow at %d %d\n", s->mb_x, s->mb_y);
break; break;
}else{ }else{
......
...@@ -365,6 +365,7 @@ static int rv10_decode_init(AVCodecContext *avctx) ...@@ -365,6 +365,7 @@ static int rv10_decode_init(AVCodecContext *avctx)
s->y_dc_scale_table= s->y_dc_scale_table=
s->c_dc_scale_table= ff_mpeg1_dc_scale_table; s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
s->progressive_sequence=1;
/* init rv vlc */ /* init rv vlc */
if (!done) { if (!done) {
...@@ -393,7 +394,6 @@ static int rv10_decode_packet(AVCodecContext *avctx, ...@@ -393,7 +394,6 @@ static int rv10_decode_packet(AVCodecContext *avctx,
{ {
MpegEncContext *s = avctx->priv_data; MpegEncContext *s = avctx->priv_data;
int i, mb_count, mb_pos, left; int i, mb_count, mb_pos, left;
DCTELEM block[6][64];
init_get_bits(&s->gb, buf, buf_size); init_get_bits(&s->gb, buf, buf_size);
...@@ -430,47 +430,35 @@ static int rv10_decode_packet(AVCodecContext *avctx, ...@@ -430,47 +430,35 @@ static int rv10_decode_packet(AVCodecContext *avctx,
s->rv10_first_dc_coded[1] = 0; s->rv10_first_dc_coded[1] = 0;
s->rv10_first_dc_coded[2] = 0; s->rv10_first_dc_coded[2] = 0;
if(s->mb_y==0) s->first_slice_line=1;
s->block_wrap[0]= s->block_wrap[0]=
s->block_wrap[1]= s->block_wrap[1]=
s->block_wrap[2]= s->block_wrap[2]=
s->block_wrap[3]= s->mb_width*2 + 2; s->block_wrap[3]= s->mb_width*2 + 2;
s->block_wrap[4]= s->block_wrap[4]=
s->block_wrap[5]= s->mb_width + 2; s->block_wrap[5]= s->mb_width + 2;
s->block_index[0]= s->block_wrap[0]*(s->mb_y*2 + 1) - 1 + s->mb_x*2; ff_init_block_index(s);
s->block_index[1]= s->block_wrap[0]*(s->mb_y*2 + 1) + s->mb_x*2;
s->block_index[2]= s->block_wrap[0]*(s->mb_y*2 + 2) - 1 + s->mb_x*2;
s->block_index[3]= s->block_wrap[0]*(s->mb_y*2 + 2) + s->mb_x*2;
s->block_index[4]= s->block_wrap[4]*(s->mb_y + 1) + s->block_wrap[0]*(s->mb_height*2 + 2) + s->mb_x;
s->block_index[5]= s->block_wrap[4]*(s->mb_y + 1 + s->mb_height + 2) + s->block_wrap[0]*(s->mb_height*2 + 2) + s->mb_x;
/* decode each macroblock */ /* decode each macroblock */
for(i=0;i<mb_count;i++) { for(i=0;i<mb_count;i++) {
s->block_index[0]+=2; ff_update_block_index(s);
s->block_index[1]+=2;
s->block_index[2]+=2;
s->block_index[3]+=2;
s->block_index[4]++;
s->block_index[5]++;
#ifdef DEBUG #ifdef DEBUG
printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y); printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y);
#endif #endif
memset(block, 0, sizeof(block)); clear_blocks(s->block[0]);
s->mv_dir = MV_DIR_FORWARD; s->mv_dir = MV_DIR_FORWARD;
s->mv_type = MV_TYPE_16X16; s->mv_type = MV_TYPE_16X16;
if (h263_decode_mb(s, block) < 0) { if (ff_h263_decode_mb(s, s->block) == SLICE_ERROR) {
fprintf(stderr, "ERROR at MB %d %d\n", s->mb_x, s->mb_y); fprintf(stderr, "ERROR at MB %d %d\n", s->mb_x, s->mb_y);
return -1; return -1;
} }
MPV_decode_mb(s, block); MPV_decode_mb(s, s->block);
if (++s->mb_x == s->mb_width) { if (++s->mb_x == s->mb_width) {
s->mb_x = 0; s->mb_x = 0;
s->mb_y++; s->mb_y++;
s->block_index[0]= s->block_wrap[0]*(s->mb_y*2 + 1) - 1; ff_init_block_index(s);
s->block_index[1]= s->block_wrap[0]*(s->mb_y*2 + 1); s->first_slice_line=0;
s->block_index[2]= s->block_wrap[0]*(s->mb_y*2 + 2) - 1;
s->block_index[3]= s->block_wrap[0]*(s->mb_y*2 + 2);
s->block_index[4]= s->block_wrap[4]*(s->mb_y + 1) + s->block_wrap[0]*(s->mb_height*2 + 2);
s->block_index[5]= s->block_wrap[4]*(s->mb_y + 1 + s->mb_height + 2) + s->block_wrap[0]*(s->mb_height*2 + 2);
} }
} }
......
...@@ -61,6 +61,8 @@ void avcodec_get_context_defaults(AVCodecContext *s){ ...@@ -61,6 +61,8 @@ void avcodec_get_context_defaults(AVCodecContext *s){
s->b_quant_offset=1.25; s->b_quant_offset=1.25;
s->i_quant_factor=-0.8; s->i_quant_factor=-0.8;
s->i_quant_offset=0.0; s->i_quant_offset=0.0;
s->error_concealment= 3;
s->workaround_bugs= FF_BUG_AUTODETECT;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment