Mercurial > mplayer.hg
annotate libvo/vo_odivx.c @ 6604:62ce54563e56
Hopefully the end of the RealPlayer codecs saga..
Explained where to put things and which configure options to use in case
something goes wrong.
author | diego |
---|---|
date | Sat, 29 Jun 2002 16:27:48 +0000 |
parents | 32e1f5042f65 |
children | eca7dbad0166 |
rev | line source |
---|---|
1 | 1 /* |
2 * OpenDivX AVI file writer | |
3 */ | |
4 | |
5 #include <stdio.h> | |
6 #include <stdlib.h> | |
7 #include <string.h> | |
4737
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
8 #include <errno.h> |
1 | 9 |
10 #include "config.h" | |
11 #include "video_out.h" | |
12 #include "video_out_internal.h" | |
13 | |
14 LIBVO_EXTERN(odivx) | |
15 | |
16 #include <sys/ioctl.h> | |
17 #include <unistd.h> | |
18 #include <fcntl.h> | |
19 #include <sys/mman.h> | |
20 | |
21 #include "../encore/encore.h" | |
22 | |
354 | 23 #include "fastmemcpy.h" |
350 | 24 |
1 | 25 static vo_info_t vo_info = |
26 { | |
27 "OpenDivX AVI File writer", | |
28 "odivx", | |
29 "Arpad Gereoffy <arpi@esp-team.scene.hu>", | |
30 "" | |
31 }; | |
32 | |
33 static uint8_t *image=NULL; | |
34 static int image_width=0; | |
35 static int image_height=0; | |
36 static unsigned int image_format=0; | |
37 static char *buffer=NULL; | |
38 static int frameno=0; | |
39 | |
40 extern char* encode_name; | |
41 extern char* encode_index_name; | |
42 | |
43 //static uint32_t draw_slice(uint8_t *src[], uint32_t slice_num) | |
44 static uint32_t draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y) | |
45 { | |
46 uint8_t *s; | |
47 uint8_t *d; | |
48 int i; | |
49 int dstride=image_width; | |
50 | |
51 // copy Y | |
52 d=image+dstride*y+x; | |
53 s=src[0]; | |
54 for(i=0;i<h;i++){ | |
55 memcpy(d,s,w); | |
56 s+=stride[0]; | |
57 d+=dstride; | |
58 } | |
59 | |
60 w/=2;h/=2;x/=2;y/=2; dstride/=2; | |
61 | |
62 // copy U | |
63 d=image+image_width*image_height + dstride*y+x; | |
64 s=src[1]; | |
65 for(i=0;i<h;i++){ | |
66 memcpy(d,s,w); | |
67 s+=stride[1]; | |
68 d+=dstride; | |
69 } | |
70 | |
71 // copy V | |
72 d=image+image_width*image_height +image_width*image_height/4 + dstride*y+x; | |
73 s=src[2]; | |
74 for(i=0;i<h;i++){ | |
75 memcpy(d,s,w); | |
76 s+=stride[2]; | |
77 d+=dstride; | |
78 } | |
79 | |
80 return 0; | |
81 } | |
82 | |
83 static uint32_t | |
84 draw_frame(uint8_t *src[]) | |
85 { | |
86 uint8_t *d=image; | |
87 | |
88 switch(image_format){ | |
89 case IMGFMT_YV12: | |
90 // copy Y | |
91 memcpy(d,src[0],image_width*image_height); | |
92 // copy U | |
93 d+=image_width*image_height; | |
94 memcpy(d,src[1],image_width*image_height/4); | |
95 // copy V | |
96 d+=image_width*image_height/4; | |
97 memcpy(d,src[2],image_width*image_height/4); | |
98 break; | |
80 | 99 case IMGFMT_YUY2: { |
100 uint8_t *dY=image; | |
101 uint8_t *dU=image+image_width*image_height; | |
102 uint8_t *dV=dU+image_width*image_height/4; | |
103 uint8_t *s=src[0]; | |
104 int y; | |
105 for(y=0;y<image_height;y+=2){ | |
106 uint8_t *e=s+image_width*2; | |
107 while(s<e){ | |
108 *dY++=s[0]; | |
109 *dU++=s[1]; | |
110 *dY++=s[2]; | |
111 *dV++=s[3]; | |
112 s+=4; | |
113 } | |
114 e=s+image_width*2; | |
115 while(s<e){ | |
116 *dY++=s[0]; | |
117 *dY++=s[2]; | |
118 s+=4; | |
119 } | |
120 } | |
121 | |
122 // case IMGFMT_BGR|24: | |
123 // memcpy(d,src[0],image_width*image_height*2); | |
1 | 124 break; |
125 } | |
80 | 126 } |
1 | 127 |
128 return 0; | |
129 } | |
130 | |
131 typedef unsigned int DWORD; | |
132 | |
133 typedef struct | |
134 { | |
135 DWORD ckid; | |
136 DWORD dwFlags; | |
137 DWORD dwChunkOffset; // Position of chunk | |
138 DWORD dwChunkLength; // Length of chunk | |
139 } AVIINDEXENTRY; | |
140 | |
1502 | 141 static void draw_osd(void) |
142 { | |
143 } | |
144 | |
1 | 145 static void |
146 flip_page(void) | |
147 { | |
148 | |
149 // we are rady to encode this frame | |
150 ENC_FRAME enc_frame; | |
151 ENC_RESULT enc_result; | |
152 | |
153 if(++frameno<10) return; | |
154 | |
80 | 155 enc_frame.image=image; |
1 | 156 enc_frame.bitstream=buffer; |
157 enc_frame.length=0; | |
158 encore(0x123,0,&enc_frame,&enc_result); | |
159 | |
612 | 160 printf("coded length: %ld \n",enc_frame.length); |
1 | 161 |
162 if(encode_name){ | |
163 AVIINDEXENTRY i; | |
164 FILE *file; | |
165 i.ckid=('c'<<24)|('d'<<16)|('0'<<8)|'0'; // "00dc" | |
166 i.dwFlags=enc_result.isKeyFrame?0x10:0; | |
167 i.dwChunkLength=enc_frame.length; | |
168 // Write AVI chunk: | |
169 if((file=fopen(encode_name,"ab"))){ | |
170 unsigned char zerobyte=0; | |
171 i.dwChunkOffset=ftell(file); | |
172 fwrite(&i.ckid,4,1,file); | |
173 fwrite(&enc_frame.length,4,1,file); | |
174 fwrite(buffer,enc_frame.length,1,file); | |
175 if(enc_frame.length&1) fwrite(&zerobyte,1,1,file); // padding | |
176 fclose(file); | |
177 } | |
178 // Write AVI index: | |
179 if(encode_index_name && (file=fopen(encode_index_name,"ab"))){ | |
180 fwrite(&i,sizeof(i),1,file); | |
181 fclose(file); | |
182 } | |
183 } | |
184 | |
185 | |
186 } | |
187 | |
188 static uint32_t | |
189 query_format(uint32_t format) | |
190 { | |
191 switch(format){ | |
192 case IMGFMT_YV12: | |
80 | 193 case IMGFMT_YUY2: |
194 // case IMGFMT_BGR|24: | |
1 | 195 return 1; |
196 } | |
197 return 0; | |
198 } | |
199 | |
200 extern int encode_bitrate; | |
201 | |
202 static uint32_t | |
4433 | 203 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) |
1 | 204 { |
205 uint32_t frame_size; | |
206 ENC_PARAM enc_param; | |
207 | |
208 // file = fopen("encoded.odvx","wb"); | |
209 // if(!file) return -1; | |
210 | |
211 switch(format){ | |
212 case IMGFMT_YV12: | |
213 frame_size=width*height+width*height/2; | |
80 | 214 // enc_param.flip=2; // 0=RGB 1=flippedRGB 2=planarYUV format |
1 | 215 break; |
80 | 216 case IMGFMT_YUY2: |
217 // case IMGFMT_BGR|24: | |
218 // enc_param.flip=0; // 0=RGB 1=flippedRGB 2=planarYUV format | |
219 // frame_size=width*height*2; | |
220 frame_size=width*height+width*height/2; | |
1 | 221 break; |
222 default: return -1; // invalid format | |
223 } | |
224 | |
225 enc_param.x_dim=width; | |
226 enc_param.y_dim=height; | |
227 | |
228 image_width=width; | |
229 image_height=height; | |
230 image_format=format; | |
231 image=malloc(frame_size); | |
232 | |
233 //clear the buffer | |
234 memset(image,0x80,frame_size); | |
235 | |
236 // buffer for encoded video data: | |
237 buffer=malloc(0x100000); | |
238 if(!buffer) return -1; | |
239 | |
240 // encoding parameters: | |
241 enc_param.framerate=25.0; | |
242 enc_param.bitrate=encode_bitrate?encode_bitrate:780000; | |
243 enc_param.rc_period=300; | |
244 enc_param.max_quantizer=15; | |
245 enc_param.min_quantizer=1; | |
246 enc_param.search_range=128; | |
247 | |
248 // init codec: | |
249 encore(0x123,ENC_OPT_INIT,&enc_param,NULL); | |
250 | |
251 return 0; | |
252 } | |
253 | |
254 static const vo_info_t* | |
255 get_info(void) | |
256 { | |
257 return &vo_info; | |
258 } | |
259 | |
260 static void | |
261 uninit(void) | |
262 { | |
263 } | |
264 | |
31 | 265 static void check_events(void) |
266 { | |
267 } | |
268 | |
4352 | 269 static uint32_t preinit(const char *arg) |
270 { | |
4737
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
271 if(arg) |
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
272 { |
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
273 printf("vo_odivx: Unknown subdevice: %s\n",arg); |
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
274 return ENOSYS; |
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
275 } |
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
276 return 0; |
4352 | 277 } |
31 | 278 |
4596 | 279 static uint32_t control(uint32_t request, void *data, ...) |
4352 | 280 { |
4592
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4433
diff
changeset
|
281 switch (request) { |
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4433
diff
changeset
|
282 case VOCTRL_QUERY_FORMAT: |
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4433
diff
changeset
|
283 return query_format(*((uint32_t*)data)); |
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4433
diff
changeset
|
284 } |
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4433
diff
changeset
|
285 return VO_NOTIMPL; |
4352 | 286 } |