summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libffmpeg/libavcodec/Makefile.am2
-rw-r--r--src/libffmpeg/libavcodec/avcodec.h67
-rw-r--r--src/libffmpeg/libavcodec/dsputil.c32
-rw-r--r--src/libffmpeg/libavcodec/dsputil.h26
-rw-r--r--src/libffmpeg/libavcodec/dv.c25
-rw-r--r--src/libffmpeg/libavcodec/h264.c5
-rw-r--r--src/libffmpeg/libavcodec/huffyuv.c56
-rw-r--r--src/libffmpeg/libavcodec/mpegvideo.c89
-rw-r--r--src/libffmpeg/libavcodec/mpegvideo.h5
-rw-r--r--src/libffmpeg/libavcodec/utils.c108
10 files changed, 292 insertions, 123 deletions
diff --git a/src/libffmpeg/libavcodec/Makefile.am b/src/libffmpeg/libavcodec/Makefile.am
index d0742bd9c..e9b5aa0ae 100644
--- a/src/libffmpeg/libavcodec/Makefile.am
+++ b/src/libffmpeg/libavcodec/Makefile.am
@@ -39,13 +39,11 @@ libavcodec_la_SOURCES = \
mace.c \
mem.c \
mjpeg.c \
- motion_est.c \
mpeg12.c \
mpegaudiodec.c \
mpegvideo.c \
msmpeg4.c \
opts.c \
- ratecontrol.c \
rv10.c \
simple_idct.c \
svq1.c \
diff --git a/src/libffmpeg/libavcodec/avcodec.h b/src/libffmpeg/libavcodec/avcodec.h
index d3c2bb13d..6e7532874 100644
--- a/src/libffmpeg/libavcodec/avcodec.h
+++ b/src/libffmpeg/libavcodec/avcodec.h
@@ -15,8 +15,8 @@ extern "C" {
#define LIBAVCODEC_VERSION_INT 0x000406
#define LIBAVCODEC_VERSION "0.4.6"
-#define LIBAVCODEC_BUILD 4663
-#define LIBAVCODEC_BUILD_STR "4663"
+#define LIBAVCODEC_BUILD 4666
+#define LIBAVCODEC_BUILD_STR "4666"
#define LIBAVCODEC_IDENT "FFmpeg" LIBAVCODEC_VERSION "b" LIBAVCODEC_BUILD_STR
@@ -93,6 +93,9 @@ enum PixelFormat {
PIX_FMT_MONOWHITE, ///< 0 is white
PIX_FMT_MONOBLACK, ///< 0 is black
PIX_FMT_PAL8, ///< 8 bit with RGBA palette
+ PIX_FMT_YUVJ420P, ///< YUV full scale (jpeg)
+ PIX_FMT_YUVJ422P, ///< YUV full scale (jpeg)
+ PIX_FMT_YUVJ444P, ///< YUV full scale (jpeg)
PIX_FMT_NB,
};
@@ -182,7 +185,11 @@ static const int Motion_Est_QTab[] = { ME_ZERO, ME_PHODS, ME_LOG,
/* codec capabilities */
#define CODEC_CAP_DRAW_HORIZ_BAND 0x0001 ///< decoder can use draw_horiz_band callback
-#define CODEC_CAP_DR1 0x0002 ///< direct rendering method 1
+/**
+ * Codec uses get_buffer() for allocating buffers.
+ * direct rendering method 1
+ */
+#define CODEC_CAP_DR1 0x0002
/* if 'parse_only' field is true, then avcodec_parse_frame() can be
used */
#define CODEC_CAP_PARSE_ONLY 0x0004
@@ -310,8 +317,15 @@ static const int Motion_Est_QTab[] = { ME_ZERO, ME_PHODS, ME_LOG,
* - encoding: unused\
* - decoding: set by lavc\
*/\
- int repeat_pict;
+ int repeat_pict;\
+ \
+ /**\
+ * \
+ */\
+ int qscale_type;\
+#define FF_QSCALE_TYPE_MPEG1 0
+#define FF_QSCALE_TYPE_MPEG2 1
#define FF_BUFFER_TYPE_INTERNAL 1
#define FF_BUFFER_TYPE_USER 2 ///< Direct rendering buffers
@@ -1066,7 +1080,26 @@ typedef struct AVCodecContext {
* - decoding: unused
*/
int inter_quant_bias;
+
+ /**
+ * color table ID.
+ * - encoding: unused.
+ * - decoding: which clrtable should be used for 8bit RGB images
+ * table have to be stored somewhere FIXME
+ */
+ int color_table_id;
+ /**
+ * internal_buffer count.
+ * Dont touch, used by lavc default_get_buffer()
+ */
+ int internal_buffer_count;
+
+ /**
+ * internal_buffers.
+ * Dont touch, used by lavc default_get_buffer()
+ */
+ void *internal_buffer;
} AVCodecContext;
@@ -1119,7 +1152,7 @@ int avoption_parse(void* strct, const AVOption* list, const char* opts);
*/
typedef struct AVCodec {
const char *name;
- int type;
+ enum CodecType type;
int id;
int priv_data_size;
int (*init)(AVCodecContext *);
@@ -1185,6 +1218,7 @@ extern AVCodec oggvorbis_decoder;
extern AVCodec cyuv_decoder;
extern AVCodec h264_decoder;
extern AVCodec indeo3_decoder;
+extern AVCodec vp3_decoder;
/* pcm codecs */
#define PCM_CODEC(id, name) \
@@ -1209,7 +1243,8 @@ PCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms);
#undef PCM_CODEC
/* dummy raw video codec */
-extern AVCodec rawvideo_codec;
+extern AVCodec rawvideo_encoder;
+extern AVCodec rawvideo_decoder;
/* the following codecs use external GPL libs */
extern AVCodec ac3_decoder;
@@ -1246,9 +1281,28 @@ void img_resample_close(ImgReSampleContext *s);
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
int pix_fmt, int width, int height);
+int avpicture_layout(AVPicture* src, int pix_fmt, int width, int height,
+ unsigned char *dest, int dest_size);
int avpicture_get_size(int pix_fmt, int width, int height);
void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift);
const char *avcodec_get_pix_fmt_name(int pix_fmt);
+enum PixelFormat avcodec_get_pix_fmt(const char* name);
+
+#define FF_LOSS_RESOLUTION 0x0001 /* loss due to resolution change */
+#define FF_LOSS_DEPTH 0x0002 /* loss due to color depth change */
+#define FF_LOSS_COLORSPACE 0x0004 /* loss due to color space conversion */
+#define FF_LOSS_ALPHA 0x0008 /* loss of alpha bits */
+#define FF_LOSS_COLORQUANT 0x0010 /* loss due to color quantization */
+#define FF_LOSS_CHROMA 0x0020 /* loss of chroma (e.g. rgb to gray conversion) */
+
+int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt,
+ int has_alpha);
+int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt,
+ int has_alpha, int *loss_ptr);
+
+#define FF_ALPHA_TRANSP 0x0001 /* image has some totally transparent pixels */
+#define FF_ALPHA_SEMI_TRANSP 0x0002 /* image has some transparent pixels */
+int img_get_alpha_info(AVPicture *src, int pix_fmt, int width, int height);
/* convert among pixel formats */
int img_convert(AVPicture *dst, int dst_pix_fmt,
@@ -1282,6 +1336,7 @@ 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_open(AVCodecContext *avctx, AVCodec *codec);
int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples,
diff --git a/src/libffmpeg/libavcodec/dsputil.c b/src/libffmpeg/libavcodec/dsputil.c
index 146a657dd..b9a5f1382 100644
--- a/src/libffmpeg/libavcodec/dsputil.c
+++ b/src/libffmpeg/libavcodec/dsputil.c
@@ -2489,26 +2489,28 @@ static void ff_jref_idct_add(uint8_t *dest, int line_size, DCTELEM *block)
add_pixels_clamped_c(block, dest, line_size);
}
-void dsputil_init(DSPContext* c, AVCodecContext *avctx)
+/* init static data */
+void dsputil_static_init(void)
{
- static int init_done = 0;
int i;
- if (!init_done) {
- for(i=0;i<256;i++) cropTbl[i + MAX_NEG_CROP] = i;
- for(i=0;i<MAX_NEG_CROP;i++) {
- cropTbl[i] = 0;
- cropTbl[i + MAX_NEG_CROP + 256] = 255;
- }
-
- for(i=0;i<512;i++) {
- squareTbl[i] = (i - 256) * (i - 256);
- }
+ for(i=0;i<256;i++) cropTbl[i + MAX_NEG_CROP] = i;
+ for(i=0;i<MAX_NEG_CROP;i++) {
+ cropTbl[i] = 0;
+ cropTbl[i + MAX_NEG_CROP + 256] = 255;
+ }
+
+ for(i=0;i<512;i++) {
+ squareTbl[i] = (i - 256) * (i - 256);
+ }
+
+ for(i=0; i<64; i++) inv_zigzag_direct16[ff_zigzag_direct[i]]= i+1;
+}
- for(i=0; i<64; i++) inv_zigzag_direct16[ff_zigzag_direct[i]]= i+1;
- init_done = 1;
- }
+void dsputil_init(DSPContext* c, AVCodecContext *avctx)
+{
+ int i;
#ifdef CONFIG_ENCODERS
if(avctx->dct_algo==FF_DCT_FASTINT)
diff --git a/src/libffmpeg/libavcodec/dsputil.h b/src/libffmpeg/libavcodec/dsputil.h
index 14ea882b3..e4a524d8d 100644
--- a/src/libffmpeg/libavcodec/dsputil.h
+++ b/src/libffmpeg/libavcodec/dsputil.h
@@ -20,6 +20,8 @@
/**
* @file dsputil.h
* DSP utils.
+ * note, many functions in here may use MMX which trashes the FPU state, it is
+ * absolutely necessary to call emms_c() between dsp & float/double code
*/
#ifndef DSPUTIL_H
@@ -27,14 +29,17 @@
#include "common.h"
#include "avcodec.h"
+
+
#include "xineutils.h"
#if defined(ARCH_X86)
-#define HAVE_MMX 1
+#define HAVE_MMX 1
#endif
#undef DEBUG
+//#define DEBUG
/* dct code */
typedef short DCTELEM;
//typedef int DCTELEM;
@@ -152,7 +157,9 @@ typedef struct DSPContext {
/* maybe create an array for 16/8 functions */
/**
* Halfpel motion compensation with rounding (a+b+1)>>1.
- * *pixels_tab[ 0->16x16 1->8x8 ][ xhalfpel + 2*yhalfpel ]
+ * this is an array[2][4] of motion compensation funcions for 2
+ * horizontal blocksizes (8,16) and the 4 halfpel positions<br>
+ * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
* @param block destination where the result is stored
* @param pixels source
* @param line_size number of bytes in a horizontal line of block
@@ -162,7 +169,9 @@ typedef struct DSPContext {
/**
* Halfpel motion compensation with rounding (a+b+1)>>1.
- * *pixels_tab[ 0->16x16 1->8x8 ][ xhalfpel + 2*yhalfpel ]
+ * this is an array[2][4] of motion compensation funcions for 2
+ * horizontal blocksizes (8,16) and the 4 halfpel positions<br>
+ * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
* @param block destination into which the result is averaged (a+b+1)>>1
* @param pixels source
* @param line_size number of bytes in a horizontal line of block
@@ -172,7 +181,9 @@ typedef struct DSPContext {
/**
* Halfpel motion compensation with no rounding (a+b)>>1.
- * *pixels_tab[ 0->16x16 1->8x8 ][ xhalfpel + 2*yhalfpel ]
+ * this is an array[2][4] of motion compensation funcions for 2
+ * horizontal blocksizes (8,16) and the 4 halfpel positions<br>
+ * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
* @param block destination where the result is stored
* @param pixels source
* @param line_size number of bytes in a horizontal line of block
@@ -182,7 +193,9 @@ typedef struct DSPContext {
/**
* Halfpel motion compensation with no rounding (a+b)>>1.
- * *pixels_tab[ 0->16x16 1->8x8 ][ xhalfpel + 2*yhalfpel ]
+ * this is an array[2][4] of motion compensation funcions for 2
+ * horizontal blocksizes (8,16) and the 4 halfpel positions<br>
+ * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
* @param block destination into which the result is averaged (a+b)>>1
* @param pixels source
* @param line_size number of bytes in a horizontal line of block
@@ -250,6 +263,7 @@ typedef struct DSPContext {
} DSPContext;
+void dsputil_static_init(void);
void dsputil_init(DSPContext* p, AVCodecContext *avctx);
/**
@@ -286,7 +300,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);
-#if 0
+#if 0
static inline void emms(void)
{
__asm __volatile ("emms;":::"memory");
diff --git a/src/libffmpeg/libavcodec/dv.c b/src/libffmpeg/libavcodec/dv.c
index eb8dbb7c0..32d4c3a27 100644
--- a/src/libffmpeg/libavcodec/dv.c
+++ b/src/libffmpeg/libavcodec/dv.c
@@ -278,7 +278,7 @@ static void dv_decode_ac(DVVideoDecodeContext *s,
if (pos >= 64) {
read_error:
#if defined(VLC_DEBUG) || 1
- printf("error pos=%d\n", pos);
+ fprintf(stderr, "error pos=%d\n", pos);
#endif
/* for errors, we consider the eob is reached */
mb->eob_reached = 1;
@@ -538,16 +538,17 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
width = 720;
if (dsf) {
avctx->frame_rate = 25;
+ avctx->frame_rate_base = 1;
packet_size = PAL_FRAME_SIZE;
height = 576;
nb_dif_segs = 12;
} else {
- avctx->frame_rate = 30;
+ avctx->frame_rate = 30000;
+ avctx->frame_rate_base = 1001;
packet_size = NTSC_FRAME_SIZE;
height = 480;
nb_dif_segs = 10;
}
- avctx->frame_rate_base= 1;
/* NOTE: we only accept several full frames */
if (buf_size < packet_size)
return -1;
@@ -579,6 +580,9 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
else
avctx->aspect_ratio = 4.0 / 3.0;
+ if(s->picture.data[0])
+ avctx->release_buffer(avctx, &s->picture);
+
s->picture.reference= 0;
if(avctx->get_buffer(avctx, &s->picture) < 0) {
fprintf(stderr, "get_buffer() failed\n");
@@ -616,23 +620,14 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
*data_size = sizeof(AVFrame);
*(AVFrame*)data= s->picture;
- avctx->release_buffer(avctx, &s->picture);
-
return packet_size;
}
static int dvvideo_decode_end(AVCodecContext *avctx)
{
DVVideoDecodeContext *s = avctx->priv_data;
- int i;
-
- if(avctx->get_buffer == avcodec_default_get_buffer){
- for(i=0; i<4; i++){
- av_freep(&s->picture.base[i]);
- s->picture.data[i]= NULL;
- }
- av_freep(&s->picture.opaque);
- }
+
+ avcodec_default_free_buffers(avctx);
return 0;
}
@@ -730,8 +725,8 @@ static int dvaudio_decode_frame(AVCodecContext *avctx,
avctx->sample_rate = dv_audio_frequency[freq];
avctx->channels = 2;
+ avctx->bit_rate = avctx->channels * avctx->sample_rate * 16;
// What about:
- // avctx->bit_rate =
// avctx->frame_size =
*data_size = (dv_audio_min_samples[sys][freq] + smpls) *
diff --git a/src/libffmpeg/libavcodec/h264.c b/src/libffmpeg/libavcodec/h264.c
index 31cb74963..5acce0d83 100644
--- a/src/libffmpeg/libavcodec/h264.c
+++ b/src/libffmpeg/libavcodec/h264.c
@@ -3868,6 +3868,7 @@ fprintf(stderr, "FMO not supported\n");
|) | | |
| slice_group_id[ i ] |1 |u(v) |
#endif
+ break;
}
}
pps->ref_count[0]= get_ue_golomb(&s->gb) + 1;
@@ -3942,7 +3943,7 @@ static int find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){
}
pc->state= state;
- return -1;
+ return END_NOT_FOUND;
}
static int decode_nal_units(H264Context *h, uint8_t *buf, int buf_size){
@@ -4366,6 +4367,6 @@ AVCodec h264_decoder = {
NULL,
decode_end,
decode_frame,
- /*CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | */CODEC_CAP_TRUNCATED,
+ /*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED,
};
diff --git a/src/libffmpeg/libavcodec/huffyuv.c b/src/libffmpeg/libavcodec/huffyuv.c
index ea4d26943..1ab31a933 100644
--- a/src/libffmpeg/libavcodec/huffyuv.c
+++ b/src/libffmpeg/libavcodec/huffyuv.c
@@ -170,6 +170,8 @@ static inline void add_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *d
*left= l;
*left_top= lt;
}
+
+#ifdef CONFIG_ENCODERS
//FIXME optimize
static inline void sub_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w, int *left, int *left_top){
int i;
@@ -189,6 +191,7 @@ static inline void sub_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *s
*left_top= lt;
}
+#endif //CONFIG_ENCODERS
static inline void add_left_prediction_bgr32(uint8_t *dst, uint8_t *src, int w, int *red, int *green, int *blue){
int i;
@@ -212,6 +215,7 @@ static inline void add_left_prediction_bgr32(uint8_t *dst, uint8_t *src, int w,
*blue= b;
}
+#ifdef CONFIG_ENCODERS
static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst, uint8_t *src, int w, int left){
int i;
if(w<32){
@@ -231,7 +235,7 @@ static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst, uint8_t *src
return src[w-1];
}
}
-
+#endif //CONFIG_ENCODERS
static void read_len_table(uint8_t *dst, GetBitContext *gb){
int i, val, repeat;
@@ -266,6 +270,8 @@ static int generate_bits_table(uint32_t *dst, uint8_t *len_table){
return 0;
}
+#ifdef CONFIG_ENCODERS
+
static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){
uint64_t counts[2*size];
int up[2*size];
@@ -322,6 +328,8 @@ static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){
}
}
+#endif //CONFIG_ENCODERS
+
static int read_huffman_tables(HYuvContext *s, uint8_t *src, int length){
GetBitContext gb;
int i;
@@ -472,6 +480,8 @@ s->bgr32=1;
return 0;
}
+#ifdef CONFIG_ENCODERS
+
static void store_table(HYuvContext *s, uint8_t *len){
int i;
int index= s->avctx->extradata_size;
@@ -585,17 +595,19 @@ static int encode_init(AVCodecContext *avctx)
s->stats[i][j]= 0;
s->interlaced= height > 288;
-
+
// printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
-
+
s->picture_number=0;
-
+
return 0;
}
+#endif //CONFIG_ENCODERS
+
static void decode_422_bitstream(HYuvContext *s, int count){
int i;
-
+
count/=2;
for(i=0; i<count; i++){
@@ -617,6 +629,8 @@ static void decode_gray_bitstream(HYuvContext *s, int count){
}
}
+#ifdef CONFIG_ENCODERS
+
static void encode_422_bitstream(HYuvContext *s, int count){
int i;
@@ -655,9 +669,11 @@ static void encode_gray_bitstream(HYuvContext *s, int count){
}
}
+#endif //CONFIG_ENCODERS
+
static void decode_bgr_bitstream(HYuvContext *s, int count){
int i;
-
+
if(s->decorrelate){
if(s->bitstream_bpp==24){
for(i=0; i<count; i++){
@@ -737,6 +753,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
init_get_bits(&s->gb, s->bitstream_buffer, buf_size*8);
+ if(p->data[0])
+ avctx->release_buffer(avctx, p);
+
p->reference= 0;
if(avctx->get_buffer(avctx, p) < 0){
fprintf(stderr, "get_buffer() failed\n");
@@ -943,9 +962,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
emms_c();
*picture= *p;
-
- avctx->release_buffer(avctx, p);
-
*data_size = sizeof(AVFrame);
return (get_bits_count(&s->gb)+31)/32*4;
@@ -959,18 +975,14 @@ static int decode_end(AVCodecContext *avctx)
for(i=0; i<3; i++){
free_vlc(&s->vlc[i]);
}
-
- if(avctx->get_buffer == avcodec_default_get_buffer){
- for(i=0; i<4; i++){
- av_freep(&s->picture.base[i]);
- s->picture.data[i]= NULL;
- }
- av_freep(&s->picture.opaque);
- }
+
+ avcodec_default_free_buffers(avctx);
return 0;
}
+#ifdef CONFIG_ENCODERS
+
static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
HYuvContext *s = avctx->priv_data;
AVFrame *pict = data;
@@ -1132,6 +1144,8 @@ static int encode_end(AVCodecContext *avctx)
return 0;
}
+#endif //CONFIG_ENCODERS
+
static const AVOption huffyuv_options[] =
{
AVOPTION_CODEC_INT("prediction_method", "prediction_method", prediction_method, 0, 2, 0),
@@ -1151,6 +1165,8 @@ AVCodec huffyuv_decoder = {
NULL
};
+#ifdef CONFIG_ENCODERS
+
AVCodec huffyuv_encoder = {
"huffyuv",
CODEC_TYPE_VIDEO,
@@ -1159,7 +1175,7 @@ AVCodec huffyuv_encoder = {
encode_init,
encode_frame,
encode_end,
- NULL,
- 0,
- huffyuv_options,
+ .options = huffyuv_options,
};
+
+#endif //CONFIG_ENCODERS \ No newline at end of file
diff --git a/src/libffmpeg/libavcodec/mpegvideo.c b/src/libffmpeg/libavcodec/mpegvideo.c
index c576695f3..ea24c2a48 100644
--- a/src/libffmpeg/libavcodec/mpegvideo.c
+++ b/src/libffmpeg/libavcodec/mpegvideo.c
@@ -34,7 +34,8 @@
#include "fastmemcpy.h"
#endif
-#define CONFIG_RISKY
+//#undef NDEBUG
+//#include <assert.h>
#ifdef CONFIG_ENCODERS
static void encode_picture(MpegEncContext *s, int picture_number);
@@ -304,15 +305,8 @@ static void free_picture(MpegEncContext *s, Picture *pic){
av_freep(&pic->motion_val[i]);
av_freep(&pic->ref_index[i]);
}
-
- if(pic->type == FF_BUFFER_TYPE_INTERNAL){
- for(i=0; i<4; i++){
- av_freep(&pic->base[i]);
- pic->data[i]= NULL;
- }
- av_freep(&pic->opaque);
- pic->type= 0;
- }else if(pic->type == FF_BUFFER_TYPE_SHARED){
+
+ if(pic->type == FF_BUFFER_TYPE_SHARED){
for(i=0; i<4; i++){
pic->base[i]=
pic->data[i]= NULL;
@@ -523,6 +517,7 @@ void MPV_common_end(MpegEncContext *s)
for(i=0; i<MAX_PICTURE_COUNT; i++){
free_picture(s, &s->picture[i]);
}
+ avcodec_default_free_buffers(s->avctx);
s->context_initialized = 0;
}
@@ -934,7 +929,7 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
s->mb_skiped = 0;
assert(s->last_picture_ptr==NULL || s->out_format != FMT_H264);
-
+
/* mark&release old frames */
if (s->pict_type != B_TYPE && s->last_picture_ptr) {
avctx->release_buffer(avctx, (AVFrame*)s->last_picture_ptr);
@@ -950,9 +945,15 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
}
}
}
-
alloc:
if(!s->encoding){
+ /* release non refernce frames */
+ for(i=0; i<MAX_PICTURE_COUNT; i++){
+ if(s->picture[i].data[0] && !s->picture[i].reference /*&& s->picture[i].type!=FF_BUFFER_TYPE_SHARED*/){
+ s->avctx->release_buffer(s->avctx, (AVFrame*)&s->picture[i]);
+ }
+ }
+
i= find_unused_picture(s, 0);
pic= (AVFrame*)&s->picture[i];
@@ -977,6 +978,7 @@ alloc:
s->last_picture_ptr= s->next_picture_ptr;
s->next_picture_ptr= s->current_picture_ptr;
}
+
if(s->last_picture_ptr) s->last_picture= *s->last_picture_ptr;
if(s->next_picture_ptr) s->next_picture= *s->next_picture_ptr;
if(s->new_picture_ptr ) s->new_picture = *s->new_picture_ptr;
@@ -1045,12 +1047,14 @@ void MPV_frame_end(MpegEncContext *s)
assert(i<MAX_PICTURE_COUNT);
#endif
- /* release non refernce frames */
- for(i=0; i<MAX_PICTURE_COUNT; i++){
- if(s->picture[i].data[0] && !s->picture[i].reference /*&& s->picture[i].type!=FF_BUFFER_TYPE_SHARED*/)
- s->avctx->release_buffer(s->avctx, (AVFrame*)&s->picture[i]);
+ if(s->encoding){
+ /* release non refernce frames */
+ for(i=0; i<MAX_PICTURE_COUNT; i++){
+ if(s->picture[i].data[0] && !s->picture[i].reference /*&& s->picture[i].type!=FF_BUFFER_TYPE_SHARED*/){
+ s->avctx->release_buffer(s->avctx, (AVFrame*)&s->picture[i]);
+ }
+ }
}
-
// clear copies, to avoid confusion
#if 0
memset(&s->last_picture, 0, sizeof(Picture));
@@ -1865,6 +1869,18 @@ inline int ff_h263_round_chroma(int x){
}
}
+/**
+ * motion compesation of a single macroblock
+ * @param s context
+ * @param dest_y luma destination pointer
+ * @param dest_cb chroma cb/u destination pointer
+ * @param dest_cr chroma cr/v destination pointer
+ * @param dir direction (0->forward, 1->backward)
+ * @param ref_picture array[3] of pointers to the 3 planes of the reference picture
+ * @param pic_op halfpel motion compensation function (average or put normally)
+ * @param pic_op qpel motion compensation function (average or put normally)
+ * the motion vectors are taken from s->mv and the MV type from s->mv_type
+ */
static inline void MPV_motion(MpegEncContext *s,
uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
int dir, uint8_t **ref_picture,
@@ -2774,17 +2790,33 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
*/
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;
- if(next==-1){
+ /* 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;
}
-
+
+ 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);
@@ -2794,6 +2826,19 @@ int ff_combine_frame( MpegEncContext *s, int next, uint8_t **buf, int *buf_size)
*buf_size= pc->last_index + next;
}
+ /* 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;
}
@@ -3863,8 +3908,8 @@ static int dct_quantize_c(MpegEncContext *s,
level = block[j];
level = level * qmat[j];
-// if( bias+level >= (1<<(QMAT_SHIFT - 3))
-// || bias-level >= (1<<(QMAT_SHIFT - 3))){
+// if( bias+level >= (1<<QMAT_SHIFT)
+// || bias-level >= (1<<QMAT_SHIFT)){
if(((unsigned)(level+threshold1))>threshold2){
if(level>0){
level= (bias + level)>>QMAT_SHIFT;
diff --git a/src/libffmpeg/libavcodec/mpegvideo.h b/src/libffmpeg/libavcodec/mpegvideo.h
index dc15a51f8..2cbc0ef19 100644
--- a/src/libffmpeg/libavcodec/mpegvideo.h
+++ b/src/libffmpeg/libavcodec/mpegvideo.h
@@ -205,8 +205,10 @@ typedef struct ParseContext{
int index;
int last_index;
int buffer_size;
- int state;
+ uint32_t state; ///< contains the last few bytes in MSB order
int frame_start_found;
+ int overread; ///< the number of bytes which where irreversibly read from the next frame
+ int overread_index; ///< the index into ParseContext.buffer of the overreaded bytes
} ParseContext;
struct MpegEncContext;
@@ -709,6 +711,7 @@ void ff_draw_horiz_band(MpegEncContext *s, int y, int h);
void ff_emulated_edge_mc(MpegEncContext *s, uint8_t *src, int linesize, int block_w, int block_h,
int src_x, int src_y, int w, int h);
char ff_get_pict_type_char(int pict_type);
+#define END_NOT_FOUND -100
int ff_combine_frame( MpegEncContext *s, int next, uint8_t **buf, int *buf_size);
void ff_print_debug_info(MpegEncContext *s, Picture *pict);
diff --git a/src/libffmpeg/libavcodec/utils.c b/src/libffmpeg/libavcodec/utils.c
index 8face129f..a422cf282 100644
--- a/src/libffmpeg/libavcodec/utils.c
+++ b/src/libffmpeg/libavcodec/utils.c
@@ -119,29 +119,39 @@ void register_avcodec(AVCodec *format)
format->next = NULL;
}
-typedef struct DefaultPicOpaque{
+typedef struct InternalBuffer{
int last_pic_num;
+ uint8_t *base[4];
uint8_t *data[4];
-}DefaultPicOpaque;
+}InternalBuffer;
+
+#define INTERNAL_BUFFER_SIZE 32
int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){
int i;
const int width = s->width;
const int height= s->height;
- DefaultPicOpaque *opaque;
+ InternalBuffer *buf;
assert(pic->data[0]==NULL);
- assert(pic->type==0 || pic->type==FF_BUFFER_TYPE_INTERNAL);
-
- if(pic->opaque){
- opaque= (DefaultPicOpaque *)pic->opaque;
- for(i=0; i<3; i++)
- pic->data[i]= opaque->data[i];
+ assert(INTERNAL_BUFFER_SIZE > s->internal_buffer_count);
-// printf("get_buffer %X coded_pic_num:%d last:%d\n", pic->opaque, pic->coded_picture_number, opaque->last_pic_num);
- pic->age= pic->coded_picture_number - opaque->last_pic_num;
- opaque->last_pic_num= pic->coded_picture_number;
-//printf("age: %d %d %d\n", pic->age, c->picture_number, pic->coded_picture_number);
+ if(s->internal_buffer==NULL){
+ s->internal_buffer= av_mallocz(INTERNAL_BUFFER_SIZE*sizeof(InternalBuffer));
+ }
+#if 0
+ s->internal_buffer= av_fast_realloc(
+ s->internal_buffer,
+ &s->internal_buffer_size,
+ sizeof(InternalBuffer)*FFMAX(99, s->internal_buffer_count+1)/*FIXME*/
+ );
+#endif
+
+ buf= &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count];
+
+ if(buf->base[0]){
+ pic->age= pic->coded_picture_number - buf->last_pic_num;
+ buf->last_pic_num= pic->coded_picture_number;
}else{
int align, h_chroma_shift, v_chroma_shift;
int w, h, pixel_size;
@@ -174,11 +184,7 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){
h+= EDGE_WIDTH*2;
}
- opaque= av_mallocz(sizeof(DefaultPicOpaque));
- if(opaque==NULL) return -1;
-
- pic->opaque= opaque;
- opaque->last_pic_num= -256*256*256*64;
+ buf->last_pic_num= -256*256*256*64;
for(i=0; i<3; i++){
const int h_shift= i==0 ? 0 : h_chroma_shift;
@@ -186,32 +192,51 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){
pic->linesize[i]= pixel_size*w>>h_shift;
- pic->base[i]= av_mallocz((pic->linesize[i]*h>>v_shift)+16); //FIXME 16
- if(pic->base[i]==NULL) return -1;
-
- memset(pic->base[i], 128, pic->linesize[i]*h>>v_shift);
+ buf->base[i]= av_mallocz((pic->linesize[i]*h>>v_shift)+16); //FIXME 16
+ if(buf->base[i]==NULL) return -1;
+ memset(buf->base[i], 128, pic->linesize[i]*h>>v_shift);
if(s->flags&CODEC_FLAG_EMU_EDGE)
- pic->data[i] = pic->base[i];
+ buf->data[i] = buf->base[i];
else
- pic->data[i] = pic->base[i] + (pic->linesize[i]*EDGE_WIDTH>>v_shift) + (EDGE_WIDTH>>h_shift);
-
- opaque->data[i]= pic->data[i];
+ buf->data[i] = buf->base[i] + (pic->linesize[i]*EDGE_WIDTH>>v_shift) + (EDGE_WIDTH>>h_shift);
}
pic->age= 256*256*256*64;
pic->type= FF_BUFFER_TYPE_INTERNAL;
}
+ for(i=0; i<4; i++){
+ pic->base[i]= buf->base[i];
+ pic->data[i]= buf->data[i];
+ }
+ s->internal_buffer_count++;
+
return 0;
}
void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic){
int i;
-
+ InternalBuffer *buf, *last, temp;
+
assert(pic->type==FF_BUFFER_TYPE_INTERNAL);
-
- for(i=0; i<3; i++)
+
+ for(i=0; i<s->internal_buffer_count; i++){ //just 3-5 checks so is not worth to optimize
+ buf= &((InternalBuffer*)s->internal_buffer)[i];
+ if(buf->data[0] == pic->data[0])
+ break;
+ }
+ assert(i < s->internal_buffer_count);
+ s->internal_buffer_count--;
+ last = &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count];
+
+ temp= *buf;
+ *buf= *last;
+ *last= temp;
+
+ for(i=0; i<3; i++){
pic->data[i]=NULL;
+// pic->base[i]=NULL;
+ }
//printf("R%X\n", pic->opaque);
}
@@ -555,7 +580,7 @@ void avcodec_init(void)
return;
inited = 1;
- //dsputil_init();
+ dsputil_static_init();
}
/* this can be called after seeking and before trying to decode the next keyframe */
@@ -565,13 +590,11 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
MpegEncContext *s = avctx->priv_data;
switch(avctx->codec_id){
- case CODEC_ID_MJPEG:
- case CODEC_ID_MJPEGB:
- if(avctx->codec->priv_data_size != sizeof(MpegEncContext))
- break;
case CODEC_ID_MPEG1VIDEO:
case CODEC_ID_H263:
case CODEC_ID_RV10:
+// case CODEC_ID_MJPEG:
+// case CODEC_ID_MJPEGB:
case CODEC_ID_MPEG4:
case CODEC_ID_MSMPEG4V1:
case CODEC_ID_MSMPEG4V2:
@@ -594,6 +617,23 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
}
}
+void avcodec_default_free_buffers(AVCodecContext *s){
+ int i, j;
+
+ if(s->internal_buffer==NULL) return;
+
+ for(i=0; i<INTERNAL_BUFFER_SIZE; i++){
+ InternalBuffer *buf= &((InternalBuffer*)s->internal_buffer)[i];
+ for(j=0; j<4; j++){
+ av_freep(&buf->base[j]);
+ buf->data[j]= NULL;
+ }
+ }
+ av_freep(&s->internal_buffer);
+
+ s->internal_buffer_count=0;
+}
+
int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max){
int exact=1, sign=0;
int64_t gcd, larger;