updated to cvs : February 1, 2004

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6462 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
shatty
2004-02-02 00:42:25 +00:00
parent 5a84c3b178
commit a96f066c38
38 changed files with 2317 additions and 1552 deletions
@@ -1,6 +1,6 @@
SubDir OBOS_TOP src add-ons media plugins avcodec libavcodec ; SubDir OBOS_TOP src add-ons media plugins avcodec libavcodec ;
CFLAGS += -fomit-frame-pointer -DPIC ; SubDirCcFlags -fomit-frame-pointer -DPIC ;
DEFINES += HAVE_AV_CONFIG_H=1 ; DEFINES += HAVE_AV_CONFIG_H=1 ;
StaticLibrary avcodec : StaticLibrary avcodec :
@@ -299,7 +299,7 @@ static int adpcm_decode_init(AVCodecContext * avctx)
return 0; return 0;
} }
static inline short adpcm_ima_expand_nibble(ADPCMChannelStatus *c, char nibble) static inline short adpcm_ima_expand_nibble(ADPCMChannelStatus *c, char nibble, int shift)
{ {
int step_index; int step_index;
int predictor; int predictor;
@@ -315,34 +315,7 @@ static inline short adpcm_ima_expand_nibble(ADPCMChannelStatus *c, char nibble)
/* perform direct multiplication instead of series of jumps proposed by /* perform direct multiplication instead of series of jumps proposed by
* the reference ADPCM implementation since modern CPUs can do the mults * the reference ADPCM implementation since modern CPUs can do the mults
* quickly enough */ * quickly enough */
diff = ((2 * delta + 1) * step) >> 3; diff = ((2 * delta + 1) * step) >> shift;
predictor = c->predictor;
if (sign) predictor -= diff;
else predictor += diff;
CLAMP_TO_SHORT(predictor);
c->predictor = predictor;
c->step_index = step_index;
return (short)predictor;
}
static inline short adpcm_4xa_expand_nibble(ADPCMChannelStatus *c, char nibble)
{
int step_index;
int predictor;
int sign, delta, diff, step;
step = step_table[c->step_index];
step_index = c->step_index + index_table[(unsigned)nibble];
if (step_index < 0) step_index = 0;
else if (step_index > 88) step_index = 88;
sign = nibble & 8;
delta = nibble & 7;
diff = (delta*step + (step>>1))>>3; // difference to code above
predictor = c->predictor; predictor = c->predictor;
if (sign) predictor -= diff; if (sign) predictor -= diff;
else predictor += diff; else predictor += diff;
@@ -471,6 +444,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
int decode_top_nibble_next = 0; int decode_top_nibble_next = 0;
int diff_channel; int diff_channel;
if (!buf_size)
return 0;
samples = data; samples = data;
src = buf; src = buf;
@@ -505,9 +481,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
samples++; samples++;
for(m=32; n>0 && m>0; n--, m--) { /* in QuickTime, IMA is encoded by chuncks of 34 bytes (=64 samples) */ for(m=32; n>0 && m>0; n--, m--) { /* in QuickTime, IMA is encoded by chuncks of 34 bytes (=64 samples) */
*samples = adpcm_ima_expand_nibble(cs, src[0] & 0x0F); *samples = adpcm_ima_expand_nibble(cs, src[0] & 0x0F, 3);
samples += avctx->channels; samples += avctx->channels;
*samples = adpcm_ima_expand_nibble(cs, (src[0] >> 4) & 0x0F); *samples = adpcm_ima_expand_nibble(cs, (src[0] >> 4) & 0x0F, 3);
samples += avctx->channels; samples += avctx->channels;
src ++; src ++;
} }
@@ -524,44 +500,29 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
if (avctx->block_align != 0 && buf_size > avctx->block_align) if (avctx->block_align != 0 && buf_size > avctx->block_align)
buf_size = avctx->block_align; buf_size = avctx->block_align;
// XXX: do as per-channel loop for(i=0; i<avctx->channels; i++){
cs = &(c->status[0]); cs = &(c->status[i]);
cs->predictor = (*src++) & 0x0FF; cs->predictor = *src++;
cs->predictor |= ((*src++) << 8) & 0x0FF00; cs->predictor |= (*src++) << 8;
if(cs->predictor & 0x8000)
cs->predictor -= 0x10000;
CLAMP_TO_SHORT(cs->predictor);
// XXX: is this correct ??: *samples++ = cs->predictor;
cs->step_index = *src++;
if (cs->step_index < 0) cs->step_index = 0;
if (cs->step_index > 88) cs->step_index = 88;
if (*src++) av_log(avctx, AV_LOG_ERROR, "unused byte should be null !!\n"); /* unused */
if (st) {
cs = &(c->status[1]);
cs->predictor = (*src++) & 0x0FF;
cs->predictor |= ((*src++) << 8) & 0x0FF00;
if(cs->predictor & 0x8000) if(cs->predictor & 0x8000)
cs->predictor -= 0x10000; cs->predictor -= 0x10000;
CLAMP_TO_SHORT(cs->predictor); CLAMP_TO_SHORT(cs->predictor);
// XXX: is this correct ??: *samples++ = cs->predictor; // XXX: is this correct ??: *samples++ = cs->predictor;
cs->step_index = *src++; cs->step_index = *src++;
if (cs->step_index < 0) cs->step_index = 0; if (cs->step_index < 0) cs->step_index = 0;
if (cs->step_index > 88) cs->step_index = 88; if (cs->step_index > 88) cs->step_index = 88;
src++; /* if != 0 -> out-of-sync */ if (*src++) av_log(avctx, AV_LOG_ERROR, "unused byte should be null !!\n"); /* unused */
} }
for(m=4; src < (buf + buf_size);) { for(m=4; src < (buf + buf_size);) {
*samples++ = adpcm_ima_expand_nibble(&c->status[0], src[0] & 0x0F); *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[0] & 0x0F, 3);
if (st) if (st)
*samples++ = adpcm_ima_expand_nibble(&c->status[1], src[4] & 0x0F); *samples++ = adpcm_ima_expand_nibble(&c->status[1], src[4] & 0x0F, 3);
*samples++ = adpcm_ima_expand_nibble(&c->status[0], (src[0] >> 4) & 0x0F); *samples++ = adpcm_ima_expand_nibble(&c->status[0], (src[0] >> 4) & 0x0F, 3);
if (st) { if (st) {
*samples++ = adpcm_ima_expand_nibble(&c->status[1], (src[4] >> 4) & 0x0F); *samples++ = adpcm_ima_expand_nibble(&c->status[1], (src[4] >> 4) & 0x0F, 3);
if (!--m) { if (!--m) {
m=4; m=4;
src+=4; src+=4;
@@ -585,12 +546,12 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
m= (buf_size - (src - buf))>>st; m= (buf_size - (src - buf))>>st;
for(i=0; i<m; i++) { for(i=0; i<m; i++) {
*samples++ = adpcm_4xa_expand_nibble(&c->status[0], src[i] & 0x0F); *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[i] & 0x0F, 4);
if (st) if (st)
*samples++ = adpcm_4xa_expand_nibble(&c->status[1], src[i+m] & 0x0F); *samples++ = adpcm_ima_expand_nibble(&c->status[1], src[i+m] & 0x0F, 4);
*samples++ = adpcm_4xa_expand_nibble(&c->status[0], src[i] >> 4); *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[i] >> 4, 4);
if (st) if (st)
*samples++ = adpcm_4xa_expand_nibble(&c->status[1], src[i+m] >> 4); *samples++ = adpcm_ima_expand_nibble(&c->status[1], src[i+m] >> 4, 4);
} }
src += m<<st; src += m<<st;
@@ -664,16 +625,16 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
/* take care of the top nibble (always left or mono channel) */ /* take care of the top nibble (always left or mono channel) */
*samples++ = adpcm_ima_expand_nibble(&c->status[0], *samples++ = adpcm_ima_expand_nibble(&c->status[0],
(src[0] >> 4) & 0x0F); (src[0] >> 4) & 0x0F, 3);
/* take care of the bottom nibble, which is right sample for /* take care of the bottom nibble, which is right sample for
* stereo, or another mono sample */ * stereo, or another mono sample */
if (st) if (st)
*samples++ = adpcm_ima_expand_nibble(&c->status[1], *samples++ = adpcm_ima_expand_nibble(&c->status[1],
src[0] & 0x0F); src[0] & 0x0F, 3);
else else
*samples++ = adpcm_ima_expand_nibble(&c->status[0], *samples++ = adpcm_ima_expand_nibble(&c->status[0],
src[0] & 0x0F); src[0] & 0x0F, 3);
src++; src++;
} }
@@ -703,11 +664,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
/* process the first predictor of the sum channel */ /* process the first predictor of the sum channel */
DK3_GET_NEXT_NIBBLE(); DK3_GET_NEXT_NIBBLE();
adpcm_ima_expand_nibble(&c->status[0], nibble); adpcm_ima_expand_nibble(&c->status[0], nibble, 3);
/* process the diff channel predictor */ /* process the diff channel predictor */
DK3_GET_NEXT_NIBBLE(); DK3_GET_NEXT_NIBBLE();
adpcm_ima_expand_nibble(&c->status[1], nibble); adpcm_ima_expand_nibble(&c->status[1], nibble, 3);
/* process the first pair of stereo PCM samples */ /* process the first pair of stereo PCM samples */
diff_channel = (diff_channel + c->status[1].predictor) / 2; diff_channel = (diff_channel + c->status[1].predictor) / 2;
@@ -716,7 +677,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
/* process the second predictor of the sum channel */ /* process the second predictor of the sum channel */
DK3_GET_NEXT_NIBBLE(); DK3_GET_NEXT_NIBBLE();
adpcm_ima_expand_nibble(&c->status[0], nibble); adpcm_ima_expand_nibble(&c->status[0], nibble, 3);
/* process the second pair of stereo PCM samples */ /* process the second pair of stereo PCM samples */
diff_channel = (diff_channel + c->status[1].predictor) / 2; diff_channel = (diff_channel + c->status[1].predictor) / 2;
@@ -730,14 +691,14 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
if (st) { if (st) {
*samples++ = adpcm_ima_expand_nibble(&c->status[0], *samples++ = adpcm_ima_expand_nibble(&c->status[0],
(src[0] >> 4) & 0x0F); (src[0] >> 4) & 0x0F, 3);
*samples++ = adpcm_ima_expand_nibble(&c->status[1], *samples++ = adpcm_ima_expand_nibble(&c->status[1],
src[0] & 0x0F); src[0] & 0x0F, 3);
} else { } else {
*samples++ = adpcm_ima_expand_nibble(&c->status[0], *samples++ = adpcm_ima_expand_nibble(&c->status[0],
(src[0] >> 4) & 0x0F); (src[0] >> 4) & 0x0F, 3);
*samples++ = adpcm_ima_expand_nibble(&c->status[0], *samples++ = adpcm_ima_expand_nibble(&c->status[0],
src[0] & 0x0F); src[0] & 0x0F, 3);
} }
src++; src++;
@@ -73,6 +73,7 @@ void avcodec_register_all(void)
register_avcodec(&asv1_encoder); register_avcodec(&asv1_encoder);
register_avcodec(&asv2_encoder); register_avcodec(&asv2_encoder);
register_avcodec(&ffv1_encoder); register_avcodec(&ffv1_encoder);
register_avcodec(&zlib_encoder);
#endif /* CONFIG_ENCODERS */ #endif /* CONFIG_ENCODERS */
register_avcodec(&rawvideo_encoder); register_avcodec(&rawvideo_encoder);
register_avcodec(&rawvideo_decoder); register_avcodec(&rawvideo_decoder);
@@ -140,6 +141,10 @@ void avcodec_register_all(void)
register_avcodec(&smc_decoder); register_avcodec(&smc_decoder);
register_avcodec(&flic_decoder); register_avcodec(&flic_decoder);
register_avcodec(&truemotion1_decoder); register_avcodec(&truemotion1_decoder);
register_avcodec(&vmdvideo_decoder);
register_avcodec(&vmdaudio_decoder);
register_avcodec(&mszh_decoder);
register_avcodec(&zlib_decoder);
#ifdef CONFIG_AC3 #ifdef CONFIG_AC3
register_avcodec(&ac3_decoder); register_avcodec(&ac3_decoder);
#endif #endif
@@ -17,7 +17,7 @@ extern "C" {
#define FFMPEG_VERSION_INT 0x000408 #define FFMPEG_VERSION_INT 0x000408
#define FFMPEG_VERSION "0.4.8" #define FFMPEG_VERSION "0.4.8"
#define LIBAVCODEC_BUILD 4697 #define LIBAVCODEC_BUILD 4699
#define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT #define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT
#define LIBAVCODEC_VERSION FFMPEG_VERSION #define LIBAVCODEC_VERSION FFMPEG_VERSION
@@ -89,6 +89,10 @@ enum CodecID {
CODEC_ID_SMC, CODEC_ID_SMC,
CODEC_ID_FLIC, CODEC_ID_FLIC,
CODEC_ID_TRUEMOTION1, CODEC_ID_TRUEMOTION1,
CODEC_ID_VMDVIDEO,
CODEC_ID_VMDAUDIO,
CODEC_ID_MSZH,
CODEC_ID_ZLIB,
/* various pcm "codecs" */ /* various pcm "codecs" */
CODEC_ID_PCM_S16LE, CODEC_ID_PCM_S16LE,
@@ -263,7 +267,10 @@ static const __attribute__((unused)) int Motion_Est_QTab[] =
#define CODEC_FLAG_H263P_AIV 0x00000008 ///< H263 Alternative inter vlc #define CODEC_FLAG_H263P_AIV 0x00000008 ///< H263 Alternative inter vlc
#define CODEC_FLAG_OBMC 0x00000001 ///< OBMC #define CODEC_FLAG_OBMC 0x00000001 ///< OBMC
#define CODEC_FLAG_LOOP_FILTER 0x00000800 ///< loop filter #define CODEC_FLAG_LOOP_FILTER 0x00000800 ///< loop filter
#define CODEC_FLAG_H263P_SLICE_STRUCT 0x10000000 #define CODEC_FLAG_H263P_SLICE_STRUCT 0x10000000
#define CODEC_FLAG_INTERLACED_ME 0x20000000 ///< interlaced motion estimation
#define CODEC_FLAG_SVCD_SCAN_OFFSET 0x40000000 ///< will reserve space for SVCD scan offset user data
#define CODEC_FLAG_CLOSED_GOP 0x80000000
/* Unsupported options : /* Unsupported options :
* Syntax Arithmetic coding (SAC) * Syntax Arithmetic coding (SAC)
* Reference Picture Selection * Reference Picture Selection
@@ -956,6 +963,8 @@ typedef struct AVCodecContext {
/** /**
* qscale factor between p and i frames. * qscale factor between p and i frames.
* if > 0 then the last p frame quantizer will be used (q= lastp_q*factor+offset)
* if < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset)
* - encoding: set by user. * - encoding: set by user.
* - decoding: unused * - decoding: unused
*/ */
@@ -963,8 +972,6 @@ typedef struct AVCodecContext {
/** /**
* qscale offset between p and i frames. * qscale offset between p and i frames.
* if > 0 then the last p frame quantizer will be used (q= lastp_q*factor+offset)
* if < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset)
* - encoding: set by user. * - encoding: set by user.
* - decoding: unused * - decoding: unused
*/ */
@@ -1133,7 +1140,7 @@ typedef struct AVCodecContext {
#define FF_DEBUG_MB_TYPE 8 #define FF_DEBUG_MB_TYPE 8
#define FF_DEBUG_QP 16 #define FF_DEBUG_QP 16
#define FF_DEBUG_MV 32 #define FF_DEBUG_MV 32
#define FF_DEBUG_VIS_MV 0x00000040 //#define FF_DEBUG_VIS_MV 0x00000040
#define FF_DEBUG_SKIP 0x00000080 #define FF_DEBUG_SKIP 0x00000080
#define FF_DEBUG_STARTCODE 0x00000100 #define FF_DEBUG_STARTCODE 0x00000100
#define FF_DEBUG_PTS 0x00000200 #define FF_DEBUG_PTS 0x00000200
@@ -1143,6 +1150,16 @@ typedef struct AVCodecContext {
#define FF_DEBUG_VIS_QP 0x00002000 #define FF_DEBUG_VIS_QP 0x00002000
#define FF_DEBUG_VIS_MB_TYPE 0x00004000 #define FF_DEBUG_VIS_MB_TYPE 0x00004000
/**
* debug.
* - encoding: set by user.
* - decoding: set by user.
*/
int debug_mv;
#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames
#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames
#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames
/** /**
* error. * error.
* - encoding: set by lavc if flags&CODEC_FLAG_PSNR * - encoding: set by lavc if flags&CODEC_FLAG_PSNR
@@ -1182,6 +1199,12 @@ typedef struct AVCodecContext {
* - decoding: unused * - decoding: unused
*/ */
int mb_cmp; int mb_cmp;
/**
* interlaced dct compare function
* - encoding: set by user.
* - decoding: unused
*/
int ildct_cmp;
#define FF_CMP_SAD 0 #define FF_CMP_SAD 0
#define FF_CMP_SSE 1 #define FF_CMP_SSE 1
#define FF_CMP_SATD 2 #define FF_CMP_SATD 2
@@ -1190,6 +1213,8 @@ typedef struct AVCodecContext {
#define FF_CMP_BIT 5 #define FF_CMP_BIT 5
#define FF_CMP_RD 6 #define FF_CMP_RD 6
#define FF_CMP_ZERO 7 #define FF_CMP_ZERO 7
#define FF_CMP_VSAD 8
#define FF_CMP_VSSE 9
#define FF_CMP_CHROMA 256 #define FF_CMP_CHROMA 256
/** /**
@@ -1468,6 +1493,17 @@ typedef struct AVCodecContext {
* - decoding: unused. * - decoding: unused.
*/ */
int error_rate; int error_rate;
/**
* MP3 antialias algorithm, see FF_AA_* below.
* - encoding: unused
* - decoding: set by user
*/
int antialias_algo;
#define FF_AA_AUTO 0
#define FF_AA_FASTINT 1 //not implemented yet
#define FF_AA_INT 2
#define FF_AA_FLOAT 3
} AVCodecContext; } AVCodecContext;
@@ -1591,6 +1627,7 @@ extern AVCodec asv2_encoder;
extern AVCodec vcr1_encoder; extern AVCodec vcr1_encoder;
extern AVCodec ffv1_encoder; extern AVCodec ffv1_encoder;
extern AVCodec mdec_encoder; extern AVCodec mdec_encoder;
extern AVCodec zlib_encoder;
extern AVCodec h263_decoder; extern AVCodec h263_decoder;
extern AVCodec mpeg4_decoder; extern AVCodec mpeg4_decoder;
@@ -1651,7 +1688,11 @@ extern AVCodec idcin_decoder;
extern AVCodec eightbps_decoder; extern AVCodec eightbps_decoder;
extern AVCodec smc_decoder; extern AVCodec smc_decoder;
extern AVCodec flic_decoder; extern AVCodec flic_decoder;
extern AVCodec vmdvideo_decoder;
extern AVCodec vmdaudio_decoder;
extern AVCodec truemotion1_decoder; extern AVCodec truemotion1_decoder;
extern AVCodec mszh_decoder;
extern AVCodec zlib_decoder;
extern AVCodec ra_144_decoder; extern AVCodec ra_144_decoder;
extern AVCodec ra_288_decoder; extern AVCodec ra_288_decoder;
extern AVCodec roq_dpcm_decoder; extern AVCodec roq_dpcm_decoder;
@@ -1,6 +1,7 @@
/* /*
* Common bit i/o utils * Common bit i/o utils
* Copyright (c) 2000, 2001 Fabrice Bellard. * Copyright (c) 2000, 2001 Fabrice Bellard.
* Copyright (c) 2002-2004 Michael Niedermayer <[email protected]>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -59,7 +60,8 @@ void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
#endif #endif
} }
#ifdef CONFIG_ENCODERS //#ifdef CONFIG_ENCODERS
#if 1
/* return the number of bits output */ /* return the number of bits output */
int get_bit_count(PutBitContext *s) int get_bit_count(PutBitContext *s)
@@ -18,6 +18,10 @@
//#define A32_BITSTREAM_READER //#define A32_BITSTREAM_READER
#define LIBMPEG2_BITSTREAM_READER_HACK //add BERO #define LIBMPEG2_BITSTREAM_READER_HACK //add BERO
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifdef HAVE_AV_CONFIG_H #ifdef HAVE_AV_CONFIG_H
/* only include the following when compiling package */ /* only include the following when compiling package */
# include "config.h" # include "config.h"
@@ -37,10 +41,6 @@
# define ENODATA 61 # define ENODATA 61
# endif # endif
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#include <stddef.h> #include <stddef.h>
#ifndef offsetof #ifndef offsetof
# define offsetof(T,F) ((unsigned int)((char *)&((T *)0)->F)) # define offsetof(T,F) ((unsigned int)((char *)&((T *)0)->F))
@@ -82,6 +82,29 @@ extern const struct AVOption avoptions_workaround_bug[11];
# define always_inline inline # define always_inline inline
#endif #endif
#ifndef EMULATE_INTTYPES
# include <inttypes.h>
#else
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
# ifdef CONFIG_WIN32
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
# else /* other OS */
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
# endif /* other OS */
#endif /* HAVE_INTTYPES_H */
#ifndef INT64_MAX
#define INT64_MAX 9223372036854775807LL
#endif
#ifdef EMULATE_FAST_INT #ifdef EMULATE_FAST_INT
/* note that we don't emulate 64bit ints */ /* note that we don't emulate 64bit ints */
typedef signed char int_fast8_t; typedef signed char int_fast8_t;
@@ -102,15 +125,6 @@ static inline float floorf(float f) {
/* windows */ /* windows */
typedef unsigned short uint16_t;
typedef signed short int16_t;
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
typedef unsigned __int64 uint64_t;
typedef signed char int8_t;
typedef signed int int32_t;
typedef signed __int64 int64_t;
# ifndef __MINGW32__ # ifndef __MINGW32__
# define int64_t_C(c) (c ## i64) # define int64_t_C(c) (c ## i64)
# define uint64_t_C(c) (c ## i64) # define uint64_t_C(c) (c ## i64)
@@ -137,8 +151,6 @@ typedef signed __int64 int64_t;
#elif defined (CONFIG_OS2) #elif defined (CONFIG_OS2)
/* OS/2 EMX */ /* OS/2 EMX */
#include <inttypes.h>
#ifndef int64_t_C #ifndef int64_t_C
#define int64_t_C(c) (c ## LL) #define int64_t_C(c) (c ## LL)
#define uint64_t_C(c) (c ## ULL) #define uint64_t_C(c) (c ## ULL)
@@ -159,8 +171,6 @@ typedef signed __int64 int64_t;
/* unix */ /* unix */
#include <inttypes.h>
#ifndef int64_t_C #ifndef int64_t_C
#define int64_t_C(c) (c ## LL) #define int64_t_C(c) (c ## LL)
#define uint64_t_C(c) (c ## ULL) #define uint64_t_C(c) (c ## ULL)
@@ -201,13 +211,9 @@ inline void dprintf(const char* fmt,...) {}
# else # else
# ifdef DEBUG # ifdef DEBUG
# if defined(__BEOS__) # define dprintf(fmt,...) printf(fmt, __VA_ARGS__)
# define dprintf(fmt...) printf(fmt)
# else
# define dprintf(fmt,...) printf(fmt, __VA_ARGS__)
# endif
# else # else
# if defined(__BEOS__) # if defined(CONFIG_BEOS)
# define dprintf(fmt...) # define dprintf(fmt...)
# else # else
# define dprintf(fmt,...) # define dprintf(fmt,...)
@@ -1014,23 +1020,31 @@ static inline int av_log2_16bit(unsigned int v)
return n; return n;
} }
/* median of 3 */ /* median of 3 */
static inline int mid_pred(int a, int b, int c) static inline int mid_pred(int a, int b, int c)
{ {
int vmin, vmax; #if 0
vmax = vmin = a; int t= (a-b)&((a-b)>>31);
if (b < vmin) a-=t;
vmin = b; b+=t;
else b-= (b-c)&((b-c)>>31);
vmax = b; b+= (a-b)&((a-b)>>31);
if (c < vmin) return b;
vmin = c; #else
else if (c > vmax) if(a>b){
vmax = c; if(c>b){
if(c>a) b=a;
return a + b + c - vmin - vmax; else b=c;
}
}else{
if(b>c){
if(c>a) b=c;
else b=a;
}
}
return b;
#endif
} }
static inline int clip(int a, int amin, int amax) static inline int clip(int a, int amin, int amax)
@@ -125,6 +125,9 @@ static int dpcm_decode_frame(AVCodecContext *avctx,
unsigned char byte; unsigned char byte;
short diff; short diff;
if (!buf_size)
return 0;
switch(avctx->codec->id) { switch(avctx->codec->id) {
case CODEC_ID_ROQ_DPCM: case CODEC_ID_ROQ_DPCM:
@@ -1,6 +1,7 @@
/* /*
* DSP utils * DSP utils
* Copyright (c) 2000, 2001 Fabrice Bellard. * Copyright (c) 2000, 2001 Fabrice Bellard.
* Copyright (c) 2002-2004 Michael Niedermayer <[email protected]>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -218,13 +219,13 @@ static void bswap_buf(uint32_t *dst, uint32_t *src, int w){
} }
} }
static int sse8_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size) static int sse8_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h)
{ {
int s, i; int s, i;
uint32_t *sq = squareTbl + 256; uint32_t *sq = squareTbl + 256;
s = 0; s = 0;
for (i = 0; i < 8; i++) { for (i = 0; i < h; i++) {
s += sq[pix1[0] - pix2[0]]; s += sq[pix1[0] - pix2[0]];
s += sq[pix1[1] - pix2[1]]; s += sq[pix1[1] - pix2[1]];
s += sq[pix1[2] - pix2[2]]; s += sq[pix1[2] - pix2[2]];
@@ -239,13 +240,13 @@ static int sse8_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size)
return s; return s;
} }
static int sse16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size) static int sse16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
{ {
int s, i; int s, i;
uint32_t *sq = squareTbl + 256; uint32_t *sq = squareTbl + 256;
s = 0; s = 0;
for (i = 0; i < 16; i++) { for (i = 0; i < h; i++) {
s += sq[pix1[ 0] - pix2[ 0]]; s += sq[pix1[ 0] - pix2[ 0]];
s += sq[pix1[ 1] - pix2[ 1]]; s += sq[pix1[ 1] - pix2[ 1]];
s += sq[pix1[ 2] - pix2[ 2]]; s += sq[pix1[ 2] - pix2[ 2]];
@@ -2331,12 +2332,12 @@ static void h263_h_loop_filter_c(uint8_t *src, int stride, int qscale){
} }
} }
static inline int pix_abs16x16_c(uint8_t *pix1, uint8_t *pix2, int line_size) static inline int pix_abs16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
{ {
int s, i; int s, i;
s = 0; s = 0;
for(i=0;i<16;i++) { for(i=0;i<h;i++) {
s += abs(pix1[0] - pix2[0]); s += abs(pix1[0] - pix2[0]);
s += abs(pix1[1] - pix2[1]); s += abs(pix1[1] - pix2[1]);
s += abs(pix1[2] - pix2[2]); s += abs(pix1[2] - pix2[2]);
@@ -2359,12 +2360,12 @@ static inline int pix_abs16x16_c(uint8_t *pix1, uint8_t *pix2, int line_size)
return s; return s;
} }
static int pix_abs16x16_x2_c(uint8_t *pix1, uint8_t *pix2, int line_size) static int pix_abs16_x2_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
{ {
int s, i; int s, i;
s = 0; s = 0;
for(i=0;i<16;i++) { for(i=0;i<h;i++) {
s += abs(pix1[0] - avg2(pix2[0], pix2[1])); s += abs(pix1[0] - avg2(pix2[0], pix2[1]));
s += abs(pix1[1] - avg2(pix2[1], pix2[2])); s += abs(pix1[1] - avg2(pix2[1], pix2[2]));
s += abs(pix1[2] - avg2(pix2[2], pix2[3])); s += abs(pix1[2] - avg2(pix2[2], pix2[3]));
@@ -2387,13 +2388,13 @@ static int pix_abs16x16_x2_c(uint8_t *pix1, uint8_t *pix2, int line_size)
return s; return s;
} }
static int pix_abs16x16_y2_c(uint8_t *pix1, uint8_t *pix2, int line_size) static int pix_abs16_y2_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
{ {
int s, i; int s, i;
uint8_t *pix3 = pix2 + line_size; uint8_t *pix3 = pix2 + line_size;
s = 0; s = 0;
for(i=0;i<16;i++) { for(i=0;i<h;i++) {
s += abs(pix1[0] - avg2(pix2[0], pix3[0])); s += abs(pix1[0] - avg2(pix2[0], pix3[0]));
s += abs(pix1[1] - avg2(pix2[1], pix3[1])); s += abs(pix1[1] - avg2(pix2[1], pix3[1]));
s += abs(pix1[2] - avg2(pix2[2], pix3[2])); s += abs(pix1[2] - avg2(pix2[2], pix3[2]));
@@ -2417,13 +2418,13 @@ static int pix_abs16x16_y2_c(uint8_t *pix1, uint8_t *pix2, int line_size)
return s; return s;
} }
static int pix_abs16x16_xy2_c(uint8_t *pix1, uint8_t *pix2, int line_size) static int pix_abs16_xy2_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
{ {
int s, i; int s, i;
uint8_t *pix3 = pix2 + line_size; uint8_t *pix3 = pix2 + line_size;
s = 0; s = 0;
for(i=0;i<16;i++) { for(i=0;i<h;i++) {
s += abs(pix1[0] - avg4(pix2[0], pix2[1], pix3[0], pix3[1])); s += abs(pix1[0] - avg4(pix2[0], pix2[1], pix3[0], pix3[1]));
s += abs(pix1[1] - avg4(pix2[1], pix2[2], pix3[1], pix3[2])); s += abs(pix1[1] - avg4(pix2[1], pix2[2], pix3[1], pix3[2]));
s += abs(pix1[2] - avg4(pix2[2], pix2[3], pix3[2], pix3[3])); s += abs(pix1[2] - avg4(pix2[2], pix2[3], pix3[2], pix3[3]));
@@ -2447,12 +2448,12 @@ static int pix_abs16x16_xy2_c(uint8_t *pix1, uint8_t *pix2, int line_size)
return s; return s;
} }
static inline int pix_abs8x8_c(uint8_t *pix1, uint8_t *pix2, int line_size) static inline int pix_abs8_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
{ {
int s, i; int s, i;
s = 0; s = 0;
for(i=0;i<8;i++) { for(i=0;i<h;i++) {
s += abs(pix1[0] - pix2[0]); s += abs(pix1[0] - pix2[0]);
s += abs(pix1[1] - pix2[1]); s += abs(pix1[1] - pix2[1]);
s += abs(pix1[2] - pix2[2]); s += abs(pix1[2] - pix2[2]);
@@ -2467,12 +2468,12 @@ static inline int pix_abs8x8_c(uint8_t *pix1, uint8_t *pix2, int line_size)
return s; return s;
} }
static int pix_abs8x8_x2_c(uint8_t *pix1, uint8_t *pix2, int line_size) static int pix_abs8_x2_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
{ {
int s, i; int s, i;
s = 0; s = 0;
for(i=0;i<8;i++) { for(i=0;i<h;i++) {
s += abs(pix1[0] - avg2(pix2[0], pix2[1])); s += abs(pix1[0] - avg2(pix2[0], pix2[1]));
s += abs(pix1[1] - avg2(pix2[1], pix2[2])); s += abs(pix1[1] - avg2(pix2[1], pix2[2]));
s += abs(pix1[2] - avg2(pix2[2], pix2[3])); s += abs(pix1[2] - avg2(pix2[2], pix2[3]));
@@ -2487,13 +2488,13 @@ static int pix_abs8x8_x2_c(uint8_t *pix1, uint8_t *pix2, int line_size)
return s; return s;
} }
static int pix_abs8x8_y2_c(uint8_t *pix1, uint8_t *pix2, int line_size) static int pix_abs8_y2_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
{ {
int s, i; int s, i;
uint8_t *pix3 = pix2 + line_size; uint8_t *pix3 = pix2 + line_size;
s = 0; s = 0;
for(i=0;i<8;i++) { for(i=0;i<h;i++) {
s += abs(pix1[0] - avg2(pix2[0], pix3[0])); s += abs(pix1[0] - avg2(pix2[0], pix3[0]));
s += abs(pix1[1] - avg2(pix2[1], pix3[1])); s += abs(pix1[1] - avg2(pix2[1], pix3[1]));
s += abs(pix1[2] - avg2(pix2[2], pix3[2])); s += abs(pix1[2] - avg2(pix2[2], pix3[2]));
@@ -2509,13 +2510,13 @@ static int pix_abs8x8_y2_c(uint8_t *pix1, uint8_t *pix2, int line_size)
return s; return s;
} }
static int pix_abs8x8_xy2_c(uint8_t *pix1, uint8_t *pix2, int line_size) static int pix_abs8_xy2_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
{ {
int s, i; int s, i;
uint8_t *pix3 = pix2 + line_size; uint8_t *pix3 = pix2 + line_size;
s = 0; s = 0;
for(i=0;i<8;i++) { for(i=0;i<h;i++) {
s += abs(pix1[0] - avg4(pix2[0], pix2[1], pix3[0], pix3[1])); s += abs(pix1[0] - avg4(pix2[0], pix2[1], pix3[0], pix3[1]));
s += abs(pix1[1] - avg4(pix2[1], pix2[2], pix3[1], pix3[2])); s += abs(pix1[1] - avg4(pix2[1], pix2[2], pix3[1], pix3[2]));
s += abs(pix1[2] - avg4(pix2[2], pix2[3], pix3[2], pix3[3])); s += abs(pix1[2] - avg4(pix2[2], pix2[3], pix3[2], pix3[3]));
@@ -2531,14 +2532,6 @@ static int pix_abs8x8_xy2_c(uint8_t *pix1, uint8_t *pix2, int line_size)
return s; return s;
} }
static int sad16x16_c(void *s, uint8_t *a, uint8_t *b, int stride){
return pix_abs16x16_c(a,b,stride);
}
static int sad8x8_c(void *s, uint8_t *a, uint8_t *b, int stride){
return pix_abs8x8_c(a,b,stride);
}
/** /**
* permutes an 8x8 block. * permutes an 8x8 block.
* @param block the block which will be permuted according to the given permutation vector * @param block the block which will be permuted according to the given permutation vector
@@ -2568,6 +2561,53 @@ void ff_block_permute(DCTELEM *block, uint8_t *permutation, const uint8_t *scant
} }
} }
static int zero_cmp(void *s, uint8_t *a, uint8_t *b, int stride, int h){
return 0;
}
void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type){
int i;
memset(cmp, 0, sizeof(void*)*5);
for(i=0; i<5; i++){
switch(type&0xFF){
case FF_CMP_SAD:
cmp[i]= c->sad[i];
break;
case FF_CMP_SATD:
cmp[i]= c->hadamard8_diff[i];
break;
case FF_CMP_SSE:
cmp[i]= c->sse[i];
break;
case FF_CMP_DCT:
cmp[i]= c->dct_sad[i];
break;
case FF_CMP_PSNR:
cmp[i]= c->quant_psnr[i];
break;
case FF_CMP_BIT:
cmp[i]= c->bit[i];
break;
case FF_CMP_RD:
cmp[i]= c->rd[i];
break;
case FF_CMP_VSAD:
cmp[i]= c->vsad[i];
break;
case FF_CMP_VSSE:
cmp[i]= c->vsse[i];
break;
case FF_CMP_ZERO:
cmp[i]= zero_cmp;
break;
default:
av_log(NULL, AV_LOG_ERROR,"internal error in cmp function selection\n");
}
}
}
/** /**
* memset(blocks, 0, sizeof(DCTELEM)*6*64) * memset(blocks, 0, sizeof(DCTELEM)*6*64)
*/ */
@@ -2641,10 +2681,12 @@ o2= (i1)-(i2);
#define BUTTERFLYA(x,y) (ABS((x)+(y)) + ABS((x)-(y))) #define BUTTERFLYA(x,y) (ABS((x)+(y)) + ABS((x)-(y)))
static int hadamard8_diff_c(/*MpegEncContext*/ void *s, uint8_t *dst, uint8_t *src, int stride){ static int hadamard8_diff8x8_c(/*MpegEncContext*/ void *s, uint8_t *dst, uint8_t *src, int stride, int h){
int i; int i;
int temp[64]; int temp[64];
int sum=0; int sum=0;
assert(h==8);
for(i=0; i<8; i++){ for(i=0; i<8; i++){
//FIXME try pointer walks //FIXME try pointer walks
@@ -2691,17 +2733,19 @@ if(sum>maxi){
return sum; return sum;
} }
static int hadamard8_abs_c(uint8_t *src, int stride, int mean){ static int hadamard8_intra8x8_c(/*MpegEncContext*/ void *s, uint8_t *src, uint8_t *dummy, int stride, int h){
int i; int i;
int temp[64]; int temp[64];
int sum=0; int sum=0;
//FIXME OOOPS ignore 0 term instead of mean mess
assert(h==8);
for(i=0; i<8; i++){ for(i=0; i<8; i++){
//FIXME try pointer walks //FIXME try pointer walks
BUTTERFLY2(temp[8*i+0], temp[8*i+1], src[stride*i+0]-mean,src[stride*i+1]-mean); BUTTERFLY2(temp[8*i+0], temp[8*i+1], src[stride*i+0],src[stride*i+1]);
BUTTERFLY2(temp[8*i+2], temp[8*i+3], src[stride*i+2]-mean,src[stride*i+3]-mean); BUTTERFLY2(temp[8*i+2], temp[8*i+3], src[stride*i+2],src[stride*i+3]);
BUTTERFLY2(temp[8*i+4], temp[8*i+5], src[stride*i+4]-mean,src[stride*i+5]-mean); BUTTERFLY2(temp[8*i+4], temp[8*i+5], src[stride*i+4],src[stride*i+5]);
BUTTERFLY2(temp[8*i+6], temp[8*i+7], src[stride*i+6]-mean,src[stride*i+7]-mean); BUTTERFLY2(temp[8*i+6], temp[8*i+7], src[stride*i+6],src[stride*i+7]);
BUTTERFLY1(temp[8*i+0], temp[8*i+2]); BUTTERFLY1(temp[8*i+0], temp[8*i+2]);
BUTTERFLY1(temp[8*i+1], temp[8*i+3]); BUTTERFLY1(temp[8*i+1], temp[8*i+3]);
@@ -2732,14 +2776,18 @@ static int hadamard8_abs_c(uint8_t *src, int stride, int mean){
+BUTTERFLYA(temp[8*3+i], temp[8*7+i]); +BUTTERFLYA(temp[8*3+i], temp[8*7+i]);
} }
sum -= ABS(temp[8*0] + temp[8*4]); // -mean
return sum; return sum;
} }
static int dct_sad8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride){ static int dct_sad8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){
MpegEncContext * const s= (MpegEncContext *)c; MpegEncContext * const s= (MpegEncContext *)c;
uint64_t __align8 aligned_temp[sizeof(DCTELEM)*64/8]; uint64_t __align8 aligned_temp[sizeof(DCTELEM)*64/8];
DCTELEM * const temp= (DCTELEM*)aligned_temp; DCTELEM * const temp= (DCTELEM*)aligned_temp;
int sum=0, i; int sum=0, i;
assert(h==8);
s->dsp.diff_pixels(temp, src1, src2, stride); s->dsp.diff_pixels(temp, src1, src2, stride);
s->dsp.fdct(temp); s->dsp.fdct(temp);
@@ -2752,13 +2800,14 @@ static int dct_sad8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2
void simple_idct(DCTELEM *block); //FIXME void simple_idct(DCTELEM *block); //FIXME
static int quant_psnr8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride){ static int quant_psnr8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){
MpegEncContext * const s= (MpegEncContext *)c; MpegEncContext * const s= (MpegEncContext *)c;
uint64_t __align8 aligned_temp[sizeof(DCTELEM)*64*2/8]; uint64_t __align8 aligned_temp[sizeof(DCTELEM)*64*2/8];
DCTELEM * const temp= (DCTELEM*)aligned_temp; DCTELEM * const temp= (DCTELEM*)aligned_temp;
DCTELEM * const bak = ((DCTELEM*)aligned_temp)+64; DCTELEM * const bak = ((DCTELEM*)aligned_temp)+64;
int sum=0, i; int sum=0, i;
assert(h==8);
s->mb_intra=0; s->mb_intra=0;
s->dsp.diff_pixels(temp, src1, src2, stride); s->dsp.diff_pixels(temp, src1, src2, stride);
@@ -2775,7 +2824,7 @@ static int quant_psnr8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *s
return sum; return sum;
} }
static int rd8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride){ static int rd8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){
MpegEncContext * const s= (MpegEncContext *)c; MpegEncContext * const s= (MpegEncContext *)c;
const uint8_t *scantable= s->intra_scantable.permutated; const uint8_t *scantable= s->intra_scantable.permutated;
uint64_t __align8 aligned_temp[sizeof(DCTELEM)*64/8]; uint64_t __align8 aligned_temp[sizeof(DCTELEM)*64/8];
@@ -2787,6 +2836,8 @@ static int rd8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int
uint8_t * length; uint8_t * length;
uint8_t * last_length; uint8_t * last_length;
assert(h==8);
for(i=0; i<8; i++){ for(i=0; i<8; i++){
((uint32_t*)(bak + i*stride))[0]= ((uint32_t*)(src2 + i*stride))[0]; ((uint32_t*)(bak + i*stride))[0]= ((uint32_t*)(src2 + i*stride))[0];
((uint32_t*)(bak + i*stride))[1]= ((uint32_t*)(src2 + i*stride))[1]; ((uint32_t*)(bak + i*stride))[1]= ((uint32_t*)(src2 + i*stride))[1];
@@ -2847,12 +2898,12 @@ static int rd8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int
s->dsp.idct_add(bak, stride, temp); s->dsp.idct_add(bak, stride, temp);
distoration= s->dsp.sse[1](NULL, bak, src1, stride); distoration= s->dsp.sse[1](NULL, bak, src1, stride, 8);
return distoration + ((bits*s->qscale*s->qscale*109 + 64)>>7); return distoration + ((bits*s->qscale*s->qscale*109 + 64)>>7);
} }
static int bit8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride){ static int bit8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){
MpegEncContext * const s= (MpegEncContext *)c; MpegEncContext * const s= (MpegEncContext *)c;
const uint8_t *scantable= s->intra_scantable.permutated; const uint8_t *scantable= s->intra_scantable.permutated;
uint64_t __align8 aligned_temp[sizeof(DCTELEM)*64/8]; uint64_t __align8 aligned_temp[sizeof(DCTELEM)*64/8];
@@ -2861,6 +2912,8 @@ static int bit8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, in
const int esc_length= s->ac_esc_length; const int esc_length= s->ac_esc_length;
uint8_t * length; uint8_t * length;
uint8_t * last_length; uint8_t * last_length;
assert(h==8);
s->dsp.diff_pixels(temp, src1, src2, stride); s->dsp.diff_pixels(temp, src1, src2, stride);
@@ -2910,12 +2963,73 @@ static int bit8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, in
return bits; return bits;
} }
static int vsad_intra16_c(/*MpegEncContext*/ void *c, uint8_t *s, uint8_t *dummy, int stride, int h){
int score=0;
int x,y;
for(y=1; y<h; y++){
for(x=0; x<16; x+=4){
score+= ABS(s[x ] - s[x +stride]) + ABS(s[x+1] - s[x+1+stride])
+ABS(s[x+2] - s[x+2+stride]) + ABS(s[x+3] - s[x+3+stride]);
}
s+= stride;
}
return score;
}
WARPER88_1616(hadamard8_diff_c, hadamard8_diff16_c) static int vsad16_c(/*MpegEncContext*/ void *c, uint8_t *s1, uint8_t *s2, int stride, int h){
WARPER88_1616(dct_sad8x8_c, dct_sad16x16_c) int score=0;
WARPER88_1616(quant_psnr8x8_c, quant_psnr16x16_c) int x,y;
WARPER88_1616(rd8x8_c, rd16x16_c)
WARPER88_1616(bit8x8_c, bit16x16_c) for(y=1; y<h; y++){
for(x=0; x<16; x++){
score+= ABS(s1[x ] - s2[x ] - s1[x +stride] + s2[x +stride]);
}
s1+= stride;
s2+= stride;
}
return score;
}
#define SQ(a) ((a)*(a))
static int vsse_intra16_c(/*MpegEncContext*/ void *c, uint8_t *s, uint8_t *dummy, int stride, int h){
int score=0;
int x,y;
for(y=1; y<h; y++){
for(x=0; x<16; x+=4){
score+= SQ(s[x ] - s[x +stride]) + SQ(s[x+1] - s[x+1+stride])
+SQ(s[x+2] - s[x+2+stride]) + SQ(s[x+3] - s[x+3+stride]);
}
s+= stride;
}
return score;
}
static int vsse16_c(/*MpegEncContext*/ void *c, uint8_t *s1, uint8_t *s2, int stride, int h){
int score=0;
int x,y;
for(y=1; y<h; y++){
for(x=0; x<16; x++){
score+= SQ(s1[x ] - s2[x ] - s1[x +stride] + s2[x +stride]);
}
s1+= stride;
s2+= stride;
}
return score;
}
WARPER8_16_SQ(hadamard8_diff8x8_c, hadamard8_diff16_c)
WARPER8_16_SQ(hadamard8_intra8x8_c, hadamard8_intra16_c)
WARPER8_16_SQ(dct_sad8x8_c, dct_sad16_c)
WARPER8_16_SQ(quant_psnr8x8_c, quant_psnr16_c)
WARPER8_16_SQ(rd8x8_c, rd16_c)
WARPER8_16_SQ(bit8x8_c, bit16_c)
/* XXX: those functions should be suppressed ASAP when all IDCTs are /* XXX: those functions should be suppressed ASAP when all IDCTs are
converted */ converted */
@@ -2989,18 +3103,16 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx)
c->clear_blocks = clear_blocks_c; c->clear_blocks = clear_blocks_c;
c->pix_sum = pix_sum_c; c->pix_sum = pix_sum_c;
c->pix_norm1 = pix_norm1_c; c->pix_norm1 = pix_norm1_c;
c->sse[0]= sse16_c;
c->sse[1]= sse8_c;
/* TODO [0] 16 [1] 8 */ /* TODO [0] 16 [1] 8 */
c->pix_abs16x16 = pix_abs16x16_c; c->pix_abs[0][0] = pix_abs16_c;
c->pix_abs16x16_x2 = pix_abs16x16_x2_c; c->pix_abs[0][1] = pix_abs16_x2_c;
c->pix_abs16x16_y2 = pix_abs16x16_y2_c; c->pix_abs[0][2] = pix_abs16_y2_c;
c->pix_abs16x16_xy2 = pix_abs16x16_xy2_c; c->pix_abs[0][3] = pix_abs16_xy2_c;
c->pix_abs8x8 = pix_abs8x8_c; c->pix_abs[1][0] = pix_abs8_c;
c->pix_abs8x8_x2 = pix_abs8x8_x2_c; c->pix_abs[1][1] = pix_abs8_x2_c;
c->pix_abs8x8_y2 = pix_abs8x8_y2_c; c->pix_abs[1][2] = pix_abs8_y2_c;
c->pix_abs8x8_xy2 = pix_abs8x8_xy2_c; c->pix_abs[1][3] = pix_abs8_xy2_c;
#define dspfunc(PFX, IDX, NUM) \ #define dspfunc(PFX, IDX, NUM) \
c->PFX ## _pixels_tab[IDX][0] = PFX ## _pixels ## NUM ## _c; \ c->PFX ## _pixels_tab[IDX][0] = PFX ## _pixels ## NUM ## _c; \
@@ -3097,24 +3209,24 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx)
c->put_mspel_pixels_tab[6]= put_mspel8_mc22_c; c->put_mspel_pixels_tab[6]= put_mspel8_mc22_c;
c->put_mspel_pixels_tab[7]= put_mspel8_mc32_c; c->put_mspel_pixels_tab[7]= put_mspel8_mc32_c;
c->hadamard8_diff[0]= hadamard8_diff16_c; #define SET_CMP_FUNC(name) \
c->hadamard8_diff[1]= hadamard8_diff_c; c->name[0]= name ## 16_c;\
c->hadamard8_abs = hadamard8_abs_c; c->name[1]= name ## 8x8_c;
c->dct_sad[0]= dct_sad16x16_c; SET_CMP_FUNC(hadamard8_diff)
c->dct_sad[1]= dct_sad8x8_c; c->hadamard8_diff[4]= hadamard8_intra16_c;
SET_CMP_FUNC(dct_sad)
c->sad[0]= sad16x16_c; c->sad[0]= pix_abs16_c;
c->sad[1]= sad8x8_c; c->sad[1]= pix_abs8_c;
c->sse[0]= sse16_c;
c->quant_psnr[0]= quant_psnr16x16_c; c->sse[1]= sse8_c;
c->quant_psnr[1]= quant_psnr8x8_c; SET_CMP_FUNC(quant_psnr)
SET_CMP_FUNC(rd)
c->rd[0]= rd16x16_c; SET_CMP_FUNC(bit)
c->rd[1]= rd8x8_c; c->vsad[0]= vsad16_c;
c->vsad[4]= vsad_intra16_c;
c->bit[0]= bit16x16_c; c->vsse[0]= vsse16_c;
c->bit[1]= bit8x8_c; c->vsse[4]= vsse_intra16_c;
c->add_bytes= add_bytes_c; c->add_bytes= add_bytes_c;
c->diff_bytes= diff_bytes_c; c->diff_bytes= diff_bytes_c;
@@ -1,6 +1,7 @@
/* /*
* DSP utils * DSP utils
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard. * Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -44,6 +45,7 @@ void j_rev_dct (DCTELEM *data);
void ff_fdct_mmx(DCTELEM *block); void ff_fdct_mmx(DCTELEM *block);
void ff_fdct_mmx2(DCTELEM *block); void ff_fdct_mmx2(DCTELEM *block);
void ff_fdct_sse2(DCTELEM *block);
/* encoding scans */ /* encoding scans */
extern const uint8_t ff_alternate_horizontal_scan[64]; extern const uint8_t ff_alternate_horizontal_scan[64];
@@ -79,6 +81,7 @@ void clear_blocks_c(DCTELEM *blocks);
/* add and put pixel (decoding) */ /* add and put pixel (decoding) */
// blocksizes for op_pixels_func are 8x4,8x8 16x8 16x16 // blocksizes for op_pixels_func are 8x4,8x8 16x8 16x16
//h for op_pixels_func is limited to {width/2, width} but never larger than 16 and never smaller then 4
typedef void (*op_pixels_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int h); typedef void (*op_pixels_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int h);
typedef void (*tpel_mc_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int w, int h); typedef void (*tpel_mc_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int w, int h);
typedef void (*qpel_mc_func)(uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride); typedef void (*qpel_mc_func)(uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);
@@ -109,10 +112,9 @@ static void a(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
} }
/* motion estimation */ /* motion estimation */
// h is limited to {width/2, width, 2*width} but never larger than 16 and never smaller then 2
typedef int (*op_pixels_abs_func)(uint8_t *blk1/*align width (8 or 16)*/, uint8_t *blk2/*align 1*/, int line_size)/* __attribute__ ((const))*/; // allthough currently h<4 is not used as functions with width <8 are not used and neither implemented
typedef int (*me_cmp_func)(void /*MpegEncContext*/ *s, uint8_t *blk1/*align width (8 or 16)*/, uint8_t *blk2/*align 1*/, int line_size, int h)/* __attribute__ ((const))*/;
typedef int (*me_cmp_func)(void /*MpegEncContext*/ *s, uint8_t *blk1/*align width (8 or 16)*/, uint8_t *blk2/*align 1*/, int line_size)/* __attribute__ ((const))*/;
/** /**
@@ -136,25 +138,28 @@ typedef struct DSPContext {
void (*clear_blocks)(DCTELEM *blocks/*align 16*/); void (*clear_blocks)(DCTELEM *blocks/*align 16*/);
int (*pix_sum)(uint8_t * pix, int line_size); int (*pix_sum)(uint8_t * pix, int line_size);
int (*pix_norm1)(uint8_t * pix, int line_size); int (*pix_norm1)(uint8_t * pix, int line_size);
me_cmp_func sad[2]; /* identical to pix_absAxA except additional void * */ // 16x16 8x8 4x4 2x2 16x8 8x4 4x2 8x16 4x8 2x4
me_cmp_func sse[2];
me_cmp_func hadamard8_diff[2]; me_cmp_func sad[5]; /* identical to pix_absAxA except additional void * */
me_cmp_func dct_sad[2]; me_cmp_func sse[5];
me_cmp_func quant_psnr[2]; me_cmp_func hadamard8_diff[5];
me_cmp_func bit[2]; me_cmp_func dct_sad[5];
me_cmp_func rd[2]; me_cmp_func quant_psnr[5];
int (*hadamard8_abs )(uint8_t *src, int stride, int mean); me_cmp_func bit[5];
me_cmp_func rd[5];
me_cmp_func vsad[5];
me_cmp_func vsse[5];
me_cmp_func me_pre_cmp[11]; me_cmp_func me_pre_cmp[5];
me_cmp_func me_cmp[11]; me_cmp_func me_cmp[5];
me_cmp_func me_sub_cmp[11]; me_cmp_func me_sub_cmp[5];
me_cmp_func mb_cmp[11]; me_cmp_func mb_cmp[5];
me_cmp_func ildct_cmp[5]; //only width 16 used
/* maybe create an array for 16/8/4/2 functions */
/** /**
* Halfpel motion compensation with rounding (a+b+1)>>1. * Halfpel motion compensation with rounding (a+b+1)>>1.
* this is an array[4][4] of motion compensation funcions for 4 * this is an array[4][4] of motion compensation funcions for 4
* horizontal blocksizes (2,4,8,16) and the 4 halfpel positions<br> * horizontal blocksizes (8,16) and the 4 halfpel positions<br>
* *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
* @param block destination where the result is stored * @param block destination where the result is stored
* @param pixels source * @param pixels source
@@ -166,7 +171,7 @@ typedef struct DSPContext {
/** /**
* Halfpel motion compensation with rounding (a+b+1)>>1. * Halfpel motion compensation with rounding (a+b+1)>>1.
* This is an array[4][4] of motion compensation functions for 4 * This is an array[4][4] of motion compensation functions for 4
* horizontal blocksizes (2,4,8,16) and the 4 halfpel positions<br> * horizontal blocksizes (8,16) and the 4 halfpel positions<br>
* *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
* @param block destination into which the result is averaged (a+b+1)>>1 * @param block destination into which the result is averaged (a+b+1)>>1
* @param pixels source * @param pixels source
@@ -226,14 +231,7 @@ typedef struct DSPContext {
qpel_mc_func put_h264_qpel_pixels_tab[3][16]; qpel_mc_func put_h264_qpel_pixels_tab[3][16];
qpel_mc_func avg_h264_qpel_pixels_tab[3][16]; qpel_mc_func avg_h264_qpel_pixels_tab[3][16];
op_pixels_abs_func pix_abs16x16; me_cmp_func pix_abs[2][4];
op_pixels_abs_func pix_abs16x16_x2;
op_pixels_abs_func pix_abs16x16_y2;
op_pixels_abs_func pix_abs16x16_xy2;
op_pixels_abs_func pix_abs8x8;
op_pixels_abs_func pix_abs8x8_x2;
op_pixels_abs_func pix_abs8x8_y2;
op_pixels_abs_func pix_abs8x8_xy2;
/* huffyuv specific */ /* huffyuv specific */
void (*add_bytes)(uint8_t *dst/*align 16*/, uint8_t *src/*align 16*/, int w); void (*add_bytes)(uint8_t *dst/*align 16*/, uint8_t *src/*align 16*/, int w);
@@ -298,6 +296,8 @@ void dsputil_init(DSPContext* p, AVCodecContext *avctx);
*/ */
void ff_block_permute(DCTELEM *block, uint8_t *permutation, const uint8_t *scantable, int last); void ff_block_permute(DCTELEM *block, uint8_t *permutation, const uint8_t *scantable, int last);
void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type);
#define BYTE_VEC32(c) ((c)*0x01010101UL) #define BYTE_VEC32(c) ((c)*0x01010101UL)
static inline uint32_t rnd_avg32(uint32_t a, uint32_t b) static inline uint32_t rnd_avg32(uint32_t a, uint32_t b)
@@ -484,12 +484,24 @@ void ff_mdct_calc(MDCTContext *s, FFTSample *out,
const FFTSample *input, FFTSample *tmp); const FFTSample *input, FFTSample *tmp);
void ff_mdct_end(MDCTContext *s); void ff_mdct_end(MDCTContext *s);
#define WARPER88_1616(name8, name16)\ #define WARPER8_16(name8, name16)\
static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride){\ static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\
return name8(s, dst , src , stride)\ return name8(s, dst , src , stride, h)\
+name8(s, dst+8 , src+8 , stride)\ +name8(s, dst+8 , src+8 , stride, h);\
+name8(s, dst +8*stride, src +8*stride, stride)\ }
+name8(s, dst+8+8*stride, src+8+8*stride, stride);\
#define WARPER8_16_SQ(name8, name16)\
static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\
int score=0;\
score +=name8(s, dst , src , stride, 8);\
score +=name8(s, dst+8 , src+8 , stride, 8);\
if(h==16){\
dst += 8*stride;\
src += 8*stride;\
score +=name8(s, dst , src , stride, 8);\
score +=name8(s, dst+8 , src+8 , stride, 8);\
}\
return score;\
} }
#ifndef HAVE_LRINTF #ifndef HAVE_LRINTF
@@ -921,6 +921,11 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
DVVideoDecodeContext *s = avctx->priv_data; DVVideoDecodeContext *s = avctx->priv_data;
int ds, vs; int ds, vs;
const uint16_t *mb_pos_ptr; const uint16_t *mb_pos_ptr;
*data_size=0;
/* special case for last picture */
if(buf_size==0)
return 0;
s->sys = dv_frame_profile(buf); s->sys = dv_frame_profile(buf);
if (!s->sys || buf_size < s->sys->frame_size) if (!s->sys || buf_size < s->sys->frame_size)
@@ -1,7 +1,7 @@
/* /*
* Error resilience / concealment * Error resilience / concealment
* *
* Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at> * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -582,8 +582,8 @@ static int is_intra_more_likely(MpegEncContext *s){
uint8_t *mb_ptr = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize; uint8_t *mb_ptr = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
uint8_t *last_mb_ptr= s->last_picture.data [0] + mb_x*16 + mb_y*16*s->linesize; uint8_t *last_mb_ptr= s->last_picture.data [0] + mb_x*16 + mb_y*16*s->linesize;
is_intra_likely += s->dsp.pix_abs16x16(last_mb_ptr, mb_ptr , s->linesize); is_intra_likely += s->dsp.sad[0](NULL, last_mb_ptr, mb_ptr , s->linesize, 16);
is_intra_likely -= s->dsp.pix_abs16x16(last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize); is_intra_likely -= s->dsp.sad[0](NULL, last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize, 16);
}else{ }else{
if(IS_INTRA(s->current_picture.mb_type[mb_xy])) if(IS_INTRA(s->current_picture.mb_type[mb_xy]))
is_intra_likely++; is_intra_likely++;
@@ -673,10 +673,16 @@ void ff_er_frame_end(MpegEncContext *s){
if(s->current_picture.motion_val[0] == NULL){ if(s->current_picture.motion_val[0] == NULL){
int size = (2 * s->mb_width + 2) * (2 * s->mb_height + 2); int size = (2 * s->mb_width + 2) * (2 * s->mb_height + 2);
Picture *pic= s->current_picture_ptr;
av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n"); av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
s->current_picture.motion_val[0]= av_mallocz(size * 2 * sizeof(int16_t)); //FIXME for(i=0; i<2; i++){
pic->motion_val_base[i]= av_mallocz((size+1) * 2 * sizeof(uint16_t)); //FIXME size
pic->motion_val[i]= pic->motion_val_base[i]+1;
}
pic->motion_subsample_log2= 3;
s->current_picture= *s->current_picture_ptr;
} }
if(s->avctx->debug&FF_DEBUG_ER){ if(s->avctx->debug&FF_DEBUG_ER){
@@ -1,6 +1,6 @@
/* /*
* FLI/FLC Animation Video Decoder * FLI/FLC Animation Video Decoder
* Copyright (C) 2003 the ffmpeg project * Copyright (C) 2003, 2004 the ffmpeg project
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -60,7 +60,6 @@
typedef struct FlicDecodeContext { typedef struct FlicDecodeContext {
AVCodecContext *avctx; AVCodecContext *avctx;
AVFrame frame; AVFrame frame;
AVFrame prev_frame;
unsigned int palette[256]; unsigned int palette[256];
int new_palette; int new_palette;
@@ -82,11 +81,11 @@ static int flic_decode_init(AVCodecContext *avctx)
} else if (s->avctx->extradata_size == 128) { } else if (s->avctx->extradata_size == 128) {
s->fli_type = LE_16(&fli_header[4]); s->fli_type = LE_16(&fli_header[4]);
} else { } else {
printf (" FLI video: expected extradata of 12 or 128 bytes\n"); av_log(avctx, AV_LOG_ERROR, "Expected extradata of 12 or 128 bytes\n");
return -1; return -1;
} }
s->frame.data[0] = s->prev_frame.data[0] = NULL; s->frame.data[0] = NULL;
s->new_palette = 0; s->new_palette = 0;
return 0; return 0;
@@ -126,18 +125,16 @@ static int flic_decode_frame(AVCodecContext *avctx,
signed char byte_run; signed char byte_run;
int pixel_skip; int pixel_skip;
int pixel_countdown; int pixel_countdown;
int height_countdown;
unsigned char *pixels; unsigned char *pixels;
unsigned char *prev_pixels;
s->frame.reference = 1; s->frame.reference = 1;
if (avctx->get_buffer(avctx, &s->frame) < 0) { s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
fprintf(stderr, " FLI: get_buffer() failed\n"); if (avctx->reget_buffer(avctx, &s->frame) < 0) {
av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
return -1; return -1;
} }
pixels = s->frame.data[0]; pixels = s->frame.data[0];
prev_pixels = s->prev_frame.data[0];
frame_size = LE_32(&buf[stream_ptr]); frame_size = LE_32(&buf[stream_ptr]);
stream_ptr += 6; /* skip the magic number */ stream_ptr += 6; /* skip the magic number */
@@ -146,11 +143,6 @@ static int flic_decode_frame(AVCodecContext *avctx,
frame_size -= 16; frame_size -= 16;
/* if there is no data, copy previous frame */
if (frame_size == 0) {
memcpy(pixels, prev_pixels, s->frame.linesize[0] * s->avctx->height);
}
/* iterate through the chunks */ /* iterate through the chunks */
while ((frame_size > 0) && (num_chunks > 0)) { while ((frame_size > 0) && (num_chunks > 0)) {
chunk_size = LE_32(&buf[stream_ptr]); chunk_size = LE_32(&buf[stream_ptr]);
@@ -210,7 +202,6 @@ static int flic_decode_frame(AVCodecContext *avctx,
case FLI_DELTA: case FLI_DELTA:
y_ptr = 0; y_ptr = 0;
height_countdown = s->avctx->height;
compressed_lines = LE_16(&buf[stream_ptr]); compressed_lines = LE_16(&buf[stream_ptr]);
stream_ptr += 2; stream_ptr += 2;
while (compressed_lines > 0) { while (compressed_lines > 0) {
@@ -218,25 +209,14 @@ static int flic_decode_frame(AVCodecContext *avctx,
stream_ptr += 2; stream_ptr += 2;
if (line_packets < 0) { if (line_packets < 0) {
line_packets = -line_packets; line_packets = -line_packets;
/* height_countdown was already decremented once on y_ptr += line_packets * s->frame.linesize[0];
* this iteration */
height_countdown -= line_packets;
/* copy the skipped lines from the previous frame */
while (line_packets--) {
memcpy(&pixels[y_ptr], &prev_pixels[y_ptr],
s->avctx->width);
y_ptr += s->frame.linesize[0];
}
} else { } else {
height_countdown--;
compressed_lines--; compressed_lines--;
pixel_ptr = y_ptr; pixel_ptr = y_ptr;
pixel_countdown = s->avctx->width; pixel_countdown = s->avctx->width;
for (i = 0; i < line_packets; i++) { for (i = 0; i < line_packets; i++) {
/* account for the skip bytes */ /* account for the skip bytes */
pixel_skip = buf[stream_ptr++]; pixel_skip = buf[stream_ptr++];
memcpy(&pixels[pixel_ptr], &prev_pixels[pixel_ptr],
pixel_skip);
pixel_ptr += pixel_skip; pixel_ptr += pixel_skip;
pixel_countdown -= pixel_skip; pixel_countdown -= pixel_skip;
byte_run = buf[stream_ptr++]; byte_run = buf[stream_ptr++];
@@ -256,36 +236,17 @@ static int flic_decode_frame(AVCodecContext *avctx,
} }
} }
/* copy the remaining pixels in the line from the
* previous frame */
memcpy(&pixels[pixel_ptr], &prev_pixels[pixel_ptr],
pixel_countdown);
y_ptr += s->frame.linesize[0]; y_ptr += s->frame.linesize[0];
} }
} }
/* copy the remainder of the lines from the previous frame */
while (height_countdown--) {
memcpy(&pixels[y_ptr], &prev_pixels[y_ptr], s->avctx->width);
y_ptr += s->frame.linesize[0];
}
break; break;
case FLI_LC: case FLI_LC:
/* line compressed */ /* line compressed */
height_countdown = s->avctx->height;
starting_line = LE_16(&buf[stream_ptr]); starting_line = LE_16(&buf[stream_ptr]);
stream_ptr += 2; stream_ptr += 2;
/* copy from the previous frame all of the lines prior to the
* starting line */
y_ptr = 0; y_ptr = 0;
height_countdown -= starting_line; y_ptr += starting_line * s->frame.linesize[0];
while (starting_line--) {
memcpy(&pixels[y_ptr], &prev_pixels[y_ptr], s->avctx->width);
y_ptr += s->frame.linesize[0];
}
compressed_lines = LE_16(&buf[stream_ptr]); compressed_lines = LE_16(&buf[stream_ptr]);
stream_ptr += 2; stream_ptr += 2;
@@ -297,8 +258,6 @@ static int flic_decode_frame(AVCodecContext *avctx,
for (i = 0; i < line_packets; i++) { for (i = 0; i < line_packets; i++) {
/* account for the skip bytes */ /* account for the skip bytes */
pixel_skip = buf[stream_ptr++]; pixel_skip = buf[stream_ptr++];
memcpy(&pixels[pixel_ptr],
&prev_pixels[pixel_ptr], pixel_skip);
pixel_ptr += pixel_skip; pixel_ptr += pixel_skip;
pixel_countdown -= pixel_skip; pixel_countdown -= pixel_skip;
byte_run = buf[stream_ptr++]; byte_run = buf[stream_ptr++];
@@ -317,19 +276,8 @@ static int flic_decode_frame(AVCodecContext *avctx,
} }
} }
/* copy the remainder of the line from the previous frame */
memcpy(&pixels[pixel_ptr], &prev_pixels[pixel_ptr],
pixel_countdown);
y_ptr += s->frame.linesize[0]; y_ptr += s->frame.linesize[0];
compressed_lines--; compressed_lines--;
height_countdown--;
}
/* copy the remainder of the lines from the previous frame */
while (height_countdown--) {
memcpy(&pixels[y_ptr], &prev_pixels[y_ptr], s->avctx->width);
y_ptr += s->frame.linesize[0];
} }
break; break;
@@ -357,8 +305,8 @@ static int flic_decode_frame(AVCodecContext *avctx,
pixels[pixel_ptr++] = palette_idx1; pixels[pixel_ptr++] = palette_idx1;
pixel_countdown--; pixel_countdown--;
if (pixel_countdown < 0) if (pixel_countdown < 0)
printf ("fli warning: pixel_countdown < 0 (%d)\n", av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
pixel_countdown); pixel_countdown);
} }
} else { /* copy bytes if byte_run < 0 */ } else { /* copy bytes if byte_run < 0 */
byte_run = -byte_run; byte_run = -byte_run;
@@ -367,8 +315,8 @@ static int flic_decode_frame(AVCodecContext *avctx,
pixels[pixel_ptr++] = palette_idx1; pixels[pixel_ptr++] = palette_idx1;
pixel_countdown--; pixel_countdown--;
if (pixel_countdown < 0) if (pixel_countdown < 0)
printf ("fli warning: pixel_countdown < 0 (%d)\n", av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
pixel_countdown); pixel_countdown);
} }
} }
} }
@@ -378,13 +326,10 @@ static int flic_decode_frame(AVCodecContext *avctx,
break; break;
case FLI_COPY: case FLI_COPY:
/* copy the chunk (uncompressed frame) to the ghost image and /* copy the chunk (uncompressed frame) */
* schedule the whole frame to be updated */
if (chunk_size - 6 > s->avctx->width * s->avctx->height) { if (chunk_size - 6 > s->avctx->width * s->avctx->height) {
printf( av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
"FLI: in chunk FLI_COPY : source data (%d bytes) bigger than" \ "bigger than image, skipping chunk\n", chunk_size - 6);
" image, skipping chunk\n",
chunk_size - 6);
stream_ptr += chunk_size - 6; stream_ptr += chunk_size - 6;
} else { } else {
for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height; for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
@@ -402,7 +347,7 @@ static int flic_decode_frame(AVCodecContext *avctx,
break; break;
default: default:
printf ("FLI: Unrecognized chunk type: %d\n", chunk_type); av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
break; break;
} }
@@ -413,9 +358,8 @@ static int flic_decode_frame(AVCodecContext *avctx,
/* by the end of the chunk, the stream ptr should equal the frame /* by the end of the chunk, the stream ptr should equal the frame
* size (minus 1, possibly); if it doesn't, issue a warning */ * size (minus 1, possibly); if it doesn't, issue a warning */
if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1)) if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1))
printf (" warning: processed FLI chunk where chunk size = %d\n" \ av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
" and final chunk ptr = %d\n", "and final chunk ptr = %d\n", buf_size, stream_ptr);
buf_size, stream_ptr);
/* make the palette available on the way out */ /* make the palette available on the way out */
// if (s->new_palette) { // if (s->new_palette) {
@@ -425,12 +369,6 @@ static int flic_decode_frame(AVCodecContext *avctx,
s->new_palette = 0; s->new_palette = 0;
} }
if (s->prev_frame.data[0])
avctx->release_buffer(avctx, &s->prev_frame);
/* shuffle frames */
s->prev_frame = s->frame;
*data_size=sizeof(AVFrame); *data_size=sizeof(AVFrame);
*(AVFrame*)data = s->frame; *(AVFrame*)data = s->frame;
@@ -441,8 +379,8 @@ static int flic_decode_end(AVCodecContext *avctx)
{ {
FlicDecodeContext *s = avctx->priv_data; FlicDecodeContext *s = avctx->priv_data;
if (s->prev_frame.data[0]) if (s->frame.data[0])
avctx->release_buffer(avctx, &s->prev_frame); avctx->release_buffer(avctx, &s->frame);
return 0; return 0;
} }
@@ -25,7 +25,7 @@
* @author Michael Niedermayer <michaelni@gmx.at> * @author Michael Niedermayer <michaelni@gmx.at>
*/ */
#include <inttypes.h> #include "common.h"
const uint8_t ff_golomb_vlc_len[512]={ const uint8_t ff_golomb_vlc_len[512]={
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
@@ -3,6 +3,7 @@
* Copyright (c) 2000,2001 Fabrice Bellard. * Copyright (c) 2000,2001 Fabrice Bellard.
* H263+ support. * H263+ support.
* Copyright (c) 2001 Juan J. Sierralta P. * Copyright (c) 2001 Juan J. Sierralta P.
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -479,9 +480,9 @@ void ff_clean_mpeg4_qscales(MpegEncContext *s){
for(i=1; i<s->mb_num; i++){ for(i=1; i<s->mb_num; i++){
int mb_xy= s->mb_index2xy[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]&MB_TYPE_INTER4V)){ 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]&= ~MB_TYPE_INTER4V; s->mb_type[mb_xy]&= ~CANDIDATE_MB_TYPE_INTER4V;
s->mb_type[mb_xy]|= MB_TYPE_INTER; s->mb_type[mb_xy]|= CANDIDATE_MB_TYPE_INTER;
} }
} }
@@ -508,9 +509,9 @@ void ff_clean_mpeg4_qscales(MpegEncContext *s){
for(i=1; i<s->mb_num; i++){ for(i=1; i<s->mb_num; i++){
int mb_xy= s->mb_index2xy[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]&MB_TYPE_DIRECT)){ if(qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i-1]] && (s->mb_type[mb_xy]&CANDIDATE_MB_TYPE_DIRECT)){
s->mb_type[mb_xy]&= ~MB_TYPE_DIRECT; s->mb_type[mb_xy]&= ~CANDIDATE_MB_TYPE_DIRECT;
s->mb_type[mb_xy]|= MB_TYPE_BIDIR; s->mb_type[mb_xy]|= CANDIDATE_MB_TYPE_BIDIR;
} }
} }
} }
@@ -523,7 +524,7 @@ void ff_clean_mpeg4_qscales(MpegEncContext *s){
*/ */
int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my){ int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my){
const int mb_index= s->mb_x + s->mb_y*s->mb_stride; const int mb_index= s->mb_x + s->mb_y*s->mb_stride;
const int colocated_mb_type= s->next_picture.mb_type[mb_index]; //FIXME or next? const int colocated_mb_type= s->next_picture.mb_type[mb_index];
int xy= s->block_index[0]; int xy= s->block_index[0];
uint16_t time_pp= s->pp_time; uint16_t time_pp= s->pp_time;
uint16_t time_pb= s->pb_time; uint16_t time_pb= s->pb_time;
@@ -547,18 +548,18 @@ int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my){
s->mv_type = MV_TYPE_FIELD; s->mv_type = MV_TYPE_FIELD;
for(i=0; i<2; i++){ for(i=0; i<2; i++){
if(s->top_field_first){ if(s->top_field_first){
time_pp= s->pp_field_time - s->field_select_table[mb_index][i] + i; time_pp= s->pp_field_time - s->p_field_select_table[i][mb_index] + i;
time_pb= s->pb_field_time - s->field_select_table[mb_index][i] + i; time_pb= s->pb_field_time - s->p_field_select_table[i][mb_index] + i;
}else{ }else{
time_pp= s->pp_field_time + s->field_select_table[mb_index][i] - i; time_pp= s->pp_field_time + s->p_field_select_table[i][mb_index] - i;
time_pb= s->pb_field_time + s->field_select_table[mb_index][i] - i; time_pb= s->pb_field_time + s->p_field_select_table[i][mb_index] - i;
} }
s->mv[0][i][0] = s->field_mv_table[mb_index][i][0]*time_pb/time_pp + mx; s->mv[0][i][0] = s->p_field_mv_table[i][0][mb_index][0]*time_pb/time_pp + mx;
s->mv[0][i][1] = s->field_mv_table[mb_index][i][1]*time_pb/time_pp + my; s->mv[0][i][1] = s->p_field_mv_table[i][0][mb_index][1]*time_pb/time_pp + my;
s->mv[1][i][0] = mx ? s->mv[0][i][0] - s->field_mv_table[mb_index][i][0] s->mv[1][i][0] = mx ? s->mv[0][i][0] - s->p_field_mv_table[i][0][mb_index][0]
: s->field_mv_table[mb_index][i][0]*(time_pb - time_pp)/time_pp; : s->p_field_mv_table[i][0][mb_index][0]*(time_pb - time_pp)/time_pp;
s->mv[1][i][1] = my ? s->mv[0][i][1] - s->field_mv_table[mb_index][i][1] s->mv[1][i][1] = my ? s->mv[0][i][1] - s->p_field_mv_table[i][0][mb_index][1]
: s->field_mv_table[mb_index][i][1]*(time_pb - time_pp)/time_pp; : s->p_field_mv_table[i][0][mb_index][1]*(time_pb - time_pp)/time_pp;
} }
return MB_TYPE_DIRECT2 | MB_TYPE_16x8 | MB_TYPE_L0L1 | MB_TYPE_INTERLACED; return MB_TYPE_DIRECT2 | MB_TYPE_16x8 | MB_TYPE_L0L1 | MB_TYPE_INTERLACED;
}else{ }else{
@@ -598,9 +599,9 @@ void ff_h263_update_motion_val(MpegEncContext * s){
motion_y = s->mv[0][0][1] + s->mv[0][1][1]; motion_y = s->mv[0][0][1] + s->mv[0][1][1];
motion_x = (motion_x>>1) | (motion_x&1); motion_x = (motion_x>>1) | (motion_x&1);
for(i=0; i<2; i++){ for(i=0; i<2; i++){
s->field_mv_table[mb_xy][i][0]= s->mv[0][i][0]; s->p_field_mv_table[i][0][mb_xy][0]= s->mv[0][i][0];
s->field_mv_table[mb_xy][i][1]= s->mv[0][i][1]; s->p_field_mv_table[i][0][mb_xy][1]= s->mv[0][i][1];
s->field_select_table[mb_xy][i]= s->field_select[0][i]; s->p_field_select_table[i][mb_xy]= s->field_select[0][i];
} }
} }
@@ -744,12 +745,14 @@ void mpeg4_encode_mb(MpegEncContext * s,
if(s->pict_type==B_TYPE){ if(s->pict_type==B_TYPE){
static const int mb_type_table[8]= {-1, 2, 3, 1,-1,-1,-1, 0}; /* convert from mv_dir to type */ static const int mb_type_table[8]= {-1, 2, 3, 1,-1,-1,-1, 0}; /* convert from mv_dir to type */
int mb_type= mb_type_table[s->mv_dir]; int mb_type= mb_type_table[s->mv_dir];
if(s->mb_x==0){ if(s->mb_x==0){
s->last_mv[0][0][0]= for(i=0; i<2; i++){
s->last_mv[0][0][1]= s->last_mv[i][0][0]=
s->last_mv[1][0][0]= s->last_mv[i][0][1]=
s->last_mv[1][0][1]= 0; s->last_mv[i][1][0]=
s->last_mv[i][1][1]= 0;
}
} }
assert(s->dquant>=-2 && s->dquant<=2); assert(s->dquant>=-2 && s->dquant<=2);
@@ -803,50 +806,64 @@ void mpeg4_encode_mb(MpegEncContext * s,
if(cbp) if(cbp)
put_bits(&s->pb, 1, s->interlaced_dct); put_bits(&s->pb, 1, s->interlaced_dct);
if(mb_type) // not diect mode if(mb_type) // not diect mode
put_bits(&s->pb, 1, 0); // no interlaced ME yet put_bits(&s->pb, 1, s->mv_type == MV_TYPE_FIELD);
} }
if(interleaved_stats){ if(interleaved_stats){
s->misc_bits+= get_bits_diff(s); s->misc_bits+= get_bits_diff(s);
} }
switch(mb_type) if(mb_type == 0){
{ assert(s->mv_dir & MV_DIRECT);
case 0: /* direct */
h263_encode_motion(s, motion_x, 1); h263_encode_motion(s, motion_x, 1);
h263_encode_motion(s, motion_y, 1); h263_encode_motion(s, motion_y, 1);
s->b_count++; s->b_count++;
s->f_count++; s->f_count++;
break; }else{
case 1: /* bidir */ assert(mb_type > 0 && mb_type < 4);
h263_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code); if(s->mv_type != MV_TYPE_FIELD){
h263_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code); if(s->mv_dir & MV_DIR_FORWARD){
h263_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code); h263_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code);
h263_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code); h263_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code);
s->last_mv[0][0][0]= s->mv[0][0][0]; s->last_mv[0][0][0]= s->last_mv[0][1][0]= s->mv[0][0][0];
s->last_mv[0][0][1]= s->mv[0][0][1]; s->last_mv[0][0][1]= s->last_mv[0][1][1]= s->mv[0][0][1];
s->last_mv[1][0][0]= s->mv[1][0][0]; s->f_count++;
s->last_mv[1][0][1]= s->mv[1][0][1]; }
s->b_count++; if(s->mv_dir & MV_DIR_BACKWARD){
s->f_count++; h263_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code);
break; h263_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code);
case 2: /* backward */ s->last_mv[1][0][0]= s->last_mv[1][1][0]= s->mv[1][0][0];
h263_encode_motion(s, motion_x - s->last_mv[1][0][0], s->b_code); s->last_mv[1][0][1]= s->last_mv[1][1][1]= s->mv[1][0][1];
h263_encode_motion(s, motion_y - s->last_mv[1][0][1], s->b_code); s->b_count++;
s->last_mv[1][0][0]= motion_x; }
s->last_mv[1][0][1]= motion_y; }else{
s->b_count++; if(s->mv_dir & MV_DIR_FORWARD){
break; put_bits(&s->pb, 1, s->field_select[0][0]);
case 3: /* forward */ put_bits(&s->pb, 1, s->field_select[0][1]);
h263_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); }
h263_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); if(s->mv_dir & MV_DIR_BACKWARD){
s->last_mv[0][0][0]= motion_x; put_bits(&s->pb, 1, s->field_select[1][0]);
s->last_mv[0][0][1]= motion_y; put_bits(&s->pb, 1, s->field_select[1][1]);
s->f_count++; }
break; if(s->mv_dir & MV_DIR_FORWARD){
default: for(i=0; i<2; i++){
av_log(s->avctx, AV_LOG_ERROR, "unknown mb type\n"); h263_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code);
return; h263_encode_motion(s, s->mv[0][i][1] - s->last_mv[0][i][1]/2, s->f_code);
s->last_mv[0][i][0]= s->mv[0][i][0];
s->last_mv[0][i][1]= s->mv[0][i][1]*2;
}
s->f_count++;
}
if(s->mv_dir & MV_DIR_BACKWARD){
for(i=0; i<2; i++){
h263_encode_motion(s, s->mv[1][i][0] - s->last_mv[1][i][0] , s->b_code);
h263_encode_motion(s, s->mv[1][i][1] - s->last_mv[1][i][1]/2, s->b_code);
s->last_mv[1][i][0]= s->mv[1][i][0];
s->last_mv[1][i][1]= s->mv[1][i][1]*2;
}
s->b_count++;
}
}
} }
if(interleaved_stats){ if(interleaved_stats){
@@ -861,6 +878,7 @@ void mpeg4_encode_mb(MpegEncContext * s,
if(interleaved_stats){ if(interleaved_stats){
s->p_tex_bits+= get_bits_diff(s); s->p_tex_bits+= get_bits_diff(s);
} }
}else{ /* s->pict_type==B_TYPE */ }else{ /* s->pict_type==B_TYPE */
cbp= get_p_cbp(s, block, motion_x, motion_y); cbp= get_p_cbp(s, block, motion_x, motion_y);
@@ -889,7 +907,7 @@ void mpeg4_encode_mb(MpegEncContext * s,
if(pic==NULL || pic->pict_type!=B_TYPE) break; if(pic==NULL || pic->pict_type!=B_TYPE) break;
b_pic= pic->data[0] + offset + 16; //FIXME +16 b_pic= pic->data[0] + offset + 16; //FIXME +16
diff= s->dsp.pix_abs16x16(p_pic, b_pic, s->linesize); diff= s->dsp.sad[0](NULL, p_pic, b_pic, s->linesize, 16);
if(diff>s->qscale*70){ //FIXME check that 70 is optimal if(diff>s->qscale*70){ //FIXME check that 70 is optimal
s->mb_skiped=0; s->mb_skiped=0;
break; break;
@@ -929,7 +947,7 @@ void mpeg4_encode_mb(MpegEncContext * s,
if(!s->progressive_sequence){ if(!s->progressive_sequence){
if(cbp) if(cbp)
put_bits(pb2, 1, s->interlaced_dct); put_bits(pb2, 1, s->interlaced_dct);
put_bits(pb2, 1, 0); // no interlaced ME yet put_bits(pb2, 1, 0);
} }
if(interleaved_stats){ if(interleaved_stats){
@@ -941,7 +959,38 @@ void mpeg4_encode_mb(MpegEncContext * s,
h263_encode_motion(s, motion_x - pred_x, s->f_code); h263_encode_motion(s, motion_x - pred_x, s->f_code);
h263_encode_motion(s, motion_y - pred_y, s->f_code); h263_encode_motion(s, motion_y - pred_y, s->f_code);
}else if(s->mv_type==MV_TYPE_FIELD){
if(s->dquant) cbpc+= 8;
put_bits(&s->pb,
inter_MCBPC_bits[cbpc],
inter_MCBPC_code[cbpc]);
put_bits(pb2, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]);
if(s->dquant)
put_bits(pb2, 2, dquant_code[s->dquant+2]);
assert(!s->progressive_sequence);
if(cbp)
put_bits(pb2, 1, s->interlaced_dct);
put_bits(pb2, 1, 1);
if(interleaved_stats){
s->misc_bits+= get_bits_diff(s);
}
/* motion vectors: 16x8 interlaced mode */
h263_pred_motion(s, 0, &pred_x, &pred_y);
pred_y /=2;
put_bits(&s->pb, 1, s->field_select[0][0]);
put_bits(&s->pb, 1, s->field_select[0][1]);
h263_encode_motion(s, s->mv[0][0][0] - pred_x, s->f_code);
h263_encode_motion(s, s->mv[0][0][1] - pred_y, s->f_code);
h263_encode_motion(s, s->mv[0][1][0] - pred_x, s->f_code);
h263_encode_motion(s, s->mv[0][1][1] - pred_y, s->f_code);
}else{ }else{
assert(s->mv_type==MV_TYPE_8X8);
put_bits(&s->pb, put_bits(&s->pb,
inter_MCBPC_bits[cbpc+16], inter_MCBPC_bits[cbpc+16],
inter_MCBPC_code[cbpc+16]); inter_MCBPC_code[cbpc+16]);
@@ -1081,6 +1130,8 @@ void h263_encode_mb(MpegEncContext * s,
s->misc_bits++; s->misc_bits++;
s->last_bits++; s->last_bits++;
} }
s->skip_count++;
return; return;
} }
put_bits(&s->pb, 1, 0); /* mb coded */ put_bits(&s->pb, 1, 0); /* mb coded */
@@ -1548,9 +1599,9 @@ int16_t *h263_pred_motion2(MpegEncContext * s, int block, int dir,
static const int off[4]= {2, 1, 1, -1}; static const int off[4]= {2, 1, 1, -1};
wrap = s->b8_stride; wrap = s->b8_stride;
xy = s->mb_x + s->mb_y * wrap; xy = 2*(s->mb_x + s->mb_y * wrap);
mot_val = s->current_picture.motion_val[0][dir] + xy; mot_val = s->current_picture.motion_val[dir] + xy;
A = mot_val[ - 1]; A = mot_val[ - 1];
/* special case for first (slice) line */ /* special case for first (slice) line */
@@ -1983,7 +2034,7 @@ static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n)
if (level == 128) //FIXME check rv10 if (level == 128) //FIXME check rv10
put_bits(&s->pb, 8, 0xff); put_bits(&s->pb, 8, 0xff);
else else
put_bits(&s->pb, 8, level & 0xff); put_bits(&s->pb, 8, level);
i = 1; i = 1;
} else { } else {
i = 0; i = 0;
@@ -2053,7 +2104,7 @@ static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n)
assert(slevel != 0); assert(slevel != 0);
if(slevel < 128 && slevel > -128) if(level < 128)
put_bits(&s->pb, 8, slevel & 0xff); put_bits(&s->pb, 8, slevel & 0xff);
else{ else{
put_bits(&s->pb, 8, 128); put_bits(&s->pb, 8, 128);
@@ -2061,8 +2112,7 @@ static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n)
put_bits(&s->pb, 6, (slevel>>5)&0x3f); put_bits(&s->pb, 6, (slevel>>5)&0x3f);
} }
}else{ }else{
if(slevel < 64 && slevel > -64) { if(level < 64) { // 7-bit level
/* 7-bit level */
put_bits(&s->pb, 1, 0); put_bits(&s->pb, 1, 0);
put_bits(&s->pb, 1, last); put_bits(&s->pb, 1, last);
put_bits(&s->pb, 6, run); put_bits(&s->pb, 6, run);
@@ -2123,11 +2173,18 @@ void ff_set_mpeg4_time(MpegEncContext * s, int picture_number){
static void mpeg4_encode_gop_header(MpegEncContext * s){ static void mpeg4_encode_gop_header(MpegEncContext * s){
int hours, minutes, seconds; int hours, minutes, seconds;
int64_t time;
put_bits(&s->pb, 16, 0); put_bits(&s->pb, 16, 0);
put_bits(&s->pb, 16, GOP_STARTCODE); put_bits(&s->pb, 16, GOP_STARTCODE);
seconds= s->time/s->time_increment_resolution; if(s->current_picture_ptr->pts && s->reordered_input_picture[1]){
time= FFMIN(s->reordered_input_picture[1]->pts, s->current_picture_ptr->pts);
time= (time*s->time_increment_resolution + 500*1000)/(1000*1000);
}else
time= av_rescale(s->current_picture_ptr->coded_picture_number*(int64_t)s->avctx->frame_rate_base, s->time_increment_resolution, s->avctx->frame_rate);
seconds= time/s->time_increment_resolution;
minutes= seconds/60; seconds %= 60; minutes= seconds/60; seconds %= 60;
hours= minutes/60; minutes %= 60; hours= minutes/60; minutes %= 60;
hours%=24; hours%=24;
@@ -2137,8 +2194,10 @@ static void mpeg4_encode_gop_header(MpegEncContext * s){
put_bits(&s->pb, 1, 1); put_bits(&s->pb, 1, 1);
put_bits(&s->pb, 6, seconds); put_bits(&s->pb, 6, seconds);
put_bits(&s->pb, 1, 0); //closed gov == NO put_bits(&s->pb, 1, !!(s->flags&CODEC_FLAG_CLOSED_GOP));
put_bits(&s->pb, 1, 0); //broken link == NO put_bits(&s->pb, 1, 0); //broken link == NO
s->last_time_base= time / s->time_increment_resolution;
ff_mpeg4_stuffing(&s->pb); ff_mpeg4_stuffing(&s->pb);
} }
@@ -3815,15 +3874,15 @@ int ff_h263_decode_mb(MpegEncContext *s,
} else if(s->pict_type==B_TYPE) { } else if(s->pict_type==B_TYPE) {
int mb_type; int mb_type;
const int stride= s->b8_stride; const int stride= s->b8_stride;
int16_t *mot_val0 = s->current_picture.motion_val[0][ s->mb_x + s->mb_y*stride ]; int16_t *mot_val0 = s->current_picture.motion_val[0][ 2*(s->mb_x + s->mb_y*stride) ];
int16_t *mot_val1 = s->current_picture.motion_val[1][ s->mb_x + s->mb_y*stride ]; int16_t *mot_val1 = s->current_picture.motion_val[1][ 2*(s->mb_x + s->mb_y*stride) ];
// const int mv_xy= s->mb_x + 1 + s->mb_y * s->mb_stride; // const int mv_xy= s->mb_x + 1 + s->mb_y * s->mb_stride;
//FIXME ugly //FIXME ugly
mot_val0[0 ]= mot_val0[2 ]= mot_val0[0+stride]= mot_val0[2+stride]= 0; mot_val0[0 ]= mot_val0[2 ]= mot_val0[0+2*stride]= mot_val0[2+2*stride]=
mot_val0[1 ]= mot_val0[3 ]= mot_val0[1+stride]= mot_val0[3+stride]= 0; mot_val0[1 ]= mot_val0[3 ]= mot_val0[1+2*stride]= mot_val0[3+2*stride]=
mot_val1[0 ]= mot_val1[2 ]= mot_val1[0+stride]= mot_val1[2+stride]= 0; mot_val1[0 ]= mot_val1[2 ]= mot_val1[0+2*stride]= mot_val1[2+2*stride]=
mot_val1[1 ]= mot_val1[3 ]= mot_val1[1+stride]= mot_val1[3+stride]= 0; mot_val1[1 ]= mot_val1[3 ]= mot_val1[1+2*stride]= mot_val1[3+2*stride]= 0;
do{ do{
mb_type= get_vlc2(&s->gb, h263_mbtype_b_vlc.table, H263_MBTYPE_B_VLC_BITS, 2); mb_type= get_vlc2(&s->gb, h263_mbtype_b_vlc.table, H263_MBTYPE_B_VLC_BITS, 2);
@@ -3877,22 +3936,24 @@ int ff_h263_decode_mb(MpegEncContext *s,
mx = h263_decode_motion(s, mx, 1); mx = h263_decode_motion(s, mx, 1);
my = h263_decode_motion(s, my, 1); my = h263_decode_motion(s, my, 1);
s->mv[0][0][0] = mx; s->mv[0][0][0] = mx;
s->mv[0][0][1] = my; s->mv[0][0][1] = my;
mot_val[0 ]= mot_val[2 ]= mot_val[0+stride]= mot_val[2+stride]= mx; mot_val[0 ]= mot_val[2 ]= mot_val[0+2*stride]= mot_val[2+2*stride]= mx;
mot_val[1 ]= mot_val[3 ]= mot_val[1+stride]= mot_val[3+stride]= my; mot_val[1 ]= mot_val[3 ]= mot_val[1+2*stride]= mot_val[3+2*stride]= my;
} }
if(USES_LIST(mb_type, 1)){ if(USES_LIST(mb_type, 1)){
int16_t *mot_val= h263_pred_motion2(s, 0, 1, &mx, &my); int16_t *mot_val= h263_pred_motion2(s, 0, 1, &mx, &my);
s->mv_dir |= MV_DIR_BACKWARD; s->mv_dir |= MV_DIR_BACKWARD;
mx = h263_decode_motion(s, mx, 1); mx = h263_decode_motion(s, mx, 1);
my = h263_decode_motion(s, my, 1); my = h263_decode_motion(s, my, 1);
s->mv[1][0][0] = mx; s->mv[1][0][0] = mx;
s->mv[1][0][1] = my; s->mv[1][0][1] = my;
mot_val[0 ]= mot_val[2 ]= mot_val[0+stride]= mot_val[2+stride]= mx; mot_val[0 ]= mot_val[2 ]= mot_val[0+2*stride]= mot_val[2+2*stride]= mx;
mot_val[1 ]= mot_val[3 ]= mot_val[1+stride]= mot_val[3+stride]= my; mot_val[1 ]= mot_val[3 ]= mot_val[1+2*stride]= mot_val[3+2*stride]= my;
} }
} }
@@ -4381,7 +4442,8 @@ static int h263_decode_block(MpegEncContext * s, DCTELEM * block,
level = get_bits(&s->gb, 8); level = get_bits(&s->gb, 8);
if((level&0x7F) == 0){ if((level&0x7F) == 0){
av_log(s->avctx, AV_LOG_ERROR, "illegal dc %d at %d %d\n", level, s->mb_x, s->mb_y); av_log(s->avctx, AV_LOG_ERROR, "illegal dc %d at %d %d\n", level, s->mb_x, s->mb_y);
return -1; if(s->error_resilience >= FF_ER_COMPLIANT)
return -1;
} }
if (level == 255) if (level == 255)
level = 128; level = 128;
@@ -51,18 +51,18 @@ static const int h263_mb_type_b_map[15]= {
MB_TYPE_DIRECT2 | MB_TYPE_L0L1, MB_TYPE_DIRECT2 | MB_TYPE_L0L1,
MB_TYPE_DIRECT2 | MB_TYPE_L0L1 | MB_TYPE_CBP, MB_TYPE_DIRECT2 | MB_TYPE_L0L1 | MB_TYPE_CBP,
MB_TYPE_DIRECT2 | MB_TYPE_L0L1 | MB_TYPE_CBP | MB_TYPE_QUANT, MB_TYPE_DIRECT2 | MB_TYPE_L0L1 | MB_TYPE_CBP | MB_TYPE_QUANT,
MB_TYPE_L0, MB_TYPE_L0 | MB_TYPE_16x16,
MB_TYPE_L0 | MB_TYPE_CBP, MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_16x16,
MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_QUANT, MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_QUANT | MB_TYPE_16x16,
MB_TYPE_L1, MB_TYPE_L1 | MB_TYPE_16x16,
MB_TYPE_L1 | MB_TYPE_CBP, MB_TYPE_L1 | MB_TYPE_CBP | MB_TYPE_16x16,
MB_TYPE_L1 | MB_TYPE_CBP | MB_TYPE_QUANT, MB_TYPE_L1 | MB_TYPE_CBP | MB_TYPE_QUANT | MB_TYPE_16x16,
MB_TYPE_L0L1, MB_TYPE_L0L1 | MB_TYPE_16x16,
MB_TYPE_L0L1 | MB_TYPE_CBP, MB_TYPE_L0L1 | MB_TYPE_CBP | MB_TYPE_16x16,
MB_TYPE_L0L1 | MB_TYPE_CBP | MB_TYPE_QUANT, MB_TYPE_L0L1 | MB_TYPE_CBP | MB_TYPE_QUANT | MB_TYPE_16x16,
0, //stuffing 0, //stuffing
MB_TYPE_INTRA | MB_TYPE_CBP, MB_TYPE_INTRA4x4 | MB_TYPE_CBP,
MB_TYPE_INTRA | MB_TYPE_CBP | MB_TYPE_QUANT, MB_TYPE_INTRA4x4 | MB_TYPE_CBP | MB_TYPE_QUANT,
}; };
const uint8_t cbpc_b_tab[4][2] = { const uint8_t cbpc_b_tab[4][2] = {
@@ -1,6 +1,7 @@
/* /*
* H.263 decoder * H.263 decoder
* Copyright (c) 2001 Fabrice Bellard. * Copyright (c) 2001 Fabrice Bellard.
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -392,6 +393,7 @@ uint64_t time= rdtsc();
printf("bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]); printf("bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]);
#endif #endif
s->flags= avctx->flags; s->flags= avctx->flags;
s->flags2= avctx->flags2;
*data_size = 0; *data_size = 0;
@@ -424,9 +426,10 @@ uint64_t time= rdtsc();
return buf_size; return buf_size;
} }
retry: retry:
if(s->bitstream_buffer_size && buf_size<20){ //divx 5.01+ frame reorder if(s->bitstream_buffer_size && (s->divx_packed || buf_size<20)){ //divx 5.01+/xvid frame reorder
init_get_bits(&s->gb, s->bitstream_buffer, s->bitstream_buffer_size*8); init_get_bits(&s->gb, s->bitstream_buffer, s->bitstream_buffer_size*8);
}else }else
init_get_bits(&s->gb, buf, buf_size*8); init_get_bits(&s->gb, buf, buf_size*8);
@@ -677,21 +680,26 @@ retry:
/* divx 5.01+ bistream reorder stuff */ /* divx 5.01+ bistream reorder stuff */
if(s->codec_id==CODEC_ID_MPEG4 && s->bitstream_buffer_size==0 && s->divx_packed){ if(s->codec_id==CODEC_ID_MPEG4 && s->bitstream_buffer_size==0 && s->divx_packed){
int current_pos= get_bits_count(&s->gb)>>3; int current_pos= get_bits_count(&s->gb)>>3;
int startcode_found=0;
if( buf_size - current_pos > 5 if( buf_size - current_pos > 5
&& buf_size - current_pos < BITSTREAM_BUFFER_SIZE){ && buf_size - current_pos < BITSTREAM_BUFFER_SIZE){
int i; int i;
int startcode_found=0;
for(i=current_pos; i<buf_size-3; i++){ for(i=current_pos; i<buf_size-3; i++){
if(buf[i]==0 && buf[i+1]==0 && buf[i+2]==1 && buf[i+3]==0xB6){ if(buf[i]==0 && buf[i+1]==0 && buf[i+2]==1 && buf[i+3]==0xB6){
startcode_found=1; startcode_found=1;
break; break;
} }
} }
if(startcode_found){ }
memcpy(s->bitstream_buffer, buf + current_pos, buf_size - current_pos); if(s->gb.buffer == s->bitstream_buffer && buf_size>20){ //xvid style
s->bitstream_buffer_size= buf_size - current_pos; startcode_found=1;
} current_pos=0;
}
if(startcode_found){
memcpy(s->bitstream_buffer, buf + current_pos, buf_size - current_pos);
s->bitstream_buffer_size= buf_size - current_pos;
} }
} }
@@ -703,10 +711,10 @@ assert(s->current_picture.pict_type == s->current_picture_ptr->pict_type);
assert(s->current_picture.pict_type == s->pict_type); assert(s->current_picture.pict_type == s->pict_type);
if(s->pict_type==B_TYPE || s->low_delay){ if(s->pict_type==B_TYPE || s->low_delay){
*pict= *(AVFrame*)&s->current_picture; *pict= *(AVFrame*)&s->current_picture;
ff_print_debug_info(s, s->current_picture_ptr); ff_print_debug_info(s, pict);
} else { } else {
*pict= *(AVFrame*)&s->last_picture; *pict= *(AVFrame*)&s->last_picture;
ff_print_debug_info(s, s->last_picture_ptr); ff_print_debug_info(s, pict);
} }
/* Return the Picture timestamp as the frame number */ /* Return the Picture timestamp as the frame number */
@@ -2158,6 +2158,7 @@ static void common_init(H264Context *h){
init_pred_ptrs(h); init_pred_ptrs(h);
s->unrestricted_mv=1;
s->decode=1; //FIXME s->decode=1; //FIXME
} }
@@ -4130,6 +4131,7 @@ static int decode_frame(AVCodecContext *avctx,
int buf_index; int buf_index;
s->flags= avctx->flags; s->flags= avctx->flags;
s->flags2= avctx->flags2;
*data_size = 0; *data_size = 0;
@@ -4171,7 +4173,7 @@ static int decode_frame(AVCodecContext *avctx,
} }
*pict= *(AVFrame*)&s->current_picture; //FIXME *pict= *(AVFrame*)&s->current_picture; //FIXME
ff_print_debug_info(s, s->current_picture_ptr); ff_print_debug_info(s, pict);
assert(pict->data[0]); assert(pict->data[0]);
//printf("out %d\n", (int)pict->data[0]); //printf("out %d\n", (int)pict->data[0]);
#if 0 //? #if 0 //?
@@ -30,10 +30,6 @@
#include "avcodec.h" #include "avcodec.h"
#include "dsputil.h" #include "dsputil.h"
#ifndef INT64_MAX
#define INT64_MAX 9223372036854775807LL
#endif
#define VLC_BITS 11 #define VLC_BITS 11
typedef enum Predictor{ typedef enum Predictor{
@@ -900,6 +900,11 @@ static int ipvideo_decode_frame(AVCodecContext *avctx,
IpvideoContext *s = avctx->priv_data; IpvideoContext *s = avctx->priv_data;
AVPaletteControl *palette_control = avctx->palctrl; AVPaletteControl *palette_control = avctx->palctrl;
/* compressed buffer needs to be large enough to at least hold an entire
* decoding map */
if (buf_size < s->decoding_map_size)
return buf_size;
s->decoding_map = buf; s->decoding_map = buf;
s->buf = buf + s->decoding_map_size; s->buf = buf + s->decoding_map_size;
s->size = buf_size - s->decoding_map_size; s->size = buf_size - s->decoding_map_size;
@@ -855,7 +855,6 @@ static int mjpeg_decode_init(AVCodecContext *avctx)
/* ugly way to get the idct & scantable FIXME */ /* ugly way to get the idct & scantable FIXME */
memset(&s2, 0, sizeof(MpegEncContext)); memset(&s2, 0, sizeof(MpegEncContext));
s2.flags= avctx->flags;
s2.avctx= avctx; s2.avctx= avctx;
// s2->out_format = FMT_MJPEG; // s2->out_format = FMT_MJPEG;
s2.width = 8; s2.width = 8;
@@ -1052,8 +1051,10 @@ static int mjpeg_decode_sof(MJpegDecodeContext *s)
case 0x11: case 0x11:
if(s->rgb){ if(s->rgb){
s->avctx->pix_fmt = PIX_FMT_RGBA32; s->avctx->pix_fmt = PIX_FMT_RGBA32;
}else }else if(s->nb_components==3)
s->avctx->pix_fmt = PIX_FMT_YUV444P; s->avctx->pix_fmt = PIX_FMT_YUV444P;
else
s->avctx->pix_fmt = PIX_FMT_GRAY8;
break; break;
case 0x21: case 0x21:
s->avctx->pix_fmt = PIX_FMT_YUV422P; s->avctx->pix_fmt = PIX_FMT_YUV422P;
@@ -1372,7 +1373,7 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s)
return -1; return -1;
} }
/* XXX: only interleaved scan accepted */ /* XXX: only interleaved scan accepted */
if (nb_components != 3) if (nb_components != s->nb_components)
{ {
dprintf("decode_sos: components(%d) mismatch\n", nb_components); dprintf("decode_sos: components(%d) mismatch\n", nb_components);
return -1; return -1;
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,6 @@
/* /*
* Motion estimation * Motion estimation
* Copyright (c) 2002 Michael Niedermayer * Copyright (c) 2002-2004 Michael Niedermayer
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -22,29 +22,31 @@
* @file motion_est_template.c * @file motion_est_template.c
* Motion estimation template. * Motion estimation template.
*/ */
//FIXME ref2_y next_pic?
//lets hope gcc will remove the unused vars ...(gcc 3.2.2 seems to do it ...) //lets hope gcc will remove the unused vars ...(gcc 3.2.2 seems to do it ...)
//Note, the last line is there to kill these ugly unused var warnings //Note, the last line is there to kill these ugly unused var warnings
#define LOAD_COMMON(x, y)\ #define LOAD_COMMON\
uint32_t * const score_map= s->me.score_map;\ uint32_t * const score_map= s->me.score_map;\
const int stride= s->linesize;\
const int uvstride= s->uvlinesize;\
const int time_pp= s->pp_time;\ const int time_pp= s->pp_time;\
const int time_pb= s->pb_time;\ const int time_pb= s->pb_time;\
uint8_t * const src_y= s->new_picture.data[0] + ((y) * stride) + (x);\ const int xmin= s->me.xmin;\
uint8_t * const src_u= s->new_picture.data[1] + (((y)>>1) * uvstride) + ((x)>>1);\ const int ymin= s->me.ymin;\
uint8_t * const src_v= s->new_picture.data[2] + (((y)>>1) * uvstride) + ((x)>>1);\ const int xmax= s->me.xmax;\
uint8_t * const ref_y= ref_picture->data[0] + ((y) * stride) + (x);\ const int ymax= s->me.ymax;\
uint8_t * const ref_u= ref_picture->data[1] + (((y)>>1) * uvstride) + ((x)>>1);\ uint8_t * const src_y= src_data[0];\
uint8_t * const ref_v= ref_picture->data[2] + (((y)>>1) * uvstride) + ((x)>>1);\ uint8_t * const src_u= src_data[1];\
uint8_t * const ref2_y= s->next_picture.data[0] + ((y) * stride) + (x);\ uint8_t * const src_v= src_data[2];\
uint8_t * const ref_y= ref_data[0];\
uint8_t * const ref_u= ref_data[1];\
uint8_t * const ref_v= ref_data[2];\
op_pixels_func (*hpel_put)[4];\ op_pixels_func (*hpel_put)[4];\
op_pixels_func (*hpel_avg)[4]= &s->dsp.avg_pixels_tab[size];\ op_pixels_func (*hpel_avg)[4]= &s->dsp.avg_pixels_tab[size];\
op_pixels_func (*chroma_hpel_put)[4];\ op_pixels_func (*chroma_hpel_put)[4];\
qpel_mc_func (*qpel_put)[16];\ qpel_mc_func (*qpel_put)[16];\
qpel_mc_func (*qpel_avg)[16]= &s->dsp.avg_qpel_pixels_tab[size];\ qpel_mc_func (*qpel_avg)[16]= &s->dsp.avg_qpel_pixels_tab[size];\
const __attribute__((unused)) int unu= time_pp + time_pb + (size_t)src_u + (size_t)src_v + (size_t)ref_u + (size_t)ref_v\ const __attribute__((unused)) int unu= time_pp + time_pb + (size_t)src_u + (size_t)src_v + (size_t)ref_u + (size_t)ref_v\
+ (size_t)ref2_y + (size_t)hpel_avg + (size_t)qpel_avg + (size_t)score_map;\ + (size_t)hpel_avg + (size_t)qpel_avg + (size_t)score_map\
+ xmin + xmax + ymin + ymax;\
if(s->no_rounding /*FIXME b_type*/){\ if(s->no_rounding /*FIXME b_type*/){\
hpel_put= &s->dsp.put_no_rnd_pixels_tab[size];\ hpel_put= &s->dsp.put_no_rnd_pixels_tab[size];\
chroma_hpel_put= &s->dsp.put_no_rnd_pixels_tab[size+1];\ chroma_hpel_put= &s->dsp.put_no_rnd_pixels_tab[size+1];\
@@ -70,9 +72,8 @@
#if 0 #if 0
static int RENAME(hpel_motion_search)(MpegEncContext * s, static int RENAME(hpel_motion_search)(MpegEncContext * s,
int *mx_ptr, int *my_ptr, int dmin, int *mx_ptr, int *my_ptr, int dmin,
int xmin, int ymin, int xmax, int ymax, int pred_x, int pred_y, uint8_t *ref_data[3],
int pred_x, int pred_y, Picture *ref_picture, int size, uint8_t * const mv_penalty)
int n, int size, uint8_t * const mv_penalty)
{ {
const int xx = 16 * s->mb_x + 8*(n&1); const int xx = 16 * s->mb_x + 8*(n&1);
const int yy = 16 * s->mb_y + 8*(n>>1); const int yy = 16 * s->mb_y + 8*(n>>1);
@@ -80,7 +81,7 @@ static int RENAME(hpel_motion_search)(MpegEncContext * s,
const int my = *my_ptr; const int my = *my_ptr;
const int penalty_factor= s->me.sub_penalty_factor; const int penalty_factor= s->me.sub_penalty_factor;
LOAD_COMMON(xx, yy); LOAD_COMMON
// INIT; // INIT;
//FIXME factorize //FIXME factorize
@@ -139,19 +140,17 @@ static int RENAME(hpel_motion_search)(MpegEncContext * s,
#else #else
static int RENAME(hpel_motion_search)(MpegEncContext * s, static int RENAME(hpel_motion_search)(MpegEncContext * s,
int *mx_ptr, int *my_ptr, int dmin, int *mx_ptr, int *my_ptr, int dmin,
int xmin, int ymin, int xmax, int ymax, int pred_x, int pred_y, uint8_t *src_data[3],
int pred_x, int pred_y, Picture *ref_picture, uint8_t *ref_data[3], int stride, int uvstride,
int n, int size, uint8_t * const mv_penalty) int size, int h, uint8_t * const mv_penalty)
{ {
const int xx = 16 * s->mb_x + 8*(n&1);
const int yy = 16 * s->mb_y + 8*(n>>1);
const int mx = *mx_ptr; const int mx = *mx_ptr;
const int my = *my_ptr; const int my = *my_ptr;
const int penalty_factor= s->me.sub_penalty_factor; const int penalty_factor= s->me.sub_penalty_factor;
me_cmp_func cmp_sub, chroma_cmp_sub; me_cmp_func cmp_sub, chroma_cmp_sub;
int bx=2*mx, by=2*my; int bx=2*mx, by=2*my;
LOAD_COMMON(xx, yy); LOAD_COMMON
//FIXME factorize //FIXME factorize
@@ -247,20 +246,18 @@ static int RENAME(hpel_motion_search)(MpegEncContext * s,
} }
#endif #endif
static int RENAME(hpel_get_mb_score)(MpegEncContext * s, int mx, int my, int pred_x, int pred_y, Picture *ref_picture, static int RENAME(hpel_get_mb_score)(MpegEncContext * s, int mx, int my, int pred_x, int pred_y, uint8_t *src_data[3],
uint8_t *ref_data[3], int stride, int uvstride,
uint8_t * const mv_penalty) uint8_t * const mv_penalty)
{ {
// const int check_luma= s->dsp.me_sub_cmp != s->dsp.mb_cmp; // const int check_luma= s->dsp.me_sub_cmp != s->dsp.mb_cmp;
const int size= 0; const int size= 0;
const int xx = 16 * s->mb_x; const int h= 16;
const int yy = 16 * s->mb_y;
const int penalty_factor= s->me.mb_penalty_factor; const int penalty_factor= s->me.mb_penalty_factor;
const int xmin= -256*256, ymin= -256*256, xmax= 256*256, ymax= 256*256; //assume that the caller checked these
const __attribute__((unused)) int unu2= xmin + xmax +ymin + ymax; //no unused warning shit
me_cmp_func cmp_sub, chroma_cmp_sub; me_cmp_func cmp_sub, chroma_cmp_sub;
int d; int d;
LOAD_COMMON(xx, yy); LOAD_COMMON
//FIXME factorize //FIXME factorize
@@ -295,12 +292,10 @@ static int RENAME(hpel_get_mb_score)(MpegEncContext * s, int mx, int my, int pre
static int RENAME(qpel_motion_search)(MpegEncContext * s, static int RENAME(qpel_motion_search)(MpegEncContext * s,
int *mx_ptr, int *my_ptr, int dmin, int *mx_ptr, int *my_ptr, int dmin,
int xmin, int ymin, int xmax, int ymax, int pred_x, int pred_y, uint8_t *src_data[3],
int pred_x, int pred_y, Picture *ref_picture, uint8_t *ref_data[3], int stride, int uvstride,
int n, int size, uint8_t * const mv_penalty) int size, int h, uint8_t * const mv_penalty)
{ {
const int xx = 16 * s->mb_x + 8*(n&1);
const int yy = 16 * s->mb_y + 8*(n>>1);
const int mx = *mx_ptr; const int mx = *mx_ptr;
const int my = *my_ptr; const int my = *my_ptr;
const int penalty_factor= s->me.sub_penalty_factor; const int penalty_factor= s->me.sub_penalty_factor;
@@ -310,7 +305,7 @@ static int RENAME(qpel_motion_search)(MpegEncContext * s,
me_cmp_func cmp, chroma_cmp; me_cmp_func cmp, chroma_cmp;
me_cmp_func cmp_sub, chroma_cmp_sub; me_cmp_func cmp_sub, chroma_cmp_sub;
LOAD_COMMON(xx, yy); LOAD_COMMON
cmp= s->dsp.me_cmp[size]; cmp= s->dsp.me_cmp[size];
chroma_cmp= s->dsp.me_cmp[size+1]; //factorize FIXME chroma_cmp= s->dsp.me_cmp[size+1]; //factorize FIXME
@@ -514,19 +509,17 @@ static int RENAME(qpel_motion_search)(MpegEncContext * s,
return dmin; return dmin;
} }
static int RENAME(qpel_get_mb_score)(MpegEncContext * s, int mx, int my, int pred_x, int pred_y, Picture *ref_picture, static int RENAME(qpel_get_mb_score)(MpegEncContext * s, int mx, int my, int pred_x, int pred_y, uint8_t *src_data[3],
uint8_t *ref_data[3], int stride, int uvstride,
uint8_t * const mv_penalty) uint8_t * const mv_penalty)
{ {
const int size= 0; const int size= 0;
const int xx = 16 * s->mb_x; const int h= 16;
const int yy = 16 * s->mb_y;
const int penalty_factor= s->me.mb_penalty_factor; const int penalty_factor= s->me.mb_penalty_factor;
const int xmin= -256*256, ymin= -256*256, xmax= 256*256, ymax= 256*256; //assume that the caller checked these
const __attribute__((unused)) int unu2= xmin + xmax +ymin + ymax; //no unused warning shit
me_cmp_func cmp_sub, chroma_cmp_sub; me_cmp_func cmp_sub, chroma_cmp_sub;
int d; int d;
LOAD_COMMON(xx, yy); LOAD_COMMON
//FIXME factorize //FIXME factorize
@@ -597,15 +590,16 @@ if( (y)>(ymax<<(S)) ) printf("%d %d %d %d %d ymax" #v, ymax, (x), (y), s->mb_x,
static inline int RENAME(small_diamond_search)(MpegEncContext * s, int *best, int dmin, static inline int RENAME(small_diamond_search)(MpegEncContext * s, int *best, int dmin,
Picture *ref_picture, uint8_t *src_data[3],
uint8_t *ref_data[3], int stride, int uvstride,
int const pred_x, int const pred_y, int const penalty_factor, int const pred_x, int const pred_y, int const penalty_factor,
int const xmin, int const ymin, int const xmax, int const ymax, int const shift, int const shift,
uint32_t *map, int map_generation, int size, uint8_t * const mv_penalty uint32_t *map, int map_generation, int size, int h, uint8_t * const mv_penalty
) )
{ {
me_cmp_func cmp, chroma_cmp; me_cmp_func cmp, chroma_cmp;
int next_dir=-1; int next_dir=-1;
LOAD_COMMON(s->mb_x*16, s->mb_y*16); LOAD_COMMON
cmp= s->dsp.me_cmp[size]; cmp= s->dsp.me_cmp[size];
chroma_cmp= s->dsp.me_cmp[size+1]; chroma_cmp= s->dsp.me_cmp[size+1];
@@ -639,15 +633,16 @@ static inline int RENAME(small_diamond_search)(MpegEncContext * s, int *best, in
} }
static inline int RENAME(funny_diamond_search)(MpegEncContext * s, int *best, int dmin, static inline int RENAME(funny_diamond_search)(MpegEncContext * s, int *best, int dmin,
Picture *ref_picture, uint8_t *src_data[3],
uint8_t *ref_data[3], int stride, int uvstride,
int const pred_x, int const pred_y, int const penalty_factor, int const pred_x, int const pred_y, int const penalty_factor,
int const xmin, int const ymin, int const xmax, int const ymax, int const shift, int const shift,
uint32_t *map, int map_generation, int size, uint8_t * const mv_penalty uint32_t *map, int map_generation, int size, int h, uint8_t * const mv_penalty
) )
{ {
me_cmp_func cmp, chroma_cmp; me_cmp_func cmp, chroma_cmp;
int dia_size; int dia_size;
LOAD_COMMON(s->mb_x*16, s->mb_y*16); LOAD_COMMON
cmp= s->dsp.me_cmp[size]; cmp= s->dsp.me_cmp[size];
chroma_cmp= s->dsp.me_cmp[size+1]; chroma_cmp= s->dsp.me_cmp[size+1];
@@ -730,17 +725,18 @@ if(256*256*256*64 % (stats[0]+1)==0){
#define MAX_SAB_SIZE 16 #define MAX_SAB_SIZE 16
static inline int RENAME(sab_diamond_search)(MpegEncContext * s, int *best, int dmin, static inline int RENAME(sab_diamond_search)(MpegEncContext * s, int *best, int dmin,
Picture *ref_picture, uint8_t *src_data[3],
uint8_t *ref_data[3], int stride, int uvstride,
int const pred_x, int const pred_y, int const penalty_factor, int const pred_x, int const pred_y, int const penalty_factor,
int const xmin, int const ymin, int const xmax, int const ymax, int const shift, int const shift,
uint32_t *map, int map_generation, int size, uint8_t * const mv_penalty uint32_t *map, int map_generation, int size, int h, uint8_t * const mv_penalty
) )
{ {
me_cmp_func cmp, chroma_cmp; me_cmp_func cmp, chroma_cmp;
Minima minima[MAX_SAB_SIZE]; Minima minima[MAX_SAB_SIZE];
const int minima_count= ABS(s->me.dia_size); const int minima_count= ABS(s->me.dia_size);
int i, j; int i, j;
LOAD_COMMON(s->mb_x*16, s->mb_y*16); LOAD_COMMON
cmp= s->dsp.me_cmp[size]; cmp= s->dsp.me_cmp[size];
chroma_cmp= s->dsp.me_cmp[size+1]; chroma_cmp= s->dsp.me_cmp[size+1];
@@ -810,15 +806,16 @@ static inline int RENAME(sab_diamond_search)(MpegEncContext * s, int *best, int
} }
static inline int RENAME(var_diamond_search)(MpegEncContext * s, int *best, int dmin, static inline int RENAME(var_diamond_search)(MpegEncContext * s, int *best, int dmin,
Picture *ref_picture, uint8_t *src_data[3],
uint8_t *ref_data[3], int stride, int uvstride,
int const pred_x, int const pred_y, int const penalty_factor, int const pred_x, int const pred_y, int const penalty_factor,
int const xmin, int const ymin, int const xmax, int const ymax, int const shift, int const shift,
uint32_t *map, int map_generation, int size, uint8_t * const mv_penalty uint32_t *map, int map_generation, int size, int h, uint8_t * const mv_penalty
) )
{ {
me_cmp_func cmp, chroma_cmp; me_cmp_func cmp, chroma_cmp;
int dia_size; int dia_size;
LOAD_COMMON(s->mb_x*16, s->mb_y*16); LOAD_COMMON
cmp= s->dsp.me_cmp[size]; cmp= s->dsp.me_cmp[size];
chroma_cmp= s->dsp.me_cmp[size+1]; chroma_cmp= s->dsp.me_cmp[size+1];
@@ -886,10 +883,10 @@ if(256*256*256*64 % (stats[0]+1)==0){
return dmin; return dmin;
} }
static int RENAME(epzs_motion_search)(MpegEncContext * s, int block, static int RENAME(epzs_motion_search)(MpegEncContext * s,
int *mx_ptr, int *my_ptr, int *mx_ptr, int *my_ptr,
int P[10][2], int pred_x, int pred_y, int P[10][2], int pred_x, int pred_y, uint8_t *src_data[3],
int xmin, int ymin, int xmax, int ymax, Picture *ref_picture, int16_t (*last_mv)[2], uint8_t *ref_data[3], int stride, int uvstride, int16_t (*last_mv)[2],
int ref_mv_scale, uint8_t * const mv_penalty) int ref_mv_scale, uint8_t * const mv_penalty)
{ {
int best[2]={0, 0}; int best[2]={0, 0};
@@ -899,10 +896,11 @@ static int RENAME(epzs_motion_search)(MpegEncContext * s, int block,
int map_generation; int map_generation;
const int penalty_factor= s->me.penalty_factor; const int penalty_factor= s->me.penalty_factor;
const int size=0; const int size=0;
const int ref_mv_stride= s->mb_stride; const int h=16;
const int ref_mv_xy= s->mb_x + s->mb_y*ref_mv_stride; const int ref_mv_stride= s->mb_stride; //pass as arg FIXME
const int ref_mv_xy= s->mb_x + s->mb_y*ref_mv_stride; //add to last_mv beforepassing FIXME
me_cmp_func cmp, chroma_cmp; me_cmp_func cmp, chroma_cmp;
LOAD_COMMON(s->mb_x*16, s->mb_y*16); LOAD_COMMON
cmp= s->dsp.me_cmp[size]; cmp= s->dsp.me_cmp[size];
chroma_cmp= s->dsp.me_cmp[size+1]; chroma_cmp= s->dsp.me_cmp[size+1];
@@ -973,21 +971,21 @@ static int RENAME(epzs_motion_search)(MpegEncContext * s, int block,
//check(best[0],best[1],0, b0) //check(best[0],best[1],0, b0)
if(s->me.dia_size==-1) if(s->me.dia_size==-1)
dmin= RENAME(funny_diamond_search)(s, best, dmin, ref_picture, dmin= RENAME(funny_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride,
pred_x, pred_y, penalty_factor, xmin, ymin, xmax, ymax, pred_x, pred_y, penalty_factor,
shift, map, map_generation, size, mv_penalty); shift, map, map_generation, size, h, mv_penalty);
else if(s->me.dia_size<-1) else if(s->me.dia_size<-1)
dmin= RENAME(sab_diamond_search)(s, best, dmin, ref_picture, dmin= RENAME(sab_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride,
pred_x, pred_y, penalty_factor, xmin, ymin, xmax, ymax, pred_x, pred_y, penalty_factor,
shift, map, map_generation, size, mv_penalty); shift, map, map_generation, size, h, mv_penalty);
else if(s->me.dia_size<2) else if(s->me.dia_size<2)
dmin= RENAME(small_diamond_search)(s, best, dmin, ref_picture, dmin= RENAME(small_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride,
pred_x, pred_y, penalty_factor, xmin, ymin, xmax, ymax, pred_x, pred_y, penalty_factor,
shift, map, map_generation, size, mv_penalty); shift, map, map_generation, size, h, mv_penalty);
else else
dmin= RENAME(var_diamond_search)(s, best, dmin, ref_picture, dmin= RENAME(var_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride,
pred_x, pred_y, penalty_factor, xmin, ymin, xmax, ymax, pred_x, pred_y, penalty_factor,
shift, map, map_generation, size, mv_penalty); shift, map, map_generation, size, h, mv_penalty);
//check(best[0],best[1],0, b1) //check(best[0],best[1],0, b1)
*mx_ptr= best[0]; *mx_ptr= best[0];
@@ -998,10 +996,11 @@ static int RENAME(epzs_motion_search)(MpegEncContext * s, int block,
} }
#ifndef CMP_DIRECT /* no 4mv search needed in direct mode */ #ifndef CMP_DIRECT /* no 4mv search needed in direct mode */
static int RENAME(epzs_motion_search4)(MpegEncContext * s, int block, static int RENAME(epzs_motion_search4)(MpegEncContext * s,
int *mx_ptr, int *my_ptr, int *mx_ptr, int *my_ptr,
int P[10][2], int pred_x, int pred_y, int P[10][2], int pred_x, int pred_y,
int xmin, int ymin, int xmax, int ymax, Picture *ref_picture, int16_t (*last_mv)[2], uint8_t *src_data[3],
uint8_t *ref_data[3], int stride, int uvstride, int16_t (*last_mv)[2],
int ref_mv_scale, uint8_t * const mv_penalty) int ref_mv_scale, uint8_t * const mv_penalty)
{ {
int best[2]={0, 0}; int best[2]={0, 0};
@@ -1011,10 +1010,11 @@ static int RENAME(epzs_motion_search4)(MpegEncContext * s, int block,
int map_generation; int map_generation;
const int penalty_factor= s->me.penalty_factor; const int penalty_factor= s->me.penalty_factor;
const int size=1; const int size=1;
const int h=8;
const int ref_mv_stride= s->mb_stride; const int ref_mv_stride= s->mb_stride;
const int ref_mv_xy= s->mb_x + s->mb_y *ref_mv_stride; const int ref_mv_xy= s->mb_x + s->mb_y *ref_mv_stride;
me_cmp_func cmp, chroma_cmp; me_cmp_func cmp, chroma_cmp;
LOAD_COMMON((s->mb_x*2 + (block&1))*8, (s->mb_y*2 + (block>>1))*8); LOAD_COMMON
cmp= s->dsp.me_cmp[size]; cmp= s->dsp.me_cmp[size];
chroma_cmp= s->dsp.me_cmp[size+1]; chroma_cmp= s->dsp.me_cmp[size+1];
@@ -1024,7 +1024,7 @@ static int RENAME(epzs_motion_search4)(MpegEncContext * s, int block,
dmin = 1000000; dmin = 1000000;
//printf("%d %d %d %d //",xmin, ymin, xmax, ymax); //printf("%d %d %d %d //",xmin, ymin, xmax, ymax);
/* first line */ /* first line */
if (s->mb_y == 0 && block<2) { if (s->mb_y == 0/* && block<2*/) {
CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift)
CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16,
(last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
@@ -1049,21 +1049,100 @@ static int RENAME(epzs_motion_search4)(MpegEncContext * s, int block,
} }
if(s->me.dia_size==-1) if(s->me.dia_size==-1)
dmin= RENAME(funny_diamond_search)(s, best, dmin, ref_picture, dmin= RENAME(funny_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride,
pred_x, pred_y, penalty_factor, xmin, ymin, xmax, ymax, pred_x, pred_y, penalty_factor,
shift, map, map_generation, size, mv_penalty); shift, map, map_generation, size, h, mv_penalty);
else if(s->me.dia_size<-1) else if(s->me.dia_size<-1)
dmin= RENAME(sab_diamond_search)(s, best, dmin, ref_picture, dmin= RENAME(sab_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride,
pred_x, pred_y, penalty_factor, xmin, ymin, xmax, ymax, pred_x, pred_y, penalty_factor,
shift, map, map_generation, size, mv_penalty); shift, map, map_generation, size, h, mv_penalty);
else if(s->me.dia_size<2) else if(s->me.dia_size<2)
dmin= RENAME(small_diamond_search)(s, best, dmin, ref_picture, dmin= RENAME(small_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride,
pred_x, pred_y, penalty_factor, xmin, ymin, xmax, ymax, pred_x, pred_y, penalty_factor,
shift, map, map_generation, size, mv_penalty); shift, map, map_generation, size, h, mv_penalty);
else else
dmin= RENAME(var_diamond_search)(s, best, dmin, ref_picture, dmin= RENAME(var_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride,
pred_x, pred_y, penalty_factor, xmin, ymin, xmax, ymax, pred_x, pred_y, penalty_factor,
shift, map, map_generation, size, mv_penalty); shift, map, map_generation, size, h, mv_penalty);
*mx_ptr= best[0];
*my_ptr= best[1];
// printf("%d %d %d \n", best[0], best[1], dmin);
return dmin;
}
//try to merge with above FIXME (needs PSNR test)
static int RENAME(epzs_motion_search2)(MpegEncContext * s,
int *mx_ptr, int *my_ptr,
int P[10][2], int pred_x, int pred_y,
uint8_t *src_data[3],
uint8_t *ref_data[3], int stride, int uvstride, int16_t (*last_mv)[2],
int ref_mv_scale, uint8_t * const mv_penalty)
{
int best[2]={0, 0};
int d, dmin;
const int shift= 1+s->quarter_sample;
uint32_t *map= s->me.map;
int map_generation;
const int penalty_factor= s->me.penalty_factor;
const int size=0; //FIXME pass as arg
const int h=8;
const int ref_mv_stride= s->mb_stride;
const int ref_mv_xy= s->mb_x + s->mb_y *ref_mv_stride;
me_cmp_func cmp, chroma_cmp;
LOAD_COMMON
cmp= s->dsp.me_cmp[size];
chroma_cmp= s->dsp.me_cmp[size+1];
map_generation= update_map_generation(s);
dmin = 1000000;
//printf("%d %d %d %d //",xmin, ymin, xmax, ymax);
/* first line */
if (s->mb_y == 0) {
CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift)
CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16,
(last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
CHECK_MV(P_MV1[0]>>shift, P_MV1[1]>>shift)
}else{
CHECK_MV(P_MV1[0]>>shift, P_MV1[1]>>shift)
//FIXME try some early stop
if(dmin>64*2){
CHECK_MV(P_MEDIAN[0]>>shift, P_MEDIAN[1]>>shift)
CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift)
CHECK_MV(P_TOP[0]>>shift, P_TOP[1]>>shift)
CHECK_MV(P_TOPRIGHT[0]>>shift, P_TOPRIGHT[1]>>shift)
CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16,
(last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)
}
}
if(dmin>64*4){
CHECK_CLIPED_MV((last_mv[ref_mv_xy+1][0]*ref_mv_scale + (1<<15))>>16,
(last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16)
CHECK_CLIPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,
(last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)
}
if(s->me.dia_size==-1)
dmin= RENAME(funny_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride,
pred_x, pred_y, penalty_factor,
shift, map, map_generation, size, h, mv_penalty);
else if(s->me.dia_size<-1)
dmin= RENAME(sab_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride,
pred_x, pred_y, penalty_factor,
shift, map, map_generation, size, h, mv_penalty);
else if(s->me.dia_size<2)
dmin= RENAME(small_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride,
pred_x, pred_y, penalty_factor,
shift, map, map_generation, size, h, mv_penalty);
else
dmin= RENAME(var_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride,
pred_x, pred_y, penalty_factor,
shift, map, map_generation, size, h, mv_penalty);
*mx_ptr= best[0]; *mx_ptr= best[0];
*my_ptr= best[1]; *my_ptr= best[1];
@@ -1,6 +1,7 @@
/* /*
* MPEG1 codec / MPEG2 decoder * MPEG1 codec / MPEG2 decoder
* Copyright (c) 2000,2001 Fabrice Bellard. * Copyright (c) 2000,2001 Fabrice Bellard.
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -29,6 +30,9 @@
#include "mpeg12data.h" #include "mpeg12data.h"
//#undef NDEBUG
//#include <assert.h>
/* Start codes. */ /* Start codes. */
#define SEQ_END_CODE 0x000001b7 #define SEQ_END_CODE 0x000001b7
@@ -54,7 +58,6 @@ static void mpeg1_encode_block(MpegEncContext *s,
int component); int component);
static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code); // RAL: f_code parameter added static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code); // RAL: f_code parameter added
#endif //CONFIG_ENCODERS #endif //CONFIG_ENCODERS
static void mpeg1_skip_picture(MpegEncContext *s, int pict_num);
static inline int mpeg1_decode_block_inter(MpegEncContext *s, static inline int mpeg1_decode_block_inter(MpegEncContext *s,
DCTELEM *block, DCTELEM *block,
int n); int n);
@@ -178,6 +181,46 @@ static void init_uni_ac_vlc(RLTable *rl, uint32_t *uni_ac_vlc_bits, uint8_t *uni
} }
} }
static int find_frame_rate_index(MpegEncContext *s){
int i;
int64_t dmin= INT64_MAX;
int64_t d;
for(i=1;i<14;i++) {
if(s->avctx->strict_std_compliance >= 0 && i>=9) break;
d = ABS(MPEG1_FRAME_RATE_BASE*(int64_t)s->avctx->frame_rate - frame_rate_tab[i]*(int64_t)s->avctx->frame_rate_base);
if(d < dmin){
dmin=d;
s->frame_rate_index= i;
}
}
if(dmin)
return -1;
else
return 0;
}
static int encode_init(AVCodecContext *avctx)
{
MpegEncContext *s = avctx->priv_data;
if(MPV_encode_init(avctx) < 0)
return -1;
if(find_frame_rate_index(s) < 0){
if(s->strict_std_compliance >=0){
av_log(avctx, AV_LOG_ERROR, "MPEG1/2 doesnt support %d/%d fps\n", avctx->frame_rate, avctx->frame_rate_base);
return -1;
}else{
av_log(avctx, AV_LOG_INFO, "MPEG1/2 doesnt support %d/%d fps, there may be AV sync issues\n", avctx->frame_rate, avctx->frame_rate_base);
}
}
return 0;
}
static void put_header(MpegEncContext *s, int header) static void put_header(MpegEncContext *s, int header)
{ {
align_put_bits(&s->pb); align_put_bits(&s->pb);
@@ -201,22 +244,6 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s)
if (s->current_picture.key_frame) { if (s->current_picture.key_frame) {
/* mpeg1 header repeated every gop */ /* mpeg1 header repeated every gop */
put_header(s, SEQ_START_CODE); put_header(s, SEQ_START_CODE);
/* search closest frame rate */
{
int i, dmin, d;
s->frame_rate_index = 0;
dmin = 0x7fffffff;
for(i=1;i<14;i++) {
if(s->avctx->strict_std_compliance >= 0 && i>=9) break;
d = abs(MPEG1_FRAME_RATE_BASE*(int64_t)s->avctx->frame_rate/s->avctx->frame_rate_base - frame_rate_tab[i]);
if (d < dmin) {
dmin = d;
s->frame_rate_index = i;
}
}
}
put_bits(&s->pb, 12, s->width); put_bits(&s->pb, 12, s->width);
put_bits(&s->pb, 12, s->height); put_bits(&s->pb, 12, s->height);
@@ -294,30 +321,18 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s)
put_bits(&s->pb, 1, 0); /* do drop frame */ put_bits(&s->pb, 1, 0); /* do drop frame */
/* time code : we must convert from the real frame rate to a /* time code : we must convert from the real frame rate to a
fake mpeg frame rate in case of low frame rate */ fake mpeg frame rate in case of low frame rate */
fps = frame_rate_tab[s->frame_rate_index]; fps = (frame_rate_tab[s->frame_rate_index] + MPEG1_FRAME_RATE_BASE/2)/ MPEG1_FRAME_RATE_BASE;
time_code = (int64_t)s->fake_picture_number * MPEG1_FRAME_RATE_BASE; time_code = s->current_picture_ptr->coded_picture_number;
s->gop_picture_number = s->fake_picture_number;
s->gop_picture_number = time_code;
put_bits(&s->pb, 5, (uint32_t)((time_code / (fps * 3600)) % 24)); put_bits(&s->pb, 5, (uint32_t)((time_code / (fps * 3600)) % 24));
put_bits(&s->pb, 6, (uint32_t)((time_code / (fps * 60)) % 60)); put_bits(&s->pb, 6, (uint32_t)((time_code / (fps * 60)) % 60));
put_bits(&s->pb, 1, 1); put_bits(&s->pb, 1, 1);
put_bits(&s->pb, 6, (uint32_t)((time_code / fps) % 60)); put_bits(&s->pb, 6, (uint32_t)((time_code / fps) % 60));
put_bits(&s->pb, 6, (uint32_t)((time_code % fps) / MPEG1_FRAME_RATE_BASE)); put_bits(&s->pb, 6, (uint32_t)((time_code % fps)));
put_bits(&s->pb, 1, 0); /* closed gop */ put_bits(&s->pb, 1, !!(s->flags & CODEC_FLAG_CLOSED_GOP));
put_bits(&s->pb, 1, 0); /* broken link */ put_bits(&s->pb, 1, 0); /* broken link */
} }
if (s->avctx->frame_rate < (24 * s->avctx->frame_rate_base) && s->picture_number > 0) {
/* insert empty P pictures to slow down to the desired
frame rate. Each fake pictures takes about 20 bytes */
fps = frame_rate_tab[s->frame_rate_index];
n = av_rescale((int64_t)s->picture_number * s->avctx->frame_rate_base, fps, s->avctx->frame_rate) / MPEG1_FRAME_RATE_BASE - 1;
while (s->fake_picture_number < n) {
mpeg1_skip_picture(s, s->fake_picture_number -
s->gop_picture_number);
s->fake_picture_number++;
}
}
} }
static inline void encode_mb_skip_run(MpegEncContext *s, int run){ static inline void encode_mb_skip_run(MpegEncContext *s, int run){
@@ -328,49 +343,6 @@ static inline void encode_mb_skip_run(MpegEncContext *s, int run){
put_bits(&s->pb, mbAddrIncrTable[run][1], put_bits(&s->pb, mbAddrIncrTable[run][1],
mbAddrIncrTable[run][0]); mbAddrIncrTable[run][0]);
} }
/* insert a fake P picture */
static void mpeg1_skip_picture(MpegEncContext *s, int pict_num)
{
assert(s->codec_id == CODEC_ID_MPEG1VIDEO); // mpeg2 can do these repeat things
/* mpeg1 picture header */
put_header(s, PICTURE_START_CODE);
/* temporal reference */
put_bits(&s->pb, 10, pict_num & 0x3ff);
put_bits(&s->pb, 3, P_TYPE);
put_bits(&s->pb, 16, 0xffff); /* non constant bit rate */
put_bits(&s->pb, 1, 1); /* integer coordinates */
put_bits(&s->pb, 3, 1); /* forward_f_code */
put_bits(&s->pb, 1, 0); /* extra bit picture */
/* only one slice */
put_header(s, SLICE_MIN_START_CODE);
put_bits(&s->pb, 5, 1); /* quantizer scale */
put_bits(&s->pb, 1, 0); /* slice extra information */
encode_mb_skip_run(s, 0);
/* empty macroblock */
put_bits(&s->pb, 3, 1); /* motion only */
/* zero motion x & y */
put_bits(&s->pb, 1, 1);
put_bits(&s->pb, 1, 1);
/* output a number of empty slice */
encode_mb_skip_run(s, s->mb_width * s->mb_height - 2);
/* empty macroblock */
put_bits(&s->pb, 3, 1); /* motion only */
/* zero motion x & y */
put_bits(&s->pb, 1, 1);
put_bits(&s->pb, 1, 1);
}
#endif //CONFIG_ENCODERS #endif //CONFIG_ENCODERS
static void common_init(MpegEncContext *s) static void common_init(MpegEncContext *s)
@@ -405,10 +377,10 @@ void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number)
// RAL: s->picture_number instead of s->fake_picture_number // RAL: s->picture_number instead of s->fake_picture_number
put_bits(&s->pb, 10, (s->picture_number - put_bits(&s->pb, 10, (s->picture_number -
s->gop_picture_number) & 0x3ff); s->gop_picture_number) & 0x3ff);
s->fake_picture_number++;
put_bits(&s->pb, 3, s->pict_type); put_bits(&s->pb, 3, s->pict_type);
put_bits(&s->pb, 16, 0xffff); /* non constant bit rate */
s->vbv_delay_ptr= s->pb.buf + get_bit_count(&s->pb)/8;
put_bits(&s->pb, 16, 0xFFFF); /* vbv_delay */
// RAL: Forward f_code also needed for B frames // RAL: Forward f_code also needed for B frames
if (s->pict_type == P_TYPE || s->pict_type == B_TYPE) { if (s->pict_type == P_TYPE || s->pict_type == B_TYPE) {
@@ -468,18 +440,26 @@ void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number)
put_bits(&s->pb, 1, s->progressive_frame); put_bits(&s->pb, 1, s->progressive_frame);
put_bits(&s->pb, 1, 0); //composite_display_flag put_bits(&s->pb, 1, 0); //composite_display_flag
} }
if(s->flags & CODEC_FLAG_SVCD_SCAN_OFFSET){
int i;
put_header(s, USER_START_CODE);
for(i=0; i<sizeof(svcd_scan_offset_placeholder); i++){
put_bits(&s->pb, 8, svcd_scan_offset_placeholder[i]);
}
}
s->mb_y=0; s->mb_y=0;
ff_mpeg1_encode_slice_header(s); ff_mpeg1_encode_slice_header(s);
} }
static inline void put_mb_modes(MpegEncContext *s, int n, int bits, static inline void put_mb_modes(MpegEncContext *s, int n, int bits,
int has_mv) int has_mv, int field_motion)
{ {
put_bits(&s->pb, n, bits); put_bits(&s->pb, n, bits);
if (!s->frame_pred_frame_dct) { if (!s->frame_pred_frame_dct) {
if (has_mv) if (has_mv)
put_bits(&s->pb, 2, 2); /* motion_type: frame */ put_bits(&s->pb, 2, 2 - field_motion); /* motion_type: frame/field */
put_bits(&s->pb, 1, s->interlaced_dct); put_bits(&s->pb, 1, s->interlaced_dct);
} }
} }
@@ -499,9 +479,9 @@ void mpeg1_encode_mb(MpegEncContext *s,
if (s->block_last_index[i] >= 0) if (s->block_last_index[i] >= 0)
cbp |= 1 << (5 - i); cbp |= 1 << (5 - i);
} }
if (cbp == 0 && !first_mb && (mb_x != s->mb_width - 1 || (mb_y != s->mb_height - 1 && s->codec_id == CODEC_ID_MPEG1VIDEO)) && if (cbp == 0 && !first_mb && (mb_x != s->mb_width - 1 || (mb_y != s->mb_height - 1 && s->codec_id == CODEC_ID_MPEG1VIDEO)) &&
((s->pict_type == P_TYPE && (motion_x | motion_y) == 0) || ((s->pict_type == P_TYPE && s->mv_type == MV_TYPE_16X16 && (motion_x | motion_y) == 0) ||
(s->pict_type == B_TYPE && s->mv_dir == s->last_mv_dir && (((s->mv_dir & MV_DIR_FORWARD) ? ((s->mv[0][0][0] - s->last_mv[0][0][0])|(s->mv[0][0][1] - s->last_mv[0][0][1])) : 0) | (s->pict_type == B_TYPE && s->mv_dir == s->last_mv_dir && (((s->mv_dir & MV_DIR_FORWARD) ? ((s->mv[0][0][0] - s->last_mv[0][0][0])|(s->mv[0][0][1] - s->last_mv[0][0][1])) : 0) |
((s->mv_dir & MV_DIR_BACKWARD) ? ((s->mv[1][0][0] - s->last_mv[1][0][0])|(s->mv[1][0][1] - s->last_mv[1][0][1])) : 0)) == 0))) { ((s->mv_dir & MV_DIR_BACKWARD) ? ((s->mv[1][0][0] - s->last_mv[1][0][0])|(s->mv[1][0][1] - s->last_mv[1][0][1])) : 0)) == 0))) {
s->mb_skip_run++; s->mb_skip_run++;
@@ -509,6 +489,10 @@ void mpeg1_encode_mb(MpegEncContext *s,
s->skip_count++; s->skip_count++;
s->misc_bits++; s->misc_bits++;
s->last_bits++; s->last_bits++;
if(s->pict_type == P_TYPE){
s->last_mv[0][1][0]= s->last_mv[0][0][0]=
s->last_mv[0][1][1]= s->last_mv[0][0][1]= 0;
}
} else { } else {
if(first_mb){ if(first_mb){
assert(s->mb_skip_run == 0); assert(s->mb_skip_run == 0);
@@ -519,150 +503,167 @@ void mpeg1_encode_mb(MpegEncContext *s,
if (s->pict_type == I_TYPE) { if (s->pict_type == I_TYPE) {
if(s->dquant && cbp){ if(s->dquant && cbp){
put_mb_modes(s, 2, 1, 0); /* macroblock_type : macroblock_quant = 1 */ put_mb_modes(s, 2, 1, 0, 0); /* macroblock_type : macroblock_quant = 1 */
put_bits(&s->pb, 5, s->qscale); put_bits(&s->pb, 5, s->qscale);
}else{ }else{
put_mb_modes(s, 1, 1, 0); /* macroblock_type : macroblock_quant = 0 */ put_mb_modes(s, 1, 1, 0, 0); /* macroblock_type : macroblock_quant = 0 */
s->qscale -= s->dquant; s->qscale -= s->dquant;
} }
s->misc_bits+= get_bits_diff(s); s->misc_bits+= get_bits_diff(s);
s->i_count++; s->i_count++;
} else if (s->mb_intra) { } else if (s->mb_intra) {
if(s->dquant && cbp){ if(s->dquant && cbp){
put_mb_modes(s, 6, 0x01, 0); put_mb_modes(s, 6, 0x01, 0, 0);
put_bits(&s->pb, 5, s->qscale); put_bits(&s->pb, 5, s->qscale);
}else{ }else{
put_mb_modes(s, 5, 0x03, 0); put_mb_modes(s, 5, 0x03, 0, 0);
s->qscale -= s->dquant; s->qscale -= s->dquant;
} }
s->misc_bits+= get_bits_diff(s); s->misc_bits+= get_bits_diff(s);
s->i_count++; s->i_count++;
s->last_mv[0][0][0] = memset(s->last_mv, 0, sizeof(s->last_mv));
s->last_mv[0][0][1] = 0;
} else if (s->pict_type == P_TYPE) { } else if (s->pict_type == P_TYPE) {
if(s->mv_type == MV_TYPE_16X16){
if (cbp != 0) { if (cbp != 0) {
if (motion_x == 0 && motion_y == 0) { if ((motion_x|motion_y) == 0) {
if(s->dquant){ if(s->dquant){
put_mb_modes(s, 5, 1, 0); /* macroblock_pattern & quant */ put_mb_modes(s, 5, 1, 0, 0); /* macroblock_pattern & quant */
put_bits(&s->pb, 5, s->qscale); put_bits(&s->pb, 5, s->qscale);
}else{ }else{
put_mb_modes(s, 2, 1, 0); /* macroblock_pattern only */ put_mb_modes(s, 2, 1, 0, 0); /* macroblock_pattern only */
} }
s->misc_bits+= get_bits_diff(s); s->misc_bits+= get_bits_diff(s);
put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]);
} else { } else {
if(s->dquant){ if(s->dquant){
put_mb_modes(s, 5, 2, 1); /* motion + cbp */ put_mb_modes(s, 5, 2, 1, 0); /* motion + cbp */
put_bits(&s->pb, 5, s->qscale); put_bits(&s->pb, 5, s->qscale);
}else{ }else{
put_mb_modes(s, 1, 1, 1); /* motion + cbp */ put_mb_modes(s, 1, 1, 1, 0); /* motion + cbp */
} }
s->misc_bits+= get_bits_diff(s); s->misc_bits+= get_bits_diff(s);
mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); // RAL: f_code parameter added mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); // RAL: f_code parameter added
mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); // RAL: f_code parameter added mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); // RAL: f_code parameter added
s->mv_bits+= get_bits_diff(s); s->mv_bits+= get_bits_diff(s);
put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]);
} }
} else { } else {
put_bits(&s->pb, 3, 1); /* motion only */ put_bits(&s->pb, 3, 1); /* motion only */
if (!s->frame_pred_frame_dct) if (!s->frame_pred_frame_dct)
put_bits(&s->pb, 2, 2); /* motion_type: frame */ put_bits(&s->pb, 2, 2); /* motion_type: frame */
s->misc_bits+= get_bits_diff(s);
mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); // RAL: f_code parameter added mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); // RAL: f_code parameter added
mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); // RAL: f_code parameter added mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); // RAL: f_code parameter added
s->qscale -= s->dquant; s->qscale -= s->dquant;
s->mv_bits+= get_bits_diff(s); s->mv_bits+= get_bits_diff(s);
} }
s->f_count++; s->last_mv[0][1][0]= s->last_mv[0][0][0]= motion_x;
} else s->last_mv[0][1][1]= s->last_mv[0][0][1]= motion_y;
{ // RAL: All the following bloc added for B frames: }else{
if (cbp != 0) assert(!s->frame_pred_frame_dct && s->mv_type == MV_TYPE_FIELD);
{ // With coded bloc pattern
if (s->mv_dir == (MV_DIR_FORWARD | MV_DIR_BACKWARD)) if (cbp) {
{ // Bi-directional motion if(s->dquant){
if (s->dquant) { put_mb_modes(s, 5, 2, 1, 1); /* motion + cbp */
put_mb_modes(s, 5, 2, 1); put_bits(&s->pb, 5, s->qscale);
put_bits(&s->pb, 5, s->qscale); }else{
} else { put_mb_modes(s, 1, 1, 1, 1); /* motion + cbp */
put_mb_modes(s, 2, 3, 1);
}
s->misc_bits += get_bits_diff(s);
mpeg1_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code);
mpeg1_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code);
mpeg1_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code);
mpeg1_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code);
s->b_count++;
s->f_count++;
s->mv_bits += get_bits_diff(s);
put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]);
}
else if (s->mv_dir == MV_DIR_BACKWARD)
{ // Backward motion
if (s->dquant) {
put_mb_modes(s, 6, 2, 1);
put_bits(&s->pb, 5, s->qscale);
} else {
put_mb_modes(s, 3, 3, 1);
}
s->misc_bits += get_bits_diff(s);
mpeg1_encode_motion(s, motion_x - s->last_mv[1][0][0], s->b_code);
mpeg1_encode_motion(s, motion_y - s->last_mv[1][0][1], s->b_code);
s->b_count++;
s->mv_bits += get_bits_diff(s);
put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]);
}
else if (s->mv_dir == MV_DIR_FORWARD)
{ // Forward motion
if (s->dquant) {
put_mb_modes(s, 6, 3, 1);
put_bits(&s->pb, 5, s->qscale);
} else {
put_mb_modes(s, 4, 3, 1);
}
s->misc_bits += get_bits_diff(s);
mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code);
mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code);
s->f_count++;
s->mv_bits += get_bits_diff(s);
put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]);
}
} }
else } else {
{ // No coded bloc pattern put_bits(&s->pb, 3, 1); /* motion only */
if (s->mv_dir == (MV_DIR_FORWARD | MV_DIR_BACKWARD)) put_bits(&s->pb, 2, 1); /* motion_type: field */
{ // Bi-directional motion
put_bits(&s->pb, 2, 2); /* backward & forward motion */
if (!s->frame_pred_frame_dct)
put_bits(&s->pb, 2, 2); /* motion_type: frame */
mpeg1_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code);
mpeg1_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code);
mpeg1_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code);
mpeg1_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code);
s->b_count++;
s->f_count++;
}
else if (s->mv_dir == MV_DIR_BACKWARD)
{ // Backward motion
put_bits(&s->pb, 3, 2); /* backward motion only */
if (!s->frame_pred_frame_dct)
put_bits(&s->pb, 2, 2); /* motion_type: frame */
mpeg1_encode_motion(s, motion_x - s->last_mv[1][0][0], s->b_code);
mpeg1_encode_motion(s, motion_y - s->last_mv[1][0][1], s->b_code);
s->b_count++;
}
else if (s->mv_dir == MV_DIR_FORWARD)
{ // Forward motion
put_bits(&s->pb, 4, 2); /* forward motion only */
if (!s->frame_pred_frame_dct)
put_bits(&s->pb, 2, 2); /* motion_type: frame */
mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code);
mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code);
s->f_count++;
}
s->qscale -= s->dquant; s->qscale -= s->dquant;
s->mv_bits += get_bits_diff(s); }
} s->misc_bits+= get_bits_diff(s);
// End of bloc from RAL for(i=0; i<2; i++){
put_bits(&s->pb, 1, s->field_select[0][i]);
mpeg1_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code);
mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code);
s->last_mv[0][i][0]= s->mv[0][i][0];
s->last_mv[0][i][1]= 2*s->mv[0][i][1];
}
s->mv_bits+= get_bits_diff(s);
} }
if(cbp)
put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]);
s->f_count++;
} else{
static const int mb_type_len[4]={0,3,4,2}; //bak,for,bi
if(s->mv_type == MV_TYPE_16X16){
if (cbp){ // With coded bloc pattern
if (s->dquant) {
if(s->mv_dir == MV_DIR_FORWARD)
put_mb_modes(s, 6, 3, 1, 0);
else
put_mb_modes(s, mb_type_len[s->mv_dir]+3, 2, 1, 0);
put_bits(&s->pb, 5, s->qscale);
} else {
put_mb_modes(s, mb_type_len[s->mv_dir], 3, 1, 0);
}
}else{ // No coded bloc pattern
put_bits(&s->pb, mb_type_len[s->mv_dir], 2);
if (!s->frame_pred_frame_dct)
put_bits(&s->pb, 2, 2); /* motion_type: frame */
s->qscale -= s->dquant;
}
s->misc_bits += get_bits_diff(s);
if (s->mv_dir&MV_DIR_FORWARD){
mpeg1_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code);
mpeg1_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code);
s->last_mv[0][0][0]=s->last_mv[0][1][0]= s->mv[0][0][0];
s->last_mv[0][0][1]=s->last_mv[0][1][1]= s->mv[0][0][1];
s->f_count++;
}
if (s->mv_dir&MV_DIR_BACKWARD){
mpeg1_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code);
mpeg1_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code);
s->last_mv[1][0][0]=s->last_mv[1][1][0]= s->mv[1][0][0];
s->last_mv[1][0][1]=s->last_mv[1][1][1]= s->mv[1][0][1];
s->b_count++;
}
}else{
assert(s->mv_type == MV_TYPE_FIELD);
assert(!s->frame_pred_frame_dct);
if (cbp){ // With coded bloc pattern
if (s->dquant) {
if(s->mv_dir == MV_DIR_FORWARD)
put_mb_modes(s, 6, 3, 1, 1);
else
put_mb_modes(s, mb_type_len[s->mv_dir]+3, 2, 1, 1);
put_bits(&s->pb, 5, s->qscale);
} else {
put_mb_modes(s, mb_type_len[s->mv_dir], 3, 1, 1);
}
}else{ // No coded bloc pattern
put_bits(&s->pb, mb_type_len[s->mv_dir], 2);
put_bits(&s->pb, 2, 1); /* motion_type: field */
s->qscale -= s->dquant;
}
s->misc_bits += get_bits_diff(s);
if (s->mv_dir&MV_DIR_FORWARD){
for(i=0; i<2; i++){
put_bits(&s->pb, 1, s->field_select[0][i]);
mpeg1_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code);
mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code);
s->last_mv[0][i][0]= s->mv[0][i][0];
s->last_mv[0][i][1]= 2*s->mv[0][i][1];
}
s->f_count++;
}
if (s->mv_dir&MV_DIR_BACKWARD){
for(i=0; i<2; i++){
put_bits(&s->pb, 1, s->field_select[1][i]);
mpeg1_encode_motion(s, s->mv[1][i][0] - s->last_mv[1][i][0] , s->b_code);
mpeg1_encode_motion(s, s->mv[1][i][1] - (s->last_mv[1][i][1]>>1), s->b_code);
s->last_mv[1][i][0]= s->mv[1][i][0];
s->last_mv[1][i][1]= 2*s->mv[1][i][1];
}
s->b_count++;
}
}
s->mv_bits += get_bits_diff(s);
if(cbp)
put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]);
}
for(i=0;i<6;i++) { for(i=0;i<6;i++) {
if (cbp & (1 << (5 - i))) { if (cbp & (1 << (5 - i))) {
mpeg1_encode_block(s, block[i], i); mpeg1_encode_block(s, block[i], i);
@@ -674,18 +675,6 @@ void mpeg1_encode_mb(MpegEncContext *s,
else else
s->p_tex_bits+= get_bits_diff(s); s->p_tex_bits+= get_bits_diff(s);
} }
// RAL: By this:
if (s->mv_dir & MV_DIR_FORWARD)
{
s->last_mv[0][0][0]= s->mv[0][0][0];
s->last_mv[0][0][1]= s->mv[0][0][1];
}
if (s->mv_dir & MV_DIR_BACKWARD)
{
s->last_mv[1][0][0]= s->mv[1][0][0];
s->last_mv[1][0][1]= s->mv[1][0][1];
}
} }
// RAL: Parameter added: f_or_b_code // RAL: Parameter added: f_or_b_code
@@ -994,14 +983,11 @@ static inline int get_dmv(MpegEncContext *s)
static inline int get_qscale(MpegEncContext *s) static inline int get_qscale(MpegEncContext *s)
{ {
int qscale = get_bits(&s->gb, 5); int qscale = get_bits(&s->gb, 5);
if (s->codec_id == CODEC_ID_MPEG2VIDEO) { if (s->q_scale_type) {
if (s->q_scale_type) { return non_linear_qscale[qscale];
return non_linear_qscale[qscale]; } else {
} else { return qscale << 1;
return qscale << 1;
}
} }
return qscale;
} }
/* motion type (for mpeg2) */ /* motion type (for mpeg2) */
@@ -1431,7 +1417,7 @@ static inline int mpeg1_decode_block_intra(MpegEncContext *s,
} else if(level != 0) { } else if(level != 0) {
i += run; i += run;
j = scantable[i]; j = scantable[i];
level= (level*qscale*quant_matrix[j])>>3; level= (level*qscale*quant_matrix[j])>>4;
level= (level-1)|1; level= (level-1)|1;
level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
LAST_SKIP_BITS(re, &s->gb, 1); LAST_SKIP_BITS(re, &s->gb, 1);
@@ -1449,11 +1435,11 @@ static inline int mpeg1_decode_block_intra(MpegEncContext *s,
j = scantable[i]; j = scantable[i];
if(level<0){ if(level<0){
level= -level; level= -level;
level= (level*qscale*quant_matrix[j])>>3; level= (level*qscale*quant_matrix[j])>>4;
level= (level-1)|1; level= (level-1)|1;
level= -level; level= -level;
}else{ }else{
level= (level*qscale*quant_matrix[j])>>3; level= (level*qscale*quant_matrix[j])>>4;
level= (level-1)|1; level= (level-1)|1;
} }
} }
@@ -1489,7 +1475,7 @@ static inline int mpeg1_decode_block_inter(MpegEncContext *s,
v= SHOW_UBITS(re, &s->gb, 2); v= SHOW_UBITS(re, &s->gb, 2);
if (v & 2) { if (v & 2) {
LAST_SKIP_BITS(re, &s->gb, 2); LAST_SKIP_BITS(re, &s->gb, 2);
level= (3*qscale*quant_matrix[0])>>4; level= (3*qscale*quant_matrix[0])>>5;
level= (level-1)|1; level= (level-1)|1;
if(v&1) if(v&1)
level= -level; level= -level;
@@ -1507,7 +1493,7 @@ static inline int mpeg1_decode_block_inter(MpegEncContext *s,
} else if(level != 0) { } else if(level != 0) {
i += run; i += run;
j = scantable[i]; j = scantable[i];
level= ((level*2+1)*qscale*quant_matrix[j])>>4; level= ((level*2+1)*qscale*quant_matrix[j])>>5;
level= (level-1)|1; level= (level-1)|1;
level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
LAST_SKIP_BITS(re, &s->gb, 1); LAST_SKIP_BITS(re, &s->gb, 1);
@@ -1525,11 +1511,11 @@ static inline int mpeg1_decode_block_inter(MpegEncContext *s,
j = scantable[i]; j = scantable[i];
if(level<0){ if(level<0){
level= -level; level= -level;
level= ((level*2+1)*qscale*quant_matrix[j])>>4; level= ((level*2+1)*qscale*quant_matrix[j])>>5;
level= (level-1)|1; level= (level-1)|1;
level= -level; level= -level;
}else{ }else{
level= ((level*2+1)*qscale*quant_matrix[j])>>4; level= ((level*2+1)*qscale*quant_matrix[j])>>5;
level= (level-1)|1; level= (level-1)|1;
} }
} }
@@ -1718,7 +1704,9 @@ static int mpeg_decode_init(AVCodecContext *avctx)
{ {
Mpeg1Context *s = avctx->priv_data; Mpeg1Context *s = avctx->priv_data;
s->mpeg_enc_ctx.avctx= avctx;
s->mpeg_enc_ctx.flags= avctx->flags; s->mpeg_enc_ctx.flags= avctx->flags;
s->mpeg_enc_ctx.flags2= avctx->flags2;
common_init(&s->mpeg_enc_ctx); common_init(&s->mpeg_enc_ctx);
init_vlcs(); init_vlcs();
@@ -1758,15 +1746,14 @@ static int mpeg1_decode_picture(AVCodecContext *avctx,
{ {
Mpeg1Context *s1 = avctx->priv_data; Mpeg1Context *s1 = avctx->priv_data;
MpegEncContext *s = &s1->mpeg_enc_ctx; MpegEncContext *s = &s1->mpeg_enc_ctx;
int ref, f_code; int ref, f_code, vbv_delay;
init_get_bits(&s->gb, buf, buf_size*8); init_get_bits(&s->gb, buf, buf_size*8);
ref = get_bits(&s->gb, 10); /* temporal ref */ ref = get_bits(&s->gb, 10); /* temporal ref */
s->pict_type = get_bits(&s->gb, 3); s->pict_type = get_bits(&s->gb, 3);
dprintf("pict_type=%d number=%d\n", s->pict_type, s->picture_number);
skip_bits(&s->gb, 16); vbv_delay= get_bits(&s->gb, 16);
if (s->pict_type == P_TYPE || s->pict_type == B_TYPE) { if (s->pict_type == P_TYPE || s->pict_type == B_TYPE) {
s->full_pel[0] = get_bits1(&s->gb); s->full_pel[0] = get_bits1(&s->gb);
f_code = get_bits(&s->gb, 3); f_code = get_bits(&s->gb, 3);
@@ -1786,6 +1773,9 @@ static int mpeg1_decode_picture(AVCodecContext *avctx,
s->current_picture.pict_type= s->pict_type; s->current_picture.pict_type= s->pict_type;
s->current_picture.key_frame= s->pict_type == I_TYPE; s->current_picture.key_frame= s->pict_type == I_TYPE;
// if(avctx->debug & FF_DEBUG_PICT_INFO)
// av_log(avctx, AV_LOG_DEBUG, "vbv_delay %d, ref %d\n", vbv_delay, ref);
s->y_dc_scale = 8; s->y_dc_scale = 8;
s->c_dc_scale = 8; s->c_dc_scale = 8;
s->first_slice = 1; s->first_slice = 1;
@@ -1795,7 +1785,7 @@ static int mpeg1_decode_picture(AVCodecContext *avctx,
static void mpeg_decode_sequence_extension(MpegEncContext *s) static void mpeg_decode_sequence_extension(MpegEncContext *s)
{ {
int horiz_size_ext, vert_size_ext; int horiz_size_ext, vert_size_ext;
int bit_rate_ext, vbv_buf_ext; int bit_rate_ext;
int frame_rate_ext_n, frame_rate_ext_d; int frame_rate_ext_n, frame_rate_ext_d;
int level, profile; int level, profile;
@@ -1811,7 +1801,7 @@ static void mpeg_decode_sequence_extension(MpegEncContext *s)
bit_rate_ext = get_bits(&s->gb, 12); /* XXX: handle it */ bit_rate_ext = get_bits(&s->gb, 12); /* XXX: handle it */
s->bit_rate = ((s->bit_rate / 400) | (bit_rate_ext << 12)) * 400; s->bit_rate = ((s->bit_rate / 400) | (bit_rate_ext << 12)) * 400;
skip_bits1(&s->gb); /* marker */ skip_bits1(&s->gb); /* marker */
vbv_buf_ext = get_bits(&s->gb, 8); s->avctx->rc_buffer_size += get_bits(&s->gb, 8)*1024*16<<10;
s->low_delay = get_bits1(&s->gb); s->low_delay = get_bits1(&s->gb);
if(s->flags & CODEC_FLAG_LOW_DELAY) s->low_delay=1; if(s->flags & CODEC_FLAG_LOW_DELAY) s->low_delay=1;
@@ -1840,7 +1830,8 @@ static void mpeg_decode_sequence_extension(MpegEncContext *s)
} }
if(s->avctx->debug & FF_DEBUG_PICT_INFO) if(s->avctx->debug & FF_DEBUG_PICT_INFO)
av_log(s->avctx, AV_LOG_DEBUG, "profile: %d, level: %d \n", profile, level); av_log(s->avctx, AV_LOG_DEBUG, "profile: %d, level: %d vbv buffer: %d, bitrate:%d\n",
profile, level, s->avctx->rc_buffer_size, s->bit_rate);
} }
static void mpeg_decode_sequence_display_extension(Mpeg1Context *s1) static void mpeg_decode_sequence_display_extension(Mpeg1Context *s1)
@@ -1950,7 +1941,7 @@ static void mpeg_decode_picture_coding_extension(MpegEncContext *s)
s->repeat_first_field = get_bits1(&s->gb); s->repeat_first_field = get_bits1(&s->gb);
s->chroma_420_type = get_bits1(&s->gb); s->chroma_420_type = get_bits1(&s->gb);
s->progressive_frame = get_bits1(&s->gb); s->progressive_frame = get_bits1(&s->gb);
if(s->picture_structure == PICT_FRAME) if(s->picture_structure == PICT_FRAME)
s->first_field=0; s->first_field=0;
else{ else{
@@ -1961,13 +1952,9 @@ static void mpeg_decode_picture_coding_extension(MpegEncContext *s)
if(s->alternate_scan){ if(s->alternate_scan){
ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_alternate_vertical_scan); ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_alternate_vertical_scan);
ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_alternate_vertical_scan); ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_alternate_vertical_scan);
ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_vertical_scan);
ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
}else{ }else{
ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_zigzag_direct); ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_zigzag_direct);
ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_zigzag_direct); ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_zigzag_direct);
ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan);
ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
} }
/* composite display not parsed */ /* composite display not parsed */
@@ -2101,10 +2088,10 @@ static int mpeg_decode_slice(AVCodecContext *avctx,
s->qscale = get_qscale(s); s->qscale = get_qscale(s);
if (s->first_slice && (s->first_field || s->picture_structure==PICT_FRAME)) { if (s->first_slice && (s->first_field || s->picture_structure==PICT_FRAME)) {
if(s->avctx->debug&FF_DEBUG_PICT_INFO){ if(s->avctx->debug&FF_DEBUG_PICT_INFO){
av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%2d%2d%2d%2d %s %s %s %s dc:%d pstruct:%d fdct:%d cmv:%d qtype:%d ivlc:%d rff:%d %s\n", av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%2d%2d%2d%2d %s %s %s %s %s dc:%d pstruct:%d fdct:%d cmv:%d qtype:%d ivlc:%d rff:%d %s\n",
s->qscale, s->mpeg_f_code[0][0],s->mpeg_f_code[0][1],s->mpeg_f_code[1][0],s->mpeg_f_code[1][1], s->qscale, s->mpeg_f_code[0][0],s->mpeg_f_code[0][1],s->mpeg_f_code[1][0],s->mpeg_f_code[1][1],
s->pict_type == I_TYPE ? "I" : (s->pict_type == P_TYPE ? "P" : (s->pict_type == B_TYPE ? "B" : "S")), s->pict_type == I_TYPE ? "I" : (s->pict_type == P_TYPE ? "P" : (s->pict_type == B_TYPE ? "B" : "S")),
s->progressive_sequence ? "pro" :"", s->alternate_scan ? "alt" :"", s->top_field_first ? "top" :"", s->progressive_sequence ? "ps" :"", s->progressive_frame ? "pf" : "", s->alternate_scan ? "alt" :"", s->top_field_first ? "top" :"",
s->intra_dc_precision, s->picture_structure, s->frame_pred_frame_dct, s->concealment_motion_vectors, s->intra_dc_precision, s->picture_structure, s->frame_pred_frame_dct, s->concealment_motion_vectors,
s->q_scale_type, s->intra_vlc_format, s->repeat_first_field, s->chroma_420_type ? "420" :""); s->q_scale_type, s->intra_vlc_format, s->repeat_first_field, s->chroma_420_type ? "420" :"");
} }
@@ -2292,10 +2279,7 @@ static int slice_end(AVCodecContext *avctx, AVFrame *pict)
if (/*s->mb_y<<field_pic == s->mb_height &&*/ !s->first_field) { if (/*s->mb_y<<field_pic == s->mb_height &&*/ !s->first_field) {
/* end of image */ /* end of image */
if(s->codec_id == CODEC_ID_MPEG2VIDEO){ s->current_picture_ptr->qscale_type= FF_QSCALE_TYPE_MPEG2;
s->current_picture_ptr->qscale_type= FF_QSCALE_TYPE_MPEG2;
}else
s->current_picture_ptr->qscale_type= FF_QSCALE_TYPE_MPEG1;
ff_er_frame_end(s); ff_er_frame_end(s);
@@ -2303,14 +2287,14 @@ static int slice_end(AVCodecContext *avctx, AVFrame *pict)
if (s->pict_type == B_TYPE || s->low_delay) { if (s->pict_type == B_TYPE || s->low_delay) {
*pict= *(AVFrame*)s->current_picture_ptr; *pict= *(AVFrame*)s->current_picture_ptr;
ff_print_debug_info(s, s->current_picture_ptr); ff_print_debug_info(s, pict);
} else { } else {
s->picture_number++; s->picture_number++;
/* latency of 1 frame for I and P frames */ /* latency of 1 frame for I and P frames */
/* XXX: use another variable than picture_number */ /* XXX: use another variable than picture_number */
if (s->last_picture_ptr != NULL) { if (s->last_picture_ptr != NULL) {
*pict= *(AVFrame*)s->last_picture_ptr; *pict= *(AVFrame*)s->last_picture_ptr;
ff_print_debug_info(s, s->last_picture_ptr); ff_print_debug_info(s, pict);
} }
} }
@@ -2357,7 +2341,6 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx,
s->width = width; s->width = width;
s->height = height; s->height = height;
avctx->has_b_frames= 1; avctx->has_b_frames= 1;
s->avctx = avctx;
avctx->width = width; avctx->width = width;
avctx->height = height; avctx->height = height;
av_reduce( av_reduce(
@@ -2381,7 +2364,7 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx,
s->swap_uv = 0;//just in case vcr2 and mpeg2 stream have been concatinated s->swap_uv = 0;//just in case vcr2 and mpeg2 stream have been concatinated
} }
skip_bits(&s->gb, 10); /* vbv_buffer_size */ s->avctx->rc_buffer_size= get_bits(&s->gb, 10) * 1024*16;
skip_bits(&s->gb, 1); skip_bits(&s->gb, 1);
/* get matrix */ /* get matrix */
@@ -2436,6 +2419,11 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx,
s->codec_id= s->avctx->codec_id= CODEC_ID_MPEG1VIDEO; s->codec_id= s->avctx->codec_id= CODEC_ID_MPEG1VIDEO;
avctx->sub_id = 1; /* indicates mpeg1 */ avctx->sub_id = 1; /* indicates mpeg1 */
if(s->flags & CODEC_FLAG_LOW_DELAY) s->low_delay=1; if(s->flags & CODEC_FLAG_LOW_DELAY) s->low_delay=1;
if(s->avctx->debug & FF_DEBUG_PICT_INFO)
av_log(s->avctx, AV_LOG_DEBUG, "vbv buffer: %d, bitrate:%d\n",
s->avctx->rc_buffer_size, s->bit_rate);
return 0; return 0;
} }
@@ -2454,7 +2442,6 @@ static int vcr2_init_sequence(AVCodecContext *avctx)
s->height = avctx->height; s->height = avctx->height;
avctx->has_b_frames= 0; //true? avctx->has_b_frames= 0; //true?
s->low_delay= 1; s->low_delay= 1;
s->avctx = avctx;
//get_format() or set_video(width,height,aspect,pix_fmt); //get_format() or set_video(width,height,aspect,pix_fmt);
//until then pix_fmt may be changed right after codec init //until then pix_fmt may be changed right after codec init
@@ -2726,6 +2713,32 @@ AVCodec mpegvideo_decoder = {
.flush= ff_mpeg_flush, .flush= ff_mpeg_flush,
}; };
#ifdef CONFIG_ENCODERS
AVCodec mpeg1video_encoder = {
"mpeg1video",
CODEC_TYPE_VIDEO,
CODEC_ID_MPEG1VIDEO,
sizeof(MpegEncContext),
encode_init,
MPV_encode_picture,
MPV_encode_end,
};
#ifdef CONFIG_RISKY
AVCodec mpeg2video_encoder = {
"mpeg2video",
CODEC_TYPE_VIDEO,
CODEC_ID_MPEG2VIDEO,
sizeof(MpegEncContext),
encode_init,
MPV_encode_picture,
MPV_encode_end,
};
#endif
#endif
#ifdef HAVE_XVMC #ifdef HAVE_XVMC
static int mpeg_mc_decode_init(AVCodecContext *avctx){ static int mpeg_mc_decode_init(AVCodecContext *avctx){
Mpeg1Context *s; Mpeg1Context *s;
@@ -433,3 +433,10 @@ static const AVRational mpeg2_aspect[16]={
{0,1}, {0,1},
}; };
static const uint8_t svcd_scan_offset_placeholder[14]={
0x10, 0x0E,
0x00, 0x80, 0x81,
0x00, 0x80, 0x81,
0xff, 0xff, 0xff,
0xff, 0xff, 0xff,
};
@@ -25,6 +25,7 @@
//#define DEBUG //#define DEBUG
#include "avcodec.h" #include "avcodec.h"
#include "mpegaudio.h" #include "mpegaudio.h"
#include "dsputil.h"
/* /*
* TODO: * TODO:
@@ -66,6 +67,8 @@ typedef int32_t MPA_INT;
#define HEADER_SIZE 4 #define HEADER_SIZE 4
#define BACKSTEP_SIZE 512 #define BACKSTEP_SIZE 512
struct GranuleDef;
typedef struct MPADecodeContext { typedef struct MPADecodeContext {
uint8_t inbuf1[2][MPA_MAX_CODED_FRAME_SIZE + BACKSTEP_SIZE]; /* input buffer */ uint8_t inbuf1[2][MPA_MAX_CODED_FRAME_SIZE + BACKSTEP_SIZE]; /* input buffer */
int inbuf_index; int inbuf_index;
@@ -93,6 +96,7 @@ typedef struct MPADecodeContext {
#ifdef DEBUG #ifdef DEBUG
int frame_count; int frame_count;
#endif #endif
void (*compute_antialias)(struct MPADecodeContext *s, struct GranuleDef *g);
} MPADecodeContext; } MPADecodeContext;
/* layer 3 "granule" */ /* layer 3 "granule" */
@@ -127,6 +131,9 @@ typedef struct HuffTable {
#include "mpegaudiodectab.h" #include "mpegaudiodectab.h"
static void compute_antialias_integer(MPADecodeContext *s, GranuleDef *g);
static void compute_antialias_float(MPADecodeContext *s, GranuleDef *g);
/* vlc structure for decoding layer 3 huffman tables */ /* vlc structure for decoding layer 3 huffman tables */
static VLC huff_vlc[16]; static VLC huff_vlc[16];
static uint8_t *huff_code_table[16]; static uint8_t *huff_code_table[16];
@@ -144,7 +151,8 @@ static uint32_t *table_4_3_value;
/* intensity stereo coef table */ /* intensity stereo coef table */
static int32_t is_table[2][16]; static int32_t is_table[2][16];
static int32_t is_table_lsf[2][2][16]; static int32_t is_table_lsf[2][2][16];
static int32_t csa_table[8][2]; static int32_t csa_table[8][4];
static float csa_table_float[8][4];
static int32_t mdct_win[8][36]; static int32_t mdct_win[8][36];
/* lower 2 bits: modulo 3, higher bits: shift */ /* lower 2 bits: modulo 3, higher bits: shift */
@@ -310,6 +318,11 @@ static int decode_init(AVCodecContext * avctx)
static int init=0; static int init=0;
int i, j, k; int i, j, k;
if(avctx->antialias_algo == FF_AA_INT)
s->compute_antialias= compute_antialias_integer;
else
s->compute_antialias= compute_antialias_float;
if (!init && !avctx->parse_only) { if (!init && !avctx->parse_only) {
/* scale factors table for layer 1/2 */ /* scale factors table for layer 1/2 */
for(i=0;i<64;i++) { for(i=0;i<64;i++) {
@@ -462,6 +475,13 @@ static int decode_init(AVCodecContext * avctx)
ca = cs * ci; ca = cs * ci;
csa_table[i][0] = FIX(cs); csa_table[i][0] = FIX(cs);
csa_table[i][1] = FIX(ca); csa_table[i][1] = FIX(ca);
csa_table[i][2] = FIX(ca) + FIX(cs);
csa_table[i][3] = FIX(ca) - FIX(cs);
csa_table_float[i][0] = cs;
csa_table_float[i][1] = ca;
csa_table_float[i][2] = ca + cs;
csa_table_float[i][3] = ca - cs;
// printf("%d %d %d %d\n", FIX(cs), FIX(cs-1), FIX(ca), FIX(cs)-FIX(ca));
} }
/* compute mdct windows */ /* compute mdct windows */
@@ -1892,11 +1912,11 @@ static void compute_stereo(MPADecodeContext *s,
} }
} }
static void compute_antialias(MPADecodeContext *s, static void compute_antialias_integer(MPADecodeContext *s,
GranuleDef *g) GranuleDef *g)
{ {
int32_t *ptr, *p0, *p1, *csa; int32_t *ptr, *p0, *p1, *csa;
int n, tmp0, tmp1, i, j; int n, i, j;
/* we antialias only "long" bands */ /* we antialias only "long" bands */
if (g->block_type == 2) { if (g->block_type == 2) {
@@ -1912,17 +1932,85 @@ static void compute_antialias(MPADecodeContext *s,
for(i = n;i > 0;i--) { for(i = n;i > 0;i--) {
p0 = ptr - 1; p0 = ptr - 1;
p1 = ptr; p1 = ptr;
csa = &csa_table[0][0]; csa = &csa_table[0][0];
for(j=0;j<8;j++) { for(j=0;j<4;j++) {
tmp0 = *p0; int tmp0 = *p0;
tmp1 = *p1; int tmp1 = *p1;
#if 0
*p0 = FRAC_RND(MUL64(tmp0, csa[0]) - MUL64(tmp1, csa[1])); *p0 = FRAC_RND(MUL64(tmp0, csa[0]) - MUL64(tmp1, csa[1]));
*p1 = FRAC_RND(MUL64(tmp0, csa[1]) + MUL64(tmp1, csa[0])); *p1 = FRAC_RND(MUL64(tmp0, csa[1]) + MUL64(tmp1, csa[0]));
p0--; #else
p1++; int64_t tmp2= MUL64(tmp0 + tmp1, csa[0]);
csa += 2; *p0 = FRAC_RND(tmp2 - MUL64(tmp1, csa[2]));
*p1 = FRAC_RND(tmp2 + MUL64(tmp0, csa[3]));
#endif
p0--; p1++;
csa += 4;
tmp0 = *p0;
tmp1 = *p1;
#if 0
*p0 = FRAC_RND(MUL64(tmp0, csa[0]) - MUL64(tmp1, csa[1]));
*p1 = FRAC_RND(MUL64(tmp0, csa[1]) + MUL64(tmp1, csa[0]));
#else
tmp2= MUL64(tmp0 + tmp1, csa[0]);
*p0 = FRAC_RND(tmp2 - MUL64(tmp1, csa[2]));
*p1 = FRAC_RND(tmp2 + MUL64(tmp0, csa[3]));
#endif
p0--; p1++;
csa += 4;
} }
ptr += 18; ptr += 18;
}
}
static void compute_antialias_float(MPADecodeContext *s,
GranuleDef *g)
{
int32_t *ptr, *p0, *p1;
int n, i, j;
/* we antialias only "long" bands */
if (g->block_type == 2) {
if (!g->switch_point)
return;
/* XXX: check this for 8000Hz case */
n = 1;
} else {
n = SBLIMIT - 1;
}
ptr = g->sb_hybrid + 18;
for(i = n;i > 0;i--) {
float *csa = &csa_table_float[0][0];
p0 = ptr - 1;
p1 = ptr;
for(j=0;j<4;j++) {
float tmp0 = *p0;
float tmp1 = *p1;
#if 1
*p0 = lrintf(tmp0 * csa[0] - tmp1 * csa[1]);
*p1 = lrintf(tmp0 * csa[1] + tmp1 * csa[0]);
#else
float tmp2= (tmp0 + tmp1) * csa[0];
*p0 = lrintf(tmp2 - tmp1 * csa[2]);
*p1 = lrintf(tmp2 + tmp0 * csa[3]);
#endif
p0--; p1++;
csa += 4;
tmp0 = *p0;
tmp1 = *p1;
#if 1
*p0 = lrintf(tmp0 * csa[0] - tmp1 * csa[1]);
*p1 = lrintf(tmp0 * csa[1] + tmp1 * csa[0]);
#else
tmp2= (tmp0 + tmp1) * csa[0];
*p0 = lrintf(tmp2 - tmp1 * csa[2]);
*p1 = lrintf(tmp2 + tmp0 * csa[3]);
#endif
p0--; p1++;
csa += 4;
}
ptr += 18;
} }
} }
@@ -2352,7 +2440,7 @@ static int mp_decode_layer3(MPADecodeContext *s)
#if defined(DEBUG) #if defined(DEBUG)
sample_dump(0, g->sb_hybrid, 576); sample_dump(0, g->sb_hybrid, 576);
#endif #endif
compute_antialias(s, g); s->compute_antialias(s, g);
#if defined(DEBUG) #if defined(DEBUG)
sample_dump(1, g->sb_hybrid, 576); sample_dump(1, g->sb_hybrid, 576);
#endif #endif
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,7 @@
/* /*
* Generic DCT based hybrid video encoder * Generic DCT based hybrid video encoder
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard. * Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
* Copyright (c) 2002-2004 Michael Niedermayer
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -137,6 +138,7 @@ typedef struct Picture{
int16_t (*motion_val_base[2])[2]; int16_t (*motion_val_base[2])[2];
int8_t *ref_index[2]; int8_t *ref_index[2];
uint32_t *mb_type_base; uint32_t *mb_type_base;
#define MB_TYPE_INTRA MB_TYPE_INTRA4x4 //default mb_type if theres just one type
#define IS_INTRA4x4(a) ((a)&MB_TYPE_INTRA4x4) #define IS_INTRA4x4(a) ((a)&MB_TYPE_INTRA4x4)
#define IS_INTRA16x16(a) ((a)&MB_TYPE_INTRA16x16) #define IS_INTRA16x16(a) ((a)&MB_TYPE_INTRA16x16)
#define IS_PCM(a) ((a)&MB_TYPE_INTRA_PCM) #define IS_PCM(a) ((a)&MB_TYPE_INTRA_PCM)
@@ -206,23 +208,28 @@ typedef struct MotionEstContext{
int mb_penalty_factor; int mb_penalty_factor;
int pre_pass; ///< = 1 for the pre pass int pre_pass; ///< = 1 for the pre pass
int dia_size; int dia_size;
int xmin;
int xmax;
int ymin;
int ymax;
uint8_t (*mv_penalty)[MAX_MV*2+1]; ///< amount of bits needed to encode a MV uint8_t (*mv_penalty)[MAX_MV*2+1]; ///< amount of bits needed to encode a MV
int (*sub_motion_search)(struct MpegEncContext * s, int (*sub_motion_search)(struct MpegEncContext * s,
int *mx_ptr, int *my_ptr, int dmin, int *mx_ptr, int *my_ptr, int dmin,
int xmin, int ymin, int xmax, int ymax, int pred_x, int pred_y, uint8_t *src_data[3],
int pred_x, int pred_y, Picture *ref_picture, uint8_t *ref_data[6], int stride, int uvstride,
int n, int size, uint8_t * const mv_penalty); int size, int h, uint8_t * const mv_penalty);
int (*motion_search[7])(struct MpegEncContext * s, int block, int (*motion_search[7])(struct MpegEncContext * s,
int *mx_ptr, int *my_ptr, int *mx_ptr, int *my_ptr,
int P[10][2], int pred_x, int pred_y, int P[10][2], int pred_x, int pred_y, uint8_t *src_data[3],
int xmin, int ymin, int xmax, int ymax, Picture *ref_picture, int16_t (*last_mv)[2], uint8_t *ref_data[6], int stride, int uvstride, int16_t (*last_mv)[2],
int ref_mv_scale, uint8_t * const mv_penalty); int ref_mv_scale, uint8_t * const mv_penalty);
int (*pre_motion_search)(struct MpegEncContext * s, int block, int (*pre_motion_search)(struct MpegEncContext * s,
int *mx_ptr, int *my_ptr, int *mx_ptr, int *my_ptr,
int P[10][2], int pred_x, int pred_y, int P[10][2], int pred_x, int pred_y, uint8_t *src_data[3],
int xmin, int ymin, int xmax, int ymax, Picture *ref_picture, int16_t (*last_mv)[2], uint8_t *ref_data[6], int stride, int uvstride, int16_t (*last_mv)[2],
int ref_mv_scale, uint8_t * const mv_penalty); int ref_mv_scale, uint8_t * const mv_penalty);
int (*get_mb_score)(struct MpegEncContext * s, int mx, int my, int pred_x, int pred_y, Picture *ref_picture, int (*get_mb_score)(struct MpegEncContext * s, int mx, int my, int pred_x, int pred_y, uint8_t *src_data[3],
uint8_t *ref_data[6], int stride, int uvstride,
uint8_t * const mv_penalty); uint8_t * const mv_penalty);
}MotionEstContext; }MotionEstContext;
@@ -248,6 +255,7 @@ typedef struct MpegEncContext {
int fixed_qscale; ///< fixed qscale if non zero int fixed_qscale; ///< fixed qscale if non zero
int encoding; ///< true if we are encoding (vs decoding) int encoding; ///< true if we are encoding (vs decoding)
int flags; ///< AVCodecContext.flags (HQ, MV4, ...) int flags; ///< AVCodecContext.flags (HQ, MV4, ...)
int flags2; ///< AVCodecContext.flags2
int max_b_frames; ///< max number of b-frames for encoding int max_b_frames; ///< max number of b-frames for encoding
int luma_elim_threshold; int luma_elim_threshold;
int chroma_elim_threshold; int chroma_elim_threshold;
@@ -260,8 +268,9 @@ typedef struct MpegEncContext {
/* sequence parameters */ /* sequence parameters */
int context_initialized; int context_initialized;
int input_picture_number; int input_picture_number; ///< used to set pic->display_picture_number, shouldnt be used for/by anything else
int picture_number; int coded_picture_number; ///< used to set pic->coded_picture_number, shouldnt be used for/by anything else
int picture_number; //FIXME remove, unclear definition
int picture_in_gop_number; ///< 0-> first pic in gop, ... int picture_in_gop_number; ///< 0-> first pic in gop, ...
int b_frames_since_non_b; ///< used for encoding, relative to not yet reordered input int b_frames_since_non_b; ///< used for encoding, relative to not yet reordered input
int mb_width, mb_height; ///< number of MBs horizontally & vertically int mb_width, mb_height; ///< number of MBs horizontally & vertically
@@ -303,6 +312,7 @@ typedef struct MpegEncContext {
Picture *last_picture_ptr; ///< pointer to the previous picture. Picture *last_picture_ptr; ///< pointer to the previous picture.
Picture *next_picture_ptr; ///< pointer to the next picture (for bidir pred) Picture *next_picture_ptr; ///< pointer to the next picture (for bidir pred)
Picture *current_picture_ptr; ///< pointer to the current picture Picture *current_picture_ptr; ///< pointer to the current picture
uint8_t *visualization_buffer[3]; //< temporary buffer vor MV visualization
int last_dc[3]; ///< last DC values for MPEG1 int last_dc[3]; ///< last DC values for MPEG1
int16_t *dc_val[3]; ///< used for mpeg4 DC prediction, all 3 arrays must be continuous int16_t *dc_val[3]; ///< used for mpeg4 DC prediction, all 3 arrays must be continuous
int16_t dc_cache[4*5]; int16_t dc_cache[4*5];
@@ -349,12 +359,18 @@ typedef struct MpegEncContext {
int16_t (*b_bidir_forw_mv_table_base)[2]; int16_t (*b_bidir_forw_mv_table_base)[2];
int16_t (*b_bidir_back_mv_table_base)[2]; int16_t (*b_bidir_back_mv_table_base)[2];
int16_t (*b_direct_mv_table_base)[2]; int16_t (*b_direct_mv_table_base)[2];
int16_t (*p_field_mv_table_base[2][2])[2];
int16_t (*b_field_mv_table_base[2][2][2])[2];
int16_t (*p_mv_table)[2]; ///< MV table (1MV per MB) p-frame encoding int16_t (*p_mv_table)[2]; ///< MV table (1MV per MB) p-frame encoding
int16_t (*b_forw_mv_table)[2]; ///< MV table (1MV per MB) forward mode b-frame encoding int16_t (*b_forw_mv_table)[2]; ///< MV table (1MV per MB) forward mode b-frame encoding
int16_t (*b_back_mv_table)[2]; ///< MV table (1MV per MB) backward mode b-frame encoding int16_t (*b_back_mv_table)[2]; ///< MV table (1MV per MB) backward mode b-frame encoding
int16_t (*b_bidir_forw_mv_table)[2]; ///< MV table (1MV per MB) bidir mode b-frame encoding int16_t (*b_bidir_forw_mv_table)[2]; ///< MV table (1MV per MB) bidir mode b-frame encoding
int16_t (*b_bidir_back_mv_table)[2]; ///< MV table (1MV per MB) bidir mode b-frame encoding int16_t (*b_bidir_back_mv_table)[2]; ///< MV table (1MV per MB) bidir mode b-frame encoding
int16_t (*b_direct_mv_table)[2]; ///< MV table (1MV per MB) direct mode b-frame encoding int16_t (*b_direct_mv_table)[2]; ///< MV table (1MV per MB) direct mode b-frame encoding
int16_t (*p_field_mv_table[2][2])[2]; ///< MV table (2MV per MB) interlaced p-frame encoding
int16_t (*b_field_mv_table[2][2][2])[2];///< MV table (4MV per MB) interlaced b-frame encoding
uint8_t (*p_field_select_table[2]);
uint8_t (*b_field_select_table[2][2]);
int me_method; ///< ME algorithm int me_method; ///< ME algorithm
int scene_change_score; int scene_change_score;
int mv_dir; int mv_dir;
@@ -389,17 +405,22 @@ typedef struct MpegEncContext {
int mb_x, mb_y; int mb_x, mb_y;
int mb_skip_run; int mb_skip_run;
int mb_intra; int mb_intra;
uint8_t *mb_type; ///< Table for MB type FIXME remove and use picture->mb_type uint16_t *mb_type; ///< Table for candidate MB types for encoding
#define MB_TYPE_INTRA 0x01 #define CANDIDATE_MB_TYPE_INTRA 0x01
#define MB_TYPE_INTER 0x02 #define CANDIDATE_MB_TYPE_INTER 0x02
#define MB_TYPE_INTER4V 0x04 #define CANDIDATE_MB_TYPE_INTER4V 0x04
#define MB_TYPE_SKIPED 0x08 #define CANDIDATE_MB_TYPE_SKIPED 0x08
//#define MB_TYPE_GMC 0x10 //#define MB_TYPE_GMC 0x10
#define MB_TYPE_DIRECT 0x10 #define CANDIDATE_MB_TYPE_DIRECT 0x10
#define MB_TYPE_FORWARD 0x20 #define CANDIDATE_MB_TYPE_FORWARD 0x20
#define MB_TYPE_BACKWARD 0x40 #define CANDIDATE_MB_TYPE_BACKWARD 0x40
#define MB_TYPE_BIDIR 0x80 #define CANDIDATE_MB_TYPE_BIDIR 0x80
#define CANDIDATE_MB_TYPE_INTER_I 0x100
#define CANDIDATE_MB_TYPE_FORWARD_I 0x200
#define CANDIDATE_MB_TYPE_BACKWARD_I 0x400
#define CANDIDATE_MB_TYPE_BIDIR_I 0x800
int block_index[6]; ///< index to current MB in block based arrays with edges int block_index[6]; ///< index to current MB in block based arrays with edges
int block_wrap[6]; int block_wrap[6];
@@ -449,7 +470,6 @@ typedef struct MpegEncContext {
void *opaque; ///< private data for the user void *opaque; ///< private data for the user
/* bit rate control */ /* bit rate control */
int I_frame_bits; //FIXME used in mpeg12 ...
int64_t wanted_bits; int64_t wanted_bits;
int64_t total_bits; int64_t total_bits;
int frame_bits; ///< bits used for the current frame int frame_bits; ///< bits used for the current frame
@@ -549,8 +569,6 @@ typedef struct MpegEncContext {
uint8_t *tex_pb_buffer; uint8_t *tex_pb_buffer;
uint8_t *pb2_buffer; uint8_t *pb2_buffer;
int mpeg_quant; int mpeg_quant;
int16_t (*field_mv_table)[2][2]; ///< used for interlaced b frame decoding
int8_t (*field_select_table)[2]; ///< wtf, no really another table for interlaced b frames
int t_frame; ///< time distance of first I -> B, used for interlaced b frames int t_frame; ///< time distance of first I -> B, used for interlaced b frames
int padding_bug_score; ///< used to detect the VERY common padding bug in MPEG4 int padding_bug_score; ///< used to detect the VERY common padding bug in MPEG4
@@ -601,10 +619,10 @@ typedef struct MpegEncContext {
GetBitContext gb; GetBitContext gb;
/* Mpeg1 specific */ /* Mpeg1 specific */
int fake_picture_number; ///< picture number at the bitstream frame rate
int gop_picture_number; ///< index of the first picture of a GOP based on fake_pic_num & mpeg1 specific int gop_picture_number; ///< index of the first picture of a GOP based on fake_pic_num & mpeg1 specific
int last_mv_dir; ///< last mv_dir, used for b frame encoding int last_mv_dir; ///< last mv_dir, used for b frame encoding
int broken_link; ///< no_output_of_prior_pics_flag int broken_link; ///< no_output_of_prior_pics_flag
uint8_t *vbv_delay_ptr; ///< pointer to vbv_delay in the bitstream
/* MPEG2 specific - I wish I had not to support this mess. */ /* MPEG2 specific - I wish I had not to support this mess. */
int progressive_sequence; int progressive_sequence;
@@ -663,6 +681,7 @@ typedef struct MpegEncContext {
DCTELEM *block/*align 16*/, int n, int qscale); DCTELEM *block/*align 16*/, int n, int qscale);
int (*dct_quantize)(struct MpegEncContext *s, DCTELEM *block/*align 16*/, int n, int qscale, int *overflow); int (*dct_quantize)(struct MpegEncContext *s, DCTELEM *block/*align 16*/, int n, int qscale, int *overflow);
int (*fast_dct_quantize)(struct MpegEncContext *s, DCTELEM *block/*align 16*/, int n, int qscale, int *overflow); int (*fast_dct_quantize)(struct MpegEncContext *s, DCTELEM *block/*align 16*/, int n, int qscale, int *overflow);
void (*denoise_dct)(struct MpegEncContext *s, DCTELEM *block);
} MpegEncContext; } MpegEncContext;
@@ -703,7 +722,7 @@ void ff_emulated_edge_mc(uint8_t *buf, uint8_t *src, int linesize, int block_w,
#define END_NOT_FOUND -100 #define END_NOT_FOUND -100
int ff_combine_frame( MpegEncContext *s, int next, uint8_t **buf, int *buf_size); int ff_combine_frame( MpegEncContext *s, int next, uint8_t **buf, int *buf_size);
void ff_mpeg_flush(AVCodecContext *avctx); void ff_mpeg_flush(AVCodecContext *avctx);
void ff_print_debug_info(MpegEncContext *s, Picture *pict); void ff_print_debug_info(MpegEncContext *s, AVFrame *pict);
void ff_write_quant_matrix(PutBitContext *pb, int16_t *matrix); void ff_write_quant_matrix(PutBitContext *pb, int16_t *matrix);
int ff_find_unused_picture(MpegEncContext *s, int shared); int ff_find_unused_picture(MpegEncContext *s, int shared);
void ff_denoise_dct(MpegEncContext *s, DCTELEM *block); void ff_denoise_dct(MpegEncContext *s, DCTELEM *block);
@@ -745,7 +764,8 @@ void ff_estimate_b_frame_motion(MpegEncContext * s,
int mb_x, int mb_y); int mb_x, int mb_y);
int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type); int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type);
void ff_fix_long_p_mvs(MpegEncContext * s); void ff_fix_long_p_mvs(MpegEncContext * s);
void ff_fix_long_b_mvs(MpegEncContext * s, int16_t (*mv_table)[2], int f_code, int type); void ff_fix_long_mvs(MpegEncContext * s, uint8_t *field_select_table, int field_select,
int16_t (*mv_table)[2], int f_code, int type, int truncate);
void ff_init_me(MpegEncContext *s); void ff_init_me(MpegEncContext *s);
int ff_pre_estimate_p_frame_motion(MpegEncContext * s, int mb_x, int mb_y); int ff_pre_estimate_p_frame_motion(MpegEncContext * s, int mb_x, int mb_y);
@@ -1,6 +1,7 @@
/* /*
* MSMPEG4 backend for ffmpeg encoder and decoder * MSMPEG4 backend for ffmpeg encoder and decoder
* Copyright (c) 2001 Fabrice Bellard. * Copyright (c) 2001 Fabrice Bellard.
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -730,6 +731,27 @@ static inline int msmpeg4_pred_dc(MpegEncContext * s, int n,
necessitate to modify mpegvideo.c. The problem comes from the necessitate to modify mpegvideo.c. The problem comes from the
fact they decided to store the quantized DC (which would lead fact they decided to store the quantized DC (which would lead
to problems if Q could vary !) */ to problems if Q could vary !) */
#if defined ARCH_X86 && !defined PIC
asm volatile(
"movl %3, %%eax \n\t"
"shrl $1, %%eax \n\t"
"addl %%eax, %2 \n\t"
"addl %%eax, %1 \n\t"
"addl %0, %%eax \n\t"
"mull %4 \n\t"
"movl %%edx, %0 \n\t"
"movl %1, %%eax \n\t"
"mull %4 \n\t"
"movl %%edx, %1 \n\t"
"movl %2, %%eax \n\t"
"mull %4 \n\t"
"movl %%edx, %2 \n\t"
: "+b" (a), "+c" (b), "+D" (c)
: "g" (scale), "S" (inverse[scale])
: "%eax", "%edx"
);
#else
/* #elif defined (ARCH_ALPHA) */
/* Divisions are extremely costly on Alpha; optimize the most /* Divisions are extremely costly on Alpha; optimize the most
common case. But they are costly everywhere... common case. But they are costly everywhere...
*/ */
@@ -742,6 +764,7 @@ static inline int msmpeg4_pred_dc(MpegEncContext * s, int n,
b = FASTDIV((b + (scale >> 1)), scale); b = FASTDIV((b + (scale >> 1)), scale);
c = FASTDIV((c + (scale >> 1)), scale); c = FASTDIV((c + (scale >> 1)), scale);
} }
#endif
/* XXX: WARNING: they did not choose the same test as MPEG4. This /* XXX: WARNING: they did not choose the same test as MPEG4. This
is very important ! */ is very important ! */
if(s->msmpeg4_version>3){ if(s->msmpeg4_version>3){
@@ -110,8 +110,8 @@ static void msrle_decode_pal4(MsrleContext *s)
FETCH_NEXT_STREAM_BYTE(); FETCH_NEXT_STREAM_BYTE();
s->frame.data[0][row_ptr + pixel_ptr] = stream_byte >> 4; s->frame.data[0][row_ptr + pixel_ptr] = stream_byte >> 4;
pixel_ptr++; pixel_ptr++;
if (i + 1 == rle_code && odd_pixel) if (i + 1 == rle_code && odd_pixel)
break; break;
if (pixel_ptr >= s->avctx->width) if (pixel_ptr >= s->avctx->width)
break; break;
s->frame.data[0][row_ptr + pixel_ptr] = stream_byte & 0x0F; s->frame.data[0][row_ptr + pixel_ptr] = stream_byte & 0x0F;
@@ -254,9 +254,9 @@ static int msrle_decode_frame(AVCodecContext *avctx,
{ {
MsrleContext *s = (MsrleContext *)avctx->priv_data; MsrleContext *s = (MsrleContext *)avctx->priv_data;
/* no supplementary picture */ /* no supplementary picture */
if (buf_size == 0) if (buf_size == 0)
return 0; return 0;
s->buf = buf; s->buf = buf;
s->size = buf_size; s->size = buf_size;
@@ -303,15 +303,15 @@ static int msvideo1_decode_frame(AVCodecContext *avctx,
{ {
Msvideo1Context *s = (Msvideo1Context *)avctx->priv_data; Msvideo1Context *s = (Msvideo1Context *)avctx->priv_data;
/* no supplementary picture */ /* no supplementary picture */
if (buf_size == 0) if (buf_size == 0)
return 0; return 0;
s->buf = buf; s->buf = buf;
s->size = buf_size; s->size = buf_size;
s->frame.reference = 1; s->frame.reference = 1;
s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
if (avctx->reget_buffer(avctx, &s->frame)) { if (avctx->reget_buffer(avctx, &s->frame)) {
av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
return -1; return -1;
@@ -1,7 +1,7 @@
/* /*
* Rate control for video encoders * Rate control for video encoders
* *
* Copyright (c) 2002-2003 Michael Niedermayer <michaelni@gmx.at> * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -39,7 +39,7 @@ static double get_qscale(MpegEncContext *s, RateControlEntry *rce, double rate_f
void ff_write_pass1_stats(MpegEncContext *s){ void ff_write_pass1_stats(MpegEncContext *s){
sprintf(s->avctx->stats_out, "in:%d out:%d type:%d q:%d itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d;\n", sprintf(s->avctx->stats_out, "in:%d out:%d type:%d q:%d itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d;\n",
s->picture_number, s->input_picture_number - s->max_b_frames, s->pict_type, s->current_picture_ptr->display_picture_number, s->current_picture_ptr->coded_picture_number, s->pict_type,
s->current_picture.quality, s->i_tex_bits, s->p_tex_bits, s->mv_bits, s->misc_bits, s->current_picture.quality, s->i_tex_bits, s->p_tex_bits, s->mv_bits, s->misc_bits,
s->f_code, s->b_code, s->current_picture.mc_mb_var_sum, s->current_picture.mb_var_sum, s->i_count); s->f_code, s->b_code, s->current_picture.mc_mb_var_sum, s->current_picture.mb_var_sum, s->i_count);
} }
@@ -198,11 +198,11 @@ static inline double bits2qp(RateControlEntry *rce, double bits){
int ff_vbv_update(MpegEncContext *s, int frame_size){ int ff_vbv_update(MpegEncContext *s, int frame_size){
RateControlContext *rcc= &s->rc_context; RateControlContext *rcc= &s->rc_context;
const double fps= (double)s->avctx->frame_rate / (double)s->avctx->frame_rate_base; const double fps= (double)s->avctx->frame_rate / (double)s->avctx->frame_rate_base;
const double buffer_size= s->avctx->rc_buffer_size; const int buffer_size= s->avctx->rc_buffer_size;
const double min_rate= s->avctx->rc_min_rate/fps; const double min_rate= s->avctx->rc_min_rate/fps;
const double max_rate= s->avctx->rc_max_rate/fps; const double max_rate= s->avctx->rc_max_rate/fps;
//printf("%f %f %d %f %f\n", buffer_size, rcc->buffer_index, frame_size, min_rate, max_rate); //printf("%d %f %d %f %f\n", buffer_size, rcc->buffer_index, frame_size, min_rate, max_rate);
if(buffer_size){ if(buffer_size){
int left; int left;
@@ -215,8 +215,8 @@ int ff_vbv_update(MpegEncContext *s, int frame_size){
left= buffer_size - rcc->buffer_index - 1; left= buffer_size - rcc->buffer_index - 1;
rcc->buffer_index += clip(left, min_rate, max_rate); rcc->buffer_index += clip(left, min_rate, max_rate);
if(rcc->buffer_index > s->avctx->rc_buffer_size){ if(rcc->buffer_index > buffer_size){
int stuffing= ceil((rcc->buffer_index - s->avctx->rc_buffer_size)/8); int stuffing= ceil((rcc->buffer_index - buffer_size)/8);
if(stuffing < 4 && s->codec_id == CODEC_ID_MPEG4) if(stuffing < 4 && s->codec_id == CODEC_ID_MPEG4)
stuffing=4; stuffing=4;
@@ -413,6 +413,7 @@ static double modify_qscale(MpegEncContext *s, RateControlEntry *rce, double q,
/* buffer overflow/underflow protection */ /* buffer overflow/underflow protection */
if(buffer_size){ if(buffer_size){
double expected_size= rcc->buffer_index; double expected_size= rcc->buffer_index;
double q_limit;
if(min_rate){ if(min_rate){
double d= 2*(buffer_size - expected_size)/buffer_size; double d= 2*(buffer_size - expected_size)/buffer_size;
@@ -420,7 +421,13 @@ static double modify_qscale(MpegEncContext *s, RateControlEntry *rce, double q,
else if(d<0.0001) d=0.0001; else if(d<0.0001) d=0.0001;
q*= pow(d, 1.0/s->avctx->rc_buffer_aggressivity); q*= pow(d, 1.0/s->avctx->rc_buffer_aggressivity);
q= FFMIN(q, bits2qp(rce, FFMAX((min_rate - buffer_size + rcc->buffer_index)*3, 1))); q_limit= bits2qp(rce, FFMAX((min_rate - buffer_size + rcc->buffer_index)*3, 1));
if(q > q_limit){
if(s->avctx->debug&FF_DEBUG_RC){
av_log(s->avctx, AV_LOG_DEBUG, "limiting QP %f -> %f\n", q, q_limit);
}
q= q_limit;
}
} }
if(max_rate){ if(max_rate){
@@ -429,7 +436,13 @@ static double modify_qscale(MpegEncContext *s, RateControlEntry *rce, double q,
else if(d<0.0001) d=0.0001; else if(d<0.0001) d=0.0001;
q/= pow(d, 1.0/s->avctx->rc_buffer_aggressivity); q/= pow(d, 1.0/s->avctx->rc_buffer_aggressivity);
q= FFMAX(q, bits2qp(rce, FFMAX(rcc->buffer_index/3, 1))); q_limit= bits2qp(rce, FFMAX(rcc->buffer_index/3, 1));
if(q < q_limit){
if(s->avctx->debug&FF_DEBUG_RC){
av_log(s->avctx, AV_LOG_DEBUG, "limiting QP %f -> %f\n", q, q_limit);
}
q= q_limit;
}
} }
} }
//printf("q:%f max:%f min:%f size:%f index:%d bits:%f agr:%f\n", q,max_rate, min_rate, buffer_size, rcc->buffer_index, bits, s->avctx->rc_buffer_aggressivity); //printf("q:%f max:%f min:%f size:%f index:%d bits:%f agr:%f\n", q,max_rate, min_rate, buffer_size, rcc->buffer_index, bits, s->avctx->rc_buffer_aggressivity);
@@ -507,7 +520,7 @@ static void adaptive_quantization(MpegEncContext *s, double q){
if(spat_cplx < 4) spat_cplx= 4; //FIXME finetune if(spat_cplx < 4) spat_cplx= 4; //FIXME finetune
if(temp_cplx < 4) temp_cplx= 4; //FIXME finetune if(temp_cplx < 4) temp_cplx= 4; //FIXME finetune
if((s->mb_type[mb_xy]&MB_TYPE_INTRA)){//FIXME hq mode if((s->mb_type[mb_xy]&CANDIDATE_MB_TYPE_INTRA)){//FIXME hq mode
cplx= spat_cplx; cplx= spat_cplx;
factor= 1.0 + p_masking; factor= 1.0 + p_masking;
}else{ }else{
@@ -254,15 +254,15 @@ static int rpza_decode_frame(AVCodecContext *avctx,
{ {
RpzaContext *s = (RpzaContext *)avctx->priv_data; RpzaContext *s = (RpzaContext *)avctx->priv_data;
/* no supplementary picture */ /* no supplementary picture */
if (buf_size == 0) if (buf_size == 0)
return 0; return 0;
s->buf = buf; s->buf = buf;
s->size = buf_size; s->size = buf_size;
s->frame.reference = 1; s->frame.reference = 1;
s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
if (avctx->reget_buffer(avctx, &s->frame)) { if (avctx->reget_buffer(avctx, &s->frame)) {
av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
return -1; return -1;
@@ -1,6 +1,7 @@
/* /*
* RV10 codec * RV10 codec
* Copyright (c) 2000,2001 Fabrice Bellard. * Copyright (c) 2000,2001 Fabrice Bellard.
* Copyright (c) 2002-2004 Michael Niedermayer
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -378,12 +379,17 @@ static int rv20_decode_picture_header(MpegEncContext *s)
if(s->avctx->has_b_frames){ if(s->avctx->has_b_frames){
if (get_bits(&s->gb, 1)){ if (get_bits(&s->gb, 1)){
av_log(s->avctx, AV_LOG_ERROR, "unknown bit3 set\n"); // av_log(s->avctx, AV_LOG_ERROR, "unknown bit3 set\n");
return -1; // return -1;
} }
seq= get_bits(&s->gb, 15); seq= get_bits(&s->gb, 15);
}else mb_pos= get_bits(&s->gb, av_log2(s->mb_num-1)+1);
s->mb_x= mb_pos % s->mb_width;
s->mb_y= mb_pos / s->mb_width;
}else{
seq= get_bits(&s->gb, 8)*128; seq= get_bits(&s->gb, 8)*128;
mb_pos= ff_h263_decode_mba(s);
}
//printf("%d\n", seq); //printf("%d\n", seq);
seq |= s->time &~0x7FFF; seq |= s->time &~0x7FFF;
if(seq - s->time > 0x4000) seq -= 0x8000; if(seq - s->time > 0x4000) seq -= 0x8000;
@@ -404,7 +410,6 @@ static int rv20_decode_picture_header(MpegEncContext *s)
} }
// printf("%d %d %d %d %d\n", seq, (int)s->time, (int)s->last_non_b_time, s->pp_time, s->pb_time); // printf("%d %d %d %d %d\n", seq, (int)s->time, (int)s->last_non_b_time, s->pp_time, s->pb_time);
mb_pos= ff_h263_decode_mba(s);
s->no_rounding= get_bits1(&s->gb); s->no_rounding= get_bits1(&s->gb);
s->f_code = 1; s->f_code = 1;
@@ -469,8 +474,6 @@ static int rv10_decode_init(AVCodecContext *avctx)
av_log(s->avctx, AV_LOG_ERROR, "unknown header %X\n", avctx->sub_id); av_log(s->avctx, AV_LOG_ERROR, "unknown header %X\n", avctx->sub_id);
} }
//printf("ver:%X\n", avctx->sub_id); //printf("ver:%X\n", avctx->sub_id);
s->flags= avctx->flags;
if (MPV_common_init(s) < 0) if (MPV_common_init(s) < 0)
return -1; return -1;
@@ -537,11 +540,15 @@ static int rv10_decode_packet(AVCodecContext *avctx,
} }
//if(s->pict_type == P_TYPE) return 0; //if(s->pict_type == P_TYPE) return 0;
if (s->mb_x == 0 && s->mb_y == 0) { if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr==NULL) {
if(MPV_frame_start(s, avctx) < 0) if(MPV_frame_start(s, avctx) < 0)
return -1; return -1;
} }
if(s->pict_type == B_TYPE){ //FIXME remove after cleaning mottion_val indexing
memset(s->current_picture.motion_val[0], 0, sizeof(int16_t)*2*(s->mb_width*2+2)*(s->mb_height*2+2));
}
#ifdef DEBUG #ifdef DEBUG
printf("qscale=%d\n", s->qscale); printf("qscale=%d\n", s->qscale);
#endif #endif
@@ -570,7 +577,7 @@ static int rv10_decode_packet(AVCodecContext *avctx,
s->rv10_first_dc_coded[0] = 0; s->rv10_first_dc_coded[0] = 0;
s->rv10_first_dc_coded[1] = 0; s->rv10_first_dc_coded[1] = 0;
s->rv10_first_dc_coded[2] = 0; s->rv10_first_dc_coded[2] = 0;
//printf("%d %X %X\n", s->pict_type, s->current_picture.motion_val[0], s->current_picture.motion_val[1]);
s->block_wrap[0]= s->block_wrap[0]=
s->block_wrap[1]= s->block_wrap[1]=
s->block_wrap[2]= s->block_wrap[2]=
@@ -595,7 +602,8 @@ static int rv10_decode_packet(AVCodecContext *avctx,
av_log(s->avctx, AV_LOG_ERROR, "ERROR at MB %d %d\n", s->mb_x, s->mb_y); av_log(s->avctx, AV_LOG_ERROR, "ERROR at MB %d %d\n", s->mb_x, s->mb_y);
return -1; return -1;
} }
ff_h263_update_motion_val(s); if(s->pict_type != B_TYPE)
ff_h263_update_motion_val(s);
MPV_decode_mb(s, s->block); MPV_decode_mb(s, s->block);
if(s->loop_filter) if(s->loop_filter)
ff_h263_loop_filter(s); ff_h263_loop_filter(s);
@@ -630,7 +638,7 @@ static int rv10_decode_frame(AVCodecContext *avctx,
*data_size = 0; *data_size = 0;
return 0; return 0;
} }
if(avctx->slice_count){ if(avctx->slice_count){
for(i=0; i<avctx->slice_count; i++){ for(i=0; i<avctx->slice_count; i++){
int offset= avctx->slice_offset[i]; int offset= avctx->slice_offset[i];
@@ -648,16 +656,20 @@ static int rv10_decode_frame(AVCodecContext *avctx,
if( rv10_decode_packet(avctx, buf, buf_size) < 0 ) if( rv10_decode_packet(avctx, buf, buf_size) < 0 )
return -1; return -1;
} }
if(s->pict_type == B_TYPE){ //FIXME remove after cleaning mottion_val indexing
memset(s->current_picture.motion_val[0], 0, sizeof(int16_t)*2*(s->mb_width*2+2)*(s->mb_height*2+2));
}
if(s->mb_y>=s->mb_height){ if(s->mb_y>=s->mb_height){
MPV_frame_end(s); MPV_frame_end(s);
if(s->pict_type==B_TYPE || s->low_delay){ if(s->pict_type==B_TYPE || s->low_delay){
*pict= *(AVFrame*)&s->current_picture; *pict= *(AVFrame*)&s->current_picture;
ff_print_debug_info(s, s->current_picture_ptr); ff_print_debug_info(s, pict);
} else { } else {
*pict= *(AVFrame*)&s->last_picture; *pict= *(AVFrame*)&s->last_picture;
ff_print_debug_info(s, s->last_picture_ptr); ff_print_debug_info(s, pict);
} }
*data_size = sizeof(AVFrame); *data_size = sizeof(AVFrame);
@@ -453,16 +453,16 @@ static int smc_decode_frame(AVCodecContext *avctx,
{ {
SmcContext *s = (SmcContext *)avctx->priv_data; SmcContext *s = (SmcContext *)avctx->priv_data;
/* no supplementary picture */ /* no supplementary picture */
if (buf_size == 0) if (buf_size == 0)
return 0; return 0;
s->buf = buf; s->buf = buf;
s->size = buf_size; s->size = buf_size;
s->frame.reference = 1; s->frame.reference = 1;
s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE; FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE;
if (avctx->reget_buffer(avctx, &s->frame)) { if (avctx->reget_buffer(avctx, &s->frame)) {
printf ("reget_buffer() failed\n"); printf ("reget_buffer() failed\n");
return -1; return -1;
@@ -579,7 +579,7 @@ static void svq1_parse_string (GetBitContext *bitbuf, uint8_t *out) {
seed = string_table[out[0]]; seed = string_table[out[0]];
for (i=1; i < out[0]; i++) { for (i=1; i <= out[0]; i++) {
out[i] = get_bits (bitbuf, 8) ^ seed; out[i] = get_bits (bitbuf, 8) ^ seed;
seed = string_table[out[i] ^ seed]; seed = string_table[out[i] ^ seed];
} }
@@ -789,7 +789,6 @@ static int svq1_decode_init(AVCodecContext *avctx)
s->codec_id= avctx->codec->id; s->codec_id= avctx->codec->id;
avctx->pix_fmt = PIX_FMT_YUV410P; avctx->pix_fmt = PIX_FMT_YUV410P;
avctx->has_b_frames= 1; // not true, but DP frames and these behave like unidirectional b frames 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; if (MPV_common_init(s) < 0) return -1;
init_vlc(&svq1_block_type, 2, 4, init_vlc(&svq1_block_type, 2, 4,
@@ -697,8 +697,10 @@ static int svq3_decode_slice_header (H264Context *h) {
h->next_slice_index = s->gb.index + 8*show_bits (&s->gb, 8*length) + 8*length; h->next_slice_index = s->gb.index + 8*show_bits (&s->gb, 8*length) + 8*length;
if (h->next_slice_index > s->gb.size_in_bits) if (h->next_slice_index > s->gb.size_in_bits){
av_log(h->s.avctx, AV_LOG_ERROR, "slice after bitstream end\n");
return -1; return -1;
}
s->gb.size_in_bits = h->next_slice_index - 8*(length - 1); s->gb.size_in_bits = h->next_slice_index - 8*(length - 1);
s->gb.index += 8; s->gb.index += 8;
@@ -709,8 +711,10 @@ static int svq3_decode_slice_header (H264Context *h) {
} }
} }
if ((i = svq3_get_ue_golomb (&s->gb)) == INVALID_VLC || i >= 3) if ((i = svq3_get_ue_golomb (&s->gb)) == INVALID_VLC || i >= 3){
av_log(h->s.avctx, AV_LOG_ERROR, "illegal slice type %d \n", i);
return -1; return -1;
}
h->slice_type = golomb_to_pict_type[i]; h->slice_type = golomb_to_pict_type[i];
@@ -766,7 +770,9 @@ static int svq3_decode_frame (AVCodecContext *avctx,
*data_size = 0; *data_size = 0;
s->flags = avctx->flags; s->flags = avctx->flags;
s->flags2 = avctx->flags2;
s->unrestricted_mv = 1;
if (!s->context_initialized) { if (!s->context_initialized) {
s->width = avctx->width; s->width = avctx->width;
s->height = avctx->height; s->height = avctx->height;
@@ -2,6 +2,7 @@
* utils for libavcodec * utils for libavcodec
* Copyright (c) 2001 Fabrice Bellard. * Copyright (c) 2001 Fabrice Bellard.
* Copyright (c) 2003 Michel Bardiaux for the av_log API * Copyright (c) 2003 Michel Bardiaux for the av_log API
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -354,6 +355,7 @@ void avcodec_get_context_defaults(AVCodecContext *s){
s->lmin= FF_QP2LAMBDA * s->qmin; s->lmin= FF_QP2LAMBDA * s->qmin;
s->lmax= FF_QP2LAMBDA * s->qmax; s->lmax= FF_QP2LAMBDA * s->qmax;
s->sample_aspect_ratio= (AVRational){0,1}; s->sample_aspect_ratio= (AVRational){0,1};
s->ildct_cmp= FF_CMP_VSAD;
s->intra_quant_bias= FF_DEFAULT_QUANT_BIAS; s->intra_quant_bias= FF_DEFAULT_QUANT_BIAS;
s->inter_quant_bias= FF_DEFAULT_QUANT_BIAS; s->inter_quant_bias= FF_DEFAULT_QUANT_BIAS;
@@ -818,9 +820,9 @@ static void av_log_default_callback(AVCodecContext* avctx, int level, const char
if(level>av_log_level) if(level>av_log_level)
return; return;
if(avctx && print_prefix) if(avctx && print_prefix)
fprintf(stderr, "[%s @ %p]", avctx->codec->name, avctx); fprintf(stderr, "[%s @ %p]", avctx->codec ? avctx->codec->name : "?", avctx);
print_prefix= (int)strstr(fmt, "\n"); print_prefix= strstr(fmt, "\n") != NULL;
vfprintf(stderr, fmt, vl); vfprintf(stderr, fmt, vl);
} }
@@ -1187,6 +1187,11 @@ static int wma_decode_superframe(AVCodecContext *avctx,
tprintf("***decode_superframe:\n"); tprintf("***decode_superframe:\n");
if(buf_size==0){
s->last_superframe_len = 0;
return 0;
}
samples = data; samples = data;
init_get_bits(&s->gb, buf, buf_size*8); init_get_bits(&s->gb, buf, buf_size*8);