Skip to content

Commit

Permalink
Fixes video recorder ffmpeg on Centos7 and RHEL7 (openai#1893)
Browse files Browse the repository at this point in the history
* Conditionally select different arguments for ffmpeg, and add meaningful error for third party application in charge of encoding

* Consistency with other logger() calls

Co-authored-by: J K Terry <[email protected]>
  • Loading branch information
zlig and jkterry1 authored Jul 27, 2021
1 parent 41e571d commit fe1e083
Showing 1 changed file with 51 additions and 22 deletions.
73 changes: 51 additions & 22 deletions gym/wrappers/monitoring/video_recorder.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,27 +266,49 @@ def version_info(self):
}

def start(self):
self.cmdline = (self.backend,
'-nostats',
'-loglevel', 'error', # suppress warnings
'-y',

# input
'-f', 'rawvideo',
'-s:v', '{}x{}'.format(*self.wh),
'-pix_fmt',('rgb32' if self.includes_alpha else 'rgb24'),
'-framerate', '%d' % self.frames_per_sec,
'-i', '-', # this used to be /dev/stdin, which is not Windows-friendly

# output
'-vf', 'scale=trunc(iw/2)*2:trunc(ih/2)*2',
'-vcodec', 'libx264',
'-pix_fmt', 'yuv420p',
'-r', '%d' % self.output_frames_per_sec,
self.output_path
)

logger.debug('Starting ffmpeg with "%s"', ' '.join(self.cmdline))
if self.backend == "ffmpeg":
self.cmdline = (self.backend,
'-nostats',
'-loglevel', 'error', # suppress warnings
'-y',

# input
'-f', 'rawvideo',
'-s:v', '{}x{}'.format(*self.wh),
'-pix_fmt',('rgb32' if self.includes_alpha else 'rgb24'),
'-r', '%d' % self.frames_per_sec,
'-i', '-', # this used to be /dev/stdin, which is not Windows-friendly

# output
'-an',
'-r', '%d' % self.frames_per_sec,
'-vcodec', 'mpeg4',
'-pix_fmt', 'bgr24',
'-r', '%d' % self.output_frames_per_sec,
self.output_path
)
else:
self.cmdline = (self.backend,
'-nostats',
'-loglevel', 'error', # suppress warnings
'-y',

# input
'-f', 'rawvideo',
'-s:v', '{}x{}'.format(*self.wh),
'-pix_fmt',('rgb32' if self.includes_alpha else 'rgb24'),
'-framerate', '%d' % self.frames_per_sec,
'-i', '-', # this used to be /dev/stdin, which is not Windows-friendly

# output
'-vf', 'scale=trunc(iw/2)*2:trunc(ih/2)*2',
'-vcodec', 'libx264',
'-pix_fmt', 'yuv420p',
'-r', '%d' % self.output_frames_per_sec,
self.output_path
)

logger.debug('Starting %s with "%s"', self.backend, ' '.join(self.cmdline))
if hasattr(os,'setsid'): #setsid not present on Windows
self.proc = subprocess.Popen(self.cmdline, stdin=subprocess.PIPE, preexec_fn=os.setsid)
else:
Expand All @@ -300,7 +322,14 @@ def capture_frame(self, frame):
if frame.dtype != np.uint8:
raise error.InvalidFrame("Your frame has data type {}, but we require uint8 (i.e. RGB values from 0-255).".format(frame.dtype))

self.proc.stdin.write(frame.tobytes())
try:
if distutils.version.LooseVersion(np.__version__) >= distutils.version.LooseVersion('1.9.0'):
self.proc.stdin.write(frame.tobytes())
else:
self.proc.stdin.write(frame.tostring())
except Exception as e:
stdout, stderr = self.proc.communicate()
logger.error("VideoRecorder encoder failed: %s", stderr)

def close(self):
self.proc.stdin.close()
Expand Down

0 comments on commit fe1e083

Please sign in to comment.