Package-Name: ffmpeg-cvs
Conflicts: ffmpeg
Rebuild-For: lame x264-svn
Homepage: http://ffmpeg.sourceforge.net/
Source: svn://svn/svn.mplayerhq.hu/ffmpeg/trunk/ffmpeg/(.*) $1
Zap-Before-Install: 1
Repack:
	tar xzvfp "$(SOURCE)"
	mv ffmpeg* ffmpeg-cvs-"$(VERSION)"
Compile:
	cp -pf COPYING* CREDITS Change* README "$(PREFIX)/"
	if packager c lame; then LAME=--enable-mp3lame; else LAME=; fi; \
	if packager c x264-svn; then X264=--enable-x264; else X264=; fi; \
# FIXME: --enable-mp3lame and --enable-x264 cause dependencies on the respective libraries in other programs
	LAME=; X264=; \
	./configure --prefix="$(PREFIX)" --cc=gcc --extra-cflags="-O3 $(GCC_OPT_FLAGS)" --enable-gpl --enable-pp $$LAME $$X264
	$(MAKE)
	$(MAKE) install
Install:
	$(MAKE) instbin BIN="ffmpeg ffplay ffserver"
	$(MAKE) instinc INC="ffmpeg postproc"
	$(MAKE) instlib LIB="avcodec avformat avutil postproc"
	$(MAKE) instpc PC="libavcodec libavformat libavutil libpostproc"
NoPatch: <<EOT
######## begin x264 pthread patch (required as of 2006/4/21, no longer needed as of 2006/9/27?)
--- configure.old	2006-03-08 13:13:55 +0900
+++ configure	2006-04-01 12:46:05 +0900
@@ -555,7 +555,7 @@
     extralibs="$extralibs -lxvidcore"
   ;;
   --enable-x264) x264="yes"
-    extralibs="$extralibs -lx264"
+    extralibs="$extralibs -lpthread -lx264"
   ;;
   --enable-dc1394) dc1394="yes"
     extralibs="$extralibs -ldc1394_control -lraw1394"
######## end x264 pthread patch (required as of 2006/4/1)
EOT
Patch: <<EOT
--- ffmpeg.c.old	2006-09-27 12:56:06 +0900
+++ ffmpeg.c	2006-09-27 14:48:26 +0900
@@ -259,6 +259,8 @@
     int padleft;
     int padright;
 
+    int half_size;           /* video_resample and half_size are mutually exclusive */
+
     /* audio only */
     int audio_resample;
     ReSampleContext *resample; /* for audio resampling */
@@ -777,6 +779,151 @@
                 ost->padtop, ost->padbottom, ost->padleft, ost->padright, padcolor);
     }
 
