示例#1
0
void FFMatroskaVideo::DecodeNextFrame() {
	if (HasPendingDelayedFrames()) return;

	AVPacket Packet;
	InitNullPacket(Packet);

	while (PacketNumber < Frames.size()) {
		// The additional indirection is because the packets are stored in
		// presentation order and not decoding order, this is unnoticeable
		// in the other sources where less is done manually
		const TFrameInfo &FI = Frames[Frames[PacketNumber].OriginalPos];
		unsigned int FrameSize = FI.FrameSize;
		ReadFrame(FI.FilePos, FrameSize, TCC.get(), MC);

		Packet.data = MC.Buffer;
		Packet.size = FrameSize;
		Packet.flags = FI.KeyFrame ? AV_PKT_FLAG_KEY : 0;

		PacketNumber++;

		if (DecodePacket(&Packet))
			return;
	}

	FlushFinalFrames();
}
示例#2
0
bool BaseDecoderTest::DecodeNextFrame(Callback* cbk) {
  switch (decodeStatus_) {
  case Decoding:
    ReadFrame(&file_, &buf_);
    if (::testing::Test::HasFatalFailure()) {
      return false;
    }
    if (buf_.Length() == 0) {
      decodeStatus_ = EndOfStream;
      return true;
    }
    DecodeFrame(buf_.data(), buf_.Length(), cbk);
    if (::testing::Test::HasFatalFailure()) {
      return false;
    }
    return true;
  case EndOfStream: {
    int32_t iEndOfStreamFlag = 1;
    decoder_->SetOption(DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag);
    DecodeFrame(NULL, 0, cbk);
    decodeStatus_ = End;
    break;
  }
  case OpenFile:
  case End:
    break;
  }
  return false;
}
示例#3
0
void BaseDecoderTest::DecodeFile(const char* fileName, Callback* cbk) {
  std::ifstream file(fileName, std::ios::in | std::ios::binary);
  ASSERT_TRUE(file.is_open());

  BufferedData buf;
  while (true) {
    ReadFrame(&file, &buf);
    if (::testing::Test::HasFatalFailure()) {
      return;
    }
    if (buf.Length() == 0) {
      break;
    }
    DecodeFrame(buf.data(), buf.Length(), cbk);
    if (::testing::Test::HasFatalFailure()) {
      return;
    }
  }

  int32_t iEndOfStreamFlag = 1;
  decoder_->SetOption(DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag);

  // Get pending last frame
  DecodeFrame(NULL, 0, cbk);
}
示例#4
0
void cDvbPlayer::Goto(int Index, bool Still)
{
  if (index) {
     LOCK_THREAD;
     Empty();
     if (++Index <= 0)
        Index = 1; // not '0', to allow GetNextIFrame() below to work!
     uint16_t FileNumber;
     off_t FileOffset;
     int Length;
     Index = index->GetNextIFrame(Index, false, &FileNumber, &FileOffset, &Length);
     if (Index >= 0 && NextFile(FileNumber, FileOffset) && Still) {
        uchar b[MAXFRAMESIZE];
        int r = ReadFrame(replayFile, b, Length, sizeof(b));
        if (r > 0) {
           if (playMode == pmPause)
              DevicePlay();
           DeviceStillPicture(b, r);
           ptsIndex.Put(isPesRecording ? PesGetPts(b) : TsGetPts(b, r), Index);
           }
        playMode = pmStill;
        }
     readIndex = Index;
     }
}
        bool ImageSequenceAsset::Open(  )
        {
            m_MaxMemUsed = 0;
            if ( !m_IsOpen ) {
                if ( m_CacheFrames ) {
                    std::vector<std::string>::iterator it = m_FileNames.begin();
                    while ( it != m_FileNames.end() ) {
                        std::string& fname = *it++;
                        // might not be an image file
                        pei::SurfacePtr s = ReadFrame( fname.c_str() );
                        if ( s ) {
                            m_FrameCache.push_back( s );
                            double w = s->GetWidth();
                            double h = s->GetHeight();

                            m_MaxMemUsed = (int)(m_MaxMemUsed + s->GetPitch() * h);
                            if ( m_Format.m_Width  < w ) m_Format.m_Width  = w;
                            if ( m_Format.m_Height < h ) m_Format.m_Height = h;
                            if ( m_Format.m_CanvasWidth  < w ) m_Format.m_CanvasWidth  = w;
                            if ( m_Format.m_CanvasHeight < h ) m_Format.m_CanvasHeight = h;
                        }
                    }
                    m_IsOpen = m_FrameCache.size() > 0;
                } else {
                    m_IsOpen = (m_FileNames.size() > 0 && DecodeFrame ( 0 ).get() != NULL);
                }
            }
            return m_IsOpen;
        }
