📄 invtelec.cpp
字号:
// This is a weak test if ((state->pulldownSadHistAll[(PULLDOWN_HIST_LEN-1)] < state->pulldownSadHistAll[(PULLDOWN_HIST_LEN-2)] * 0.5) && (state->ulPulldownActiveTimerProg > 50) && (groupValidFlag[(PULLDOWN_HIST_LEN-1)%5] == TRUE)) { state->frameRemovalPattern = (PULLDOWN_HIST_LEN-1)%5;#ifdef CODEC_DEBUG_32PULLDOWN fprintf(fp_log,"things look interlaced, pulldown timer is %d, patternStart is %d\n",state->ulPulldownActiveTimerProg,patternStart);#endif state->lastRemovedTimestamp = timestamp; goto REMOVE_FRAME; } // Otherwise no pulldown!#ifdef CODEC_DEBUG_32PULLDOWN fprintf(fp_log,"no pattern, pulldown timer is %d, patternStart is %d\n",state->ulPulldownActiveTimerProg,patternStart);#endif if((inMax[(PULLDOWN_HIST_LEN-1)%5] > 30) || (outMax[(PULLDOWN_HIST_LEN-1)%5] >30)) if (state->ulPulldownActiveTimerProg > 0) state->ulPulldownActiveTimerProg--;NO_PATTERN: // If there was no clear pattern, do nothing state->checkNextFrameForProgressive = FALSE; return INVTELE_RESULT_NO_PATTERN;INTERLEAVE_ODD: state->checkNextFrameForProgressive = FALSE; // Test if data should be re-interleaved. // Look at cross difference of old vs. re-stitched. Only replace if better if (obviousPatternFlag == FALSE || sceneChangeFlag == TRUE) { switch (state->impl_id) {#ifdef ALLOW_MMX_INVTELE case INVTELE_IMPL_ID_MMX: { RestitchCheck_MMX(data, prevData, pels, lines, pels, &sumOld, &sumNew); } break;#endif case INVTELE_IMPL_ID_C: default: { pNew = (LONG32 *)(data); pOld = (LONG32 *)(prevData); for (i = 0; i < lines; i += 2) // only do the luma. { for(j = 0; j < ll; j++) { temp = (float)((pNew[j]&0xff00) - (pNew[j+ll]&0xff00)); sumOld += (temp*temp); temp = (float)((pNew[j]&0xff00) - (pOld[j+ll]&0xff00)); sumNew += (temp*temp); } pOld += 2*ll; pNew += 2*ll; } } break; } if (sumNew > sumOld) { return INVTELE_RESULT_FRAME_OK; } } state->interleaveOddFlag = TRUE;#ifdef CODEC_DEBUG_32PULLDOWN fprintf(fp_log,"interleaving odd\n");#endif // Re-interleave pNew = ((LONG32 *)data)+ll; pOld = ((LONG32 *)prevData)+ll; for (k = 1; k < lines; k += 2) // only do the luma. { memcpy(pNew,pOld,sizeof(ULONG32)*ll); /* Flawfinder: ignore */ pOld+=2*ll; pNew+=2*ll; } return INVTELE_RESULT_FRAME_OK;INTERLEAVE_EVEN: state->checkNextFrameForProgressive = FALSE; // Test if data should be re-interleaved. // Look at cross difference of old vs. re-stitched. Only replace if better if (obviousPatternFlag == FALSE || sceneChangeFlag == TRUE) { switch (state->impl_id) {#ifdef ALLOW_MMX_INVTELE case INVTELE_IMPL_ID_MMX: { RestitchCheck_MMX(data + pels, prevData + pels, pels, lines - 2, pels, &sumOld, &sumNew); } break;#endif case INVTELE_IMPL_ID_C: default: { pNew = (LONG32 *)(data); pOld = (LONG32 *)(prevData); for (i = 0; i < lines; i += 2) // only do the luma. { for(j = 0; j < ll; j++) { temp = (float)((pNew[j]&0xff00) - (pNew[j+ll]&0xff00)); sumOld += (temp*temp); temp = (float)((pNew[j+ll]&0xff00) - (pOld[j]&0xff00)); sumNew += (temp*temp); } pOld+=2*ll; pNew+=2*ll; } } break; } if (sumNew > sumOld) { return INVTELE_RESULT_FRAME_OK; } } state->interleaveEvenFlag = TRUE;#ifdef CODEC_DEBUG_32PULLDOWN fprintf(fp_log,"interleaving even\n");#endif // Re-interleave pNew = ((LONG32 *)data); pOld = ((LONG32 *)prevData); for (k = 0; k < lines; k += 2) // only do the luma. { memcpy(pNew,pOld,sizeof(ULONG32)*ll); /* Flawfinder: ignore */ pOld+=2*ll; pNew+=2*ll; } return INVTELE_RESULT_FRAME_OK;DO_NOTHING: // One final check in this case // If we are here, we think the frame is progressive. // If we think the previous frame was also progressive, then // the odd and even SADs should be somewhat similar. If not, // we're in trouble. if (state->checkNextFrameForProgressive) { if (state->ulPulldownActiveTimerProg < 10 && state->ulPulldownActiveTimerIntl > 90 && (sumEven > 8 * sumOdd || sumOdd > 8 * sumEven)) { goto NO_PATTERN; } if (sceneChangeFlag == TRUE) { // Just return here because we want to be sure // state->checkNextFrameForProgressive is TRUE return INVTELE_RESULT_NO_PATTERN; } } state->checkNextFrameForProgressive = TRUE; return INVTELE_RESULT_FRAME_OK;REMOVE_FRAME:#ifdef CODEC_DEBUG_32PULLDOWN fprintf(fp_log,"removing frame\n");#endif state->checkNextFrameForProgressive = FALSE; return INVTELE_RESULT_DROP_FRAME;TOO_EARLY: state->checkNextFrameForProgressive = FALSE; return INVTELE_RESULT_TOO_EARLY;}// Platform specific SSD functions#ifdef ALLOW_MMX_INVTELEvoidSumSqaredFrameDiff_MMX( unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, float *ssd_odd, float *ssd_even){ unsigned int res_odd[2]; unsigned int res_even[2]; float pel_avg; const unsigned int mask[2] = {0x00FF00FF, 0x00FF00FF}; int line_shift; int pels_div8; pels_div8 = (pels >> 3); // round down line_shift = ((pitch) - (pels & ~7)); __asm { mov ecx, lines // ecx -> lines shr ecx, 1 // ecx -> lines/2 mov esi, frame // esi -> current frame mov edi, prev_frame // edi -> previous frame movq mm5, [mask] pxor mm6, mm6 // mm6 -> odd ssd pxor mm7, mm7 // mm7 -> even ssdALIGN 16line_loop: mov ebx, pels_div8 // ebx -> pels/8 (rounded down)ALIGN 16pel_loop_even: movq mm0,[esi] movq mm1,[edi] pand mm0, mm5 pand mm1, mm5 psubw mm0, mm1 pmaddwd mm0, mm0 paddd mm6, mm0 lea esi,[esi+8] lea edi,[edi+8] dec ebx jnz pel_loop_even add esi, line_shift; // move esi to the next line add edi, line_shift; // move edi to the next line mov ebx, pels_div8 // ebx -> pels/8 (rounded down)ALIGN 16pel_loop_odd: movq mm0,[esi] movq mm1,[edi] pand mm0, mm5 pand mm1, mm5 psubw mm0, mm1 pmaddwd mm0, mm0 paddd mm7, mm0 lea esi,[esi+8] lea edi,[edi+8] dec ebx jnz pel_loop_odd add esi, line_shift; // move esi to the next line add edi, line_shift; // move edi to the next line dec ecx jnz line_loop movq res_odd, mm6 movq res_even, mm7 emms } // fill "even" result pel_avg = (float)(res_even[0] + res_even[1]); pel_avg /= (float)((pels*lines)>>2); *ssd_even = pel_avg; // fill "odd" result pel_avg = (float)(res_odd[0] + res_odd[1]); pel_avg /= (float)((pels*lines)>>2); *ssd_odd = pel_avg;}voidRestitchCheck_MMX( unsigned char *frame, unsigned char *prev_frame, int pels, int lines, int pitch, float *ssd_new, float *ssd_old){ unsigned int res_new[2]; unsigned int res_old[2]; const unsigned int mask[2] = {0x00FF00FF, 0x00FF00FF}; int line_shift; int pels_div8; pels_div8 = (pels >> 3); // round down line_shift = ((pitch << 1) - (pels & ~7)); __asm { mov ecx, lines // ecx -> lines shr ecx, 1 // ecx -> lines/2 mov esi, frame // esi -> current frame mov edi, prev_frame // edi -> previous frame mov edx, pitch // pitch lea edi, [edi+edx] // edi -> previous frame + pitch movq mm5, [mask] pxor mm6, mm6 // mm6 -> odd ssd pxor mm7, mm7 // mm7 -> even ssdALIGN 16line_loop: mov ebx, pels_div8 // ebx -> pels/8 (rounded down)ALIGN 16pel_loop: movq mm0,[esi] movq mm1,[esi + edx] movq mm2,[edi] pand mm0, mm5 pand mm1, mm5 pand mm2, mm5 psubw mm1, mm0 pmaddwd mm1, mm1 paddd mm6, mm1 psubw mm2, mm0 pmaddwd mm2, mm2 paddd mm7, mm2 lea esi, [esi+8] lea edi, [edi+8] dec ebx jnz pel_loop add esi, line_shift // move esi down 2 lines add edi, line_shift // move edi down 2 lines dec ecx jnz line_loop movq res_new, mm6 movq res_old, mm7 emms } // fill "new" result *ssd_new = (float)(res_new[0] + res_new[1]); // fill "old" result *ssd_old = (float)(res_old[0] + res_old[1]);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -