⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 encode.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 4 页
字号:
    cpi->FourMVThreshold = (2500<<12);  } else {    cpi->ExhaustiveSearchThresh = (250<<12);    cpi->FourMVThreshold = (500<<12);  }  cpi->MinImprovementForFourMV = cpi->MinImprovementForNewMV * 4;  if(cpi->MinImprovementForFourMV < (40<<12))    cpi->MinImprovementForFourMV = (40<<12);  cpi->FourMvChangeFactor = 8; /* cpi->MVChangeFactor - 0.05;  */  /* decide what block type and motion vectors to use on all of the frames */  for ( SBrow=0; SBrow<SBRows; SBrow++ ) {    for ( SBcol=0; SBcol<SBCols; SBcol++ ) {      /* Check its four Macro-Blocks */      for ( MB=0; MB<4; MB++ ) {        /* There may be MB's lying out of frame which must be           ignored. For these MB's Top left block will have a negative           Fragment Index. */        if ( QuadMapToMBTopLeft(cpi->pb.BlockMap,SB,MB) < 0 ) continue;        /* Is the current macro block coded (in part or in whole) */        MBCodedFlag = 0;        for ( B=0; B<4; B++ ) {          YFragIndex = QuadMapToIndex1( cpi->pb.BlockMap, SB, MB, B );          /* Does Block lie in frame: */          if ( YFragIndex >= 0 ) {            /* In Frame: Is it coded: */            if ( cpi->pb.display_fragments[YFragIndex] ) {              MBCodedFlag = 1;              break;            }          } else            MBCodedFlag = 0;        }        /* This one isn't coded go to the next one */        if(!MBCodedFlag) continue;        /* Calculate U and V FragIndex from YFragIndex */        YFragIndex = QuadMapToMBTopLeft(cpi->pb.BlockMap, SB,MB);        UVRow = (YFragIndex / (cpi->pb.HFragments * 2));        UVColumn = (YFragIndex % cpi->pb.HFragments) / 2;        UVFragOffset = (UVRow * (cpi->pb.HFragments / 2)) + UVColumn;        UFragIndex = cpi->pb.YPlaneFragments + UVFragOffset;        VFragIndex = cpi->pb.YPlaneFragments + cpi->pb.UVPlaneFragments +          UVFragOffset;        /**************************************************************         Find the block choice with the lowest error         NOTE THAT if U or V is coded but no Y from a macro block then         the mode will be CODE_INTER_NO_MV as this is the default         state to which the mode data structure is initialised in         encoder and decoder at the start of each frame. */        BestError = HUGE_ERROR;        /* Look at the intra coding error. */        MBIntraError = GetMBIntraError( cpi, YFragIndex, PixelsPerLine );        BestError = (BestError > MBIntraError) ? MBIntraError : BestError;        /* Get the golden frame error */        MBGFError = GetMBInterError( cpi, cpi->ConvDestBuffer,                                     cpi->pb.GoldenFrame, YFragIndex,                                     0, 0, PixelsPerLine );        BestError = (BestError > MBGFError) ? MBGFError : BestError;        /* Calculate the 0,0 case. */        MBInterError = GetMBInterError( cpi, cpi->ConvDestBuffer,                                        cpi->pb.LastFrameRecon,                                        YFragIndex, 0, 0, PixelsPerLine );        BestError = (BestError > MBInterError) ? MBInterError : BestError;        /* Measure error for last MV */        MBLastInterError =  GetMBInterError( cpi, cpi->ConvDestBuffer,                                             cpi->pb.LastFrameRecon,                                             YFragIndex, LastInterMVect.x,                                             LastInterMVect.y, PixelsPerLine );        BestError = (BestError > MBLastInterError) ?          MBLastInterError : BestError;        /* Measure error for prior last MV */        MBPriorLastInterError =  GetMBInterError( cpi, cpi->ConvDestBuffer,                                                  cpi->pb.LastFrameRecon,                                                  YFragIndex,                                                  PriorLastInterMVect.x,                                                  PriorLastInterMVect.y,                                                  PixelsPerLine );        BestError = (BestError > MBPriorLastInterError) ?          MBPriorLastInterError : BestError;        /* Temporarily force usage of no motionvector blocks */        MBInterMVError = HUGE_ERROR;        InterMVect.x = 0;  /* Set 0,0 motion vector */        InterMVect.y = 0;        /* If the best error is above the required threshold search           for a new inter MV */        if ( BestError > cpi->MinImprovementForNewMV ) {          /* Use a mix of heirachical and exhaustive searches for             quick mode. */          if ( cpi->pb.info.quick_p ) {            MBInterMVError = GetMBMVInterError( cpi, cpi->pb.LastFrameRecon,                                                YFragIndex, PixelsPerLine,                                                cpi->MVPixelOffsetY,                                                &InterMVect );            /* If we still do not have a good match try an exhaustive               MBMV search */            if ( (MBInterMVError > cpi->ExhaustiveSearchThresh) &&                 (BestError > cpi->ExhaustiveSearchThresh) ) {              MBInterMVExError =                GetMBMVExhaustiveSearch( cpi, cpi->pb.LastFrameRecon,                                         YFragIndex, PixelsPerLine,                                         &InterMVectEx );              /* Is the Variance measure for the EX search                 better... If so then use it. */              if ( MBInterMVExError < MBInterMVError ) {                MBInterMVError = MBInterMVExError;                InterMVect.x = InterMVectEx.x;                InterMVect.y = InterMVectEx.y;              }            }          }else{            /* Use an exhaustive search */            MBInterMVError =              GetMBMVExhaustiveSearch( cpi, cpi->pb.LastFrameRecon,                                       YFragIndex, PixelsPerLine,                                       &InterMVect );          }          /* Is the improvement, if any, good enough to justify a new MV */          if ( (16 * MBInterMVError < (BestError * cpi->MVChangeFactor)) &&               ((MBInterMVError + cpi->MinImprovementForNewMV) < BestError) ){            BestError = MBInterMVError;          }        }        /* If the best error is still above the required threshold           search for a golden frame MV */        MBGF_MVError = HUGE_ERROR;        GFMVect.x = 0; /* Set 0,0 motion vector */        GFMVect.y = 0;        if ( BestError > cpi->MinImprovementForNewMV ) {          /* Do an MV search in the golden reference frame */          MBGF_MVError = GetMBMVInterError( cpi, cpi->pb.GoldenFrame,                                            YFragIndex, PixelsPerLine,                                            cpi->MVPixelOffsetY, &GFMVect );          /* Measure error for last GFMV */          LastMBGF_MVError =  GetMBInterError( cpi, cpi->ConvDestBuffer,                                               cpi->pb.GoldenFrame,                                               YFragIndex, LastGFMVect.x,                                               LastGFMVect.y, PixelsPerLine );          /* Check against last GF motion vector and reset if the             search has thrown a worse result. */          if ( LastMBGF_MVError < MBGF_MVError ) {            GFMVect.x = LastGFMVect.x;            GFMVect.y = LastGFMVect.y;            MBGF_MVError = LastMBGF_MVError;          }else{            LastGFMVect.x = GFMVect.x;            LastGFMVect.y = GFMVect.y;          }          /* Is the improvement, if any, good enough to justify a new MV */          if ( (16 * MBGF_MVError < (BestError * cpi->MVChangeFactor)) &&               ((MBGF_MVError + cpi->MinImprovementForNewMV) < BestError) ) {            BestError = MBGF_MVError;          }        }        /* Finally... If the best error is still to high then consider           the 4MV mode */        MBInterFOURMVError = HUGE_ERROR;        if ( BestError > cpi->FourMVThreshold ) {          /* Get the 4MV error. */          MBInterFOURMVError =            GetFOURMVExhaustiveSearch( cpi, cpi->pb.LastFrameRecon,                                       YFragIndex, PixelsPerLine, FourMVect );          /* If the improvement is great enough then use the four MV mode */          if ( ((MBInterFOURMVError + cpi->MinImprovementForFourMV) <                BestError) && (16 * MBInterFOURMVError <                               (BestError * cpi->FourMvChangeFactor))) {            BestError = MBInterFOURMVError;          }        }        /********************************************************         end finding the best error         *******************************************************         Figure out what to do with the block we chose         Over-ride and force intra if error high and Intra error similar         Now choose a mode based on lowest error (with bias towards no MV) */        if ( (BestError > cpi->InterTripOutThresh) &&             (10 * BestError > MBIntraError * 7 ) ) {          cpi->MBCodingMode = CODE_INTRA;          SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,                                    VFragIndex,&ZeroVect);        } else if ( BestError == MBInterError ) {          cpi->MBCodingMode = CODE_INTER_NO_MV;          SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,                                    VFragIndex,&ZeroVect);        } else if ( BestError == MBGFError ) {          cpi->MBCodingMode = CODE_USING_GOLDEN;          SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,                                    VFragIndex,&ZeroVect);        } else if ( BestError == MBLastInterError ) {          cpi->MBCodingMode = CODE_INTER_LAST_MV;          SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,                                    VFragIndex,&LastInterMVect);        } else if ( BestError == MBPriorLastInterError ) {          cpi->MBCodingMode = CODE_INTER_PRIOR_LAST;          SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,                                    VFragIndex,&PriorLastInterMVect);          /* Swap the prior and last MV cases over */          TmpMVect.x = PriorLastInterMVect.x;          TmpMVect.y = PriorLastInterMVect.y;          PriorLastInterMVect.x = LastInterMVect.x;          PriorLastInterMVect.y = LastInterMVect.y;          LastInterMVect.x = TmpMVect.x;          LastInterMVect.y = TmpMVect.y;        } else if ( BestError == MBInterMVError ) {          cpi->MBCodingMode = CODE_INTER_PLUS_MV;          SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,                                    VFragIndex,&InterMVect);          /* Update Prior last mv with last mv */          PriorLastInterMVect.x = LastInterMVect.x;          PriorLastInterMVect.y = LastInterMVect.y;          /* Note last inter MV for future use */          LastInterMVect.x = InterMVect.x;          LastInterMVect.y = InterMVect.y;          AddMotionVector( cpi, &InterMVect);        } else if ( BestError == MBGF_MVError ) {          cpi->MBCodingMode = CODE_GOLDEN_MV;          SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,                                    VFragIndex,&GFMVect);          /* Note last inter GF MV for future use */          LastGFMVect.x = GFMVect.x;          LastGFMVect.y = GFMVect.y;          AddMotionVector( cpi, &GFMVect);        } else if ( BestError == MBInterFOURMVError ) {          cpi->MBCodingMode = CODE_INTER_FOURMV;          /* Calculate the UV vectors as the average of the Y plane ones. */          /* First .x component */          FourMVect[4].x = FourMVect[0].x + FourMVect[1].x +            FourMVect[2].x + FourMVect[3].x;          if ( FourMVect[4].x >= 0 )            FourMVect[4].x = (FourMVect[4].x + 2) / 4;          else            FourMVect[4].x = (FourMVect[4].x - 2) / 4;          FourMVect[5].x = FourMVect[4].x;          /* Then .y component */          FourMVect[4].y = FourMVect[0].y + FourMVect[1].y +            FourMVect[2].y + FourMVect[3].y;          if ( FourMVect[4].y >= 0 )            FourMVect[4].y = (FourMVect[4].y + 2) / 4;          else            FourMVect[4].y = (FourMVect[4].y - 2) / 4;          FourMVect[5].y = FourMVect[4].y;          SetFragMotionVectorAndMode(cpi, YFragIndex, &FourMVect[0]);          SetFragMotionVectorAndMode(cpi, YFragIndex + 1, &FourMVect[1]);          SetFragMotionVectorAndMode(cpi, YFragIndex + cpi->pb.HFragments,                                     &FourMVect[2]);          SetFragMotionVectorAndMode(cpi, YFragIndex + cpi->pb.HFragments + 1,                                     &FourMVect[3]);          SetFragMotionVectorAndMode(cpi, UFragIndex, &FourMVect[4]);          SetFragMotionVectorAndMode(cpi, VFragIndex, &FourMVect[5]);          /* Note the four MVs values for current macro-block. */          AddMotionVector( cpi, &FourMVect[0]);          AddMotionVector( cpi, &FourMVect[1]);          AddMotionVector( cpi, &FourMVect[2]);          AddMotionVector( cpi, &FourMVect[3]);          /* Update Prior last mv with last mv */          PriorLastInterMVect.x = LastInterMVect.x;          PriorLastInterMVect.y = LastInterMVect.y;          /* Note last inter MV for future use */          LastInterMVect.x = FourMVect[3].x;          LastInterMVect.y = FourMVect[3].y;        } else {          cpi->MBCodingMode = CODE_INTRA;          SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,                                    VFragIndex,&ZeroVect);        }        /* setting up mode specific block types           *******************************************************/        *InterError += (BestError>>8);        *IntraError += (MBIntraError>>8);      }      SB++;    }  }  /* Return number of pixels coded */  return 0;}void WriteFrameHeader( CP_INSTANCE *cpi) {  ogg_uint32_t i;  oggpack_buffer *opb=cpi->oggbuffer;  /* Output the frame type (base/key frame or inter frame) */  oggpackB_write( opb, cpi->pb.FrameType, 1 );  /* Write out details of the current value of Q... variable resolution. */  for ( i = 0; i < Q_TABLE_SIZE; i++ ) {    if ( cpi->pb.ThisFrameQualityValue == cpi->pb.QThreshTable[i] ) {      oggpackB_write( opb, i, 6 );      break;    }  }  if ( i == Q_TABLE_SIZE ) {    /* An invalid DCT value was specified.  */    /*IssueWarning( "Invalid Q Multiplier" );*/    oggpackB_write( opb, 31, 6 );  }  /* we only support one Q index per frame */  oggpackB_write( opb, 0, 1 );  /* If the frame was a base frame then write out the frame dimensions. */  if ( cpi->pb.FrameType == KEY_FRAME ) {    /* Key frame type / method */    oggpackB_write( opb, cpi->pb.KeyFrameType, 1 );    /* Spare configuration bits */    oggpackB_write( opb, 0, 2 );  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -