changeset 2866:4f6190ab52e7

Added a temporary fix to the DXR3 win32 codec playback, win32 codecs might prove to play back an unscaled image!
author mswitch
date Tue, 13 Nov 2001 16:01:56 +0000
parents 72c750bbc249
children a9a63f7e9ddc
files libvo/vo_dxr3.c
diffstat 1 files changed, 172 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/libvo/vo_dxr3.c	Tue Nov 13 13:17:46 2001 +0000
+++ b/libvo/vo_dxr3.c	Tue Nov 13 16:01:56 2001 +0000
@@ -7,12 +7,23 @@
  * libav - MPEG-PS multiplexer, part of ffmpeg
  * Copyright Gerard Lantau  (see http://ffmpeg.sf.net)
  *
+ *
+ *
+ *
+ *
+ *	*** NOTICE ***
+ * Further development of this device will be carried out using
+ * the new libvo2 system, meanwhile I hope someone can find where
+ * the lockup problem is located (caused by using subpics or audio
+ * (video gets blocked))
+ *
  */
 
 #include "fastmemcpy.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <linux/kernel.h>
 
 #include <stdio.h>
 #include <time.h>
@@ -24,7 +35,7 @@
 #include "video_out.h"
 #include "video_out_internal.h"
 
-#include "../opendivx/yuv2rgb.h"
+#include "../postproc/rgb2rgb.h"
 #ifdef HAVE_MMX
 #include "mmx.h"
 #endif
@@ -49,11 +60,12 @@
 static unsigned char *spubuf=NULL;
 static int outbuf_size = 0;
 static int v_width,v_height;
+static int s_width,s_height;
 static int s_pos_x,s_pos_y;
 static int d_pos_x,d_pos_y;
 static int osd_w,osd_h;
 static int img_format = 0;
-static int palette[] = { 0x0000, 0x4949, 0xb5b5, 0xffff };
+static int palette[] = { 0x000000, 0x494949, 0xb5b5b5, 0xffffff };
 
 static vo_info_t vo_info = 
 {
@@ -64,7 +76,7 @@
 };
 
 static uint32_t
-init(uint32_t s_width, uint32_t s_height, uint32_t width, uint32_t height, uint32_t fullscreen, char *title, uint32_t format)
+init(uint32_t scr_width, uint32_t scr_height, uint32_t width, uint32_t height, uint32_t fullscreen, char *title, uint32_t format)
 {
     if( dxr3_get_status() == DXR3_STATUS_CLOSED )
     {
@@ -74,9 +86,9 @@
 
     /* Subpic code isn't working yet, don't set to ON 
        unless you are really sure what you are doing */
-    dxr3_subpic_set_mode( DXR3_SPU_MODE_OFF );
+    dxr3_subpic_set_mode( DXR3_SPU_MODE_ON );
     dxr3_subpic_set_palette( (char*)palette );
-    spubuf = malloc(width*height);
+    spubuf = malloc(53220); //53220bytes is the standardized max size of a subpic
     
     if( dxr3_set_playmode( DXR3_PLAYMODE_PLAY ) !=0 ) printf( "Error setting playmode of DXR3\n" );
 
@@ -132,16 +144,19 @@
           codec_context.width=704;
           codec_context.height=576;
         }
+	s_width = codec_context.width;
+	s_height = codec_context.height;;
+
     
-        osd_w=s_width;
-        d_pos_x=(codec_context.width-(int)s_width)/2;
+        osd_w=scr_width;
+        d_pos_x=(codec_context.width-(int)scr_width)/2;
         if(d_pos_x<0){
           s_pos_x=-d_pos_x;d_pos_x=0;
           osd_w=codec_context.width;
         } else s_pos_x=0;
     
-        osd_h=s_height;
-        d_pos_y=(codec_context.height-(int)s_height)/2;
+        osd_h=scr_height;
+        d_pos_y=(codec_context.height-(int)scr_height)/2;
         if(d_pos_y<0){
           s_pos_y=-d_pos_y;d_pos_y=0;
           osd_h=codec_context.height;
@@ -155,7 +170,7 @@
             return -1;
         }
         
-        outbuf_size=10000+width*height*4;
+        outbuf_size=10000+width*height;
         outbuf = malloc(outbuf_size);
     
         size = codec_context.width*codec_context.height;
@@ -193,7 +208,7 @@
             return -1;
         }
             
-        outbuf_size=10000+width*height*4;
+        outbuf_size=10000+width*height;
         outbuf = malloc(outbuf_size);
 	
         memset(&codec_context,0,sizeof(codec_context));
@@ -204,8 +219,95 @@
         codec_context.quality=1;
 	codec_context.pix_fmt = PIX_FMT_YUV420P;
 
-/*	codec_context.width=width;
-	codec_context.height=height;*/
+        /*if(width<=352 && height<=288){
+          codec_context.width=352;
+          codec_context.height=288;
+        } else
+        if(width<=352 && height<=576){
+          codec_context.width=352;
+          codec_context.height=576;
+        } else
+        if(width<=480 && height<=576){
+          codec_context.width=480;
+          codec_context.height=576;
+        } else
+        if(width<=544 && height<=576){
+          codec_context.width=544;
+          codec_context.height=576;
+        } else {
+          codec_context.width=704;
+          codec_context.height=576;
+        }*/
+	s_width = codec_context.width = width;
+	s_height = codec_context.height = height;
+
+        osd_w=scr_width;
+        d_pos_x=(codec_context.width-(int)scr_width)/2;
+        if(d_pos_x<0){
+          s_pos_x=-d_pos_x;d_pos_x=0;
+          osd_w=codec_context.width;
+        } else s_pos_x=0;
+    
+        osd_h=scr_height;
+        d_pos_y=(codec_context.height-(int)scr_height)/2;
+        if(d_pos_y<0){
+          s_pos_y=-d_pos_y;d_pos_y=0;
+          osd_h=codec_context.height;
+        } else s_pos_y=0;
+    
+        printf("[vo] position mapping: %d;%d => %d;%d\n",s_pos_x,s_pos_y,d_pos_x,d_pos_y);
+    
+        /* open it */
+        if (avcodec_open(&codec_context, codec) < 0) {
+            fprintf(stderr, "could not open codec\n");
+            return -1;
+        }
+
+        size = 10000+codec_context.width*codec_context.height;
+        picture_buf = malloc((size * 3)/2);
+        
+        picture.data[0] = picture_buf;
+        picture.data[1] = picture.data[0] + size;
+        picture.data[2] = picture.data[1] + size / 4;
+	picture.linesize[0] = codec_context.width;
+        picture.linesize[1] = codec_context.width / 2;
+        picture.linesize[2] = codec_context.width / 2;
+	return 0;
+#endif
+	return -1;
+    }
+    else if(format==IMGFMT_YUY2)
+    {
+#ifdef USE_LIBAVCODEC
+	int size = 0;
+	printf("Format: YUY2\n");
+
+        if(!avcodec_inited)
+	{
+	  avcodec_init();
+          avcodec_register_all();
+          avcodec_inited=1;
+        }
+    
+        /* find the mpeg1 video encoder */
+        codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
+        if (!codec) 
+	{
+            fprintf(stderr, "mpeg1 codec not found\n");
+            return -1;
+        }
+            
+        outbuf_size=10000+width*height;
+        outbuf = malloc(outbuf_size);
+	
+        memset(&codec_context,0,sizeof(codec_context));
+        codec_context.bit_rate=100000;
+        codec_context.frame_rate=25*FRAME_RATE_BASE;
+        codec_context.gop_size=0;
+        codec_context.flags=CODEC_FLAG_QSCALE;
+        codec_context.quality=1;
+	codec_context.pix_fmt = PIX_FMT_YUV420P;
+
         if(width<=352 && height<=288){
           codec_context.width=352;
           codec_context.height=288;
@@ -225,16 +327,21 @@
           codec_context.width=704;
           codec_context.height=576;
         }
-
-        osd_w=s_width;
-        d_pos_x=(codec_context.width-(int)s_width)/2;
+	s_width = codec_context.width;
+	s_height = codec_context.height;;
+	/* FOR DEBUGGING ONLY!! */
+	codec_context.width = width;
+	codec_context.height = height;
+	
+        osd_w=scr_width;
+        d_pos_x=(codec_context.width-(int)scr_width)/2;
         if(d_pos_x<0){
           s_pos_x=-d_pos_x;d_pos_x=0;
           osd_w=codec_context.width;
         } else s_pos_x=0;
     
-        osd_h=s_height;
-        d_pos_y=(codec_context.height-(int)s_height)/2;
+        osd_h=scr_height;
+        d_pos_y=(codec_context.height-(int)scr_height)/2;
         if(d_pos_y<0){
           s_pos_y=-d_pos_y;d_pos_y=0;
           osd_h=codec_context.height;
@@ -248,13 +355,13 @@
             return -1;
         }
 
-        size = codec_context.width*codec_context.height;
+        size = 10000+codec_context.width*codec_context.height;
         picture_buf = malloc((size * 3)/2);
         
         picture.data[0] = picture_buf;
         picture.data[1] = picture.data[0] + size;
         picture.data[2] = picture.data[1] + size / 4;
-        picture.linesize[0] = codec_context.width;
+	picture.linesize[0] = codec_context.width;
         picture.linesize[1] = codec_context.width / 2;
         picture.linesize[2] = codec_context.width / 2;
 	return 0;
@@ -271,23 +378,41 @@
     return -1;
 }
 
-static const vo_info_t*
-get_info(void)
+static const vo_info_t* get_info(void)
 {
     return &vo_info;
 }
 
-static void draw_alpha(int x, int y, int w, int h, unsigned char* src, unsigned char *srca, int srcstride)
+static void draw_alpha(int x0, int y0, int w, int h, unsigned char* src, unsigned char *srca, int srcstride)
 {
-    int i,skip=0,index=0;
+    int x,y,index=0;
+    int n_rles=0, prev_nibbled=0, nibbled=0;
+    char prevcolor=0;
     unsigned char *dst = spubuf;
-    for( i = (y*w)+x; i < w*h; i++ )
+    unsigned short *subpic_size, *cs_table;
+    subpic_size = dst+=2;
+    cs_table = dst+=2;
+    prevcolor = src[0];
+    for( y = 0; y <= (h-1); y+=2 )
     {
-	    if(srca[i]) {*dst=skip;skip=0;dst++;*dst=3;dst++;index+=2;}
-	    else skip++;
+	for( x = 0; x < w; x++ )
+	{
+	    if( prevcolor == src[x+(y*w)] ) index++;
+	    else
+	    {
+		if( prevcolor < 64 )
+		    prevcolor = 0x00;
+		else if( prevcolor < 128 )
+		    prevcolor = 0x01;
+		else if( prevcolor < 192 )
+		    prevcolor = 0x02;
+		else
+		    prevcolor = 0x03;
+	    }
+	}
     }
 
-    dxr3_subpic_write(spubuf,index);
+    dxr3_subpic_write(spubuf,(dst-spubuf));
 }
 
 static void draw_osd(void)
@@ -320,20 +445,21 @@
 	int r, g, b, R, G, B, h = v_height, w = v_width;
 	unsigned char *s, *Y, *U, *V;
 
+	printf( "dS: %dx%d dD: %dx%d S: %dx%d V: %dx%d\n",s_pos_x,s_pos_y,d_pos_x,d_pos_y,s_width,s_height,v_width,v_height);
         if(d_pos_x+w>picture.linesize[0]) w=picture.linesize[0]-d_pos_x;
         if(d_pos_y+h>codec_context.height) h=codec_context.height-d_pos_y;
 	
-	Y = picture.data[0]+d_pos_x+d_pos_y*picture.linesize[0];
-	U = picture.data[1]+(d_pos_x/2)+(d_pos_y/2)*picture.linesize[1];
-	V = picture.data[2]+(d_pos_x/2)+(d_pos_y/2)*picture.linesize[2];
-	
+	Y = picture.data[0]+d_pos_x+(d_pos_y*picture.linesize[0]);
+	U = picture.data[1]+(d_pos_x/2)+((d_pos_y/2)*picture.linesize[1]);
+	V = picture.data[2]+(d_pos_x/2)+((d_pos_y/2)*picture.linesize[2]);
+
 	//BGR24->YUV420P from ffmpeg, see ffmpeg.sourceforge.net for terms of license
 #define SCALEBITS	8
 #define ONE_HALF	(1 << (SCALEBITS - 1))
 #define FIX(x)		((int) ((x) * (1L<<SCALEBITS) + 0.5))
-	wrap = w;
+	wrap = s_width;
 	wrap3 = w * 3;
-        s = src[0];
+        s = src[0]+s_pos_x+(s_pos_y*wrap3);
 	for( y = 0; y < h; y+=2 )
 	{
 	    for( x = 0; x < w; x+=2 )
@@ -375,7 +501,7 @@
 		U++;
 		V++;
 		s -= (wrap3-6);
-		Y -= (wrap-2);
+		Y -= (wrap-(3/2));
 	    }
 	    s += wrap3;
 	    Y += wrap;
@@ -387,7 +513,15 @@
         tmp_size = out_size = avcodec_encode_video(&codec_context, outbuf, outbuf_size, &picture);
 	while( out_size )
 		out_size -= dxr3_video_write( &outbuf[tmp_size-out_size], out_size );
-	
+	return 0;
+    }
+    else if( img_format == IMGFMT_YUY2 )
+    {
+	int tmp_size, out_size;	
+        tmp_size = out_size = avcodec_encode_video(&codec_context, outbuf, outbuf_size, &picture);
+        while( out_size )
+		out_size -= dxr3_video_write( &outbuf[tmp_size-out_size], out_size );
+
 	return 0;
     }
 #endif
@@ -479,9 +613,11 @@
     if(format==IMGFMT_MPEGPES) return 0x2|0x4;
 #ifdef USE_LIBAVCODEC
     if(format==IMGFMT_YV12) return 0x1|0x4;
+    if(format==IMGFMT_YUY2) return 0x1|0x4;
     if(format==IMGFMT_BGR24) return 0x1|0x4;
 #else
     if(format==IMGFMT_YV12) {printf("You need to compile with libavcodec or ffmpeg.so to play this file!\n" ); return 0;}
+    if(format==IMGFMT_YUY2) {printf("You need to compile with libavcodec or ffmpeg.so to play this file!\n" ); return 0;}
     if(format==IMGFMT_BGR24) {printf("You need to compile with libavcodec or ffmpeg.so to play this file!\n" ); return 0;}
 #endif    
     return 0;