Mercurial > mplayer.hg
view libvo/vo_odivx.c @ 5229:d4fbe9eb9397
-dr
author | gabucino |
---|---|
date | Wed, 20 Mar 2002 20:24:47 +0000 |
parents | 32e1f5042f65 |
children | eca7dbad0166 |
line wrap: on
line source
/* * OpenDivX AVI file writer */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.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" #include "fastmemcpy.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: { uint8_t *dY=image; uint8_t *dU=image+image_width*image_height; uint8_t *dV=dU+image_width*image_height/4; uint8_t *s=src[0]; int y; for(y=0;y<image_height;y+=2){ uint8_t *e=s+image_width*2; while(s<e){ *dY++=s[0]; *dU++=s[1]; *dY++=s[2]; *dV++=s[3]; s+=4; } e=s+image_width*2; while(s<e){ *dY++=s[0]; *dY++=s[2]; s+=4; } } // case IMGFMT_BGR|24: // memcpy(d,src[0],image_width*image_height*2); 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 draw_osd(void) { } 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.image=image; enc_frame.bitstream=buffer; enc_frame.length=0; encore(0x123,0,&enc_frame,&enc_result); printf("coded length: %ld \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 config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t fullscreen, char *title, uint32_t format,const vo_tune_info_t *info) { 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_YUY2: // case IMGFMT_BGR|24: // enc_param.flip=0; // 0=RGB 1=flippedRGB 2=planarYUV format // frame_size=width*height*2; frame_size=width*height+width*height/2; 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) { } static void check_events(void) { } static uint32_t preinit(const char *arg) { if(arg) { printf("vo_odivx: Unknown subdevice: %s\n",arg); return ENOSYS; } return 0; } static uint32_t control(uint32_t request, void *data, ...) { switch (request) { case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); } return VO_NOTIMPL; }