summaryrefslogtreecommitdiffstats
path: root/debian/transcode/transcode-1.1.7/src/video_trans.c
diff options
context:
space:
mode:
authorMichele Calgaro <michele.calgaro@yahoo.it>2020-09-11 14:38:47 +0900
committerMichele Calgaro <michele.calgaro@yahoo.it>2020-09-11 14:38:47 +0900
commit884c8093d63402a1ad0b502244b791e3c6782be3 (patch)
treea600d4ab0d431a2bdfe4c15b70df43c14fbd8dd0 /debian/transcode/transcode-1.1.7/src/video_trans.c
parent14e1aa2006796f147f3f4811fb908a6b01e79253 (diff)
downloadextra-dependencies-884c8093d63402a1ad0b502244b791e3c6782be3.tar.gz
extra-dependencies-884c8093d63402a1ad0b502244b791e3c6782be3.zip
Added debian extra dependency packages.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
Diffstat (limited to 'debian/transcode/transcode-1.1.7/src/video_trans.c')
-rw-r--r--debian/transcode/transcode-1.1.7/src/video_trans.c607
1 files changed, 607 insertions, 0 deletions
diff --git a/debian/transcode/transcode-1.1.7/src/video_trans.c b/debian/transcode/transcode-1.1.7/src/video_trans.c
new file mode 100644
index 00000000..bee77ef1
--- /dev/null
+++ b/debian/transcode/transcode-1.1.7/src/video_trans.c
@@ -0,0 +1,607 @@
+/*
+ * video_trans.c - video frame transformation routines
+ * Written by Andrew Church <achurch@achurch.org>
+ * Based on code written by Thomas Oestreich.
+ *
+ * This file is part of transcode, a video stream processing tool.
+ * transcode is free software, distributable under the terms of the GNU
+ * General Public License (version 2 or later). See the file COPYING
+ * for details.
+ */
+
+#include "transcode.h"
+#include "framebuffer.h"
+#include "video_trans.h"
+#include "libtcvideo/tcvideo.h"
+
+/*************************************************************************/
+
+/* Structure that holds video frame information for passing around to
+ * processing routines. Since this is used only locally, we don't add
+ * the fields to vframe_list_t itself. */
+
+typedef struct {
+ vframe_list_t *ptr;
+ int preadj_w, preadj_h; // width and height used for secondary buffer
+ int Bpp; // BYTES (not bits) per pixel
+ int nplanes; // number of planes
+ uint8_t *planes[3]; // pointer to start of each plane
+ uint8_t *tmpplanes[3]; // same, for secondary buffer
+ int width_div[3]; // width divisors for each plane
+ int height_div[3]; // height divisors for each plane
+ uint8_t black_pixel[3]; // "black" value for each plane (e.g. 128 for U/V)
+} video_trans_data_t;
+
+/* Macro to perform a transformation on a frame. `vtd' is a pointer to a
+ * video_trans_data_t; the given function `func' will be called for each
+ * plane `i' as:
+ * func(handle, vtd->planes[i], vtd->tmpplanes[i], vtd->ptr->v_width,
+ * vtd->ptr->v_height, vtd->Bpp, args)
+ * where `args' are all arguments to this macro (if any) following `vtd'.
+ * swap_buffers(vtd) is called after the processing is complete.
+ */
+#define PROCESS_FRAME(func,vtd,args...) do { \
+ int i; \
+ for (i = 0; i < (vtd)->nplanes; i++) { \
+ func(handle, (vtd)->planes[i], (vtd)->tmpplanes[i], \
+ (vtd)->ptr->v_width / (vtd)->width_div[i], \
+ (vtd)->ptr->v_height / (vtd)->height_div[i], \
+ (vtd)->Bpp , ## args); \
+ } \
+ swap_buffers(vtd); \
+} while (0)
+
+/* Handle for calling tcvideo functions. */
+static TCVHandle handle = 0;
+
+/*************************************************************************/
+/*************************** Internal routines ***************************/
+/*************************************************************************/
+
+/**
+ * set_vtd: Initialize the given vtd structure from the given
+ * vframe_list_t, and update ptr->video_size.
+ *
+ * Parameters:
+ * vtd: Pointer to video frame data to be initialized.
+ * ptr: Pointer to video frame buffer.
+ * Return value:
+ * None.
+ */
+
+static void set_vtd(video_trans_data_t *vtd, vframe_list_t *ptr)
+{
+ int i;
+
+ vtd->ptr = ptr;
+ vtd->preadj_w = 0;
+ vtd->preadj_h = 0;
+ /* Set some defaults */
+ vtd->Bpp = 1;
+ vtd->nplanes = 1;
+ vtd->planes[0] = ptr->video_buf;
+ vtd->tmpplanes[0] = ptr->video_buf_Y[ptr->free];
+ vtd->width_div[0] = 1;
+ vtd->height_div[0] = 1;
+ vtd->black_pixel[0] = 0;
+ /* Now set parameters based on image format */
+ if (ptr->v_codec == CODEC_YUV) {
+ vtd->nplanes = 3;
+ vtd->Bpp = 1;
+ vtd->width_div[1] = 2;
+ vtd->width_div[2] = 2;
+ vtd->height_div[1] = 2;
+ vtd->height_div[2] = 2;
+ vtd->black_pixel[1] = 128;
+ vtd->black_pixel[2] = 128;
+ } else if (vtd->ptr->v_codec == CODEC_YUV422) {
+ vtd->nplanes = 3;
+ vtd->Bpp = 1;
+ vtd->width_div[1] = 2;
+ vtd->width_div[2] = 2;
+ vtd->height_div[1] = 1;
+ vtd->height_div[2] = 1;
+ vtd->black_pixel[1] = 128;
+ vtd->black_pixel[2] = 128;
+ } else if (vtd->ptr->v_codec == CODEC_RGB) {
+ vtd->Bpp = 3;
+ }
+ ptr->video_size = 0;
+ for (i = 0; i < vtd->nplanes; i++) {
+ int planesize = (ptr->v_width/vtd->width_div[i])
+ * (ptr->v_height/vtd->height_div[i])
+ * vtd->Bpp;
+ ptr->video_size += planesize;
+ if (i < vtd->nplanes-1) {
+ vtd->planes[i+1] = vtd->planes[i] + planesize;
+ vtd->tmpplanes[i+1] = vtd->tmpplanes[i] + planesize;
+ }
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * preadjust_frame_size: Prepare for an operation that will change the
+ * frame size, setting up the secondary buffer plane pointers with the new
+ * size. Calling swap_buffers() will store the new size in the
+ * vframe_list_t structure.
+ *
+ * Parameters:
+ * vtd: Pointer to video frame data.
+ * new_w: New frame width.
+ * new_h: New frame height.
+ * Return value:
+ * None.
+ */
+
+static void preadjust_frame_size(video_trans_data_t *vtd, int new_w, int new_h)
+{
+ int i;
+
+ vtd->preadj_w = new_w;
+ vtd->preadj_h = new_h;
+ for (i = 0; i < vtd->nplanes-1; i++) {
+ int planesize = (new_w/vtd->width_div[i]) * (new_h/vtd->height_div[i])
+ * vtd->Bpp;
+ vtd->tmpplanes[i+1] = vtd->tmpplanes[i] + planesize;
+ }
+}
+
+/*************************************************************************/
+
+/**
+ * swap_buffers: Swap current video frame buffer with free buffer. Also
+ * updates frame size if preadjust_frame_size() has been called.
+ *
+ * Parameters:
+ * vtd: Pointer to video frame data.
+ * Return value:
+ * None.
+ */
+
+static void swap_buffers(video_trans_data_t *vtd)
+{
+ vtd->ptr->video_buf = vtd->ptr->video_buf_Y[vtd->ptr->free];
+ vtd->ptr->free = (vtd->ptr->free==0) ? 1 : 0;
+ /* Install new width/height if preadjust_frame_size() was called */
+ if (vtd->preadj_w && vtd->preadj_h) {
+ vtd->ptr->v_width = vtd->preadj_w;
+ vtd->ptr->v_height = vtd->preadj_h;
+ vtd->preadj_w = 0;
+ vtd->preadj_h = 0;
+ }
+ /* Set up plane pointers again */
+ set_vtd(vtd, vtd->ptr);
+}
+
+/*************************************************************************/
+/*************************************************************************/
+
+/**
+ * do_process_frame: Perform video frame transformations based on global
+ * transcoding settings (derived from command-line arguments).
+ *
+ * Parameters:
+ * vob: Global data pointer.
+ * ptr: Pointer to video frame buffer.
+ * Return value:
+ * 0 on success, -1 on failure.
+ */
+
+static int do_process_frame(vob_t *vob, vframe_list_t *ptr)
+{
+ video_trans_data_t vtd; /* for passing to subroutines */
+
+
+ /**** Sanity check and initialization ****/
+
+ if (ptr->video_buf_Y[0] == ptr->video_buf_Y[1]) {
+ tc_log_error(__FILE__, "video frame has no temporary buffer!");
+ return -1;
+ }
+ if (ptr->video_buf == ptr->video_buf_Y[ptr->free]) {
+ static int warned = 0;
+ if (!warned) {
+ tc_log_warn(__FILE__, "ptr->free points to wrong buffer"
+ " (BUG in transcode or modules)");
+ warned = 1;
+ }
+ ptr->free = !ptr->free;
+ }
+ set_vtd(&vtd, ptr);
+
+ /**** -j: clip frame (import) ****/
+
+ if (im_clip) {
+ preadjust_frame_size(&vtd,
+ ptr->v_width - vob->im_clip_left - vob->im_clip_right,
+ ptr->v_height - vob->im_clip_top - vob->im_clip_bottom);
+ PROCESS_FRAME(tcv_clip, &vtd,
+ vob->im_clip_left / vtd.width_div[i],
+ vob->im_clip_right / vtd.width_div[i],
+ vob->im_clip_top / vtd.height_div[i],
+ vob->im_clip_bottom / vtd.height_div[i],
+ vtd.black_pixel[i]);
+ }
+
+ /**** -I: deinterlace video frame ****/
+
+ if (vob->deinterlace > 0
+ || ((ptr->attributes & TC_FRAME_IS_INTERLACED) && ptr->deinter_flag > 0)
+ ) {
+ int mode = (vob->deinterlace>0 ? vob->deinterlace : ptr->deinter_flag);
+ if (mode == 1) {
+ /* Simple linear interpolation */
+ /* Note that for YUV, we can just leave U and V alone, since
+ * they already cover pairs of lines; thus instead of using
+ * PROCESS_FRAME, we just call tcv_deinterlace() on the Y/RGB
+ * plane, then copy the other two planes and swap_buffers(). */
+ int i;
+ tcv_deinterlace(handle, vtd.planes[0], vtd.tmpplanes[0],
+ ptr->v_width, ptr->v_height, vtd.Bpp,
+ TCV_DEINTERLACE_INTERPOLATE);
+ for (i = 1; i < vtd.nplanes; i++) {
+ ac_memcpy(vtd.tmpplanes[i], vtd.planes[i],
+ (ptr->v_width/vtd.width_div[i])
+ * (ptr->v_height/vtd.height_div[i]));
+ }
+ swap_buffers(&vtd);
+ } else if (mode == 3 || mode == 4) {
+ /* Drop every other line (and zoom back out in mode 3) */
+ preadjust_frame_size(&vtd, ptr->v_width, ptr->v_height/2);
+ /* Drop the top or the bottom field? (Does it matter?) */
+ PROCESS_FRAME(tcv_deinterlace, &vtd,
+ TCV_DEINTERLACE_DROP_FIELD_BOTTOM);
+ if (mode == 3) {
+ int w = ptr->v_width, h = ptr->v_height*2;
+ preadjust_frame_size(&vtd, w, h);
+ PROCESS_FRAME(tcv_zoom, &vtd, w / vtd.width_div[i],
+ h / vtd.height_div[i], vob->zoom_filter);
+ }
+ } else if (mode == 5) {
+ /* Linear blend; as for -I 1, only Y is processed in YUV mode */
+ int i;
+ tcv_deinterlace(handle, vtd.planes[0], vtd.tmpplanes[0],
+ ptr->v_width, ptr->v_height, vtd.Bpp,
+ TCV_DEINTERLACE_LINEAR_BLEND);
+ for (i = 1; i < vtd.nplanes; i++) {
+ ac_memcpy(vtd.tmpplanes[i], vtd.planes[i],
+ (ptr->v_width/vtd.width_div[i])
+ * (ptr->v_height/vtd.height_div[i]));
+ }
+ swap_buffers(&vtd);
+ }
+ /* else mode 2 (handled by encoder) or unknown: do nothing */
+ ptr->attributes &= ~TC_FRAME_IS_INTERLACED;
+ }
+
+ /**** -X: fast resize (up) ****/
+ /**** -B: fast resize (down) ****/
+
+ if (resize1 || resize2) {
+ int width = ptr->v_width, height = ptr->v_height;
+ int resize_w = vob->hori_resize2 - vob->hori_resize1;
+ int resize_h = vob->vert_resize2 - vob->vert_resize1;
+ if (resize_h) {
+ preadjust_frame_size(&vtd, width, height+resize_h*8);
+ PROCESS_FRAME(tcv_resize, &vtd, 0, resize_h, 8/vtd.width_div[i],
+ 8/vtd.height_div[i]);
+ height += resize_h * 8;
+ }
+ if (resize_w) {
+ preadjust_frame_size(&vtd, width+resize_w*8, height);
+ PROCESS_FRAME(tcv_resize, &vtd, resize_w, 0, 8/vtd.width_div[i],
+ 8/vtd.height_div[i]);
+ }
+ }
+
+ /**** -Z: zoom frame (slow resize) ****/
+
+ if (zoom) {
+ preadjust_frame_size(&vtd, vob->zoom_width, vob->zoom_height);
+ if (vob->zoom_interlaced) {
+ /* In YUV mode, only handle the first place as interlaced;
+ * the U and V planes are shared between both fields */
+ int i;
+ tcv_zoom(handle, vtd.planes[0], vtd.tmpplanes[0],
+ ptr->v_width, ptr->v_height, vtd.Bpp,
+ vob->zoom_width, -vob->zoom_height, vob->zoom_filter);
+ for (i = 1; i < vtd.nplanes; i++) {
+ tcv_zoom(handle, vtd.planes[i], vtd.tmpplanes[i],
+ ptr->v_width / vtd.width_div[i],
+ ptr->v_height / vtd.height_div[i], vtd.Bpp,
+ vob->zoom_width / vtd.width_div[i],
+ vob->zoom_height / vtd.height_div[i],
+ vob->zoom_filter);
+ }
+ swap_buffers(&vtd);
+ } else {
+ PROCESS_FRAME(tcv_zoom, &vtd, vob->zoom_width / vtd.width_div[i],
+ vob->zoom_height / vtd.height_div[i],
+ vob->zoom_filter);
+ }
+ }
+
+ /**** -Y: clip frame (export) ****/
+
+ if (ex_clip) {
+ preadjust_frame_size(&vtd,
+ ptr->v_width - vob->ex_clip_left-vob->ex_clip_right,
+ ptr->v_height - vob->ex_clip_top - vob->ex_clip_bottom);
+ PROCESS_FRAME(tcv_clip, &vtd,
+ vob->ex_clip_left / vtd.width_div[i],
+ vob->ex_clip_right / vtd.width_div[i],
+ vob->ex_clip_top / vtd.height_div[i],
+ vob->ex_clip_bottom / vtd.height_div[i],
+ vtd.black_pixel[i]);
+ }
+
+ /**** -r: rescale video frame ****/
+
+ if (rescale) {
+ preadjust_frame_size(&vtd, ptr->v_width / vob->reduce_w,
+ ptr->v_height / vob->reduce_h);
+ PROCESS_FRAME(tcv_reduce, &vtd, vob->reduce_w, vob->reduce_h);
+ }
+
+ /**** -z: flip frame vertically ****/
+
+ if (flip) {
+ PROCESS_FRAME(tcv_flip_v, &vtd);
+ }
+
+ /**** -l: flip flame horizontally (mirror) ****/
+
+ if (mirror) {
+ PROCESS_FRAME(tcv_flip_h, &vtd);
+ }
+
+ /**** -k: red/blue swap ****/
+
+ if (rgbswap) {
+ if (ptr->v_codec == CODEC_RGB) {
+ int i;
+ for (i = 0; i < ptr->v_width * ptr->v_height; i++) {
+ uint8_t tmp = vtd.planes[0][i*3];
+ vtd.planes[0][i*3] = vtd.planes[0][i*3+2];
+ vtd.planes[0][i*3+2] = tmp;
+ }
+ } else {
+ int UVsize = (ptr->v_width / vtd.width_div[1])
+ * (ptr->v_height / vtd.height_div[1]) * vtd.Bpp;
+ ac_memcpy(vtd.tmpplanes[1], vtd.planes[1], UVsize); /* tmp<-U */
+ ac_memcpy(vtd.planes[1], vtd.planes[2], UVsize); /* U<-V */
+ ac_memcpy(vtd.planes[2], vtd.tmpplanes[1], UVsize); /* V<-tmp */
+ }
+ }
+
+ /**** -K: grayscale ****/
+
+ if (decolor) {
+ if (ptr->v_codec == CODEC_RGB) {
+ /* Convert to 8-bit grayscale, then back to RGB24. Just
+ * averaging the values won't give us the right intensity. */
+ tcv_convert(handle, vtd.planes[0], vtd.tmpplanes[0],
+ ptr->v_width, ptr->v_height, IMG_RGB24, IMG_GRAY8);
+ tcv_convert(handle, vtd.tmpplanes[0], vtd.planes[0],
+ ptr->v_width, ptr->v_height, IMG_GRAY8, IMG_RGB24);
+ } else {
+ /* YUV is easy: just set U and V to 128 */
+ int UVsize = (ptr->v_width / vtd.width_div[1])
+ * (ptr->v_height / vtd.height_div[1]) * vtd.Bpp;
+ memset(vtd.planes[1], 128, UVsize);
+ memset(vtd.planes[2], 128, UVsize);
+ }
+ }
+
+ /**** -G: gamma correction ****/
+
+ if (dgamma) {
+ /* Only process the first plane (Y) for YUV; for RGB it's all in
+ * one plane anyway */
+ tcv_gamma_correct(handle, ptr->video_buf, ptr->video_buf,
+ ptr->v_width, ptr->v_height, vtd.Bpp, vob->gamma);
+ }
+
+ /**** -C: antialiasing ****/
+
+ if (vob->antialias) {
+ /* Only Y is antialiased; U and V remain the same */
+ tcv_antialias(handle, vtd.planes[0], vtd.tmpplanes[0],
+ ptr->v_width, ptr->v_height, vtd.Bpp,
+ vob->aa_weight, vob->aa_bias);
+ if (ptr->v_codec != CODEC_RGB) {
+ int UVsize = (ptr->v_width / vtd.width_div[1])
+ * (ptr->v_height / vtd.height_div[1]) * vtd.Bpp;
+ ac_memcpy(vtd.tmpplanes[1], vtd.planes[1], UVsize);
+ ac_memcpy(vtd.tmpplanes[2], vtd.planes[2], UVsize);
+ }
+ swap_buffers(&vtd);
+ }
+
+ /**** End of processing ****/
+
+ return 0;
+}
+
+/*************************************************************************/
+/*************************** Exported routines ***************************/
+/*************************************************************************/
+
+/**
+ * process_vid_frame: Main video frame processing routine. The image is
+ * passed in ptr->video_buf; this can be updated as needed, e.g. to point
+ * to the secondary buffer after transformations.
+ *
+ * Parameters:
+ * vob: Global data pointer.
+ * ptr: Pointer to video frame buffer.
+ * Return value:
+ * 0 on success, -1 on failure.
+ */
+
+int process_vid_frame(vob_t *vob, vframe_list_t *ptr)
+{
+ /* Check parameter validity */
+ if (!vob || !ptr)
+ return -1;
+
+ /* Check for pass-through mode or skipped frames */
+ if (vob->pass_flag & TC_VIDEO)
+ return 0;
+ if (ptr->attributes & TC_FRAME_IS_SKIPPED)
+ return 0;
+
+ /* It's a valid frame, check the colorspace for validity and process it */
+ if (vob->im_v_codec == CODEC_RGB
+ || vob->im_v_codec == CODEC_YUV
+ || vob->im_v_codec == CODEC_YUV422
+ ) {
+ ptr->v_codec = vob->im_v_codec;
+ return do_process_frame(vob, ptr);
+ }
+
+ /* Invalid colorspace, bail out */
+ tc_error("Oops, invalid colorspace video frame data");
+ return -1;
+}
+
+/*************************************************************************/
+
+/**
+ * preprocess_vid_frame: Frame preprocessing routine. Checks for frame
+ * out of -c range and performs early clipping.
+ *
+ * Parameters:
+ * vob: Global data pointer.
+ * ptr: Pointer to video frame buffer.
+ * Return value:
+ * 0 on success, -1 on failure.
+ */
+
+int preprocess_vid_frame(vob_t *vob, vframe_list_t *ptr)
+{
+ /* Check parameter validity */
+ if (!vob || !ptr)
+ return -1;
+
+ /* Allocate tcvideo handle if necessary */
+ if (!handle) {
+ handle = tcv_init();
+ if (!handle) {
+ tc_log_error(PACKAGE, "video_trans.c: tcv_init() failed!");
+ return -1;
+ }
+ }
+
+ /* Check for pass-through mode */
+ if (vob->pass_flag & TC_VIDEO)
+ return 0;
+
+ /* Check frame colorspace */
+ if (vob->im_v_codec != CODEC_RGB
+ && vob->im_v_codec != CODEC_YUV
+ && vob->im_v_codec != CODEC_YUV422
+ ) {
+ tc_error("Oops, invalid colorspace video frame data");
+ return -1;
+ }
+
+ /* Perform early clipping */
+ if (pre_im_clip) {
+ video_trans_data_t vtd;
+ ptr->v_codec = vob->im_v_codec;
+ set_vtd(&vtd, ptr);
+ preadjust_frame_size(&vtd,
+ ptr->v_width - vob->pre_im_clip_left - vob->pre_im_clip_right,
+ ptr->v_height - vob->pre_im_clip_top - vob->pre_im_clip_bottom);
+ PROCESS_FRAME(tcv_clip, &vtd,
+ vob->pre_im_clip_left / vtd.width_div[i],
+ vob->pre_im_clip_right / vtd.width_div[i],
+ vob->pre_im_clip_top / vtd.height_div[i],
+ vob->pre_im_clip_bottom / vtd.height_div[i],
+ vtd.black_pixel[i]);
+ }
+
+ /* Finished with preprocessing */
+ return 0;
+}
+
+/*************************************************************************/
+
+/**
+ * postprocess_vid_frame: Frame postprocessing routine. Performs final
+ * clipping and sanity checks.
+ *
+ * Parameters:
+ * vob: Global data pointer.
+ * ptr: Pointer to video frame buffer.
+ * Return value:
+ * 0 on success, -1 on failure.
+ */
+
+/* Frame postprocessing routine. Performs final clipping and sanity
+ * checks. Parameters are as for process_vid_frame().
+ */
+
+int postprocess_vid_frame(vob_t *vob, vframe_list_t *ptr)
+{
+ /* Check parameter validity */
+ if (!vob || !ptr)
+ return -1;
+
+ /* Check for pass-through mode or skipped frames */
+ if (vob->pass_flag & TC_VIDEO)
+ return 0;
+ if (ptr->attributes & TC_FRAME_IS_SKIPPED)
+ return 0;
+
+ /* Check frame colorspace */
+ if (vob->im_v_codec != CODEC_RGB
+ && vob->im_v_codec != CODEC_YUV
+ && vob->im_v_codec != CODEC_YUV422
+ ) {
+ tc_error("Oops, invalid colorspace video frame data");
+ return -1;
+ }
+
+ /* Perform final clipping, if this isn't a cloned frame */
+ if (post_ex_clip && !(ptr->attributes & TC_FRAME_WAS_CLONED)) {
+ video_trans_data_t vtd;
+ ptr->v_codec = vob->im_v_codec;
+ set_vtd(&vtd, ptr);
+ preadjust_frame_size(&vtd,
+ ptr->v_width - vob->post_ex_clip_left - vob->post_ex_clip_right,
+ ptr->v_height - vob->post_ex_clip_top - vob->post_ex_clip_bottom);
+ PROCESS_FRAME(tcv_clip, &vtd,
+ vob->post_ex_clip_left / vtd.width_div[i],
+ vob->post_ex_clip_right / vtd.width_div[i],
+ vob->post_ex_clip_top / vtd.height_div[i],
+ vob->post_ex_clip_bottom / vtd.height_div[i],
+ vtd.black_pixel[i]);
+ }
+
+ /* Sanity check: make sure the frame size is what we're expecting */
+ if (ptr->v_width != vob->ex_v_width || ptr->v_height != vob->ex_v_height) {
+ tc_log_msg(__FILE__, "width %d %d | height %d %d",
+ ptr->v_width, vob->ex_v_width,
+ ptr->v_height, vob->ex_v_height);
+ tc_error("Oops, frame parameter mismatch detected");
+ }
+
+ /* Finished with postprocessing */
+ return 0;
+}
+
+/*************************************************************************/
+
+/*
+ * Local variables:
+ * c-file-style: "stroustrup"
+ * c-file-offsets: ((case-label . *) (statement-case-intro . *))
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vim: expandtab shiftwidth=4:
+ */