示例#6
0
bool BaseDecoderTest::DecodeFile (const char* fileName, Callback* cbk) {
  std::ifstream file (fileName, std::ios::in | std::ios::binary);
  if (!file.is_open())
    return false;

  BufferedData buf;
  while (true) {
    if (false == ReadFrame(&file, &buf))
      return false;
    if (::testing::Test::HasFatalFailure()) {
      return false;
    }
    if (buf.Length() == 0) {
      break;
    }
    DecodeFrame (buf.data(), buf.Length(), cbk);
    if (::testing::Test::HasFatalFailure()) {
      return false;
    }
  }

  int32_t iEndOfStreamFlag = 1;
  decoder_->SetOption (DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag);

  // Get pending last frame
  DecodeFrame (NULL, 0, cbk);
  // Flush out last frames in decoder buffer
  int32_t num_of_frames_in_buffer = 0;
  decoder_->GetOption (DECODER_OPTION_NUM_OF_FRAMES_REMAINING_IN_BUFFER, &num_of_frames_in_buffer);
  for (int32_t i = 0; i < num_of_frames_in_buffer; ++i) {
    FlushFrame (cbk);
  }
  return true;
}
示例#7
0
void cBufferRecorder::FillInitialData(uchar *Data, int Size) {
	if(liveBufferIndex) {
		int64_t search_pts = Data ? TsGetPts(Data, Size) : -1;
		int maxWait = WAIT_WRITING_COUNT;
		uchar buffer[MAXFRAMESIZE];
		int Length;
		bool Independent;
		bool found = false;
		while(Running() && (!Data || (Size >= TS_SIZE))) {
			cUnbufferedFile *file = ((cLiveIndex *)liveBufferIndex)->GetNextBuffer(Length, Independent);
			if(!file) {
				if(((cLiveIndex *)liveBufferIndex)->WritingBufferCanceled()) {
					isyslog("Writing buffer canceled by user");
					if(fileSize) TsSetTeiOnBrokenPackets(Data, Size);
					((cLiveIndex *)liveBufferIndex)->SetBufferStart(0);
					liveBufferIndex = NULL;
					return;
				} // if
				if(!Data || !Size) return;
				if(!maxWait--)
					break;
				usleep(WAIT_WRITING_SLEEP);
				continue;
			} // if
			if (!NextFile())
				break;
			int len = ReadFrame(file, buffer, Length, sizeof(buffer));
			if(len < TS_SIZE) {
				isyslog("Failed to read live buffer data");
				break;
			} // if
			if(Data && Independent && (search_pts == TsGetPts(buffer, len))) {
				found = true;
				break;
			} // if
			if (index)
				index->Write(Independent, fileName->Number(), fileSize);
			if (recordFile->Write(buffer, len) < 0) {
				isyslog("Failed to write live buffer data");
				break;
			} // if
			fileSize += len;
		} // while
		if(Data) {
			isyslog("%lld bytes from live buffer %swritten to recording", fileSize, found ? "seamless ": "");
			if(!found && fileSize) TsSetTeiOnBrokenPackets(Data, Size);
			((cLiveIndex *)liveBufferIndex)->SetBufferStart(0);
			liveBufferIndex = NULL;
		} else if(((cLiveIndex *)liveBufferIndex)->WritingBufferCanceled()) {
			isyslog("%lld bytes from live buffer written to recording (aborted)", fileSize);
			((cLiveIndex *)liveBufferIndex)->SetBufferStart(0);
			liveBufferIndex = NULL;
		} // if
	} else if (Data && fileSize)
		TsSetTeiOnBrokenPackets(Data, Size);
} // cBufferRecorder::FillInitialData
示例#8
0
bool FFMatroskaAudio::ReadPacket(AVPacket *Packet) {
	unsigned int FrameSize = CurrentFrame->FrameSize;
	ReadFrame(CurrentFrame->FilePos, FrameSize, TCC.get(), MC);
	InitNullPacket(*Packet);
	Packet->data = MC.Buffer;
	Packet->size = FrameSize;
	Packet->flags = CurrentFrame->KeyFrame ? AV_PKT_FLAG_KEY : 0;

	return true;
}
 pei::SurfacePtr ImageSequenceAsset::DecodeFrame( int frame_num )
 {
     if ( (int)m_FrameCache.size() > frame_num ) {
         return m_FrameCache[ frame_num ];
     } else {
         bool decode_frame( (int)m_FileNames.size() > frame_num);
         if ( decode_frame ) {
             return ReadFrame( m_FileNames[frame_num].c_str() );
         }
     }
     return pei::SurfacePtr( );
 }
