summaryrefslogtreecommitdiff
path: root/src/libffmpeg/libavcodec/mpeg12.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libffmpeg/libavcodec/mpeg12.c')
-rw-r--r--src/libffmpeg/libavcodec/mpeg12.c91
1 files changed, 70 insertions, 21 deletions
diff --git a/src/libffmpeg/libavcodec/mpeg12.c b/src/libffmpeg/libavcodec/mpeg12.c
index 758124eea..41bf524e4 100644
--- a/src/libffmpeg/libavcodec/mpeg12.c
+++ b/src/libffmpeg/libavcodec/mpeg12.c
@@ -33,6 +33,8 @@
#define EXT_START_CODE 0x000001b5
#define USER_START_CODE 0x000001b2
+#define ABS(a) ((a)<0 ? -(a) : (a))
+
static void mpeg1_encode_block(MpegEncContext *s,
DCTELEM *block,
int component);
@@ -52,7 +54,8 @@ static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred);
static void put_header(MpegEncContext *s, int header)
{
align_put_bits(&s->pb);
- put_bits(&s->pb, 32, header);
+ put_bits(&s->pb, 16, header>>16);
+ put_bits(&s->pb, 16, header&0xFFFF);
}
/* put sequence header if needed */
@@ -103,7 +106,7 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s)
/* time code : we must convert from the real frame rate to a
fake mpeg frame rate in case of low frame rate */
fps = frame_rate_tab[s->frame_rate_index];
- time_code = s->fake_picture_number * FRAME_RATE_BASE;
+ time_code = (INT64)s->fake_picture_number * FRAME_RATE_BASE;
s->gop_picture_number = s->fake_picture_number;
put_bits(&s->pb, 5, (UINT32)((time_code / (fps * 3600)) % 24));
put_bits(&s->pb, 6, (UINT32)((time_code / (fps * 60)) % 60));
@@ -118,7 +121,7 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s)
/* 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 = ((s->picture_number * fps) / s->frame_rate) - 1;
+ n = (((INT64)s->picture_number * fps) / s->frame_rate) - 1;
while (s->fake_picture_number < n) {
mpeg1_skip_picture(s, s->fake_picture_number -
s->gop_picture_number);
@@ -183,11 +186,38 @@ static void mpeg1_skip_picture(MpegEncContext *s, int pict_num)
void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number)
{
- static int done;
+ static int done=0;
if (!done) {
+ int i;
done = 1;
init_rl(&rl_mpeg1);
+
+ for(i=0; i<64; i++)
+ {
+ mpeg1_max_level[0][i]= rl_mpeg1.max_level[0][i];
+ mpeg1_index_run[0][i]= rl_mpeg1.index_run[0][i];
+ }
+
+ /* build unified dc encoding tables */
+ for(i=-255; i<256; i++)
+ {
+ int adiff, index;
+ int bits, code;
+ int diff=i;
+
+ adiff = ABS(diff);
+ if(diff<0) diff--;
+ index = vlc_dc_table[adiff];
+
+ bits= vlc_dc_lum_bits[index] + index;
+ code= (vlc_dc_lum_code[index]<<index) + (diff & ((1 << index) - 1));
+ mpeg1_lum_dc_uni[i+255]= bits + (code<<8);
+
+ bits= vlc_dc_chroma_bits[index] + index;
+ code= (vlc_dc_chroma_code[index]<<index) + (diff & ((1 << index) - 1));
+ mpeg1_chr_dc_uni[i+255]= bits + (code<<8);
+ }
}
mpeg1_encode_sequence_header(s);
@@ -325,19 +355,16 @@ static void mpeg1_encode_motion(MpegEncContext *s, int val)
static inline void encode_dc(MpegEncContext *s, int diff, int component)
{
- int adiff, index;
-
- adiff = abs(diff);
- index = vlc_dc_table[adiff];
if (component == 0) {
- put_bits(&s->pb, vlc_dc_lum_bits[index], vlc_dc_lum_code[index]);
+ put_bits(
+ &s->pb,
+ mpeg1_lum_dc_uni[diff+255]&0xFF,
+ mpeg1_lum_dc_uni[diff+255]>>8);
} else {
- put_bits(&s->pb, vlc_dc_chroma_bits[index], vlc_dc_chroma_code[index]);
- }
- if (diff > 0) {
- put_bits(&s->pb, index, (diff & ((1 << index) - 1)));
- } else if (diff < 0) {
- put_bits(&s->pb, index, ((diff - 1) & ((1 << index) - 1)));
+ put_bits(
+ &s->pb,
+ mpeg1_chr_dc_uni[diff+255]&0xFF,
+ mpeg1_chr_dc_uni[diff+255]>>8);
}
}
@@ -347,7 +374,7 @@ static void mpeg1_encode_block(MpegEncContext *s,
{
int alevel, level, last_non_zero, dc, diff, i, j, run, last_index, sign;
int code, component;
- RLTable *rl = &rl_mpeg1;
+// RLTable *rl = &rl_mpeg1;
last_index = s->block_last_index[n];
@@ -376,6 +403,7 @@ static void mpeg1_encode_block(MpegEncContext *s,
/* now quantify & encode AC coefs */
last_non_zero = i - 1;
+
for(;i<=last_index;i++) {
j = zigzag_direct[i];
level = block[j];
@@ -387,17 +415,38 @@ static void mpeg1_encode_block(MpegEncContext *s,
/* encode using VLC */
if (level != 0) {
run = i - last_non_zero - 1;
+#ifdef ARCH_X86
+ asm volatile(
+ "movl %2, %1 \n\t"
+ "movl %1, %0 \n\t"
+ "addl %1, %1 \n\t"
+ "sbbl %1, %1 \n\t"
+ "xorl %1, %0 \n\t"
+ "subl %1, %0 \n\t"
+ "andl $1, %1 \n\t"
+ : "=&r" (alevel), "=&r" (sign)
+ : "g" (level)
+ );
+#else
sign = 0;
alevel = level;
if (alevel < 0) {
sign = 1;
alevel = -alevel;
}
- code = get_rl_index(rl, 0, run, alevel);
- put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]);
- if (code != rl->n) {
- put_bits(&s->pb, 1, sign);
+#endif
+// code = get_rl_index(rl, 0, run, alevel);
+ if (alevel > mpeg1_max_level[0][run])
+ code= 111; /*rl->n*/
+ else
+ code= mpeg1_index_run[0][run] + alevel - 1;
+
+ if (code < 111 /* rl->n */) {
+ /* store the vlc & sign at once */
+ put_bits(&s->pb, mpeg1_vlc[code][1]+1, (mpeg1_vlc[code][0]<<1) + sign);
} else {
+ /* escape seems to be pretty rare <5% so i dont optimize it */
+ put_bits(&s->pb, mpeg1_vlc[111/*rl->n*/][1], mpeg1_vlc[111/*rl->n*/][0]);
/* escape: only clip in this case */
put_bits(&s->pb, 6, run);
if (alevel < 128) {
@@ -899,7 +948,7 @@ static int mpeg1_decode_block(MpegEncContext *s,
block[j] = level;
i++;
}
- s->block_last_index[n] = i;
+ s->block_last_index[n] = i-1;
return 0;
}