Move MJPEG DHT insertion from SourceImpl to MJPEGServerImpl.

OpenCV imdecode supports images with no DHT, so it's not necessary to
add it on the source side.
This commit is contained in:
Peter Johnson
2016-11-11 23:17:39 -08:00
parent c80c4ae55c
commit 5ae1162378
2 changed files with 71 additions and 75 deletions

View File

@@ -16,44 +16,6 @@ using namespace cs;
static constexpr std::size_t kMaxFramesAvail = 32;
// DHT data for MJPEG images that don't have it.
static const unsigned char dhtData[] = {
0xff, 0xc4, 0x01, 0xa2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x01, 0x00, 0x03,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05,
0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04,
0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22,
0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15,
0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36,
0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66,
0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95,
0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2,
0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5,
0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
0xfa, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05,
0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22,
0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33,
0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25,
0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36,
0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66,
0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94,
0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,
0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa};
SourceImpl::SourceImpl(llvm::StringRef name)
: m_name{name}, m_frame{*this, nullptr} {}
@@ -291,29 +253,6 @@ std::vector<VideoMode> SourceImpl::EnumerateVideoModes(
void SourceImpl::PutFrame(VideoMode::PixelFormat pixelFormat, int width,
int height, llvm::StringRef data, Frame::Time time) {
std::size_t dataSize = data.size();
// If MJPEG, determine if we need to add DHT to it, and allocate enough space
// for adding it if required.
bool addDHT = false;
std::size_t locSOF = dataSize;
if (pixelFormat == VideoMode::kMJPEG) {
// Search first 2048 bytes (or until SOS) for DHT tag
for (llvm::StringRef::size_type i = 0; i < 2048 && i < data.size(); ++i) {
if (static_cast<unsigned char>(data[i]) != 0xff) continue; // not a tag
unsigned char tag = static_cast<unsigned char>(data[i + 1]);
if (tag == 0xda) break; // SOS
if (tag == 0xc4) goto done; // DHT
if (tag == 0xc0) locSOF = i; // SOF
}
// Only add DHT if we also found SOF (insertion point)
if (locSOF != dataSize) {
addDHT = true;
dataSize += sizeof(dhtData);
}
}
done:
std::unique_ptr<Frame::Data> frameData;
{
std::lock_guard<std::mutex> lock{m_poolMutex};
@@ -321,7 +260,7 @@ done:
int found = -1;
for (std::size_t i = 0; i < m_framesAvail.size(); ++i) {
// is it big enough?
if (m_framesAvail[i] && m_framesAvail[i]->capacity >= dataSize) {
if (m_framesAvail[i] && m_framesAvail[i]->capacity >= data.size()) {
// is it smaller than the last found?
if (found < 0 ||
m_framesAvail[i]->capacity < m_framesAvail[found]->capacity) {
@@ -333,7 +272,7 @@ done:
// if nothing found, allocate a new buffer
if (found < 0)
frameData.reset(new Frame::Data{dataSize});
frameData.reset(new Frame::Data{data.size()});
else
frameData = std::move(m_framesAvail[found]);
}
@@ -341,7 +280,7 @@ done:
// Initialize frame data
frameData->refcount = 0;
frameData->time = time;
frameData->size = dataSize;
frameData->size = data.size();
frameData->pixelFormat = pixelFormat;
frameData->width = width;
frameData->height = height;
@@ -349,16 +288,8 @@ done:
// Copy in image data
DEBUG4("Copying data to " << ((void*)frameData->data) << " from "
<< ((void*)data.data()) << " (" << data.size()
<< " bytes)" << (addDHT ? ", adding DHT" : ""));
if (addDHT) {
// Insert DHT data immediately before SOF
std::memcpy(frameData->data, data.data(), locSOF);
std::memcpy(frameData->data + locSOF, dhtData, sizeof(dhtData));
std::memcpy(frameData->data + locSOF + sizeof(dhtData),
data.data() + locSOF, data.size() - locSOF);
} else {
std::memcpy(frameData->data, data.data(), data.size());
}
<< " bytes)");
std::memcpy(frameData->data, data.data(), data.size());
// Update frame
{