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 + -
显示快捷键?