Recherche avancée

Médias (91)

Autres articles (79)

  • Qu’est ce qu’un éditorial

    21 juin 2013, par

    Ecrivez votre de point de vue dans un article. Celui-ci sera rangé dans une rubrique prévue à cet effet.
    Un éditorial est un article de type texte uniquement. Il a pour objectif de ranger les points de vue dans une rubrique dédiée. Un seul éditorial est placé à la une en page d’accueil. Pour consulter les précédents, consultez la rubrique dédiée.
    Vous pouvez personnaliser le formulaire de création d’un éditorial.
    Formulaire de création d’un éditorial Dans le cas d’un document de type éditorial, les (...)

  • Personnaliser en ajoutant son logo, sa bannière ou son image de fond

    5 septembre 2013, par

    Certains thèmes prennent en compte trois éléments de personnalisation : l’ajout d’un logo ; l’ajout d’une bannière l’ajout d’une image de fond ;

  • MediaSPIP v0.2

    21 juin 2013, par

    MediaSPIP 0.2 est la première version de MediaSPIP stable.
    Sa date de sortie officielle est le 21 juin 2013 et est annoncée ici.
    Le fichier zip ici présent contient uniquement les sources de MediaSPIP en version standalone.
    Comme pour la version précédente, il est nécessaire d’installer manuellement l’ensemble des dépendances logicielles sur le serveur.
    Si vous souhaitez utiliser cette archive pour une installation en mode ferme, il vous faudra également procéder à d’autres modifications (...)

