golomb rice codes
use gradients instead of prediction errors as context model store independant quantization tables for each point merge contexts with opposit sign Originally committed as revision 1957 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
5dbafeb7ba
commit
11e659c203
@ -15,8 +15,8 @@ extern "C" {
|
|||||||
|
|
||||||
#define LIBAVCODEC_VERSION_INT 0x000406
|
#define LIBAVCODEC_VERSION_INT 0x000406
|
||||||
#define LIBAVCODEC_VERSION "0.4.6"
|
#define LIBAVCODEC_VERSION "0.4.6"
|
||||||
#define LIBAVCODEC_BUILD 4668
|
#define LIBAVCODEC_BUILD 4669
|
||||||
#define LIBAVCODEC_BUILD_STR "4668"
|
#define LIBAVCODEC_BUILD_STR "4669"
|
||||||
|
|
||||||
#define LIBAVCODEC_IDENT "FFmpeg" LIBAVCODEC_VERSION "b" LIBAVCODEC_BUILD_STR
|
#define LIBAVCODEC_IDENT "FFmpeg" LIBAVCODEC_VERSION "b" LIBAVCODEC_BUILD_STR
|
||||||
|
|
||||||
@ -1127,6 +1127,22 @@ typedef struct AVCodecContext {
|
|||||||
* - decoding: unused
|
* - decoding: unused
|
||||||
*/
|
*/
|
||||||
int global_quality;
|
int global_quality;
|
||||||
|
|
||||||
|
#define FF_CODER_TYPE_VLC 0
|
||||||
|
#define FF_CODER_TYPE_AC 1
|
||||||
|
/**
|
||||||
|
* coder type
|
||||||
|
* - encoding: set by user.
|
||||||
|
* - decoding: unused
|
||||||
|
*/
|
||||||
|
int coder_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* context model
|
||||||
|
* - encoding: set by user.
|
||||||
|
* - decoding: unused
|
||||||
|
*/
|
||||||
|
int context_model;
|
||||||
} AVCodecContext;
|
} AVCodecContext;
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,74 +28,145 @@
|
|||||||
#include "avcodec.h"
|
#include "avcodec.h"
|
||||||
#include "dsputil.h"
|
#include "dsputil.h"
|
||||||
#include "cabac.h"
|
#include "cabac.h"
|
||||||
|
#include "golomb.h"
|
||||||
|
|
||||||
#define MAX_PLANES 4
|
#define MAX_PLANES 4
|
||||||
#define CONTEXT_SIZE 32
|
#define CONTEXT_SIZE 32
|
||||||
|
|
||||||
#if 0
|
static const int8_t quant3[256]={
|
||||||
#define DEFAULT_QDIFF_COUNT (9)
|
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
static const uint8_t default_quant_table[512]={
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3,
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
4,
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8,
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0,
|
||||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
||||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
||||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
||||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
||||||
};
|
};
|
||||||
#else
|
static const int8_t quant5[256]={
|
||||||
#define DEFAULT_QDIFF_COUNT (16)
|
0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
|
||||||
static const uint8_t default_quant_table[256]={
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7,
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
8,
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
9,10,11,11,12,12,12,12,13,13,13,13,13,13,13,13,
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
|
||||||
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
|
||||||
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
|
||||||
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
|
||||||
};
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
|
||||||
#endif
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
|
||||||
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
|
||||||
static const int to5[16]={
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1,-1,-1,
|
||||||
0,0,0,0,
|
|
||||||
0,0,0,1,
|
|
||||||
2,3,4,4,
|
|
||||||
4,4,4,4,
|
|
||||||
};
|
};
|
||||||
|
static const int8_t quant7[256]={
|
||||||
|
0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||||
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||||
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||||
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||||
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||||
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||||
|
-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
|
||||||
|
-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
|
||||||
|
-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
|
||||||
|
-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
|
||||||
|
-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
|
||||||
|
-3,-3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-2,-2,-2,
|
||||||
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
|
||||||
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1,-1,
|
||||||
|
};
|
||||||
|
static const int8_t quant9[256]={
|
||||||
|
0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||||
|
3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
|
||||||
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
|
||||||
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
|
||||||
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
|
||||||
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
|
||||||
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
|
||||||
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,
|
||||||
|
-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-1,-1,
|
||||||
|
};
|
||||||
|
static const int8_t quant11[256]={
|
||||||
|
0, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
|
||||||
|
-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
|
||||||
|
-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
|
||||||
|
-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
|
||||||
|
-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
|
||||||
|
-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-4,-4,
|
||||||
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
|
||||||
|
-4,-4,-4,-4,-4,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-1,
|
||||||
|
};
|
||||||
|
static const int8_t quant13[256]={
|
||||||
|
0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||||
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||||
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||||
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||||
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||||
|
-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
|
||||||
|
-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
|
||||||
|
-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
|
||||||
|
-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
|
||||||
|
-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-5,
|
||||||
|
-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
|
||||||
|
-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
|
||||||
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,-2,-2,-1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t log2_run[32]={
|
||||||
|
0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
|
||||||
|
4, 4, 5, 5, 6, 6, 7, 7,
|
||||||
|
8, 9,10,11,12,13,14,15,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct VlcState{
|
||||||
|
int16_t drift;
|
||||||
|
uint16_t error_sum;
|
||||||
|
int8_t bias;
|
||||||
|
uint8_t count;
|
||||||
|
} VlcState;
|
||||||
|
|
||||||
typedef struct PlaneContext{
|
typedef struct PlaneContext{
|
||||||
uint8_t quant_table[256];
|
|
||||||
int qdiff_count;
|
|
||||||
int context_count;
|
int context_count;
|
||||||
uint8_t (*state)[CONTEXT_SIZE];
|
uint8_t (*state)[CONTEXT_SIZE];
|
||||||
|
VlcState *vlc_state;
|
||||||
uint8_t interlace_bit_state[2];
|
uint8_t interlace_bit_state[2];
|
||||||
} PlaneContext;
|
} PlaneContext;
|
||||||
|
|
||||||
typedef struct FFV1Context{
|
typedef struct FFV1Context{
|
||||||
AVCodecContext *avctx;
|
AVCodecContext *avctx;
|
||||||
CABACContext c;
|
CABACContext c;
|
||||||
|
GetBitContext gb;
|
||||||
|
PutBitContext pb;
|
||||||
int version;
|
int version;
|
||||||
int width, height;
|
int width, height;
|
||||||
int chroma_h_shift, chroma_v_shift;
|
int chroma_h_shift, chroma_v_shift;
|
||||||
@ -103,68 +174,38 @@ typedef struct FFV1Context{
|
|||||||
int picture_number;
|
int picture_number;
|
||||||
AVFrame picture;
|
AVFrame picture;
|
||||||
int plane_count;
|
int plane_count;
|
||||||
|
int ac; ///< 1-> CABAC 0-> golomb rice
|
||||||
PlaneContext plane[MAX_PLANES];
|
PlaneContext plane[MAX_PLANES];
|
||||||
|
int16_t quant_table[5][256];
|
||||||
|
|
||||||
DSPContext dsp;
|
DSPContext dsp;
|
||||||
}FFV1Context;
|
}FFV1Context;
|
||||||
|
|
||||||
//1.774215
|
static inline int predict(uint8_t *src, uint8_t *last){
|
||||||
static inline int predict(FFV1Context *s, uint8_t *src, int stride, int x, int y){
|
const int LT= last[-1];
|
||||||
if(x && y){
|
const int T= last[ 0];
|
||||||
// const int RT= src[+1-stride];
|
const int L = src[-1];
|
||||||
const int LT= src[-1-stride];
|
uint8_t *cm = cropTbl + MAX_NEG_CROP;
|
||||||
const int T= src[ -stride];
|
const int gradient= cm[L + T - LT];
|
||||||
const int L = src[-1 ];
|
|
||||||
uint8_t *cm = cropTbl + MAX_NEG_CROP;
|
|
||||||
const int gradient= cm[L + T - LT];
|
|
||||||
|
|
||||||
// return gradient;
|
return mid_pred(L, gradient, T);
|
||||||
return mid_pred(L, gradient, T);
|
|
||||||
}else{
|
|
||||||
if(y){
|
|
||||||
return src[ -stride];
|
|
||||||
}else if(x){
|
|
||||||
return src[-1 ];
|
|
||||||
}else{
|
|
||||||
return 128;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int get_context(FFV1Context *f, uint8_t *src, uint8_t *last, uint8_t *last2){
|
||||||
|
const int LT= last[-1];
|
||||||
|
const int T= last[ 0];
|
||||||
|
const int RT= last[ 1];
|
||||||
|
const int L = src[-1];
|
||||||
|
|
||||||
#if 0
|
if(f->quant_table[3][127]){
|
||||||
static inline void put_symbol(CABACContext, uint8_t *state, int v){
|
const int TT= last2[0];
|
||||||
put_cabac_ueg(c, state, v, 32, 1, 4 , 32);
|
const int LL= src[-2];
|
||||||
|
return f->quant_table[0][(L-LT) & 0xFF] + f->quant_table[1][(LT-T) & 0xFF] + f->quant_table[2][(T-RT) & 0xFF]
|
||||||
|
+f->quant_table[3][(LL-L) & 0xFF] + f->quant_table[4][(TT-T) & 0xFF];
|
||||||
|
}else
|
||||||
|
return f->quant_table[0][(L-LT) & 0xFF] + f->quant_table[1][(LT-T) & 0xFF] + f->quant_table[2][(T-RT) & 0xFF];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int get_symbol(CABACContext, uint8_t *state){
|
|
||||||
return get_cabac_ueg(c, state, 32, 1, 4 , 32);
|
|
||||||
}
|
|
||||||
#elif 0
|
|
||||||
static inline void put_symbol(CABACContext *c, uint8_t *state, int v){
|
|
||||||
if(v==0)
|
|
||||||
put_cabac(c, state+0, 1);
|
|
||||||
else{
|
|
||||||
put_cabac(c, state+0, 0);
|
|
||||||
put_cabac(c, state+1, v<0);
|
|
||||||
if(v<0) state += 64;
|
|
||||||
put_cabac_ueg(c, state+2, ABS(v)-1, 32, 0, 4 , 32);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int get_symbol(CABACContext *c, uint8_t *state){
|
|
||||||
if(get_cabac(c, state+0))
|
|
||||||
return 0;
|
|
||||||
else{
|
|
||||||
int sign= get_cabac(c, state+1);
|
|
||||||
if(sign)
|
|
||||||
return -1-get_cabac_ueg(c, state+66, 32, 0, 4 , 32);
|
|
||||||
else
|
|
||||||
return 1+get_cabac_ueg(c, state+2 , 32, 0, 4 , 32);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* put
|
* put
|
||||||
*/
|
*/
|
||||||
@ -214,53 +255,184 @@ static inline int get_symbol(CABACContext *c, uint8_t *state, int is_signed){
|
|||||||
return -128;
|
return -128;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void update_vlc_state(VlcState * const state, const int v){
|
||||||
|
int drift= state->drift;
|
||||||
|
int count= state->count;
|
||||||
|
state->error_sum += ABS(v);
|
||||||
|
drift += v;
|
||||||
|
|
||||||
|
if(count == 128){ //FIXME variable
|
||||||
|
count >>= 1;
|
||||||
|
drift >>= 1;
|
||||||
|
state->error_sum >>= 1;
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if(drift <= -count){
|
||||||
|
if(state->bias > -128) state->bias--;
|
||||||
|
|
||||||
|
drift += count;
|
||||||
|
if(drift <= -count)
|
||||||
|
drift= -count + 1;
|
||||||
|
}else if(drift > 0){
|
||||||
|
if(state->bias < 127) state->bias++;
|
||||||
|
|
||||||
|
drift -= count;
|
||||||
|
if(drift > 0)
|
||||||
|
drift= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
state->drift= drift;
|
||||||
|
state->count= count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void put_vlc_symbol(PutBitContext *pb, VlcState * const state, int v){
|
||||||
|
int i, k, code;
|
||||||
|
//printf("final: %d ", v);
|
||||||
|
v = (int8_t)(v - state->bias);
|
||||||
|
|
||||||
|
i= state->count;
|
||||||
|
k=0;
|
||||||
|
while(i < state->error_sum){ //FIXME optimize
|
||||||
|
k++;
|
||||||
|
i += i;
|
||||||
|
}
|
||||||
|
#if 0 // JPEG LS
|
||||||
|
if(k==0 && 2*state->drift <= - state->count) code= v ^ (-1);
|
||||||
|
else code= v;
|
||||||
|
#else
|
||||||
|
code= v ^ ((2*state->drift + state->count)>>31);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
code = -2*code-1;
|
||||||
|
code^= (code>>31);
|
||||||
|
//printf("v:%d/%d bias:%d error:%d drift:%d count:%d k:%d\n", v, code, state->bias, state->error_sum, state->drift, state->count, k);
|
||||||
|
set_ur_golomb(pb, code, k, 8, 8);
|
||||||
|
|
||||||
|
update_vlc_state(state, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int get_vlc_symbol(GetBitContext *gb, VlcState * const state){
|
||||||
|
int k, i, v, ret;
|
||||||
|
|
||||||
|
i= state->count;
|
||||||
|
k=0;
|
||||||
|
while(i < state->error_sum){ //FIXME optimize
|
||||||
|
k++;
|
||||||
|
i += i;
|
||||||
|
}
|
||||||
|
|
||||||
|
v= get_ur_golomb(gb, k, 8, 8);
|
||||||
|
//printf("v:%d bias:%d error:%d drift:%d count:%d k:%d", v, state->bias, state->error_sum, state->drift, state->count, k);
|
||||||
|
|
||||||
|
v++;
|
||||||
|
if(v&1) v= (v>>1);
|
||||||
|
else v= -(v>>1);
|
||||||
|
|
||||||
|
#if 0 // JPEG LS
|
||||||
|
if(k==0 && 2*state->drift <= - state->count) v ^= (-1);
|
||||||
|
#else
|
||||||
|
v ^= ((2*state->drift + state->count)>>31);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ret= (int8_t)(v + state->bias);
|
||||||
|
|
||||||
|
update_vlc_state(state, v);
|
||||||
|
//printf("final: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index){
|
static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index){
|
||||||
PlaneContext * const p= &s->plane[plane_index];
|
PlaneContext * const p= &s->plane[plane_index];
|
||||||
CABACContext * const c= &s->c;
|
CABACContext * const c= &s->c;
|
||||||
int x,y;
|
int x,y;
|
||||||
uint8_t pred_diff_buffer[4][w+6];
|
uint8_t pred_diff_buffer[4][w+6]; //FIXME rema,e
|
||||||
uint8_t *pred_diff[4]= {pred_diff_buffer[0]+3, pred_diff_buffer[1]+3, pred_diff_buffer[2]+3, pred_diff_buffer[3]+3};
|
uint8_t *pred_diff[4]= {pred_diff_buffer[0]+3, pred_diff_buffer[1]+3, pred_diff_buffer[2]+3, pred_diff_buffer[3]+3};
|
||||||
// uint8_t temp_buf[3*w], *temp= temp_buf + 3*w;
|
int run_index=0;
|
||||||
|
|
||||||
memset(pred_diff_buffer, 0, sizeof(pred_diff_buffer));
|
memset(pred_diff_buffer, 0, sizeof(pred_diff_buffer));
|
||||||
|
|
||||||
for(y=0; y<h; y++){
|
for(y=0; y<h; y++){
|
||||||
uint8_t *temp= pred_diff[0]; //FIXME try a normal buffer
|
uint8_t *temp= pred_diff[0]; //FIXME try a normal buffer
|
||||||
|
int run_count=0;
|
||||||
|
int run_mode=0;
|
||||||
|
|
||||||
pred_diff[0]= pred_diff[1];
|
pred_diff[0]= pred_diff[1];
|
||||||
pred_diff[1]= pred_diff[2];
|
pred_diff[1]= pred_diff[2];
|
||||||
pred_diff[2]= pred_diff[3];
|
pred_diff[2]= pred_diff[3];
|
||||||
pred_diff[3]= temp;
|
pred_diff[3]= temp;
|
||||||
|
|
||||||
|
pred_diff[3][-1]= pred_diff[2][0 ];
|
||||||
|
pred_diff[2][ w]= pred_diff[2][w-1];
|
||||||
|
|
||||||
for(x=0; x<w; x++){
|
for(x=0; x<w; x++){
|
||||||
uint8_t *temp_src= src + x + stride*y;
|
uint8_t *temp_src= src + x + stride*y;
|
||||||
int diff, context, qdiff;
|
int diff, context;
|
||||||
|
|
||||||
if(p->context_count == 256)
|
|
||||||
context= pred_diff[3+0][x-1] + 16*pred_diff[3-1][x+0];
|
|
||||||
else
|
|
||||||
context= pred_diff[3+0][x-1] + 16*pred_diff[3-1][x+0]
|
|
||||||
+ 16*16*to5[pred_diff[3-1][x+1]] + 16*16*5*to5[pred_diff[3-0][x-2]] + 16*16*5*5*to5[pred_diff[3-2][x+0]];
|
|
||||||
|
|
||||||
diff = (int8_t)(temp_src[0] - predict(s, temp_src, stride, x, y));
|
|
||||||
|
|
||||||
qdiff= p->quant_table[128+diff];
|
context= get_context(s, pred_diff[3]+x, pred_diff[2]+x, pred_diff[1]+x);
|
||||||
|
diff= temp_src[0] - predict(pred_diff[3]+x, pred_diff[2]+x);
|
||||||
|
|
||||||
put_symbol(c, p->state[context], diff, 1);
|
if(context < 0){
|
||||||
|
context = -context;
|
||||||
|
diff= -diff;
|
||||||
|
}
|
||||||
|
|
||||||
pred_diff[3][x]= qdiff;
|
diff= (int8_t)diff;
|
||||||
|
|
||||||
|
if(s->ac)
|
||||||
|
put_symbol(c, p->state[context], diff, 1);
|
||||||
|
else{
|
||||||
|
if(context == 0) run_mode=1;
|
||||||
|
|
||||||
|
if(run_mode){
|
||||||
|
|
||||||
|
if(diff){
|
||||||
|
while(run_count >= 1<<log2_run[run_index]){
|
||||||
|
run_count -= 1<<log2_run[run_index];
|
||||||
|
run_index++;
|
||||||
|
put_bits(&s->pb, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
put_bits(&s->pb, 1 + log2_run[run_index], run_count);
|
||||||
|
if(run_index) run_index--;
|
||||||
|
run_count=0;
|
||||||
|
run_mode=0;
|
||||||
|
if(diff>0) diff--;
|
||||||
|
}else{
|
||||||
|
run_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// printf("count:%d index:%d, mode:%d, x:%d y:%d pos:%d\n", run_count, run_index, run_mode, x, y, (int)get_bit_count(&s->pb));
|
||||||
|
|
||||||
|
if(run_mode == 0)
|
||||||
|
put_vlc_symbol(&s->pb, &p->vlc_state[context], diff);
|
||||||
|
}
|
||||||
|
|
||||||
|
pred_diff[3][x]= temp_src[0];
|
||||||
|
}
|
||||||
|
if(run_mode){
|
||||||
|
while(run_count >= 1<<log2_run[run_index]){
|
||||||
|
run_count -= 1<<log2_run[run_index];
|
||||||
|
run_index++;
|
||||||
|
put_bits(&s->pb, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(run_count)
|
||||||
|
put_bits(&s->pb, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_quant_table(CABACContext *c, uint8_t *quant_table){
|
static void write_quant_table(CABACContext *c, int16_t *quant_table){
|
||||||
int last=0;
|
int last=0;
|
||||||
int i;
|
int i;
|
||||||
uint8_t state[CONTEXT_SIZE]={0};
|
uint8_t state[CONTEXT_SIZE]={0};
|
||||||
|
|
||||||
for(i=1; i<256 ; i++){
|
for(i=1; i<128 ; i++){
|
||||||
if(quant_table[i] != quant_table[i-1]){
|
if(quant_table[i] != quant_table[i-1]){
|
||||||
put_symbol(c, state, i-last-1, 0);
|
put_symbol(c, state, i-last-1, 0);
|
||||||
last= i;
|
last= i;
|
||||||
@ -275,18 +447,15 @@ static void write_header(FFV1Context *f){
|
|||||||
CABACContext * const c= &f->c;
|
CABACContext * const c= &f->c;
|
||||||
|
|
||||||
put_symbol(c, state, f->version, 0);
|
put_symbol(c, state, f->version, 0);
|
||||||
|
put_symbol(c, state, f->avctx->coder_type, 0);
|
||||||
put_symbol(c, state, 0, 0); //YUV cs type
|
put_symbol(c, state, 0, 0); //YUV cs type
|
||||||
put_cabac(c, state, 1); //chroma planes
|
put_cabac(c, state, 1); //chroma planes
|
||||||
put_symbol(c, state, f->chroma_h_shift, 0);
|
put_symbol(c, state, f->chroma_h_shift, 0);
|
||||||
put_symbol(c, state, f->chroma_v_shift, 0);
|
put_symbol(c, state, f->chroma_v_shift, 0);
|
||||||
put_cabac(c, state, 0); //no transparency plane
|
put_cabac(c, state, 0); //no transparency plane
|
||||||
|
|
||||||
for(i=0; i<3; i++){ //FIXME chroma & trasparency decission
|
for(i=0; i<5; i++)
|
||||||
PlaneContext * const p= &f->plane[i];
|
write_quant_table(c, f->quant_table[i]);
|
||||||
|
|
||||||
put_symbol(c, state, av_log2(p->context_count), 0);
|
|
||||||
write_quant_table(c, p->quant_table);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int common_init(AVCodecContext *avctx){
|
static int common_init(AVCodecContext *avctx){
|
||||||
@ -314,21 +483,37 @@ static int encode_init(AVCodecContext *avctx)
|
|||||||
common_init(avctx);
|
common_init(avctx);
|
||||||
|
|
||||||
s->version=0;
|
s->version=0;
|
||||||
|
s->ac= avctx->coder_type;
|
||||||
|
|
||||||
s->plane_count=3;
|
s->plane_count=3;
|
||||||
|
for(i=0; i<256; i++){
|
||||||
|
s->quant_table[0][i]= quant11[i];
|
||||||
|
s->quant_table[1][i]= 11*quant11[i];
|
||||||
|
if(avctx->context_model==0){
|
||||||
|
s->quant_table[2][i]= 11*11*quant11[i];
|
||||||
|
s->quant_table[3][i]=
|
||||||
|
s->quant_table[4][i]=0;
|
||||||
|
}else{
|
||||||
|
s->quant_table[2][i]= 11*11*quant5 [i];
|
||||||
|
s->quant_table[3][i]= 5*11*11*quant5 [i];
|
||||||
|
s->quant_table[4][i]= 5*5*11*11*quant5 [i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(i=0; i<s->plane_count; i++){
|
for(i=0; i<s->plane_count; i++){
|
||||||
PlaneContext * const p= &s->plane[i];
|
PlaneContext * const p= &s->plane[i];
|
||||||
memcpy(p->quant_table, default_quant_table, sizeof(uint8_t)*256);
|
|
||||||
p->qdiff_count= DEFAULT_QDIFF_COUNT;
|
if(avctx->context_model==0){
|
||||||
|
p->context_count= (11*11*11+1)/2;
|
||||||
#if 1
|
}else{
|
||||||
p->context_count= 256;
|
p->context_count= (11*11*5*5*5+1)/2;
|
||||||
p->state= av_malloc(CONTEXT_SIZE*p->context_count*sizeof(uint8_t));
|
}
|
||||||
#else
|
|
||||||
p->context_count= 16*16*128 /*5*5*5*/;
|
if(s->ac){
|
||||||
p->state= av_malloc(CONTEXT_SIZE*p->context_count*sizeof(uint8_t));
|
if(!p->state) p->state= av_malloc(CONTEXT_SIZE*p->context_count*sizeof(uint8_t));
|
||||||
#endif
|
}else{
|
||||||
|
if(!p->vlc_state) p->vlc_state= av_malloc(p->context_count*sizeof(VlcState));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
avctx->coded_frame= &s->picture;
|
avctx->coded_frame= &s->picture;
|
||||||
@ -362,8 +547,15 @@ static void clear_state(FFV1Context *f){
|
|||||||
p->interlace_bit_state[1]= 0;
|
p->interlace_bit_state[1]= 0;
|
||||||
|
|
||||||
for(j=0; j<p->context_count; j++){
|
for(j=0; j<p->context_count; j++){
|
||||||
memset(p->state[j], 0, sizeof(uint8_t)*CONTEXT_SIZE);
|
if(f->ac){
|
||||||
p->state[j][7] = 2*62;
|
memset(p->state[j], 0, sizeof(uint8_t)*CONTEXT_SIZE);
|
||||||
|
p->state[j][7] = 2*62;
|
||||||
|
}else{
|
||||||
|
p->vlc_state[j].drift= 0;
|
||||||
|
p->vlc_state[j].error_sum= 4; //FFMAX((RANGE + 32)/64, 2);
|
||||||
|
p->vlc_state[j].bias= 0;
|
||||||
|
p->vlc_state[j].count= 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -375,6 +567,7 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size,
|
|||||||
const int width= f->width;
|
const int width= f->width;
|
||||||
const int height= f->height;
|
const int height= f->height;
|
||||||
AVFrame * const p= &f->picture;
|
AVFrame * const p= &f->picture;
|
||||||
|
int used_count= 0;
|
||||||
|
|
||||||
if(avctx->strict_std_compliance >= 0){
|
if(avctx->strict_std_compliance >= 0){
|
||||||
printf("this codec is under development, files encoded with it wont be decodeable with future versions!!!\n"
|
printf("this codec is under development, files encoded with it wont be decodeable with future versions!!!\n"
|
||||||
@ -398,6 +591,12 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size,
|
|||||||
p->key_frame= 0;
|
p->key_frame= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!f->ac){
|
||||||
|
used_count += put_cabac_terminate(c, 1);
|
||||||
|
//printf("pos=%d\n", used_count);
|
||||||
|
init_put_bits(&f->pb, buf + used_count, buf_size - used_count, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if(1){
|
if(1){
|
||||||
const int chroma_width = -((-width )>>f->chroma_h_shift);
|
const int chroma_width = -((-width )>>f->chroma_h_shift);
|
||||||
const int chroma_height= -((-height)>>f->chroma_v_shift);
|
const int chroma_height= -((-height)>>f->chroma_v_shift);
|
||||||
@ -411,7 +610,12 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size,
|
|||||||
|
|
||||||
f->picture_number++;
|
f->picture_number++;
|
||||||
|
|
||||||
return put_cabac_terminate(c, 1);
|
if(f->ac){
|
||||||
|
return put_cabac_terminate(c, 1);
|
||||||
|
}else{
|
||||||
|
flush_put_bits(&f->pb); //nicer padding FIXME
|
||||||
|
return used_count + (get_bit_count(&f->pb)+7)/8;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void common_end(FFV1Context *s){
|
static void common_end(FFV1Context *s){
|
||||||
@ -439,67 +643,109 @@ static void decode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride,
|
|||||||
int x,y;
|
int x,y;
|
||||||
uint8_t pred_diff_buffer[4][w+6];
|
uint8_t pred_diff_buffer[4][w+6];
|
||||||
uint8_t *pred_diff[4]= {pred_diff_buffer[0]+3, pred_diff_buffer[1]+3, pred_diff_buffer[2]+3, pred_diff_buffer[3]+3};
|
uint8_t *pred_diff[4]= {pred_diff_buffer[0]+3, pred_diff_buffer[1]+3, pred_diff_buffer[2]+3, pred_diff_buffer[3]+3};
|
||||||
// uint8_t temp_buf[3*w], *temp= temp_buf + 3*w;
|
int run_index=0;
|
||||||
|
|
||||||
memset(pred_diff_buffer, 0, sizeof(pred_diff_buffer));
|
memset(pred_diff_buffer, 0, sizeof(pred_diff_buffer));
|
||||||
|
|
||||||
for(y=0; y<h; y++){
|
for(y=0; y<h; y++){
|
||||||
uint8_t *temp= pred_diff[0]; //FIXME try a normal buffer
|
uint8_t *temp= pred_diff[0]; //FIXME try a normal buffer
|
||||||
|
int run_count=0;
|
||||||
|
int run_mode=0;
|
||||||
|
|
||||||
pred_diff[0]= pred_diff[1];
|
pred_diff[0]= pred_diff[1];
|
||||||
pred_diff[1]= pred_diff[2];
|
pred_diff[1]= pred_diff[2];
|
||||||
pred_diff[2]= pred_diff[3];
|
pred_diff[2]= pred_diff[3];
|
||||||
pred_diff[3]= temp;
|
pred_diff[3]= temp;
|
||||||
|
|
||||||
|
pred_diff[3][-1]= pred_diff[2][0 ];
|
||||||
|
pred_diff[2][ w]= pred_diff[2][w-1];
|
||||||
|
|
||||||
for(x=0; x<w; x++){
|
for(x=0; x<w; x++){
|
||||||
uint8_t *temp_src= src + x + stride*y;
|
uint8_t *temp_src= src + x + stride*y;
|
||||||
int diff, context, qdiff;
|
int diff, context, sign;
|
||||||
|
|
||||||
if(p->context_count == 256)
|
context= get_context(s, pred_diff[3] + x, pred_diff[2] + x, pred_diff[1] + x);
|
||||||
context= pred_diff[3+0][x-1] + 16*pred_diff[3-1][x+0];
|
if(context < 0){
|
||||||
else
|
context= -context;
|
||||||
context= pred_diff[3+0][x-1] + 16*pred_diff[3-1][x+0]
|
sign=1;
|
||||||
+ 16*16*to5[pred_diff[3-1][x+1]] + 16*16*5*to5[pred_diff[3-0][x-2]] + 16*16*5*5*to5[pred_diff[3-2][x+0]];
|
}else
|
||||||
|
sign=0;
|
||||||
|
|
||||||
|
|
||||||
diff= get_symbol(c, p->state[context], 1);
|
if(s->ac)
|
||||||
|
diff= get_symbol(c, p->state[context], 1);
|
||||||
|
else{
|
||||||
|
if(context == 0 && run_mode==0) run_mode=1;
|
||||||
|
|
||||||
|
if(run_mode){
|
||||||
|
if(run_count==0 && run_mode==1){
|
||||||
|
if(get_bits1(&s->gb)){
|
||||||
|
run_count = 1<<log2_run[run_index];
|
||||||
|
if(x + run_count <= w) run_index++;
|
||||||
|
}else{
|
||||||
|
if(log2_run[run_index]) run_count = get_bits(&s->gb, log2_run[run_index]);
|
||||||
|
else run_count=0;
|
||||||
|
if(run_index) run_index--;
|
||||||
|
run_mode=2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
run_count--;
|
||||||
|
if(run_count < 0){
|
||||||
|
run_mode=0;
|
||||||
|
run_count=0;
|
||||||
|
diff= get_vlc_symbol(&s->gb, &p->vlc_state[context]);
|
||||||
|
if(diff>=0) diff++;
|
||||||
|
}else
|
||||||
|
diff=0;
|
||||||
|
}else
|
||||||
|
diff= get_vlc_symbol(&s->gb, &p->vlc_state[context]);
|
||||||
|
|
||||||
|
// printf("count:%d index:%d, mode:%d, x:%d y:%d pos:%d\n", run_count, run_index, run_mode, x, y, get_bits_count(&s->gb));
|
||||||
|
}
|
||||||
|
|
||||||
temp_src[0] = predict(s, temp_src, stride, x, y) + diff;
|
if(sign) diff= (int8_t)(-diff); //FIXME remove cast
|
||||||
|
|
||||||
|
pred_diff[3][x]=
|
||||||
|
temp_src[0] = predict(pred_diff[3] + x, pred_diff[2] + x) + diff;
|
||||||
|
|
||||||
assert(diff>= -128 && diff <= 127);
|
assert(diff>= -128 && diff <= 127);
|
||||||
|
|
||||||
qdiff= p->quant_table[128+diff];
|
|
||||||
|
|
||||||
pred_diff[3][x]= qdiff;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_quant_table(CABACContext *c, uint8_t *quant_table){
|
static int read_quant_table(CABACContext *c, int16_t *quant_table, int scale){
|
||||||
int v;
|
int v;
|
||||||
int i=0;
|
int i=0;
|
||||||
uint8_t state[CONTEXT_SIZE]={0};
|
uint8_t state[CONTEXT_SIZE]={0};
|
||||||
|
|
||||||
for(v=0; i<256 ; v++){
|
for(v=0; i<128 ; v++){
|
||||||
int len= get_symbol(c, state, 0) + 1;
|
int len= get_symbol(c, state, 0) + 1;
|
||||||
|
|
||||||
if(len + i > 256) return -1;
|
if(len + i > 128) return -1;
|
||||||
|
|
||||||
while(len--){
|
while(len--){
|
||||||
quant_table[i++] = v;
|
quant_table[i] = scale*v;
|
||||||
|
i++;
|
||||||
//printf("%2d ",v);
|
//printf("%2d ",v);
|
||||||
//if(i%16==0) printf("\n");
|
//if(i%16==0) printf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(i=1; i<128; i++){
|
||||||
|
quant_table[256-i]= -quant_table[i];
|
||||||
|
}
|
||||||
|
quant_table[128]= -quant_table[127];
|
||||||
|
|
||||||
return v;
|
return 2*v - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_header(FFV1Context *f){
|
static int read_header(FFV1Context *f){
|
||||||
uint8_t state[CONTEXT_SIZE]={0};
|
uint8_t state[CONTEXT_SIZE]={0};
|
||||||
int i;
|
int i, context_count;
|
||||||
CABACContext * const c= &f->c;
|
CABACContext * const c= &f->c;
|
||||||
|
|
||||||
f->version= get_symbol(c, state, 0);
|
f->version= get_symbol(c, state, 0);
|
||||||
|
f->ac= f->avctx->coder_type= get_symbol(c, state, 0);
|
||||||
get_symbol(c, state, 0); //YUV cs type
|
get_symbol(c, state, 0); //YUV cs type
|
||||||
get_cabac(c, state); //no chroma = false
|
get_cabac(c, state); //no chroma = false
|
||||||
f->chroma_h_shift= get_symbol(c, state, 0);
|
f->chroma_h_shift= get_symbol(c, state, 0);
|
||||||
@ -507,15 +753,22 @@ static int read_header(FFV1Context *f){
|
|||||||
get_cabac(c, state); //transparency plane
|
get_cabac(c, state); //transparency plane
|
||||||
f->plane_count= 3;
|
f->plane_count= 3;
|
||||||
|
|
||||||
|
context_count=1;
|
||||||
|
for(i=0; i<5; i++){
|
||||||
|
context_count*= read_quant_table(c, f->quant_table[i], context_count);
|
||||||
|
}
|
||||||
|
context_count= (context_count+1)/2;
|
||||||
|
|
||||||
for(i=0; i<f->plane_count; i++){
|
for(i=0; i<f->plane_count; i++){
|
||||||
PlaneContext * const p= &f->plane[i];
|
PlaneContext * const p= &f->plane[i];
|
||||||
|
|
||||||
p->context_count= 1<<get_symbol(c, state, 0);
|
p->context_count= context_count;
|
||||||
p->qdiff_count= read_quant_table(c, p->quant_table);
|
|
||||||
if(p->qdiff_count < 0) return -1;
|
if(f->ac){
|
||||||
|
if(!p->state) p->state= av_malloc(CONTEXT_SIZE*p->context_count*sizeof(uint8_t));
|
||||||
if(!p->state)
|
}else{
|
||||||
p->state= av_malloc(CONTEXT_SIZE*p->context_count*sizeof(uint8_t));
|
if(!p->vlc_state) p->vlc_state= av_malloc(p->context_count*sizeof(VlcState));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -523,7 +776,7 @@ static int read_header(FFV1Context *f){
|
|||||||
|
|
||||||
static int decode_init(AVCodecContext *avctx)
|
static int decode_init(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
FFV1Context *s = avctx->priv_data;
|
// FFV1Context *s = avctx->priv_data;
|
||||||
|
|
||||||
common_init(avctx);
|
common_init(avctx);
|
||||||
|
|
||||||
@ -587,6 +840,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
|
|||||||
if(avctx->debug&FF_DEBUG_PICT_INFO)
|
if(avctx->debug&FF_DEBUG_PICT_INFO)
|
||||||
printf("keyframe:%d\n", p->key_frame);
|
printf("keyframe:%d\n", p->key_frame);
|
||||||
|
|
||||||
|
if(!f->ac){
|
||||||
|
bytes_read = get_cabac_terminate(c);
|
||||||
|
if(bytes_read ==0) printf("error at end of AC stream\n");
|
||||||
|
//printf("pos=%d\n", bytes_read);
|
||||||
|
init_get_bits(&f->gb, buf + bytes_read, buf_size - bytes_read);
|
||||||
|
}
|
||||||
|
|
||||||
if(1){
|
if(1){
|
||||||
const int chroma_width = -((-width )>>f->chroma_h_shift);
|
const int chroma_width = -((-width )>>f->chroma_h_shift);
|
||||||
@ -607,9 +866,13 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
|
|||||||
|
|
||||||
*data_size = sizeof(AVFrame);
|
*data_size = sizeof(AVFrame);
|
||||||
|
|
||||||
bytes_read= get_cabac_terminate(c);
|
if(f->ac){
|
||||||
if(bytes_read ==0) printf("error at end of frame\n");
|
bytes_read= get_cabac_terminate(c);
|
||||||
|
if(bytes_read ==0) printf("error at end of frame\n");
|
||||||
|
}else{
|
||||||
|
bytes_read+= (get_bits_count(&f->gb)+7)/8;
|
||||||
|
}
|
||||||
|
|
||||||
return bytes_read;
|
return bytes_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,6 +178,37 @@ static inline int svq3_get_se_golomb(GetBitContext *gb){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read unsigned golomb rice code.
|
||||||
|
*/
|
||||||
|
static inline int get_ur_golomb(GetBitContext *gb, int k, int limit, int esc_len){
|
||||||
|
unsigned int buf;
|
||||||
|
int log;
|
||||||
|
|
||||||
|
OPEN_READER(re, gb);
|
||||||
|
UPDATE_CACHE(re, gb);
|
||||||
|
buf=GET_CACHE(re, gb);
|
||||||
|
|
||||||
|
log= av_log2(buf);
|
||||||
|
//printf("buf:%X log:%d\n", buf, log);
|
||||||
|
if(log > 31-limit){
|
||||||
|
buf >>= log - k;
|
||||||
|
buf += (30-log)<<k;
|
||||||
|
LAST_SKIP_BITS(re, gb, 32 + k - log);
|
||||||
|
CLOSE_READER(re, gb);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}else if(log == 31-limit){
|
||||||
|
buf >>= log - esc_len;
|
||||||
|
buf -= 1<<esc_len;
|
||||||
|
LAST_SKIP_BITS(re, gb, esc_len + limit + 1);
|
||||||
|
CLOSE_READER(re, gb);
|
||||||
|
|
||||||
|
return buf + 1;
|
||||||
|
}else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef TRACE
|
#ifdef TRACE
|
||||||
|
|
||||||
static inline int get_ue(GetBitContext *s, char *file, char *func, int line){
|
static inline int get_ue(GetBitContext *s, char *file, char *func, int line){
|
||||||
@ -279,3 +310,22 @@ static inline void set_se_golomb(PutBitContext *pb, int i){
|
|||||||
#endif
|
#endif
|
||||||
set_ue_golomb(pb, i);
|
set_ue_golomb(pb, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* write unsigned golomb rice code.
|
||||||
|
*/
|
||||||
|
static inline void set_ur_golomb(PutBitContext *pb, int i, int k, int limit, int esc_len){
|
||||||
|
int e;
|
||||||
|
|
||||||
|
assert(i>=0);
|
||||||
|
|
||||||
|
e= i>>k;
|
||||||
|
if(e<limit){
|
||||||
|
put_bits(pb, e + k + 1, (1<<k) + (i&((1<<k)-1)));
|
||||||
|
}else{
|
||||||
|
// printf("set %08X, %d\n", (1<<esc_len) + i - 1, limit + esc_len + 1);
|
||||||
|
put_bits(pb, limit + esc_len + 1, (1<<esc_len) + i - 1);
|
||||||
|
// put_bits(pb, 1, limit + 1);
|
||||||
|
// put_bits(pb, i - 1, esc_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user