changeset 4427:6310422b9557

new video format: yuvrgb. patch by Fredrik Kuivinen <freku045@student.liu.se>
author arpi
date Thu, 31 Jan 2002 00:38:53 +0000
parents 1ceadec3ea67
children 3e1378354c2e
files cfg-mencoder.h mencoder.c
diffstat 2 files changed, 111 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/cfg-mencoder.h	Thu Jan 31 00:37:59 2002 +0000
+++ b/cfg-mencoder.h	Thu Jan 31 00:38:53 2002 +0000
@@ -73,7 +73,8 @@
 	{"raw", &out_video_codec, CONF_TYPE_FLAG, 0, 0, VCODEC_RAW, NULL},
 	{"lavc", &out_video_codec, CONF_TYPE_FLAG, 0, 0, VCODEC_LIBAVCODEC, NULL},
 	{"null", &out_video_codec, CONF_TYPE_FLAG, 0, 0, VCODEC_NULL, NULL},
-	{"help", "\nAvailable codecs:\n   copy\n   frameno\n   divx4\n   raw\n   lavc\n    null\n\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
+    {"rawrgb", &out_video_codec, CONF_TYPE_FLAG, 0, 0, VCODEC_RAWRGB, NULL},
+	{"help", "\nAvailable codecs:\n   copy\n   frameno\n   divx4\n   raw\n   lavc\n   rawrgb\n   null\n\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
 	{NULL, NULL, 0, 0, 0, 0, NULL}
 };
 
--- a/mencoder.c	Thu Jan 31 00:37:59 2002 +0000
+++ b/mencoder.c	Thu Jan 31 00:38:53 2002 +0000
@@ -4,6 +4,7 @@
 #define VCODEC_RAW 3
 #define VCODEC_LIBAVCODEC 4
 #define VCODEC_NULL 5
+#define VCODEC_RAWRGB 6
 
 #define ACODEC_COPY 0
 #define ACODEC_PCM 1
@@ -46,6 +47,8 @@
 #include "dec_audio.h"
 #include "dec_video.h"
 
+#include "postproc/rgb2rgb.h"
+
 #ifdef HAVE_DIVX4ENCORE
 #include <encore2.h>
 #include "divx4_vbr.h"
@@ -192,6 +195,7 @@
 }
 
 static int parse_end_at(struct config *conf, const char* param);
+static uint8_t* flip_upside_down(uint8_t* dst, const uint8_t* src, int width, int height);
 
 #include "get_path.c"
 
@@ -520,12 +524,20 @@
 for(i=0;i<CODECS_MAX_OUTFMT;i++){
     out_fmt=sh_video->codec->outfmt[i];
     if(out_fmt==0xFFFFFFFF) continue;
-    if(IMGFMT_IS_RGB(out_fmt) || IMGFMT_IS_BGR(out_fmt)) break;
+
+    if(IMGFMT_IS_RGB(out_fmt)) break;
     if(out_fmt==IMGFMT_YV12) break;
+    
+    if(out_video_codec == VCODEC_RAWRGB) {
+        if(IMGFMT_IS_BGR(out_fmt) && IMGFMT_BGR_DEPTH(out_fmt) == 32) break;
+    }
+    else {
+        if(IMGFMT_IS_BGR(out_fmt)) break;   
     if(out_fmt==IMGFMT_I420) break;
     if(out_fmt==IMGFMT_IYUV) break;
     if(out_fmt==IMGFMT_YUY2) break;
     if(out_fmt==IMGFMT_UYVY) break;
+    }
 }
 if(i>=CODECS_MAX_OUTFMT){
     mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_VOincompCodec);
@@ -674,6 +686,31 @@
 	mux_v->bih->biWidth, mux_v->bih->biHeight,
 	mux_v->bih->biBitCount, mux_v->bih->biCompression);
     break;
+case VCODEC_RAWRGB:
+	mux_v->bih=malloc(sizeof(BITMAPINFOHEADER));
+	mux_v->bih->biSize=sizeof(BITMAPINFOHEADER);
+	mux_v->bih->biWidth=sh_video->disp_w;
+	mux_v->bih->biHeight=sh_video->disp_h;
+	mux_v->bih->biCompression=0;
+	mux_v->bih->biPlanes=1;
+	
+	if(IMGFMT_IS_RGB(out_fmt))
+        mux_v->bih->biBitCount = IMGFMT_RGB_DEPTH(out_fmt);    
+	else if(IMGFMT_IS_BGR(out_fmt))
+        mux_v->bih->biBitCount = IMGFMT_BGR_DEPTH(out_fmt);
+	else {
+        mux_v->bih->biBitCount = 24;
+        yuv2rgb_init(24, MODE_BGR);
+	}
+    
+    if(mux_v->bih->biBitCount == 32)
+        mux_v->bih->biBitCount = 24;
+
+	mux_v->bih->biSizeImage=mux_v->bih->biWidth*mux_v->bih->biHeight*(mux_v->bih->biBitCount/8);
+    printf("videocodec: rawrgb (%dx%d %dbpp fourcc=%x)\n",
+	mux_v->bih->biWidth, mux_v->bih->biHeight,
+	mux_v->bih->biBitCount, mux_v->bih->biCompression);
+    break;
 case VCODEC_FRAMENO:
     mux_v->bih=malloc(sizeof(BITMAPINFOHEADER));
     mux_v->bih->biSize=sizeof(BITMAPINFOHEADER);