+    if (ost->half_size) {
+	int x, y;
+	unsigned char *src, *dest;
+#if 1
+	asm("	push	%%ebx			\n"
+	    "	push	%%ecx			\n"	// Need to save modified input regs (reused later)
+	    "	push	%%edx			\n"
+	    "	mov	%%edi,%%ebx		\n"	// Source line size in EBX
+	    "	mov	%%esi,%%edi		\n"	// Destination pointer in EDI
+	    "	mov	$0x00FF00FF,%%eax	\n"	// Set up XMM0 to clear high bytes of words
+	    "	movd	%%eax,%%xmm0		\n"
+	    "	movdqa	%%xmm0,%%xmm1		\n"
+	    "	pslldq	$4,%%xmm1		\n"
+	    "	por	%%xmm1,%%xmm0		\n"
+	    "	movdqa	%%xmm0,%%xmm1		\n"
+	    "	pslldq	$8,%%xmm1		\n"
+	    "	por	%%xmm1,%%xmm0		\n"
+	    "0:	xor	%%eax,%%eax		\n"
+	    "1:	movdqu	(%%esi,%%eax,2),%%xmm1	\n"	// Read 32 pixels
+	    "	movdqu	16(%%esi,%%eax,2),%%xmm2\n"
+	    "	pand	%%xmm0,%%xmm1		\n"	// Clear odd pixels (== high bytes of words)
+	    "	pand	%%xmm0,%%xmm2		\n"
+	    "	packuswb %%xmm2,%%xmm1		\n"	// Pack even pixels into XMM1
+	    "	movdqu	%%xmm1,(%%edi,%%eax)	\n"	// And store
+	    "	add	$16,%%eax		\n"
+	    "	cmp	%%ecx,%%eax		\n"
+	    "	jb	1b			\n"
+	    "	add	%%ebx,%%esi		\n"	// Advance pointers to next line
+	    "	add	%%ecx,%%edi		\n"
+	    "	dec	%%edx			\n"
+	    "	jnz	0b			\n"
+	    "	emms				\n"
+	    "	sfence				\n"
+	    "	pop	%%edx			\n"
+	    "	pop	%%ecx			\n"
+	    "	pop	%%ebx"
+	    : // no outputs
+	    : "c" (enc->width), "d" (enc->height), "S" (final_picture->data[0]), "D" (final_picture->linesize[0]*2)
+	    : "eax");
+	for (x = 1; x <= 2; x++)
+	asm("	push	%%ebx			\n"
+	    "	push	%%ebp			\n"
+	    "	push	%%ecx			\n"
+	    "	push	%%edx			\n"
+	    "	mov	%%edi,%%ebx		\n"	// Source line size in EBX
+	    "	mov	%%esi,%%ebp		\n"	// Odd line pointer in EBP
+	    "	add	%%ebx,%%ebp		\n"
+	    "	mov	%%esi,%%edi		\n"	// Destination pointer in EDI
+	    "	shl	$1,%%ebx		\n"	// Skip a line each loop
+//	    "	mov	$0x00FF00FF,%%eax	\n"	// Set up XMM0 and XMM1 to clear high and low bytes of words, respectively
+//	    "	movd	%%eax,%%xmm0		\n"	// (XMM0 already set up from above)
+//	    "	movdqa	%%xmm0,%%xmm1		\n"
+//	    "	pslldq	$4,%%xmm1		\n"
+//	    "	por	%%xmm1,%%xmm0		\n"
+//	    "	movdqa	%%xmm0,%%xmm1		\n"
+//	    "	pslldq	$8,%%xmm1		\n"
+//	    "	por	%%xmm1,%%xmm0		\n"
+	    "	movdqa	%%xmm0,%%xmm1		\n"
+	    "	pslldq	$1,%%xmm1		\n"
+	    "	mov	$0x00020002,%%eax	\n"	// Set up XMM2 with 8 words of 0x0002 (for rounding when averaging)
+	    "	movd	%%eax,%%xmm2		\n"
+	    "	movdqa	%%xmm2,%%xmm3		\n"
+	    "	pslldq	$4,%%xmm3		\n"
+	    "	por	%%xmm3,%%xmm2		\n"
+	    "	movdqa	%%xmm2,%%xmm3		\n"
+	    "	pslldq	$8,%%xmm3		\n"
+	    "	por	%%xmm3,%%xmm2		\n"
+	    "0:	xor	%%eax,%%eax		\n"
+	    "1:	movdqu	(%%esi,%%eax,2),%%xmm4	\n"	// Read 32 pixels from each of 2 lines
+	    "	movdqu	16(%%esi,%%eax,2),%%xmm5\n"
+	    "	movdqu	(%%ebp,%%eax,2),%%xmm6	\n"
+	    "	movdqu	16(%%ebp,%%eax,2),%%xmm7\n"
+	    "	movdqa	%%xmm4,%%xmm3		\n"	// Add odd and even pixels together
+	    "	pand	%%xmm1,%%xmm3		\n"
+	    "	pand	%%xmm0,%%xmm4		\n"
+	    "	psrldq	$1,%%xmm3		\n"
+	    "	paddw	%%xmm3,%%xmm4		\n"
+	    "	movdqa	%%xmm5,%%xmm3		\n"
+	    "	pand	%%xmm1,%%xmm3		\n"
+	    "	pand	%%xmm0,%%xmm5		\n"
+	    "	psrldq	$1,%%xmm3		\n"
+	    "	paddw	%%xmm3,%%xmm5		\n"
+	    "	movdqa	%%xmm6,%%xmm3		\n"
+	    "	pand	%%xmm1,%%xmm3		\n"
+	    "	pand	%%xmm0,%%xmm6		\n"
+	    "	psrldq	$1,%%xmm3		\n"
+	    "	paddw	%%xmm3,%%xmm6		\n"
+	    "	movdqa	%%xmm7,%%xmm3		\n"
+	    "	pand	%%xmm1,%%xmm3		\n"
+	    "	pand	%%xmm0,%%xmm7		\n"
+	    "	psrldq	$1,%%xmm3		\n"
+	    "	paddw	%%xmm3,%%xmm7		\n"
+	    "	paddw	%%xmm6,%%xmm4		\n"	// Add top and bottom pixels together
+	    "	paddw	%%xmm7,%%xmm5		\n"
+	    "	paddw	%%xmm2,%%xmm4		\n"	// Add 2 to each pixel sum for rounding
+	    "	paddw	%%xmm2,%%xmm5		\n"
+	    "	psrlw	$2,%%xmm4		\n"	// Divide sums by 4
+	    "	psrlw	$2,%%xmm5		\n"
+	    "	packuswb %%xmm5,%%xmm4		\n"	// Pack into bytes
+	    "	movdqu	%%xmm4,(%%edi,%%eax)	\n"	// And store 16 destination pixels
+	    "	add	$16,%%eax		\n"
+	    "	cmp	%%ecx,%%eax		\n"
+	    "	jb	1b			\n"
+	    "	add	%%ebx,%%esi		\n"	// Update pointers
+	    "	add	%%ebx,%%ebp		\n"
+	    "	add	%%ecx,%%edi		\n"
+	    "	dec	%%edx			\n"
+	    "	jnz	0b			\n"
+	    "	emms				\n"
+	    "	sfence				\n"
+	    "	pop	%%edx			\n"
+	    "	pop	%%ecx			\n"
+	    "	pop	%%ebp			\n"
+	    "	pop	%%ebx"
+	    : // no outputs
+	    : "c" (enc->width/2), "d" (enc->height/2), "S" (final_picture->data[x]), "D" (final_picture->linesize[x])
+	    : "eax");
+#else
+	src = dest = final_picture->data[0];
+	for (y = 0; y < enc->height; y++) {
+	    for (x = 0; x < enc->width; x++)
+		dest[x] = src[x*2];
+	    src += final_picture->linesize[0]*2;
+	    dest += enc->width;
+	}
+	src = dest = final_picture->data[1];
+	for (y = 0; y < enc->height/2; y++) {
+	    for (x = 0; x < enc->width/2; x++)
+		dest[x] = (src[x*2] + src[x*2+1] + src[x*2+final_picture->linesize[1]] + src[x*2+final_picture->linesize[1]+1] + 2) / 4;
+	    src += final_picture->linesize[1]*2;
+	    dest += enc->width/2;
+	}
+	src = dest = final_picture->data[2];
+	for (y = 0; y < enc->height/2; y++) {
+	    for (x = 0; x < enc->width/2; x++)
+		dest[x] = (src[x*2] + src[x*2+1] + src[x*2+final_picture->linesize[2]] + src[x*2+final_picture->linesize[2]+1] + 2) / 4;
+	    src += final_picture->linesize[2]*2;
+	    dest += enc->width/2;
+	}
+#endif
+	final_picture->linesize[0] = enc->width;
+	final_picture->linesize[1] = enc->width/2;
+	final_picture->linesize[2] = enc->width/2;
+    }
+
     /* duplicates frame if needed */
     for(i=0;i<nb_frames;i++) {
         AVPacket pkt;
@@ -1606,6 +1753,10 @@
                                 (frame_topBand  + frame_bottomBand) +
                                 (frame_padtop + frame_padbottom)) ||
                         (codec->pix_fmt != icodec->pix_fmt));
