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