@@ -862,6 +899,7 @@
 switch(mux_v->codec){
 case VCODEC_COPY:
 case VCODEC_RAW:
+case VCODEC_RAWRGB:        
 case VCODEC_NULL:
     break;
 case VCODEC_FRAMENO:
@@ -1277,6 +1315,57 @@
     mux_v->buffer=start;
     if(skip_flag<=0) aviwrite_write_chunk(muxer,mux_v,muxer_f,in_size,(sh_video->ds->flags&1)?0x10:0);
     break;
+case VCODEC_RAWRGB:
+ {
+     static uint8_t* raw_rgb_buffer = NULL;
+     static uint8_t* raw_rgb_buffer2 = NULL;
+        
+     if(!raw_rgb_buffer) {
+         raw_rgb_buffer = malloc(vo_w*vo_h*4);
+         raw_rgb_buffer2 = malloc(vo_w*vo_h*4);
+     }
+	    
+     blit_frame=decode_video(&video_out,sh_video,start,in_size,0);
+     if(skip_flag>0) break;
+     if(!blit_frame){
+         // empty.
+         aviwrite_write_chunk(muxer,mux_v,muxer_f,0,0);
+         break;
+     }
+
+     /* Uncompressed avi files store rgb data with the top most row last so we
+      * have to flip the frames. */
+     if(IMGFMT_IS_BGR(out_fmt)) {
+         if(IMGFMT_BGR_DEPTH(out_fmt) == 32) {
+             rgb32to24(vo_image_ptr, raw_rgb_buffer, vo_w*vo_h*4);
+             mux_v->buffer = flip_upside_down(raw_rgb_buffer, raw_rgb_buffer,
+                                              vo_w*3, vo_h);
+         }
+         else
+             mux_v->buffer = flip_upside_down(raw_rgb_buffer, vo_image_ptr,
+                                              vo_w*3, vo_h);
+     }
+     else if(IMGFMT_IS_RGB(out_fmt)) {
+         if(IMGFMT_RGB_DEPTH(out_fmt) == 32) {
+             rgb32tobgr32(vo_image_ptr, raw_rgb_buffer2, vo_w*vo_h*4);
+             rgb32to24(raw_rgb_buffer2, raw_rgb_buffer, vo_w*vo_h*4);
+             mux_v->buffer = flip_upside_down(raw_rgb_buffer, raw_rgb_buffer,
+                                              vo_w*3, vo_h);
+         }
+         else
+             mux_v->buffer = flip_upside_down(raw_rgb_buffer, vo_image_ptr,
+                                              vo_w*3, vo_h);
+     }
+     else {
+         yuv2rgb(raw_rgb_buffer, vo_image_ptr, vo_image_ptr + vo_w*vo_h*5/4,
+                 vo_image_ptr + vo_w*vo_h, vo_w, vo_h, vo_w*24/8, vo_w, vo_w/2);
+         mux_v->buffer = flip_upside_down(raw_rgb_buffer, raw_rgb_buffer,
+                                          vo_w*3, vo_h);
+     }
+
+     aviwrite_write_chunk(muxer,mux_v,muxer_f, vo_w*vo_h*3, 0x10);
+ }
+ break;
 case VCODEC_RAW:
     blit_frame=decode_video(&video_out,sh_video,start,in_size,0);
     if(skip_flag>0) break;
@@ -1440,7 +1529,7 @@
 	    (p>0.001) ? (int)(ftell(muxer_f)/p/1024/1024) : 0,
 	    v_pts_corr,
 	    (mux_v->timer>1) ? (int)(mux_v->size/mux_v->timer/125) : 0,
-	    (mux_a->timer>1) ? (int)(mux_a->size/mux_a->timer/125) : 0
+	    (mux_a && mux_a->timer>1) ? (int)(mux_a->size/mux_a->timer/125) : 0
 	);
 #endif
     }
@@ -1541,3 +1630,21 @@
 
     return 1;
 }
+
+/* Flip the image in src and store the result in dst. src and dst may overlap.
+   width is the size of each line in bytes. */
+static uint8_t* flip_upside_down(uint8_t* dst, const uint8_t* src, int width,
+                                 int height)
+{
+    uint8_t* tmp = malloc(width);
+    int i;
+
+    for(i = 0; i < height/2; i++) {
+        memcpy(tmp, &src[i*width], width);
+        memcpy(&dst[i * width], &src[(height - i) * width], width);
+        memcpy(&dst[(height - i) * width], tmp, width);
+    }
+
+    free(tmp);
+    return dst;
+}