summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2004-09-02 15:30:46 +0000
committerMichael Niedermayer <michaelni@gmx.at>2004-09-02 15:30:46 +0000
commit6fc5b059b84d93feb4749eb01318b2349b7e795b (patch)
tree402e6b54f1dad928b7b020bf7b868e06438c4ef1
parentbf0669aa8712842af354c99d572503f0fc66baaa (diff)
optional non spec compliant optimizations
Originally committed as revision 3429 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--ffplay.c3
-rw-r--r--libavcodec/avcodec.h2
-rw-r--r--libavcodec/mpeg12.c93
3 files changed, 87 insertions, 11 deletions
diff --git a/ffplay.c b/ffplay.c
index bfff450cdf..ff655f7868 100644
--- a/ffplay.c
+++ b/ffplay.c
@@ -170,6 +170,7 @@ static int debug_mv = 0;
static int step = 0;
static int thread_count = 1;
static int workaround_bugs = 1;
+static int fast = 0;
/* current context */
static int is_full_screen;
@@ -1172,6 +1173,7 @@ static int stream_component_open(VideoState *is, int stream_index)
enc->debug_mv = debug_mv;
enc->debug = debug;
enc->workaround_bugs = workaround_bugs;
+ if(fast) enc->flags2 |= CODEC_FLAG2_FAST;
if (!codec ||
avcodec_open(enc, codec) < 0)
return -1;
@@ -1829,6 +1831,7 @@ const OptionDef options[] = {
{ "debug", HAS_ARG | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
{ "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
{ "vismv", HAS_ARG | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
+ { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
#ifdef CONFIG_NETWORK
{ "rtp_tcp", OPT_EXPERT, {(void*)&opt_rtp_tcp}, "force RTP/TCP protocol usage", "" },
#endif
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index e2da0f85a2..76bc946f3a 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -283,6 +283,8 @@ extern int motion_estimation_method;
#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
+#define CODEC_FLAG2_FAST 0x00000001 ///< allow non spec compliant speedup tricks
+
/* Unsupported options :
* Syntax Arithmetic coding (SAC)
* Reference Picture Selection
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
index 1c8a6e2bfa..c31efad402 100644
--- a/libavcodec/mpeg12.c
+++ b/libavcodec/mpeg12.c
@@ -70,6 +70,7 @@ static inline int mpeg2_decode_block_non_intra(MpegEncContext *s,
static inline int mpeg2_decode_block_intra(MpegEncContext *s,
DCTELEM *block,
int n);
+static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, DCTELEM *block, int n);
static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred);
static void exchange_uv(MpegEncContext *s);
@@ -1358,16 +1359,27 @@ static int mpeg_decode_mb(MpegEncContext *s,
#endif
if (s->codec_id == CODEC_ID_MPEG2VIDEO) {
- cbp<<= 12-mb_block_count;
-
- for(i=0;i<mb_block_count;i++) {
- if ( cbp & (1<<11) ) {
- if (mpeg2_decode_block_non_intra(s, s->pblocks[i], i) < 0)
- return -1;
- } else {
- s->block_last_index[i] = -1;
+ if(s->flags2 & CODEC_FLAG2_FAST){
+ for(i=0;i<6;i++) {
+ if(cbp & 32) {
+ mpeg2_fast_decode_block_non_intra(s, s->pblocks[i], i);
+ } else {
+ s->block_last_index[i] = -1;
+ }
+ cbp+=cbp;
+ }
+ }else{
+ cbp<<= 12-mb_block_count;
+
+ for(i=0;i<mb_block_count;i++) {
+ if ( cbp & (1<<11) ) {
+ if (mpeg2_decode_block_non_intra(s, s->pblocks[i], i) < 0)
+ return -1;
+ } else {
+ s->block_last_index[i] = -1;
+ }
+ cbp+=cbp;
}
- cbp+=cbp;
}
} else {
for(i=0;i<6;i++) {
@@ -1592,8 +1604,6 @@ static inline int mpeg1_decode_block_inter(MpegEncContext *s,
return 0;
}
-/* Also does unquantization here, since I will never support mpeg2
- encoding */
static inline int mpeg2_decode_block_non_intra(MpegEncContext *s,
DCTELEM *block,
int n)
@@ -1673,6 +1683,67 @@ static inline int mpeg2_decode_block_non_intra(MpegEncContext *s,
return 0;
}
+static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s,
+ DCTELEM *block,
+ int n)
+{
+ int level, i, j, run;
+ RLTable *rl = &rl_mpeg1;
+ uint8_t * const scantable= s->intra_scantable.permutated;
+ const int qscale= s->qscale;
+ int v;
+ OPEN_READER(re, &s->gb);
+ i = -1;
+
+ /* special case for the first coef. no need to add a second vlc table */
+ UPDATE_CACHE(re, &s->gb);
+ v= SHOW_UBITS(re, &s->gb, 2);
+ if (v & 2) {
+ LAST_SKIP_BITS(re, &s->gb, 2);
+ level= (3*qscale)>>1;
+ if(v&1)
+ level= -level;
+ block[0] = level;
+ i++;
+ }
+
+ /* now quantify & encode AC coefs */
+ for(;;) {
+ UPDATE_CACHE(re, &s->gb);
+ GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2);
+
+ if(level == 127){
+ break;
+ } else if(level != 0) {
+ i += run;
+ j = scantable[i];
+ level= ((level*2+1)*qscale)>>1;
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+ LAST_SKIP_BITS(re, &s->gb, 1);
+ } else {
+ /* escape */
+ run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6);
+ UPDATE_CACHE(re, &s->gb);
+ level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12);
+
+ i += run;
+ j = scantable[i];
+ if(level<0){
+ level= ((-level*2+1)*qscale)>>1;
+ level= -level;
+ }else{
+ level= ((level*2+1)*qscale)>>1;
+ }
+ }
+
+ block[j] = level;
+ }
+ CLOSE_READER(re, &s->gb);
+ s->block_last_index[n] = i;
+ return 0;
+}
+
+
static inline int mpeg2_decode_block_intra(MpegEncContext *s,
DCTELEM *block,
int n)