Mercurial > mplayer.hg
annotate libvo/vo_mpegpes.c @ 5161:b9ba9cefcd7d
Mp4S fixed
author | arpi |
---|---|
date | Sun, 17 Mar 2002 14:21:07 +0000 |
parents | 5823cde0dfdf |
children | b16820598c1b |
rev | line source |
---|---|
5059 | 1 // Don't change for DVB card, it must be 2048 |
1876 | 2 #define PES_MAX_SIZE 2048 |
5059 | 3 |
4 // 100=best >=80 very good >=50 fast | |
5 #define QUALITY 90 | |
6 | |
7 // #undef if you don't want mpeg1 transcoder (you'll be limited to mpeg1/2 playback only) | |
5141 | 8 #define USE_LIBFAME |
5059 | 9 |
1876 | 10 /* |
11 * Based on: | |
12 * | |
13 * test_av.c - Test program for new API | |
14 * | |
15 * Copyright (C) 2000 Ralph Metzler <ralph@convergence.de> | |
16 * & Marcus Metzler <marcus@convergence.de> | |
17 * for convergence integrated media GmbH | |
18 * | |
19 * libav - MPEG-PS multiplexer, part of ffmpeg | |
20 * Copyright Gerard Lantau (see http://ffmpeg.sf.net) | |
21 * | |
22 */ | |
1871 | 23 |
24 #include <stdio.h> | |
25 #include <stdlib.h> | |
26 #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
|
27 #include <errno.h> |
1876 | 28 #include <sys/types.h> |
29 #include <sys/stat.h> | |
30 #include <fcntl.h> | |
31 | |
2727 | 32 #include "config.h" |
33 | |
1876 | 34 #ifdef HAVE_DVB |
35 | |
2066
2b14cad013b7
using poll() only for DVB card - not required for file write
arpi
parents:
1986
diff
changeset
|
36 #include <sys/poll.h> |
2b14cad013b7
using poll() only for DVB card - not required for file write
arpi
parents:
1986
diff
changeset
|
37 |
1876 | 38 #include <sys/ioctl.h> |
39 #include <stdio.h> | |
40 #include <time.h> | |
41 #include <unistd.h> | |
42 | |
43 #include <ost/dmx.h> | |
44 #include <ost/frontend.h> | |
45 #include <ost/sec.h> | |
46 #include <ost/video.h> | |
47 #include <ost/audio.h> | |
48 | |
49 #endif | |
50 | |
1871 | 51 #include "config.h" |
52 #include "video_out.h" | |
53 #include "video_out_internal.h" | |
54 | |
55 LIBVO_EXTERN (mpegpes) | |
56 | |
1872 | 57 int vo_mpegpes_fd=-1; |
1876 | 58 int vo_mpegpes_fd2=-1; |
1872 | 59 |
5059 | 60 #ifdef USE_LIBFAME |
1935 | 61 |
5059 | 62 #include "../libfame/fame.h" |
63 | |
1935 | 64 static unsigned char *picture_buf=NULL; |
65 static unsigned char *outbuf=NULL; | |
5059 | 66 static int outbuf_size = 1000000; |
1935 | 67 |
68 static int s_pos_x,s_pos_y; | |
69 static int d_pos_x,d_pos_y; | |
70 | |
1943 | 71 static int osd_w,osd_h; |
72 | |
5059 | 73 static fame_parameters_t params; |
74 static fame_yuv_t yuv; | |
75 static fame_context_t *ctx=NULL; | |
1935 | 76 |
77 #endif | |
78 | |
1871 | 79 static vo_info_t vo_info = |
80 { | |
1876 | 81 #ifdef HAVE_DVB |
82 "Mpeg-PES to DVB card", | |
83 #else | |
1871 | 84 "Mpeg-PES file", |
1876 | 85 #endif |
86 "mpegpes", | |
1871 | 87 "A'rpi", |
88 "" | |
89 }; | |
90 | |
91 static uint32_t | |
4433 | 92 config(uint32_t s_width, uint32_t s_height, uint32_t width, uint32_t height, uint32_t fullscreen, char *title, uint32_t format,const vo_tune_info_t *info) |
1871 | 93 { |
1876 | 94 #ifdef HAVE_DVB |
95 //|O_NONBLOCK | |
96 if((vo_mpegpes_fd = open("/dev/ost/video",O_RDWR)) < 0){ | |
97 perror("DVB VIDEO DEVICE: "); | |
98 return -1; | |
99 } | |
100 if((vo_mpegpes_fd2 = open("/dev/ost/audio",O_RDWR|O_NONBLOCK)) < 0){ | |
101 perror("DVB AUDIO DEVICE: "); | |
102 return -1; | |
103 } | |
104 if ( (ioctl(vo_mpegpes_fd,VIDEO_SET_BLANK, false) < 0)){ | |
105 perror("DVB VIDEO SET BLANK: "); | |
106 return -1; | |
107 } | |
108 if ( (ioctl(vo_mpegpes_fd,VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY) < 0)){ | |
109 perror("DVB VIDEO SELECT SOURCE: "); | |
110 return -1; | |
111 } | |
112 #if 1 | |
113 if ( (ioctl(vo_mpegpes_fd2,AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY) < 0)){ | |
114 perror("DVB AUDIO SELECT SOURCE: "); | |
115 return -1; | |
116 } | |
117 if ( (ioctl(vo_mpegpes_fd2,AUDIO_PLAY) < 0)){ | |
118 perror("DVB AUDIO PLAY: "); | |
119 return -1; | |
120 } | |
121 #else | |
122 if ( (ioctl(vo_mpegpes_fd2,AUDIO_STOP,0) < 0)){ | |
123 perror("DVB AUDIO STOP: "); | |
124 return -1; | |
125 } | |
126 #endif | |
127 if ( (ioctl(vo_mpegpes_fd,VIDEO_PLAY) < 0)){ | |
128 perror("DVB VIDEO PLAY: "); | |
129 return -1; | |
130 } | |
131 if ( (ioctl(vo_mpegpes_fd2,AUDIO_SET_AV_SYNC, false) < 0)){ | |
132 perror("DVB AUDIO SET AV SYNC: "); | |
133 return -1; | |
134 } | |
135 if ( (ioctl(vo_mpegpes_fd2,AUDIO_SET_MUTE, false) < 0)){ | |
136 perror("DVB AUDIO SET MUTE: "); | |
137 return -1; | |
138 } | |
139 | |
140 #else | |
141 vo_mpegpes_fd=open("grab.mpg",O_WRONLY|O_CREAT); | |
1872 | 142 if(vo_mpegpes_fd<0){ |
143 perror("vo_mpegpes"); | |
144 return -1; | |
145 } | |
1876 | 146 #endif |
1935 | 147 |
5059 | 148 #ifdef USE_LIBFAME |
1935 | 149 picture_buf=NULL; |
150 if(format==IMGFMT_YV12){ | |
151 int size; | |
5059 | 152 |
153 ctx=fame_open(); | |
154 if(!ctx){ | |
155 printf("FATAL: cannot open libFAME!\n"); | |
156 return -1; | |
1935 | 157 } |
158 | |
5059 | 159 params.width=720; |
160 params.height=576; | |
161 //params.coding="IPPPPP"; // seems to be buggy and eats more cpu | |
162 params.coding="I"; | |
163 params.quality=QUALITY; // 100=best >=80 very good >=50 fast | |
5078
18c5dc6db592
10l? frames_per_sequence==GOPsize... so it should be few seconds
arpi
parents:
5059
diff
changeset
|
164 params.bitrate=0; // 6*1000000 // bitrate (X bits/sec), 0=VBR |
5059 | 165 params.slices_per_frame=1; |
5078
18c5dc6db592
10l? frames_per_sequence==GOPsize... so it should be few seconds
arpi
parents:
5059
diff
changeset
|
166 params.frames_per_sequence=25; //0xffffffff; |
5059 | 167 params.frame_rate_num=25; |
168 params.frame_rate_den=1; | |
169 params.shape_quality=100; | |
170 params.search_range=8; // for "IPPP" only | |
171 params.verbose=0; | |
172 params.profile=NULL; // TODO | |
1935 | 173 |
174 #if 0 | |
5059 | 175 params.width=width; |
176 params.height=height; | |
1935 | 177 #else |
178 if(width<=352 && height<=288){ | |
5059 | 179 params.width=352; |
180 params.height=288; | |
1935 | 181 } else |
182 if(width<=352 && height<=576){ | |
5059 | 183 params.width=352; |
184 params.height=576; | |
1935 | 185 } else |
186 if(width<=480 && height<=576){ | |
5059 | 187 params.width=480; |
188 params.height=576; | |
1935 | 189 } else |
190 if(width<=544 && height<=576){ | |
5059 | 191 params.width=544; |
192 params.height=576; | |
1935 | 193 } else { |
5059 | 194 params.width=704; |
195 params.height=576; | |
1935 | 196 } |
197 #endif | |
198 | |
1943 | 199 osd_w=s_width; |
5059 | 200 d_pos_x=(params.width-(int)s_width)/2; |
1935 | 201 if(d_pos_x<0){ |
202 s_pos_x=-d_pos_x;d_pos_x=0; | |
5059 | 203 osd_w=params.width; |
1935 | 204 } else s_pos_x=0; |
205 | |
5059 | 206 d_pos_y=(params.height-(int)s_height)/2; |
1935 | 207 if(d_pos_y<0){ |
208 s_pos_y=-d_pos_y;d_pos_y=0; | |
5059 | 209 osd_h=params.height; |
5080 | 210 } else { |
211 s_pos_y=0; | |
212 osd_h=s_height+d_pos_y; | |
213 // if(d_pos_y) osd clear: s_height+d_pos_y .. params.height | |
214 } | |
1943 | 215 |
1935 | 216 printf("[vo] position mapping: %d;%d => %d;%d\n",s_pos_x,s_pos_y,d_pos_x,d_pos_y); |
217 | |
218 /* open it */ | |
5059 | 219 |
1935 | 220 outbuf_size=10000+width*height; // must be enough! |
221 outbuf = malloc(outbuf_size); | |
222 | |
5059 | 223 fame_init(ctx,¶ms,outbuf,outbuf_size); |
224 | |
225 size = params.width*params.height; | |
1935 | 226 picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */ |
227 | |
228 memset(picture_buf,0,size); // clear Y | |
229 memset(picture_buf+size,128,size/2); // clear UV | |
5059 | 230 |
231 yuv.w=params.width; | |
232 yuv.h=params.height; | |
233 yuv.y=picture_buf; | |
234 yuv.u=yuv.y+size; | |
235 yuv.v=yuv.u+size/4; | |
1935 | 236 |
237 } | |
238 #endif | |
1871 | 239 return 0; |
240 } | |
241 | |
242 static const vo_info_t* | |
243 get_info(void) | |
244 { | |
245 return &vo_info; | |
246 } | |
247 | |
5059 | 248 #ifdef USE_LIBFAME |
1943 | 249 static void draw_alpha(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){ |
250 int x,y; | |
251 vo_draw_alpha_yv12(w,h,src,srca,stride, | |
5059 | 252 yuv.y+(x0+d_pos_x)+(y0+d_pos_y)*yuv.w,yuv.w); |
1943 | 253 } |
254 #endif | |
255 | |
1871 | 256 static void draw_osd(void) |
257 { | |
5059 | 258 #ifdef USE_LIBFAME |
1943 | 259 if(picture_buf){ // YV12 only: |
5080 | 260 // if(d_pos_y) osd clear: s_height+d_pos_y .. params.height |
261 if(d_pos_y){ | |
262 memset(yuv.y+osd_h*yuv.w,0,(params.height-osd_h)*yuv.w); | |
263 } | |
1943 | 264 vo_draw_text(osd_w,osd_h,draw_alpha); |
265 } | |
266 #endif | |
1871 | 267 } |
268 | |
1876 | 269 |
1872 | 270 static void my_write(unsigned char* data,int len){ |
2066
2b14cad013b7
using poll() only for DVB card - not required for file write
arpi
parents:
1986
diff
changeset
|
271 #ifdef HAVE_DVB |
2b14cad013b7
using poll() only for DVB card - not required for file write
arpi
parents:
1986
diff
changeset
|
272 #define NFD 2 |
1876 | 273 struct pollfd pfd[NFD]; |
274 | |
275 // printf("write %d bytes \n",len); | |
276 | |
277 pfd[0].fd = vo_mpegpes_fd; | |
278 pfd[0].events = POLLOUT; | |
279 | |
280 pfd[1].fd = vo_mpegpes_fd2; | |
281 pfd[1].events = POLLOUT; | |
282 | |
1872 | 283 while(len>0){ |
1876 | 284 if (poll(pfd,NFD,1)){ |
285 if (pfd[0].revents & POLLOUT){ | |
286 int ret=write(vo_mpegpes_fd,data,len); | |
287 // printf("ret=%d \n",ret); | |
288 if(ret<=0){ | |
289 perror("write"); | |
290 usleep(0); | |
291 } else { | |
292 len-=ret; data+=ret; | |
293 } | |
294 } else usleep(1000); | |
295 } | |
1872 | 296 } |
2066
2b14cad013b7
using poll() only for DVB card - not required for file write
arpi
parents:
1986
diff
changeset
|
297 |
2b14cad013b7
using poll() only for DVB card - not required for file write
arpi
parents:
1986
diff
changeset
|
298 #else |
2b14cad013b7
using poll() only for DVB card - not required for file write
arpi
parents:
1986
diff
changeset
|
299 write(vo_mpegpes_fd,data,len); // write to file |
2b14cad013b7
using poll() only for DVB card - not required for file write
arpi
parents:
1986
diff
changeset
|
300 #endif |
1872 | 301 } |
1871 | 302 |
1876 | 303 static unsigned char pes_header[PES_MAX_SIZE]; |
304 | |
2706 | 305 void send_pes_packet(unsigned char* data,int len,int id,int timestamp){ |
4306 | 306 int ptslen=timestamp?5:1; |
1876 | 307 |
4306 | 308 // startcode: |
1876 | 309 pes_header[0]=pes_header[1]=0; |
310 pes_header[2]=id>>8; pes_header[3]=id&255; | |
311 | |
4306 | 312 while(len>0){ |
313 int payload_size=len; // data + PTS | |
314 if(6+ptslen+payload_size>PES_MAX_SIZE) payload_size=PES_MAX_SIZE-(6+ptslen); | |
1876 | 315 |
316 // construct PES header: (code from ffmpeg's libav) | |
317 // packetsize: | |
4306 | 318 pes_header[4]=(ptslen+payload_size)>>8; |
319 pes_header[5]=(ptslen+payload_size)&255; | |
320 | |
321 if(ptslen==5){ | |
322 int x; | |
1876 | 323 // presentation time stamp: |
324 x=(0x02 << 4) | (((timestamp >> 30) & 0x07) << 1) | 1; | |
325 pes_header[6]=x; | |
326 x=((((timestamp >> 15) & 0x7fff) << 1) | 1); | |
327 pes_header[7]=x>>8; pes_header[8]=x&255; | |
328 x=((((timestamp) & 0x7fff) << 1) | 1); | |
329 pes_header[9]=x>>8; pes_header[10]=x&255; | |
4306 | 330 } else { |
331 // stuffing and header bits: | |
332 pes_header[6]=0x0f; | |
333 } | |
334 | |
335 memcpy(&pes_header[6+ptslen],data,payload_size); | |
336 my_write(pes_header,6+ptslen+payload_size); | |
1876 | 337 |
338 len-=payload_size; data+=payload_size; | |
4306 | 339 ptslen=1; // store PTS only once, at first packet! |
1876 | 340 } |
341 | |
342 // printf("PES: draw frame! pts=%d size=%d \n",timestamp,len); | |
343 | |
344 } | |
345 | |
4299
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
346 void send_lpcm_packet(unsigned char* data,int len,int id,unsigned int timestamp,int freq_id){ |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
347 |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
348 int ptslen=timestamp?5:0; |
2706 | 349 |
4306 | 350 // startcode: |
2706 | 351 pes_header[0]=pes_header[1]=0; |
352 pes_header[2]=1; pes_header[3]=0xBD; | |
353 | |
354 while(len>=4){ | |
355 int payload_size; | |
356 | |
357 payload_size=PES_MAX_SIZE-6-20; // max possible data len | |
358 if(payload_size>len) payload_size=len; | |
359 payload_size&=(~3); // align! | |
360 | |
361 //if(6+payload_size>PES_MAX_SIZE) payload_size=PES_MAX_SIZE-6; | |
362 | |
363 // packetsize: | |
4299
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
364 pes_header[4]=(payload_size+3+ptslen+7)>>8; |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
365 pes_header[5]=(payload_size+3+ptslen+7)&255; |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
366 |
2706 | 367 // stuffing: |
368 pes_header[6]=0x81; | |
369 pes_header[7]=0x80; | |
4299
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
370 |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
371 // hdrlen: |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
372 pes_header[8]=ptslen; |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
373 |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
374 if(ptslen){ |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
375 int x; |
2706 | 376 // presentation time stamp: |
377 x=(0x02 << 4) | (((timestamp >> 30) & 0x07) << 1) | 1; | |
378 pes_header[9]=x; | |
379 x=((((timestamp >> 15) & 0x7fff) << 1) | 1); | |
380 pes_header[10]=x>>8; pes_header[11]=x&255; | |
381 x=((((timestamp) & 0x7fff) << 1) | 1); | |
382 pes_header[12]=x>>8; pes_header[13]=x&255; | |
4299
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
383 } |
2706 | 384 |
4299
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
385 // ============ LPCM header: (7 bytes) ================= |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
386 // Info by mocm@convergence.de |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
387 |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
388 // ID: |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
389 pes_header[ptslen+9]=id; |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
390 |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
391 // number of frames: |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
392 pes_header[ptslen+10]=0x07; |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
393 |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
394 // first acces unit pointer, i.e. start of audio frame: |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
395 pes_header[ptslen+11]=0x00; |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
396 pes_header[ptslen+12]=0x04; |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
397 |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
398 // audio emphasis on-off 1 bit |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
399 // audio mute on-off 1 bit |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
400 // reserved 1 bit |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
401 // audio frame number 5 bit |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
402 pes_header[ptslen+13]=0x0C; |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
403 |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
404 // quantization word length 2 bit |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
405 // audio sampling frequency (48khz = 0, 96khz = 1) 2 bit |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
406 // reserved 1 bit |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
407 // number of audio channels - 1 (e.g. stereo = 1) 3 bit |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
408 pes_header[ptslen+14]=1|(freq_id<<4); |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
409 |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
410 // dynamic range control (0x80 if off) |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
411 pes_header[ptslen+15]=0x80; |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
412 |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
413 memcpy(&pes_header[6+3+ptslen+7],data,payload_size); |
8e157167cee5
LPCM write code rewritten, thanks to Marcus at mocm@convergence.de
arpi
parents:
2727
diff
changeset
|
414 my_write(pes_header,6+3+ptslen+7+payload_size); |
2706 | 415 |
416 len-=payload_size; data+=payload_size; | |
4306 | 417 ptslen=0; // store PTS only once, at first packet! |
2706 | 418 } |
419 | |
420 // printf("PES: draw frame! pts=%d size=%d \n",timestamp,len); | |
421 | |
422 } | |
423 | |
424 | |
1871 | 425 static uint32_t draw_frame(uint8_t * src[]) |
426 { | |
1872 | 427 vo_mpegpes_t *p=(vo_mpegpes_t *)src[0]; |
1876 | 428 unsigned char *data=p->data; |
429 // int tmp=-1; | |
430 send_pes_packet(p->data,p->size,p->id,p->timestamp); // video data | |
431 // send_pes_packet(&tmp,0,0x1C0,p->timestamp+30000); // fake audio data | |
1871 | 432 |
433 return 0; | |
434 } | |
435 | |
1935 | 436 static void flip_page (void) |
437 { | |
5059 | 438 #ifdef USE_LIBFAME |
1935 | 439 if(picture_buf){ // YV12 only: |
440 int out_size; | |
4330 | 441 // static int fno=0; |
1935 | 442 /* encode the image */ |
5059 | 443 out_size = fame_encode_frame(ctx, &yuv, NULL); |
4330 | 444 // send_pes_packet(outbuf,out_size,0x1E0,fno*(90000/25));++fno; |
445 send_pes_packet(outbuf,out_size,0x1E0,vo_pts); | |
1935 | 446 // printf("frame size: %d \n",out_size); |
447 } | |
448 #endif | |
449 } | |
450 | |
451 static uint32_t draw_slice(uint8_t *srcimg[], int stride[], int w,int h,int x0,int y0) | |
452 { | |
5059 | 453 #ifdef USE_LIBFAME |
1935 | 454 int y; |
455 unsigned char* s; | |
456 unsigned char* d; | |
457 | |
458 x0+=d_pos_x; | |
459 y0+=d_pos_y; | |
5059 | 460 if(x0+w>yuv.w) w=yuv.w-x0; // !! |
461 if(y0+h>params.height) h=params.height-y0; | |
1935 | 462 |
463 // Y | |
464 s=srcimg[0]+s_pos_x+s_pos_y*stride[0]; | |
5059 | 465 d=yuv.y+x0+y0*yuv.w; |
1935 | 466 for(y=0;y<h;y++){ |
467 memcpy(d,s,w); | |
468 s+=stride[0]; | |
5059 | 469 d+=yuv.w; |
1935 | 470 } |
471 | |
472 w/=2;h/=2;x0/=2;y0/=2; | |
473 | |
474 // U | |
475 s=srcimg[1]+(s_pos_x/2)+(s_pos_y/2)*stride[1]; | |
5059 | 476 d=yuv.u+x0+y0*(yuv.w>>1); |
1935 | 477 for(y=0;y<h;y++){ |
478 memcpy(d,s,w); | |
479 s+=stride[1]; | |
5059 | 480 d+=(yuv.w>>1); |
1935 | 481 } |
482 | |
483 // V | |
484 s=srcimg[2]+(s_pos_x/2)+(s_pos_y/2)*stride[2]; | |
5059 | 485 d=yuv.v+x0+y0*(yuv.w>>1); |
1935 | 486 for(y=0;y<h;y++){ |
487 memcpy(d,s,w); | |
488 s+=stride[2]; | |
5059 | 489 d+=(yuv.w>>1); |
1935 | 490 } |
491 #endif | |
492 return 0; | |
493 } | |
494 | |
495 | |
1871 | 496 static uint32_t |
497 query_format(uint32_t format) | |
498 { | |
2706 | 499 if(format==IMGFMT_MPEGPES) return 1|256; |
5059 | 500 #ifdef USE_LIBFAME |
2706 | 501 if(format==IMGFMT_YV12) return 1|256; |
1935 | 502 #endif |
1871 | 503 return 0; |
504 } | |
505 | |
506 static void | |
507 uninit(void) | |
508 { | |
5059 | 509 #ifdef USE_LIBFAME |
1935 | 510 if(picture_buf){ // YV12 only: |
511 free(outbuf); | |
512 free(picture_buf); | |
5059 | 513 fame_close(ctx); ctx=NULL; |
1935 | 514 } |
515 #endif | |
1876 | 516 if(vo_mpegpes_fd>=0){ close(vo_mpegpes_fd);vo_mpegpes_fd=-1;} |
517 if(vo_mpegpes_fd2>=0){ close(vo_mpegpes_fd2);vo_mpegpes_fd2=-1;} | |
1871 | 518 } |
519 | |
520 | |
521 static void check_events(void) | |
522 { | |
523 } | |
524 | |
4352 | 525 static uint32_t preinit(const char *arg) |
526 { | |
4737
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
527 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
|
528 { |
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
529 printf("vo_mpegpes: 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
|
530 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
|
531 } |
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
532 return 0; |
4352 | 533 } |
534 | |
4596 | 535 static uint32_t control(uint32_t request, void *data, ...) |
4352 | 536 { |
4592
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4433
diff
changeset
|
537 switch (request) { |
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4433
diff
changeset
|
538 case VOCTRL_QUERY_FORMAT: |
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4433
diff
changeset
|
539 return query_format(*((uint32_t*)data)); |
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4433
diff
changeset
|
540 } |
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4433
diff
changeset
|
541 return VO_NOTIMPL; |
4352 | 542 } |