示例#1
0
void PacketReceiver::createFrames()
{
	frameReceived = avcodec_alloc_frame(); // av_frame_alloc()
	frameBGR = avcodec_alloc_frame(); // av_frame_alloc()
	if (frameReceived == NULL || frameBGR == NULL)
	{
		exit();
		throw NotEnoughSpaceException();
	}

	int numBytes = avpicture_get_size(FRAME_FORMAT_CV, codecCtx->width, codecCtx->height);
	frameBGRBuffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));
	if (frameBGRBuffer == NULL)
	{
		exit();
		throw NotEnoughSpaceException();
	}

	int error = avpicture_fill((AVPicture *) frameBGR,
							   frameBGRBuffer,
							   FRAME_FORMAT_CV,
							   codecCtx->width,
							   codecCtx->height);
	if (error < 0)
	{
		exit();
		throw KasinoException(avErr2Str(error));
	}
}
示例#2
0
void MetatileStructureSet::exportToROM(WritableROM& rom) {
  // TODO: support for adding metatile definitions
  // search freespace &c
  
  FreeSpaceList::iterator spaceIt = rom.freeSpace().getFreeSpace(
    exportSize());
    
  if (spaceIt == rom.freeSpace().freeSpaceList().end()) {
    throw NotEnoughSpaceException(TALES_SRCANDLINE,
                                  "MetatileStructureSet::exportToROM("
                                  "WritableROM&)",
                                  exportSize());
  }
  
  int writeAddress = spaceIt->address();
  address_ = spaceIt->address();
  
  rom.freeSpace().claimSpace(spaceIt, exportSize());
  
//  std::cout << "addr: " << writeAddress << std::endl;
  
  // Starting address of structure definitions
  int contentStartAddress = writeAddress
        + (index_.size() * ByteSizes::uint16Size);

  // Write the index
  for (MetatileIndexToStructureMap::iterator it = index_.begin();
       it != index_.end();
       it++) {
    int contentIndex = it->second;
    
    // Compute the address of the content
    Taddress contentAddress = (contentStartAddress 
                  + (contentIndex * MetatileStructure::dataSize));
    
    // Convert to banked address
    Taddress contentBankedAddress = LoadedROM
          ::directToBankedAddress(contentAddress);
    
    // Write to index
    Tbyte buffer[ByteSizes::uint16Size];
    ByteConversion::toBytes(contentBankedAddress,
                            buffer,
                            ByteSizes::uint16Size,
                            EndiannessTypes::little,
                            SignednessTypes::nosign);
    rom.directWrite(writeAddress + (it->first * ByteSizes::uint16Size),
                    buffer,
                    ByteSizes::uint16Size);
  }
  
  // Write content
  int metatileNum = 0;
  for (MetatileStructureCollection::iterator it = primaryStorage_.begin();
       it != primaryStorage_.end();
       it++) {
    // Write metatile to buffer
    Tbyte buffer[MetatileStructure::dataSize];
    it->writeToData(buffer);
    // Write buffer to table
    rom.directWrite(contentStartAddress
                      + (metatileNum * MetatileStructure::dataSize),
                    buffer,
                    MetatileStructure::dataSize);
    ++metatileNum;
  }
  
//  std::cout << "metatiles: " << metatileNum << std::endl;
//  std::cout << std::endl;
}
Taddress EditableLevelObjectEntryGroups::moveToNewBank(WritableROM& rom) {

//  std::cout << "Preparing to move to new bank" << std::endl;
  
  // More for convenience than anything else, we grab a whole bank of data
  // for use by this table (and a few bits of associated code).
  // Note that this basically requires expanding the ROM to 1 MB
  FreeSpaceList::iterator spaceIt
      = rom.freeSpace().getFreeSpace(LoadedROM::bankSize);
  
  // Throw if a full bank isn't available
  if (spaceIt == rom.freeSpace().freeSpaceList().end()) {
    throw NotEnoughSpaceException(TALES_SRCANDLINE,
                                  "EditableLevelObjectEntryGroups::"
                                  "exportToROM(WritableROM&)",
                                  LoadedROM::bankSize);
  }
  
//  std::cout << spaceIt->address() << " " << spaceIt->length() << std::endl;
                             
  Taddress newBaseAddress = spaceIt->address();
  
  // Claim the bank
  rom.freeSpace().claimSpace(spaceIt,
                             LoadedROM::bankSize);
  
//  std::cout << "New base address: " << newBaseAddress << std::endl;
  
  // Copy code segments C1 and C3 to new bank.
  // C1 and C3 both contain code that references the object table,
  // so they must (to avoid more complicated hacking) be in the same bank.
  // After rearranging the code, the new bank will contain C1, C3, and
  // the object table, in that order, starting from the beginning of the
  // bank
  
  // Copy C1 to start of bank
  Taddress newC1Address = newBaseAddress;
  std::memcpy(rom.directWrite(newC1Address),
              codeSegmentC1,
              lengthOfC1Segment);
              
  // Copy C3 to directly after C1
  Taddress newC3Address = newC1Address
                            + lengthOfC1Segment;
  std::memcpy(rom.directWrite(newC3Address),
              codeSegmentC3,
              lengthOfC3Segment);
  
  // Set new export address for table (directly after C3)
  int exportAddress = newBaseAddress
                    + lengthOfC1Segment
                    + lengthOfC3Segment;
                    
//  std::cout << "New C1 address: " << newC1Address << std::endl;
//  std::cout << "New C3 address: " << newC3Address << std::endl;
//  std::cout << "Export address: " << exportAddress << std::endl;
  
  // Update all the code that references the old locations of C1 and C3
  
  // Get the banked address for the new direct address of C1
  int newC1BankNum = LoadedROM::directToBankNum(newC1Address);
  int newC1BankedAddress = LoadedROM::directToBankedAddress(newC1Address);
  
  // Get the banked address for the new direct address of C3
  int newC3BankNum = LoadedROM::directToBankNum(newC3Address);
  int newC3BankedAddress = LoadedROM::directToBankedAddress(newC3Address);
  
  // Update bank number in code that calls C1
  ByteConversion::toBytes(newC1BankNum,
                          rom.directWrite(callReferenceToC1Bank),
                          ByteSizes::uint8Size,
                          EndiannessTypes::little,
                          SignednessTypes::nosign);
  
  // C1's banked address is the same (0000), so we don't need to update it
  // ... but do anyway for consistency
  ByteConversion::toBytes(newC1BankedAddress,
                          rom.directWrite(callReferenceToC1Address),
                          ByteSizes::uint16Size,
                          EndiannessTypes::little,
                          SignednessTypes::nosign);
  
  // Update banked address in code that calls C3
  ByteConversion::toBytes(newC3BankNum,
                          rom.directWrite(callReferenceToC3Bank),
                          ByteSizes::uint8Size,
                          EndiannessTypes::little,
                          SignednessTypes::nosign);
  
  // Update bank number in code that calls C3.
  ByteConversion::toBytes(newC3BankedAddress,
                          rom.directWrite(callReferenceToC3Address),
                          ByteSizes::uint16Size,
                          EndiannessTypes::little,
                          SignednessTypes::nosign);
  
  // C3 contains a hardcoded JP instruction into itself. Since we moved
  // C3, we have to update the JP to correspond to the new location.
  
  // Get new address of the JP instruction's address parameter
  Taddress addressOfNewJpParameter = newC3Address
                                      + offsetOfJpInC3;
  
  // Get new address of the JP instruction's jump point base
  Taddress addressOfNewJpBase = newC3Address
                                      + baseOffsetOfJpInC3;
  
  // Compute the new target address
  Taddress newJpTargetAddress = addressOfNewJpBase
                                  - absoluteLengthOfJpInC3;
                                  
//  std::cout << "New JP target: " << newJpTargetAddress << std::endl;
                                  
  // Convert to banked form
  Taddress newJpTargetBankedAddress
      = LoadedROM::directToBankedAddress(newJpTargetAddress);
  
  // Write the new target address to the JP parameter
  ByteConversion::toBytes(newJpTargetBankedAddress,
                          rom.directWrite(addressOfNewJpParameter),
                          ByteSizes::uint16Size,
                          EndiannessTypes::little,
                          SignednessTypes::nosign);
  
  // Get the banked address for the new direct address of the object table
//    int newTableBankNum
//        = LoadedROM::directToBankNum(exportAddress);
  int newTableBankedAddress
      = LoadedROM::directToBankedAddress(exportAddress);
  
  // Update C1 to refer to the new location of the object table
  ByteConversion::toBytes(newTableBankedAddress,
                          rom.directWrite(newC1Address
                                          + offsetOfTableReferenceInC1),
                          ByteSizes::uint16Size,
                          EndiannessTypes::little,
                          SignednessTypes::nosign);
  
  // Update C3 to refer to the new location of the object table
  ByteConversion::toBytes(newTableBankedAddress,
                          rom.directWrite(newC3Address
                                          + offsetOfTableReferenceInC3),
                          ByteSizes::uint16Size,
                          EndiannessTypes::little,
                          SignednessTypes::nosign);
  
  // Update table information
//    initialTableAddress_ = exportAddress;

//  initialTableContentSize_ = spaceIt->length()
//                              - exportAddress
//                              - tableHeaderSize_;

//  initialTableContentSize_ = exportAddress - spaceIt->address()
//                              - tableHeaderSize_;

//  initialTableContentSize_ = LoadedROM::bankSize;
                              
//  std::cout << initialTableContentSize_ << std::endl;
  
  // Mark that we've moved to a new bank
  movedToNewBank_ = true;
  
  return exportAddress;
}
示例#4
0
void PacketReceiver::threadFunc()
{
	init();
	mainWindow->log("Empfange Pakete…");

	int error;
	int gotPicture = 0;
	AVPacket packet;
	while (!quit)
	{
		try
		{
			packet = { 0 };
			av_init_packet(&packet);
			error = av_read_frame(formatCtx, &packet);
			if (error < 0)
			{
				throw KasinoException(avErr2Str(error));
			}

			if (packet.stream_index == videoStreamNr)
			{
				error = avcodec_decode_video2(codecCtx,
											  frameReceived,
											  &gotPicture,
											  &packet);
				if (error < 0)
				{
					throw KasinoException(avErr2Str(error));
				}

				if (gotPicture != 0)
				{
					sws_scale(imgConverter,
							  ((AVPicture*)frameReceived)->data,
							  ((AVPicture*)frameReceived)->linesize,
							  0,
							  codecCtx->height,
							  ((AVPicture *)frameBGR)->data,
							  ((AVPicture *)frameBGR)->linesize);

					cv::Mat imgCv;
					frame2mat(*frameBGR, imgCv);
					Frame* frame = new Frame(imgCv);
					if (frame == NULL)
					{
						throw NotEnoughSpaceException();
					}

					frame->pts = frameReceived->pkt_pts; // todo welchen Wert hier reinziehen?
					frame->quali = stream.getQuali();
					push(frame);
				}
			}
		}
		catch(KasinoException& e)
		{
			mainWindow->log(e.what(), ERROR);
		}

		av_free_packet(&packet);
	}
}