Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Unified Diff: tools/telemetry/telemetry/internal/image_processing/video.py

Issue 1647513002: Delete tools/telemetry. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tools/telemetry/telemetry/internal/image_processing/video.py
diff --git a/tools/telemetry/telemetry/internal/image_processing/video.py b/tools/telemetry/telemetry/internal/image_processing/video.py
deleted file mode 100644
index 43f2f2882ac2f8621cfde599be26bdb40a6e6ca5..0000000000000000000000000000000000000000
--- a/tools/telemetry/telemetry/internal/image_processing/video.py
+++ /dev/null
@@ -1,172 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import subprocess
-
-from catapult_base import cloud_storage # pylint: disable=import-error
-
-from telemetry.core import platform
-from telemetry.util import image_util
-from telemetry.util import rgba_color
-
-HIGHLIGHT_ORANGE_FRAME = rgba_color.WEB_PAGE_TEST_ORANGE
-
-class BoundingBoxNotFoundException(Exception):
- pass
-
-
-class Video(object):
- """Utilities for storing and interacting with the video capture."""
-
- def __init__(self, video_file_obj):
- assert video_file_obj.delete
- assert not video_file_obj.close_called
- self._video_file_obj = video_file_obj
- self._tab_contents_bounding_box = None
-
- def UploadToCloudStorage(self, bucket, target_path):
- """Uploads video file to cloud storage.
-
- Args:
- target_path: Path indicating where to store the file in cloud storage.
- """
- cloud_storage.Insert(bucket, target_path, self._video_file_obj.name)
-
- def GetVideoFrameIter(self):
- """Returns the iteration for processing the video capture.
-
- This looks for the initial color flash in the first frame to establish the
- tab content boundaries and then omits all frames displaying the flash.
-
- Yields:
- (time_ms, image) tuples representing each video keyframe. Only the first
- frame is a run of sequential duplicate bitmaps is typically included.
- time_ms is milliseconds since navigationStart.
- image may be a telemetry.core.Bitmap, or a numpy array depending on
- whether numpy is installed.
- """
- frame_generator = self._FramesFromMp4(self._video_file_obj.name)
-
- # Flip through frames until we find the initial tab contents flash.
- content_box = None
- for _, bmp in frame_generator:
- content_box = self._FindHighlightBoundingBox(
- bmp, HIGHLIGHT_ORANGE_FRAME)
- if content_box:
- break
-
- if not content_box:
- raise BoundingBoxNotFoundException(
- 'Failed to identify tab contents in video capture.')
-
- # Flip through frames until the flash goes away and emit that as frame 0.
- timestamp = 0
- for timestamp, bmp in frame_generator:
- if not self._FindHighlightBoundingBox(bmp, HIGHLIGHT_ORANGE_FRAME):
- yield 0, image_util.Crop(bmp, *content_box)
- break
-
- start_time = timestamp
- for timestamp, bmp in frame_generator:
- yield timestamp - start_time, image_util.Crop(bmp, *content_box)
-
- def _FindHighlightBoundingBox(self, bmp, color, bounds_tolerance=8,
- color_tolerance=8):
- """Returns the bounding box of the content highlight of the given color.
-
- Raises:
- BoundingBoxNotFoundException if the hightlight could not be found.
- """
- content_box, pixel_count = image_util.GetBoundingBox(bmp, color,
- tolerance=color_tolerance)
-
- if not content_box:
- return None
-
- # We assume arbitrarily that tabs are all larger than 200x200. If this
- # fails it either means that assumption has changed or something is
- # awry with our bounding box calculation.
- if content_box[2] < 200 or content_box[3] < 200:
- raise BoundingBoxNotFoundException('Unexpectedly small tab contents.')
-
- # TODO(tonyg): Can this threshold be increased?
- if pixel_count < 0.9 * content_box[2] * content_box[3]:
- raise BoundingBoxNotFoundException(
- 'Low count of pixels in tab contents matching expected color.')
-
- # Since we allow some fuzziness in bounding box finding, we want to make
- # sure that the bounds are always stable across a run. So we cache the
- # first box, whatever it may be.
- #
- # This relies on the assumption that since Telemetry doesn't know how to
- # resize the window, we should always get the same content box for a tab.
- # If this assumption changes, this caching needs to be reworked.
- if not self._tab_contents_bounding_box:
- self._tab_contents_bounding_box = content_box
-
- # Verify that there is only minor variation in the bounding box. If it's
- # just a few pixels, we can assume it's due to compression artifacts.
- for x, y in zip(self._tab_contents_bounding_box, content_box):
- if abs(x - y) > bounds_tolerance:
- # If this fails, it means either that either the above assumption has
- # changed or something is awry with our bounding box calculation.
- raise BoundingBoxNotFoundException(
- 'Unexpected change in tab contents box.')
-
- return self._tab_contents_bounding_box
-
- def _FramesFromMp4(self, mp4_file):
- host_platform = platform.GetHostPlatform()
- if not host_platform.CanLaunchApplication('avconv'):
- host_platform.InstallApplication('avconv')
-
- def GetDimensions(video):
- proc = subprocess.Popen(['avconv', '-i', video], stderr=subprocess.PIPE)
- dimensions = None
- output = ''
- for line in proc.stderr.readlines():
- output += line
- if 'Video:' in line:
- dimensions = line.split(',')[2]
- dimensions = map(int, dimensions.split()[0].split('x'))
- break
- proc.communicate()
- assert dimensions, ('Failed to determine video dimensions. output=%s' %
- output)
- return dimensions
-
- def GetFrameTimestampMs(stderr):
- """Returns the frame timestamp in integer milliseconds from the dump log.
-
- The expected line format is:
- ' dts=1.715 pts=1.715\n'
-
- We have to be careful to only read a single timestamp per call to avoid
- deadlock because avconv interleaves its writes to stdout and stderr.
- """
- while True:
- line = ''
- next_char = ''
- while next_char != '\n':
- next_char = stderr.read(1)
- line += next_char
- if 'pts=' in line:
- return int(1000 * float(line.split('=')[-1]))
-
- dimensions = GetDimensions(mp4_file)
- frame_length = dimensions[0] * dimensions[1] * 3
- frame_data = bytearray(frame_length)
-
- # Use rawvideo so that we don't need any external library to parse frames.
- proc = subprocess.Popen(['avconv', '-i', mp4_file, '-vcodec',
- 'rawvideo', '-pix_fmt', 'rgb24', '-dump',
- '-loglevel', 'debug', '-f', 'rawvideo', '-'],
- stderr=subprocess.PIPE, stdout=subprocess.PIPE)
- while True:
- num_read = proc.stdout.readinto(frame_data)
- if not num_read:
- raise StopIteration
- assert num_read == len(frame_data), 'Unexpected frame size: %d' % num_read
- yield (GetFrameTimestampMs(proc.stderr),
- image_util.FromRGBPixels(dimensions[0], dimensions[1], frame_data))

Powered by Google App Engine
This is Rietveld 408576698