summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libffmpeg/libavcodec/4xm.c2
-rw-r--r--src/libffmpeg/libavcodec/Makefile.am3
-rw-r--r--src/libffmpeg/libavcodec/asv1.c2
-rw-r--r--src/libffmpeg/libavcodec/avcodec.h15
-rw-r--r--src/libffmpeg/libavcodec/cinepak.c38
-rw-r--r--src/libffmpeg/libavcodec/common.h4
-rw-r--r--src/libffmpeg/libavcodec/cyuv.c3
-rw-r--r--src/libffmpeg/libavcodec/dsputil.c25
-rw-r--r--src/libffmpeg/libavcodec/dsputil.h49
-rw-r--r--src/libffmpeg/libavcodec/dv.c10
-rw-r--r--src/libffmpeg/libavcodec/h263.c122
-rw-r--r--src/libffmpeg/libavcodec/h263dec.c66
-rw-r--r--src/libffmpeg/libavcodec/h264.c36
-rw-r--r--src/libffmpeg/libavcodec/huffyuv.c2
-rw-r--r--src/libffmpeg/libavcodec/i386/dsputil_mmx.c28
-rw-r--r--src/libffmpeg/libavcodec/i386/fdct_mmx.c273
-rw-r--r--src/libffmpeg/libavcodec/i386/vp3dsp_mmx.c80
-rw-r--r--src/libffmpeg/libavcodec/i386/vp3dsp_sse2.c60
-rw-r--r--src/libffmpeg/libavcodec/integer.c195
-rw-r--r--src/libffmpeg/libavcodec/integer.h47
-rw-r--r--src/libffmpeg/libavcodec/mdec.c2
-rw-r--r--src/libffmpeg/libavcodec/mjpeg.c3
-rw-r--r--src/libffmpeg/libavcodec/motion_est.c10
-rw-r--r--src/libffmpeg/libavcodec/mpeg12.c48
-rw-r--r--src/libffmpeg/libavcodec/mpeg12data.h56
-rw-r--r--src/libffmpeg/libavcodec/mpegvideo.c72
-rw-r--r--src/libffmpeg/libavcodec/mpegvideo.h3
-rw-r--r--src/libffmpeg/libavcodec/parser.c749
-rw-r--r--src/libffmpeg/libavcodec/ppc/dsputil_altivec.c69
-rw-r--r--src/libffmpeg/libavcodec/ppc/dsputil_ppc.c2
-rw-r--r--src/libffmpeg/libavcodec/svq1.c989
-rw-r--r--src/libffmpeg/libavcodec/svq1_cb.h68
-rw-r--r--src/libffmpeg/libavcodec/svq1_vlc.h2
-rw-r--r--src/libffmpeg/libavcodec/utils.c47
-rw-r--r--src/libffmpeg/libavcodec/vcr1.c9
-rw-r--r--src/libffmpeg/libavcodec/vp3.c13
-rw-r--r--src/libffmpeg/libavcodec/vp3dsp.c80
37 files changed, 2553 insertions, 729 deletions
diff --git a/src/libffmpeg/libavcodec/4xm.c b/src/libffmpeg/libavcodec/4xm.c
index 6544d88d0..50dc4a55b 100644
--- a/src/libffmpeg/libavcodec/4xm.c
+++ b/src/libffmpeg/libavcodec/4xm.c
@@ -738,8 +738,6 @@ static int decode_end(AVCodecContext *avctx){
}
free_vlc(&f->pre_vlc);
- avcodec_default_free_buffers(avctx);
-
return 0;
}
diff --git a/src/libffmpeg/libavcodec/Makefile.am b/src/libffmpeg/libavcodec/Makefile.am
index 7bbcbd281..8b3a7f634 100644
--- a/src/libffmpeg/libavcodec/Makefile.am
+++ b/src/libffmpeg/libavcodec/Makefile.am
@@ -36,6 +36,7 @@ libavcodec_la_SOURCES = \
idcinvideo.c \
imgconvert.c \
indeo3.c \
+ integer.c \
interplayvideo.c \
jfdctfst.c \
jfdctint.c \
@@ -53,6 +54,7 @@ libavcodec_la_SOURCES = \
msrle.c \
msvideo1.c \
opts.c \
+ parser.c \
pcm.c \
qtrle.c \
ra144.c \
@@ -96,6 +98,7 @@ noinst_HEADERS = \
golomb.h \
imgconvert_template.h \
indeo3data.h \
+ integer.h \
h263data.h \
h264data.h \
mangle.h \
diff --git a/src/libffmpeg/libavcodec/asv1.c b/src/libffmpeg/libavcodec/asv1.c
index 87b13c637..24916590f 100644
--- a/src/libffmpeg/libavcodec/asv1.c
+++ b/src/libffmpeg/libavcodec/asv1.c
@@ -613,8 +613,6 @@ static int decode_end(AVCodecContext *avctx){
av_freep(&a->picture.qscale_table);
a->bitstream_buffer_size=0;
- avcodec_default_free_buffers(avctx);
-
return 0;
}
diff --git a/src/libffmpeg/libavcodec/avcodec.h b/src/libffmpeg/libavcodec/avcodec.h
index 731bcd375..d071e0891 100644
--- a/src/libffmpeg/libavcodec/avcodec.h
+++ b/src/libffmpeg/libavcodec/avcodec.h
@@ -24,7 +24,7 @@ extern "C" {
#define FFMPEG_VERSION_INT 0x000408
#define FFMPEG_VERSION "0.4.8"
-#define LIBAVCODEC_BUILD 4710
+#define LIBAVCODEC_BUILD 4713
#define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT
#define LIBAVCODEC_VERSION FFMPEG_VERSION
@@ -848,6 +848,7 @@ typedef struct AVCodecContext {
#define FF_BUG_XVID_ILACE 4
#define FF_BUG_UMP4 8
#define FF_BUG_NO_PADDING 16
+#define FF_BUG_AMV 32
#define FF_BUG_AC_VLC 0 ///< will be removed, libavcodec can now handle these non compliant files by default
#define FF_BUG_QPEL_CHROMA 64
#define FF_BUG_STD_QPEL 128
@@ -855,6 +856,7 @@ typedef struct AVCodecContext {
#define FF_BUG_DIRECT_BLOCKSIZE 512
#define FF_BUG_EDGE 1024
#define FF_BUG_HPEL_CHROMA 2048
+#define FF_BUG_DC_CLIP 4096
//#define FF_BUG_FAKE_SCALABILITY 16 //autodetection should work 100%
/**
@@ -1591,6 +1593,13 @@ typedef struct AVCodecContext {
* - decoding: unused
*/
int mb_threshold;
+
+ /**
+ *
+ * - encoding: set by user
+ * - decoding: unused
+ */
+ int intra_dc_precision;
} AVCodecContext;
@@ -1717,6 +1726,7 @@ extern AVCodec vcr1_encoder;
extern AVCodec ffv1_encoder;
extern AVCodec mdec_encoder;
extern AVCodec zlib_encoder;
+extern AVCodec svq1_encoder;
extern AVCodec h263_decoder;
extern AVCodec mpeg4_decoder;
@@ -1934,7 +1944,6 @@ AVFrame *avcodec_alloc_frame(void);
int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic);
void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic);
-void avcodec_default_free_buffers(AVCodecContext *s);
int avcodec_thread_init(AVCodecContext *s, int thread_count);
void avcodec_thread_free(AVCodecContext *s);
@@ -1986,7 +1995,7 @@ int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max)
* rescale a 64bit integer.
* a simple a*b/c isnt possible as it can overflow
*/
-int64_t av_rescale(int64_t a, int b, int c);
+int64_t av_rescale(int64_t a, int64_t b, int64_t c);
/**
diff --git a/src/libffmpeg/libavcodec/cinepak.c b/src/libffmpeg/libavcodec/cinepak.c
index 412db7f7e..da9a8127f 100644
--- a/src/libffmpeg/libavcodec/cinepak.c
+++ b/src/libffmpeg/libavcodec/cinepak.c
@@ -57,7 +57,6 @@ typedef struct CinepakContext {
AVCodecContext *avctx;
DSPContext dsp;
AVFrame frame;
- AVFrame prev_frame;
unsigned char *data;
int size;
@@ -125,7 +124,7 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip_t *strip,
uint8_t *eod = (data + size);
uint32_t flag, mask;
cvid_codebook_t *codebook;
- unsigned int i, j, x, y;
+ unsigned int x, y;
uint32_t iy[4];
uint32_t iu[2];
uint32_t iv[2];
@@ -250,22 +249,6 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip_t *strip,
}
}
- } else {
- /* copy from the previous frame */
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- s->frame.data[0][iy[i] + j] =
- s->prev_frame.data[0][iy[i] + j];
- }
- }
- for (i = 0; i < 2; i++) {
- for (j = 0; j < 2; j++) {
- s->frame.data[1][iu[i] + j] =
- s->prev_frame.data[1][iu[i] + j];
- s->frame.data[2][iv[i] + j] =
- s->prev_frame.data[2][iv[i] + j];
- }
- }
}
iy[0] += 4; iy[1] += 4;
@@ -397,7 +380,7 @@ s->palette_video = 0;
avctx->has_b_frames = 0;
dsputil_init(&s->dsp, avctx);
- s->frame.data[0] = s->prev_frame.data[0] = NULL;
+ s->frame.data[0] = NULL;
return 0;
}
@@ -411,19 +394,16 @@ static int cinepak_decode_frame(AVCodecContext *avctx,
s->data = buf;
s->size = buf_size;
- if (avctx->get_buffer(avctx, &s->frame)) {
- av_log(avctx, AV_LOG_ERROR, " Cinepak: get_buffer() failed\n");
+ s->frame.reference = 1;
+ s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
+ FF_BUFFER_HINTS_REUSABLE;
+ if (avctx->reget_buffer(avctx, &s->frame)) {
+ av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
return -1;
}
cinepak_decode(s);
- if (s->prev_frame.data[0])
- avctx->release_buffer(avctx, &s->prev_frame);
-
- /* shuffle frames */
- s->prev_frame = s->frame;
-
*data_size = sizeof(AVFrame);
*(AVFrame*)data = s->frame;
@@ -435,8 +415,8 @@ static int cinepak_decode_end(AVCodecContext *avctx)
{
CinepakContext *s = (CinepakContext *)avctx->priv_data;
- if (s->prev_frame.data[0])
- avctx->release_buffer(avctx, &s->prev_frame);
+ if (s->frame.data[0])
+ avctx->release_buffer(avctx, &s->frame);
return 0;
}
diff --git a/src/libffmpeg/libavcodec/common.h b/src/libffmpeg/libavcodec/common.h
index de9382a13..b6fdcdd6e 100644
--- a/src/libffmpeg/libavcodec/common.h
+++ b/src/libffmpeg/libavcodec/common.h
@@ -81,17 +81,21 @@ extern const struct AVOption avoptions_workaround_bug[11];
# define restrict
#endif
+#ifndef always_inline
#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0)
# define always_inline __attribute__((always_inline)) inline
#else
# define always_inline inline
#endif
+#endif
+#ifndef attribute_used
#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0)
# define attribute_used __attribute__((used))
#else
# define attribute_used
#endif
+#endif
#ifndef EMULATE_INTTYPES
# include <inttypes.h>
diff --git a/src/libffmpeg/libavcodec/cyuv.c b/src/libffmpeg/libavcodec/cyuv.c
index 70b55066a..aee2bc5ec 100644
--- a/src/libffmpeg/libavcodec/cyuv.c
+++ b/src/libffmpeg/libavcodec/cyuv.c
@@ -100,6 +100,7 @@ static int cyuv_decode_frame(AVCodecContext *avctx,
if(s->frame.data[0])
avctx->release_buffer(avctx, &s->frame);
+ s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
s->frame.reference = 0;
if(avctx->get_buffer(avctx, &s->frame) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
@@ -180,7 +181,7 @@ AVCodec cyuv_decoder = {
NULL,
cyuv_decode_end,
cyuv_decode_frame,
- 0,
+ CODEC_CAP_DR1,
NULL
};
diff --git a/src/libffmpeg/libavcodec/dsputil.c b/src/libffmpeg/libavcodec/dsputil.c
index fce0b8163..b1252251a 100644
--- a/src/libffmpeg/libavcodec/dsputil.c
+++ b/src/libffmpeg/libavcodec/dsputil.c
@@ -332,6 +332,27 @@ static void put_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels,
}
}
+static void put_signed_pixels_clamped_c(const DCTELEM *block,
+ uint8_t *restrict pixels,
+ int line_size)
+{
+ int i, j;
+
+ for (i = 0; i < 8; i++) {
+ for (j = 0; j < 8; j++) {
+ if (*block < -128)
+ *pixels = 0;
+ else if (*block > 127)
+ *pixels = 255;
+ else
+ *pixels = (uint8_t)(*block + 128);
+ block++;
+ pixels++;
+ }
+ pixels += (line_size - 8);
+ }
+}
+
static void add_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels,
int line_size)
{
@@ -3126,12 +3147,12 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx)
/* VP3 DSP support */
c->vp3_dsp_init = vp3_dsp_init_c;
- c->vp3_idct_put = vp3_idct_put_c;
- c->vp3_idct_add = vp3_idct_add_c;
+ c->vp3_idct = vp3_idct_c;
c->get_pixels = get_pixels_c;
c->diff_pixels = diff_pixels_c;
c->put_pixels_clamped = put_pixels_clamped_c;
+ c->put_signed_pixels_clamped = put_signed_pixels_clamped_c;
c->add_pixels_clamped = add_pixels_clamped_c;
c->gmc1 = gmc1_c;
c->gmc = gmc_c;
diff --git a/src/libffmpeg/libavcodec/dsputil.h b/src/libffmpeg/libavcodec/dsputil.h
index 730e1489d..83c0c4b23 100644
--- a/src/libffmpeg/libavcodec/dsputil.h
+++ b/src/libffmpeg/libavcodec/dsputil.h
@@ -65,23 +65,16 @@ extern uint8_t cropTbl[256 + 2 * MAX_NEG_CROP];
/* VP3 DSP functions */
void vp3_dsp_init_c(void);
-void vp3_idct_put_c(int16_t *input_data, int16_t *dequant_matrix,
- int coeff_count, uint8_t *dest, int stride);
-void vp3_idct_add_c(int16_t *input_data, int16_t *dequant_matrix,
- int coeff_count, uint8_t *dest, int stride);
+void vp3_idct_c(int16_t *input_data, int16_t *dequant_matrix,
+ int coeff_count, DCTELEM *output_data);
void vp3_dsp_init_mmx(void);
-void vp3_idct_put_mmx(int16_t *input_data, int16_t *dequant_matrix,
- int coeff_count, uint8_t *dest, int stride);
-void vp3_idct_add_mmx(int16_t *input_data, int16_t *dequant_matrix,
- int coeff_count, uint8_t *dest, int stride);
+void vp3_idct_mmx(int16_t *input_data, int16_t *dequant_matrix,
+ int coeff_count, DCTELEM *output_data);
void vp3_dsp_init_sse2(void);
-void vp3_idct_put_sse2(int16_t *input_data, int16_t *dequant_matrix,
- int coeff_count, uint8_t *dest, int stride);
-void vp3_idct_add_sse2(int16_t *input_data, int16_t *dequant_matrix,
- int coeff_count, uint8_t *dest, int stride);
-
+void vp3_idct_sse2(int16_t *input_data, int16_t *dequant_matrix,
+ int coeff_count, DCTELEM *output_data);
/* minimum alignment rules ;)
if u notice errors in the align stuff, need more alignment for some asm code for some cpu
@@ -147,6 +140,7 @@ typedef struct DSPContext {
void (*get_pixels)(DCTELEM *block/*align 16*/, const uint8_t *pixels/*align 8*/, int line_size);
void (*diff_pixels)(DCTELEM *block/*align 16*/, const uint8_t *s1/*align 8*/, const uint8_t *s2/*align 8*/, int stride);
void (*put_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
+ void (*put_signed_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
void (*add_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
/**
* translational global motion compensation.
@@ -321,32 +315,16 @@ typedef struct DSPContext {
/**
* This function is responsible for taking a block of zigzag'd,
- * quantized DCT coefficients, reconstructing the original block of
- * samples, and placing it into the output.
- * @param input_data 64 zigzag'd, quantized DCT coefficients
- * @param dequant_matrix 64 zigzag'd quantizer coefficients
- * @param coeff_count index of the last coefficient
- * @param dest the final output location where the transformed samples
- * are to be placed
- * @param stride the width in 8-bit samples of a line on this plane
- */
- void (*vp3_idct_put)(int16_t *input_data, int16_t *dequant_matrix,
- int coeff_count, uint8_t *dest, int stride);
-
- /**
- * This function is responsible for taking a block of zigzag'd,
- * quantized DCT coefficients, reconstructing the original block of
- * samples, and adding the transformed samples to an existing block of
- * samples in the output.
+ * quantized DCT coefficients and reconstructing the original block of
+ * samples.
* @param input_data 64 zigzag'd, quantized DCT coefficients
* @param dequant_matrix 64 zigzag'd quantizer coefficients
* @param coeff_count index of the last coefficient
- * @param dest the final output location where the transformed samples
- * are to be placed
- * @param stride the width in 8-bit samples of a line on this plane
+ * @param output_samples space for 64 DCTELEMs where the transformed
+ * samples will be stored
*/
- void (*vp3_idct_add)(int16_t *input_data, int16_t *dequant_matrix,
- int coeff_count, uint8_t *dest, int stride);
+ void (*vp3_idct)(int16_t *input_data, int16_t *dequant_matrix,
+ int coeff_count, DCTELEM *output_samples);
} DSPContext;
@@ -400,6 +378,7 @@ extern int mm_flags;
void add_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size);
void put_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size);
+void put_signed_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size);
static inline void emms(void)
{
diff --git a/src/libffmpeg/libavcodec/dv.c b/src/libffmpeg/libavcodec/dv.c
index 5f1eaaa3b..c62c964fb 100644
--- a/src/libffmpeg/libavcodec/dv.c
+++ b/src/libffmpeg/libavcodec/dv.c
@@ -235,12 +235,6 @@ static int dvvideo_init(AVCodecContext *avctx)
return 0;
}
-static int dvvideo_end(AVCodecContext *avctx)
-{
- avcodec_default_free_buffers(avctx);
- return 0;
-}
-
// #define VLC_DEBUG
// #define printf(...) av_log(NULL, AV_LOG_ERROR, __VA_ARGS__)
@@ -954,7 +948,7 @@ AVCodec dvvideo_encoder = {
sizeof(DVVideoContext),
dvvideo_init,
dvvideo_encode_frame,
- dvvideo_end,
+ NULL,
NULL,
CODEC_CAP_DR1,
NULL
@@ -967,7 +961,7 @@ AVCodec dvvideo_decoder = {
sizeof(DVVideoContext),
dvvideo_init,
NULL,
- dvvideo_end,
+ NULL,
dvvideo_decode_frame,
CODEC_CAP_DR1,
NULL
diff --git a/src/libffmpeg/libavcodec/h263.c b/src/libffmpeg/libavcodec/h263.c
index ec776eb98..59d746272 100644
--- a/src/libffmpeg/libavcodec/h263.c
+++ b/src/libffmpeg/libavcodec/h263.c
@@ -76,7 +76,7 @@ static void mpeg4_encode_visual_object_header(MpegEncContext * s);
static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_number);
#endif //CONFIG_ENCODERS
static void mpeg4_decode_sprite_trajectory(MpegEncContext * s, GetBitContext *gb);
-static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, uint16_t **dc_val_ptr, int *dir_ptr);
+static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, int level, int *dir_ptr, int encoding);
#ifdef CONFIG_ENCODERS
static uint8_t uni_DCtab_lum_len[512];
@@ -496,6 +496,17 @@ void ff_clean_h263_qscales(MpegEncContext *s){
if(qscale_table[ s->mb_index2xy[i] ] - qscale_table[ s->mb_index2xy[i+1] ] >2)
qscale_table[ s->mb_index2xy[i] ]= qscale_table[ s->mb_index2xy[i+1] ]+2;
}
+
+ if(s->codec_id != CODEC_ID_H263P){
+ for(i=1; i<s->mb_num; i++){
+ int mb_xy= s->mb_index2xy[i];
+
+ if(qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i-1]] && (s->mb_type[mb_xy]&CANDIDATE_MB_TYPE_INTER4V)){
+ s->mb_type[mb_xy]&= ~CANDIDATE_MB_TYPE_INTER4V;
+ s->mb_type[mb_xy]|= CANDIDATE_MB_TYPE_INTER;
+ }
+ }
+ }
}
/**
@@ -507,15 +518,6 @@ void ff_clean_mpeg4_qscales(MpegEncContext *s){
ff_clean_h263_qscales(s);
- for(i=1; i<s->mb_num; i++){
- int mb_xy= s->mb_index2xy[i];
-
- if(qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i-1]] && (s->mb_type[mb_xy]&CANDIDATE_MB_TYPE_INTER4V)){
- s->mb_type[mb_xy]&= ~CANDIDATE_MB_TYPE_INTER4V;
- s->mb_type[mb_xy]|= CANDIDATE_MB_TYPE_INTER;
- }
- }
-
if(s->pict_type== B_TYPE){
int odd=0;
/* ok, come on, this isnt funny anymore, theres more code for handling this mpeg4 mess than
@@ -1071,15 +1073,7 @@ void mpeg4_encode_mb(MpegEncContext * s,
int i;
for(i=0; i<6; i++){
- const int level= block[i][0];
- uint16_t *dc_ptr;
-
- dc_diff[i]= level - ff_mpeg4_pred_dc(s, i, &dc_ptr, &dir[i]);
- if (i < 4) {
- *dc_ptr = level * s->y_dc_scale;
- } else {
- *dc_ptr = level * s->c_dc_scale;
- }
+ dc_diff[i]= ff_mpeg4_pred_dc(s, i, block[i][0], &dir[i], 1);
}
if(s->flags & CODEC_FLAG_AC_PRED){
@@ -2380,14 +2374,14 @@ void ff_set_qscale(MpegEncContext * s, int qscale)
/**
* predicts the dc.
+ * encoding quantized level -> quantized diff
+ * decoding quantized diff -> quantized level
* @param n block index (0-3 are luma, 4-5 are chroma)
- * @param dc_val_ptr a pointer to the dc_val entry for the current MB will be stored here
* @param dir_ptr pointer to an integer where the prediction direction will be stored
- * @return the quantized predicted dc
*/
-static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, uint16_t **dc_val_ptr, int *dir_ptr)
+static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, int level, int *dir_ptr, int encoding)
{
- int a, b, c, wrap, pred, scale;
+ int a, b, c, wrap, pred, scale, ret;
uint16_t *dc_val;
/* find prediction */
@@ -2429,10 +2423,32 @@ static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, uint16_t **dc_val_
/* we assume pred is positive */
pred = FASTDIV((pred + (scale >> 1)), scale);
- /* prepare address for prediction update */
- *dc_val_ptr = &dc_val[0];
+ if(encoding){
+ ret = level - pred;
+ }else{
+ level += pred;
+ ret= level;
+ if(s->error_resilience>=3){
+ if(level<0){
+ av_log(s->avctx, AV_LOG_ERROR, "dc<0 at %dx%d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ if(level*scale > 2048 + scale){
+ av_log(s->avctx, AV_LOG_ERROR, "dc overflow at %dx%d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ }
+ }
+ level *=scale;
+ if(level&(~2047)){
+ if(level<0)
+ level=0;
+ else if(!(s->workaround_bugs&FF_BUG_DC_CLIP))
+ level=2047;
+ }
+ dc_val[0]= level;
- return pred;
+ return ret;
}
/**
@@ -3219,6 +3235,9 @@ static inline int get_amv(MpegEncContext *s, int n){
int x, y, mb_v, sum, dx, dy, shift;
int len = 1 << (s->f_code + 4);
const int a= s->sprite_warping_accuracy;
+
+ if(s->workaround_bugs & FF_BUG_AMV)
+ len >>= s->quarter_sample;
if(s->real_sprite_warping_points==1){
if(s->divx_version==500 && s->divx_build==413)
@@ -4433,6 +4452,8 @@ static int h263_decode_block(MpegEncContext * s, DCTELEM * block,
}
} else {
level = get_bits(&s->gb, 8);
+ if (level == 255)
+ level = 128;
}
}else{
level = get_bits(&s->gb, 8);
@@ -4530,8 +4551,7 @@ not_coded:
*/
static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr)
{
- int level, pred, code;
- uint16_t *dc_val;
+ int level, code;
if (n < 4)
code = get_vlc2(&s->gb, dc_lum.table, DC_VLC_BITS, 1);
@@ -4566,30 +4586,8 @@ static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr)
}
}
}
- pred = ff_mpeg4_pred_dc(s, n, &dc_val, dir_ptr);
- level += pred;
- if (level < 0){
- if(s->error_resilience>=3){
- av_log(s->avctx, AV_LOG_ERROR, "dc<0 at %dx%d\n", s->mb_x, s->mb_y);
- return -1;
- }
- level = 0;
- }
- if (n < 4) {
- *dc_val = level * s->y_dc_scale;
- } else {
- *dc_val = level * s->c_dc_scale;
- }
- if(IS_3IV1)
- *dc_val = level * 8;
-
- if(s->error_resilience>=3){
- if(*dc_val > 2048 + s->y_dc_scale + s->c_dc_scale){
- av_log(s->avctx, AV_LOG_ERROR, "dc overflow at %dx%d\n", s->mb_x, s->mb_y);
- return -1;
- }
- }
- return level;
+
+ return ff_mpeg4_pred_dc(s, n, level, dir_ptr, 0);
}
/**
@@ -4720,6 +4718,8 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
if (cache&0x80000000) {
if (cache&0x40000000) {
+ int ulevel;
+
/* third escape */
SKIP_CACHE(re, &s->gb, 2);
last= SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1);
@@ -4745,10 +4745,16 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
SKIP_COUNTER(re, &s->gb, 1+12+1);
}
- if(level*s->qscale>1024 || level*s->qscale<-1024){
+ if(s->mpeg_quant){
+ if(intra) ulevel= level*s->qscale*s->intra_matrix[scan_table[1]];
+ else ulevel= level*s->qscale*s->inter_matrix[scan_table[0]];
+ }else
+ ulevel= level*s->qscale*16;
+ if(ulevel>1030*16 || ulevel<-1030*16){
av_log(s->avctx, AV_LOG_ERROR, "|level| overflow in 3. esc, qp=%d\n", s->qscale);
return -1;
}
+
#if 0
if(s->error_resilience >= FF_ER_COMPLIANT){
const int abs_level= ABS(level);
@@ -4827,14 +4833,8 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
not_coded:
if (intra) {
if(s->qscale >= s->intra_dc_threshold){
- uint16_t *dc_val;
- block[0] += ff_mpeg4_pred_dc(s, n, &dc_val, &dc_pred_dir);
- if (n < 4) {
- *dc_val = block[0] * s->y_dc_scale;
- } else {
- *dc_val = block[0] * s->c_dc_scale;
- }
-
+ block[0] = ff_mpeg4_pred_dc(s, n, block[0], &dc_pred_dir, 0);
+
if(i == -1) i=0;
}
diff --git a/src/libffmpeg/libavcodec/h263dec.c b/src/libffmpeg/libavcodec/h263dec.c
index aaf38b172..ea8badb9d 100644
--- a/src/libffmpeg/libavcodec/h263dec.c
+++ b/src/libffmpeg/libavcodec/h263dec.c
@@ -306,8 +306,7 @@ static int decode_slice(MpegEncContext *s){
* 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 mpeg4_find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){
- ParseContext *pc= &s->parse_context;
+int ff_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){
int vop_found, i;
uint32_t state;
@@ -326,23 +325,25 @@ static int mpeg4_find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){
}
}
- if(vop_found){
- for(; i<buf_size; i++){
- state= (state<<8) | buf[i];
- if((state&0xFFFFFF00) == 0x100){
- pc->frame_start_found=0;
- pc->state=-1;
- return i-3;
+ if(vop_found){
+ /* EOF considered as end of frame */
+ if (buf_size == 0)
+ return 0;
+ for(; i<buf_size; i++){
+ state= (state<<8) | buf[i];
+ if((state&0xFFFFFF00) == 0x100){
+ pc->frame_start_found=0;
+ pc->state=-1;
+ return i-3;
+ }
}
- }
}
pc->frame_start_found= vop_found;
pc->state= state;
return END_NOT_FOUND;
}
-static int h263_find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){
- ParseContext *pc= &s->parse_context;
+static int h263_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){
int vop_found, i;
uint32_t state;
@@ -377,6 +378,27 @@ static int h263_find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){
return END_NOT_FOUND;
}
+static int h263_parse(AVCodecParserContext *s,
+ AVCodecContext *avctx,
+ uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size)
+{
+ ParseContext *pc = s->priv_data;
+ int next;
+
+ next= h263_find_frame_end(pc, buf, buf_size);
+
+ if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
+ *poutbuf = NULL;
+ *poutbuf_size = 0;
+ return buf_size;
+ }
+
+ *poutbuf = (uint8_t *)buf;
+ *poutbuf_size = buf_size;
+ return next;
+}
+
int ff_h263_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
uint8_t *buf, int buf_size)
@@ -414,15 +436,15 @@ uint64_t time= rdtsc();
int next;
if(s->codec_id==CODEC_ID_MPEG4){
- next= mpeg4_find_frame_end(s, buf, buf_size);
+ next= ff_mpeg4_find_frame_end(&s->parse_context, buf, buf_size);
}else if(s->codec_id==CODEC_ID_H263){
- next= h263_find_frame_end(s, buf, buf_size);
+ next= h263_find_frame_end(&s->parse_context, buf, buf_size);
}else{
av_log(s->avctx, AV_LOG_ERROR, "this codec doesnt support truncated bitstreams\n");
return -1;
}
- if( ff_combine_frame(s, next, &buf, &buf_size) < 0 )
+ if( ff_combine_frame(&s->parse_context, next, &buf, &buf_size) < 0 )
return buf_size;
}
@@ -526,6 +548,9 @@ retry:
if(s->xvid_build && s->xvid_build<=12)
s->workaround_bugs|= FF_BUG_EDGE;
+ if(s->xvid_build && s->xvid_build<=32)
+ s->workaround_bugs|= FF_BUG_DC_CLIP;
+
#define SET_QPEL_FUNC(postfix1, postfix2) \
s->dsp.put_ ## postfix1 = ff_put_ ## postfix2;\
s->dsp.put_no_rnd_ ## postfix1 = ff_put_no_rnd_ ## postfix2;\
@@ -540,6 +565,9 @@ retry:
if(s->lavc_build && s->lavc_build<4670){
s->workaround_bugs|= FF_BUG_EDGE;
}
+
+ if(s->lavc_build && s->lavc_build<=4712)
+ s->workaround_bugs|= FF_BUG_DC_CLIP;
if(s->divx_version)
s->workaround_bugs|= FF_BUG_DIRECT_BLOCKSIZE;
@@ -843,3 +871,11 @@ AVCodec flv_decoder = {
ff_h263_decode_frame,
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1
};
+
+AVCodecParser h263_parser = {
+ { CODEC_ID_H263 },
+ sizeof(ParseContext),
+ NULL,
+ h263_parse,
+ ff_parse_close,
+};
diff --git a/src/libffmpeg/libavcodec/h264.c b/src/libffmpeg/libavcodec/h264.c
index fa254e93b..77c3393ef 100644
--- a/src/libffmpeg/libavcodec/h264.c
+++ b/src/libffmpeg/libavcodec/h264.c
@@ -5520,8 +5520,7 @@ static inline int decode_picture_parameter_set(H264Context *h){
* 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 find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){
- ParseContext *pc= &s->parse_context;
+static int find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){
int i;
uint32_t state;
//printf("first %02X%02X%02X%02X\n", buf[0], buf[1],buf[2],buf[3]);
@@ -5544,6 +5543,27 @@ static int find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){
return END_NOT_FOUND;
}
+static int h264_parse(AVCodecParserContext *s,
+ AVCodecContext *avctx,
+ uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size)
+{
+ ParseContext *pc = s->priv_data;
+ int next;
+
+ next= find_frame_end(pc, buf, buf_size);
+
+ if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
+ *poutbuf = NULL;
+ *poutbuf_size = 0;
+ return buf_size;
+ }
+
+ *poutbuf = (uint8_t *)buf;
+ *poutbuf_size = buf_size;
+ return next;
+}
+
static int decode_nal_units(H264Context *h, uint8_t *buf, int buf_size){
MpegEncContext * const s = &h->s;
AVCodecContext * const avctx= s->avctx;
@@ -5701,9 +5721,9 @@ static int decode_frame(AVCodecContext *avctx,
}
if(s->flags&CODEC_FLAG_TRUNCATED){
- int next= find_frame_end(s, buf, buf_size);
+ int next= find_frame_end(&s->parse_context, buf, buf_size);
- if( ff_combine_frame(s, next, &buf, &buf_size) < 0 )
+ if( ff_combine_frame(&s->parse_context, next, &buf, &buf_size) < 0 )
return buf_size;
//printf("next:%d buf_size:%d last_index:%d\n", next, buf_size, s->parse_context.last_index);
}
@@ -5970,4 +5990,12 @@ AVCodec h264_decoder = {
/*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED,
};
+AVCodecParser h264_parser = {
+ { CODEC_ID_H264 },
+ sizeof(ParseContext),
+ NULL,
+ h264_parse,
+ ff_parse_close,
+};
+
#include "svq3.c"
diff --git a/src/libffmpeg/libavcodec/huffyuv.c b/src/libffmpeg/libavcodec/huffyuv.c
index 4047a6a93..210d45419 100644
--- a/src/libffmpeg/libavcodec/huffyuv.c
+++ b/src/libffmpeg/libavcodec/huffyuv.c
@@ -916,8 +916,6 @@ static int decode_end(AVCodecContext *avctx)
for(i=0; i<3; i++){
free_vlc(&s->vlc[i]);
}
-
- avcodec_default_free_buffers(avctx);
return 0;
}
diff --git a/src/libffmpeg/libavcodec/i386/dsputil_mmx.c b/src/libffmpeg/libavcodec/i386/dsputil_mmx.c
index 772c9c1f0..c8db22e64 100644
--- a/src/libffmpeg/libavcodec/i386/dsputil_mmx.c
+++ b/src/libffmpeg/libavcodec/i386/dsputil_mmx.c
@@ -22,6 +22,7 @@
#include "../dsputil.h"
#include "../simple_idct.h"
+#include "mmx.h"
//#undef NDEBUG
//#include <assert.h>
@@ -293,6 +294,24 @@ void put_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size
:"memory");
}
+static unsigned char __align8 vector128[8] =
+ { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
+
+void put_signed_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size)
+{
+ int i;
+
+ movq_m2r(*vector128, mm1);
+ for (i = 0; i < 8; i++) {
+ movq_m2r(*(block), mm0);
+ packsswb_m2r(*(block + 4), mm0);
+ block += 8;
+ paddb_r2r(mm1, mm0);
+ movq_r2m(mm0, *pixels);
+ pixels += line_size;
+ }
+}
+
void add_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size)
{
const DCTELEM *p;
@@ -2149,19 +2168,18 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx)
/* VP3 optimized DSP functions */
if (mm_flags & MM_SSE2) {
c->vp3_dsp_init = vp3_dsp_init_sse2;
- c->vp3_idct_put = vp3_idct_put_sse2;
- c->vp3_idct_add = vp3_idct_add_sse2;
+ c->vp3_idct = vp3_idct_sse2;
} else {
c->vp3_dsp_init = vp3_dsp_init_mmx;
- c->vp3_idct_put = vp3_idct_put_mmx;
- c->vp3_idct_add = vp3_idct_add_mmx;
+ c->vp3_idct = vp3_idct_mmx;
}
-
+
#ifdef CONFIG_ENCODERS
c->get_pixels = get_pixels_mmx;
c->diff_pixels = diff_pixels_mmx;
#endif //CONFIG_ENCODERS
c->put_pixels_clamped = put_pixels_clamped_mmx;
+ c->put_signed_pixels_clamped = put_signed_pixels_clamped_mmx;
c->add_pixels_clamped = add_pixels_clamped_mmx;
c->clear_blocks = clear_blocks_mmx;
#ifdef CONFIG_ENCODERS
diff --git a/src/libffmpeg/libavcodec/i386/fdct_mmx.c b/src/libffmpeg/libavcodec/i386/fdct_mmx.c
index 7af576971..68f788a23 100644
--- a/src/libffmpeg/libavcodec/i386/fdct_mmx.c
+++ b/src/libffmpeg/libavcodec/i386/fdct_mmx.c
@@ -60,77 +60,77 @@ struct
//static const long fdct_r_row_sse2[4] ATTR_ALIGN(16) = {RND_FRW_ROW, RND_FRW_ROW, RND_FRW_ROW, RND_FRW_ROW};
static const int16_t tab_frw_01234567[] ATTR_ALIGN(8) = { // forward_dct coeff table
- 16384, 16384, -8867, -21407,
- 16384, 16384, 21407, 8867,
- 16384, -16384, 21407, -8867,
- -16384, 16384, 8867, -21407,
- 22725, 19266, -22725, -12873,
- 12873, 4520, 19266, -4520,
- 12873, -22725, 19266, -22725,
- 4520, 19266, 4520, -12873,
-
- 22725, 22725, -12299, -29692,
- 22725, 22725, 29692, 12299,
- 22725, -22725, 29692, -12299,
- -22725, 22725, 12299, -29692,
- 31521, 26722, -31521, -17855,
- 17855, 6270, 26722, -6270,
- 17855, -31521, 26722, -31521,
- 6270, 26722, 6270, -17855,
-
- 21407, 21407, -11585, -27969,
- 21407, 21407, 27969, 11585,
- 21407, -21407, 27969, -11585,
- -21407, 21407, 11585, -27969,
- 29692, 25172, -29692, -16819,
- 16819, 5906, 25172, -5906,
- 16819, -29692, 25172, -29692,
- 5906, 25172, 5906, -16819,
-
- 19266, 19266, -10426, -25172,
- 19266, 19266, 25172, 10426,
- 19266, -19266, 25172, -10426,
- -19266, 19266, 10426, -25172,
- 26722, 22654, -26722, -15137,
- 15137, 5315, 22654, -5315,
- 15137, -26722, 22654, -26722,
- 5315, 22654, 5315, -15137,
-
- 16384, 16384, -8867, -21407,
- 16384, 16384, 21407, 8867,
- 16384, -16384, 21407, -8867,
- -16384, 16384, 8867, -21407,
- 22725, 19266, -22725, -12873,
- 12873, 4520, 19266, -4520,
- 12873, -22725, 19266, -22725,
- 4520, 19266, 4520, -12873,
-
- 19266, 19266, -10426, -25172,
- 19266, 19266, 25172, 10426,
- 19266, -19266, 25172, -10426,
- -19266, 19266, 10426, -25172,
- 26722, 22654, -26722, -15137,
- 15137, 5315, 22654, -5315,
- 15137, -26722, 22654, -26722,
- 5315, 22654, 5315, -15137,
-
- 21407, 21407, -11585, -27969,
- 21407, 21407, 27969, 11585,
- 21407, -21407, 27969, -11585,
- -21407, 21407, 11585, -27969,
- 29692, 25172, -29692, -16819,
- 16819, 5906, 25172, -5906,
- 16819, -29692, 25172, -29692,
- 5906, 25172, 5906, -16819,
-
- 22725, 22725, -12299, -29692,
- 22725, 22725, 29692, 12299,
- 22725, -22725, 29692, -12299,
- -22725, 22725, 12299, -29692,
- 31521, 26722, -31521, -17855,
- 17855, 6270, 26722, -6270,
- 17855, -31521, 26722, -31521,
- 6270, 26722, 6270, -17855,
+ 16384, 16384, 22725, 19266,
+ 16384, 16384, 12873, 4520,
+ 21407, 8867, 19266, -4520,
+ -8867, -21407, -22725, -12873,
+ 16384, -16384, 12873, -22725,
+ -16384, 16384, 4520, 19266,
+ 8867, -21407, 4520, -12873,
+ 21407, -8867, 19266, -22725,
+
+ 22725, 22725, 31521, 26722,
+ 22725, 22725, 17855, 6270,
+ 29692, 12299, 26722, -6270,
+ -12299, -29692, -31521, -17855,
+ 22725, -22725, 17855, -31521,
+ -22725, 22725, 6270, 26722,
+ 12299, -29692, 6270, -17855,
+ 29692, -12299, 26722, -31521,
+
+ 21407, 21407, 29692, 25172,
+ 21407, 21407, 16819, 5906,
+ 27969, 11585, 25172, -5906,
+ -11585, -27969, -29692, -16819,
+ 21407, -21407, 16819, -29692,
+ -21407, 21407, 5906, 25172,
+ 11585, -27969, 5906, -16819,
+ 27969, -11585, 25172, -29692,
+
+ 19266, 19266, 26722, 22654,
+ 19266, 19266, 15137, 5315,
+ 25172, 10426, 22654, -5315,
+ -10426, -25172, -26722, -15137,
+ 19266, -19266, 15137, -26722,
+ -19266, 19266, 5315, 22654,
+ 10426, -25172, 5315, -15137,
+ 25172, -10426, 22654, -26722,
+
+ 16384, 16384, 22725, 19266,
+ 16384, 16384, 12873, 4520,
+ 21407, 8867, 19266, -4520,
+ -8867, -21407, -22725, -12873,
+ 16384, -16384, 12873, -22725,
+ -16384, 16384, 4520, 19266,
+ 8867, -21407, 4520, -12873,
+ 21407, -8867, 19266, -22725,
+
+ 19266, 19266, 26722, 22654,
+ 19266, 19266, 15137, 5315,
+ 25172, 10426, 22654, -5315,
+ -10426, -25172, -26722, -15137,
+ 19266, -19266, 15137, -26722,
+ -19266, 19266, 5315, 22654,
+ 10426, -25172, 5315, -15137,
+ 25172, -10426, 22654, -26722,
+
+ 21407, 21407, 29692, 25172,
+ 21407, 21407, 16819, 5906,
+ 27969, 11585, 25172, -5906,
+ -11585, -27969, -29692, -16819,
+ 21407, -21407, 16819, -29692,
+ -21407, 21407, 5906, 25172,
+ 11585, -27969, 5906, -16819,
+ 27969, -11585, 25172, -29692,
+
+ 22725, 22725, 31521, 26722,
+ 22725, 22725, 17855, 6270,
+ 29692, 12299, 26722, -6270,
+ -12299, -29692, -31521, -17855,
+ 22725, -22725, 17855, -31521,
+ -22725, 22725, 6270, 26722,
+ 12299, -29692, 6270, -17855,
+ 29692, -12299, 26722, -31521,
};
struct
@@ -413,93 +413,91 @@ static always_inline void fdct_row_mmx2(const int16_t *in, int16_t *out, const i
{
pshufw_m2r(*(in + 4), mm5, 0x1B);
movq_m2r(*(in + 0), mm0);
- movq_r2r(mm0, mm1);
+ movq_r2r(mm0, mm1);
paddsw_r2r(mm5, mm0);
psubsw_r2r(mm5, mm1);
- pshufw_r2r(mm0, mm2, 0x4E);
- pshufw_r2r(mm1, mm3, 0x4E);
- movq_m2r(*(table + 0), mm4);
- movq_m2r(*(table + 4), mm6);
- movq_m2r(*(table + 16), mm5);
+ movq_r2r(mm0, mm2);
+ punpckldq_r2r(mm1, mm0);
+ punpckhdq_r2r(mm1, mm2);
+ movq_m2r(*(table + 0), mm1);
+ movq_m2r(*(table + 4), mm3);
+ movq_m2r(*(table + 8), mm4);
+ movq_m2r(*(table + 12), mm5);
+ movq_m2r(*(table + 16), mm6);
movq_m2r(*(table + 20), mm7);
+ pmaddwd_r2r(mm0, mm1);
+ pmaddwd_r2r(mm2, mm3);
pmaddwd_r2r(mm0, mm4);
- pmaddwd_r2r(mm1, mm5);
- pmaddwd_r2r(mm2, mm6);
- pmaddwd_r2r(mm3, mm7);
- pmaddwd_m2r(*(table + 8), mm0);
- pmaddwd_m2r(*(table + 12), mm2);
- pmaddwd_m2r(*(table + 24), mm1);
- pmaddwd_m2r(*(table + 28), mm3);
- paddd_r2r(mm6, mm4);
- paddd_r2r(mm7, mm5);
- paddd_r2r(mm2, mm0);
- paddd_r2r(mm3, mm1);
- movq_m2r(*fdct_r_row, mm7);
- paddd_r2r(mm7, mm4);
- paddd_r2r(mm7, mm5);
- paddd_r2r(mm7, mm0);
- paddd_r2r(mm7, mm1);
- psrad_i2r(SHIFT_FRW_ROW, mm4);
+ pmaddwd_r2r(mm2, mm5);
+ pmaddwd_r2r(mm0, mm6);
+ pmaddwd_r2r(mm2, mm7);
+ pmaddwd_m2r(*(table + 24), mm0);
+ pmaddwd_m2r(*(table + 28), mm2);
+ paddd_r2r(mm1, mm3);
+ paddd_r2r(mm4, mm5);
+ paddd_r2r(mm6, mm7);
+ paddd_r2r(mm0, mm2);
+ movq_m2r(*fdct_r_row, mm0);
+ paddd_r2r(mm0, mm3);
+ paddd_r2r(mm0, mm5);
+ paddd_r2r(mm0, mm7);
+ paddd_r2r(mm0, mm2);
+ psrad_i2r(SHIFT_FRW_ROW, mm3);
psrad_i2r(SHIFT_FRW_ROW, mm5);
- psrad_i2r(SHIFT_FRW_ROW, mm0);
- psrad_i2r(SHIFT_FRW_ROW, mm1);
- packssdw_r2r(mm0, mm4);
- packssdw_r2r(mm1, mm5);
- movq_r2r(mm4, mm2);
- punpcklwd_r2r(mm5, mm4);
- punpckhwd_r2r(mm5, mm2);
- movq_r2m(mm4, *(out + 0));
- movq_r2m(mm2, *(out + 4));
+ psrad_i2r(SHIFT_FRW_ROW, mm7);
+ psrad_i2r(SHIFT_FRW_ROW, mm2);
+ packssdw_r2r(mm5, mm3);
+ packssdw_r2r(mm2, mm7);
+ movq_r2m(mm3, *(out + 0));
+ movq_r2m(mm7, *(out + 4));
}
static always_inline void fdct_row_mmx(const int16_t *in, int16_t *out, const int16_t *table)
{
+//FIXME reorder (i dont have a old mmx only cpu here to benchmark ...)
movd_m2r(*(in + 6), mm1);
punpcklwd_m2r(*(in + 4), mm1);
movq_r2r(mm1, mm2);
psrlq_i2r(0x20, mm1);
movq_m2r(*(in + 0), mm0);
punpcklwd_r2r(mm2, mm1);
- movq_r2r(mm0, mm5);
+ movq_r2r(mm0, mm5);
paddsw_r2r(mm1, mm0);
psubsw_r2r(mm1, mm5);
- movq_r2r(mm0, mm1);
- movq_r2r(mm5, mm6);
- punpckldq_r2r(mm5, mm3);
- punpckhdq_r2r(mm3, mm6);
- movq_m2r(*(table + 0), mm3);
- movq_m2r(*(table + 4), mm4);
- punpckldq_r2r(mm0, mm2);
- pmaddwd_r2r(mm0, mm3);
- punpckhdq_r2r(mm2, mm1);
- movq_m2r(*(table + 16), mm2);
- pmaddwd_r2r(mm1, mm4);
- pmaddwd_m2r(*(table + 8), mm0);
+ movq_r2r(mm0, mm2);
+ punpckldq_r2r(mm5, mm0);
+ punpckhdq_r2r(mm5, mm2);
+ movq_m2r(*(table + 0), mm1);
+ movq_m2r(*(table + 4), mm3);
+ movq_m2r(*(table + 8), mm4);
+ movq_m2r(*(table + 12), mm5);
+ movq_m2r(*(table + 16), mm6);
movq_m2r(*(table + 20), mm7);
- pmaddwd_r2r(mm5, mm2);
- paddd_m2r(*fdct_r_row, mm3);
- pmaddwd_r2r(mm6, mm7);
- pmaddwd_m2r(*(table + 12), mm1);
- paddd_r2r(mm4, mm3);
- pmaddwd_m2r(*(table + 24), mm5);
- pmaddwd_m2r(*(table + 28), mm6);
- paddd_r2r(mm7, mm2);
- paddd_m2r(*fdct_r_row, mm0);
+ pmaddwd_r2r(mm0, mm1);
+ pmaddwd_r2r(mm2, mm3);
+ pmaddwd_r2r(mm0, mm4);
+ pmaddwd_r2r(mm2, mm5);
+ pmaddwd_r2r(mm0, mm6);
+ pmaddwd_r2r(mm2, mm7);
+ pmaddwd_m2r(*(table + 24), mm0);
+ pmaddwd_m2r(*(table + 28), mm2);
+ paddd_r2r(mm1, mm3);
+ paddd_r2r(mm4, mm5);
+ paddd_r2r(mm6, mm7);
+ paddd_r2r(mm0, mm2);
+ movq_m2r(*fdct_r_row, mm0);
+ paddd_r2r(mm0, mm3);
+ paddd_r2r(mm0, mm5);
+ paddd_r2r(mm0, mm7);
+ paddd_r2r(mm0, mm2);
psrad_i2r(SHIFT_FRW_ROW, mm3);
- paddd_m2r(*fdct_r_row, mm2);
- paddd_r2r(mm1, mm0);
- paddd_m2r(*fdct_r_row, mm5);
- psrad_i2r(SHIFT_FRW_ROW, mm2);
- paddd_r2r(mm6, mm5);
- psrad_i2r(SHIFT_FRW_ROW, mm0);
psrad_i2r(SHIFT_FRW_ROW, mm5);
- packssdw_r2r(mm0, mm3);
- packssdw_r2r(mm5, mm2);
- movq_r2r(mm3, mm6);
- punpcklwd_r2r(mm2, mm3);
- punpckhwd_r2r(mm2, mm6);
+ psrad_i2r(SHIFT_FRW_ROW, mm7);
+ psrad_i2r(SHIFT_FRW_ROW, mm2);
+ packssdw_r2r(mm5, mm3);
+ packssdw_r2r(mm2, mm7);
movq_r2m(mm3, *(out + 0));
- movq_r2m(mm6, *(out + 4));
+ movq_r2m(mm7, *(out + 4));
}
void ff_fdct_mmx(int16_t *block)
@@ -553,7 +551,6 @@ void ff_fdct_sse2(int16_t *block)
int64_t align_tmp[16] ATTR_ALIGN(8);
int16_t * const block_tmp= (int16_t*)align_tmp;
int16_t *block1;
- int i;
block1 = block_tmp;
fdct_col(block, block1, 0);
diff --git a/src/libffmpeg/libavcodec/i386/vp3dsp_mmx.c b/src/libffmpeg/libavcodec/i386/vp3dsp_mmx.c
index 76007a1d1..319e57f1b 100644
--- a/src/libffmpeg/libavcodec/i386/vp3dsp_mmx.c
+++ b/src/libffmpeg/libavcodec/i386/vp3dsp_mmx.c
@@ -279,8 +279,8 @@ void vp3_dsp_init_mmx(void)
idct_constants[46] = idct_constants[47] = IdctAdjustBeforeShift;
}
-static void vp3_idct_mmx(int16_t *input_data, int16_t *dequant_matrix,
- int16_t *output_data)
+void vp3_idct_mmx(int16_t *input_data, int16_t *dequant_matrix,
+ int coeff_count, int16_t *output_data)
{
/* eax = quantized input
* ebx = dequantizer matrix
@@ -563,79 +563,3 @@ static void vp3_idct_mmx(int16_t *input_data, int16_t *dequant_matrix,
#undef J
}
-
-void vp3_idct_put_mmx(int16_t *input_data, int16_t *dequant_matrix,
- int coeff_count, uint8_t *dest, int stride)
-{
- int16_t transformed_data[64];
- int16_t *op;
- int i, j;
- uint8_t vector128[8] = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
-
- vp3_idct_mmx(input_data, dequant_matrix, transformed_data);
-
- /* place in final output */
- op = transformed_data;
- movq_m2r(*vector128, mm0);
- for (i = 0; i < 8; i++) {
-#if 1
- for (j = 0; j < 8; j++) {
- if (*op < -128)
- *dest = 0;
- else if (*op > 127)
- *dest = 255;
- else
- *dest = (uint8_t)(*op + 128);
- op++;
- dest++;
- }
- dest += (stride - 8);
-#else
-/* prototype optimization */
- pxor_r2r(mm1, mm1);
- packsswb_m2r(*(op + 4), mm1);
- movq_r2r(mm1, mm2);
- psrlq_i2r(32, mm2);
- packsswb_m2r(*(op + 0), mm1);
- op += 8;
- por_r2r(mm2, mm1);
- paddb_r2r(mm0, mm1);
- movq_r2m(mm1, *dest);
- dest += stride;
-#endif
- }
-
- /* be a good MMX citizen */
- emms();
-}
-
-void vp3_idct_add_mmx(int16_t *input_data, int16_t *dequant_matrix,
- int coeff_count, uint8_t *dest, int stride)
-{
- int16_t transformed_data[64];
- int16_t *op;
- int i, j;
- int16_t sample;
-
- vp3_idct_mmx(input_data, dequant_matrix, transformed_data);
-
- /* place in final output */
- op = transformed_data;
- for (i = 0; i < 8; i++) {
- for (j = 0; j < 8; j++) {
- sample = *dest + *op;
- if (sample < 0)
- *dest = 0;
- else if (sample > 255)
- *dest = 255;
- else
- *dest = (uint8_t)(sample & 0xFF);
- op++;
- dest++;
- }
- dest += (stride - 8);
- }
-
- /* be a good MMX citizen */
- emms();
-}
diff --git a/src/libffmpeg/libavcodec/i386/vp3dsp_sse2.c b/src/libffmpeg/libavcodec/i386/vp3dsp_sse2.c
index c8f9158af..60c6bf80e 100644
--- a/src/libffmpeg/libavcodec/i386/vp3dsp_sse2.c
+++ b/src/libffmpeg/libavcodec/i386/vp3dsp_sse2.c
@@ -802,8 +802,8 @@ void vp3_dsp_init_sse2(void)
}
-static void vp3_idct_sse2(int16_t *input_data, int16_t *dequant_matrix,
- int16_t *output_data)
+void vp3_idct_sse2(int16_t *input_data, int16_t *dequant_matrix,
+ int coeff_count, int16_t *output_data)
{
unsigned char *input_bytes = (unsigned char *)input_data;
unsigned char *dequant_matrix_bytes = (unsigned char *)dequant_matrix;
@@ -832,59 +832,3 @@ static void vp3_idct_sse2(int16_t *input_data, int16_t *dequant_matrix,
SSE2_Column_IDCT();
}
-
-
-void vp3_idct_put_sse2(int16_t *input_data, int16_t *dequant_matrix,
- int coeff_count, uint8_t *dest, int stride)
-{
- int16_t transformed_data[64];
- int16_t *op;
- int i, j;
-
- vp3_idct_sse2(input_data, dequant_matrix, transformed_data);
-
- /* place in final output */
- op = transformed_data;
- for (i = 0; i < 8; i++) {
- for (j = 0; j < 8; j++) {
- if (*op < -128)
- *dest = 0;
- else if (*op > 127)
- *dest = 255;
- else
- *dest = (uint8_t)(*op + 128);
- op++;
- dest++;
- }
- dest += (stride - 8);
- }
-}
-
-
-void vp3_idct_add_sse2(int16_t *input_data, int16_t *dequant_matrix,
- int coeff_count, uint8_t *dest, int stride)
-{
- int16_t transformed_data[64];
- int16_t *op;
- int i, j;
- int16_t sample;
-
- vp3_idct_sse2(input_data, dequant_matrix, transformed_data);
-
- /* place in final output */
- op = transformed_data;
- for (i = 0; i < 8; i++) {
- for (j = 0; j < 8; j++) {
- sample = *dest + *op;
- if (sample < 0)
- *dest = 0;
- else if (sample > 255)
- *dest = 255;
- else
- *dest = (uint8_t)(sample & 0xFF);
- op++;
- dest++;
- }
- dest += (stride - 8);
- }
-}
diff --git a/src/libffmpeg/libavcodec/integer.c b/src/libffmpeg/libavcodec/integer.c
new file mode 100644
index 000000000..025560f9e
--- /dev/null
+++ b/src/libffmpeg/libavcodec/integer.c
@@ -0,0 +1,195 @@
+/*
+ * arbitrary precision integers
+ * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/**
+ * @file integer.c
+ * arbitrary precision integers.
+ * @author Michael Niedermayer <michaelni@gmx.at>
+ */
+
+#include "common.h"
+#include "integer.h"
+
+AVInteger av_add_i(AVInteger a, AVInteger b){
+ int i, carry=0;
+
+ for(i=0; i<AV_INTEGER_SIZE; i++){
+ carry= (carry>>16) + a.v[i] + b.v[i];
+ a.v[i]= carry;
+ }
+ return a;
+}
+
+AVInteger av_sub_i(AVInteger a, AVInteger b){
+ int i, carry=0;
+
+ for(i=0; i<AV_INTEGER_SIZE; i++){
+ carry= (carry>>16) + a.v[i] - b.v[i];
+ a.v[i]= carry;
+ }
+ return a;
+}
+
+int av_log2_i(AVInteger a){
+ int i;
+
+ for(i=AV_INTEGER_SIZE-1; i>=0; i--){
+ if(a.v[i])
+ return av_log2_16bit(a.v[i]) + 16*i;
+ }
+ return -1;
+}
+
+AVInteger av_mul_i(AVInteger a, AVInteger b){
+ AVInteger out;
+ int i, j;
+ int na= (av_log2_i(a)+16) >> 4;
+ int nb= (av_log2_i(b)+16) >> 4;
+
+ memset(&out, 0, sizeof(out));
+
+ for(i=0; i<na; i++){
+ unsigned int carry=0;
+
+ if(a.v[i])
+ for(j=i; j<AV_INTEGER_SIZE && j-i<=nb; j++){
+ carry= (carry>>16) + out.v[j] + a.v[i]*b.v[j-i];
+ out.v[j]= carry;
+ }
+ }
+
+ return out;
+}
+
+int av_cmp_i(AVInteger a, AVInteger b){
+ int i;
+ int v= (int16_t)a.v[AV_INTEGER_SIZE-1] - (int16_t)b.v[AV_INTEGER_SIZE-1];
+ if(v) return (v>>16)|1;
+
+ for(i=AV_INTEGER_SIZE-2; i>=0; i--){
+ int v= a.v[i] - b.v[i];
+ if(v) return (v>>16)|1;
+ }
+ return 0;
+}
+
+AVInteger av_shr_i(AVInteger a, int s){
+ AVInteger out;
+ int i;
+
+ for(i=0; i<AV_INTEGER_SIZE; i++){
+ int index= i + (s>>4);
+ unsigned int v=0;
+ if(index+1<AV_INTEGER_SIZE && index+1>=0) v = a.v[index+1]<<16;
+ if(index <AV_INTEGER_SIZE && index >=0) v+= a.v[index ];
+ out.v[i]= v >> (s&15);
+ }
+ return out;
+}
+
+AVInteger av_mod_i(AVInteger *quot, AVInteger a, AVInteger b){
+ int i= av_log2_i(a) - av_log2_i(b);
+ AVInteger quot_temp;
+ if(!quot) quot = &quot_temp;
+
+ assert((int16_t)a[AV_INTEGER_SIZE-1] >= 0 && (int16_t)b[AV_INTEGER_SIZE-1] >= 0);
+ assert(av_log2(b)>=0);
+
+ if(i > 0)
+ b= av_shr_i(b, -i);
+
+ memset(quot, 0, sizeof(AVInteger));
+
+ while(i-- >= 0){
+ *quot= av_shr_i(*quot, -1);
+ if(av_cmp_i(a, b) >= 0){
+ a= av_sub_i(a, b);
+ quot->v[0] += 1;
+ }
+ b= av_shr_i(b, 1);
+ }
+ return a;
+}
+
+AVInteger av_div_i(AVInteger a, AVInteger b){
+ AVInteger quot;
+ av_mod_i(&quot, a, b);
+ return quot;
+}
+
+AVInteger av_int2i(int64_t a){
+ AVInteger out;
+ int i;
+
+ for(i=0; i<AV_INTEGER_SIZE; i++){
+ out.v[i]= a;
+ a>>=16;
+ }
+ return out;
+}
+
+int64_t av_i2int(AVInteger a){
+ int i;
+ int64_t out=(int8_t)a.v[AV_INTEGER_SIZE-1];
+
+ for(i= AV_INTEGER_SIZE-2; i>=0; i--){
+ out = (out<<16) + a.v[i];
+ }
+ return out;
+}
+
+#if 0
+#undef NDEBUG
+#include <assert.h>
+
+const uint8_t ff_log2_tab[256]={
+ 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
+};
+
+main(){
+ int64_t a,b;
+
+ for(a=7; a<256*256*256; a+=13215){
+ for(b=3; b<256*256*256; b+=27118){
+ AVInteger ai= av_int2i(a);
+ AVInteger bi= av_int2i(b);
+
+ assert(av_i2int(ai) == a);
+ assert(av_i2int(bi) == b);
+ assert(av_i2int(av_add_i(ai,bi)) == a+b);
+ assert(av_i2int(av_sub_i(ai,bi)) == a-b);
+ assert(av_i2int(av_mul_i(ai,bi)) == a*b);
+ assert(av_i2int(av_shr_i(ai, 9)) == a>>9);
+ assert(av_i2int(av_shr_i(ai,-9)) == a<<9);
+ assert(av_i2int(av_shr_i(ai, 17)) == a>>17);
+ assert(av_i2int(av_shr_i(ai,-17)) == a<<17);
+ assert(av_log2_i(ai) == av_log2(a));
+ assert(av_i2int(av_div_i(ai,bi)) == a/b);
+ }
+ }
+}
+#endif
diff --git a/src/libffmpeg/libavcodec/integer.h b/src/libffmpeg/libavcodec/integer.h
new file mode 100644
index 000000000..ef1b2a089
--- /dev/null
+++ b/src/libffmpeg/libavcodec/integer.h
@@ -0,0 +1,47 @@
+/*
+ * arbitrary precision integers
+ * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/**
+ * @file integer.h
+ * arbitrary precision integers
+ * @author Michael Niedermayer <michaelni@gmx.at>
+ */
+
+#ifndef INTEGER_H
+#define INTEGER_H
+
+#define AV_INTEGER_SIZE 8
+
+typedef struct AVInteger{
+ uint16_t v[AV_INTEGER_SIZE];
+} AVInteger;
+
+AVInteger av_add_i(AVInteger a, AVInteger b);
+AVInteger av_sub_i(AVInteger a, AVInteger b);
+int av_log2_i(AVInteger a);
+AVInteger av_mul_i(AVInteger a, AVInteger b);
+int av_cmp_i(AVInteger a, AVInteger b);
+AVInteger av_shr_i(AVInteger a, int s);
+AVInteger av_mod_i(AVInteger *quot, AVInteger a, AVInteger b);
+AVInteger av_div_i(AVInteger a, AVInteger b);
+AVInteger av_int2i(int64_t a);
+int64_t av_i2int(AVInteger a);
+
+#endif // INTEGER_H
diff --git a/src/libffmpeg/libavcodec/mdec.c b/src/libffmpeg/libavcodec/mdec.c
index faf3cef31..219a39b25 100644
--- a/src/libffmpeg/libavcodec/mdec.c
+++ b/src/libffmpeg/libavcodec/mdec.c
@@ -257,8 +257,6 @@ static int decode_end(AVCodecContext *avctx){
av_freep(&a->picture.qscale_table);
a->bitstream_buffer_size=0;
- avcodec_default_free_buffers(avctx);
-
return 0;
}
diff --git a/src/libffmpeg/libavcodec/mjpeg.c b/src/libffmpeg/libavcodec/mjpeg.c
index 255a82d2c..78a620fd3 100644
--- a/src/libffmpeg/libavcodec/mjpeg.c
+++ b/src/libffmpeg/libavcodec/mjpeg.c
@@ -1340,7 +1340,7 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s){
(h * mb_x + x) * 8;
if (s->interlaced && s->bottom_field)
ptr += s->linesize[c] >> 1;
-//printf("%d %d %d %d %d %d %d %d \n", mb_x, mb_y, x, y, c, s->bottom_field, (v * mb_y + y) * 8, (h * mb_x + x) * 8);
+//av_log(NULL, AV_LOG_DEBUG, "%d %d %d %d %d %d %d %d \n", mb_x, mb_y, x, y, c, s->bottom_field, (v * mb_y + y) * 8, (h * mb_x + x) * 8);
s->idct_put(ptr, s->linesize[c], s->block);
if (++x == h) {
x = 0;
@@ -2171,7 +2171,6 @@ static int mjpeg_decode_end(AVCodecContext *avctx)
av_free(s->buffer);
av_free(s->qscale_table);
- avcodec_default_free_buffers(avctx);
for(i=0;i<2;i++) {
for(j=0;j<4;j++)
diff --git a/src/libffmpeg/libavcodec/motion_est.c b/src/libffmpeg/libavcodec/motion_est.c
index f194a4d60..6aeedd5b9 100644
--- a/src/libffmpeg/libavcodec/motion_est.c
+++ b/src/libffmpeg/libavcodec/motion_est.c
@@ -1002,7 +1002,10 @@ static inline int check_input_motion(MpegEncContext * s, int mb_x, int mb_y, int
c->stride<<=1;
c->uvstride<<=1;
- assert(s->flags & CODEC_FLAG_INTERLACED_ME);
+ if(!(s->flags & CODEC_FLAG_INTERLACED_ME)){
+ av_log(s->avctx, AV_LOG_ERROR, "Interlaced macroblock selected but interlaced motion estimation disabled\n");
+ return -1;
+ }
if(USES_LIST(mb_type, 0)){
int field_select0= p->ref_index[0][xy ];
@@ -1060,7 +1063,10 @@ static inline int check_input_motion(MpegEncContext * s, int mb_x, int mb_y, int
c->stride>>=1;
c->uvstride>>=1;
}else if(IS_8X8(mb_type)){
- assert(s->flags & CODEC_FLAG_4MV);
+ if(!(s->flags & CODEC_FLAG_4MV)){
+ av_log(s->avctx, AV_LOG_ERROR, "4MV macroblock selected but 4MV encoding disabled\n");
+ return -1;
+ }
cmpf= s->dsp.sse[1];
chroma_cmpf= s->dsp.sse[1];
init_mv4_ref(s);
diff --git a/src/libffmpeg/libavcodec/mpeg12.c b/src/libffmpeg/libavcodec/mpeg12.c
index 493d1a445..20ca493f2 100644
--- a/src/libffmpeg/libavcodec/mpeg12.c
+++ b/src/libffmpeg/libavcodec/mpeg12.c
@@ -365,14 +365,10 @@ static inline void encode_mb_skip_run(MpegEncContext *s, int run){
static void common_init(MpegEncContext *s)
{
-int i;
s->y_dc_scale_table=
- s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
+ s->c_dc_scale_table= mpeg2_dc_scale_table[s->intra_dc_precision];
- if(!s->encoding)
- for(i=0;i<64;i++)
- s->dsp.idct_permutation[i]=i;
}
void ff_mpeg1_clean_buffers(MpegEncContext *s){
@@ -784,7 +780,7 @@ void ff_mpeg1_encode_init(MpegEncContext *s)
adiff = ABS(diff);
if(diff<0) diff--;
- index = vlc_dc_table[adiff];
+ index = av_log2(2*adiff);
bits= vlc_dc_lum_bits[index] + index;
code= (vlc_dc_lum_code[index]<<index) + (diff & ((1 << index) - 1));
@@ -848,6 +844,27 @@ void ff_mpeg1_encode_init(MpegEncContext *s)
static inline void encode_dc(MpegEncContext *s, int diff, int component)
{
+ if(((unsigned) (diff+255)) >= 511){
+ int index;
+
+ if(diff<0){
+ index= av_log2_16bit(-2*diff);
+ diff--;
+ }else{
+ index= av_log2_16bit(2*diff);
+ }
+ if (component == 0) {
+ put_bits(
+ &s->pb,
+ vlc_dc_lum_bits[index] + index,
+ (vlc_dc_lum_code[index]<<index) + (diff & ((1 << index) - 1)));
+ }else{
+ put_bits(
+ &s->pb,
+ vlc_dc_chroma_bits[index] + index,
+ (vlc_dc_chroma_code[index]<<index) + (diff & ((1 << index) - 1)));
+ }
+ }else{
if (component == 0) {
put_bits(
&s->pb,
@@ -859,6 +876,7 @@ static inline void encode_dc(MpegEncContext *s, int diff, int component)
mpeg1_chr_dc_uni[diff+255]&0xFF,
mpeg1_chr_dc_uni[diff+255]>>8);
}
+ }
}
static void mpeg1_encode_block(MpegEncContext *s,
@@ -1770,7 +1788,14 @@ static int mpeg_decode_init(AVCodecContext *avctx)
{
Mpeg1Context *s = avctx->priv_data;
MpegEncContext *s2 = &s->mpeg_enc_ctx;
+ int i;
+ //we need some parmutation to store
+ //matrixes, until MPV_common_init()
+ //set the real permutatuon
+ for(i=0;i<64;i++)
+ s2->dsp.idct_permutation[i]=i;
+
MPV_decode_defaults(s2);
s->mpeg_enc_ctx.avctx= avctx;
@@ -2726,8 +2751,8 @@ static void mpeg_decode_gop(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 ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size)
+{
int i;
uint32_t state;
@@ -2746,6 +2771,9 @@ static int mpeg1_find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){
}
if(pc->frame_start_found){
+ /* EOF considered as end of frame */
+ if (buf_size == 0)
+ return 0;
for(; i<buf_size; i++){
state= (state<<8) | buf[i];
if((state&0xFFFFFF00) == 0x100){
@@ -2786,9 +2814,9 @@ static int mpeg_decode_frame(AVCodecContext *avctx,
}
if(s2->flags&CODEC_FLAG_TRUNCATED){
- int next= mpeg1_find_frame_end(s2, buf, buf_size);
+ int next= ff_mpeg1_find_frame_end(&s2->parse_context, buf, buf_size);
- if( ff_combine_frame(s2, next, &buf, &buf_size) < 0 )
+ if( ff_combine_frame(&s2->parse_context, next, &buf, &buf_size) < 0 )
return buf_size;
}
diff --git a/src/libffmpeg/libavcodec/mpeg12data.h b/src/libffmpeg/libavcodec/mpeg12data.h
index 4ee460ccc..82e2ab6a1 100644
--- a/src/libffmpeg/libavcodec/mpeg12data.h
+++ b/src/libffmpeg/libavcodec/mpeg12data.h
@@ -25,29 +25,6 @@ const int16_t ff_mpeg1_default_non_intra_matrix[64] = {
16, 16, 16, 16, 16, 16, 16, 16,
};
-static const unsigned char vlc_dc_table[256] = {
- 0, 1, 2, 2,
- 3, 3, 3, 3,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-};
-
static const uint16_t vlc_dc_lum_code[12] = {
0x4, 0x0, 0x1, 0x5, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe, 0x1ff,
};
@@ -382,7 +359,7 @@ static const uint8_t non_linear_qscale[32] = {
56,64,72,80,88,96,104,112,
};
-uint8_t ff_mpeg1_dc_scale_table[128]={ // MN: mpeg2 really can have such large qscales?
+uint8_t ff_mpeg1_dc_scale_table[128]={
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
@@ -390,6 +367,37 @@ uint8_t ff_mpeg1_dc_scale_table[128]={ // MN: mpeg2 really can have such large q
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
};
+static uint8_t mpeg2_dc_scale_table1[128]={
+// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+};
+
+static uint8_t mpeg2_dc_scale_table2[128]={
+// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+};
+
+static uint8_t mpeg2_dc_scale_table3[128]={
+// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+};
+
+static uint8_t *mpeg2_dc_scale_table[4]={
+ ff_mpeg1_dc_scale_table,
+ mpeg2_dc_scale_table1,
+ mpeg2_dc_scale_table2,
+ mpeg2_dc_scale_table3,
+};
+
static const float mpeg1_aspect[16]={
0.0000,
1.0000,
diff --git a/src/libffmpeg/libavcodec/mpegvideo.c b/src/libffmpeg/libavcodec/mpegvideo.c
index bef088a41..41ee62435 100644
--- a/src/libffmpeg/libavcodec/mpegvideo.c
+++ b/src/libffmpeg/libavcodec/mpegvideo.c
@@ -605,6 +605,11 @@ int MPV_common_init(MpegEncContext *s)
{
int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y;
+ if(s->avctx->thread_count > MAX_THREADS || (16*s->avctx->thread_count > s->height && s->height)){
+ av_log(s->avctx, AV_LOG_ERROR, "too many threads\n");
+ return -1;
+ }
+
dsputil_init(&s->dsp, s->avctx);
DCT_common_init(s);
@@ -850,7 +855,6 @@ void MPV_common_end(MpegEncContext *s)
}
}
av_freep(&s->picture);
- avcodec_default_free_buffers(s->avctx);
s->context_initialized = 0;
s->last_picture_ptr=
s->next_picture_ptr=
@@ -893,6 +897,7 @@ int MPV_encode_init(AVCodecContext *avctx)
s->quarter_sample= (avctx->flags & CODEC_FLAG_QPEL)!=0;
s->mpeg_quant= avctx->mpeg_quant;
s->rtp_mode= !!avctx->rtp_payload_size;
+ s->intra_dc_precision= avctx->intra_dc_precision;
if (s->gop_size <= 1) {
s->intra_only = 1;
@@ -998,11 +1003,6 @@ int MPV_encode_init(AVCodecContext *avctx)
return -1;
}
- if(s->avctx->thread_count > MAX_THREADS || 16*s->avctx->thread_count > s->height){
- av_log(avctx, AV_LOG_ERROR, "too many threads\n");
- return -1;
- }
-
if(s->avctx->thread_count > 1)
s->rtp_mode= 1;
@@ -3727,64 +3727,6 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
#endif //CONFIG_ENCODERS
-/**
- * combines the (truncated) bitstream to a complete frame
- * @returns -1 if no complete frame could be created
- */
-int ff_combine_frame( MpegEncContext *s, int next, uint8_t **buf, int *buf_size){
- ParseContext *pc= &s->parse_context;
-
-#if 0
- if(pc->overread){
- printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index);
- printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]);
- }
-#endif
-
- /* copy overreaded byes from last frame into buffer */
- for(; pc->overread>0; pc->overread--){
- pc->buffer[pc->index++]= pc->buffer[pc->overread_index++];
- }
-
- pc->last_index= pc->index;
-
- /* copy into buffer end return */
- if(next == END_NOT_FOUND){
- pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, (*buf_size) + pc->index + FF_INPUT_BUFFER_PADDING_SIZE);
-
- memcpy(&pc->buffer[pc->index], *buf, *buf_size);
- pc->index += *buf_size;
- return -1;
- }
-
- *buf_size=
- pc->overread_index= pc->index + next;
-
- /* append to buffer */
- if(pc->index){
- pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + FF_INPUT_BUFFER_PADDING_SIZE);
-
- memcpy(&pc->buffer[pc->index], *buf, next + FF_INPUT_BUFFER_PADDING_SIZE );
- pc->index = 0;
- *buf= pc->buffer;
- }
-
- /* store overread bytes */
- for(;next < 0; next++){
- pc->state = (pc->state<<8) | pc->buffer[pc->last_index + next];
- pc->overread++;
- }
-
-#if 0
- if(pc->overread){
- printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index);
- printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]);
- }
-#endif
-
- return 0;
-}
-
void ff_mpeg_flush(AVCodecContext *avctx){
int i;
MpegEncContext *s = avctx->priv_data;
@@ -4099,7 +4041,7 @@ static int encode_thread(AVCodecContext *c, void *arg){
for(i=0; i<3; i++){
/* init last dc values */
/* note: quant matrix value (8) is implied here */
- s->last_dc[i] = 128;
+ s->last_dc[i] = 128 << s->intra_dc_precision;
s->current_picture_ptr->error[i] = 0;
}
diff --git a/src/libffmpeg/libavcodec/mpegvideo.h b/src/libffmpeg/libavcodec/mpegvideo.h
index cd42177f5..d09fd4e0a 100644
--- a/src/libffmpeg/libavcodec/mpegvideo.h
+++ b/src/libffmpeg/libavcodec/mpegvideo.h
@@ -749,7 +749,8 @@ void ff_draw_horiz_band(MpegEncContext *s, int y, int h);
void ff_emulated_edge_mc(uint8_t *buf, uint8_t *src, int linesize, int block_w, int block_h,
int src_x, int src_y, int w, int h);
#define END_NOT_FOUND -100
-int ff_combine_frame( MpegEncContext *s, int next, uint8_t **buf, int *buf_size);
+int ff_combine_frame(ParseContext *pc, int next, uint8_t **buf, int *buf_size);
+void ff_parse_close(AVCodecParserContext *s);
void ff_mpeg_flush(AVCodecContext *avctx);
void ff_print_debug_info(MpegEncContext *s, AVFrame *pict);
void ff_write_quant_matrix(PutBitContext *pb, int16_t *matrix);
diff --git a/src/libffmpeg/libavcodec/parser.c b/src/libffmpeg/libavcodec/parser.c
new file mode 100644
index 000000000..88894884c
--- /dev/null
+++ b/src/libffmpeg/libavcodec/parser.c
@@ -0,0 +1,749 @@
+/*
+ * Audio and Video frame extraction
+ * Copyright (c) 2003 Fabrice Bellard.
+ * Copyright (c) 2003 Michael Niedermayer.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include "avcodec.h"
+#include "mpegvideo.h"
+#include "mpegaudio.h"
+
+AVCodecParser *av_first_parser = NULL;
+
+void av_register_codec_parser(AVCodecParser *parser)
+{
+ parser->next = av_first_parser;
+ av_first_parser = parser;
+}
+
+AVCodecParserContext *av_parser_init(int codec_id)
+{
+ AVCodecParserContext *s;
+ AVCodecParser *parser;
+ int ret;
+
+ for(parser = av_first_parser; parser != NULL; parser = parser->next) {
+ if (parser->codec_ids[0] == codec_id ||
+ parser->codec_ids[1] == codec_id ||
+ parser->codec_ids[2] == codec_id)
+ goto found;
+ }
+ return NULL;
+ found:
+ s = av_mallocz(sizeof(AVCodecParserContext));
+ if (!s)
+ return NULL;
+ s->parser = parser;
+ s->priv_data = av_mallocz(parser->priv_data_size);
+ if (!s->priv_data) {
+ av_free(s);
+ return NULL;
+ }
+ if (parser->parser_init) {
+ ret = parser->parser_init(s);
+ if (ret != 0) {
+ av_free(s->priv_data);
+ av_free(s);
+ return NULL;
+ }
+ }
+ return s;
+}
+
+/* NOTE: buf_size == 0 is used to signal EOF so that the last frame
+ can be returned if necessary */
+int av_parser_parse(AVCodecParserContext *s,
+ AVCodecContext *avctx,
+ uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size,
+ int64_t pts, int64_t dts)
+{
+ int index, i, k;
+ uint8_t dummy_buf[FF_INPUT_BUFFER_PADDING_SIZE];
+
+ if (buf_size == 0) {
+ /* padding is always necessary even if EOF, so we add it here */
+ memset(dummy_buf, 0, sizeof(dummy_buf));
+ buf = dummy_buf;
+ } else {
+ /* add a new packet descriptor */
+ k = (s->cur_frame_start_index + 1) & (AV_PARSER_PTS_NB - 1);
+ s->cur_frame_start_index = k;
+ s->cur_frame_offset[k] = s->cur_offset;
+ s->cur_frame_pts[k] = pts;
+ s->cur_frame_dts[k] = dts;
+
+ /* fill first PTS/DTS */
+ if (s->cur_offset == 0) {
+ s->last_pts = pts;
+ s->last_dts = dts;
+ }
+ }
+
+ /* WARNING: the returned index can be negative */
+ index = s->parser->parser_parse(s, avctx, poutbuf, poutbuf_size, buf, buf_size);
+ /* update the file pointer */
+ if (*poutbuf_size) {
+ /* fill the data for the current frame */
+ s->frame_offset = s->last_frame_offset;
+ s->pts = s->last_pts;
+ s->dts = s->last_dts;
+
+ /* offset of the next frame */
+ s->last_frame_offset = s->cur_offset + index;
+ /* find the packet in which the new frame starts. It
+ is tricky because of MPEG video start codes
+ which can begin in one packet and finish in
+ another packet. In the worst case, an MPEG
+ video start code could be in 4 different
+ packets. */
+ k = s->cur_frame_start_index;
+ for(i = 0; i < AV_PARSER_PTS_NB; i++) {
+ if (s->last_frame_offset >= s->cur_frame_offset[k])
+ break;
+ k = (k - 1) & (AV_PARSER_PTS_NB - 1);
+ }
+ s->last_pts = s->cur_frame_pts[k];
+ s->last_dts = s->cur_frame_dts[k];
+ }
+ if (index < 0)
+ index = 0;
+ s->cur_offset += index;
+ return index;
+}
+
+void av_parser_close(AVCodecParserContext *s)
+{
+ if (s->parser->parser_close)
+ s->parser->parser_close(s);
+ av_free(s->priv_data);
+ av_free(s);
+}
+
+/*****************************************************/
+
+//#define END_NOT_FOUND (-100)
+
+#define PICTURE_START_CODE 0x00000100
+#define SEQ_START_CODE 0x000001b3
+#define EXT_START_CODE 0x000001b5
+#define SLICE_MIN_START_CODE 0x00000101
+#define SLICE_MAX_START_CODE 0x000001af
+
+typedef struct ParseContext1{
+ ParseContext pc;
+/* XXX/FIXME PC1 vs. PC */
+ /* MPEG2 specific */
+ int frame_rate;
+ int progressive_sequence;
+ int width, height;
+
+ /* XXX: suppress that, needed by MPEG4 */
+ MpegEncContext *enc;
+ int first_picture;
+} ParseContext1;
+
+/**
+ * combines the (truncated) bitstream to a complete frame
+ * @returns -1 if no complete frame could be created
+ */
+int ff_combine_frame(ParseContext *pc, int next, uint8_t **buf, int *buf_size)
+{
+#if 0
+ if(pc->overread){
+ printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index);
+ printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]);
+ }
+#endif
+
+ /* copy overreaded bytes from last frame into buffer */
+ for(; pc->overread>0; pc->overread--){
+ pc->buffer[pc->index++]= pc->buffer[pc->overread_index++];
+ }
+
+ pc->last_index= pc->index;
+
+ /* copy into buffer end return */
+ if(next == END_NOT_FOUND){
+ pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, (*buf_size) + pc->index + FF_INPUT_BUFFER_PADDING_SIZE);
+
+ memcpy(&pc->buffer[pc->index], *buf, *buf_size);
+ pc->index += *buf_size;
+ return -1;
+ }
+
+ *buf_size=
+ pc->overread_index= pc->index + next;
+
+ /* append to buffer */
+ if(pc->index){
+ pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + FF_INPUT_BUFFER_PADDING_SIZE);
+
+ memcpy(&pc->buffer[pc->index], *buf, next + FF_INPUT_BUFFER_PADDING_SIZE );
+ pc->index = 0;
+ *buf= pc->buffer;
+ }
+
+ /* store overread bytes */
+ for(;next < 0; next++){
+ pc->state = (pc->state<<8) | pc->buffer[pc->last_index + next];
+ pc->overread++;
+ }
+
+#if 0
+ if(pc->overread){
+ printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index);
+ printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]);
+ }
+#endif
+
+ return 0;
+}
+
+static int find_start_code(const uint8_t **pbuf_ptr, const uint8_t *buf_end)
+{
+ const uint8_t *buf_ptr;
+ unsigned int state=0xFFFFFFFF, v;
+ int val;
+
+ buf_ptr = *pbuf_ptr;
+ while (buf_ptr < buf_end) {
+ v = *buf_ptr++;
+ if (state == 0x000001) {
+ state = ((state << 8) | v) & 0xffffff;
+ val = state;
+ goto found;
+ }
+ state = ((state << 8) | v) & 0xffffff;
+ }
+ val = -1;
+ found:
+ *pbuf_ptr = buf_ptr;
+ return val;
+}
+
+/* XXX: merge with libavcodec ? */
+#define MPEG1_FRAME_RATE_BASE 1001
+
+static const int frame_rate_tab[16] = {
+ 0,
+ 24000,
+ 24024,
+ 25025,
+ 30000,
+ 30030,
+ 50050,
+ 60000,
+ 60060,
+ // Xing's 15fps: (9)
+ 15015,
+ // libmpeg3's "Unofficial economy rates": (10-13)
+ 5005,
+ 10010,
+ 12012,
+ 15015,
+ // random, just to avoid segfault !never encode these
+ 25025,
+ 25025,
+};
+
+static void mpegvideo_extract_headers(AVCodecParserContext *s,
+ AVCodecContext *avctx,
+ const uint8_t *buf, int buf_size)
+{
+ ParseContext1 *pc = s->priv_data;
+ const uint8_t *buf_end;
+ int32_t start_code;
+ int frame_rate_index, ext_type, bytes_left;
+ int frame_rate_ext_n, frame_rate_ext_d;
+ int top_field_first, repeat_first_field, progressive_frame;
+ int horiz_size_ext, vert_size_ext;
+
+ s->repeat_pict = 0;
+ buf_end = buf + buf_size;
+ while (buf < buf_end) {
+ start_code = find_start_code(&buf, buf_end);
+ bytes_left = buf_end - buf;
+ switch(start_code) {
+ case PICTURE_START_CODE:
+ if (bytes_left >= 2) {
+ s->pict_type = (buf[1] >> 3) & 7;
+ }
+ break;
+ case SEQ_START_CODE:
+ if (bytes_left >= 4) {
+ pc->width = avctx->width = (buf[0] << 4) | (buf[1] >> 4);
+ pc->height = avctx->height = ((buf[1] & 0x0f) << 8) | buf[2];
+ frame_rate_index = buf[3] & 0xf;
+ pc->frame_rate = avctx->frame_rate = frame_rate_tab[frame_rate_index];
+ avctx->frame_rate_base = MPEG1_FRAME_RATE_BASE;
+ avctx->codec_id = CODEC_ID_MPEG1VIDEO;
+ avctx->sub_id = 1;
+ }
+ break;
+ case EXT_START_CODE:
+ if (bytes_left >= 1) {
+ ext_type = (buf[0] >> 4);
+ switch(ext_type) {
+ case 0x1: /* sequence extension */
+ if (bytes_left >= 6) {
+ horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7);
+ vert_size_ext = (buf[2] >> 5) & 3;
+ frame_rate_ext_n = (buf[5] >> 5) & 3;
+ frame_rate_ext_d = (buf[5] & 0x1f);
+ pc->progressive_sequence = buf[1] & (1 << 3);
+
+ avctx->width = pc->width | (horiz_size_ext << 12);
+ avctx->height = pc->height | (vert_size_ext << 12);
+ avctx->frame_rate = pc->frame_rate * (frame_rate_ext_n + 1);
+ avctx->frame_rate_base = MPEG1_FRAME_RATE_BASE * (frame_rate_ext_d + 1);
+ avctx->codec_id = CODEC_ID_MPEG2VIDEO;
+ avctx->sub_id = 2; /* forces MPEG2 */
+ }
+ break;
+ case 0x8: /* picture coding extension */
+ if (bytes_left >= 5) {
+ top_field_first = buf[3] & (1 << 7);
+ repeat_first_field = buf[3] & (1 << 1);
+ progressive_frame = buf[4] & (1 << 7);
+
+ /* check if we must repeat the frame */
+ if (repeat_first_field) {
+ if (pc->progressive_sequence) {
+ if (top_field_first)
+ s->repeat_pict = 4;
+ else
+ s->repeat_pict = 2;
+ } else if (progressive_frame) {
+ s->repeat_pict = 1;
+ }
+ }
+ }
+ break;
+ }
+ }
+ break;
+ case -1:
+ goto the_end;
+ default:
+ /* we stop parsing when we encounter a slice. It ensures
+ that this function takes a negligible amount of time */
+ if (start_code >= SLICE_MIN_START_CODE &&
+ start_code <= SLICE_MAX_START_CODE)
+ goto the_end;
+ break;
+ }
+ }
+ the_end: ;
+}
+
+static int mpegvideo_parse(AVCodecParserContext *s,
+ AVCodecContext *avctx,
+ uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size)
+{
+ ParseContext1 *pc1 = s->priv_data;
+ ParseContext *pc= &pc1->pc;
+ int next;
+
+ next= ff_mpeg1_find_frame_end(pc, buf, buf_size);
+
+ if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
+ *poutbuf = NULL;
+ *poutbuf_size = 0;
+ return buf_size;
+ }
+ /* we have a full frame : we just parse the first few MPEG headers
+ to have the full timing information. The time take by this
+ function should be negligible for uncorrupted streams */
+ mpegvideo_extract_headers(s, avctx, buf, buf_size);
+#if 0
+ printf("pict_type=%d frame_rate=%0.3f repeat_pict=%d\n",
+ s->pict_type, (double)avctx->frame_rate / avctx->frame_rate_base, s->repeat_pict);
+#endif
+
+ *poutbuf = (uint8_t *)buf;
+ *poutbuf_size = buf_size;
+ return next;
+}
+
+void ff_parse_close(AVCodecParserContext *s)
+{
+ ParseContext *pc = s->priv_data;
+
+ av_free(pc->buffer);
+}
+
+static void parse1_close(AVCodecParserContext *s)
+{
+ ParseContext1 *pc1 = s->priv_data;
+
+ av_free(pc1->pc.buffer);
+ av_free(pc1->enc);
+}
+
+/*************************/
+
+/* used by parser */
+/* XXX: make it use less memory */
+static int av_mpeg4_decode_header(AVCodecParserContext *s1,
+ AVCodecContext *avctx,
+ const uint8_t *buf, int buf_size)
+{
+ ParseContext1 *pc = s1->priv_data;
+ MpegEncContext *s = pc->enc;
+ GetBitContext gb1, *gb = &gb1;
+ int ret;
+
+ s->avctx = avctx;
+ s->current_picture_ptr = &s->current_picture;
+
+ if (avctx->extradata_size && pc->first_picture){
+ init_get_bits(gb, avctx->extradata, avctx->extradata_size*8);
+ ret = ff_mpeg4_decode_picture_header(s, gb);
+ }
+
+ init_get_bits(gb, buf, 8 * buf_size);
+ ret = ff_mpeg4_decode_picture_header(s, gb);
+ if (s->width) {
+ avctx->width = s->width;
+ avctx->height = s->height;
+ }
+ pc->first_picture = 0;
+ return ret;
+}
+
+int mpeg4video_parse_init(AVCodecParserContext *s)
+{
+ ParseContext1 *pc = s->priv_data;
+
+ pc->enc = av_mallocz(sizeof(MpegEncContext));
+ if (!pc->enc)
+ return -1;
+ pc->first_picture = 1;
+ return 0;
+}
+
+static int mpeg4video_parse(AVCodecParserContext *s,
+ AVCodecContext *avctx,
+ uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size)
+{
+ ParseContext *pc = s->priv_data;
+ int next;
+
+ next= ff_mpeg4_find_frame_end(pc, buf, buf_size);
+
+ if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
+ *poutbuf = NULL;
+ *poutbuf_size = 0;
+ return buf_size;
+ }
+ av_mpeg4_decode_header(s, avctx, buf, buf_size);
+
+ *poutbuf = (uint8_t *)buf;
+ *poutbuf_size = buf_size;
+ return next;
+}
+
+/*************************/
+
+typedef struct MpegAudioParseContext {
+ uint8_t inbuf[MPA_MAX_CODED_FRAME_SIZE]; /* input buffer */
+ uint8_t *inbuf_ptr;
+ int frame_size;
+ int free_format_frame_size;
+ int free_format_next_header;
+} MpegAudioParseContext;
+
+#define MPA_HEADER_SIZE 4
+
+/* header + layer + bitrate + freq + lsf/mpeg25 */
+#define SAME_HEADER_MASK \
+ (0xffe00000 | (3 << 17) | (0xf << 12) | (3 << 10) | (3 << 19))
+
+static int mpegaudio_parse_init(AVCodecParserContext *s1)
+{
+ MpegAudioParseContext *s = s1->priv_data;
+ s->inbuf_ptr = s->inbuf;
+ return 0;
+}
+
+static int mpegaudio_parse(AVCodecParserContext *s1,
+ AVCodecContext *avctx,
+ uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size)
+{
+ MpegAudioParseContext *s = s1->priv_data;
+ int len, ret;
+ uint32_t header;
+ const uint8_t *buf_ptr;
+
+ *poutbuf = NULL;
+ *poutbuf_size = 0;
+ buf_ptr = buf;
+ while (buf_size > 0) {
+ len = s->inbuf_ptr - s->inbuf;
+ if (s->frame_size == 0) {
+ /* special case for next header for first frame in free
+ format case (XXX: find a simpler method) */
+ if (s->free_format_next_header != 0) {
+ s->inbuf[0] = s->free_format_next_header >> 24;
+ s->inbuf[1] = s->free_format_next_header >> 16;
+ s->inbuf[2] = s->free_format_next_header >> 8;
+ s->inbuf[3] = s->free_format_next_header;
+ s->inbuf_ptr = s->inbuf + 4;
+ s->free_format_next_header = 0;
+ goto got_header;
+ }
+ /* no header seen : find one. We need at least MPA_HEADER_SIZE
+ bytes to parse it */
+ len = MPA_HEADER_SIZE - len;
+ if (len > buf_size)
+ len = buf_size;
+ if (len > 0) {
+ memcpy(s->inbuf_ptr, buf_ptr, len);
+ buf_ptr += len;
+ buf_size -= len;
+ s->inbuf_ptr += len;
+ }
+ if ((s->inbuf_ptr - s->inbuf) >= MPA_HEADER_SIZE) {
+ got_header:
+ header = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) |
+ (s->inbuf[2] << 8) | s->inbuf[3];
+
+ ret = mpa_decode_header(avctx, header);
+ if (ret < 0) {
+ /* no sync found : move by one byte (inefficient, but simple!) */
+ memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1);
+ s->inbuf_ptr--;
+ dprintf("skip %x\n", header);
+ /* reset free format frame size to give a chance
+ to get a new bitrate */
+ s->free_format_frame_size = 0;
+ } else {
+ s->frame_size = ret;
+#if 0
+ /* free format: prepare to compute frame size */
+ if (decode_header(s, header) == 1) {
+ s->frame_size = -1;
+ }
+#endif
+ }
+ }
+ } else
+#if 0
+ if (s->frame_size == -1) {
+ /* free format : find next sync to compute frame size */
+ len = MPA_MAX_CODED_FRAME_SIZE - len;
+ if (len > buf_size)
+ len = buf_size;
+ if (len == 0) {
+ /* frame too long: resync */
+ s->frame_size = 0;
+ memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1);
+ s->inbuf_ptr--;
+ } else {
+ uint8_t *p, *pend;
+ uint32_t header1;
+ int padding;
+
+ memcpy(s->inbuf_ptr, buf_ptr, len);
+ /* check for header */
+ p = s->inbuf_ptr - 3;
+ pend = s->inbuf_ptr + len - 4;
+ while (p <= pend) {
+ header = (p[0] << 24) | (p[1] << 16) |
+ (p[2] << 8) | p[3];
+ header1 = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) |
+ (s->inbuf[2] << 8) | s->inbuf[3];
+ /* check with high probability that we have a
+ valid header */
+ if ((header & SAME_HEADER_MASK) ==
+ (header1 & SAME_HEADER_MASK)) {
+ /* header found: update pointers */
+ len = (p + 4) - s->inbuf_ptr;
+ buf_ptr += len;
+ buf_size -= len;
+ s->inbuf_ptr = p;
+ /* compute frame size */
+ s->free_format_next_header = header;
+ s->free_format_frame_size = s->inbuf_ptr - s->inbuf;
+ padding = (header1 >> 9) & 1;
+ if (s->layer == 1)
+ s->free_format_frame_size -= padding * 4;
+ else
+ s->free_format_frame_size -= padding;
+ dprintf("free frame size=%d padding=%d\n",
+ s->free_format_frame_size, padding);
+ decode_header(s, header1);
+ goto next_data;
+ }
+ p++;
+ }
+ /* not found: simply increase pointers */
+ buf_ptr += len;
+ s->inbuf_ptr += len;
+ buf_size -= len;
+ }
+ } else
+#endif
+ if (len < s->frame_size) {
+ if (s->frame_size > MPA_MAX_CODED_FRAME_SIZE)
+ s->frame_size = MPA_MAX_CODED_FRAME_SIZE;
+ len = s->frame_size - len;
+ if (len > buf_size)
+ len = buf_size;
+ memcpy(s->inbuf_ptr, buf_ptr, len);
+ buf_ptr += len;
+ s->inbuf_ptr += len;
+ buf_size -= len;
+ }
+ // next_data:
+ if (s->frame_size > 0 &&
+ (s->inbuf_ptr - s->inbuf) >= s->frame_size) {
+ *poutbuf = s->inbuf;
+ *poutbuf_size = s->inbuf_ptr - s->inbuf;
+ s->inbuf_ptr = s->inbuf;
+ s->frame_size = 0;
+ break;
+ }
+ }
+ return buf_ptr - buf;
+}
+
+#ifdef CONFIG_AC3
+extern int a52_syncinfo (const uint8_t * buf, int * flags,
+ int * sample_rate, int * bit_rate);
+
+typedef struct AC3ParseContext {
+ uint8_t inbuf[4096]; /* input buffer */
+ uint8_t *inbuf_ptr;
+ int frame_size;
+ int flags;
+} AC3ParseContext;
+
+#define AC3_HEADER_SIZE 7
+#define A52_LFE 16
+
+static int ac3_parse_init(AVCodecParserContext *s1)
+{
+ AC3ParseContext *s = s1->priv_data;
+ s->inbuf_ptr = s->inbuf;
+ return 0;
+}
+
+static int ac3_parse(AVCodecParserContext *s1,
+ AVCodecContext *avctx,
+ uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size)
+{
+ AC3ParseContext *s = s1->priv_data;
+ const uint8_t *buf_ptr;
+ int len, sample_rate, bit_rate;
+ static const int ac3_channels[8] = {
+ 2, 1, 2, 3, 3, 4, 4, 5
+ };
+
+ *poutbuf = NULL;
+ *poutbuf_size = 0;
+
+ buf_ptr = buf;
+ while (buf_size > 0) {
+ len = s->inbuf_ptr - s->inbuf;
+ if (s->frame_size == 0) {
+ /* no header seen : find one. We need at least 7 bytes to parse it */
+ len = AC3_HEADER_SIZE - len;
+ if (len > buf_size)
+ len = buf_size;
+ memcpy(s->inbuf_ptr, buf_ptr, len);
+ buf_ptr += len;
+ s->inbuf_ptr += len;
+ buf_size -= len;
+ if ((s->inbuf_ptr - s->inbuf) == AC3_HEADER_SIZE) {
+ len = a52_syncinfo(s->inbuf, &s->flags, &sample_rate, &bit_rate);
+ if (len == 0) {
+ /* no sync found : move by one byte (inefficient, but simple!) */
+ memmove(s->inbuf, s->inbuf + 1, AC3_HEADER_SIZE - 1);
+ s->inbuf_ptr--;
+ } else {
+ s->frame_size = len;
+ /* update codec info */
+ avctx->sample_rate = sample_rate;
+ /* set channels,except if the user explicitly requests 1 or 2 channels, XXX/FIXME this is a bit ugly */
+ if(avctx->channels!=1 && avctx->channels!=2){
+ avctx->channels = ac3_channels[s->flags & 7];
+ if (s->flags & A52_LFE)
+ avctx->channels++;
+ }
+ avctx->bit_rate = bit_rate;
+ avctx->frame_size = 6 * 256;
+ }
+ }
+ } else if (len < s->frame_size) {
+ len = s->frame_size - len;
+ if (len > buf_size)
+ len = buf_size;
+
+ memcpy(s->inbuf_ptr, buf_ptr, len);
+ buf_ptr += len;
+ s->inbuf_ptr += len;
+ buf_size -= len;
+ } else {
+ *poutbuf = s->inbuf;
+ *poutbuf_size = s->frame_size;
+ s->inbuf_ptr = s->inbuf;
+ s->frame_size = 0;
+ break;
+ }
+ }
+ return buf_ptr - buf;
+}
+#endif
+
+AVCodecParser mpegvideo_parser = {
+ { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO },
+ sizeof(ParseContext1),
+ NULL,
+ mpegvideo_parse,
+ parse1_close,
+};
+
+AVCodecParser mpeg4video_parser = {
+ { CODEC_ID_MPEG4 },
+ sizeof(ParseContext1),
+ mpeg4video_parse_init,
+ mpeg4video_parse,
+ parse1_close,
+};
+
+AVCodecParser mpegaudio_parser = {
+ { CODEC_ID_MP2, CODEC_ID_MP3 },
+ sizeof(MpegAudioParseContext),
+ mpegaudio_parse_init,
+ mpegaudio_parse,
+ NULL,
+};
+
+#ifdef CONFIG_AC3
+AVCodecParser ac3_parser = {
+ { CODEC_ID_AC3 },
+ sizeof(AC3ParseContext),
+ ac3_parse_init,
+ ac3_parse,
+ NULL,
+};
+#endif
diff --git a/src/libffmpeg/libavcodec/ppc/dsputil_altivec.c b/src/libffmpeg/libavcodec/ppc/dsputil_altivec.c
index 1bc6fb009..ff6e870b7 100644
--- a/src/libffmpeg/libavcodec/ppc/dsputil_altivec.c
+++ b/src/libffmpeg/libavcodec/ppc/dsputil_altivec.c
@@ -1302,52 +1302,32 @@ POWERPC_PERF_STOP_COUNT(altivec_put_no_rnd_pixels16_xy2_num, 1);
#endif /* ALTIVEC_USE_REFERENCE_C_CODE */
}
+#if (__GNUC__ * 100 + __GNUC_MINOR__ >= 330)
int hadamard8_diff8x8_altivec(/*MpegEncContext*/ void *s, uint8_t *dst, uint8_t *src, int stride, int h){
POWERPC_PERF_DECLARE(altivec_hadamard8_diff8x8_num, 1);
int sum;
POWERPC_PERF_START_COUNT(altivec_hadamard8_diff8x8_num, 1);
register const_vector unsigned char vzero = (const_vector unsigned char)vec_splat_u8(0);
register vector signed short temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
-#ifdef CONFIG_DARWIN
{
- register const_vector signed short vprod1 = (const_vector signed short)( 1,-1, 1,-1, 1,-1, 1,-1);
- register const_vector signed short vprod2 = (const_vector signed short)( 1, 1,-1,-1, 1, 1,-1,-1);
- register const_vector signed short vprod3 = (const_vector signed short)( 1, 1, 1, 1,-1,-1,-1,-1);
+ register const_vector signed short vprod1 = (const_vector signed short)AVV( 1,-1, 1,-1, 1,-1, 1,-1);
+ register const_vector signed short vprod2 = (const_vector signed short)AVV( 1, 1,-1,-1, 1, 1,-1,-1);
+ register const_vector signed short vprod3 = (const_vector signed short)AVV( 1, 1, 1, 1,-1,-1,-1,-1);
register const_vector unsigned char perm1 = (const_vector unsigned char)
- (0x02, 0x03, 0x00, 0x01,
+ AVV(0x02, 0x03, 0x00, 0x01,
0x06, 0x07, 0x04, 0x05,
0x0A, 0x0B, 0x08, 0x09,
0x0E, 0x0F, 0x0C, 0x0D);
register const_vector unsigned char perm2 = (const_vector unsigned char)
- (0x04, 0x05, 0x06, 0x07,
+ AVV(0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03,
0x0C, 0x0D, 0x0E, 0x0F,
0x08, 0x09, 0x0A, 0x0B);
register const_vector unsigned char perm3 = (const_vector unsigned char)
- (0x08, 0x09, 0x0A, 0x0B,
+ AVV(0x08, 0x09, 0x0A, 0x0B,
0x0C, 0x0D, 0x0E, 0x0F,
0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07);
-#else
- register const_vector signed short vprod1 = (const_vector signed short){ 1,-1, 1,-1, 1,-1, 1,-1};
- register const_vector signed short vprod2 = (const_vector signed short){ 1, 1,-1,-1, 1, 1,-1,-1};
- register const_vector signed short vprod3 = (const_vector signed short){ 1, 1, 1, 1,-1,-1,-1,-1};
- register const_vector unsigned char perm1 = (const_vector unsigned char)
- {0x02, 0x03, 0x00, 0x01,
- 0x06, 0x07, 0x04, 0x05,
- 0x0A, 0x0B, 0x08, 0x09,
- 0x0E, 0x0F, 0x0C, 0x0D};
- register const_vector unsigned char perm2 = (const_vector unsigned char)
- {0x04, 0x05, 0x06, 0x07,
- 0x00, 0x01, 0x02, 0x03,
- 0x0C, 0x0D, 0x0E, 0x0F,
- 0x08, 0x09, 0x0A, 0x0B};
- register const_vector unsigned char perm3 = (const_vector unsigned char)
- {0x08, 0x09, 0x0A, 0x0B,
- 0x0C, 0x0D, 0x0E, 0x0F,
- 0x00, 0x01, 0x02, 0x03,
- 0x04, 0x05, 0x06, 0x07};
-#endif
#define ONEITERBUTTERFLY(i, res) \
{ \
@@ -1475,45 +1455,25 @@ static int hadamard8_diff16x8_altivec(/*MpegEncContext*/ void *s, uint8_t *dst,
temp7S asm ("v15");
register const_vector unsigned char vzero asm ("v31")= (const_vector unsigned char)vec_splat_u8(0);
{
-#ifdef CONFIG_DARWIN
- register const_vector signed short vprod1 asm ("v16")= (const_vector signed short)( 1,-1, 1,-1, 1,-1, 1,-1);
- register const_vector signed short vprod2 asm ("v17")= (const_vector signed short)( 1, 1,-1,-1, 1, 1,-1,-1);
- register const_vector signed short vprod3 asm ("v18")= (const_vector signed short)( 1, 1, 1, 1,-1,-1,-1,-1);
+ register const_vector signed short vprod1 asm ("v16")= (const_vector signed short)AVV( 1,-1, 1,-1, 1,-1, 1,-1);
+ register const_vector signed short vprod2 asm ("v17")= (const_vector signed short)AVV( 1, 1,-1,-1, 1, 1,-1,-1);
+ register const_vector signed short vprod3 asm ("v18")= (const_vector signed short)AVV( 1, 1, 1, 1,-1,-1,-1,-1);
register const_vector unsigned char perm1 asm ("v19")= (const_vector unsigned char)
- (0x02, 0x03, 0x00, 0x01,
+ AVV(0x02, 0x03, 0x00, 0x01,
0x06, 0x07, 0x04, 0x05,
0x0A, 0x0B, 0x08, 0x09,
0x0E, 0x0F, 0x0C, 0x0D);
register const_vector unsigned char perm2 asm ("v20")= (const_vector unsigned char)
- (0x04, 0x05, 0x06, 0x07,
+ AVV(0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03,
0x0C, 0x0D, 0x0E, 0x0F,
0x08, 0x09, 0x0A, 0x0B);
register const_vector unsigned char perm3 asm ("v21")= (const_vector unsigned char)
- (0x08, 0x09, 0x0A, 0x0B,
+ AVV(0x08, 0x09, 0x0A, 0x0B,
0x0C, 0x0D, 0x0E, 0x0F,
0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07);
-#else
- register const_vector signed short vprod1 = (const_vector signed short){ 1,-1, 1,-1, 1,-1, 1,-1};
- register const_vector signed short vprod2 = (const_vector signed short){ 1, 1,-1,-1, 1, 1,-1,-1};
- register const_vector signed short vprod3 = (const_vector signed short){ 1, 1, 1, 1,-1,-1,-1,-1};
- register const_vector unsigned char perm1 = (const_vector unsigned char)
- {0x02, 0x03, 0x00, 0x01,
- 0x06, 0x07, 0x04, 0x05,
- 0x0A, 0x0B, 0x08, 0x09,
- 0x0E, 0x0F, 0x0C, 0x0D};
- register const_vector unsigned char perm2 = (const_vector unsigned char)
- {0x04, 0x05, 0x06, 0x07,
- 0x00, 0x01, 0x02, 0x03,
- 0x0C, 0x0D, 0x0E, 0x0F,
- 0x08, 0x09, 0x0A, 0x0B};
- register const_vector unsigned char perm3 = (const_vector unsigned char)
- {0x08, 0x09, 0x0A, 0x0B,
- 0x0C, 0x0D, 0x0E, 0x0F,
- 0x00, 0x01, 0x02, 0x03,
- 0x04, 0x05, 0x06, 0x07};
-#endif
+
#define ONEITERBUTTERFLY(i, res1, res2) \
{ \
register vector unsigned char src1 asm ("v22"), src2 asm ("v23"); \
@@ -1652,6 +1612,7 @@ POWERPC_PERF_START_COUNT(altivec_hadamard8_diff16_num, 1);
POWERPC_PERF_STOP_COUNT(altivec_hadamard8_diff16_num, 1);
return score;
}
+#endif
int has_altivec(void)
{
diff --git a/src/libffmpeg/libavcodec/ppc/dsputil_ppc.c b/src/libffmpeg/libavcodec/ppc/dsputil_ppc.c
index b70de7328..55a4587f9 100644
--- a/src/libffmpeg/libavcodec/ppc/dsputil_ppc.c
+++ b/src/libffmpeg/libavcodec/ppc/dsputil_ppc.c
@@ -279,8 +279,10 @@ void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx)
c->gmc1 = gmc1_altivec;
+#if (__GNUC__ * 100 + __GNUC_MINOR__ >= 330)
c->hadamard8_diff[0] = hadamard8_diff16_altivec;
c->hadamard8_diff[1] = hadamard8_diff8x8_altivec;
+#endif
#ifdef CONFIG_ENCODERS
if (avctx->dct_algo == FF_DCT_AUTO ||
diff --git a/src/libffmpeg/libavcodec/svq1.c b/src/libffmpeg/libavcodec/svq1.c
index 781194f03..8fec2a31e 100644
--- a/src/libffmpeg/libavcodec/svq1.c
+++ b/src/libffmpeg/libavcodec/svq1.c
@@ -17,14 +17,18 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
+ * (SVQ1 Decoder)
* Ported to mplayer by Arpi <arpi@thot.banki.hu>
* Ported to libavcodec by Nick Kurshev <nickols_k@mail.ru>
*
+ * SVQ1 Encoder (c) 2004 Mike Melanson <melanson@pcisys.net>
*/
/**
* @file svq1.c
- * Sorenson Vector Quantizer #1 (SVQ1) video decoder.
+ * Sorenson Vector Quantizer #1 (SVQ1) video codec.
+ * For more information of the SVQ1 algorithm, visit:
+ * http://www.pcisys.net/~melanson/codecs/
*/
@@ -33,6 +37,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <limits.h>
#include "common.h"
#include "avcodec.h"
@@ -40,6 +45,9 @@
#include "mpegvideo.h"
#include "bswap.h"
+#undef NDEBUG
+#include <assert.h>
+
static VLC svq1_block_type;
static VLC svq1_motion_component;
static VLC svq1_intra_multistage[6];
@@ -54,6 +62,34 @@ static VLC svq1_inter_mean;
#define SVQ1_BLOCK_INTER_4V 2
#define SVQ1_BLOCK_INTRA 3
+typedef struct SVQ1Context {
+
+ AVCodecContext *avctx;
+ DSPContext dsp;
+ AVFrame picture;
+ AVFrame current_picture;
+ AVFrame last_picture;
+ PutBitContext pb;
+ GetBitContext gb;
+
+ PutBitContext reorder_pb[6]; //why ooh why this sick breadth first order, everything is slower and more complex
+
+ int frame_width;
+ int frame_height;
+
+ /* Y plane block dimensions */
+ int y_block_width;
+ int y_block_height;
+
+ /* U & V plane (C planes) block dimensions */
+ int c_block_width;
+ int c_block_height;
+
+ unsigned char *c_plane;
+
+ int64_t rd_total;
+} SVQ1Context;
+
/* motion vector (prediction) */
typedef struct svq1_pmv_s {
int x;
@@ -243,7 +279,7 @@ static int svq1_decode_block_intra (GetBitContext *bitbuf, uint8_t *pixels, int
if ((stages > 0) && (level >= 4)) {
#ifdef DEBUG_SVQ1
- printf("Error (svq1_decode_block_intra): invalid vector: stages=%i level=%i\n",stages,level);
+ av_log(s->avctx, AV_LOG_INFO, "Error (svq1_decode_block_intra): invalid vector: stages=%i level=%i\n",stages,level);
#endif
return -1; /* invalid vector */
}
@@ -293,7 +329,7 @@ static int svq1_decode_block_non_intra (GetBitContext *bitbuf, uint8_t *pixels,
if ((stages > 0) && (level >= 4)) {
#ifdef DEBUG_SVQ1
- printf("Error (svq1_decode_block_non_intra): invalid vector: stages=%i level=%i\n",stages,level);
+ av_log(s->avctx, AV_LOG_INFO, "Error (svq1_decode_block_non_intra): invalid vector: stages=%i level=%i\n",stages,level);
#endif
return -1; /* invalid vector */
}
@@ -381,7 +417,7 @@ static int svq1_motion_inter_block (MpegEncContext *s, GetBitContext *bitbuf,
int w= (s->width+15)&~15;
int h= (s->height+15)&~15;
if(x + (mv.x >> 1)<0 || y + (mv.y >> 1)<0 || x + (mv.x >> 1) + 16 > w || y + (mv.y >> 1) + 16> h)
- printf("%d %d %d %d\n", x, y, x + (mv.x >> 1), y + (mv.y >> 1));
+ av_log(s->avctx, AV_LOG_INFO, "%d %d %d %d\n", x, y, x + (mv.x >> 1), y + (mv.y >> 1));
#endif
src = &previous[(x + (mv.x >> 1)) + (y + (mv.y >> 1))*pitch];
@@ -464,7 +500,7 @@ static int svq1_motion_inter_4v_block (MpegEncContext *s, GetBitContext *bitbuf,
int w= (s->width+15)&~15;
int h= (s->height+15)&~15;
if(x + (mvx >> 1)<0 || y + (mvy >> 1)<0 || x + (mvx >> 1) + 8 > w || y + (mvy >> 1) + 8> h)
- printf("%d %d %d %d\n", x, y, x + (mvx >> 1), y + (mvy >> 1));
+ av_log(s->avctx, AV_LOG_INFO, "%d %d %d %d\n", x, y, x + (mvx >> 1), y + (mvy >> 1));
#endif
src = &previous[(x + (mvx >> 1)) + (y + (mvy >> 1))*pitch];
dst = current;
@@ -512,7 +548,7 @@ static int svq1_decode_delta_block (MpegEncContext *s, GetBitContext *bitbuf,
if (result != 0)
{
#ifdef DEBUG_SVQ1
- printf("Error in svq1_motion_inter_block %i\n",result);
+ av_log(s->avctx, AV_LOG_INFO, "Error in svq1_motion_inter_block %i\n",result);
#endif
break;
}
@@ -525,7 +561,7 @@ static int svq1_decode_delta_block (MpegEncContext *s, GetBitContext *bitbuf,
if (result != 0)
{
#ifdef DEBUG_SVQ1
- printf("Error in svq1_motion_inter_4v_block %i\n",result);
+ av_log(s->avctx, AV_LOG_INFO, "Error in svq1_motion_inter_4v_block %i\n",result);
#endif
break;
}
@@ -604,7 +640,7 @@ static int svq1_decode_frame_header (GetBitContext *bitbuf,MpegEncContext *s) {
csum = svq1_packet_checksum ((uint8_t *)bitbuf->buffer, bitbuf->size_in_bits>>3, csum);
-// printf ("%s checksum (%02x) for packet data\n",
+// av_log(s->avctx, AV_LOG_INFO, "%s checksum (%02x) for packet data\n",
// (csum == 0) ? "correct" : "incorrect", csum);
}
@@ -692,13 +728,13 @@ static int svq1_decode_frame(AVCodecContext *avctx,
if (result != 0)
{
#ifdef DEBUG_SVQ1
- printf("Error in svq1_decode_frame_header %i\n",result);
+ av_log(s->avctx, AV_LOG_INFO, "Error in svq1_decode_frame_header %i\n",result);
#endif
return result;
}
//FIXME this avoids some confusion for "B frames" without 2 references
- //this should be removed after libavcodec can handle more flaxible picture types & ordering
+ //this should be removed after libavcodec can handle more flexible picture types & ordering
if(s->pict_type==B_TYPE && s->last_picture_ptr==NULL) return buf_size;
if(avctx->hurry_up && s->pict_type==B_TYPE) return buf_size;
@@ -735,9 +771,9 @@ static int svq1_decode_frame(AVCodecContext *avctx,
result = svq1_decode_block_intra (&s->gb, &current[x], linesize);
if (result != 0)
{
-#ifdef DEBUG_SVQ1
- printf("Error in svq1_decode_block %i (keyframe)\n",result);
-#endif
+//#ifdef DEBUG_SVQ1
+ av_log(s->avctx, AV_LOG_INFO, "Error in svq1_decode_block %i (keyframe)\n",result);
+//#endif
return result;
}
}
@@ -755,7 +791,7 @@ static int svq1_decode_frame(AVCodecContext *avctx,
if (result != 0)
{
#ifdef DEBUG_SVQ1
- printf("Error in svq1_decode_delta_block %i\n",result);
+ av_log(s->avctx, AV_LOG_INFO, "Error in svq1_decode_delta_block %i\n",result);
#endif
return result;
}
@@ -791,6 +827,7 @@ static int svq1_decode_init(AVCodecContext *avctx)
s->codec_id= avctx->codec->id;
avctx->pix_fmt = PIX_FMT_YUV410P;
avctx->has_b_frames= 1; // not true, but DP frames and these behave like unidirectional b frames
+ s->flags= avctx->flags;
if (MPV_common_init(s) < 0) return -1;
init_vlc(&svq1_block_type, 2, 4,
@@ -798,8 +835,8 @@ static int svq1_decode_init(AVCodecContext *avctx)
&svq1_block_type_vlc[0][0], 2, 1);
init_vlc(&svq1_motion_component, 7, 65,
- &svq1_motion_component_vlc[0][1], 4, 2,
- &svq1_motion_component_vlc[0][0], 4, 2);
+ &svq1_motion_component_vlc[0][1], 2, 1,
+ &svq1_motion_component_vlc[0][0], 2, 1);
for (i = 0; i < 6; i++) {
init_vlc(&svq1_intra_multistage[i], 3, 8,
@@ -829,6 +866,912 @@ static int svq1_decode_end(AVCodecContext *avctx)
return 0;
}
+static void svq1_write_header(SVQ1Context *s, int frame_type)
+{
+ /* frame code */
+ put_bits(&s->pb, 22, 0x20);
+
+ /* temporal reference (sure hope this is a "don't care") */
+ put_bits(&s->pb, 8, 0x00);
+
+ /* frame type */
+ put_bits(&s->pb, 2, frame_type - 1);
+
+ if (frame_type == I_TYPE) {
+
+ /* no checksum since frame code is 0x20 */
+
+ /* no embedded string either */
+
+ /* output 5 unknown bits (2 + 2 + 1) */
+ put_bits(&s->pb, 5, 0);
+
+ /* forget about matching up resolutions, just use the free-form
+ * resolution code (7) for now */
+ put_bits(&s->pb, 3, 7);
+ put_bits(&s->pb, 12, s->frame_width);
+ put_bits(&s->pb, 12, s->frame_height);
+
+ }
+
+ /* no checksum or extra data (next 2 bits get 0) */
+ put_bits(&s->pb, 2, 0);
+}
+
+int level_sizes[6] = { 8, 16, 32, 64, 128, 256 };
+int level_log2_sizes[6] = { 3, 4, 5, 6, 7, 8 };
+
+#define IABS(x) ((x < 0) ? (-(x)) : x)
+
+
+
+//#define USE_MAD_ALGORITHM
+
+#ifdef USE_MAD_ALGORITHM
+
+#define QUALITY_THRESHOLD 100
+#define THRESHOLD_MULTIPLIER 0.6
+
+/* This function calculates vector differences using mean absolute
+ * difference (MAD). */
+
+static int encode_vector(SVQ1Context *s, unsigned char *vector,
+ unsigned int level, int threshold)
+{
+ int i, j, k;
+ int mean;
+ signed short work_vector[256];
+ int best_codebook;
+ int best_score;
+ int multistage_codebooks[6];
+ int number_of_stages = 0;
+ int8_t *current_codebook;
+ int total_deviation;
+ int ret;
+
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, " ** recursive entry point: encoding level %d vector at threshold %d\n",
+ level, threshold);
+#endif
+ if (level > 5) {
+ av_log(s->avctx, AV_LOG_INFO, " help! level %d > 5\n", level);
+ return 0;
+ }
+
+#ifdef DEBUG_SVQ1
+for (i = 0; i < level_sizes[level]; i++)
+ av_log(s->avctx, AV_LOG_INFO, " %02X", vector[i]);
+av_log(s->avctx, AV_LOG_INFO, "\n");
+#endif
+
+ /* calculate the mean */
+ mean = 0;
+ for (i = 0; i < level_sizes[level]; i++)
+ mean += vector[i];
+ mean >>= level_log2_sizes[level];
+
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, " vector mean = 0x%02X\n", mean);
+#endif
+
+ /* remove the mean from the vector */
+ total_deviation = 0;
+ for (i = 0; i < level_sizes[level]; i++) {
+ work_vector[i] = (signed short)vector[i] - mean;
+ total_deviation += IABS(work_vector[i]);
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, " %d", work_vector[i]);
+#endif
+ }
+
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, "\n total deviation = %d\n", total_deviation);
+#endif
+
+ if (total_deviation < threshold) {
+
+#ifdef DEBUG_SVQ1
+ av_log(s->avctx, AV_LOG_INFO, " mean-only encoding found for level %d vector, mean = %d\n",
+ level, mean);
+#endif
+
+ /* indicate that this is the end of the subdivisions */
+ if (level > 0)
+ put_bits(&s->pb, 1, 0);
+
+ /* index 1 in the table indicates mean-only encoding */
+ put_bits(&s->pb, svq1_intra_multistage_vlc[level][1][1],
+ svq1_intra_multistage_vlc[level][1][0]);
+ put_bits(&s->pb, svq1_intra_mean_vlc[mean][1],
+ svq1_intra_mean_vlc[mean][0]);
+
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, " mean-only L%d, VLC = (0x%X, %d), mean = %d (0x%X, %d)\n",
+ level,
+ svq1_intra_multistage_vlc[level][1 + number_of_stages][0],
+ svq1_intra_multistage_vlc[level][1 + number_of_stages][1],
+ mean,
+ svq1_intra_mean_vlc[mean][0],
+ svq1_intra_mean_vlc[mean][1]);
+#endif
+
+ ret = 0;
+
+ } else {
+
+ if (level <= 3) {
+
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, " multistage VQ search...\n");
+#endif
+ /* conduct multistage VQ search, for each stage... */
+ for (i = 0; i < 6; i++) {
+
+ best_codebook = 0;
+ best_score = 0x7FFFFFFF;
+ /* for each codebook in stage */
+ for (j = 0; j < 16; j++) {
+
+ total_deviation = 0;
+ current_codebook =
+ &svq1_intra_codebooks[level]
+ [i * level_sizes[level] * 16 + j * level_sizes[level]];
+ /* calculate the total deviation for the vector */
+ for (k = 0; k < level_sizes[level]; k++) {
+ total_deviation +=
+ IABS(work_vector[k] - current_codebook[k]);
+ }
+
+ /* lowest score so far? */
+ if (total_deviation < best_score) {
+ best_score = total_deviation;
+ best_codebook = j;
+ }
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, " after %d, %d, best codebook is %d with a score of %d (score was %d)\n",
+ i, j, best_codebook, best_score, total_deviation);
+#endif
+ }
+
+ /* apply the winning codebook to the work vector and check if
+ * the vector meets the quality threshold */
+ total_deviation = 0;
+ current_codebook =
+ &svq1_intra_codebooks[level]
+ [i * level_sizes[level] * 16 + j * level_sizes[level]];
+ multistage_codebooks[number_of_stages++] = best_codebook;
+ for (j = 0; j < level_sizes[level]; j++) {
+ work_vector[j] = work_vector[j] - current_codebook[j];
+ total_deviation += IABS(work_vector[j]);
+ }
+
+ /* do not go forward with the rest of the search if an acceptable
+ * codebook combination has been found */
+ if (total_deviation < threshold)
+ break;
+ }
+ }
+
+ if ((total_deviation < threshold) || (level == 0)) {
+#ifdef DEBUG_SVQ1
+ av_log(s->avctx, AV_LOG_INFO, " level %d VQ encoding found using mean %d and codebooks", level, mean);
+ for (i = 0; i < number_of_stages; i++)
+ av_log(s->avctx, AV_LOG_INFO, " %d", multistage_codebooks[i]);
+ av_log(s->avctx, AV_LOG_INFO, "\n");
+#endif
+
+ /* indicate that this is the end of the subdivisions */
+ if (level > 0)
+ put_bits(&s->pb, 1, 0);
+
+ /* output the encoding */
+ put_bits(&s->pb,
+ svq1_intra_multistage_vlc[level][1 + number_of_stages][1],
+ svq1_intra_multistage_vlc[level][1 + number_of_stages][0]);
+ put_bits(&s->pb, svq1_intra_mean_vlc[mean][1],
+ svq1_intra_mean_vlc[mean][0]);
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, " L%d: multistage = %d (0x%X, %d), mean = %d (0x%X, %d), codebooks = ",
+ level,
+ number_of_stages,
+ svq1_intra_multistage_vlc[level][1 + number_of_stages][0],
+ svq1_intra_multistage_vlc[level][1 + number_of_stages][1],
+ mean,
+ svq1_intra_mean_vlc[mean][0],
+ svq1_intra_mean_vlc[mean][1]);
+#endif
+
+ for (i = 0; i < number_of_stages; i++)
+{
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, "%d ", multistage_codebooks[i]);
+#endif
+ put_bits(&s->pb, 4, multistage_codebooks[i]);
+}
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, "\n");
+#endif
+
+ ret = 0;
+
+ } else {
+
+ /* output a subdivision bit to the encoded stream and signal to
+ * the calling function that this vector could not be
+ * coded at the requested threshold and needs to be subdivided */
+ put_bits(&s->pb, 1, 1);
+ ret = 1;
+ }
+ }
+
+ return ret;
+}
+
+#else
+
+#define QUALITY_THRESHOLD 100
+#define THRESHOLD_MULTIPLIER 0.6
+
+/* This function calculates vector differences using mean square
+ * error (MSE). */
+
+static int encode_vector(SVQ1Context *s, unsigned char *vector,
+ unsigned int level, int threshold)
+{
+ int i, j, k;
+ int mean;
+ signed short work_vector[256];
+ int best_codebook;
+ int best_score;
+ int multistage_codebooks[6];
+ int number_of_stages = 0;
+ int8_t *current_codebook;
+ int mse;
+ int diff;
+ int ret;
+
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, " ** recursive entry point: encoding level %d vector at threshold %d\n",
+ level, threshold);
+#endif
+ if (level > 5) {
+ av_log(s->avctx, AV_LOG_INFO, " help! level %d > 5\n", level);
+ return 0;
+ }
+
+#ifdef DEBUG_SVQ1
+for (i = 0; i < level_sizes[level]; i++)
+ av_log(s->avctx, AV_LOG_INFO, " %02X", vector[i]);
+av_log(s->avctx, AV_LOG_INFO, "\n");
+#endif
+
+ /* calculate the mean */
+ mean = 0;
+ for (i = 0; i < level_sizes[level]; i++)
+ mean += vector[i];
+ mean >>= level_log2_sizes[level];
+
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, " vector mean = 0x%02X\n", mean);
+#endif
+
+ /* remove the mean from the vector and compute the resulting MSE */
+ mse = 0;
+ for (i = 0; i < level_sizes[level]; i++) {
+ work_vector[i] = (signed short)vector[i] - mean;
+ mse += (work_vector[i] * work_vector[i]);
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, " %d", work_vector[i]);
+#endif
+ }
+ mse >>= level_log2_sizes[level];
+
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, "\n MSE = %d\n", mse);
+#endif
+
+ if (mse < threshold) {
+
+#ifdef DEBUG_SVQ1
+ av_log(s->avctx, AV_LOG_INFO, " mean-only encoding found for level %d vector, mean = %d\n",
+ level, mean);
+#endif
+
+ /* indicate that this is the end of the subdivisions */
+ if (level > 0)
+ put_bits(&s->pb, 1, 0);
+
+ /* index 1 in the table indicates mean-only encoding */
+ put_bits(&s->pb, svq1_intra_multistage_vlc[level][1][1],
+ svq1_intra_multistage_vlc[level][1][0]);
+ put_bits(&s->pb, svq1_intra_mean_vlc[mean][1],
+ svq1_intra_mean_vlc[mean][0]);
+
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, " mean-only L%d, VLC = (0x%X, %d), mean = %d (0x%X, %d)\n",
+ level,
+ svq1_intra_multistage_vlc[level][1 + number_of_stages][0],
+ svq1_intra_multistage_vlc[level][1 + number_of_stages][1],
+ mean,
+ svq1_intra_mean_vlc[mean][0],
+ svq1_intra_mean_vlc[mean][1]);
+#endif
+
+ ret = 0;
+
+ } else {
+
+ if (level <= 3) {
+
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, " multistage VQ search...\n");
+#endif
+ /* conduct multistage VQ search, for each stage... */
+ for (i = 0; i < 6; i++) {
+
+ best_codebook = 0;
+ best_score = 0x7FFFFFFF;
+ /* for each codebook in stage */
+ for (j = 0; j < 16; j++) {
+
+ mse = 0;
+ current_codebook =
+ &svq1_intra_codebooks[level]
+ [i * level_sizes[level] * 16 + j * level_sizes[level]];
+ /* calculate the MSE for this vector */
+ for (k = 0; k < level_sizes[level]; k++) {
+ diff = work_vector[k] - current_codebook[k];
+ mse += (diff * diff);
+ }
+ mse >>= level_log2_sizes[level];
+
+ /* lowest score so far? */
+ if (mse < best_score) {
+ best_score = mse;
+ best_codebook = j;
+ }
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, " after %d, %d, best codebook is %d with a score of %d (score was %d)\n",
+ i, j, best_codebook, best_score, mse);
+#endif
+ }
+
+ /* apply the winning codebook to the work vector and check if
+ * the vector meets the quality threshold */
+ mse = 0;
+ current_codebook =
+ &svq1_intra_codebooks[level]
+ [i * level_sizes[level] * 16 + j * level_sizes[level]];
+ multistage_codebooks[number_of_stages++] = best_codebook;
+ for (j = 0; j < level_sizes[level]; j++) {
+ work_vector[j] = work_vector[j] - current_codebook[j];
+ mse += (work_vector[j] * work_vector[j]);
+ }
+ mse >>= level_log2_sizes[level];
+
+ /* do not go forward with the rest of the search if an acceptable
+ * codebook combination has been found */
+ if (mse < threshold)
+ break;
+ }
+ }
+
+ if ((mse < threshold) || (level == 0)) {
+#ifdef DEBUG_SVQ1
+ av_log(s->avctx, AV_LOG_INFO, " level %d VQ encoding found using mean %d and codebooks", level, mean);
+ for (i = 0; i < number_of_stages; i++)
+ av_log(s->avctx, AV_LOG_INFO, " %d", multistage_codebooks[i]);
+ av_log(s->avctx, AV_LOG_INFO, "\n");
+#endif
+
+ /* indicate that this is the end of the subdivisions */
+ if (level > 0)
+ put_bits(&s->pb, 1, 0);
+
+ /* output the encoding */
+ put_bits(&s->pb,
+ svq1_intra_multistage_vlc[level][1 + number_of_stages][1],
+ svq1_intra_multistage_vlc[level][1 + number_of_stages][0]);
+ put_bits(&s->pb, svq1_intra_mean_vlc[mean][1],
+ svq1_intra_mean_vlc[mean][0]);
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, " L%d: multistage = %d (0x%X, %d), mean = %d (0x%X, %d), codebooks = ",
+ level,
+ number_of_stages,
+ svq1_intra_multistage_vlc[level][1 + number_of_stages][0],
+ svq1_intra_multistage_vlc[level][1 + number_of_stages][1],
+ mean,
+ svq1_intra_mean_vlc[mean][0],
+ svq1_intra_mean_vlc[mean][1]);
+#endif
+
+ for (i = 0; i < number_of_stages; i++)
+{
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, "%d ", multistage_codebooks[i]);
+#endif
+ put_bits(&s->pb, 4, multistage_codebooks[i]);
+}
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, "\n");
+#endif
+
+ ret = 0;
+
+ } else {
+
+ /* output a subdivision bit to the encoded stream and signal to
+ * the calling function that this vector could not be
+ * coded at the requested threshold and needs to be subdivided */
+ put_bits(&s->pb, 1, 1);
+ ret = 1;
+ }
+ }
+
+ return ret;
+}
+#endif
+
+static int encode_block(SVQ1Context *s, uint8_t *src, uint8_t *ref, uint8_t *decoded, int stride, int level, int threshold, int lambda, int intra){
+ int count, y, x, i, j, split, best_mean, best_score, best_count;
+ int best_vector[6];
+ int block_sum[7]= {0, 0, 0, 0, 0, 0};
+ int w= 2<<((level+2)>>1);
+ int h= 2<<((level+1)>>1);
+ int size=w*h;
+ int16_t block[7][256];
+ const int8_t *codebook_sum, *codebook;
+ const uint16_t (*mean_vlc)[2];
+ const uint8_t (*multistage_vlc)[2];
+
+ best_score=0;
+ //FIXME optimize, this doenst need to be done multiple times
+ if(intra){
+ codebook_sum= svq1_intra_codebook_sum[level];
+ codebook= svq1_intra_codebooks[level];
+ mean_vlc= svq1_intra_mean_vlc;
+ multistage_vlc= svq1_intra_multistage_vlc[level];
+ for(y=0; y<h; y++){
+ for(x=0; x<w; x++){
+ int v= src[x + y*stride];
+ block[0][x + w*y]= v;
+ best_score += v*v;
+ block_sum[0] += v;
+ }
+ }
+ }else{
+ codebook_sum= svq1_inter_codebook_sum[level];
+ codebook= svq1_inter_codebooks[level];
+ mean_vlc= svq1_inter_mean_vlc + 256;
+ multistage_vlc= svq1_inter_multistage_vlc[level];
+ for(y=0; y<h; y++){
+ for(x=0; x<w; x++){
+ int v= src[x + y*stride] - ref[x + y*stride];
+ block[0][x + w*y]= v;
+ best_score += v*v;
+ block_sum[0] += v;
+ }
+ }
+ }
+
+ best_count=0;
+ best_score -= ((block_sum[0]*block_sum[0])>>(level+3));
+ best_mean= (block_sum[0] + (size>>1)) >> (level+3);
+
+ if(level<4){
+ for(count=1; count<7; count++){
+ int best_vector_score= INT_MAX;
+ int best_vector_sum=-999, best_vector_mean=-999;
+ const int stage= count-1;
+ const int8_t *vector;
+
+ for(i=0; i<16; i++){
+ int sum= codebook_sum[stage*16 + i];
+ int sqr=0;
+ int diff, mean, score;
+
+ vector = codebook + stage*size*16 + i*size;
+
+ for(j=0; j<size; j++){
+ int v= vector[j];
+ sqr += (v - block[stage][j])*(v - block[stage][j]);
+ }
+ diff= block_sum[stage] - sum;
+ mean= (diff + (size>>1)) >> (level+3);
+ assert(mean >-300 && mean<300);
+ if(intra) mean= clip(mean, 0, 255);
+ else mean= clip(mean, -256, 255);
+ score= sqr - ((diff*(int64_t)diff)>>(level+3)); //FIXME 64bit slooow
+ if(score < best_vector_score){
+ best_vector_score= score;
+ best_vector[stage]= i;
+ best_vector_sum= sum;
+ best_vector_mean= mean;
+ }
+ }
+ assert(best_vector_mean != -999);
+ vector= codebook + stage*size*16 + best_vector[stage]*size;
+ for(j=0; j<size; j++){
+ block[stage+1][j] = block[stage][j] - vector[j];
+ }
+ block_sum[stage+1]= block_sum[stage] - best_vector_sum;
+ best_vector_score +=
+ lambda*(+ 1 + 4*count
+ + multistage_vlc[1+count][1]
+ + mean_vlc[best_vector_mean][1]);
+
+ if(best_vector_score < best_score){
+ best_score= best_vector_score;
+ best_count= count;
+ best_mean= best_vector_mean;
+ }
+ }
+ }
+
+ split=0;
+ if(best_score > threshold && level){
+ int score=0;
+ int offset= (level&1) ? stride*h/2 : w/2;
+ PutBitContext backup[6];
+
+ for(i=level-1; i>=0; i--){
+ backup[i]= s->reorder_pb[i];
+ }
+ score += encode_block(s, src , ref , decoded , stride, level-1, threshold>>1, lambda, intra);
+ score += encode_block(s, src + offset, ref + offset, decoded + offset, stride, level-1, threshold>>1, lambda, intra);
+ score += lambda;
+
+ if(score < best_score){
+ best_score= score;
+ split=1;
+ }else{
+ for(i=level-1; i>=0; i--){
+ s->reorder_pb[i]= backup[i];
+ }
+ }
+ }
+ if (level > 0)
+ put_bits(&s->reorder_pb[level], 1, split);
+
+ if(!split){
+ assert((best_mean >= 0 && best_mean<256) || !intra);
+ assert(best_mean >= -256 && best_mean<256);
+ assert(best_count >=0 && best_count<7);
+ assert(level<4 || best_count==0);
+
+ /* output the encoding */
+ put_bits(&s->reorder_pb[level],
+ multistage_vlc[1 + best_count][1],
+ multistage_vlc[1 + best_count][0]);
+ put_bits(&s->reorder_pb[level], mean_vlc[best_mean][1],
+ mean_vlc[best_mean][0]);
+
+ for (i = 0; i < best_count; i++){
+ assert(best_vector[i]>=0 && best_vector[i]<16);
+ put_bits(&s->reorder_pb[level], 4, best_vector[i]);
+ }
+
+ for(y=0; y<h; y++){
+ for(x=0; x<w; x++){
+ decoded[x + y*stride]= src[x + y*stride] - block[best_count][x + w*y] + best_mean;
+ }
+ }
+ }
+
+ return best_score;
+}
+
+static void svq1_encode_plane(SVQ1Context *s, unsigned char *src_plane, unsigned char *ref_plane, unsigned char *decoded_plane,
+ int width, int height, int src_stride, int stride)
+{
+ unsigned char buffer0[256];
+ unsigned char buffer1[256];
+ int current_buffer;
+ unsigned char *vector;
+ unsigned char *subvectors;
+ int vector_count;
+ int subvector_count;
+ int x, y;
+ int i, j;
+ int block_width, block_height;
+ int left_edge;
+ int level;
+ int threshold[6];
+ const int lambda= (s->picture.quality*s->picture.quality) >> (2*FF_LAMBDA_SHIFT);
+
+static int frame = 0;
+
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, "********* frame #%d\n", frame++);
+#endif
+
+ /* figure out the acceptable level thresholds in advance */
+ threshold[5] = QUALITY_THRESHOLD;
+ for (level = 4; level >= 0; level--)
+ threshold[level] = threshold[level + 1] * THRESHOLD_MULTIPLIER;
+
+ block_width = (width + 15) / 16;
+ block_height = (height + 15) / 16;
+
+ for (y = 0; y < block_height; y++) {
+ uint8_t src[stride*16];
+
+ for(i=0; i<16 && i + 16*y<height; i++){
+ memcpy(&src[i*stride], &src_plane[(i+16*y)*src_stride], width);
+ for(x=width; x<16*block_width; x++)
+ src[i*stride+x]= src[i*stride+x-1];
+ }
+ for(; i<16 && i + 16*y<16*block_height; i++)
+ memcpy(&src[i*stride], &src[(i-1)*stride], 16*block_width);
+
+ for (x = 0; x < block_width; x++) {
+ uint8_t reorder_buffer[2][6][7*32];
+ int count[2][6];
+ int offset = y * 16 * stride + x * 16;
+ uint8_t *decoded= decoded_plane + offset;
+ uint8_t *ref= ref_plane + offset;
+ int score[2]={0,0}, best;
+ uint8_t temp[16*stride];
+
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, "* level 5 vector @ %d, %d:\n", x * 16, y * 16);
+#endif
+
+ for(i=0; i<6; i++){
+ init_put_bits(&s->reorder_pb[i], reorder_buffer[0][i], 7*32);
+ }
+ if(s->picture.pict_type == P_TYPE){
+ const uint8_t *vlc= svq1_block_type_vlc[SVQ1_BLOCK_INTRA];
+ put_bits(&s->reorder_pb[5], vlc[1], vlc[0]);
+ score[0]= vlc[1]*lambda;
+ }
+ score[0]+= encode_block(s, src+16*x, ref, temp, stride, 5, 64, lambda, 1);
+ for(i=0; i<6; i++){
+ count[0][i]= put_bits_count(&s->reorder_pb[i]);
+ flush_put_bits(&s->reorder_pb[i]);
+ init_put_bits(&s->reorder_pb[i], reorder_buffer[1][i], 7*32);
+ }
+ if(s->picture.pict_type == P_TYPE){
+ const uint8_t *vlc= svq1_block_type_vlc[SVQ1_BLOCK_INTER];
+ put_bits(&s->reorder_pb[5], vlc[1], vlc[0]);
+ score[1] = vlc[1]*lambda;
+ for(i=0; i<2; i++){
+ vlc= svq1_motion_component_vlc[32];
+ put_bits(&s->reorder_pb[5], vlc[1], vlc[0]);
+ score[1] += vlc[1]*lambda;
+ }
+
+ score[1]+= encode_block(s, src+16*x, ref, decoded, stride, 5, 64, lambda, 0);
+ best= score[1] <= score[0];
+ if(best==1){
+ for(i=0; i<6; i++){
+ count[1][i]= put_bits_count(&s->reorder_pb[i]);
+ flush_put_bits(&s->reorder_pb[i]);
+ }
+ }
+ }else
+ best= 0;
+
+ s->rd_total += score[best];
+
+ for(i=5; i>=0; i--){
+ ff_copy_bits(&s->pb, reorder_buffer[best][i], count[best][i]);
+ }
+ if(best==0){
+ s->dsp.put_pixels_tab[0][0](decoded, temp, stride, 16);
+ }
+
+#if 0
+ for (i = 0; i < 256; i += 16) {
+ memcpy(&buffer0[i], &plane[left_edge], 16);
+ left_edge += stride;
+ }
+ current_buffer = 1; /* this will toggle to 0 immediately */
+
+ /* perform a breadth-first tree encoding for each vector level */
+ subvector_count = 1; /* one subvector at level 5 */
+ for (level = 5; level >= 0; level--) {
+
+ vector_count = subvector_count;
+ subvector_count = 0;
+
+ if (current_buffer == 0) {
+ current_buffer = 1;
+ vector = buffer1;
+ subvectors = buffer0;
+ } else {
+ current_buffer = 0;
+ vector = buffer0;
+ subvectors = buffer1;
+ }
+
+ /* iterate through each vector in the list */
+ for (i = 0; i < vector_count; i++) {
+
+ if (encode_vector(s, vector, level, threshold[level])) {
+
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, " split to level %d\n", level - 1);
+#endif
+ /* subdivide into 2 subvectors for later processing */
+ subvector_count += 2;
+
+ if (level - 1 == 3) {
+ /* subdivide 16x8 -> 2 8x8 */
+ for (j = 0; j < 8; j++) {
+ /* left half */
+ memcpy(subvectors + j * 8, vector + j * 16, 8);
+ /* right half */
+ memcpy(subvectors + 64 + j * 8,
+ vector + 8 + j * 16, 8);
+ }
+ subvectors += 128;
+ } else if (level - 1 == 1) {
+ /* subdivide 8x4 -> 2 4x4 */
+ for (j = 0; j < 4; j++) {
+ /* left half */
+ memcpy(subvectors + j * 4, vector + j * 8, 4);
+ /* right half */
+ memcpy(subvectors + 16 + j * 4,
+ vector + 4 + j * 8, 4);
+ }
+ subvectors += 32;
+ } else {
+ /* first half */
+ memcpy(subvectors, vector, level_sizes[level - 1]);
+ subvectors += level_sizes[level - 1];
+ /* second half */
+ memcpy(subvectors, vector + level_sizes[level - 1],
+ level_sizes[level - 1]);
+ subvectors += level_sizes[level - 1];
+ }
+ }
+
+ vector += level_sizes[level];
+ }
+
+ /* if there are no more subvectors, break early */
+ if (!subvector_count)
+ break;
+ }
+#endif
+ }
+ }
+}
+
+/* output a plane with a constant mean value; good for debugging and for
+ * greyscale encoding but only valid for intra frames */
+static void svq1_output_intra_constant_mean(SVQ1Context *s, int block_width,
+ int block_height, unsigned char mean)
+{
+ int i;
+
+ /* for each level 5 vector, output the specified mean value */
+ for (i = 0; i < block_width * block_height; i++) {
+
+ /* output a 0 before each vector indicating no subdivision */
+ put_bits(&s->pb, 1, 0);
+
+ /* output a 0 indicating mean-only encoding; use index 1 as that
+ * maps to code 0 */
+ put_bits(&s->pb, svq1_intra_multistage_vlc[5][1][1],
+ svq1_intra_multistage_vlc[5][1][0]);
+
+ /* output a constant mean */
+ put_bits(&s->pb, svq1_intra_mean_vlc[mean][1],
+ svq1_intra_mean_vlc[mean][0]);
+#ifdef DEBUG_SVQ1
+av_log(s->avctx, AV_LOG_INFO, " const L5 %d/%d: multistage = 0 (0x%X, %d), mean = %d (0x%X, %d)\n",
+ i, block_width * block_height,
+ svq1_intra_multistage_vlc[5][1][0],
+ svq1_intra_multistage_vlc[5][1][1],
+ mean,
+ svq1_intra_mean_vlc[mean][0],
+ svq1_intra_mean_vlc[mean][1]);
+#endif
+ }
+}
+
+static int svq1_encode_init(AVCodecContext *avctx)
+{
+ SVQ1Context * const s = avctx->priv_data;
+ int i;
+ unsigned char least_bits_value = 0;
+ int least_bits;
+
+ dsputil_init(&s->dsp, avctx);
+ avctx->coded_frame= (AVFrame*)&s->picture;
+
+ s->frame_width = avctx->width;
+ s->frame_height = avctx->height;
+
+ s->y_block_width = (s->frame_width + 15) / 16;
+ s->y_block_height = (s->frame_height + 15) / 16;
+
+ s->c_block_width = (s->frame_width / 4 + 15) / 16;
+ s->c_block_height = (s->frame_height / 4 + 15) / 16;
+
+av_log(s->avctx, AV_LOG_INFO, " Hey: %d x %d, %d x %d, %d x %d\n",
+ s->frame_width, s->frame_height,
+ s->y_block_width, s->y_block_height,
+ s->c_block_width, s->c_block_height);
+
+ /* allocate a plane for the U & V planes (color, or C, planes) and
+ * initialize them to the value that is represented by the fewest bits
+ * in the mean table; the reasoning behind this is that when the border
+ * vectors are operated upon and possibly subdivided, the mean will be
+ * removed resulting in a perfect deviation score of 0 and encoded with
+ * the minimal possible bits */
+ s->c_plane = av_malloc(s->c_block_width * s->c_block_height * 16 * 16);
+ least_bits = 10000;
+ for (i = 0; i < 256; i++)
+ if (svq1_intra_mean_vlc[i][1] < least_bits) {
+ least_bits = svq1_intra_mean_vlc[i][1];
+ least_bits_value = i;
+ }
+ memset(s->c_plane, least_bits_value,
+ s->c_block_width * s->c_block_height * 16 * 16);
+
+ return 0;
+}
+
+static int svq1_encode_frame(AVCodecContext *avctx, unsigned char *buf,
+ int buf_size, void *data)
+{
+ SVQ1Context * const s = avctx->priv_data;
+ AVFrame *pict = data;
+ AVFrame * const p= (AVFrame*)&s->picture;
+ AVFrame temp;
+ int i;
+
+ if(avctx->pix_fmt != PIX_FMT_YUV410P){
+ av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n");
+ return -1;
+ }
+
+ if(!s->current_picture.data[0]){
+ avctx->get_buffer(avctx, &s->current_picture);
+ avctx->get_buffer(avctx, &s->last_picture);
+ }
+
+ temp= s->current_picture;
+ s->current_picture= s->last_picture;
+ s->last_picture= temp;
+
+ init_put_bits(&s->pb, buf, buf_size);
+
+ *p = *pict;
+ p->pict_type = avctx->frame_number % avctx->gop_size ? P_TYPE : I_TYPE;
+ p->key_frame = p->pict_type == I_TYPE;
+
+ svq1_write_header(s, p->pict_type);
+ for(i=0; i<3; i++){
+ svq1_encode_plane(s,
+ s->picture.data[i], s->last_picture.data[i], s->current_picture.data[i],
+ s->frame_width / (i?4:1), s->frame_height / (i?4:1),
+ s->picture.linesize[i], s->current_picture.linesize[i]);
+ }
+
+// align_put_bits(&s->pb);
+ while(put_bits_count(&s->pb) & 31)
+ put_bits(&s->pb, 1, 0);
+
+ flush_put_bits(&s->pb);
+
+ return (put_bits_count(&s->pb) / 8);
+}
+
+static int svq1_encode_end(AVCodecContext *avctx)
+{
+ SVQ1Context * const s = avctx->priv_data;
+
+ av_log(avctx, AV_LOG_DEBUG, "RD: %f\n", s->rd_total/(double)(avctx->width*avctx->height*avctx->frame_number));
+
+ av_free(s->c_plane);
+
+ return 0;
+}
+
AVCodec svq1_decoder = {
"svq1",
CODEC_TYPE_VIDEO,
@@ -841,3 +1784,17 @@ AVCodec svq1_decoder = {
CODEC_CAP_DR1,
.flush= ff_mpeg_flush,
};
+
+#ifdef CONFIG_ENCODERS
+
+AVCodec svq1_encoder = {
+ "svq1",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_SVQ1,
+ sizeof(SVQ1Context),
+ svq1_encode_init,
+ svq1_encode_frame,
+ svq1_encode_end,
+};
+
+#endif //CONFIG_ENCODERS
diff --git a/src/libffmpeg/libavcodec/svq1_cb.h b/src/libffmpeg/libavcodec/svq1_cb.h
index 14372a255..0f766aa88 100644
--- a/src/libffmpeg/libavcodec/svq1_cb.h
+++ b/src/libffmpeg/libavcodec/svq1_cb.h
@@ -764,11 +764,43 @@ static const int8_t svq1_inter_codebook_8x8[6144] = {
};
/* list of codebooks for inter-coded vectors */
-static const uint8_t* const svq1_inter_codebooks[4] = {
+static const int8_t* const svq1_inter_codebooks[4] = {
svq1_inter_codebook_4x2, svq1_inter_codebook_4x4,
svq1_inter_codebook_8x4, svq1_inter_codebook_8x8
};
+static const int8_t const svq1_inter_codebook_sum[4][16*6] = {
+ {
+ -1, 1, -2, 0, 1, -1, -1, -1, -2, -1, 1, -1, -1, 0, -1, -1,
+ 0, -1, -1, -1, -1, 0, -1, 0, 0, 0, -3, 1, -1, 0, 1, -1,
+ 1, -1, 2, 2, 1, 1, 2, 0, 0, 0, -1, 1, 1, 0, 0, 0,
+ 1, -1, 0, 1, -1, 1, 1, 0, 1, 0, -1, 1, 1, 0, 0, 0,
+ -2, 0, 0, -2, 0, 0, -2, 0, -2, -1, -2, -1, 0, 0, -1, 0,
+ 1, 0, 1, -1, 2, 2, 1, 2, 2, 1, 0, 1, 1, 0, 1, 1,
+ },{
+ -2, 1, -1, -1, 1, 0, 1, -1, -1, -1, 1, -1, 0, -1, 0, -1,
+ 0, 0, 0, -2, 0, 1, 0, -1, -1, 0, 2, -3, 1, -2, 3, -1,
+ 2, 0, 2, 1, 1, -1, 1, 1, 0, 0, 1, 1, 2, -2, 1, 0,
+ -2, -1, 2, -2, -2, 0, -3, 0, -1, 0, -1, 0, -1, 0, -2, -3,
+ 1, -2, -2, -1, 1, -1, -1, 1, -1, 1, 1, 0, -2, 0, 1, 1,
+ 1, 1, 2, 1, 0, 0, -1, 0, 0, 1, 0, 1, -1, 1, 0, 2,
+ },{
+ 0, 0, 0, -3, 1, 1, 1, -3, 0, -1, 0, -3, 1, -3, 0, -2,
+ 1, 2, -1, -3, 0, -3, 1, -1, 0, -1, 0, 0, 1, 2, 1, 1,
+ -1, 2, -3, 3, 1, 0, -5, 1, 0, -1, -3, 1, 0, 2, 0, -3,
+ 4, 2, 0, -2, 1, -2, 3, -2, 1, 1, 0, -1, 2, 5, 3, 1,
+ -1, 0, 2, -3, -2, 0, 0, -2, 2, -3, -1, -1, 2, 1, 0, -2,
+ 3, -1, 1, -1, 2, 4, 0, 1, 0, 1, 0, -1, -3, -2, -1, 0,
+ },{
+ 0, 2, -1, -1, 2, -4, -2, 3, 0, -1, -5, 1, 0, 1, 0, 6,
+ -2, 2, 0, 1, 1, -1, -1, -2, 1, -2, -1, 0, 2, -2, -2, -1,
+ -4, 2, -1, -3, -1, -2, 2, -1, 2, -1, 2, 0, 3, -3, -3, 0,
+ -3, 0, 0, -2, 4, -4, 0, -1, 4, 0, -2, -2, 3, -2, 0, 4,
+ 5, 0, 1, 0, -3, 3, 3, 2, 0, 0, 1, 2, -5, -2, -3, 0,
+ -3, 2, -2, 2, -2, 4, 7, -3, 4, 2, 3, 2, -1, 0, -3, 1,
+ }
+};
+
/* 6x16-entry codebook for intra-coded 4x2 vectors */
static const int8_t svq1_intra_codebook_4x2[768] = {
12, 13, 13, 11, -7,-10,-15,-17,-16,-15,-12,-10, 11, 15, 15, 12,
@@ -1506,7 +1538,39 @@ static const int8_t svq1_intra_codebook_8x8[6144] = {
};
/* list of codebooks for intra-coded vectors */
-static const uint8_t* const svq1_intra_codebooks[4] = {
+static const int8_t* const svq1_intra_codebooks[4] = {
svq1_intra_codebook_4x2, svq1_intra_codebook_4x4,
svq1_intra_codebook_8x4, svq1_intra_codebook_8x8
};
+
+static const int8_t const svq1_intra_codebook_sum[4][16*6] = {
+ {
+ 0, 0, 0, -1, -1, -1, -1, -2, 0, -1, -1, 0, -1, 0, 1, 0,
+ 1, 0, -1, 1, 0, 0, -1, 1, -1, 0, 0, 0, -1, 1, 0, 0,
+ -1, 0, 0, 1, -1, 1, 0, -1, -1, 0, 1, 1, 0, 0, -1, 1,
+ 0, 1, 0, 0, 1, -1, 0, 0, 0, -1, 1, 0, 1, 0, -2, 1,
+ 0, -1, 1, 0, 0, 0, 1, 0, -1, 0, 0, 0, -1, 0, 0, 0,
+ 0, 1, 1, 0, 0, -1, 0, 1, 0, 0, 0, 0, -1, 1, 1, -1,
+ },{
+ -1, -2, 0, -1, 1, 0, -1, 0, -1, -4, -1, -2, -1, -2, 1, -2,
+ 0, 0, 4, -2, -1, 1, 1, 0, 2, 1, 1, 0, 2, 0, 0, 0,
+ 1, 1, 0, -1, -1, -1, 1, 0, -1, -3, -3, 1, -1, 1, -2, -1,
+ 1, -1, 0, 1, 2, 1, -1, -1, 1, 1, 1, 2, 1, 0, 1, -2,
+ -2, 0, -1, -2, -2, 0, -1, -1, -1, 0, 1, 0, -1, -1, 0, -1,
+ 0, 2, 1, 2, 2, 1, -1, 1, 0, 2, 0, -1, 1, 0, 0, 0,
+ },{
+ -2, 0, -1, -1, 1, 1, -2, 0, -2, 0, 1, -2, -2, 1, -1, -1,
+ 3, -2, 0, -3, -4, -3, 2, 1, 0, 3, -2, 2, 3, 2, 2, -1,
+ -3, 1, 0, 1, 0, 0, 0, 1, -2, 1, -2, -2, -1, -2, -2, 2,
+ 0, -4, 0, 2, -1, 0, 2, 2, 2, 1, 0, -1, -1, 1, -3, 2,
+ 2, 1, 0, 3, 1, -1, 1, 3, 1, 0, 1, 1, 2, -1, 1, -1,
+ -2, -1, 0, -1, 1, -1, 1, -2, -2, -1, -1, -3, 1, -4, -3, 1,
+ },{
+ -2, 0, -2, 3, -1, -1, 0, 2, 2, -1, -3, 2, 1, 0, -2, -1,
+ -3, -2, -2, 1, 2, -3, 0, 1, -5, -2, -3, 0, -2, -1, 2, 0,
+ -1, -1, 0, -2, 1, 3, -7, -2, -2, -1, 2, -1, 0, 3, 1, 3,
+ 1, 0, 0, 1, 2, 3, 1, 2, 0, -2, -2, 1, 1, 2, 2, 3,
+ 4, 1, -1, 2, -2, 4, 0, 0, 0, 4, 2, 0, -2, -2, 2, -4,
+ -1, 5, -2, -2, -3, 2, -3, -1, 3, -3, 0, 4, 3, 0, 1, -2,
+ }
+};
diff --git a/src/libffmpeg/libavcodec/svq1_vlc.h b/src/libffmpeg/libavcodec/svq1_vlc.h
index fa6efb860..d15ac07fb 100644
--- a/src/libffmpeg/libavcodec/svq1_vlc.h
+++ b/src/libffmpeg/libavcodec/svq1_vlc.h
@@ -9,7 +9,7 @@ static const uint8_t svq1_block_type_vlc[4][2] = {
};
/* values in this table range from -32..32; adjust retrieved value by -32 */
-static const uint16_t svq1_motion_component_vlc[65][2] = {
+static const uint8_t svq1_motion_component_vlc[65][2] = {
/* { code, length } */
{ 0x5, 13 }, { 0x7, 13 }, { 0x5, 12 }, { 0x7, 12 },
{ 0x9, 12 }, { 0xB, 12 }, { 0xD, 12 }, { 0xF, 12 },
diff --git a/src/libffmpeg/libavcodec/utils.c b/src/libffmpeg/libavcodec/utils.c
index ffa0cb855..ffcefb46b 100644
--- a/src/libffmpeg/libavcodec/utils.c
+++ b/src/libffmpeg/libavcodec/utils.c
@@ -27,7 +27,11 @@
#include "avcodec.h"
#include "dsputil.h"
#include "mpegvideo.h"
+#include "integer.h"
#include <stdarg.h>
+#include <limits.h>
+
+static void avcodec_default_free_buffers(AVCodecContext *s);
void *av_mallocz(unsigned int size)
{
@@ -514,6 +518,7 @@ int avcodec_close(AVCodecContext *avctx)
{
if (avctx->codec->close)
avctx->codec->close(avctx);
+ avcodec_default_free_buffers(avctx);
av_freep(&avctx->priv_data);
avctx->codec = NULL;
return 0;
@@ -738,7 +743,7 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
avctx->codec->flush(avctx);
}
-void avcodec_default_free_buffers(AVCodecContext *s){
+static void avcodec_default_free_buffers(AVCodecContext *s){
int i, j;
if(s->internal_buffer==NULL) return;
@@ -773,15 +778,11 @@ int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max)
assert(den != 0);
- if(den < 0){
- den= -den;
- nom= -nom;
- }
+ if(den < 0)
+ return av_reduce(dst_nom, dst_den, -nom, -den, max);
- if(nom < 0){
- nom= -nom;
- sign= 1;
- }
+ sign= nom < 0;
+ nom= ABS(nom);
gcd = ff_gcd(nom, den);
nom /= gcd;
@@ -811,31 +812,31 @@ int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max)
assert(ff_gcd(nom, den) == 1);
- if(sign) nom= -nom;
-
- *dst_nom = nom;
+ *dst_nom = sign ? -nom : nom;
*dst_den = den;
return exact;
}
-int64_t av_rescale(int64_t a, int b, int c){
- uint64_t h, l;
+int64_t av_rescale(int64_t a, int64_t b, int64_t c){
+ AVInteger ai, ci;
assert(c > 0);
assert(b >=0);
if(a<0) return -av_rescale(-a, b, c);
- h= a>>32;
- if(h==0) return a*b/c;
+ if(b<=INT_MAX && c<=INT_MAX){
+ if(a<=INT_MAX)
+ return (a * b + c/2)/c;
+ else
+ return a/c*b + (a%c*b + c/2)/c;
+ }
- l= a&0xFFFFFFFF;
- l *= b;
- h *= b;
-
- l += (h%c)<<32;
-
- return ((h/c)<<32) + l/c;
+ ai= av_mul_i(av_int2i(a), av_int2i(b));
+ ci= av_int2i(c);
+ ai= av_add_i(ai, av_shr_i(ci,1));
+
+ return av_i2int(av_div_i(ai, ci));
}
/* av_log API */
diff --git a/src/libffmpeg/libavcodec/vcr1.c b/src/libffmpeg/libavcodec/vcr1.c
index 4b8c9fc41..05539452a 100644
--- a/src/libffmpeg/libavcodec/vcr1.c
+++ b/src/libffmpeg/libavcodec/vcr1.c
@@ -165,13 +165,6 @@ static int encode_init(AVCodecContext *avctx){
return 0;
}
-static int decode_end(AVCodecContext *avctx){
-
- avcodec_default_free_buffers(avctx);
-
- return 0;
-}
-
AVCodec vcr1_decoder = {
"vcr1",
CODEC_TYPE_VIDEO,
@@ -179,7 +172,7 @@ AVCodec vcr1_decoder = {
sizeof(VCR1Context),
decode_init,
NULL,
- decode_end,
+ NULL,
decode_frame,
CODEC_CAP_DR1,
};
diff --git a/src/libffmpeg/libavcodec/vp3.c b/src/libffmpeg/libavcodec/vp3.c
index 0667d99eb..59d183505 100644
--- a/src/libffmpeg/libavcodec/vp3.c
+++ b/src/libffmpeg/libavcodec/vp3.c
@@ -2051,6 +2051,7 @@ static void render_fragments(Vp3DecodeContext *s,
int m, n;
int i = first_fragment;
int16_t *dequantizer;
+ DCTELEM __align16 output_samples[64];
unsigned char *output_plane;
unsigned char *last_plane;
unsigned char *golden_plane;
@@ -2176,16 +2177,16 @@ av_log(s->avctx, AV_LOG_ERROR, " help! got beefy vector! (%X, %X)\n", motion_x,
s->all_fragments[i].coeffs[0], dequantizer[0]);
/* invert DCT and place (or add) in final output */
+ s->dsp.vp3_idct(s->all_fragments[i].coeffs,
+ dequantizer,
+ s->all_fragments[i].coeff_count,
+ output_samples);
if (s->all_fragments[i].coding_method == MODE_INTRA) {
- s->dsp.vp3_idct_put(s->all_fragments[i].coeffs,
- dequantizer,
- s->all_fragments[i].coeff_count,
+ s->dsp.put_signed_pixels_clamped(output_samples,
output_plane + s->all_fragments[i].first_pixel,
stride);
} else {
- s->dsp.vp3_idct_add(s->all_fragments[i].coeffs,
- dequantizer,
- s->all_fragments[i].coeff_count,
+ s->dsp.add_pixels_clamped(output_samples,
output_plane + s->all_fragments[i].first_pixel,
stride);
}
diff --git a/src/libffmpeg/libavcodec/vp3dsp.c b/src/libffmpeg/libavcodec/vp3dsp.c
index ec62d9456..3ead73280 100644
--- a/src/libffmpeg/libavcodec/vp3dsp.c
+++ b/src/libffmpeg/libavcodec/vp3dsp.c
@@ -40,8 +40,10 @@ void vp3_dsp_init_c(void)
/* nop */
}
-static void vp3_idct_c(int32_t *dequantized_data, int16_t *output_data)
+void vp3_idct_c(int16_t *input_data, int16_t *dequant_matrix,
+ int coeff_count, int16_t *output_data)
{
+ int32_t dequantized_data[64];
int32_t *ip = dequantized_data;
int16_t *op = output_data;
@@ -49,7 +51,13 @@ static void vp3_idct_c(int32_t *dequantized_data, int16_t *output_data)
int32_t _Ed, _Gd, _Add, _Bdd, _Fd, _Hd;
int32_t t1, t2;
- int i;
+ int i, j;
+
+ /* de-zigzag and dequantize */
+ for (i = 0; i < coeff_count; i++) {
+ j = dezigzag_index[i];
+ dequantized_data[j] = dequant_matrix[i] * input_data[i];
+ }
/* Inverse DCT on the rows now */
for (i = 0; i < 8; i++) {
@@ -248,71 +256,3 @@ static void vp3_idct_c(int32_t *dequantized_data, int16_t *output_data)
op++;
}
}
-
-void vp3_idct_put_c(int16_t *input_data, int16_t *dequant_matrix,
- int coeff_count, uint8_t *dest, int stride)
-{
- int32_t dequantized_data[64];
- int16_t transformed_data[64];
- int16_t *op;
- int i, j;
-
- /* de-zigzag and dequantize */
- for (i = 0; i < coeff_count; i++) {
- j = dezigzag_index[i];
- dequantized_data[j] = dequant_matrix[i] * input_data[i];
- }
-
- vp3_idct_c(dequantized_data, transformed_data);
-
- /* place in final output */
- op = transformed_data;
- for (i = 0; i < 8; i++) {
- for (j = 0; j < 8; j++) {
- if (*op < -128)
- *dest = 0;
- else if (*op > 127)
- *dest = 255;
- else
- *dest = (uint8_t)(*op + 128);
- op++;
- dest++;
- }
- dest += (stride - 8);
- }
-}
-
-void vp3_idct_add_c(int16_t *input_data, int16_t *dequant_matrix,
- int coeff_count, uint8_t *dest, int stride)
-{
- int32_t dequantized_data[64];
- int16_t transformed_data[64];
- int16_t *op;
- int i, j;
- int16_t sample;
-
- /* de-zigzag and dequantize */
- for (i = 0; i < coeff_count; i++) {
- j = dezigzag_index[i];
- dequantized_data[j] = dequant_matrix[i] * input_data[i];
- }
-
- vp3_idct_c(dequantized_data, transformed_data);
-
- /* place in final output */
- op = transformed_data;
- for (i = 0; i < 8; i++) {
- for (j = 0; j < 8; j++) {
- sample = *dest + *op;
- if (sample < 0)
- *dest = 0;
- else if (sample > 255)
- *dest = 255;
- else
- *dest = (uint8_t)(sample & 0xFF);
- op++;
- dest++;
- }
- dest += (stride - 8);
- }
-}