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); }
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; }