示例#10
0
文件: radio.c 项目: suborb/reelvdr
void cPluginRadio::Replaying(const cControl *Control, const char *Name, const char *FileName, bool On)
{
    IsRadioOrReplay = 0;
    radioAudio->DisableRadioTextProcessing();

    if (S_Activate == false) return;

    bool isRadio = false;

    if (On && FileName != NULL) {
        char *vdrfile;
        // check VDR PES-Recordings
        asprintf(&vdrfile, "%s/001.vdr", FileName);
        if (file_exists(vdrfile)) {
#if VDRVERSNUM >= 10703
            cFileName fn(FileName, false, true, true);
#else
            cFileName fn(FileName, false, true);
#endif
            cUnbufferedFile *f = fn.Open();
            if (f) {
                uchar b[4] = { 0x00, 0x00, 0x00, 0x00 };
                ReadFrame(f, b, sizeof (b), sizeof (b));
                fn.Close();
                isRadio = (b[0] == 0x00) && (b[1] == 0x00) && (b[2] == 0x01) && (0xc0 <= b[3] && b[3] <= 0xdf);
                }
            }
#if VDRVERSNUM >= 10703
        // check VDR TS-Recordings
        asprintf(&vdrfile, "%s/info", FileName);
        if (file_exists(vdrfile)) {
            cRecordingInfo rfi(FileName);
            if (rfi.Read()) {
                if (rfi.FramesPerSecond() > 0 && rfi.FramesPerSecond() < 18) // max. seen 13.88 @ ARD-RadioTP 320k
                    isRadio = true;
                }
            }
#endif
        free(vdrfile);
        }

    if (isRadio) {
        if (!file_exists(ReplayFile))
            dsyslog("radio: replay-image not found '%s'", ReplayFile);
        else
            radioImage->SetBackgroundImage(ReplayFile);
        radioAudio->EnableRadioTextProcessing(Name, 0, true);
        IsRadioOrReplay = 2;
        }
}
示例#11
0
FFMS_Track::FFMS_Track(ZipFile &stream) {
    TT = static_cast<FFMS_TrackType>(stream.Read<uint8_t>());
    TB.Num = stream.Read<int64_t>();
    TB.Den = stream.Read<int64_t>();
    MaxBFrames = stream.Read<int32_t>();
    UseDTS = !!stream.Read<uint8_t>();
    HasTS = !!stream.Read<uint8_t>();
    size_t FrameCount = static_cast<size_t>(stream.Read<uint64_t>());

    if (!FrameCount) return;

    FrameInfo temp{};
    Frames.reserve(FrameCount);
    for (size_t i = 0; i < FrameCount; ++i)
        Frames.push_back(ReadFrame(stream, i == 0 ? temp : Frames.back(), TT));

    if (TT == FFMS_TYPE_VIDEO)
        GeneratePublicInfo();
}
void VideoInput::MainLoop(void)
{
	fd_set fds;
	struct timeval tv;
	int r;

	cout << "VideoInput: Entering the main loop\n";

	while (playing)
	//while (playing && !errored)
	{
		FD_ZERO(&fds);
		FD_SET(fd, &fds);

		// Timeout
		tv.tv_sec = 2;
		tv.tv_usec = 0;

		r = select(fd+1, &fds, NULL, NULL, &tv);

		if (-1 == r)
		{
			if (EINTR == errno)
				continue;

			ErrnoError("select");
		}

		if (0 == r)
		{
			cout << "VideoInput: select timeout\n";
			errored = true;
		}

		if (ReadFrame())
			break;

		// EAGAIN - continue select loop
	}
	cout << "VideoInput: Exiting the main loop\n";
}
示例#13
0
////////////////////////////////////////////////////////////////////////////
///
/// Handle a block of data that is not frame aligned.
///
/// There may be the end of a frame, whole frames, the start of a frame or even just
/// the middle of the frame.
///
/// If we have incomplete blocks we build up a complete one in the saved data,
/// in order to process we need to acquire a frame plus the next header (for sync check)
/// we can end up with the save buffer having a frame + part of a header, and a secondary
/// save with just part of a header.
///
/// \return Collator status code, CollatorNoError indicates success.
///
CollatorStatus_t Collator_PesAudio_c::HandleElementaryStream(unsigned int Length, unsigned char *Data)
{
	CollatorStatus_t Status;
	//
	if (DiscardPesPacket)
	{
		COLLATOR_DEBUG("Discarding %d bytes of elementary stream\n", Length);
		return CodecNoError;
	}
	//
	// Copy our arguments to class members so the utility functions can
	// act upon it.
	//
	RemainingElementaryOrigin = Data;
	RemainingElementaryData = Data;
	RemainingElementaryLength = Length;
	//
	// Continually handle units of input until all input is exhausted (or an error occurs).
	//
	// Be aware that our helper functions may, during their execution, cause state changes
	// that result in a different branch being taken next time round the loop.
	//
	Status = CollatorNoError;
	while (Status == CollatorNoError && RemainingElementaryLength != 0)
	{
		COLLATOR_DEBUG("ES loop has %d bytes remaining\n", RemainingElementaryLength);
		//report_dump_hex( severity_note, RemainingElementaryData, min(RemainingElementaryLength, 188), 32, 0);
		switch (CollatorState)
		{
			case SeekingSyncWord:
				//
				// Try to lock to incoming frame headers
				//
				Status = SearchForSyncWord();
				break;
			case GotSynchronized:
			case SeekingFrameEnd:
				//
				// Read in the remains of the frame header
				//
				Status = ReadPartialFrameHeader();
				break;
			case ReadSubFrame:
			case SkipSubFrame:
				//
				// Squirrel away the frame
				//
				Status = ReadFrame();
				break;
			case GotCompleteFrame:
				//
				// Pass the accumulated subframes to the frame parser
				//
				InternalFrameFlush();
				CollatorState = ReadSubFrame;
				break;
			default:
				// should not occur...
				COLLATOR_DEBUG("General failure; wrong collator state");
				Status = CollatorError;
				break;
		}
	}
	if (Status != CollatorNoError)
	{
		// if anything when wrong then we need to resynchronize
		COLLATOR_DEBUG("General failure; seeking new synchronization sequence\n");
		DiscardAccumulatedData();
		CollatorState = SeekingSyncWord;
	}
	return Status;
}
示例#14
0
void cCuttingThread::Action(void)
{
  {
    sched_param tmp;
    tmp.sched_priority = CUTTER_PRIORITY;
    if(!pthread_setschedparam(pthread_self(), SCHED_OTHER, &tmp))
      printf("cCuttingThread::Action: cant set priority\n");
  }

  int bytes = 0;
  int __attribute__((unused)) burst_size = CUTTER_MAX_BANDWIDTH * CUTTER_TIMESLICE / 1000; // max bytes/timeslice 
  cTimeMs __attribute__((unused)) t;

  cMark *Mark = fromMarks.First();
  if (Mark) {
     fromFile = fromFileName->Open();
     toFile = toFileName->Open();
     if (!fromFile || !toFile)
        return;
     CheckTS(fromFile);
     fromFile->SetReadAhead(MEGABYTE(20));
     int Index = Mark->position;
     Mark = fromMarks.Next(Mark);
     int FileSize = 0;
     int CurrentFileNumber = 0;
     int LastIFrame = 0;
     toMarks.Add(0);
     toMarks.Save();
     uchar buffer[MAXFRAMESIZE];
     bool LastMark = false;
     bool cutIn = true;
     while (Running()) {
           uchar FileNumber;
           int FileOffset, Length;
           uchar PictureType;

           // Make sure there is enough disk space:

           AssertFreeDiskSpace(-1);

           // Read one frame:

           if (fromIndex->Get(Index++, &FileNumber, &FileOffset, &PictureType, &Length)) {
              if (FileNumber != CurrentFileNumber) {
                 fromFile = fromFileName->SetOffset(FileNumber, FileOffset);
                 fromFile->SetReadAhead(MEGABYTE(20));
                 CurrentFileNumber = FileNumber;
                 }
              if (fromFile) {
                 int len = ReadFrame(fromFile, buffer,  Length, sizeof(buffer));
                 if (len < 0) {
                    error = "ReadFrame";
                    break;
                    }
                 if (len != Length) {
                    CurrentFileNumber = 0; // this re-syncs in case the frame was larger than the buffer
                    Length = len;
                    }
                 }
              else {
                 error = "fromFile";
                 break;
                 }
              }
           else
              break;

           // Write one frame:

           if (PictureType == I_FRAME || PATPMT != NULL) { // every file shall start with an I_FRAME
              if (LastMark) // edited version shall end before next I-frame
                 break;
              if (FileSize == 0) {
                 if (PATPMT != NULL) {
                    if (toFile->Write(PATPMT, 2*TS_SIZE) < 0) // Add PATPMT to start of every file
                       break;
                    else
                       FileSize+=TS_SIZE*2;
                    }   
                 }
              else if (FileSize > MEGABYTE(Setup.MaxVideoFileSize)) {
                 toFile = toFileName->NextFile();
                 if (!toFile) {
                    error = "toFile 1";
                    break;
                    }
                 FileSize = 0;
                 if (PATPMT != NULL) {
                    if (toFile->Write(PATPMT, 2*TS_SIZE) < 0) // Add PATPMT to start of every file
                       break;
                    else
                       FileSize+=TS_SIZE*2;
                    }
                 }
              LastIFrame = 0;

              if (cutIn) {
                 cRemux::SetBrokenLink(buffer, Length);
                 cutIn = false;
                 }
              }
           if (toFile->Write(buffer, Length) < 0) {
              error = "safe_write";
              break;
              }
           if (!toIndex->Write(PictureType, toFileName->Number(), FileSize)) {
              error = "toIndex";
              break;
              }
           FileSize += Length;
           if (!LastIFrame)
              LastIFrame = toIndex->Last();

           // Check editing marks:

           if (Mark && Index >= Mark->position) {
              Mark = fromMarks.Next(Mark);
              toMarks.Add(LastIFrame);
              if (Mark)
                 toMarks.Add(toIndex->Last() + 1);
              toMarks.Save();
              if (Mark) {
                 Index = Mark->position;
                 Mark = fromMarks.Next(Mark);
                 CurrentFileNumber = 0; // triggers SetOffset before reading next frame
                 cutIn = true;
                 if (Setup.SplitEditedFiles) {
                    toFile = toFileName->NextFile();
                    if (!toFile) {
                       error = "toFile 2";
                       break;
                       }
                    FileSize = 0;
                    }
                 }
              else
                 LastMark = true;
              }

	   bytes += Length;
	   if(bytes >= burst_size) {
	     int elapsed = t.Elapsed();
	     int sleep = 0;
	     
#if CUTTER_REL_BANDWIDTH > 0 &&  CUTTER_REL_BANDWIDTH < 100
	     // stay under max. relative bandwidth

	     sleep = (elapsed * 100 / CUTTER_REL_BANDWIDTH) - elapsed;
	     //if(sleep<=0 && elapsed<=2) sleep = 1; 
	     //if(sleep) esyslog("cutter: relative bandwidth limit, sleep %d ms (chunk %dk / %dms)", sleep, burst_size/1024, CUTTER_TIMESLICE);
#endif
	     // stay under max. absolute bandwidth
	     if(elapsed < CUTTER_TIMESLICE) {
	       sleep = max(CUTTER_TIMESLICE - elapsed, sleep);
	       //if(sleep) esyslog("cutter: absolute bandwidth limit, sleep %d ms (chunk %dk / %dms)", sleep, burst_size/1024, CUTTER_TIMESLICE);
	     }

	     if(sleep>0)
	       cCondWait::SleepMs(sleep);
	     t.Set();
	     bytes = 0;
	   }

           }
     Recordings.TouchUpdate();
     }
  else
     esyslog("no editing marks found!");
}
void GSDrawScanlineCodeGenerator::Generate()
{
    push(ebx);
    push(esi);
    push(edi);
    push(ebp);

    const int params = 16;

    Init(params);

    if(!m_sel.edge)
    {
        align(16);
    }

    L("loop");

    // ecx = steps
    // esi = fzbr
    // edi = fzbc
    // xmm0 = z/zi
    // xmm2 = u (tme)
    // xmm3 = v (tme)
    // xmm5 = rb (!tme)
    // xmm6 = ga (!tme)
    // xmm7 = test

    bool tme = m_sel.tfx != TFX_NONE;

    TestZ(tme ? xmm5 : xmm2, tme ? xmm6 : xmm3);

    // ecx = steps
    // esi = fzbr
    // edi = fzbc
    // - xmm0
    // xmm2 = u (tme)
    // xmm3 = v (tme)
    // xmm5 = rb (!tme)
    // xmm6 = ga (!tme)
    // xmm7 = test

    SampleTexture();

    // ecx = steps
    // esi = fzbr
    // edi = fzbc
    // ebp = za
    // - xmm2
    // - xmm3
    // - xmm4
    // xmm5 = rb
    // xmm6 = ga
    // xmm7 = test

    AlphaTFX();

    // ecx = steps
    // esi = fzbr
    // edi = fzbc
    // ebp = za
    // xmm2 = gaf (TFX_HIGHLIGHT || TFX_HIGHLIGHT2 && !tcc)
    // xmm5 = rb
    // xmm6 = ga
    // xmm7 = test

    if(m_sel.fwrite)
    {
        movdqa(xmm3, xmmword[&m_env.fm]);
    }

    if(m_sel.zwrite)
    {
        movdqa(xmm4, xmmword[&m_env.zm]);
    }

    // ecx = steps
    // esi = fzbr
    // edi = fzbc
    // ebp = za
    // xmm2 = gaf (TFX_HIGHLIGHT || TFX_HIGHLIGHT2 && !tcc)
    // xmm3 = fm
    // xmm4 = zm
    // xmm5 = rb
    // xmm6 = ga
    // xmm7 = test

    TestAlpha();

    // ecx = steps
    // esi = fzbr
    // edi = fzbc
    // ebp = za
    // xmm2 = gaf (TFX_HIGHLIGHT || TFX_HIGHLIGHT2 && !tcc)
    // xmm3 = fm
    // xmm4 = zm
    // xmm5 = rb
    // xmm6 = ga
    // xmm7 = test

    ColorTFX();

    // ecx = steps
    // esi = fzbr
    // edi = fzbc
    // ebp = za
    // xmm3 = fm
    // xmm4 = zm
    // xmm5 = rb
    // xmm6 = ga
    // xmm7 = test

    Fog();

    // ecx = steps
    // esi = fzbr
    // edi = fzbc
    // ebp = za
    // xmm3 = fm
    // xmm4 = zm
    // xmm5 = rb
    // xmm6 = ga
    // xmm7 = test

    ReadFrame();

    // ecx = steps
    // esi = fzbr
    // edi = fzbc
    // ebp = za
    // xmm2 = fd
    // xmm3 = fm
    // xmm4 = zm
    // xmm5 = rb
    // xmm6 = ga
    // xmm7 = test

    TestDestAlpha();

    // fm |= test;
    // zm |= test;

    if(m_sel.fwrite)
    {
        por(xmm3, xmm7);
    }

    if(m_sel.zwrite)
    {
        por(xmm4, xmm7);
    }

    // int fzm = ~(fm == GSVector4i::xffffffff()).ps32(zm == GSVector4i::xffffffff()).mask();

    pcmpeqd(xmm1, xmm1);

    if(m_sel.fwrite && m_sel.zwrite)
    {
        movdqa(xmm0, xmm1);
        pcmpeqd(xmm1, xmm3);
        pcmpeqd(xmm0, xmm4);
        packssdw(xmm1, xmm0);
    }
    else if(m_sel.fwrite)
    {
        pcmpeqd(xmm1, xmm3);
        packssdw(xmm1, xmm1);
    }
    else if(m_sel.zwrite)
    {
        pcmpeqd(xmm1, xmm4);
        packssdw(xmm1, xmm1);
    }

    pmovmskb(edx, xmm1);
    not(edx);

    // ebx = fa
    // ecx = steps
    // edx = fzm
    // esi = fzbr
    // edi = fzbc
    // ebp = za
    // xmm2 = fd
    // xmm3 = fm
    // xmm4 = zm
    // xmm5 = rb
    // xmm6 = ga

    WriteZBuf();

    // ebx = fa
    // ecx = steps
    // edx = fzm
    // esi = fzbr
    // edi = fzbc
    // - ebp
    // xmm2 = fd
    // xmm3 = fm
    // - xmm4
    // xmm5 = rb
    // xmm6 = ga

    AlphaBlend();

    // ebx = fa
    // ecx = steps
    // edx = fzm
    // esi = fzbr
    // edi = fzbc
    // xmm2 = fd
    // xmm3 = fm
    // xmm5 = rb
    // xmm6 = ga

    WriteFrame(params);

    L("step");

    // if(steps <= 0) break;

    if(!m_sel.edge)
    {
        test(ecx, ecx);
        jle("exit", T_NEAR);

        Step();

        jmp("loop", T_NEAR);
    }

    L("exit");

    pop(ebp);
    pop(edi);
    pop(esi);
    pop(ebx);

    ret(8);
}
int CVxParamArray::InitializeIO(vx_context context, vx_graph graph, vx_reference ref, const char * io_params)
{
	// save reference object and get object attributes
	m_vxObjRef = ref;
	m_array = (vx_array)m_vxObjRef;
	ERROR_CHECK(vxQueryArray(m_array, VX_ARRAY_ATTRIBUTE_ITEMTYPE, &m_format, sizeof(m_format)));
	ERROR_CHECK(vxQueryArray(m_array, VX_ARRAY_ATTRIBUTE_CAPACITY, &m_capacity, sizeof(m_capacity)));
	ERROR_CHECK(vxQueryArray(m_array, VX_ARRAY_ATTRIBUTE_ITEMSIZE, &m_itemSize, sizeof(m_itemSize)));

	// process I/O parameters
	if (*io_params == ':') io_params++;
	while (*io_params) {
		char ioType[64], fileName[256];
		io_params = ScanParameters(io_params, "<io-operation>,<parameter>", "s,S", ioType, fileName);
		if (!_stricmp(ioType, "read"))
		{ // read request syntax: read,<fileName>[,ascii|binary]
			m_fileNameRead.assign(RootDirUpdated(fileName));
			m_fileNameForReadHasIndex = (m_fileNameRead.find("%") != m_fileNameRead.npos) ? true : false;
			m_readFileIsBinary = (m_fileNameRead.find(".txt") != m_fileNameRead.npos) ? false : true;
			while (*io_params == ',') {
				char option[64];
				io_params = ScanParameters(io_params, ",ascii|binary", ",s", option);
				if (!_stricmp(option, "ascii")) {
					m_readFileIsBinary = false;
				}
				else if (!_stricmp(option, "binary")) {
					m_readFileIsBinary = true;
				}
				else ReportError("ERROR: invalid array read option: %s\n", option);
			}
		}
		else if (!_stricmp(ioType, "write"))
		{ // write request syntax: write,<fileName>[,ascii|binary]
			m_fileNameWrite.assign(RootDirUpdated(fileName));
			m_writeFileIsBinary = (m_fileNameWrite.find(".txt") != m_fileNameWrite.npos) ? false : true;
			while (*io_params == ',') {
				char option[64];
				io_params = ScanParameters(io_params, ",ascii|binary", ",s", option);
				if (!_stricmp(option, "ascii")) {
					m_writeFileIsBinary = false;
				}
				else if (!_stricmp(option, "binary")) {
					m_writeFileIsBinary = true;
				}
				else ReportError("ERROR: invalid array write option: %s\n", option);
			}
		}
		else if (!_stricmp(ioType, "compare"))
		{ // compare syntax: compare,fileName[,ascii|binary][,err{<x>;<y>[;<strength>][;<%mismatch>]}][,log{<fileName>}]
			m_fileNameCompareLog = "";
			m_fileNameCompare.assign(RootDirUpdated(fileName));
			m_compareFileIsBinary = (m_fileNameCompare.find(".txt") != m_fileNameCompare.npos) ? false : true;
			while (*io_params == ',') {
				char option[256];
				io_params = ScanParameters(io_params, ",ascii|binary|err{<x>;<y>[;<strength>][;<%mismatch>]}|log{<fileName>}", ",S", option);
				if (!_stricmp(option, "ascii")) {
					m_compareFileIsBinary = false;
				}
				else if (!_stricmp(option, "binary")) {
					m_compareFileIsBinary = true;
				}
				else if (!_strnicmp(option, "err{", 4)) {
					if (m_format == VX_TYPE_KEYPOINT) {
						const char * p = ScanParameters(&option[3], "{<x>;<y>;<strength>[;<%mismatch>]}", "{d;d;f", &m_errX, &m_errY, &m_errStrength);
						if (*p == ';') {
							ScanParameters(p, ";<%mismatch>}", ";f}", &m_errMismatchPercent);
						}
					}
					else if (m_format == VX_TYPE_COORDINATES2D) {
						const char * p = ScanParameters(&option[3], "{<x>;<y>[;<%mismatch>]}", "{d;d", &m_errX, &m_errY);
						if (*p == ';') {
							ScanParameters(p, ";<%mismatch>}", ";f}", &m_errMismatchPercent);
						}
					}
					else ReportError("ERROR: array compare option not supported for this array: %s\n", option);
				}
				else if (!_strnicmp(option, "log{", 4)) {
					option[strlen(option) - 1] = 0;
					m_fileNameCompareLog.assign(RootDirUpdated(&option[4]));
				}
				else ReportError("ERROR: invalid array compare option: %s\n", option);
			}
		}
		else if (!_stricmp(ioType, "view")) {
			m_displayName.assign(fileName);
			m_paramList.push_back(this);
		}
		else if (!_stricmp(ioType, "directive") && (!_stricmp(fileName, "VX_DIRECTIVE_AMD_COPY_TO_OPENCL") || !_stricmp(fileName, "sync-cl-write"))) {
			m_useSyncOpenCLWriteDirective = true;
		}
		else if (!_stricmp(ioType, "init")) {
			m_fileNameRead.assign(RootDirUpdated(fileName));
			m_fileNameForReadHasIndex = (m_fileNameRead.find("%") != m_fileNameRead.npos) ? true : false;
			m_readFileIsBinary = (m_fileNameRead.find(".txt") != m_fileNameRead.npos) ? false : true;
			while (*io_params == ',') {
				char option[64];
				io_params = ScanParameters(io_params, ",ascii|binary", ",s", option);
				if (!_stricmp(option, "ascii")) {
					m_readFileIsBinary = false;
				}
				else if (!_stricmp(option, "binary")) {
					m_readFileIsBinary = true;
				}
				else ReportError("ERROR: invalid array init option: %s\n", option);
			}
			if (ReadFrame(0) < 0)
				ReportError("ERROR: reading from input file for array init\n");
		}
		else ReportError("ERROR: invalid array operation: %s\n", ioType);
		if (*io_params == ':') io_params++;
		else if (*io_params) ReportError("ERROR: unexpected character sequence in parameter specification: %s\n", io_params);
	}

	return 0;
}
void GSDrawScanlineCodeGenerator::Generate()
{
	// TODO: on linux/mac rsi, rdi, xmm6-xmm15 are all caller saved

	push(rbx);
	push(rsi);
	push(rdi);
	push(rbp);
	push(r12);
	push(r13);

	sub(rsp, 8 + 10 * 16);
	
	for(int i = 6; i < 16; i++)
	{
		vmovdqa(ptr[rsp + (i - 6) * 16], Xmm(i));
	}

	mov(r10, (size_t)&m_test[0]);
	mov(r11, (size_t)&m_local);
	mov(r12, (size_t)m_local.gd);
	mov(r13, (size_t)m_local.gd->vm);

	Init();

	// rcx = steps
	// rsi = fza_base
	// rdi = fza_offset
	// r10 = &m_test[0]
	// r11 = &m_local
	// r12 = m_local->gd
	// r13 = m_local->gd.vm
	// xmm7 = vf (sprite && ltf)
	// xmm8 = z
	// xmm9 = f
	// xmm10 = s
	// xmm11 = t
	// xmm12 = q
	// xmm13 = rb
	// xmm14 = ga 
	// xmm15 = test

	if(!m_sel.edge)
	{
		align(16);
	}

L("loop");

	TestZ(xmm5, xmm6);

	// ebp = za

	if(m_sel.mmin)
	{
		SampleTextureLOD();
	}
	else
	{
		SampleTexture();
	}

	// ebp = za
	// xmm2 = rb
	// xmm3 = ga

	AlphaTFX();

	// ebp = za
	// xmm2 = rb
	// xmm3 = ga

	ReadMask();

	// ebp = za
	// xmm2 = rb
	// xmm3 = ga
	// xmm4 = fm
	// xmm5 = zm

	TestAlpha();

	// ebp = za
	// xmm2 = rb
	// xmm3 = ga
	// xmm4 = fm
	// xmm5 = zm

	ColorTFX();

	// ebp = za
	// xmm2 = rb
	// xmm3 = ga
	// xmm4 = fm
	// xmm5 = zm

	Fog();

	// ebp = za
	// xmm2 = rb
	// xmm3 = ga
	// xmm4 = fm
	// xmm5 = zm

	ReadFrame();

	// ebx = fa
	// ebp = za
	// xmm2 = rb
	// xmm3 = ga
	// xmm4 = fm
	// xmm5 = zm
	// xmm6 = fd

	TestDestAlpha();

	// ebx = fa
	// ebp = za
	// xmm2 = rb
	// xmm3 = ga
	// xmm4 = fm
	// xmm5 = zm
	// xmm6 = fd

	WriteMask();

	// ebx = fa
	// edx = fzm
	// ebp = za
	// xmm2 = rb
	// xmm3 = ga
	// xmm4 = fm
	// xmm5 = zm
	// xmm6 = fd

	WriteZBuf();

	// ebx = fa
	// edx = fzm
	// xmm2 = rb
	// xmm3 = ga
	// xmm4 = fm
	// xmm6 = fd

	AlphaBlend();

	// ebx = fa
	// edx = fzm
	// xmm2 = rb
	// xmm3 = ga
	// xmm4 = fm
	// xmm6 = fd

	WriteFrame();

L("step");

	// if(steps <= 0) break;

	if(!m_sel.edge)
	{
		test(rcx, rcx);

		jle("exit", T_NEAR);

		Step();

		jmp("loop", T_NEAR);
	}

L("exit");

	for(int i = 6; i < 16; i++)
	{
		vmovdqa(Xmm(i), ptr[rsp + (i - 6) * 16]);
	}

	add(rsp, 8 + 10 * 16);

	pop(r13);
	pop(r12);
	pop(rbp);
	pop(rdi);
	pop(rsi);
	pop(rbx);

	ret();
}
示例#18
0
Image *Animation::ReadNextFrame() // reading only
{
    currentFrame++;

    return ReadFrame(inFile);
}