[Ffmpeg-devel] interlace and motion artifacts

Dan Maas dmaas
Wed Feb 15 20:55:25 CET 2006


> If the input is 480i or 1080i, the output often (not always)
> has massive amounts of motion artifacts.

I had this problem yesterday while transcoding from MPEG-2 to DV. The
field order of the resulting DV video was obviously wrong.

The solution is to shift the video image up or down by one
scanline. Unfortunately, ffmpeg's -pad/-crop options do not
work in increments of one pixel.

So, I hacked myself a new command-line switch that cycles the image up
by one scanline. Attached. Use "-shift 1" to reverse the field
order. I only implented this for PIX_FMT_YUV422P but it should be
easy to do for other formats.

Regards,
Dan
-------------- next part --------------
Index: ffmpeg.c
===================================================================
RCS file: /cvsroot/ffmpeg/ffmpeg/ffmpeg.c,v
retrieving revision 1.368
diff -u -p -r1.368 ffmpeg.c
--- ffmpeg.c	1 Feb 2006 11:31:33 -0000	1.368
+++ ffmpeg.c	15 Feb 2006 19:52:46 -0000
@@ -100,6 +100,7 @@ static int frame_topBand  = 0;
 static int frame_bottomBand = 0;
 static int frame_leftBand  = 0;
 static int frame_rightBand = 0;
+static int frame_shift = 0;
 static int max_frames[4] = {INT_MAX, INT_MAX, INT_MAX, INT_MAX};
 static int frame_rate = 25;
 static int frame_rate_base = 1;
@@ -280,6 +281,8 @@ typedef struct AVOutputStream {
     int padleft;
     int padright;
 
+    int video_shift;         /* shift by N scanlines for manipulating field order */
+
     /* audio only */
     int audio_resample;
     ReSampleContext *resample; /* for audio resampling */
@@ -913,6 +916,31 @@ static void do_video_out(AVFormatContext
     } else {
         final_picture = formatted_picture;
     }
+
+    if(ost->video_shift != 0) {
+	uint8_t *tempbuf;
+	int chan;
+
+	if(enc->pix_fmt != PIX_FMT_YUV422P) {
+	    fprintf(stderr, "shift only works in 4:2:2 mode\n");
+	    goto the_end;
+	}
+
+	tempbuf = alloca(final_picture->linesize[0]);
+
+	for(chan = 0; chan < 3; chan++) {
+	    int y;
+	    memcpy(tempbuf, final_picture->data[chan], final_picture->linesize[chan]);
+	    for(y = 1; y < enc->height; y++) {
+		memcpy(final_picture->data[chan] + (y-1)*final_picture->linesize[chan],
+		       final_picture->data[chan] + (y)*final_picture->linesize[chan],
+		       final_picture->linesize[chan]);
+	    }
+	    memcpy(final_picture->data[chan] + (enc->height-1) * final_picture->linesize[chan],
+		   tempbuf, final_picture->linesize[chan]);
+	}
+    }
+    
     /* duplicates frame if needed */
     for(i=0;i<nb_frames;i++) {
         AVPacket pkt;
@@ -1771,6 +1799,7 @@ static int av_encode(AVFormatContext **o
                     ost->padright = frame_padright;
 
                 }
+		ost->video_shift = frame_shift;
                 ost->encoding_needed = 1;
                 ist->decoding_needed = 1;
                 break;
@@ -2450,6 +2479,14 @@ static void opt_frame_pad_right(const ch
     }
 }
 
+static void opt_frame_shift(const char *arg)
+{
+    frame_shift = atoi(arg);
+    if (frame_shift < -1 || frame_shift > 1) {
+	fprintf(stderr, "Frame shift must be -1, 0, or 1\n");
+	exit(1);
+    }
+}
 
 static void opt_frame_pix_fmt(const char *arg)
 {
@@ -4053,6 +4090,7 @@ const OptionDef options[] = {
     { "padleft", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_pad_left}, "set left pad band size (in pixels)", "size" },
     { "padright", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_pad_right}, "set right pad band size (in pixels)", "size" },
     { "padcolor", HAS_ARG | OPT_VIDEO, {(void*)opt_pad_color}, "set color of pad bands (Hex 000000 thru FFFFFF)", "color" },
+    { "shift", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_shift}, "shift image up or down by 1 pixel to change field order (-1, 0, or 1)", "size" },
     { "g", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_gop_size}, "set the group of picture size", "gop_size" },
     { "intra", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&intra_only}, "use only intra frames"},
     { "vn", OPT_BOOL | OPT_VIDEO, {(void*)&video_disable}, "disable video" },



More information about the ffmpeg-devel mailing list