ITS: Create function to extract 4 frames with equal interval
1. Avoid flakiness from extract_key_frames(), which could extract
wrong number of frames from preview recording.
2. Modified extract_all_frames_from_video() to handle forced fps
for stability.
Bug: 350867245
Test: run scene7 and scene8
Flag: TEST_ONLY
Change-Id: Idf87e5356e81d5cd40aab94a24b0411d9ad472e8
diff --git a/apps/CameraITS/utils/video_processing_utils.py b/apps/CameraITS/utils/video_processing_utils.py
index 2b9343a..308c2f0 100644
--- a/apps/CameraITS/utils/video_processing_utils.py
+++ b/apps/CameraITS/utils/video_processing_utils.py
@@ -235,50 +235,57 @@
return key_frame_files[-1]
-def extract_all_frames_from_video(log_path, video_file_name, img_format):
- """Extracts and returns a list of all extracted frames.
+def extract_all_frames_from_video(
+ log_path, video_file_name, img_format, video_fps=None):
+ """Extracts and returns a list of frames from a video using FFmpeg.
- Ffmpeg tool is used to extract all frames from the video at path
- <log_path>/<video_file_name>. The extracted key frames will have the name
- video_file_name with "_frame" suffix to identify the frames for video of each
- size. Each frame image will be differentiated with its frame index. All
- extracted key frames will be available in the provided img_format format at
- the same path as the video file.
+ Extract all frames from the video at path <log_path>/<video_file_name>.
+ The extracted frames will have the name video_file_name with "_frame"
+ suffix to identify the frames for video of each size. Each frame image
+ will be differentiated with its frame index. All extracted rames will be
+ available in the provided img_format format at the same path as the video.
The run time flag '-loglevel quiet' hides the information from terminal.
In order to see the detailed output of ffmpeg command change the loglevel
option to 'info'.
Args:
- log_path: str; path for video file directory
+ log_path: str; directory containing video file.
video_file_name: str; name of the video file.
- img_format: str; type of image to export frames into. ex. 'png'
+ img_format: str; desired image format for export frames. ex. 'png'
+ video_fps: str; fps of imported video.
Returns:
- key_frame_files: An ordered list of paths for each frame extracted from the
- video
+ an ordered list of paths to the extracted frame images.
"""
logging.debug('Extracting all frames')
ffmpeg_image_name = f"{video_file_name.split('.')[0]}_frame"
logging.debug('ffmpeg_image_name: %s', ffmpeg_image_name)
ffmpeg_image_file_names = (
f'{os.path.join(log_path, ffmpeg_image_name)}_%04d.{img_format}')
- cmd = [
- 'ffmpeg', '-i', os.path.join(log_path, video_file_name),
- '-vsync', 'passthrough', # prevents frame drops during decoding
- ffmpeg_image_file_names, '-loglevel', 'quiet'
- ]
- _ = subprocess.call(cmd,
- stdin=subprocess.DEVNULL,
- stdout=subprocess.DEVNULL,
- stderr=subprocess.DEVNULL)
+ if video_fps:
+ cmd = [
+ 'ffmpeg', '-i', os.path.join(log_path, video_file_name),
+ '-r', video_fps, # force a constant frame rate for reliability
+ ffmpeg_image_file_names, '-loglevel', 'quiet'
+ ]
+ else:
+ cmd = [
+ 'ffmpeg', '-i', os.path.join(log_path, video_file_name),
+ '-vsync', 'passthrough', # prevents frame drops during decoding
+ ffmpeg_image_file_names, '-loglevel', 'quiet'
+ ]
+ subprocess.call(cmd,
+ stdin=subprocess.DEVNULL,
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL)
- file_list = sorted(
- [_ for _ in os.listdir(log_path) if (_.endswith(img_format)
- and ffmpeg_image_name in _)])
- if not file_list:
+ files = sorted(
+ [file for file in os.listdir(log_path) if
+ (file.endswith(img_format) and ffmpeg_image_name in file)])
+ if not files:
raise AssertionError('No frames extracted. Check source video.')
- return file_list
+ return files
def extract_last_key_frame_from_recording(log_path, file_name):