pulldown.c
来自「linux下的MPEG1」· C语言 代码 · 共 615 行 · 第 1/2 页
C
615 行
for( j = 0; j < HISTORY_SIZE; j++ ) { avgtop += tophistory[ j ]; avgbot += bothistory[ j ]; } avgtop /= 5; avgbot /= 5; for( i = 0; i < 5; i++ ) { if( (1<<i) == predicted ) { predicted_pos = i; break; } } /* printf(top: %8d bot: %8d\ttop-avg: %8d bot-avg: %8d (%d)\n", top_repeat, bot_repeat, top_repeat - avgtop, bot_repeat - avgbot, (5 + predicted_pos - reference) % 5 ); */ for( j = 0; j < HISTORY_SIZE; j++ ) { int cur = tophistory[ j ]; if( cur < mintopval || mintopval < 0 ) { min2topval = mintopval; min2toppos = mintoppos; mintopval = cur; mintoppos = j; } else if( cur < min2topval || min2topval < 0 ) { min2topval = cur; min2toppos = j; } } for( j = 0; j < HISTORY_SIZE; j++ ) { int cur = bothistory[ j ]; if( cur < minbotval || minbotval < 0 ) { min2botval = minbotval; min2botpos = minbotpos; minbotval = cur; minbotpos = j; } else if( cur < min2botval || min2botval < 0 ) { min2botval = cur; min2botpos = j; } } tophistory_diff[ histpos ] = ((mintoppos == histpos) || (min2toppos == histpos)); bothistory_diff[ histpos ] = ((minbotpos == histpos) || (min2botpos == histpos)); ret = 0; for( i = 0; i < 5; i++ ) { int valid = 1; for( j = 0; j < 5; j++ ) { // if( tff_top_pattern[ j ] && !tophistory_diff[ (i + j) % 5 ] && tophistory[ (i + j) % 5 ] != mintopval ) { if( tff_top_pattern[ j ] && (tophistory[ (i + j) % 5 ] > avgtop || !tophistory_diff[ (i + j) % 5 ]) ) { valid = 0; break; } // if( tff_bot_pattern[ j ] && !bothistory_diff[ (i + j) % 5 ] && bothistory[ (i + j) % 5 ] != minbotval ) { if( tff_bot_pattern[ j ] && (bothistory[ (i + j) % 5 ] > avgbot || !bothistory_diff[ (i + j) % 5 ]) ) { valid = 0; break; } } if( valid ) ret |= (1<<(((5-i)+histpos)%5)); } /* printf( "ret: %d %d %d %d %d\n", PULLDOWN_OFFSET_1 & ret, PULLDOWN_OFFSET_2 & ret, PULLDOWN_OFFSET_3 & ret, PULLDOWN_OFFSET_4 & ret, PULLDOWN_OFFSET_5 & ret ); */ histpos = (histpos + 1) % HISTORY_SIZE; reference = (reference + 1) % 5; if( !ret ) { /* No pulldown sequence is valid, return an error. */ return 0; } else if( !(predicted & ret) ) { /** * We have a valid sequence, but it doesn't match our prediction. * Return the first 'valid' sequence in the list. */ for( i = 0; i < 5; i++ ) { if( ret & (1<<i) ) return (1<<i); } } /** * The predicted phase is still valid. */ return predicted;}int determine_pulldown_offset_short_history_new( int top_repeat, int bot_repeat, int tff, int predicted ){ int avgbot = 0; int avgtop = 0; int i, j; int ret; int mintopval = -1; int mintoppos = -1; int min2topval = -1; int min2toppos = -1; int minbotval = -1; int minbotpos = -1; int min2botval = -1; int min2botpos = -1; int predicted_pos = 0; tophistory[ histpos ] = top_repeat; bothistory[ histpos ] = bot_repeat; for( j = 0; j < 3; j++ ) { avgtop += tophistory[ (histpos + 5 - j) % 5 ]; avgbot += bothistory[ (histpos + 5 - j) % 5 ]; } avgtop /= 3; avgbot /= 3; for( i = 0; i < 5; i++ ) { if( (1<<i) == predicted ) { predicted_pos = i; break; } } /* printf( "top: %8d bot: %8d\ttop-avg: %8d bot-avg: %8d (%d)\n", top_repeat, bot_repeat, top_repeat - avgtop, bot_repeat - avgbot, (5 + predicted_pos - reference) % 5 ); */ for( j = 0; j < 3; j++ ) { int cur = tophistory[ (histpos + 5 - j) % 5 ]; if( cur < mintopval || mintopval < 0 ) { min2topval = mintopval; min2toppos = mintoppos; mintopval = cur; mintoppos = j; } else if( cur < min2topval || min2topval < 0 ) { min2topval = cur; min2toppos = j; } } for( j = 0; j < 3; j++ ) { int cur = bothistory[ (histpos + 5 - j) % 5 ]; if( cur < minbotval || minbotval < 0 ) { min2botval = minbotval; min2botpos = minbotpos; minbotval = cur; minbotpos = j; } else if( cur < min2botval || min2botval < 0 ) { min2botval = cur; min2botpos = j; } } tophistory_diff[ histpos ] = ((mintoppos == histpos) || (min2toppos == histpos)); bothistory_diff[ histpos ] = ((minbotpos == histpos) || (min2botpos == histpos)); ret = 0; for( i = 0; i < 5; i++ ) { int valid = 1; for( j = 0; j < 3; j++ ) { // if( tff_top_pattern[ j ] && !tophistory_diff[ (i + j) % 5 ] && tophistory[ (i + j) % 5 ] != mintopval ) { // if( tff_top_pattern[ j ] && (tophistory[ (i + j) % 5 ] > avgtop || !tophistory_diff[ (i + j) % 5 ]) ) { if( tff_top_pattern[ (i + 5 - j) % 5 ] && tophistory[ (histpos + 5 - j) % 5 ] > avgtop ) { // if( tff_top_pattern[ (i + 5 - j) % 5 ] && !tophistory_diff[ (histpos + 5 - j) % 5 ] && tophistory[ (histpos + 5 - j) % 5 ] != mintopval ) { valid = 0; break; } // if( tff_bot_pattern[ j ] && !bothistory_diff[ (i + j) % 5 ] && bothistory[ (i + j) % 5 ] != minbotval ) { // if( tff_bot_pattern[ j ] && (bothistory[ (i + j) % 5 ] > avgbot || !bothistory_diff[ (i + j) % 5 ]) ) { if( tff_bot_pattern[ (i + 5 - j) % 5 ] && bothistory[ (histpos + 5 - j) % 5 ] > avgbot ) { // if( tff_bot_pattern[ (i + 5 - j) % 5 ] && !bothistory_diff[ (histpos + 5 - j) % 5 ] && bothistory[ (histpos + 5 - j) % 5 ] != minbotval ) { valid = 0; break; } } if( valid ) ret |= (1<<i); } /* printf( "ret: %d %d %d %d %d\n", PULLDOWN_OFFSET_1 & ret, PULLDOWN_OFFSET_2 & ret, PULLDOWN_OFFSET_3 & ret, PULLDOWN_OFFSET_4 & ret, PULLDOWN_OFFSET_5 & ret ); */ histpos = (histpos + 1) % HISTORY_SIZE; reference = (reference + 1) % 5; if( !ret ) { /* No pulldown sequence is valid, return an error. */ return 0; } else if( !(predicted & ret) ) { /** * We have a valid sequence, but it doesn't match our prediction. * Return the first 'valid' sequence in the list. */ for( i = 0; i < 5; i++ ) { if( ret & (1<<i) ) return (1<<i); } } /** * The predicted phase is still valid. */ return predicted;}int determine_pulldown_offset_dalias( pulldown_metrics_t *old_peak, pulldown_metrics_t *old_relative, pulldown_metrics_t *old_mean, pulldown_metrics_t *new_peak, pulldown_metrics_t *new_relative, pulldown_metrics_t *new_mean ){ int laced = 0; if (old_peak->d > 360) { if (3*old_relative->e < old_relative->o) laced=1; if ((2*old_relative->d < old_relative->s) && (old_relative->s > 600)) laced=1; } if (new_peak->d > 360) { if ((2*new_relative->t < new_relative->p) && (new_relative->p > 600)) laced=1; } if( !laced ) return PULLDOWN_ACTION_NEXT_PREV; if (new_relative->t < 2*new_relative->p) { if ((3*old_relative->e < old_relative->o) || (2*new_relative->t < new_relative->p)) { return PULLDOWN_ACTION_PREV_NEXT; } } return PULLDOWN_ACTION_PREV_NEXT;}#define MAXUP(a,b) ((a) = ((a)>(b)) ? (a) : (b))void diff_factor_packed422_frame( pulldown_metrics_t *peak, pulldown_metrics_t *rel, pulldown_metrics_t *mean, uint8_t *old, uint8_t *new, int w, int h, int os, int ns ){ int x, y; pulldown_metrics_t l; memset(peak, 0, sizeof(pulldown_metrics_t)); memset(rel, 0, sizeof(pulldown_metrics_t)); memset(mean, 0, sizeof(pulldown_metrics_t)); for (y = 0; y < h-7; y += 8) { for (x = 8; x < w-8-7; x += 8) { diff_packed422_block8x8(&l, old+x+y*os, new+x+y*ns, os, ns); mean->d += l.d; mean->e += l.e; mean->o += l.o; mean->s += l.s; mean->p += l.p; mean->t += l.t; MAXUP(peak->d, l.d); MAXUP(peak->e, l.e); MAXUP(peak->o, l.o); MAXUP(peak->s, l.s); MAXUP(peak->p, l.p); MAXUP(peak->t, l.t); MAXUP(rel->e, l.e-l.o); MAXUP(rel->o, l.o-l.e); MAXUP(rel->s, l.s-l.t); MAXUP(rel->p, l.p-l.t); MAXUP(rel->t, l.t-l.p); MAXUP(rel->d, l.t-l.s); /* hack */ } } x = (w/8-2)*(h/8); mean->d /= x; mean->e /= x; mean->o /= x; mean->s /= x; mean->p /= x; mean->t /= x;}int pulldown_source( int action, int bottom_field ){ if( action == PULLDOWN_SEQ_AA ) { return !bottom_field; } else if( action == PULLDOWN_SEQ_AB ) { return 1; } else if( action == PULLDOWN_SEQ_BC ) { return bottom_field; } else if( action == PULLDOWN_SEQ_CC ) { return 0; } else if( action == PULLDOWN_SEQ_DD ) { return !bottom_field; } return 0;}int pulldown_drop( int action, int bottom_field ){ int ret = 1; if( action == PULLDOWN_SEQ_AA && bottom_field ) ret = 0; if( action == PULLDOWN_SEQ_BC && !bottom_field ) ret = 0; if( action == PULLDOWN_SEQ_CC && !bottom_field ) ret = 0; if( action == PULLDOWN_SEQ_DD && bottom_field ) ret = 0; return ret;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?