Sur d’autres sites (12915)

  • How to get .mp4 videos from motion on a Raspberry Pi ?

    9 octobre 2016, par Maarti

    I use motion on my laptop and it works perfectly in any format. But when I use it on my Raspberry Pi 3 (Raspbian Jessie) with the Raspberry Camera V2, the only formats that work are : .avi and .swf.

    When I choose any other format, the output video is a "0 sec video" that is played and closed instantly.

    I would like to have .mp4 or .ogg output so I can read it easily with HTML5.

    Here is the motion codec documentation.

    Here is my config file :

    ############################################################
    # Daemon
    ############################################################

    # Start in daemon (background) mode and release terminal (default: off)
    daemon on

    # File to store the process ID, also called pid file. (default: not defined)
    process_id_file /var/run/motion/motion.pid

    ############################################################
    # Basic Setup Mode
    ############################################################

    # Start in Setup-Mode, daemon disabled. (default: off)
    setup_mode off


    # Use a file to save logs messages, if not defined stderr and syslog is used. (default: not defined)
    #logfile /mnt/camshare/Cam1/motion.log
    logfile /tmp/motion.log

    # Level of log messages [1..9] (EMR, ALR, CRT, ERR, WRN, NTC, INF, DBG, ALL). (default: 6 / NTC)
    log_level 2

    # Filter to log messages by type (COR, STR, ENC, NET, DBL, EVT, TRK, VID, ALL). (default: ALL)
    log_type all

    ###########################################################
    # Capture device options
    ############################################################

    # Videodevice to be used for capturing  (default /dev/video0)
    # for FreeBSD default is /dev/bktr0
    #videodevice /dev/video0

    # v4l2_palette allows to choose preferable palette to be use by motion
    # to capture from those supported by your videodevice. (default: 17)
    # E.g. if your videodevice supports both V4L2_PIX_FMT_SBGGR8 and
    # V4L2_PIX_FMT_MJPEG then motion will by default use V4L2_PIX_FMT_MJPEG.
    # Setting v4l2_palette to 2 forces motion to use V4L2_PIX_FMT_SBGGR8
    # instead.
    #
    # Values :
    # V4L2_PIX_FMT_SN9C10X : 0  'S910'
    # V4L2_PIX_FMT_SBGGR16 : 1  'BYR2'
    # V4L2_PIX_FMT_SBGGR8  : 2  'BA81'
    # V4L2_PIX_FMT_SPCA561 : 3  'S561'
    # V4L2_PIX_FMT_SGBRG8  : 4  'GBRG'
    # V4L2_PIX_FMT_SGRBG8  : 5  'GRBG'
    # V4L2_PIX_FMT_PAC207  : 6  'P207'
    # V4L2_PIX_FMT_PJPG    : 7  'PJPG'
    # V4L2_PIX_FMT_MJPEG   : 8  'MJPEG'
    # V4L2_PIX_FMT_JPEG    : 9  'JPEG'
    # V4L2_PIX_FMT_RGB24   : 10 'RGB3'
    # V4L2_PIX_FMT_SPCA501 : 11 'S501'
    # V4L2_PIX_FMT_SPCA505 : 12 'S505'
    # V4L2_PIX_FMT_SPCA508 : 13 'S508'
    # V4L2_PIX_FMT_UYVY    : 14 'UYVY'
    # V4L2_PIX_FMT_YUYV    : 15 'YUYV'
    # V4L2_PIX_FMT_YUV422P : 16 '422P'
    # V4L2_PIX_FMT_YUV420  : 17 'YU12'
    #
    v4l2_palette 7

    # Tuner device to be used for capturing using tuner as source (default /dev/tuner0)
    # This is ONLY used for FreeBSD. Leave it commented out for Linux
    ; tunerdevice /dev/tuner0

    # The video input to be used (default: -1)
    # Should normally be set to 0 or 1 for video/TV cards, and -1 for USB cameras
    input -1

    # The video norm to use (only for video capture and TV tuner cards)
    # Values: 0 (PAL), 1 (NTSC), 2 (SECAM), 3 (PAL NC no colour). Default: 0 (PAL)
    norm 0

    # The frequency to set the tuner to (kHz) (only for TV tuner cards) (default: 0)
    frequency 0

    # Rotate image this number of degrees. The rotation affects all saved images as
    # well as movies. Valid values: 0 (default = no rotation), 90, 180 and 270.
    rotate 0

    # Image width (pixels). Valid range: Camera dependent, default: 352
    #width 1024
    width 640

    # Image height (pixels). Valid range: Camera dependent, default: 288
    #height 576
    height 480

    # Maximum number of frames to be captured per second.
    # Valid range: 2-100. Default: 100 (almost no limit).
    framerate 15

    # Minimum time in seconds between capturing picture frames from the camera.
    # Default: 0 = disabled - the capture rate is given by the camera framerate.
    # This option is used when you want to capture images at a rate lower than 2 per second.
    minimum_frame_time 0

    # URL to use if you are using a network camera, size will be autodetected (incl http:// ftp:// mjpg:// or file:///)
    # Must be a URL that returns single jpeg pictures or a raw mjpeg stream. Default: Not defined
    ;netcam_url http://127.0.0.1/cgi-bin/raspicam.sh

    # Username and password for network camera (only if required). Default: not defined
    # Syntax is user:password
    ; netcam_userpass value

    # The setting for keep-alive of network socket, should improve performance on compatible net cameras.
    # off:   The historical implementation using HTTP/1.0, closing the socket after each http request.
    # force: Use HTTP/1.0 requests with keep alive header to reuse the same connection.
    # on:    Use HTTP/1.1 requests that support keep alive as default.
    # Default: off
    netcam_keepalive off

    # URL to use for a netcam proxy server, if required, e.g. "http://myproxy".
    # If a port number other than 80 is needed, use "http://myproxy:1234".
    # Default: not defined
    ; netcam_proxy value

    # Set less strict jpeg checks for network cameras with a poor/buggy firmware.
    # Default: off
    netcam_tolerant_check off

    # Let motion regulate the brightness of a video device (default: off).
    # The auto_brightness feature uses the brightness option as its target value.
    # If brightness is zero auto_brightness will adjust to average brightness value 128.
    # Only recommended for cameras without auto brightness
    auto_brightness off

    # Set the initial brightness of a video device.
    # If auto_brightness is enabled, this value defines the average brightness level
    # which Motion will try and adjust to.
    # Valid range 0-255, default 0 = disabled
    brightness 0

    # Set the contrast of a video device.
    # Valid range 0-255, default 0 = disabled
    contrast 0

    # Set the saturation of a video device.
    # Valid range 0-255, default 0 = disabled
    saturation 0

    # Set the hue of a video device (NTSC feature).
    # Valid range 0-255, default 0 = disabled
    hue 0

    ############################################################
    # File "camera" support - read raw YUV data from a file
    ############################################################
    #filecam_path /home/pi/test-cap/motion-mmal.capture

    ############################################################
    # OpenMax/MMAL camera support for Raspberry Pi
    ############################################################
    mmalcam_name vc.ril.camera
    #mmalcam_control_params
    #mmalcam_raw_capture_file /home/pi/motion-mmal.capture

    # Switch this setting to "on" to use the still image mode of the Pi's camera
    # instead of video. This gives a wider field of view, but requires
    # a much slower frame-rate to achieve exposure stability
    # (e.g. 0.25 fps or slower). You can use the minimum_frame_time
    # parameter above to achieve this

    mmalcam_use_still off


    ############################################################
    # Round Robin (multiple inputs on same video device name)
    ############################################################

    # Number of frames to capture in each roundrobin step (default: 1)
    roundrobin_frames 1

    # Number of frames to skip before each roundrobin step (default: 1)
    roundrobin_skip 1

    # Try to filter out noise generated by roundrobin (default: off)
    switchfilter off


    ############################################################
    # Motion Detection Settings:
    ############################################################

    # Threshold for number of changed pixels in an image that
    # triggers motion detection (default: 1500)
    threshold 1500

    # Automatically tune the threshold down if possible (default: off)
    threshold_tune off

    # Noise threshold for the motion detection (default: 32)
    noise_level 32

    # Automatically tune the noise threshold (default: on)
    noise_tune on

    # Despeckle motion image using (e)rode or (d)ilate or (l)abel (Default: not defined)
    # Recommended value is EedDl. Any combination (and number of) of E, e, d, and D is valid.
    # (l)abeling must only be used once and the 'l' must be the last letter.
    # Comment out to disable
    despeckle_filter EedDl

    # Detect motion in predefined areas (1 - 9). Areas are numbered like that:  1 2 3
    # A script (on_area_detected) is started immediately when motion is         4 5 6
    # detected in one of the given areas, but only once during an event.        7 8 9
    # One or more areas can be specified with this option. Take care: This option
    # does NOT restrict detection to these areas! (Default: not defined)
    ; area_detect value

    # PGM file to use as a sensitivity mask.
    # Full path name to. (Default: not defined)
    ; mask_file value

    # Dynamically create a mask file during operation (default: 0)
    # Adjust speed of mask changes from 0 (off) to 10 (fast)
    smart_mask_speed 0

    # Ignore sudden massive light intensity changes given as a percentage of the picture
    # area that changed intensity. Valid range: 0 - 100 , default: 0 = disabled
    lightswitch 0

    # Picture frames must contain motion at least the specified number of frames
    # in a row before they are detected as true motion. At the default of 1, all
    # motion is detected. Valid range: 1 to thousands, recommended 1-5
    minimum_motion_frames 1

    # Specifies the number of pre-captured (buffered) pictures from before motion
    # was detected that will be output at motion detection.
    # Recommended range: 0 to 5 (default: 0)
    # Do not use large values! Large values will cause Motion to skip video frames and
    # cause unsmooth movies. To smooth movies use larger values of post_capture instead.
    pre_capture 2

    # Number of frames to capture after motion is no longer detected (default: 0)
    post_capture 2

    # Event Gap is the seconds of no motion detection that triggers the end of an event.
    # An event is defined as a series of motion images taken within a short timeframe.
    # Recommended value is 60 seconds (Default). The value -1 is allowed and disables
    # events causing all Motion to be written to one single movie file and no pre_capture.
    # If set to 0, motion is running in gapless mode. Movies don't have gaps anymore. An
    # event ends right after no more motion is detected and post_capture is over.
    event_gap 60

    # Maximum length in seconds of an mpeg movie
    # When value is exceeded a new movie file is created. (Default: 0 = infinite)
    # ATTENTION: when you're not using the motion build from the tutorial, it might fail with error 'Unknown config option "max_mpeg_time"'
    # the use this line instead:
    # max_movie_time 60
    max_movie_time 60

    # Always save images even if there was no motion (default: off)
    emulate_motion off


    ############################################################
    # Image File Output
    ############################################################

    # Output 'normal' pictures when motion is detected (default: on)
    # Valid values: on, off, first, best, center
    # When set to 'first', only the first picture of an event is saved.
    # Picture with most motion of an event is saved when set to 'best'.
    # Picture with motion nearest center of picture is saved when set to 'center'.
    # Can be used as preview shot for the corresponding movie.
    output_pictures best

    # Output pictures with only the pixels moving object (ghost images) (default: off)
    output_debug_pictures off

    # The quality (in percent) to be used by the jpeg compression (default: 75)
    quality 75

    # Type of output images
    # Valid values: jpeg, ppm (default: jpeg)
    picture_type jpeg

    ############################################################
    # FFMPEG related options
    # Film (movies) file output, and deinterlacing of the video input
    # The options movie_filename and timelapse_filename are also used
    # by the ffmpeg feature
    ############################################################

    # Use ffmpeg to encode movies in realtime (default: off)
    ffmpeg_output_movies on

    # Use ffmpeg to make movies with only the pixels moving
    # object (ghost images) (default: off)
    ffmpeg_output_debug_movies off

    # Use ffmpeg to encode a timelapse movie
    # Default value 0 = off - else save frame every Nth second
    ffmpeg_timelapse 0

    # The file rollover mode of the timelapse video
    # Valid values: hourly, daily (default), weekly-sunday, weekly-monday, monthly, manual
    ffmpeg_timelapse_mode daily

    # Bitrate to be used by the ffmpeg encoder (default: 400000)
    # This option is ignored if ffmpeg_variable_bitrate is not 0 (disabled)
    ffmpeg_bps 500000

    # Enables and defines variable bitrate for the ffmpeg encoder.
    # ffmpeg_bps is ignored if variable bitrate is enabled.
    # Valid values: 0 (default) = fixed bitrate defined by ffmpeg_bps,
    # or the range 2 - 31 where 2 means best quality and 31 is worst.
    ffmpeg_variable_bitrate 5

    # Codec to used by ffmpeg for the video compression.
    # Timelapse mpegs are always made in mpeg1 format independent from this option.
    # Supported formats are: mpeg1 (ffmpeg-0.4.8 only), mpeg4 (default), and msmpeg4.
    # mpeg1 - gives you files with extension .mpg
    # mpeg4 or msmpeg4 - gives you files with extension .avi
    # msmpeg4 is recommended for use with Windows Media Player because
    # it requires no installation of codec on the Windows client.
    # swf - gives you a flash film with extension .swf
    # flv - gives you a flash video with extension .flv
    # ffv1 - FF video codec 1 for Lossless Encoding ( experimental )
    # mov - QuickTime ( testing )
    # ogg - Ogg/Theora ( testing )
    #ffmpeg_video_codec msmpeg4
    ffmpeg_video_codec mp4

    # Use ffmpeg to deinterlace video. Necessary if you use an analog camera
    # and see horizontal combing on moving objects in video or pictures.
    # (default: off)
    ffmpeg_deinterlace off

    ############################################################
    # SDL Window
    ############################################################

    # Number of motion thread to show in SDL Window (default: 0 = disabled)
    #sdl_threadnr 0

    ############################################################
    # External pipe to video encoder
    # Replacement for FFMPEG builtin encoder for ffmpeg_output_movies only.
    # The options movie_filename and timelapse_filename are also used
    # by the ffmpeg feature
    #############################################################

    # Bool to enable or disable extpipe (default: off)
    use_extpipe off

    # External program (full path and opts) to pipe raw video to
    # Generally, use '-' for STDIN...
    ;extpipe mencoder -demuxer rawvideo -rawvideo w=320:h=240:i420 -ovc x264 -x264encopts bframes=4:frameref=1:subq=1:scenecut=-1:nob_adapt:threads=1:keyint=1000:8x8dct:vbv_bufsize=4000:crf=24:partitions=i8x8,i4x4:vbv_maxrate=800:no-chroma-me -vf denoise3d=16:12:48:4,pp=lb -of   avi -o %f.avi - -fps %fps



    ############################################################
    # Snapshots (Traditional Periodic Webcam File Output)
    ############################################################

    # Make automated snapshot every N seconds (default: 0 = disabled)
    snapshot_interval 0


    ############################################################
    # Text Display
    # %Y = year, %m = month, %d = date,
    # %H = hour, %M = minute, %S = second, %T = HH:MM:SS,
    # %v = event, %q = frame number, %t = thread (camera) number,
    # %D = changed pixels, %N = noise level, \n = new line,
    # %i and %J = width and height of motion area,
    # %K and %L = X and Y coordinates of motion center
    # %C = value defined by text_event - do not use with text_event!
    # You can put quotation marks around the text to allow
    # leading spaces
    ############################################################

    # Locate and draw a box around the moving object.
    # Valid values: on, off, preview (default: off)
    # Set to 'preview' will only draw a box in preview_shot pictures.
    locate_motion_mode off

    # Set the look and style of the locate box if enabled.
    # Valid values: box, redbox, cross, redcross (default: box)
    # Set to 'box' will draw the traditional box.
    # Set to 'redbox' will draw a red box.
    # Set to 'cross' will draw a little cross to mark center.
    # Set to 'redcross' will draw a little red cross to mark center.
    locate_motion_style box

    # Draws the timestamp using same options as C function strftime(3)
    # Default: %Y-%m-%d\n%T = date in ISO format and time in 24 hour clock
    # Text is placed in lower right corner
    text_right %d.%m.%Y\n%T

    # Draw a user defined text on the images using same options as C function strftime(3)
    # Default: Not defined = no text
    # Text is placed in lower left corner
    ; text_left CAMERA %t
    text_left HofCam

    # Draw the number of changed pixed on the images (default: off)
    # Will normally be set to off except when you setup and adjust the motion settings
    # Text is placed in upper right corner
    text_changes off

    # This option defines the value of the special event conversion specifier %C
    # You can use any conversion specifier in this option except %C. Date and time
    # values are from the timestamp of the first image in the current event.
    # Default: %Y%m%d%H%M%S
    # The idea is that %C can be used filenames and text_left/right for creating
    # a unique identifier for each event.
    text_event %Y%m%d%H%M%S

    # Draw characters at twice normal size on images. (default: off)
    text_double on


    # Text to include in a JPEG EXIF comment
    # May be any text, including conversion specifiers.
    # The EXIF timestamp is included independent of this text.
    ;exif_text %i%J/%K%L

    ############################################################
    # Target Directories and filenames For Images And Films
    # For the options snapshot_, picture_, movie_ and timelapse_filename
    # you can use conversion specifiers
    # %Y = year, %m = month, %d = date,
    # %H = hour, %M = minute, %S = second,
    # %v = event, %q = frame number, %t = thread (camera) number,
    # %D = changed pixels, %N = noise level,
    # %i and %J = width and height of motion area,
    # %K and %L = X and Y coordinates of motion center
    # %C = value defined by text_event
    # Quotation marks round string are allowed.
    ############################################################

    # Target base directory for pictures and films
    # Recommended to use absolute path. (Default: current working directory)
    target_dir /home/pi

    # File path for snapshots (jpeg or ppm) relative to target_dir
    # Default: %v-%Y%m%d%H%M%S-snapshot
    # Default value is equivalent to legacy oldlayout option
    # For Motion 3.0 compatible mode choose: %Y/%m/%d/%H/%M/%S-snapshot
    # File extension .jpg or .ppm is automatically added so do not include this.
    # Note: A symbolic link called lastsnap.jpg created in the target_dir will always
    # point to the latest snapshot, unless snapshot_filename is exactly 'lastsnap'
    snapshot_filename %v-%Y%m%d%H%M%S-snapshot

    # File path for motion triggered images (jpeg or ppm) relative to target_dir
    # Default: %v-%Y%m%d%H%M%S-%q
    # Default value is equivalent to legacy oldlayout option
    # For Motion 3.0 compatible mode choose: %Y/%m/%d/%H/%M/%S-%q
    # File extension .jpg or .ppm is automatically added so do not include this
    # Set to 'preview' together with best-preview feature enables special naming
    # convention for preview shots. See motion guide for details
    picture_filename %v-%Y%m%d%H%M%S-%q

    # File path for motion triggered ffmpeg films (movies) relative to target_dir
    # Default: %v-%Y%m%d%H%M%S
    # Default value is equivalent to legacy oldlayout option
    # For Motion 3.0 compatible mode choose: %Y/%m/%d/%H%M%S
    # File extension .mpg or .avi is automatically added so do not include this
    # This option was previously called ffmpeg_filename
    movie_filename %v-%Y%m%d%H%M%S

    # File path for timelapse movies relative to target_dir
    # Default: %Y%m%d-timelapse
    # Default value is near equivalent to legacy oldlayout option
    # For Motion 3.0 compatible mode choose: %Y/%m/%d-timelapse
    # File extension .mpg is automatically added so do not include this
    timelapse_filename %Y%m%d-timelapse

    ############################################################
    # Global Network Options
    ############################################################
    # Enable or disable IPV6 for http control and stream (default: off )
    ipv6_enabled off

    ############################################################
    # Live Stream Server
    ############################################################

    # The mini-http server listens to this port for requests (default: 0 = disabled)
    stream_port 8080

    # Quality of the jpeg (in percent) images produced (default: 50)
    stream_quality 50

    # Output frames at 1 fps when no motion is detected and increase to the
    # rate given by stream_maxrate when motion is detected (default: off)
    stream_motion on

    # Maximum framerate for stream streams (default: 1)
    stream_maxrate 4

    # Restrict stream connections to localhost only (default: on)
    stream_localhost off

    # Limits the number of images per connection (default: 0 = unlimited)
    # Number can be defined by multiplying actual stream rate by desired number of seconds
    # Actual stream rate is the smallest of the numbers framerate and stream_maxrate
    stream_limit 0

    # Set the authentication method (default: 0)
    # 0 = disabled
    # 1 = Basic authentication
    # 2 = MD5 digest (the safer authentication)
    stream_auth_method 0

    # Authentication for the stream. Syntax username:password
    # Default: not defined (Disabled)
    ; stream_authentication username:password


    ############################################################
    # HTTP Based Control
    ############################################################

    # TCP/IP port for the http server to listen on (default: 0 = disabled)
    webcontrol_port 8081

    # Restrict control connections to localhost only (default: on)
    webcontrol_localhost off

    # Output for http server, select off to choose raw text plain (default: on)
    webcontrol_html_output on

    # Authentication for the http based control. Syntax username:password
    # Default: not defined (Disabled)
    ; webcontrol_authentication username:password


    ############################################################
    # Tracking (Pan/Tilt)
    #############################################################

    # Type of tracker (0=none (default), 1=stepper, 2=iomojo, 3=pwc, 4=generic, 5=uvcvideo, 6=servo)
    # The generic type enables the definition of motion center and motion size to
    # be used with the conversion specifiers for options like on_motion_detected
    track_type 0

    # Enable auto tracking (default: off)
    track_auto off

    # Serial port of motor (default: none)
    ;track_port /dev/ttyS0

    # Motor number for x-axis (default: 0)
    ;track_motorx 0

    # Set motorx reverse (default: 0)
    ;track_motorx_reverse 0

    # Motor number for y-axis (default: 0)
    ;track_motory 1

    # Set motory reverse (default: 0)
    ;track_motory_reverse 0

    # Maximum value on x-axis (default: 0)
    ;track_maxx 200

    # Minimum value on x-axis (default: 0)
    ;track_minx 50

    # Maximum value on y-axis (default: 0)
    ;track_maxy 200

    # Minimum value on y-axis (default: 0)
    ;track_miny 50

    # Center value on x-axis (default: 0)
    ;track_homex 128

    # Center value on y-axis (default: 0)
    ;track_homey 128

    # ID of an iomojo camera if used (default: 0)
    track_iomojo_id 0

    # Angle in degrees the camera moves per step on the X-axis
    # with auto-track (default: 10)
    # Currently only used with pwc type cameras
    track_step_angle_x 10

    [...]
  • FFmpeg mp4 compression

    22 septembre 2016, par Nikita Pronchik

    I’m developing photo and video social network ( partially like instagram ). And i’m using ffmpeg for mp4 to mp4 file size compression. I achieved 3 time scale factor for file size ( from 13 mb to 2,5 mb ) but very stupidly - 3 times converting output files by the following command-line string :

    ./ffmpeg -i input.mp4 -vcodec h264 -acodec mp2 output.mp4

    I’m a newbee in video-audio codec theory, so i completely lost audio while such compression. So my question is - where is audio ? Which option should i use ? Thanks in advance !

  • Subtitling Sierra VMD Files

    1er juin 2016, par Multimedia Mike — Game Hacking

    I was contacted by a game translation hobbyist from Spain (henceforth known as The Translator). He had set his sights on Sierra’s 7-CD Phantasmagoria. This mammoth game was driven by a lot of FMV files and animations that have speech. These require language translation in the form of video subtitling. He’s lucky that he found possibly the one person on the whole internet who has just the right combination of skill, time, and interest to pull this off. And why would I care about helping ? I guess I share a certain camaraderie with game hackers. Don’t act so surprised. You know what kind of stuff I like to work on.

    The FMV format used in this game is VMD, which makes an appearance in numerous Sierra titles. FFmpeg already supports decoding this format. FFmpeg also supports subtitling video. So, ideally, all that’s necessary to support this goal is to add a muxer for the VMD format which can encode raw video and audio, which the format supports. Implement video compression as extra credit.

    The pipeline that I envisioned looks like this :


    VMD Subtitling Process

    VMD Subtitling Process


    “Trivial !” I surmised. I just never learn, do I ?

    The Plan
    So here’s my initial pitch, outlining the work I estimated that I would need to do towards the stated goal :

    1. Create a new file muxer that produces a syntactically valid VMD file with bogus video and audio data. Make sure it works with both FFmpeg’s playback system as well as the proper Phantasmagoria engine.
    2. Create a new video encoder that essentially operates in pass-through mode while correctly building a palette.
    3. Create a new basic encoder for the video frames.

    A big unknown for me was exactly how subtitle handling operates in FFmpeg. Thanks to this project, I now know. I was concerned because I was pretty sure that font rendering entails anti-aliasing which bodes poorly for keeping the palette count under 256 unique colors.

    Computer Science Puzzle
    When pondering how to process the palette, I was excited for the opportunity to exercise actual computer science. FFmpeg converts frames from paletted frames to full RGB frames. Then it needs to convert them back to paletted frames. I had a vague recollection of solving this problem once before when I was experimenting with a new paletted video codec. I seem to recall that I did the palette conversion in a very naive manner. I just used a static 256-element array and processed each RGB pixel of the frame, seeing if the value already occurred in the table (O(n) lookup) and adding it otherwise.

    There are more efficient algorithms, however, such as hash tables and trees. Somewhere along the line, FFmpeg helpfully acquired a rarely-used tree data structure, which was perfect for this project.

    So I was pretty pleased with this optimization. Too bad this wouldn’t survive to the end of the effort.

    Another palette-related challenge was the fact that a group of pictures would be accumulating a new palette but that palette needed to be recorded before the group. Thus, the muxer needed to have extra logic to rewind the file when the video encoder transmitted a palette change.

    Video Compression
    VMD has a few methods in its compression toolbox. It can use interframe differencing, it has some RLE, or it can code a frame raw. It can also use a custom LZ-like format on top of these. For early prototypes, I elected to leave each frame coded raw. After the concept was proved, I implemented the frame differencing.


    VMD frame #1

    VMD frame #2

    VMD frame difference
    Top frame compared with the middle frame yields the bottom frame : red pixels indicate changes

    Encoding only those red dots in between vast runs of unchanged pixels yielded a vast measurable improvement. The next step was to try wiring up FFmpeg’s existing LZ compression facilities to the encoder. This turned out to be implausible since VMD’s LZ variant has nothing to do with anything FFmpeg already provides. Fortunately, the LZ piece is not absolutely required and the frame differencing + RLE provides plenty of compression.

    Subtitling
    I’ve never done anything, multimedia programming-wise, concerning subtitles. I guess all the entertainment I care about has always been in my native tongue. What a good excuse to program outside of my comfort zone !

    First, I needed to know how to access FFmpeg’s subtitling facilities. Fortunately, The Translator did the legwork on this matter so I didn’t have to figure it out.

    However, I intuitively had misgivings about this phase. I had heard that the subtitling process performs anti-aliasing. That means that the image would need to be promoted to a higher colorspace for this phase and that the anti-aliasing process would likely push the color count way past 256. Some quick tests revealed this to be the case, as the running color count would leap by several hundred colors as soon as the palette accounting algorithm encountered a subtitle.

    So I dug into the subtitle subsystem. I discovered that the subtitle library operates by creating a linked list of subtitle bitmaps that the client app must render. The bitmaps are comprised of 8-bit alpha transparency values that must be composited onto the target frame (i.e., 0 = transparent, 255 = 100% opaque). For example, the letter ‘H’ :

                                      (with 00s removed)
    13 F8 41 00 00 00 00 68 E4  |  13 F8 41             68 E4    
    14 FF 44 00 00 00 00 6C EC  |  14 FF 44             6C EC
    14 FF 44 00 00 00 00 6C EC  |  14 FF 44             6C EC
    14 FF 44 00 00 00 00 6C EC  |  14 FF 44             6C EC
    14 FF DC D0 D0 D0 D0 E4 EC  |  14 FF DC D0 D0 D0 D0 E4 EC
    14 FF 7E 50 50 50 50 9A EC  |  14 FF 7E 50 50 50 50 9A EC
    14 FF 44 00 00 00 00 6C EC  |  14 FF 44             6C EC
    14 FF 44 00 00 00 00 6C EC  |  14 FF 44             6C EC
    14 FF 44 00 00 00 00 6C EC  |  14 FF 44             6C EC
    11 E0 3B 00 00 00 00 5E CE  |  11 E0 3B             5E CE
    

    To get around the color explosion problem, I chose a threshold value and quantized values above and below to 255 and 0, respectively. Further, the process chooses an appropriate color from the existing palette rather than introducing any new colors.

    Muxing Matters
    In order to force VMD into a general purpose media framework, a lot of special information needs to be passed around. Like many paletted codecs, the palette needs to be transmitted from the file demuxer to the video decoder via some side channel. For re-encoding, this also implies that the palette needs to make the trip from the video encoder to the file muxer. As if this wasn’t enough, individual VMD frames have even more data that needs to be ferried between the muxer and codec levels, including frame change boundaries. FFmpeg provides methods to do these things, but I could not always rely on the systems to relay the data in all cases. I was probably doing something wrong ; I accept that. Instead, I just packed all the information at the front of an encoded frame and split it apart in the muxer.

    I could not quite figure out how to get the audio and video muxed correctly. As a result, neither FFmpeg nor the Phantasmagoria engine could replay the files correctly.

    Plan B
    Since I was having so much trouble creating an entirely new VMD file, likely due to numerous unknown bits of the file format, I thought of another angle : re-use the existing VMD file. For this approach, I kept the video encoder and file muxer that I created in the initial phase, but modified the file muxer to emit a special intermediate file. Then, I created a Python tool to repackage the original VMD file using compressed video data in the intermediate file.

    For this phase, I also implemented a command line switch for FFmpeg to disable subtitle blending, to make the feature feel like less of an unofficial hack, as though this nonsense would ever have a chance of being incorporated upstream.

    At this point, I was seeing some success with the complete, albeit roundabout, subtitling process. I constructed a subtitle file using “Spanish I Learned From Mexican Telenovelas” and the frames turned out fairly readable :


    Le puso los cuernos a él

    “she cheated on him”


    es un desgraciado

    “he’s a scumbag” … these random subtitles could fit surprisingly well !


    The few files that I tested appeared to work fine. But then I handed off my work to The Translator and he immediately found a bunch of problems. According to my notes, the problems mostly took the form of flashing, solid color frames. Further, I found tiny, mostly imperceptible flaws in my RLE compressor, usually only detectable by running strict comparison tools ; but I wasn’t satisfied.

    At this point, I think I attempted to just encode the entire palette at the front of each frame, as allowed by the format, but that did not seem to fix any problems. My notes are not completely clear on this matter (likely because I was still trying to figure out the exact problem), but I think it had to do with FFmpeg inserting extra video frames in order to even out gaps in the video framerate.

    Sigh, Plan C
    At this point, I was getting tired of trying to force FFmpeg to do this. So I decided to minimize its involvement using lessons learned up to this point.

    The next pitch :

    1. Create a new C program that can open an existing VMD file and output an identical VMD file. I know this sounds easy, but the specific method of copying entails interpreting individual parts of the file and writing those individual parts to the new file. This is in preparation for…
    2. Import the VMD video decoder functions directly into the program to decode the individual video frames and re-encode them, replacing the video frames as the file is rewritten.
    3. Wire up the subtitle system. During the adventure to disable subtitle blending, I accidentally learned enough about interfacing to the subtitle library to just invoke it directly.
    4. Rewrite the RLE method so that it is 100% correct.

    Off to work I went. That part about lifting the existing VMD decoder functions out of their libavcodec nest turned out to not be that straightforward. As an alternative, I modified the decoder to dump the raw frames to an intermediate file. In doing so, I think I was able to avoid the issue of the duplicated frames that plagued the previous efforts.

    Also, remember how I was really pleased with the palette conversion technique in which I was able to leverage computer science big-O theory ? By this stage, I had no reason to convert the paletted video to RGB in the first place ; all of the decoding, subtitling and re-encoding operates in the paletted colorspace.

    This approach seemed to work pretty well. The final program is subtitle-vmd.c. The process is still a little weird. The modifications in my own FFmpeg fork are necessary to create an intermediate file that the new C tool can operate with.

    Next Steps
    The Translator has found some assorted bugs and corner cases that still need to be ironed out. Further, for extra credit, I need find the change windows for each frame to improve compression just a little more. I don’t think I will be trying for LZ compression, though.

    However, almost as soon as I had this whole system working, The Translator informed me that there is another, different movie format in play in the Phantasmagoria engine called ROBOT, with an extension of RBT. Fortunately, enough of the algorithms have been reverse engineered and re-implemented in ScummVM that I was able to sort out enough details for another subtitling project. That will be the subject of a future post.

    See Also :

    The post Subtitling Sierra VMD Files first appeared on Breaking Eggs And Making Omelettes.