1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
5 from telemetry
.internal
.image_processing
import frame_generator
6 from telemetry
.internal
.util
import external_modules
8 cv2
= external_modules
.ImportRequiredModule('cv2')
11 class VideoFileFrameGenerator(frame_generator
.FrameGenerator
):
12 """Provides a Frame Generator for a video file.
15 generator = VideoFileFrameGenerator(sys.argv[1]).GetGenerator()
16 for frame in generator:
20 _capture: The openCV video capture.
21 _frame_count: The number of frames in the video capture.
22 _frame_index: The frame number of the current frame.
23 _timestamp: The timestamp of the current frame.
24 _dimensions: The dimensions of the video capture."""
25 def __init__(self
, video_filename
, start_frame_index
=0):
26 """Initializes the VideoFileFrameGenerator object.
29 video_filename: str, The path to the video file.
30 start_frame_index: int, The number of frames to skip at the start of the
34 FrameReadError: A read error occurred during initialization."""
35 self
._capture
= cv2
.VideoCapture(video_filename
)
36 self
._frame
_count
= int(self
._capture
.get(cv2
.cv
.CV_CAP_PROP_FRAME_COUNT
))
37 self
._frame
_index
= -1
39 width
= self
._capture
.get(cv2
.cv
.CV_CAP_PROP_FRAME_WIDTH
)
40 height
= self
._capture
.get(cv2
.cv
.CV_CAP_PROP_FRAME_HEIGHT
)
41 self
._dimensions
= (int(width
), int(height
))
42 if self
._frame
_count
<= start_frame_index
:
43 raise frame_generator
.FrameReadError('Not enough frames in capture.')
44 while self
._frame
_index
< start_frame_index
- 1:
47 super(self
.__class
__, self
).__init
__()
49 def _ReadFrame(self
, skip_decode
=False):
50 """Reads the next frame, updates attributes.
53 skip_decode: Whether or not to skip decoding. Useful for seeking.
56 The frame if not EOF, 'None' if EOF.
59 FrameReadError: Unexpectedly failed to read a frame from the capture."""
60 if self
._frame
_index
>= self
._frame
_count
- 1:
62 self
._timestamp
= self
._capture
.get(cv2
.cv
.CV_CAP_PROP_POS_MSEC
)
64 ret
= self
._capture
.grab()
67 ret
, frame
= self
._capture
.read()
69 raise frame_generator
.FrameReadError(
70 'Failed to read frame from capture.')
71 self
._frame
_index
+= 1
75 def _CreateGenerator(self
):
77 frame
= self
._ReadFrame
()
84 def CurrentTimestamp(self
):
85 return self
._timestamp
89 def CurrentFrameNumber(self
):
90 return self
._frame
_index
95 return self
._dimensions