📄 mpegvideo.c
字号:
/*
* The simplest mpeg encoder (well, it was the simplest!)
* Copyright (c) 2000,2001 Gerard Lantau.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "avcodec.h"
#include "dsputil.h"
#include "mpegvideo.h"
#include <winsock.h>
#define EDGE_WIDTH 16
void j_rev_dct_ARM (DCTELEM *data);
const UINT8 zigzag_direct[64] = {
0, 1, 8, 16, 9, 2, 3, 10,
17, 24, 32, 25, 18, 11, 4, 5,
12, 19, 26, 33, 40, 48, 41, 34,
27, 20, 13, 6, 7, 14, 21, 28,
35, 42, 49, 56, 57, 50, 43, 36,
29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46,
53, 60, 61, 54, 47, 55, 62, 63
};
const UINT8 default_intra_matrix[64] = {
8, 16, 19, 22, 26, 27, 29, 34,
16, 16, 22, 24, 27, 29, 34, 37,
19, 22, 26, 27, 29, 34, 34, 38,
22, 22, 26, 27, 29, 34, 37, 40,
22, 26, 27, 29, 32, 35, 40, 48,
26, 27, 29, 32, 35, 40, 48, 58,
26, 27, 29, 34, 38, 46, 56, 69,
27, 29, 35, 38, 46, 56, 69, 83
};
const UINT8 default_non_intra_matrix[64] = {
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
};
int get_rl_index(const RLTable *rl, int last, int run, int level)
{
int index;
index = rl->index_run[last][run];
if (index >= rl->n)
return rl->n;
if (level > rl->max_level[last][run])
return rl->n;
return index + level - 1;
}
/* enable all paranoid tests for rounding, overflows, etc... */
//#define PARANOID
//#define DEBUG
/* for jpeg fast DCT */
#define CONST_BITS 14
static const unsigned short aanscales[64] = {
/* precomputed values scaled up by 14 bits */
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
};
static UINT8 h263_chroma_roundtab[16] = {
0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
};
static void rate_control_init(MpegEncContext *s);
static int rate_estimate_qscale(MpegEncContext *s);
static void dct_unquantize(MpegEncContext *s, DCTELEM *block, int n, int qscale);
/* default motion estimation */
int motion_estimation_method = ME_LOG;
/* XXX: should use variable shift ? */
#define QMAT_SHIFT_MMX 19
#define QMAT_SHIFT 25
#define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */
#define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */
#define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */
#define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */
#define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */
#define W7 565 /* 2048*sqrt(2)*cos(7*pi/16) */
#define W1_minus_W7 2276
#define W1_plus_W7 3406
#define W3_minus_W5 799
#define W3_plus_W5 4017
#define W2_minus_W6 1568
#define W2_plus_W6 3784
/*
* Perform the inverse DCT on one block of coefficients.
*/
#if (defined(MIPS)&&(_WIN32_WCE>=300))
//#ifdef MIPSX
//#ifdef GAPI
//it finally uses 64bits MIPSIII instructions!!
static void clearblock (DCTELEM *psblock)
{
__asm ("addi $2,$0,2;"
"comienzo:sdr $0,0($4);"
"sdr $0,8($4);"
"sdr $0,16($4);"
"sdr $0,24($4);"
"sdr $0,32($4);"
"sdr $0,40($4);"
"sdr $0,48($4);"
"sdr $0,56($4);"
"addi $4,$4,64;"
"addi $2,$2,-1;"
"bgtz $2,comienzo;",psblock);
}
/*#else
static void clearblock (idct_block_t *psblock)
{
__asm ("addi $2,$0,2;"
"comienzo:sw $0,0($4);"
"sw $0,4($4);"
"sw $0,8($4);"
"sw $0,12($4);"
"sw $0,16($4);"
"sw $0,20($4);"
"sw $0,24($4);"
"sw $0,28($4);"
"sw $0,32($4);"
"sw $0,36($4);"
"sw $0,40($4);"
"sw $0,44($4);"
"sw $0,48($4);"
"sw $0,52($4);"
"sw $0,56($4);"
"sw $0,60($4);"
"addi $4,$4,64;"
"addi $2,$2,-1;"
"bgtz $2,comienzo;",psblock);
}
#endif*/
#else
static __inline void clearblock (DCTELEM *psblock)
{
int i;
__int64* t=(__int64*) psblock;
for (i=16; i!=0;i--)
{
psblock++[0]=0;
}
}
#endif
//#endif
#if (defined(MIPS)&&(_WIN32_WCE>=300))
//Inverse Discrete Cosinus Transform(IDCT)
//MIPS ASM - MACC VERSION
//v0.1 => first working version. No optimizations at all
//v0.2a => it磗 macc optimized.
//v0.3 => 8 bits destination buffer-bypass buffer conversions.
//v0.4 => Merged both idctrows functions of v0.3
static void idctrow_special (DCTELEM *blk, UINT8 *destU8,int flag )
{
__asm("add $24,$5,$0;"
"add $25,$6,$0;"
"lh $5,0($4);" //x0
"lh $9,2($4);" //x4
"lh $8,4($4);" //x3
"lh $12,6($4);" //x7
"lh $6,8($4);" //x1
"lh $11,10($4);" //x6
"lh $7,12($4);" //x2
"lh $10,14($4);" //x5
"sll $6,$6,8;" // x1<<
"or $2,$7,$6;"
"or $2,$2,$8;"
"or $2,$2,$9;"
"or $2,$2,$10;"
"or $2,$2,$11;"
"or $2,$2,$12;" //shortcut
"bne $2,$0,idct_row_a;" //if some values aren磘 0, when can磘 shorcut
"addi $5,$5,32;"
"sra $5,$5,6;"
"bne $25,$0,add_eq;"
"srl $15,$5,16;" //if less than 0, then 0
"srlv $5,$5,$15;"
"sll $15,$5,23;" //if bigger than 255:255
"sra $15,$15,31;"
"or $5,$5,$15;"
"andi $5,$5,0x00FF;"
"sll $14,$5,8;"
"or $15,$5,$14;"
"sll $14,$5,16;"
"or $15,$15,$14;"
"sll $14,$5,24;"
"or $5,$15,$14;"
"sw $5,0($24);" //guardamos x0
"sw $5,4($24);"
"jr $31;");
__asm( "add_eq:lbu $6,0($24);" //we load older values
"lbu $7,1($24);" //
"lbu $8,2($24);" //
"lbu $9,3($24);" //
"lbu $10,4($24);"//
"lbu $11,5($24);"//
"lbu $12,6($24);"//
"lbu $13,7($24);"//
"add $14,$5,$6;"
"srl $15,$14,16;" //if less than 0, then 0
"srlv $14,$14,$15;"
"sll $15,$14,23;" //if bigger than 255:255
"sra $15,$15,31;"
"or $14,$14,$15;"
"sb $14,0($24);" //and we save it
"add $14,$5,$7;" //we do the same with next ones
"srl $15,$14,16;"
"srlv $14,$14,$15;"
"sll $15,$14,23;"
"sra $15,$15,31;"
"or $14,$14,$15;"
"sb $14,1($24);"
"add $14,$5,$8;"
"srl $15,$14,16;"
"srlv $14,$14,$15;"
"sll $15,$14,23;"
"sra $15,$15,31;"
"or $14,$14,$15;"
"sb $14,2($24);"
"add $14,$5,$9;"
"srl $15,$14,16;"
"srlv $14,$14,$15;"
"sll $15,$14,23;"
"sra $15,$15,31;"
"or $14,$14,$15;"
"sb $14,3($24);"
);
__asm( "add $14,$5,$10;"
"srl $15,$14,16;"
"srlv $14,$14,$15;"
"sll $15,$14,23;"
"sra $15,$15,31;"
"or $14,$14,$15;"
"sb $14,4($24);"
"add $14,$5,$11;"
"srl $15,$14,16;"
"srlv $14,$14,$15;"
"sll $15,$14,23;"
"sra $15,$15,31;"
"or $14,$14,$15;"
"sb $14,5($24);"
"add $14,$5,$12;"
"srl $15,$14,16;"
"srlv $14,$14,$15;"
"sll $15,$14,23;"
"sra $15,$15,31;"
"or $14,$14,$15;"
"sb $14,6($24);"
"add $14,$5,$13;"
"srl $15,$14,16;"
"srlv $14,$14,$15;"
"sll $15,$14,23;"
"sra $15,$15,31;"
"or $14,$14,$15;"
"sb $14,7($24);"//and finish
"jr $31;",blk);
__asm ("idct_row_a:add $13,$9,$10;"//x8=x4+x5
"li $14,565;" //W7
"mult $14,$13;" //W7*x8
"li $15,2276;" //W1_minus_W7
"macc $0,$15,$9;" //x4=x(W1-W7)*x4+W7*8
"mflo $9;"
"sll $5,$5,8;" // x0<<8)
"mult $14,$13;" //W7*x8
"li $15,-3406;" //-W1_plus_W7
"macc $0,$15,$10;" //-((W1+W7)*x5)+W7*x8
"mflo $10;"
"li $14,2408;" //W3
"add $13,$11,$12;" // x6+x7
"mult $14,$13;" //W3*(x6+x7)
"li $15,-799;" //-W3_minus_W5
"macc $0,$15,$11;" //-((W3-W5)*x6)+W3*(x6+x7)
"mflo $11;"
"add $5,$5,8192;" //x0+=128
"mult $14,$13;"
"li $14,-4017;"
"macc $0,$12,$14;"
"mflo $12;"
);
__asm ( "add $13,$5,$6;"
"sub $5,$5,$6;" //x0 -=x1
"add $6,$7,$8;" //x1=(x2+x3)
"li $15,1108;" //W6
"mult $15,$6;" //W6*(x3+x2)
"li $14,-3784;" //-W2_plus_W6
"macc $0,$14,$7;" //x1+(-W2_plus_W6*x2)
"mflo $7;"
"mult $15,$6;" //W6*(x3+x2)
"li $14,1568;" //W2_minus_W6
"macc $0,$14,$8;" //W2_minus_W6*x3
"mflo $8;"
"addi $9,$9,4;"
"addi $11,$11,4;"
"addi $10,$10,4;"
"addi $12,$12,4;"
"sra $9,$9,3;"
"sra $10,$10,3;"
"sra $11,$11,3;"
"sra $12,$12,3;"
"add $6,$9,$11;" //x1=x4+x6
"sub $9,$9,$11;" //x4=x4-x6
"add $11,$10,$12;" //x6=x5+x7
"sub $10,$10,$12;" //x5=x5-x7
);
__asm ( "addi $7,$7,4;"
"addi $8,$8,4;"
"sra $7,$7,3;"
"sra $8,$8,3;"
"add $12,$13,$8;" //x7=x8+x3
"sub $13,$13,$8;" //x8-=x3
"add $8,$5,$7;" //x3=x0+x2
"sub $5,$5,$7;" //x0-=x2
"li $14,181;"
"add $7,$9,$10;" //x4+x5
"mult $14,$7;" //
"mflo $7;"
"addi $7,$7,128;"
"sra $7,$7,8;"
"sub $9,$9,$10;"
"mult $14,$9;"
"mflo $9;"
"addi $9,$9,128;"
"sra $9,$9,8;");
//Fourth Stage
__asm ( "bne $25,$0,add;"
"add $15,$12,$6;" //x7+x1
"sra $15,$15,14;"
"srl $14,$15,16;" //if less than 0, then 0
"srlv $15,$15,$14;" //
"sll $14,$15,23;" //if bigger than 255:255
"sra $14,$14,31;" //
"or $15,$15,$14;" //
"sb $15,0($24);"
"add $15,$7,$8;" //x3+x2
"sra $15,$15,14;"
"srl $14,$15,16;" //
"srlv $15,$15,$14;" //
"sll $14,$15,23;" //if bigger than 255:255
"sra $14,$14,31;" //
"or $15,$15,$14;" //
"sb $15,1($24);"
"add $15,$5,$9;" //x0+x4
"sra $15,$15,14;"
"srl $14,$15,16;" //
"srlv $15,$15,$14;" //
"sll $14,$15,23;" //if bigger than 255:255
"sra $14,$14,31;" //
"or $15,$15,$14;" //
"sb $15,2($24);"
"add $15,$13,$11;" //x8+x6
"sra $15,$15,14;"
"srl $14,$15,16;" //
"srlv $15,$15,$14;" //
"sll $14,$15,23;" //if bigger than 255:255
"sra $14,$14,31;" //
"or $15,$15,$14;" //
"sb $15,3($24);"
"sub $15,$13,$11;"
"sra $15,$15,14;"
"srl $14,$15,16;" //
"srlv $15,$15,$14;" //
"sll $14,$15,23;" //if bigger than 255:255
"sra $14,$14,31;" //
"or $15,$15,$14;" //
"sb $15,4($24);"
"sub $15,$5,$9;"
"sra $15,$15,14;"
"srl $14,$15,16;" //
"srlv $15,$15,$14;" //
"sll $14,$15,23;" //if bigger than 255:255
"sra $14,$14,31;" //
"or $15,$15,$14;" //
"sb $15,5($24);"
"sub $15,$8,$7;"
"sra $15,$15,14;"
"srl $14,$15,16;" //
"srlv $15,$15,$14;" //
"sll $14,$15,23;" //if bigger than 255:255
"sra $14,$14,31;" //
"or $15,$15,$14;" //
"sb $15,6($24);"
"sub $15,$12,$6;"
"sra $15,$15,14;"
"srl $14,$15,16;" //
"srlv $15,$15,$14;" //
"sll $14,$15,23;" //if bigger than 255:255
"sra $14,$14,31;" //
"or $15,$15,$14;" //
"sb $15,7($24);"
"jr $31;");
__asm ( "add:add $15,$12,$6;" //x7+x1
"lbu $2,0($24);"
"sra $15,$15,14;"
"add $15,$15,$2;"
"srl $14,$15,16;" //if less than 0, then 0
"srlv $15,$15,$14;" //
"sll $14,$15,23;" //if bigger than 255:255
"sra $14,$14,31;" //
"or $15,$15,$14;" //
"sb $15,0($24);"
"add $15,$7,$8;" //x3+x2
"lbu $2,1($24);"
"sra $15,$15,14;"
"add $15,$15,$2;"
"srl $14,$15,16;" //
"srlv $15,$15,$14;" //
"sll $14,$15,23;" //if bigger than 255:255
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -