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

📄 timgfilteravisynth.cpp

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    pict.rectFull=pict.rectClip=outputRect=Trect(0,0,vi.width,vi.height,input->outputSar);
   else if ((unsigned int)vi.width != inputRect.dx || (unsigned int)vi.height != inputRect.dy)
    pict.rectFull=pict.rectClip=outputRect=Trect(0,0,vi.width,vi.height,inputSar);
   else
    outputRect=inputRect;

   restart=true;
   deleteBuffers=true;
  }
}

void TimgFilterAvisynth::Tavisynth::process(TimgFilterAvisynth *self,TfilterQueue::iterator& it,TffPict &pict,const TavisynthSettings *cfg)
{
 bool sequenceStart=(pict.fieldtype & FIELD_TYPE::MASK_SEQ) == FIELD_TYPE::SEQ_START;
 bool sequenceEnd=(pict.fieldtype & FIELD_TYPE::MASK_SEQ) == FIELD_TYPE::SEQ_END;
 bool isYV12=((pict.csp&FF_CSPS_MASK) == FF_CSP_420P);
 Tinput* input=self->input;

 if (sequenceStart)
  passFirstThrough=true;

 if (sequenceEnd)
  passLastThrough=true;

 if (passFirstThrough)
  resetBuffers=true;

 if (restart)
  {
   if (debugPrint)
    {
     DPRINTF(_l("TimgFilterAvisynth: (Re-)Starting playback"));
     DPRINTF(_l("TimgFilterAvisynth: FrameScale: %lli/%lli"),frameScaleNum,frameScaleDen);
    }

   skipAhead(passFirstThrough,true);

   restart=false;
  }

 if (deleteBuffers)
  {
   if (debugPrint && (buffers || bufferData))
    DPRINTF(_l("TimgFilterAvisynth: Freeing buffers"));

   if (buffers) delete buffers; buffers=0;
   if (bufferData) delete bufferData; bufferData=0;

   deleteBuffers=false;
   resetBuffers=true;
  }

 if (resetBuffers)
  {
   if (debugPrint)
    DPRINTF(_l("TimgFilterAvisynth: (Re-)Initializing buffers"));

   hasPulldown=false;
   buffersFilled=0;
   curBufferNo=0;
   minAccessedFrame=INT_MAX;
   maxAccessedFrame=INT_MIN;
   ignoreAheadValue=true;

   if (!buffers)
    input->buffers=buffers=new TframeBuffer[numBuffers+(applyPulldown != 0 ? 1 : 0)];

   int pitch[4];
   int width[4];
   int height[4];
   int size[4];

   if (numBuffers > 1)
    {
     // Storage for buffers is only needed when there's more than one buffer
     // NB: pitch, width, height and size aren't initialized in that case,
     // but their values will be taken from the actual frame anyway later on

     int bufferSize;

     if (isYV12)
      {
       pitch[0]=input->stride1[0];
       pitch[1]=input->stride1[1];
       pitch[2]=input->stride1[2];
       pitch[3]=0;

       width[0]=input->dx;
       width[1]=width[2]=input->dx/2;
       width[3]=0;

       height[0]=input->dy;
       height[1]=height[2]=input->dy/2;
       height[3]=0;

       bufferSize =(size[0]=pitch[0]*height[0]);
       bufferSize+=(size[1]=pitch[1]*height[1]);
       bufferSize+=(size[2]=pitch[2]*height[2]);
       size[3]=0;
      }
     else
      {
       pitch[0]=input->stride1[0];
       pitch[1]=pitch[2]=pitch[3]=0;

       width[0]=input->dx;
       width[1]=width[2]=width[3]=0;

       height[0]=input->dy;
       height[1]=height[2]=height[3]=0;

       bufferSize=(size[0]=pitch[0]*height[0]);
       size[1]=size[2]=size[3]=0;
      }

     if (!bufferData)
      bufferData=new unsigned char[bufferSize*(numBuffers+(applyPulldown == 1 ? 1 : 0)+1)];
    }

   unsigned char* newBuffer=bufferData;

   for (int bufNo=0; bufNo < numBuffers+(applyPulldown > 0 ? 1 : 0); bufNo++)
    {
     buffers[bufNo].frameNo=-1;
     buffers[bufNo].bytesPerPixel=input->cspBpp;
     buffers[bufNo].start=0;
     buffers[bufNo].stop=0;
     buffers[bufNo].fieldType=0;

     if (bufNo < numBuffers ||
         applyPulldown == 1)
      for (int planeNo=0; planeNo < 4; planeNo++)
       {
        buffers[bufNo].width[planeNo]=width[planeNo];
        buffers[bufNo].height[planeNo]=height[planeNo];
        buffers[bufNo].pitch[planeNo]=pitch[planeNo];
        buffers[bufNo].data[planeNo]=newBuffer;

        newBuffer+=size[planeNo];
       }
    }

   resetBuffers=false;
  }

 TframeBuffer& curBuffer=buffers[curBufferNo];

 curBuffer.frameNo=curInFrameNo;

 if (numBuffers == 1)
  {
   // "Buffer" current frame without copying data

   if (isYV12)
    {
     curBuffer.data[0]=(unsigned char*)input->src[0];
     curBuffer.data[1]=(unsigned char*)input->src[1];
     curBuffer.data[2]=(unsigned char*)input->src[2];
     curBuffer.data[3]=0;

     curBuffer.pitch[0]=input->stride1[0];
     curBuffer.pitch[1]=input->stride1[1];
     curBuffer.pitch[2]=input->stride1[2];
     curBuffer.pitch[3]=0;

     curBuffer.width[0]=input->dx;
     curBuffer.width[1]=curBuffer.width[2]=input->dx/2;
     curBuffer.width[3]=0;

     curBuffer.height[0]=input->dy;
     curBuffer.height[1]=curBuffer.height[2]=input->dy/2;
     curBuffer.height[3]=0;
    }
   else
    {
     curBuffer.data[0]=(unsigned char*)input->src[0];
     curBuffer.data[1]=curBuffer.data[2]=curBuffer.data[3]=0;

     curBuffer.pitch[0]=input->stride1[0];
     curBuffer.pitch[1]=curBuffer.pitch[2]=curBuffer.pitch[3]=0;

     curBuffer.width[0]=input->dx;
     curBuffer.width[1]=curBuffer.width[2]=curBuffer.width[3]=0;

     curBuffer.height[0]=input->dy;
     curBuffer.height[1]=curBuffer.height[2]=curBuffer.height[3]=0;
    }

   curBuffer.start=pict.rtStart;
   curBuffer.stop=pict.rtStop;
   curBuffer.fieldType=pict.fieldtype;

   if (debugPrint)
    DPRINTF(_l("TimgFilterAvisynth: Passing through frame %i, %10.6f - %10.6f = %10.6f"),curInFrameNo,curBuffer.start/10000.0,curBuffer.stop/10000.0,(curBuffer.stop-curBuffer.start)/10000.0);
  }
 else if (applyPulldown != 1 || !(pict.fieldtype & FIELD_TYPE::MASK_INT))
  {
   // Buffer frames as-is and pass the fieldtype through

   if (isYV12)
    {
     TffPict::copy(curBuffer.data[0],curBuffer.pitch[0],input->src[0],input->stride1[0],input->dx  ,input->dy);
     TffPict::copy(curBuffer.data[1],curBuffer.pitch[1],input->src[1],input->stride1[1],input->dx/2,input->dy/2);
     TffPict::copy(curBuffer.data[2],curBuffer.pitch[2],input->src[2],input->stride1[2],input->dx/2,input->dy/2);
    }
   else
    TffPict::copy(curBuffer.data[0],curBuffer.pitch[0],input->src[0],input->stride1[0],input->dx*input->cspBpp,input->dy);

   curBuffer.start=pict.rtStart;
   curBuffer.stop=pict.rtStop;
   curBuffer.fieldType=pict.fieldtype;

   if (debugPrint)
    DPRINTF(_l("TimgFilterAvisynth: Buffering frame %i, %10.6f - %10.6f = %10.6f %s"),curInFrameNo,curBuffer.start/10000.0,curBuffer.stop/10000.0,(curBuffer.stop-curBuffer.start)/10000.0,_l("--"));
  }
 else
  {
   // Buffer frames with pulldown applied according to fieldtype interlace flags to get
   // constant frame rate TFF video
   //
   // Example:
   // +------------------- Number of previous frame (stored in pulldownBuffer)
   // | +----------------- Number of current frame
   // | | +--------------- TFF/BFF flag on previous frame
   // | | | +------------- TFF/BFF flag on current frame
   // | | | |       +----- Frame(s) produced by combining these top & bottom fields
   // | | | |       |
   // - - - - ------------
   // - 1 T T 1T 1B|
   // 1 2 T B 2T 2B|
   // 2 3 B B 2T 3B|
   // 3 4 B T 3T 4B|4T 4B|
   // 4 5 T T 5T 5B|
   // 5 6 T B 6T 6B|
   // 6 7 B B 6T 7B|
   // 7 8 B T 7T 8B|8T 8B|
   // 8 9 T T 9T 9B|
   // ...

   // Buffer to store the previous frame
   TframeBuffer& pulldownBuffer=buffers[numBuffers];

   // pulldownBuffer has a frameNo of -1 if it was just initialized
   bool hasPulldownBuffer=(pulldownBuffer.frameNo >= 0);

   bool lastTFF=(pulldownBuffer.fieldType & FIELD_TYPE::INT_TFF) != 0;
   bool curTFF=(pict.fieldtype & FIELD_TYPE::INT_TFF) != 0;

   REFERENCE_TIME curDuration=pict.rtStop-pict.rtStart;
   REFERENCE_TIME lastDuration=(hasPulldownBuffer ? pulldownBuffer.stop-pulldownBuffer.start : curDuration);

   // 3:2 pulldown has alternating long and short frame durations, figure out which is which
   REFERENCE_TIME shortDuration;
   REFERENCE_TIME longDuration;

   if (curDuration < lastDuration)
    {
     shortDuration=curDuration;
     longDuration=lastDuration;
    }
   else
    {
     shortDuration=lastDuration;
     longDuration=curDuration;
    }

   if (!hasPulldownBuffer)
    {
     // Just copy the first frame, whatever it is

     if (isYV12)
      {
       TffPict::copy(curBuffer.data[0],curBuffer.pitch[0],input->src[0],input->stride1[0],input->dx  ,input->dy);
       TffPict::copy(curBuffer.data[1],curBuffer.pitch[1],input->src[1],input->stride1[1],input->dx/2,input->dy/2);
       TffPict::copy(curBuffer.data[2],curBuffer.pitch[2],input->src[2],input->stride1[2],input->dx/2,input->dy/2);
      }
     else
      TffPict::copy(curBuffer.data[0],curBuffer.pitch[0],input->src[0],input->stride1[0],input->dx*input->cspBpp,input->dy);

     curBuffer.start=pict.rtStart;
     curBuffer.stop=pict.rtStop;

     if (debugPrint)
      DPRINTF(_l("TimgFilterAvisynth: Buffering frame %i, %10.6f - %10.6f = %10.6f %s"),curInFrameNo,curBuffer.start/10000.0,curBuffer.stop/10000.0,(curBuffer.stop-curBuffer.start)/10000.0,_l("TT"));
    }
   else
    {
     // Combine fields into new frames and adjust the timestamps accordingly

     if (lastTFF)
      {
       // T -> x

       if (isYV12)
        {
         TffPict::copy(curBuffer.data[0],curBuffer.pitch[0],input->src[0],input->stride1[0],input->dx  ,input->dy);
         TffPict::copy(curBuffer.data[1],curBuffer.pitch[1],input->src[1],input->stride1[1],input->dx/2,input->dy/2);
         TffPict::copy(curBuffer.data[2],curBuffer.pitch[2],input->src[2],input->stride1[2],input->dx/2,input->dy/2);
        }
       else
        TffPict::copy(curBuffer.data[0],curBuffer.pitch[0],input->src[0],input->stride1[0],input->dx*input->cspBpp,input->dy);

       char_t* fields;

       if (curTFF)
        {
         // T -> T
         curBuffer.start=pulldownBuffer.start+shortDuration;
         curBuffer.stop=pulldownBuffer.stop+shortDuration;

         fields=_l("TT");
        }
       else
        {
         hasPulldown=true;

         // T -> B
         curBuffer.start=pulldownBuffer.start+shortDuration;
         curBuffer.stop=pulldownBuffer.stop+shortDuration/2;

         fields=_l("TB");
        }

       if (debugPrint)
        DPRINTF(_l("TimgFilterAvisynth: Buffering frame %i, %10.6f - %10.6f = %10.6f %s"),curInFrameNo,curBuffer.start/10000.0,curBuffer.stop/10000.0,(curBuffer.stop-curBuffer.start)/10000.0,fields);
      }
     else
      {
       hasPulldown=true;

       // B -> x

       if (isYV12)
        {
         TffPict::copy(curBuffer.data[0],curBuffer.pitch[0]*2,pulldownBuffer.data[0],pulldownBuffer.pitch[0]*2,input->dx  ,input->dy/2);
         TffPict::copy(curBuffer.data[1],curBuffer.pitch[1]*2,pulldownBuffer.data[1],pulldownBuffer.pitch[1]*2,input->dx/2,input->dy/4);
         TffPict::copy(curBuffer.data[2],curBuffer.pitch[2]*2,pulldownBuffer.data[2],pulldownBuffer.pitch[2]*2,input->dx/2,input->dy/4);

         TffPict::copy(curBuffer.data[0]+curBuffer.pitch[0],curBuffer.pitch[0]*2,input->src[0]+input->stride1[0],input->stride1[0]*2,input->dx  ,input->dy/2);
         TffPict::copy(curBuffer.data[1]+curBuffer.pitch[1],curBuffer.pitch[1]*2,input->src[1]+input->stride1[1],input->stride1[1]*2,input->dx/2,input->dy/4);
         TffPict::copy(curBuffer.data[2]+curBuffer.pitch[2],curBuffer.pitch[2]*2,input->src[2]+input->stride1[2],input->stride1[2]*2,input->dx/2,input->dy/4);
        }
       else
        {
         TffPict::copy(curBuffer.data[0],curBuffer.pitch[0]*2,pulldownBuffer.data[0],pulldownBuffer.pitch[0]*2,input->dx*input->cspBpp,input->dy/2);

         TffPict::copy(curBuffer.data[0]+curBuffer.pitch[0],curBuffer.pitch[0]*2,input->src[0]+input->stride1[0],input->stride1[0]*2,input->dx*input->cspBpp,input->dy/2);
        }

       if (!curTFF)
        {
         // B -> B
         curBuffer.start=pulldownBuffer.start+shortDuration/2;
         curBuffer.stop=pulldownBuffer.stop+shortDuration/2;

         if (debugPrint)
          DPRINTF(_l("TimgFilterAvisynth: Buffering frame %i, %10.6f - %10.6f = %10.6f %s"),curInFrameNo,curBuffer.start/10000.0,curBuffer.stop/10000.0,(curBuffer.stop-curBuffer.start)/10000.0,_l("BB"));
        }
       else
        {
         // B -> T
         curBuffer.start=pulldownBuffer.start+shortDuration/2;
         curBuffer.stop=pulldownBuffer.stop;

         if (debugPrint)
          DPRINTF(_l("TimgFilterAvisynth: Buffering frame %i, %10.6f - %10.6f = %10.6f %s"),curInFrameNo,curBuffer.start/10000.0,curBuffer.stop/10000.0,(curBuffer.stop-curBuffer.start)/10000.0,_l("BT"));

         curBufferNo=(curBufferNo+1)%numBuffers;
         buffersFilled++;
         curInFrameNo++;

         TframeBuffer& curBuffer2=buffers[curBufferNo];

         curBuffer2.frameNo=curInFrameNo;

         if (isYV12)
          {
           TffPict::copy(curBuffer2.data[0],curBuffer2.pitch[0],input->src[0],input->stride1[0],input->dx  ,input->dy);
           TffPict::copy(curBuffer2.data[1],curBuffer2.pitch[1],input->src[1],input->stride1[1],input->dx/2,input->dy/2);
           TffPict::copy(curBuffer2.data[2],curBuffer2.pitch[2],input->src[2],input->stride1[2],input->dx/2,input->dy/2);
          }
         else
          TffPict::copy(curBuffer2.data[0],curBuffer2.pitch[0],input->src[0],input->stride1[0],input->dx*input->cspBpp,input->dy);

         curBuffer2.start=pulldownBuffer.start+shortDuration/2+shortDuration;
         curBuffer2.stop=pulldownBuffer.stop+shortDuration;
         curBuffer2.fieldType=FIELD_TYPE::INT_TFF;

         if (debugPrint)
          DPRINTF(_l("TimgFilterAvisynth: Buffering frame %i, %10.6f - %10.6f = %10.6f %s"),curInFrameNo,curBuffer2.start/10000.0,curBuffer2.stop/10000.0,(curBuffer2.stop-curBuffer2.start)/10000.0,_l("BT"));
        }
      }
    }

   // Frames that had pulldown applied are always TFF
   curBuffer.fieldType=FIELD_TYPE::INT_TFF;

   if (isYV12)
    {
     TffPict::copy(pulldownBuffer.data[0],pulldownBuffer.pitch[0],input->src[0],input->stride1[0],input->dx  ,input->dy);
     TffPict::copy(pulldownBuffer.data[1],pulldownBuffer.pitch[1],input->src[1],input->stride1[1],input->dx/2,input->dy/2);
     TffPict::copy(pulldownBuffer.data[2],pulldownBuffer.pitch[2],input->src[2],input->stride1[2],input->dx/2,input->dy/2);
    }
   else
    TffPict::copy(pulldownBuffer.data[0],pulldownBuffer.pitch[0],input->src[0],input->stride1[0],input->dx*input->cspBpp,input->dy);

   pulldownBuffer.start=pict.rtStart;
   pulldownBuffer.stop=pict.rtStop;
   pulldownBuffer.fieldType=pict.fieldtype;
   pulldownBuffer.frameNo=0;
  }

 if (applyPulldown == 2)
  {
   // Twiddle timestamps on current frame

   // Buffer to store the previous frame properties
   TframeBuffer& lastBuffer=buffers[numBuffers];

   // lastBuffer has a frameNo of -1 if it was just initialized
   bool hasLastBuffer=(lastBuffer.frameNo >= 0);

   if (hasLastBuffer)
    {
     REFERENCE_TIME lastDuration=lastBuffer.stop-lastBuffer.start;
     REFERENCE_TIME curDuration=curBuffer.stop-curBuffer.start;
     REFERENCE_TIME avgDuration=(curDuration+lastDuration)/2;

     lastBuffer.start=curBuffer.start;
     lastBuffer.stop=curBuffer.stop;

     if (curDuration > lastDuration)
      curBuffer.start+=(curDuration-avgDuration);
     else
      curBuffer.stop+=(avgDuration-curDuration);
    }
   else
    {
     lastBuffer.start=curBuffer.start;
     lastBuffer.stop=curBuffer.stop;
    }

   lastBuffer.frameNo=0;
  }

 curBufferNo=(curBufferNo+1)%numBuffers;

⌨️ 快捷键说明

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