// From buffer bool ResourceRecord::fromBuffer(unsigned char* buf, size_t size, size_t &offset) { // Header if (m_name.fromBuffer(buf, size, offset)) { if (size - offset >= 10) { m_type = ntohs(*(uint16_t*)(buf + offset)); offset += 2; m_class = ntohs(*(uint16_t*)(buf + offset)); offset += 2; m_ttl = ntohl(*(uint32_t*)(buf + offset)); offset += 4; m_rdlen = ntohs(*(uint16_t*)(buf + offset)); offset += 2; return dataFromBuffer(buf, size, offset); } } return false; }
QVideoFrame MFTransform::makeVideoFrame() { QVideoFrame frame; if (!m_format.isValid()) return frame; IMFMediaBuffer *buffer = 0; do { if (FAILED(m_sample->ConvertToContiguousBuffer(&buffer))) break; QByteArray array = dataFromBuffer(buffer, m_format.frameHeight(), &m_bytesPerLine); if (array.isEmpty()) break; // Wrapping IMFSample or IMFMediaBuffer in a QVideoFrame is not possible because we cannot hold // IMFSample for a "long" time without affecting the rest of the topology. // If IMFSample is held for more than 5 frames decoder starts to reuse it even though it hasn't been released it yet. // That is why we copy data from IMFMediaBuffer here. frame = QVideoFrame(new QMemoryVideoBuffer(array, m_bytesPerLine), m_format.frameSize(), m_format.pixelFormat()); // WMF uses 100-nanosecond units, Qt uses microseconds LONGLONG startTime = -1; if (SUCCEEDED(m_sample->GetSampleTime(&startTime))) { frame.setStartTime(startTime * 0.1); LONGLONG duration = -1; if (SUCCEEDED(m_sample->GetSampleDuration(&duration))) frame.setEndTime((startTime + duration) * 0.1); } } while (false); if (buffer) buffer->Release(); return frame; }