+                if (ost->video_resample && codec->width*2 == icodec->width && codec->height*2 == icodec->height && codec->width%16 == 0 && !ost->video_crop && !ost->video_pad) {
+                    ost->half_size = 1;
+                    ost->video_resample = 0;
+                }
                 if (ost->video_crop) {
                     ost->topBand = frame_topBand;
                     ost->leftBand = frame_leftBand;
EOT
NoPatch: <<EOT
######## begin old half-size optimization patch
--- ../ffmpeg-cvs-20060421.1734-orig/ffmpeg.c	2006-04-20 21:57:19 +0900
+++ ffmpeg.c	2006-04-21 17:44:59 +0900
@@ -281,6 +281,8 @@
     int padleft;
     int padright;
 
+    int half_size;           /* video_resample and half_size are mutually exclusive */
+
     /* audio only */
     int audio_resample;
     ReSampleContext *resample; /* for audio resampling */
@@ -833,6 +835,151 @@
                 ost->padtop, ost->padbottom, ost->padleft, ost->padright, padcolor);
     }
 
+    if (ost->half_size) {
+	int x, y;
+	unsigned char *src, *dest;
+#if 1
+	asm("	push	%%ebx			\n"
+	    "	push	%%ecx			\n"	// Need to save modified input regs (reused later)
+	    "	push	%%edx			\n"
+	    "	mov	%%edi,%%ebx		\n"	// Source line size in EBX
+	    "	mov	%%esi,%%edi		\n"	// Destination pointer in EDI
+	    "	mov	$0x00FF00FF,%%eax	\n"	// Set up XMM0 to clear high bytes of words
+	    "	movd	%%eax,%%xmm0		\n"
+	    "	movdqa	%%xmm0,%%xmm1		\n"
+	    "	pslldq	$4,%%xmm1		\n"
+	    "	por	%%xmm1,%%xmm0		\n"
+	    "	movdqa	%%xmm0,%%xmm1		\n"
+	    "	pslldq	$8,%%xmm1		\n"
+	    "	por	%%xmm1,%%xmm0		\n"
+	    "0:	xor	%%eax,%%eax		\n"
+	    "1:	movdqu	(%%esi,%%eax,2),%%xmm1	\n"	// Read 32 pixels
+	    "	movdqu	16(%%esi,%%eax,2),%%xmm2\n"
+	    "	pand	%%xmm0,%%xmm1		\n"	// Clear odd pixels (== high bytes of words)
+	    "	pand	%%xmm0,%%xmm2		\n"
+	    "	packuswb %%xmm2,%%xmm1		\n"	// Pack even pixels into XMM1
+	    "	movdqu	%%xmm1,(%%edi,%%eax)	\n"	// And store
+	    "	add	$16,%%eax		\n"
+	    "	cmp	%%ecx,%%eax		\n"
+	    "	jb	1b			\n"
+	    "	add	%%ebx,%%esi		\n"	// Advance pointers to next line
+	    "	add	%%ecx,%%edi		\n"
+	    "	dec	%%edx			\n"
+	    "	jnz	0b			\n"
+	    "	emms				\n"
+	    "	sfence				\n"
+	    "	pop	%%edx			\n"
+	    "	pop	%%ecx			\n"
+	    "	pop	%%ebx"
+	    : // no outputs
+	    : "c" (enc->width), "d" (enc->height), "S" (final_picture->data[0]), "D" (final_picture->linesize[0]*2)
+	    : "eax");
+	for (x = 1; x <= 2; x++)
+	asm("	push	%%ebx			\n"
+	    "	push	%%ebp			\n"
+	    "	push	%%ecx			\n"
+	    "	push	%%edx			\n"
+	    "	mov	%%edi,%%ebx		\n"	// Source line size in EBX
+	    "	mov	%%esi,%%ebp		\n"	// Odd line pointer in EBP
+	    "	add	%%ebx,%%ebp		\n"
+	    "	mov	%%esi,%%edi		\n"	// Destination pointer in EDI
+	    "	shl	$1,%%ebx		\n"	// Skip a line each loop
+//	    "	mov	$0x00FF00FF,%%eax	\n"	// Set up XMM0 and XMM1 to clear high and low bytes of words, respectively
+//	    "	movd	%%eax,%%xmm0		\n"	// (XMM0 already set up from above)
+//	    "	movdqa	%%xmm0,%%xmm1		\n"
+//	    "	pslldq	$4,%%xmm1		\n"
+//	    "	por	%%xmm1,%%xmm0		\n"
+//	    "	movdqa	%%xmm0,%%xmm1		\n"
+//	    "	pslldq	$8,%%xmm1		\n"
+//	    "	por	%%xmm1,%%xmm0		\n"
+	    "	movdqa	%%xmm0,%%xmm1		\n"
+	    "	pslldq	$1,%%xmm1		\n"
+	    "	mov	$0x00020002,%%eax	\n"	// Set up XMM2 with 8 words of 0x0002 (for rounding when averaging)
+	    "	movd	%%eax,%%xmm2		\n"
+	    "	movdqa	%%xmm2,%%xmm3		\n"
+	    "	pslldq	$4,%%xmm3		\n"
+	    "	por	%%xmm3,%%xmm2		\n"
+	    "	movdqa	%%xmm2,%%xmm3		\n"
+	    "	pslldq	$8,%%xmm3		\n"
+	    "	por	%%xmm3,%%xmm2		\n"
+	    "0:	xor	%%eax,%%eax		\n"
+	    "1:	movdqu	(%%esi,%%eax,2),%%xmm4	\n"	// Read 32 pixels from each of 2 lines
+	    "	movdqu	16(%%esi,%%eax,2),%%xmm5\n"
+	    "	movdqu	(%%ebp,%%eax,2),%%xmm6	\n"
+	    "	movdqu	16(%%ebp,%%eax,2),%%xmm7\n"
+	    "	movdqa	%%xmm4,%%xmm3		\n"	// Add odd and even pixels together
+	    "	pand	%%xmm1,%%xmm3		\n"
+	    "	pand	%%xmm0,%%xmm4		\n"
+	    "	psrldq	$1,%%xmm3		\n"
+	    "	paddw	%%xmm3,%%xmm4		\n"
+	    "	movdqa	%%xmm5,%%xmm3		\n"
+	    "	pand	%%xmm1,%%xmm3		\n"
+	    "	pand	%%xmm0,%%xmm5		\n"
+	    "	psrldq	$1,%%xmm3		\n"
+	    "	paddw	%%xmm3,%%xmm5		\n"
+	    "	movdqa	%%xmm6,%%xmm3		\n"
+	    "	pand	%%xmm1,%%xmm3		\n"
+	    "	pand	%%xmm0,%%xmm6		\n"
+	    "	psrldq	$1,%%xmm3		\n"
+	    "	paddw	%%xmm3,%%xmm6		\n"
+	    "	movdqa	%%xmm7,%%xmm3		\n"
+	    "	pand	%%xmm1,%%xmm3		\n"
+	    "	pand	%%xmm0,%%xmm7		\n"
+	    "	psrldq	$1,%%xmm3		\n"
+	    "	paddw	%%xmm3,%%xmm7		\n"
+	    "	paddw	%%xmm6,%%xmm4		\n"	// Add top and bottom pixels together
+	    "	paddw	%%xmm7,%%xmm5		\n"
+	    "	paddw	%%xmm2,%%xmm4		\n"	// Add 2 to each pixel sum for rounding
+	    "	paddw	%%xmm2,%%xmm5		\n"
+	    "	psrlw	$2,%%xmm4		\n"	// Divide sums by 4
+	    "	psrlw	$2,%%xmm5		\n"
+	    "	packuswb %%xmm5,%%xmm4		\n"	// Pack into bytes
+	    "	movdqu	%%xmm4,(%%edi,%%eax)	\n"	// And store 16 destination pixels
+	    "	add	$16,%%eax		\n"
+	    "	cmp	%%ecx,%%eax		\n"
+	    "	jb	1b			\n"
+	    "	add	%%ebx,%%esi		\n"	// Update pointers
+	    "	add	%%ebx,%%ebp		\n"
+	    "	add	%%ecx,%%edi		\n"
+	    "	dec	%%edx			\n"
+	    "	jnz	0b			\n"
+	    "	emms				\n"
+	    "	sfence				\n"
+	    "	pop	%%edx			\n"
+	    "	pop	%%ecx			\n"
+	    "	pop	%%ebp			\n"
+	    "	pop	%%ebx"
+	    : // no outputs
+	    : "c" (enc->width/2), "d" (enc->height/2), "S" (final_picture->data[x]), "D" (final_picture->linesize[x])
+	    : "eax");
+#else
+	src = dest = final_picture->data[0];
+	for (y = 0; y < enc->height; y++) {
+	    for (x = 0; x < enc->width; x++)
+		dest[x] = src[x*2];
+	    src += final_picture->linesize[0]*2;
+	    dest += enc->width;
+	}
+	src = dest = final_picture->data[1];
+	for (y = 0; y < enc->height/2; y++) {
+	    for (x = 0; x < enc->width/2; x++)
+		dest[x] = (src[x*2] + src[x*2+1] + src[x*2+final_picture->linesize[1]] + src[x*2+final_picture->linesize[1]+1] + 2) / 4;
+	    src += final_picture->linesize[1]*2;
+	    dest += enc->width/2;
+	}
+	src = dest = final_picture->data[2];
+	for (y = 0; y < enc->height/2; y++) {
+	    for (x = 0; x < enc->width/2; x++)
+		dest[x] = (src[x*2] + src[x*2+1] + src[x*2+final_picture->linesize[2]] + src[x*2+final_picture->linesize[2]+1] + 2) / 4;
+	    src += final_picture->linesize[2]*2;
+	    dest += enc->width/2;
+	}
+#endif
+	final_picture->linesize[0] = enc->width;
+	final_picture->linesize[1] = enc->width/2;
+	final_picture->linesize[2] = enc->width/2;
+    }
+
     /* duplicates frame if needed */
     for(i=0;i<nb_frames;i++) {
         AVPacket pkt;
@@ -1640,6 +1787,10 @@
                         (codec->height != icodec->height -
                                 (frame_topBand  + frame_bottomBand) +
                                 (frame_padtop + frame_padbottom)));
