-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Set frame rate of video extracting #382
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -272,13 +272,17 @@ def rq_handler(job, exc_type, exc_value, traceback): | |
############################# Internal implementation for server API | ||
|
||
class _FrameExtractor: | ||
def __init__(self, source_path, compress_quality, flip_flag=False): | ||
def __init__(self, source_path, compress_quality, flip_flag=False, frame_rate=0): | ||
# translate inversed range 1:95 to 2:32 | ||
translated_quality = 96 - compress_quality | ||
translated_quality = round((((translated_quality - 1) * (31 - 2)) / (95 - 1)) + 2) | ||
self.output = tempfile.mkdtemp(prefix='cvat-', suffix='.data') | ||
target_path = os.path.join(self.output, '%d.jpg') | ||
output_opts = '-start_number 0 -b:v 10000k -vsync 0 -an -y -q:v ' + str(translated_quality) | ||
output_opts = '-start_number 0 -b:v 10000k -an -y -q:v ' + str(translated_quality) | ||
if frame_rate > 0: | ||
output_opts += ' -r ' + str(frame_rate) | ||
else: | ||
output_opts += ' -vsync 0' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Option
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have tried to keep the vsync options. But if both -vsync and -r options are specified, ffmpeg reports error: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @zliang7, this is why '-r' option is not good here. See my thoughts below. |
||
if flip_flag: | ||
output_opts += ' -vf "transpose=2,transpose=2"' | ||
ff = FFmpeg( | ||
|
@@ -536,7 +540,7 @@ def _find_and_unpack_archive(upload_dir): | |
''' | ||
Search a video in upload dir and split it by frames. Copy frames to target dirs | ||
''' | ||
def _find_and_extract_video(upload_dir, output_dir, db_task, compress_quality, flip_flag, job): | ||
def _find_and_extract_video(upload_dir, output_dir, db_task, compress_quality, flip_flag, frame_rate, job): | ||
video = None | ||
for root, _, files in os.walk(upload_dir): | ||
fullnames = map(lambda f: os.path.join(root, f), files) | ||
|
@@ -548,7 +552,7 @@ def _find_and_extract_video(upload_dir, output_dir, db_task, compress_quality, f | |
if video: | ||
job.meta['status'] = 'Video is being extracted..' | ||
job.save_meta() | ||
extractor = _FrameExtractor(video, compress_quality, flip_flag) | ||
extractor = _FrameExtractor(video, compress_quality, flip_flag, frame_rate) | ||
for frame, image_orig_path in enumerate(extractor): | ||
image_dest_path = _get_frame_path(frame, output_dir) | ||
db_task.size += 1 | ||
|
@@ -696,14 +700,15 @@ def _create_thread(tid, params): | |
'compress': int(params.get('compress_quality', 50)), | ||
'segment': int(params.get('segment_size', sys.maxsize)), | ||
'labels': params['labels'], | ||
'frame_rate': int(params.get('frame_rate', 0)), | ||
} | ||
task_params['overlap'] = int(params.get('overlap_size', 5 if task_params['mode'] == 'interpolation' else 0)) | ||
task_params['overlap'] = min(task_params['overlap'], task_params['segment'] - 1) | ||
slogger.glob.info("Task #{} parameters: {}".format(tid, task_params)) | ||
|
||
if task_params['mode'] == 'interpolation': | ||
video = _find_and_extract_video(upload_dir, output_dir, db_task, | ||
task_params['compress'], task_params['flip'], job) | ||
task_params['compress'], task_params['flip'], task_params['frame_rate'], job) | ||
task_params['data'] = os.path.relpath(video, upload_dir) | ||
else: | ||
files =_find_and_compress_images(upload_dir, output_dir, db_task, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main problem with the approach is you will get annotation file which doesn't correspond to the video file. For example, originally you have a video file with 30FPS. If someone annotates the whole video file we will get
<frame000000>, <frame000001>, ...
inside the annotation file for every frame. Now you say that we can provide "custom" FPS. You will get another<frame000000>, <frame000001>, ...
which don't correspond to the original video file. How to match if you don't store extra parameters (e.g. custom frame rate) inside the annotation file?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not familiar with the internals of backend. Is there any difference between upload a video directly with upload all frame images pre-extracted locally?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zliang7, if you still have questions it is better to organize a meeting and discuss.