summaryrefslogtreecommitdiffstats
path: root/k9vamps/k9requant.h
blob: 443c3ff08bd7517e6d589057e810bbbb379cf662 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
//
// C++ Interface: k9requant
//
// Description: A transcription from m2vrequantizer in C++
//
//
// Author: Jean-Michel PETIT <k9copy@free.fr>, (C) 2006
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef K9REQUANT_H
#define K9REQUANT_H
#include "k9common.h"


#include <tqthread.h>
#include <tqmutex.h>
#include <tqwaitcondition.h>


// user defined types
//typedef unsigned int		uint;
typedef unsigned char		uint8;
typedef unsigned short		uint16;
typedef unsigned int		uint32;
typedef unsigned long long	uint64;

typedef char				int8;
typedef short				int16;
typedef int					int32;
typedef long long			int64;


typedef signed int			sint;
typedef signed char			sint8;
typedef signed short		sint16;
typedef signed int			sint32;
#ifdef WIN
typedef __int64				sint64;
#else
typedef signed long long	sint64;
#endif

#define BITS_IN_BUF (8)

// block data
typedef struct {
    uint8 run;
    short level;
}
RunLevel;
/*
#define BUF_SIZE (16*1024*1024)
#define MIN_READ (4*1024*1024)
#define MIN_WRITE (8*1024*1024)
#define MAX_READ (10*1024*1024)
*/


// keep gcc happy
#define WRITE      \
  orbuf  = orbuf;  \
  mloka1 = mloka1; \
  mloka2 = mloka2; \
  eof    = eof;

// meaningless
#define MIN_WRITE 0
#define MAX_READ  0
#define MOV_READ

// this is where we switch threads
#define LOCK(x)   if (! lock(x)) {rqt_run=false;return;}

#define COPY(x)           \
  tc_memcpy (wbuf, cbuf, x); \
  cbuf += x;              \
  wbuf += x;

#define SEEKR(x) cbuf += x;

#define SEEKW(x) wbuf += x;


/**
	@author Jean-Michel PETIT <k9copy@free.fr>
*/
class k9requant : public TQThread {
private:

    int		inbitcnt, outbitcnt;
    uint32	inbitbuf, outbitbuf;
    uint64	inbytecnt, outbytecnt;
    float	fact_x;
    int		mloka1, mloka2, eof;

    int64 orim2vsize;
    int64 bytediff;
    double stress_factor;	//	from 0.0 to 1.0

    int i_factor;
    int p_factor;
    int b_factor;
    double i_min_stress;
    double p_min_stress;
    double b_min_stress;

    short quant_table_id_data[4096];
    short *quant_table_id ;

#ifdef USE_FD

    FILE *ifd, *ofd;
#endif

#ifdef STAT

    uint64 ori_i, ori_p, ori_b;
    uint64 new_i, new_p, new_b;
    uint64 cnt_i, cnt_p, cnt_b;
    uint64 cnt_p_i, cnt_p_ni;
    uint64 cnt_b_i, cnt_b_ni;
#endif

#ifdef DEMO

    int gopCount;
#endif

#ifdef LOG_RATE_CONTROL

    FILE* LOG_FILE;
#endif

#ifdef CHANGE_BRIGHTNESS

    int delta_bright;
    int dc_reset;
    int old_dc_pred, new_dc_pred;
#endif

    // mpeg2 state
    // seq header
    uint horizontal_size_value;
    uint vertical_size_value;

    // pic header
    uint picture_coding_type;

    // pic code ext
    uint f_code[2][2];
    uint intra_dc_precision;
    uint picture_structure;
    uint frame_pred_frame_dct;
    uint concealment_motion_vectors;
    uint q_scale_type;
    uint intra_vlc_format;
    uint alternate_scan;

    // error
    int validPicHeader;
    int validSeqHeader;
    int validExtHeader;
    int sliceError;

    // slice or mb
    uint quantizer_scale;
    uint new_quantizer_scale;
    uint last_coded_scale;
    int  h_offset, v_offset;
    int  mb_skip, mb_add;
    int  mb_out;

    int  mb_sav_run, mb_sav_lev, mb_sav_c;
    short *curTable;

    RunLevel block[6][65]; // terminated by level = 0, so we need 64+1
private:
    void putbits(uint val, int n);
    void Refill_bits(void);

    void Flush_Bits(uint n);
    uint Show_Bits(uint n);
    uint Get_Bits(uint n);

    uint Copy_Bits(uint n);
    void flush_read_buffer();
    void flush_write_buffer();
    int scale_quant(double quant );
    int increment_quant(int quant);
    int intmax( int x, int y );

    int intmin( int x, int y );
    void putmbtype(int mb_type);

    int getNewQuant(int curQuant, int intra);

    int isNotEmpty(RunLevel *blk);


    // return != 0 if error
    int putAC(int run, int signed_level, int vlcformat);
    // return != 0 if error
    int putACfirst(int run, int val);
    void putnonintrablk(RunLevel *blk);
    void putcbp(int cbp);

    int get_macroblock_modes ();
    int get_quantizer_scale ();
    void get_motion_delta (const int f_code);
    void get_dmv ();
    int get_coded_block_pattern ();
    int get_luma_dc_dct_diff ();
    int get_chroma_dc_dct_diff ();
    void get_intra_block_B14 ();
    void get_intra_block_B15 ();
    int get_non_intra_block_rq (RunLevel *blk);
    int get_non_intra_block_sav (RunLevel *blk, int cc);

#ifdef P_FRAME_NON_INTRA_DROP

    int get_non_intra_block_drop (RunLevel *blk, int cc);
#endif

#ifdef CHANGE_BRIGHTNESS

    void putDC(const sVLCtable *tab, int val);
#endif

    void slice_intra_DCT (const int cc);
    void slice_non_intra_DCT (int cur_block);
    void motion_fr_frame ( uint f_code[2] );
    void motion_fr_field ( uint f_code[2] );
    void motion_fr_dmv ( uint f_code[2] );
    void motion_fr_conceal ( );
    void motion_fi_field ( uint f_code[2] );
    void motion_fi_16x8 ( uint f_code[2] );
    void motion_fi_dmv ( uint f_code[2] );
    void motion_fi_conceal ();
    void putmbdata(int macroblock_modes);
    void put_quantiser(int quantiser);
    void putaddrinc(int addrinc);
    int slice_init (int code);
    void mpeg2_slice ( const int code );
    void initRequant();
    bool lock(int64 x);

protected:
    void run ();

public:
    uint8	*cbuf, *rbuf, *wbuf, *orbuf, *owbuf;
    // global data for inter thread com
    float           rqt_fact;
    uint32_t     rqt_rcnt;
    uint32_t     rqt_wcnt;
    uint64_t     rqt_inbytes;
    uint64_t     rqt_outbytes;
    uint64_t     rqt_visize;
    uchar          *rqt_rptr;
    uchar          *rqt_wptr;
    TQWaitCondition condr;
    TQWaitCondition  condw;
    TQMutex mutr;
    TQMutex mutw;
    bool 		rqt_stop;
    bool 		rqt_run;


public:
    k9requant();
    void initvar();
};



#endif