Skip to content

Commit 6e614a6

Browse files
Make working with unique_ptr<PixelFrame> just as easy as working with shared_ptr<PixelFrame>
Summary: Unique pointers and simpler and lighter (no synchronized counter), and remove ownership ambiguities when changes need to be made. We should prefer them over shared_ptr whenever possible. This diff adds a bit of syntax sugar to support both equaly, but no actual behavior differences are expected, even if the code changes. Differential Revision: D68520764 fbshipit-source-id: 26da8ed4aed843fb9c81691bd398afed2e248523
1 parent de50fd9 commit 6e614a6

File tree

4 files changed

+123
-119
lines changed

4 files changed

+123
-119
lines changed

vrs/utils/PixelFrame.cpp

Lines changed: 56 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,14 @@ PixelFrame::PixelFrame(const ImageContentBlockSpec& spec)
222222
}
223223
}
224224

225+
PixelFrame::PixelFrame(PixelFormat pf, uint32_t w, uint32_t h, uint32_t stride)
226+
: imageSpec_{pf, w, h, stride, stride} {
227+
size_t size = imageSpec_.getRawImageSize();
228+
if (size != ContentBlock::kSizeUnknown) {
229+
frameBytes_.resize(size);
230+
}
231+
}
232+
225233
PixelFrame::PixelFrame(const ImageContentBlockSpec& spec, vector<uint8_t>&& frameBytes)
226234
: imageSpec_{spec}, frameBytes_{std::move(frameBytes)} {}
227235

@@ -253,14 +261,6 @@ void PixelFrame::init(PixelFormat pf, uint32_t w, uint32_t h, uint32_t stride, u
253261
}
254262
}
255263

