videofilt_handlingbitmaps - shekh/VirtualDub2 GitHub Wiki

VirtualDub Plugin SDK 1.2

Handling bitmaps

Images are passed in and out of video filters through the VFBitmap structure. Each VFBitmap represents an image as follows:

The image is stored as a series of sequential scanlines, where each scanline consists of a series of pixels. Individual fields in VFBitmap describe a bitmap as follows:

data
Points to the beginning of the first scanline, which is at the bottom-left corner of the image.

palette
Not used for video filters.

depth
Indicates the bit depth of the image. For video filters, this is typically 32, indicating 24-bit RGB with an unused 8-bit alpha channel in the high byte (fourth byte in memory order). If this is zero, it means the bitmap uses an alternate format and the mpPixmap field must be used.

w
Width of the image, in pixels. Always positive.

h
Height of the image, in pixels. Always positive.

pitch
Distance from the beginning of one scanline to the beginning of the next, in bytes.

V12+ only: Bitmaps can be stored top-down as well as bottom-up. The pitch value value is positive if the image is stored bottom-up in memory and negative if the image is stored top-down. This is only permitted if the filter declares support for flexible formats by returning FILTERPARAM_SUPPORTS_ALTFORMATS from paramProc; otherwise, the host ensures that the filter receives a bottom-up orientation with a positive pitch, flipping the bitmap beforehand if necessary.

modulo
Distance from the end of one scanline to the beginning of the next, in bytes. This value is positive or zero if the image is stored bottom-up in memory and negative if the image is stored top-down. A value of zero indicates that the image is stored bottom-up with no padding between scanlines. For a 32-bit bitmap, modulo is equal to pitch - 4*w.

size
Size of the bitmap, in bytes. This is the amount of memory required to hold all of the scanlines.

offset
Offset from the start of the buffer to the beginning of the bitmap, in bytes.

V12+ only: For image formats that use multiple planes, this points to the base of plane 0.

mpPixmapLayout
V12+ only: More flexible description of bitmap layout, which is able to accommodate multi-plane and YCbCr formats. In paramProc, this field is always valid when provided by the host. When set by the filter in paramProc, this field is activated when the depth field of the bitmap is set to zero.

mpPixmap
V12+ only: More flexible description of bitmap, which is able to accommodate multi-plane and YCbCr formats. This field is always valid in runProc, even if mpPixmapLayout was not used in paramProc. For filters that require V12+ of the API, mpPixmap may be used exclusively in runProc in lieu of the regular data, pitch, etc. fields above.

VirtualDub bug alert: Some of these fields are invalid on secondary source frames, i.e. ones prefetched beyond the first. All legacy fields (data, palette, depth, w, h, pitch, module, size, offset) are invalid, as are the aspect ratio fields. Use the mpPixmap and mpPixmapLayout fields for frame-specific data and use the information from the first source frame entry for stream-constant data.

Alignment and padding

Since the video filter system works with 32-bit bitmaps, scanlines are guaranteed to be aligned to 32-bit boundaries. No further alignment is guaranteed. In particular, filter code must not assume that scanlines are 16-byte aligned for SSE code.

It is important to note that there may be padding between scanlines. The pitch field indicates the true spacing in bytes, and should be used to step from one scanline to the next:

    p = (uint32 *)((char *)p + pitch);

Padding must not be overwritten. In particular, this is the wrong way to copy from one bitmap to the next:

// DO NOT DO THIS!
memcpy(dst.data, src.data, src.pitch * src.h);

You should instead copy the scanlines individually:

char *dstp = (char *)dst.data;
const char *srcp = (const char *)src.data;
for(int y=0; y< ++y) {
    memcpy(dstp, srcp, w*4);
    dstp += dst.pitch;
    srcp += src.pitch;
}

16 byte alignment via FILTERPARAM_ALIGN_SCANLINES (V14+ only)

If the paramProc() method specifies the FILTERPARAM_ALIGN_SCANLINES flag, then additional constraints are placed on the host and some constraints on the filter are relaxed. Specifically:

  • All scanlines are guaranteed to be aligned to a multiple of 16. This means that all pitch and data fields are also guaranteed to be a multiple of 16.
  • Source scanlines can safely be read up to the next 16 byte boundary even if the last 16 byte word runs over the end of the scanline. The contents of the additional bytes are undefined.
  • Output scanlines can safely be written up to the next 16 byte boundary even if the last 16 byte word runs over the end of the scanline. The contents of the additional bytes are ignored.

The result is that filters which make extensive use of SSE/2/3/4 routines can run faster with fewer alignment issues.

VirtualDub specific: Use of the alignment flag may force a copy to realign the buffer if the current buffer is not aligned suitably.


Copyright (C) 2007-2012 Avery Lee.

⚠️ **GitHub.com Fallback** ⚠️