Example #1
0
void HlsParser::CreateStreaminfo(std::shared_ptr<std::vector<TAG>> tag)
{
	std::vector<audiotrack> tmpaudiomedia;
	std::vector<subtrack> tmpsubmedia;
	std::vector<videotrack> tmpvideomedia;
	std::vector<TAG>::iterator tagitr = tag->begin();
	for (; tagitr != tag->end(); tagitr++)
	{
		switch ((*tagitr).tagname)
		{
		case TAGID::TAG_EXT_X_MEDIA:
		{
			std::vector<std::pair<ATTRID, std::string>>::iterator attritr = (*tagitr).attrccontainer.begin();
			std::vector<std::pair<ATTRID, std::string>>::iterator attritrend = (*tagitr).attrccontainer.end();
			std::vector<std::pair<ATTRID, std::string>>::iterator tmpiter = attritr;
			for (; tmpiter != (*tagitr).attrccontainer.end(); tmpiter++)
			{
				if (tmpiter->first == ATTRID::TYPE)
				{
					if (tmpiter->second == "AUDIO")
					{
						tmpaudiomedia.push_back(CreateAudioTrack(attritr, attritrend));
					}
					else if (tmpiter->second == "SUBTITLES")
					{
						tmpsubmedia.push_back(CreateSubTrack(attritr, attritrend));
					}
					break;
				}
			}
		}break;
		case TAGID::TAG_EXT_X_STREAM_INF:
		{
			std::vector<std::pair<ATTRID, std::string>>::iterator attritr = (*tagitr).attrccontainer.begin();
			std::vector<std::pair<ATTRID, std::string>>::iterator attritrend = (*tagitr).attrccontainer.end();
			videotrack tmpvideo = CreateVideoTrack(attritr, attritrend);
			tmpvideo.url = tagitr->tagurl;
			tmpvideomedia.push_back(tmpvideo);
		}break;
		default:break;
		}
	}

	GenerateStreaminfo(tmpaudiomedia, tmpsubmedia, tmpvideomedia);
}
Example #2
0
bool BinkDecoder::Open(const std::string &fileName)
{
	// open the file (read only)
	file.Open(fileName);
	if (!file.Is_Open())
	{
		BinkCommon::LogError("Can't open file " + fileName);
		return false;
	}

	// check the file signature
	signature = file.ReadUint32BE();
	if ((signature != kBIKfID) 
		&& (signature != kBIKgID)
		&& (signature != kBIKhID)
		&& (signature != kBIKiID))
	{
		BinkCommon::LogError("Unknown Bink signature");
		return false;
	}

	fileSize = file.ReadUint32LE() + 8;

	nFrames = file.ReadUint32LE();

	if (nFrames > 1000000)
	{
		BinkCommon::LogError("Invalid header, more than 1000000 frames");
		return false;
	}

	largestFrameSize = file.ReadUint32LE();
	if (largestFrameSize > fileSize)
	{
		BinkCommon::LogError("Largest frame size is greater than file size");
		return false;
	}

	// skip some unknown data
	file.Skip(4);

	frameWidth  = file.ReadUint32LE();
	frameHeight = file.ReadUint32LE();
	fpsDividend = file.ReadUint32LE();
	fpsDivider  = file.ReadUint32LE();
	videoFlags  = file.ReadUint32LE();
	
	nAudioTracks = file.ReadUint32LE();

	// audio is available
	if (nAudioTracks)
	{
		// skip some useless values (unknown and audio channels)
		file.Skip(4 * nAudioTracks);

		for (uint32_t i = 0; i < nAudioTracks; i++)
		{
			uint16_t sampleRate = file.ReadUint16LE();
			uint16_t flags      = file.ReadUint16LE();

			CreateAudioTrack(sampleRate, flags);
		}

		// skip the audio track IDs
		file.Skip(4 * nAudioTracks);
	}

	// read the video frames
	frames.resize(nFrames);

	uint32_t pos, nextPos;

	nextPos = file.ReadUint32LE();
	
	for (uint32_t i = 0; i < nFrames; i++)
	{
		pos = nextPos;
		if (i == nFrames - 1)
		{
			nextPos = fileSize;
			frames[i].keyFrame = 0;
		}
		else
		{
			nextPos = file.ReadUint32LE();
			frames[i].keyFrame = pos & 1;
		}

		pos &= ~1;
		nextPos &= ~1;

		frames[i].offset = pos;
		frames[i].size   = nextPos - pos;
	}

	// determine buffer sizes for audio tracks
	file.Seek(frames[0].offset);

	for (uint32_t trackIndex = 0; trackIndex < audioTracks.size(); trackIndex++)
	{
		// check for audio
		uint32_t audioPacketSize = file.ReadUint32LE();
			
		if (audioPacketSize >= 4)
		{
			// size in bytes of largest decoded audio
			uint32_t reportedSize = file.ReadUint32LE();

			AudioTrack *track = audioTracks[trackIndex];

			// size in bytes
			track->bufferSize = reportedSize;
			track->buffer = new uint8_t[reportedSize];

			// skip to next audio track (and -4 for reportedSize int we read) 
			file.Skip(audioPacketSize-4);
		}
		else
		{
			file.Skip(audioPacketSize);
		}
	}

	hasAlpha = videoFlags & kFlagAlpha;
	swapPlanes = signature >= kBIKhID;

	InitBundles();
	InitTrees();

	uint32_t width  = frameWidth;
	uint32_t height = frameHeight;

	// init plane memory
	Plane newPlane;
	planes.push_back(newPlane);

	// luma plane
	planes.back().Init(width, height);

	// chroma planes
	width  /= 2;
	height /= 2;

	// 1
	planes.push_back(newPlane);
	planes.back().Init(width, height);

	// 2
	planes.push_back(newPlane);
	planes.back().Init(width, height);

	// alpha plane
	if (hasAlpha)
	{
		width  *= 2;
		height *= 2;

		planes.push_back(newPlane);
		planes.back().Init(width, height);
	}

	return true;
}