summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authormagjed <magjed@chromium.org>2015-02-20 08:29:19 -0800
committerCommit bot <commit-bot@chromium.org>2015-02-20 16:30:03 +0000
commitdc556d2b54354adc95ee5474600f469f7ae65692 (patch)
treebb12e023e19fc017d598460eaea7f5226bd81927 /media
parent8b2a039c029653d4be508f6acce4cb162c68aea0 (diff)
downloadchromium_src-dc556d2b54354adc95ee5474600f469f7ae65692.zip
chromium_src-dc556d2b54354adc95ee5474600f469f7ae65692.tar.gz
chromium_src-dc556d2b54354adc95ee5474600f469f7ae65692.tar.bz2
Mac Video Capture AVFoundation: Calculate compressed frame size for MJPEG.
The frame size we receive from AVFoundation is sometimes excessive, e.g. the size of the uncompressed frame. For example, for a JPEG YUV422, the reported size might be 1280*720*2 = 1.8MB, while the actual compressed data is only 260kB. In these cases, libyuv::MJPGToI420 spends a lot of time in libyuv::ValidateJpeg, as much as 25%. The reason for this is that ValidateJpeg starts at the end of the buffer and loops backwards looking for the End Of Image (EOI) marker. This CL tries to optimize these cases by finding the EOI by looping forwards instead of backwards, and reporting the actual frame size to libyuv::MJPGToI420. BUG=346634 Review URL: https://codereview.chromium.org/912293005 Cr-Commit-Position: refs/heads/master@{#317333}
Diffstat (limited to 'media')
-rw-r--r--media/video/capture/mac/video_capture_device_avfoundation_mac.mm27
1 files changed, 27 insertions, 0 deletions
diff --git a/media/video/capture/mac/video_capture_device_avfoundation_mac.mm b/media/video/capture/mac/video_capture_device_avfoundation_mac.mm
index f3c7ca7..6d71ef8 100644
--- a/media/video/capture/mac/video_capture_device_avfoundation_mac.mm
+++ b/media/video/capture/mac/video_capture_device_avfoundation_mac.mm
@@ -6,6 +6,8 @@
#import <CoreVideo/CoreVideo.h>
+#include <cstring> // For memchr.
+
#include "base/logging.h"
#include "base/mac/foundation_util.h"
#include "media/video/capture/mac/video_capture_device_mac.h"
@@ -30,6 +32,21 @@ media::VideoPixelFormat FourCCToChromiumPixelFormat(FourCharCode code) {
}
}
+// TODO(magjed): Remove this when Chromium has the latest libyuv version.
+// Returns frame size by finding the End Of Image marker, or 0 if not found.
+size_t JpegFrameSize(const char* sample, size_t sampleSize) {
+ // Jump to next marker (0xff), check for End Of Image (0xd9), repeat.
+ const char* end = sample + sampleSize - 1;
+ for (const char* it = sample;
+ (it = static_cast<const char*>(memchr(it, 0xff, end - it)));
+ ++it) {
+ if (it[1] == static_cast<char>(0xd9))
+ return 2 + (it - sample);
+ }
+ DLOG(WARNING) << "JPEG End Of Image (EOI) marker not found.";
+ return 0;
+}
+
@implementation VideoCaptureDeviceAVFoundation
#pragma mark Class methods
@@ -306,6 +323,16 @@ media::VideoPixelFormat FourCCToChromiumPixelFormat(FourCharCode code) {
// Expect the MJPEG data to be available as a contiguous reference, i.e.
// not covered by multiple memory blocks.
CHECK_EQ(lengthAtOffset, frameSize);
+
+ // TODO(magjed): Remove this when Chromium has the latest libyuv version.
+ // If |frameSize| is suspiciously high (>= 8 bpp), calculate the actual
+ // size by finding the end of image marker. The purpose is to speed up the
+ // jpeg decoding in the browser.
+ if (static_cast<int>(frameSize) >= dimensions.width * dimensions.height)
+ frameSize = JpegFrameSize(baseAddress, frameSize);
+
+ if (frameSize == 0)
+ return;
}
} else {
videoFrame = CoreMediaGlue::CMSampleBufferGetImageBuffer(sampleBuffer);