Let's start with a shape tag. I have copied this from the built-in, and modified the resolution: 

<TranscodePresetDocument
    xmlns="http://xml.vidispine.com/schema/vidispine">
    <name>my-shape-tag</name>
    <format>mp4</format>
    <audio>
        <codec>aac</codec>
        <bitrate>128000</bitrate>
        <channel>0</channel>
        <channel>1</channel>
        <stream>2</stream>
    </audio>
    <video>
        <scaling>
            <width>500</width>
            <height>200</height>
            <pixelAspectRatio>
                <horizontal>1</horizontal>
                <vertical>1</vertical>
            </pixelAspectRatio>
        </scaling>
        <codec>h264</codec>
        <bitrate>2000000</bitrate>
        <framerate>
            <numerator>1</numerator>
            <denominator>25</denominator>
        </framerate>
        <preset>high</preset>
    </video>
</TranscodePresetDocument> 

 I then added a script: 

var inWidth = shape.getVideoComponent().get(0).getResolution().getWidth(); // http://apidoc.vidispine.com/latest/xsddocs/com/vidispine/generated/VideoComponentType.html
var inHeight = shape.getVideoComponent().get(0).getResolution().getHeight();
var scaling = preset.getVideo().getScaling();

var outWidth = scaling.getWidth();
var outHeight = scaling.getHeight();

var targetDAR = new com.vidispine.generated.AspectRatioType();
scaling.setTargetDAR(targetDAR);
targetDAR.setHorizontal(outWidth);
targetDAR.setVertical(outHeight);

var proportionalDifference = outHeight * inWidth–outWidth * inHeight;

if (proportionalDifference > 0) { // output is taller (skinnier) than input
	padding = -proportionalDifference / outWidth;
	scaling.setTop(padding / 2);
	scaling.setBottom(padding - padding / 2);
} else { // output is fatter than input
	padding = proportionalDifference / outHeight;
	scaling.setLeft(padding / 2);
	scaling.setRight(padding - padding / 2);
}


The order of how Vidispine applies the commands in the scaling tag is:

  • Crop/pad
  • Rotate
  • Scale

So, we are comparing the proportions and either pad top/bottom or left/right. Remember that setTop/Bottom/Left/Right refers to cropping values: negative values mean padding.


The original (scaled):


The result (scaled):