+                if (ost->video_resample && codec->width*2 == icodec->width && codec->height*2 == icodec->height && codec->width%16 == 0 && !ost->video_crop && !ost->video_pad) {
+                    ost->half_size = 1;
+                    ost->video_resample = 0;
+                }
                 if (ost->video_crop) {
                     ost->topBand = frame_topBand;
                     ost->leftBand = frame_leftBand;
######## end old half-size optimization patch
######## begin older half-size optimization patch
--- ffmpeg.c.old	2005-12-18 03:14:26 +0900
+++ ffmpeg.c	2005-12-18 23:54:46 +0900
@@ -276,6 +276,8 @@
     int padleft;
     int padright;
 
+    int half_size;           /* video_resample and half_size are mutually exclusive */
+
     /* audio only */
     int audio_resample;
     ReSampleContext *resample; /* for audio resampling */
@@ -909,6 +911,150 @@
     } else {
         final_picture = formatted_picture;
     }
+    if (ost->half_size) {
+	int x, y;
+	unsigned char *src, *dest;
+#if 1
+	asm("	push	%%ebx			\n"
+	    "	push	%%ecx			\n"	// Need to save modified input regs (reused later)
+	    "	push	%%edx			\n"
+	    "	mov	%%edi,%%ebx		\n"	// Source line size in EBX
+	    "	mov	%%esi,%%edi		\n"	// Destination pointer in EDI
+	    "	mov	$0x00FF00FF,%%eax	\n"	// Set up XMM0 to clear high bytes of words
+	    "	movd	%%eax,%%xmm0		\n"
+	    "	movdqa	%%xmm0,%%xmm1		\n"
+	    "	pslldq	$4,%%xmm1		\n"
+	    "	por	%%xmm1,%%xmm0		\n"
+	    "	movdqa	%%xmm0,%%xmm1		\n"
+	    "	pslldq	$8,%%xmm1		\n"
+	    "	por	%%xmm1,%%xmm0		\n"
+	    "0:	xor	%%eax,%%eax		\n"
+	    "1:	movdqu	(%%esi,%%eax,2),%%xmm1	\n"	// Read 32 pixels
+	    "	movdqu	16(%%esi,%%eax,2),%%xmm2\n"
+	    "	pand	%%xmm0,%%xmm1		\n"	// Clear odd pixels (== high bytes of words)
+	    "	pand	%%xmm0,%%xmm2		\n"
+	    "	packuswb %%xmm2,%%xmm1		\n"	// Pack even pixels into XMM1
+	    "	movdqu	%%xmm1,(%%edi,%%eax)	\n"	// And store
+	    "	add	$16,%%eax		\n"
+	    "	cmp	%%ecx,%%eax		\n"
+	    "	jb	1b			\n"
+	    "	add	%%ebx,%%esi		\n"	// Advance pointers to next line
+	    "	add	%%ecx,%%edi		\n"
+	    "	dec	%%edx			\n"
+	    "	jnz	0b			\n"
+	    "	emms				\n"
+	    "	sfence				\n"
+	    "	pop	%%edx			\n"
+	    "	pop	%%ecx			\n"
+	    "	pop	%%ebx"
+	    : // no outputs
+	    : "c" (enc->width), "d" (enc->height), "S" (final_picture->data[0]), "D" (final_picture->linesize[0]*2)
+	    : "eax");
+	for (x = 1; x <= 2; x++)
+	asm("	push	%%ebx			\n"
+	    "	push	%%ebp			\n"
+	    "	push	%%ecx			\n"
+	    "	push	%%edx			\n"
+	    "	mov	%%edi,%%ebx		\n"	// Source line size in EBX
+	    "	mov	%%esi,%%ebp		\n"	// Odd line pointer in EBP
+	    "	add	%%ebx,%%ebp		\n"
+	    "	mov	%%esi,%%edi		\n"	// Destination pointer in EDI
+	    "	shl	$1,%%ebx		\n"	// Skip a line each loop
+//	    "	mov	$0x00FF00FF,%%eax	\n"	// Set up XMM0 and XMM1 to clear high and low bytes of words, respectively
+//	    "	movd	%%eax,%%xmm0		\n"	// (XMM0 already set up from above)
+//	    "	movdqa	%%xmm0,%%xmm1		\n"
+//	    "	pslldq	$4,%%xmm1		\n"
+//	    "	por	%%xmm1,%%xmm0		\n"
+//	    "	movdqa	%%xmm0,%%xmm1		\n"
+//	    "	pslldq	$8,%%xmm1		\n"
+//	    "	por	%%xmm1,%%xmm0		\n"
+	    "	movdqa	%%xmm0,%%xmm1		\n"
+	    "	pslldq	$1,%%xmm1		\n"
+	    "	mov	$0x00020002,%%eax	\n"	// Set up XMM2 with 8 words of 0x0002 (for rounding when averaging)
+	    "	movd	%%eax,%%xmm2		\n"
+	    "	movdqa	%%xmm2,%%xmm3		\n"
+	    "	pslldq	$4,%%xmm3		\n"
+	    "	por	%%xmm3,%%xmm2		\n"
+	    "	movdqa	%%xmm2,%%xmm3		\n"
+	    "	pslldq	$8,%%xmm3		\n"
+	    "	por	%%xmm3,%%xmm2		\n"
+	    "0:	xor	%%eax,%%eax		\n"
+	    "1:	movdqu	(%%esi,%%eax,2),%%xmm4	\n"	// Read 32 pixels from each of 2 lines
+	    "	movdqu	16(%%esi,%%eax,2),%%xmm5\n"
+	    "	movdqu	(%%ebp,%%eax,2),%%xmm6	\n"
+	    "	movdqu	16(%%ebp,%%eax,2),%%xmm7\n"
+	    "	movdqa	%%xmm4,%%xmm3		\n"	// Add odd and even pixels together
+	    "	pand	%%xmm1,%%xmm3		\n"
+	    "	pand	%%xmm0,%%xmm4		\n"
+	    "	psrldq	$1,%%xmm3		\n"
+	    "	paddw	%%xmm3,%%xmm4		\n"
+	    "	movdqa	%%xmm5,%%xmm3		\n"
+	    "	pand	%%xmm1,%%xmm3		\n"
+	    "	pand	%%xmm0,%%xmm5		\n"
+	    "	psrldq	$1,%%xmm3		\n"
+	    "	paddw	%%xmm3,%%xmm5		\n"
+	    "	movdqa	%%xmm6,%%xmm3		\n"
+	    "	pand	%%xmm1,%%xmm3		\n"
+	    "	pand	%%xmm0,%%xmm6		\n"
+	    "	psrldq	$1,%%xmm3		\n"
+	    "	paddw	%%xmm3,%%xmm6		\n"
+	    "	movdqa	%%xmm7,%%xmm3		\n"
+	    "	pand	%%xmm1,%%xmm3		\n"
+	    "	pand	%%xmm0,%%xmm7		\n"
+	    "	psrldq	$1,%%xmm3		\n"
+	    "	paddw	%%xmm3,%%xmm7		\n"
+	    "	paddw	%%xmm6,%%xmm4		\n"	// Add top and bottom pixels together
+	    "	paddw	%%xmm7,%%xmm5		\n"
+	    "	paddw	%%xmm2,%%xmm4		\n"	// Add 2 to each pixel sum for rounding
+	    "	paddw	%%xmm2,%%xmm5		\n"
+	    "	psrlw	$2,%%xmm4		\n"	// Divide sums by 4
+	    "	psrlw	$2,%%xmm5		\n"
+	    "	packuswb %%xmm5,%%xmm4		\n"	// Pack into bytes
+	    "	movdqu	%%xmm4,(%%edi,%%eax)	\n"	// And store 16 destination pixels
+	    "	add	$16,%%eax		\n"
+	    "	cmp	%%ecx,%%eax		\n"
+	    "	jb	1b			\n"
+	    "	add	%%ebx,%%esi		\n"	// Update pointers
+	    "	add	%%ebx,%%ebp		\n"
+	    "	add	%%ecx,%%edi		\n"
+	    "	dec	%%edx			\n"
+	    "	jnz	0b			\n"
+	    "	emms				\n"
+	    "	sfence				\n"
+	    "	pop	%%edx			\n"
+	    "	pop	%%ecx			\n"
+	    "	pop	%%ebp			\n"
+	    "	pop	%%ebx"
+	    : // no outputs
+	    : "c" (enc->width/2), "d" (enc->height/2), "S" (final_picture->data[x]), "D" (final_picture->linesize[x])
+	    : "eax");
+#else
+	src = dest = final_picture->data[0];
+	for (y = 0; y < enc->height; y++) {
+	    for (x = 0; x < enc->width; x++)
+		dest[x] = src[x*2];
+	    src += final_picture->linesize[0]*2;
+	    dest += enc->width;
+	}
+	src = dest = final_picture->data[1];
+	for (y = 0; y < enc->height/2; y++) {
+	    for (x = 0; x < enc->width/2; x++)
+		dest[x] = (src[x*2] + src[x*2+1] + src[x*2+final_picture->linesize[1]] + src[x*2+final_picture->linesize[1]+1] + 2) / 4;
+	    src += final_picture->linesize[1]*2;
+	    dest += enc->width/2;
+	}
+	src = dest = final_picture->data[2];
+	for (y = 0; y < enc->height/2; y++) {
+	    for (x = 0; x < enc->width/2; x++)
+		dest[x] = (src[x*2] + src[x*2+1] + src[x*2+final_picture->linesize[2]] + src[x*2+final_picture->linesize[2]+1] + 2) / 4;
+	    src += final_picture->linesize[2]*2;
+	    dest += enc->width/2;
+	}
+#endif
+	final_picture->linesize[0] = enc->width;
+	final_picture->linesize[1] = enc->width/2;
+	final_picture->linesize[2] = enc->width/2;
+    }
     /* duplicates frame if needed */
     for(i=0;i<nb_frames;i++) {
         AVPacket pkt;
@@ -1698,8 +1844,11 @@
                 ost->encoding_needed = 1;
                 break;
             case CODEC_TYPE_VIDEO:
-                if (codec->width == icodec->width &&
-                    codec->height == icodec->height &&
+                if (((codec->width == icodec->width &&
+                      codec->height == icodec->height) ||
+                     (codec->width*2 == icodec->width &&
+                      codec->height*2 == icodec->height &&
+                      codec->width%16 == 0)) &&
                     frame_topBand == 0 &&
                     frame_bottomBand == 0 &&
                     frame_leftBand == 0 &&
@@ -1712,6 +1861,7 @@
                     ost->video_resample = 0;
                     ost->video_crop = 0;
                     ost->video_pad = 0;
+                    ost->half_size = (codec->width*2 == icodec->width);
                 } else if ((codec->width == icodec->width -
                                 (frame_leftBand + frame_rightBand)) &&
                         (codec->height == icodec->height -
@@ -1719,6 +1869,18 @@
                 {
                     ost->video_resample = 0;
                     ost->video_crop = 1;
+                    ost->half_size = 0;
+                    ost->topBand = frame_topBand;
+                    ost->leftBand = frame_leftBand;
+                } else if ((codec->width*2 == icodec->width -
+                                (frame_leftBand + frame_rightBand)) &&
+                        (codec->height*2 == icodec->height -
+                                (frame_topBand  + frame_bottomBand)) &&
+                        (codec->width%16 == 0))
+                {
+                    ost->video_resample = 0;
+                    ost->video_crop = 1;
+                    ost->half_size = 1;
                     ost->topBand = frame_topBand;
                     ost->leftBand = frame_leftBand;
                 } else if ((codec->width == icodec->width +
@@ -1728,6 +1890,24 @@
                     ost->video_resample = 0;
                     ost->video_crop = 0;
                     ost->video_pad = 1;
+                    ost->half_size = 0;
+                    ost->padtop = frame_padtop;
+                    ost->padleft = frame_padleft;
+                    ost->padbottom = frame_padbottom;
+                    ost->padright = frame_padright;
+                    avcodec_get_frame_defaults(&ost->pict_tmp);
+                    if( avpicture_alloc( (AVPicture*)&ost->pict_tmp, PIX_FMT_YUV420P,
+                                codec->width, codec->height ) )
+                        goto fail;
+                } else if ((codec->width*2 == icodec->width + 
+                                (frame_padleft + frame_padright)) &&
+                        (codec->height*2 == icodec->height +
+                                (frame_padtop + frame_padbottom)) &&
+                        (codec->width%16 == 0)) {
+                    ost->video_resample = 0;
+                    ost->video_crop = 0;
+                    ost->video_pad = 1;
+                    ost->half_size = 1;
                     ost->padtop = frame_padtop;
                     ost->padleft = frame_padleft;
                     ost->padbottom = frame_padbottom;
@@ -1739,6 +1919,7 @@
                 } else {
                     ost->video_resample = 1;
                     ost->video_crop = 0; // cropping is handled as part of resample
+                    ost->half_size = 0;
                     avcodec_get_frame_defaults(&ost->pict_tmp);
                     if( avpicture_alloc( (AVPicture*)&ost->pict_tmp, PIX_FMT_YUV420P,
                                          codec->width, codec->height ) )
######## end older half-size optimization patch
EOT

/pkg/ffmpeg-cvs/
/usr/bin/ffmpeg
/usr/bin/ffplay
/usr/bin/ffserver
/usr/include/ffmpeg
/usr/include/postproc
/usr/lib/libavcodec.*
/usr/lib/libavformat.*
/usr/lib/libavutil.*
/usr/lib/libpostproc.*
/usr/lib/pkgconfig/libavcodec.pc
/usr/lib/pkgconfig/libavformat.pc
/usr/lib/pkgconfig/libavutil.pc
/usr/lib/pkgconfig/libpostproc.pc
