diff libvo/vo_odivx.c @ 1:3b5f5d1c5041

Initial revision
author arpi_esp
date Sat, 24 Feb 2001 20:28:24 +0000
parents
children 1fc618eba830
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvo/vo_odivx.c	Sat Feb 24 20:28:24 2001 +0000
@@ -0,0 +1,234 @@
+/* 
+ *  OpenDivX AVI file writer
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+#include "video_out.h"
+#include "video_out_internal.h"
+
+LIBVO_EXTERN(odivx)
+
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#include "../encore/encore.h"
+
+static vo_info_t vo_info = 
+{
+	"OpenDivX AVI File writer",
+	"odivx",
+	"Arpad Gereoffy <arpi@esp-team.scene.hu>",
+	""
+};
+
+static uint8_t *image=NULL;
+static int image_width=0;
+static int image_height=0;
+static unsigned int image_format=0;
+static char *buffer=NULL;
+static int frameno=0;
+
+extern char* encode_name;
+extern char* encode_index_name;
+
+//static uint32_t draw_slice(uint8_t *src[], uint32_t slice_num)
+static uint32_t draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y)
+{
+    uint8_t *s;
+    uint8_t *d;
+    int i;
+    int dstride=image_width;
+
+    // copy Y
+    d=image+dstride*y+x;
+    s=src[0];
+    for(i=0;i<h;i++){
+        memcpy(d,s,w);
+        s+=stride[0];
+        d+=dstride;
+    }
+    
+    w/=2;h/=2;x/=2;y/=2; dstride/=2;
+    
+    // copy U
+    d=image+image_width*image_height + dstride*y+x;
+    s=src[1];
+    for(i=0;i<h;i++){
+        memcpy(d,s,w);
+        s+=stride[1];
+        d+=dstride;
+    }
+
+    // copy V
+    d=image+image_width*image_height +image_width*image_height/4 + dstride*y+x;
+    s=src[2];
+    for(i=0;i<h;i++){
+        memcpy(d,s,w);
+        s+=stride[2];
+        d+=dstride;
+    }
+    
+    return 0;
+}
+
+static uint32_t
+draw_frame(uint8_t *src[])
+{
+  uint8_t *d=image;
+
+  switch(image_format){
+  case IMGFMT_YV12:
+    // copy Y
+    memcpy(d,src[0],image_width*image_height);
+    // copy U
+    d+=image_width*image_height;
+    memcpy(d,src[1],image_width*image_height/4);
+    // copy V
+    d+=image_width*image_height/4;
+    memcpy(d,src[2],image_width*image_height/4);
+    break;
+//    case IMGFMT_YUY2:
+  case IMGFMT_BGR|24:
+    memcpy(d,src[0],image_width*image_height*3);
+    break;
+  }
+
+  return 0;
+}
+
+typedef unsigned int DWORD;
+
+typedef struct
+{
+    DWORD               ckid;
+    DWORD               dwFlags;
+    DWORD               dwChunkOffset;          // Position of chunk
+    DWORD               dwChunkLength;          // Length of chunk
+} AVIINDEXENTRY;
+
+static void
+flip_page(void)
+{
+
+// we are rady to encode this frame
+ENC_FRAME enc_frame;
+ENC_RESULT enc_result;
+
+if(++frameno<10) return;
+
+enc_frame.bmp=image;
+enc_frame.bitstream=buffer;
+enc_frame.length=0;
+encore(0x123,0,&enc_frame,&enc_result);
+
+printf("coded length: %d  \n",enc_frame.length);
+
+if(encode_name){
+  AVIINDEXENTRY i;
+  FILE *file;
+  i.ckid=('c'<<24)|('d'<<16)|('0'<<8)|'0'; // "00dc"
+  i.dwFlags=enc_result.isKeyFrame?0x10:0;
+  i.dwChunkLength=enc_frame.length;
+  // Write AVI chunk:
+  if((file=fopen(encode_name,"ab"))){
+    unsigned char zerobyte=0;
+    i.dwChunkOffset=ftell(file);
+    fwrite(&i.ckid,4,1,file);
+    fwrite(&enc_frame.length,4,1,file);
+    fwrite(buffer,enc_frame.length,1,file);
+    if(enc_frame.length&1) fwrite(&zerobyte,1,1,file); // padding
+    fclose(file);
+  }
+  // Write AVI index:
+  if(encode_index_name && (file=fopen(encode_index_name,"ab"))){
+    fwrite(&i,sizeof(i),1,file);
+    fclose(file);
+  }
+}
+
+
+}
+
+static uint32_t
+query_format(uint32_t format)
+{
+    switch(format){
+    case IMGFMT_YV12:
+//    case IMGFMT_YUY2:
+    case IMGFMT_BGR|24:
+        return 1;
+    }
+    return 0;
+}
+
+extern int encode_bitrate;
+
+static uint32_t
+init(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t fullscreen, char *title, uint32_t format)
+{
+	uint32_t frame_size;
+        ENC_PARAM enc_param;
+
+//	file = fopen("encoded.odvx","wb");
+//        if(!file) return -1;
+        
+    switch(format){
+    case IMGFMT_YV12:
+        frame_size=width*height+width*height/2;
+        enc_param.flip=2; // 0=RGB  1=flippedRGB  2=planarYUV format
+        break;
+    case IMGFMT_BGR|24:
+        enc_param.flip=0; // 0=RGB  1=flippedRGB  2=planarYUV format
+        frame_size=width*height*3;
+        break;
+    default: return -1; // invalid format
+    }
+
+    enc_param.x_dim=width;
+    enc_param.y_dim=height;
+
+    image_width=width;
+    image_height=height;
+    image_format=format;
+    image=malloc(frame_size);
+
+	//clear the buffer
+	memset(image,0x80,frame_size);
+
+    // buffer for encoded video data:
+    buffer=malloc(0x100000);
+    if(!buffer) return -1;
+
+    // encoding parameters:
+    enc_param.framerate=25.0;
+    enc_param.bitrate=encode_bitrate?encode_bitrate:780000;
+    enc_param.rc_period=300;
+    enc_param.max_quantizer=15;
+    enc_param.min_quantizer=1;
+    enc_param.search_range=128;
+
+    // init codec:
+    encore(0x123,ENC_OPT_INIT,&enc_param,NULL);
+
+  return 0;
+}
+
+static const vo_info_t*
+get_info(void)
+{
+	return &vo_info;
+}
+
+static void
+uninit(void)
+{
+}
+
+
+