comparison libvo/vo_odivx.c @ 1:3b5f5d1c5041

Initial revision
author arpi_esp
date Sat, 24 Feb 2001 20:28:24 +0000
parents
children 1fc618eba830
comparison
equal deleted inserted replaced
0:c1bb2c071d63 1:3b5f5d1c5041
1 /*
2 * OpenDivX AVI file writer
3 */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8
9 #include "config.h"
10 #include "video_out.h"
11 #include "video_out_internal.h"
12
13 LIBVO_EXTERN(odivx)
14
15 #include <sys/ioctl.h>
16 #include <unistd.h>
17 #include <fcntl.h>
18 #include <sys/mman.h>
19
20 #include "../encore/encore.h"
21
22 static vo_info_t vo_info =
23 {
24 "OpenDivX AVI File writer",
25 "odivx",
26 "Arpad Gereoffy <arpi@esp-team.scene.hu>",
27 ""
28 };
29
30 static uint8_t *image=NULL;
31 static int image_width=0;
32 static int image_height=0;
33 static unsigned int image_format=0;
34 static char *buffer=NULL;
35 static int frameno=0;
36
37 extern char* encode_name;
38 extern char* encode_index_name;
39
40 //static uint32_t draw_slice(uint8_t *src[], uint32_t slice_num)
41 static uint32_t draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y)
42 {
43 uint8_t *s;
44 uint8_t *d;
45 int i;
46 int dstride=image_width;
47
48 // copy Y
49 d=image+dstride*y+x;
50 s=src[0];
51 for(i=0;i<h;i++){
52 memcpy(d,s,w);
53 s+=stride[0];
54 d+=dstride;
55 }
56
57 w/=2;h/=2;x/=2;y/=2; dstride/=2;
58
59 // copy U
60 d=image+image_width*image_height + dstride*y+x;
61 s=src[1];
62 for(i=0;i<h;i++){
63 memcpy(d,s,w);
64 s+=stride[1];
65 d+=dstride;
66 }
67
68 // copy V
69 d=image+image_width*image_height +image_width*image_height/4 + dstride*y+x;
70 s=src[2];
71 for(i=0;i<h;i++){
72 memcpy(d,s,w);
73 s+=stride[2];
74 d+=dstride;
75 }
76
77 return 0;
78 }
79
80 static uint32_t
81 draw_frame(uint8_t *src[])
82 {
83 uint8_t *d=image;
84
85 switch(image_format){
86 case IMGFMT_YV12:
87 // copy Y
88 memcpy(d,src[0],image_width*image_height);
89 // copy U
90 d+=image_width*image_height;
91 memcpy(d,src[1],image_width*image_height/4);
92 // copy V
93 d+=image_width*image_height/4;
94 memcpy(d,src[2],image_width*image_height/4);
95 break;
96 // case IMGFMT_YUY2:
97 case IMGFMT_BGR|24:
98 memcpy(d,src[0],image_width*image_height*3);
99 break;
100 }
101
102 return 0;
103 }
104
105 typedef unsigned int DWORD;
106
107 typedef struct
108 {
109 DWORD ckid;
110 DWORD dwFlags;
111 DWORD dwChunkOffset; // Position of chunk
112 DWORD dwChunkLength; // Length of chunk
113 } AVIINDEXENTRY;
114
115 static void
116 flip_page(void)
117 {
118
119 // we are rady to encode this frame
120 ENC_FRAME enc_frame;
121 ENC_RESULT enc_result;
122
123 if(++frameno<10) return;
124
125 enc_frame.bmp=image;
126 enc_frame.bitstream=buffer;
127 enc_frame.length=0;
128 encore(0x123,0,&enc_frame,&enc_result);
129
130 printf("coded length: %d \n",enc_frame.length);
131
132 if(encode_name){
133 AVIINDEXENTRY i;
134 FILE *file;
135 i.ckid=('c'<<24)|('d'<<16)|('0'<<8)|'0'; // "00dc"
136 i.dwFlags=enc_result.isKeyFrame?0x10:0;
137 i.dwChunkLength=enc_frame.length;
138 // Write AVI chunk:
139 if((file=fopen(encode_name,"ab"))){
140 unsigned char zerobyte=0;
141 i.dwChunkOffset=ftell(file);
142 fwrite(&i.ckid,4,1,file);
143 fwrite(&enc_frame.length,4,1,file);
144 fwrite(buffer,enc_frame.length,1,file);
145 if(enc_frame.length&1) fwrite(&zerobyte,1,1,file); // padding
146 fclose(file);
147 }
148 // Write AVI index:
149 if(encode_index_name && (file=fopen(encode_index_name,"ab"))){
150 fwrite(&i,sizeof(i),1,file);
151 fclose(file);
152 }
153 }
154
155
156 }
157
158 static uint32_t
159 query_format(uint32_t format)
160 {
161 switch(format){
162 case IMGFMT_YV12:
163 // case IMGFMT_YUY2:
164 case IMGFMT_BGR|24:
165 return 1;
166 }
167 return 0;
168 }
169
170 extern int encode_bitrate;
171
172 static uint32_t
173 init(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t fullscreen, char *title, uint32_t format)
174 {
175 uint32_t frame_size;
176 ENC_PARAM enc_param;
177
178 // file = fopen("encoded.odvx","wb");
179 // if(!file) return -1;
180
181 switch(format){
182 case IMGFMT_YV12:
183 frame_size=width*height+width*height/2;
184 enc_param.flip=2; // 0=RGB 1=flippedRGB 2=planarYUV format
185 break;
186 case IMGFMT_BGR|24:
187 enc_param.flip=0; // 0=RGB 1=flippedRGB 2=planarYUV format
188 frame_size=width*height*3;
189 break;
190 default: return -1; // invalid format
191 }
192
193 enc_param.x_dim=width;
194 enc_param.y_dim=height;
195
196 image_width=width;
197 image_height=height;
198 image_format=format;
199 image=malloc(frame_size);
200
201 //clear the buffer
202 memset(image,0x80,frame_size);
203
204 // buffer for encoded video data:
205 buffer=malloc(0x100000);
206 if(!buffer) return -1;
207
208 // encoding parameters:
209 enc_param.framerate=25.0;
210 enc_param.bitrate=encode_bitrate?encode_bitrate:780000;
211 enc_param.rc_period=300;
212 enc_param.max_quantizer=15;
213 enc_param.min_quantizer=1;
214 enc_param.search_range=128;
215
216 // init codec:
217 encore(0x123,ENC_OPT_INIT,&enc_param,NULL);
218
219 return 0;
220 }
221
222 static const vo_info_t*
223 get_info(void)
224 {
225 return &vo_info;
226 }
227
228 static void
229 uninit(void)
230 {
231 }
232
233
234