256-
void PixelFrame::init(shared_ptr<PixelFrame>& inOutFrame, const ImageContentBlockSpec& spec) {
257-
if (!inOutFrame) {
258-
inOutFrame = make_shared<PixelFrame>(spec);
259-
} else {
260-
inOutFrame->init(spec);
261-
}
262-
}
263-
264264
void PixelFrame::swap(PixelFrame& other) noexcept {
265265
if (!hasSamePixels(other.imageSpec_)) {
266266
ImageContentBlockSpec tempSpec = other.imageSpec_;
@@ -292,16 +292,6 @@ void PixelFrame::blankFrame() {
292292
}
293293
}
294294

295-
bool PixelFrame::readFrame(
296-
shared_ptr<PixelFrame>& frame,
297-
RecordReader* reader,
298-
const ContentBlock& cb) {
299-
if (!frame) {
300-
frame = make_shared<PixelFrame>();
301-
}
302-
return frame->readFrame(reader, cb);
303-
}
304-
305295
bool PixelFrame::readFrame(RecordReader* reader, const ContentBlock& cb) {
306296
if (!XR_VERIFY(cb.getContentType() == ContentType::IMAGE)) {
307297
return false;
@@ -324,16 +314,6 @@ bool PixelFrame::readFrame(RecordReader* reader, const ContentBlock& cb) {
324314
return false;
325315
}
326316

327-
bool PixelFrame::readDiskImageData(
328-
shared_ptr<PixelFrame>& frame,
329-
RecordReader* reader,
330-
const ContentBlock& cb) {
331-
if (!frame) {
332-
frame = make_shared<PixelFrame>();
333-
}
334-
return frame->readDiskImageData(reader, cb);
335-
}
336-
337317
bool PixelFrame::readDiskImageData(RecordReader* reader, const ContentBlock& cb) {
338318
size_t blockSize = cb.getBlockSize();
339319
if (cb.getContentType() != ContentType::IMAGE || blockSize == ContentBlock::kSizeUnknown) {
@@ -433,16 +413,6 @@ bool PixelFrame::readCompressedFrame(const std::vector<uint8_t>& pixels, ImageFo
433413
return false;
434414
}
435415

436-
bool PixelFrame::readRawFrame(
437-
shared_ptr<PixelFrame>& frame,
438-
RecordReader* reader,
439-
const ImageContentBlockSpec& inputImageSpec) {
440-
if (!frame) {
441-
frame = make_shared<PixelFrame>(inputImageSpec);
442-
}
443-
return frame->readRawFrame(reader, inputImageSpec);
444-
}
445-
446416
void PixelFrame::normalizeFrame(
447417
const shared_ptr<PixelFrame>& sourceFrame,
448418
shared_ptr<PixelFrame>& outFrame,
@@ -528,44 +498,54 @@ inline uint8_t clipToUint8(int value) {
528498
}
529499

530500
bool PixelFrame::normalizeFrame(
531-
shared_ptr<PixelFrame>& normalizedFrame,
501+
shared_ptr<PixelFrame>& outNormalizedFrame,
532502
bool grey16supported,
533503
const NormalizeOptions& options) const {
534-
uint16_t bitsToShift = 0;
535-
uint32_t componentCount = 0;
536-
PixelFormat srcFormat = imageSpec_.getPixelFormat();
537504
// See if we can convert to something simple enough using Ocean
538-
PixelFormat targetPixelFormat = getNormalizedPixelFormat(srcFormat, grey16supported, options);
539-
if (srcFormat == targetPixelFormat) {
505+
PixelFormat targetPixelFormat =
506+
getNormalizedPixelFormat(imageSpec_.getPixelFormat(), grey16supported, options);
507+
if (imageSpec_.getPixelFormat() == targetPixelFormat) {
540508
return false;
541509
}
542-
if (normalizedFrame.get() == this) {
543-
normalizedFrame.reset();
510+
if (outNormalizedFrame.get() == this || !outNormalizedFrame) {
511+
outNormalizedFrame = make_shared<PixelFrame>();
512+
}
513+
return normalizeFrame(*outNormalizedFrame, grey16supported, options, targetPixelFormat);
514+
}
515+
516+
bool PixelFrame::normalizeFrame(
517+
PixelFrame& outNormalizedFrame,
518+
bool grey16supported,
519+
const NormalizeOptions& options,
520+
PixelFormat normalizedPixelFormat) const {
521+
PixelFormat srcFormat = imageSpec_.getPixelFormat();
522+
if (normalizedPixelFormat == PixelFormat::UNDEFINED) {
523+
normalizedPixelFormat = getNormalizedPixelFormat(srcFormat, grey16supported, options);
544524
}
545525
if (options.semantic == ImageSemantic::Depth && getPixelFormat() == PixelFormat::DEPTH32F &&
546-
targetPixelFormat == PixelFormat::GREY8) {
526+
normalizedPixelFormat == PixelFormat::GREY8) {
547527
if (options.min < options.max) {
548-
init(normalizedFrame, targetPixelFormat, getWidth(), getHeight());
528+
outNormalizedFrame.init(normalizedPixelFormat, getWidth(), getHeight());
549529
normalizeBufferWithRange(
550-
rdata(), normalizedFrame->wdata(), getWidth() * getHeight(), options.min, options.max);
530+
rdata(), outNormalizedFrame.wdata(), getWidth() * getHeight(), options.min, options.max);
551531
return true;
552532
}
553533
} else if (
554534
(options.semantic == ImageSemantic::ObjectClassSegmentation ||
555535
options.semantic == ImageSemantic::ObjectIdSegmentation) &&
556-
getPixelFormat() == PixelFormat::GREY16 && targetPixelFormat == PixelFormat::RGB8) {
557-
init(normalizedFrame, targetPixelFormat, getWidth(), getHeight());
536+
getPixelFormat() == PixelFormat::GREY16 && normalizedPixelFormat == PixelFormat::RGB8) {
537+
outNormalizedFrame.init(normalizedPixelFormat, getWidth(), getHeight());
558538
bool classSegmentation = options.semantic == ImageSemantic::ObjectClassSegmentation;
559539
const vector<RGBColor>& colors = classSegmentation ? getGetObjectClassSegmentationColors()
560540
: getGetObjectIdSegmentationColors();
561541
if (colors.size() >= (1UL << 16)) {
562542
unordered_set<uint16_t> usedColors;
563543
uint16_t lastColor = 0xffff;
564544
uint32_t srcStride = getStride();
565-
uint32_t dstStride = normalizedFrame->getStride();
545+
uint32_t dstStride = outNormalizedFrame.getStride();
566546
for (uint32_t h = 0; h < getHeight(); ++h) {
567547
const uint16_t* srcLine = data<uint16_t>(srcStride * h);
568-
RGBColor* dstLine = normalizedFrame->data<RGBColor>(dstStride * h);
548+
RGBColor* dstLine = outNormalizedFrame.data<RGBColor>(dstStride * h);
569549
for (uint32_t w = 0; w < getWidth(); ++w) {
570550
uint16_t color = srcLine[w];
571551
dstLine[w] = colors[color];
@@ -583,10 +563,12 @@ bool PixelFrame::normalizeFrame(
583563
return true;
584564
}
585565
}
586-
if (normalizeToPixelFormat(normalizedFrame, targetPixelFormat, options)) {
566+
if (normalizeToPixelFormat(outNormalizedFrame, normalizedPixelFormat, options)) {
587567
return true;
588568
}
589569
PixelFormat format = srcFormat;
570+
uint16_t bitsToShift = 0;
571+
uint32_t componentCount = 0;
590572
switch (srcFormat) {
591573
case PixelFormat::YUV_I420_SPLIT:
592574
case PixelFormat::YUV_420_NV21:
@@ -595,9 +577,9 @@ bool PixelFrame::normalizeFrame(
595577
const uint32_t width = imageSpec_.getWidth();
596578
const uint32_t height = imageSpec_.getHeight();
597579
const uint32_t stride = imageSpec_.getStride();
598-
init(normalizedFrame, PixelFormat::GREY8, width, height);
580+
outNormalizedFrame.init(PixelFormat::GREY8, width, height);
599581
const uint8_t* src = rdata();
600-
uint8_t* dst = normalizedFrame->wdata();
582+
uint8_t* dst = outNormalizedFrame.wdata();
601583
for (uint32_t line = 0; line < height; line++) {
602584
memcpy(dst, src, width);
603585
src += stride;
@@ -691,11 +673,11 @@ bool PixelFrame::normalizeFrame(
691673
if (format == srcFormat) {
692674
return false; // no conversion needed or supported
693675
}
694-
init(normalizedFrame, format, getWidth(), getHeight());
676+
outNormalizedFrame.init(format, getWidth(), getHeight());
695677
if (srcFormat == PixelFormat::BGR8) {
696678
// swap R & B
697679
const uint8_t* srcPtr = rdata();
698-
uint8_t* outPtr = normalizedFrame->wdata();
680+
uint8_t* outPtr = outNormalizedFrame.wdata();
699681
const uint32_t pixelCount = getWidth() * getHeight();
700682
for (uint32_t i = 0; i < pixelCount; ++i) {
701683
outPtr[2] = srcPtr[0];
@@ -706,20 +688,20 @@ bool PixelFrame::normalizeFrame(
706688
}
707689
} else if (srcFormat == PixelFormat::RGB32F) {
708690
// normalize float pixels to rgb8
709-
normalizeRGBXfloatToRGB8(rdata(), normalizedFrame->wdata(), getWidth() * getHeight(), 3);
691+
normalizeRGBXfloatToRGB8(rdata(), outNormalizedFrame.wdata(), getWidth() * getHeight(), 3);
710692
} else if (srcFormat == PixelFormat::RGBA32F) {
711693
// normalize float pixels to rgb8, drop alpha channel
712-
normalizeRGBXfloatToRGB8(rdata(), normalizedFrame->wdata(), getWidth() * getHeight(), 4);
694+
normalizeRGBXfloatToRGB8(rdata(), outNormalizedFrame.wdata(), getWidth() * getHeight(), 4);
713695
} else if (srcFormat == PixelFormat::DEPTH32F) {
714696
// normalize float pixels to grey8
715-
normalizeBuffer<float>(rdata(), normalizedFrame->wdata(), getWidth() * getHeight());
697+
normalizeBuffer<float>(rdata(), outNormalizedFrame.wdata(), getWidth() * getHeight());
716698
} else if (srcFormat == PixelFormat::SCALAR64F) {
717699
// normalize double pixels to grey8
718-
normalizeBuffer<double>(rdata(), normalizedFrame->wdata(), getWidth() * getHeight());
700+
normalizeBuffer<double>(rdata(), outNormalizedFrame.wdata(), getWidth() * getHeight());
719701
} else if (srcFormat == PixelFormat::BAYER8_RGGB) {
720702
// display as grey8(copy) for now
721703
const uint8_t* srcPtr = rdata();
722-
uint8_t* outPtr = normalizedFrame->wdata();
704+
uint8_t* outPtr = outNormalizedFrame.wdata();
723705
const uint32_t pixelCount = getWidth() * getHeight() * componentCount;
724706
for (uint32_t i = 0; i < pixelCount; ++i) {
725707
outPtr[i] = srcPtr[i];
@@ -730,10 +712,10 @@ bool PixelFrame::normalizeFrame(
730712
if (format == PixelFormat::GREY16) {
731713
// Convert from RAW10 to GREY10 directly into the output buffer
732714
if (!convertRaw10ToGrey10(
733-
normalizedFrame->wdata(), rdata(), getWidth(), getHeight(), getStride())) {
715+
outNormalizedFrame.wdata(), rdata(), getWidth(), getHeight(), getStride())) {
734716
return false;
735717
}
736-
uint16_t* ptr = normalizedFrame->data<uint16_t>();
718+
uint16_t* ptr = outNormalizedFrame.data<uint16_t>();
737719
const uint32_t pixelCount = getWidth() * getHeight() * componentCount;
738720
for (uint32_t i = 0; i < pixelCount; ++i) {
739721
ptr[i] <<= bitsToShift;
@@ -743,8 +725,8 @@ bool PixelFrame::normalizeFrame(
743725
// convert to GREY8 by copying 4 bytes of msb data, and dropping the 5th of lsb data...
744726
const uint8_t* srcPtr = rdata();
745727
const size_t srcStride = getStride();
746-
uint8_t* outPtr = normalizedFrame->wdata();
747-
const size_t outStride = normalizedFrame->getStride();
728+
uint8_t* outPtr = outNormalizedFrame.wdata();
729+
const size_t outStride = outNormalizedFrame.getStride();
748730
const uint32_t width = getWidth();
749731
for (uint32_t h = 0; h < getHeight(); h++, srcPtr += srcStride, outPtr += outStride) {
750732
const uint8_t* lineSrcPtr = srcPtr;
@@ -765,8 +747,8 @@ bool PixelFrame::normalizeFrame(
765747
// This is a placeholder implementation that simply writes out the source data in R, G and B.
766748
const uint8_t* srcPtr = rdata();
767749
const size_t srcStride = getStride();
768-
uint8_t* outPtr = normalizedFrame->wdata();
769-
const size_t outStride = normalizedFrame->getStride();
750+
uint8_t* outPtr = outNormalizedFrame.wdata();
751+
const size_t outStride = outNormalizedFrame.getStride();
770752
const uint32_t width = getWidth();
771753
for (uint32_t h = 0; h < getHeight(); h++, srcPtr += srcStride, outPtr += outStride) {
772754
const uint8_t* lineSrcPtr = srcPtr;
@@ -781,8 +763,8 @@ bool PixelFrame::normalizeFrame(
781763
// Unoptimized default version of YUY2 to RGB8 conversion
782764
const uint8_t* srcPtr = rdata();
783765
const size_t srcStride = getStride();
784-
uint8_t* outPtr = normalizedFrame->wdata();
785-
const size_t outStride = normalizedFrame->getStride();
766+
uint8_t* outPtr = outNormalizedFrame.wdata();
767+
const size_t outStride = outNormalizedFrame.getStride();
786768
const uint32_t width = getWidth();
787769
for (uint32_t h = 0; h < getHeight(); h++, srcPtr += srcStride, outPtr += outStride) {
788770
const uint8_t* lineSrcPtr = srcPtr;
@@ -807,15 +789,15 @@ bool PixelFrame::normalizeFrame(
807789
} else if (format == PixelFormat::GREY16 && bitsToShift > 0) {
808790
// 12/10 bit pixel scaling to 16 bit
809791
const uint16_t* srcPtr = data<uint16_t>();
810-
uint16_t* outPtr = normalizedFrame->data<uint16_t>();
792+
uint16_t* outPtr = outNormalizedFrame.data<uint16_t>();
811793
const uint32_t pixelCount = getWidth() * getHeight() * componentCount;
812794
for (uint32_t i = 0; i < pixelCount; ++i) {
813795
outPtr[i] = static_cast<uint16_t>(srcPtr[i] << bitsToShift);
814796
}
815-
} else if (XR_VERIFY(this->size() == 2 * normalizedFrame->size())) {
797+
} else if (XR_VERIFY(this->size() == 2 * outNormalizedFrame.size())) {
816798
// 16/12/10 bit pixel reduction to 8 bit
817799
const uint16_t* srcPtr = data<uint16_t>();
818-
uint8_t* outPtr = normalizedFrame->wdata();
800+
uint8_t* outPtr = outNormalizedFrame.wdata();
819801
const uint32_t pixelCount = getWidth() * getHeight() * componentCount;
820802
for (uint32_t i = 0; i < pixelCount; ++i) {
821803
outPtr[i] = (srcPtr[i] >> bitsToShift) & 0xFF;

0 commit comments

Comments
 (0)