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

Unified Diff: tools/telemetry/telemetry/core/platform/android_platform_backend.py

Issue 103723002: [Telemetry] Convert mp4 video to Timestamp+Bitmaps. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: bulach+szym comments Created 7 years 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/core/platform/android_platform_backend.py
diff --git a/tools/telemetry/telemetry/core/platform/android_platform_backend.py b/tools/telemetry/telemetry/core/platform/android_platform_backend.py
index fa4683455c71938d1278c6b2468687ef36296a12..d753372599c73b6968ee517e4574581b6cdc37ca 100644
--- a/tools/telemetry/telemetry/core/platform/android_platform_backend.py
+++ b/tools/telemetry/telemetry/core/platform/android_platform_backend.py
@@ -7,6 +7,7 @@ import os
import subprocess
import tempfile
+from telemetry.core import bitmap
from telemetry.core import exceptions
from telemetry.core import platform
from telemetry.core import util
@@ -25,6 +26,7 @@ except Exception:
_HOST_APPLICATIONS = [
+ 'avconv',
'ipfw',
]
@@ -200,9 +202,58 @@ class AndroidPlatformBackend(
self._video_recorder.wait()
self._video_recorder = None
- # TODO(tonyg/szym): Decode the mp4 and yield the (time, bitmap) tuples.
- raise NotImplementedError("mp4 video saved to %s, but Telemetry doesn't "
- "know how to decode it." % self._video_output)
+ for frame in self._FramesFromMp4(self._video_output):
+ yield frame
+
+ def _FramesFromMp4(self, mp4_file):
+ if not self.CanLaunchApplication('avconv'):
+ self.InstallApplication('avconv')
+
+ def GetDimensions(video):
+ proc = subprocess.Popen(['avconv', '-i', video], stderr=subprocess.PIPE)
+ for line in proc.stderr.readlines():
+ if 'Video:' in line:
+ dimensions = line.split(',')[2]
+ dimensions = map(int, dimensions.split()[0].split('x'))
+ break
+ proc.wait()
+ assert dimensions, 'Failed to determine video dimensions'
+ 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),
+ bitmap.Bitmap(3, dimensions[0], dimensions[1], frame_data))
def _GetFileContents(self, fname):
if not self._can_access_protected_file_contents:

Powered by Google App Engine
This is Rietveld 408576698