diff options
author | magjed <magjed@chromium.org> | 2015-02-20 08:29:19 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-02-20 16:30:03 +0000 |
commit | dc556d2b54354adc95ee5474600f469f7ae65692 (patch) | |
tree | bb12e023e19fc017d598460eaea7f5226bd81927 /media | |
parent | 8b2a039c029653d4be508f6acce4cb162c68aea0 (diff) | |
download | chromium_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.mm | 27 |
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); |