Mercurial > mplayer.hg
comparison libvo/vo_mpegpes.c @ 5059:8914f0bb6f35
using libFAME...
author | arpi |
---|---|
date | Wed, 13 Mar 2002 01:23:36 +0000 |
parents | 32e1f5042f65 |
children | 18c5dc6db592 |
comparison
equal
deleted
inserted
replaced
5058:33c01c795987 | 5059:8914f0bb6f35 |
---|---|
1 // Don't change for DVB card, it must be 2048 | |
1 #define PES_MAX_SIZE 2048 | 2 #define PES_MAX_SIZE 2048 |
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) | |
8 //#define USE_LIBFAME | |
9 | |
2 /* | 10 /* |
3 * Based on: | 11 * Based on: |
4 * | 12 * |
5 * test_av.c - Test program for new API | 13 * test_av.c - Test program for new API |
6 * | 14 * |
47 LIBVO_EXTERN (mpegpes) | 55 LIBVO_EXTERN (mpegpes) |
48 | 56 |
49 int vo_mpegpes_fd=-1; | 57 int vo_mpegpes_fd=-1; |
50 int vo_mpegpes_fd2=-1; | 58 int vo_mpegpes_fd2=-1; |
51 | 59 |
52 #ifdef USE_LIBAVCODEC | 60 #ifdef USE_LIBFAME |
53 | 61 |
54 #ifdef USE_LIBAVCODEC_SO | 62 #include "../libfame/fame.h" |
55 #include <libffmpeg/avcodec.h> | 63 |
56 #else | |
57 #include "../libavcodec/avcodec.h" | |
58 #endif | |
59 static unsigned char *picture_buf=NULL; | 64 static unsigned char *picture_buf=NULL; |
60 static unsigned char *outbuf=NULL; | 65 static unsigned char *outbuf=NULL; |
61 static int outbuf_size = 100000; | 66 static int outbuf_size = 1000000; |
62 | 67 |
63 static int s_pos_x,s_pos_y; | 68 static int s_pos_x,s_pos_y; |
64 static int d_pos_x,d_pos_y; | 69 static int d_pos_x,d_pos_y; |
65 | 70 |
66 static int osd_w,osd_h; | 71 static int osd_w,osd_h; |
67 | 72 |
68 static AVPicture picture; | 73 static fame_parameters_t params; |
69 static AVCodec *codec=NULL; | 74 static fame_yuv_t yuv; |
70 static AVCodecContext codec_context; | 75 static fame_context_t *ctx=NULL; |
71 extern int avcodec_inited; | |
72 | 76 |
73 #endif | 77 #endif |
74 | 78 |
75 static vo_info_t vo_info = | 79 static vo_info_t vo_info = |
76 { | 80 { |
139 perror("vo_mpegpes"); | 143 perror("vo_mpegpes"); |
140 return -1; | 144 return -1; |
141 } | 145 } |
142 #endif | 146 #endif |
143 | 147 |
144 #ifdef USE_LIBAVCODEC | 148 #ifdef USE_LIBFAME |
145 picture_buf=NULL; | 149 picture_buf=NULL; |
146 if(format==IMGFMT_YV12){ | 150 if(format==IMGFMT_YV12){ |
147 int size; | 151 int size; |
148 | 152 |
149 if(!avcodec_inited){ | 153 ctx=fame_open(); |
150 avcodec_init(); | 154 if(!ctx){ |
151 avcodec_register_all(); | 155 printf("FATAL: cannot open libFAME!\n"); |
152 avcodec_inited=1; | 156 return -1; |
153 } | 157 } |
154 | 158 |
155 /* find the mpeg1 video encoder */ | 159 params.width=720; |
156 codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO); | 160 params.height=576; |
157 if (!codec) { | 161 //params.coding="IPPPPP"; // seems to be buggy and eats more cpu |
158 fprintf(stderr, "mpeg1 codec not found\n"); | 162 params.coding="I"; |
159 return -1; | 163 params.quality=QUALITY; // 100=best >=80 very good >=50 fast |
160 } | 164 params.bitrate=0; // bitrate, 0=VBR |
161 memset(&codec_context,0,sizeof(codec_context)); | 165 params.slices_per_frame=1; |
162 codec_context.bit_rate=100000; // not used | 166 params.frames_per_sequence=0xffffffff; |
163 codec_context.frame_rate=25*FRAME_RATE_BASE; // !!!!! | 167 params.frame_rate_num=25; |
164 codec_context.gop_size=0; // I frames only | 168 params.frame_rate_den=1; |
165 codec_context.flags=CODEC_FLAG_QSCALE; | 169 params.shape_quality=100; |
166 codec_context.quality=2; // quality! 1..31 (1=best,slowest) | 170 params.search_range=8; // for "IPPP" only |
171 params.verbose=0; | |
172 params.profile=NULL; // TODO | |
167 | 173 |
168 #if 0 | 174 #if 0 |
169 codec_context.width=width; | 175 params.width=width; |
170 codec_context.height=height; | 176 params.height=height; |
171 #else | 177 #else |
172 if(width<=352 && height<=288){ | 178 if(width<=352 && height<=288){ |
173 codec_context.width=352; | 179 params.width=352; |
174 codec_context.height=288; | 180 params.height=288; |
175 } else | 181 } else |
176 if(width<=352 && height<=576){ | 182 if(width<=352 && height<=576){ |
177 codec_context.width=352; | 183 params.width=352; |
178 codec_context.height=576; | 184 params.height=576; |
179 } else | 185 } else |
180 if(width<=480 && height<=576){ | 186 if(width<=480 && height<=576){ |
181 codec_context.width=480; | 187 params.width=480; |
182 codec_context.height=576; | 188 params.height=576; |
183 } else | 189 } else |
184 if(width<=544 && height<=576){ | 190 if(width<=544 && height<=576){ |
185 codec_context.width=544; | 191 params.width=544; |
186 codec_context.height=576; | 192 params.height=576; |
187 } else { | 193 } else { |
188 codec_context.width=704; | 194 params.width=704; |
189 codec_context.height=576; | 195 params.height=576; |
190 } | 196 } |
191 #endif | 197 #endif |
192 | 198 |
193 osd_w=s_width; | 199 osd_w=s_width; |
194 d_pos_x=(codec_context.width-(int)s_width)/2; | 200 d_pos_x=(params.width-(int)s_width)/2; |
195 if(d_pos_x<0){ | 201 if(d_pos_x<0){ |
196 s_pos_x=-d_pos_x;d_pos_x=0; | 202 s_pos_x=-d_pos_x;d_pos_x=0; |
197 osd_w=codec_context.width; | 203 osd_w=params.width; |
198 } else s_pos_x=0; | 204 } else s_pos_x=0; |
199 | 205 |
200 osd_h=s_height; | 206 osd_h=s_height; |
201 d_pos_y=(codec_context.height-(int)s_height)/2; | 207 d_pos_y=(params.height-(int)s_height)/2; |
202 if(d_pos_y<0){ | 208 if(d_pos_y<0){ |
203 s_pos_y=-d_pos_y;d_pos_y=0; | 209 s_pos_y=-d_pos_y;d_pos_y=0; |
204 osd_h=codec_context.height; | 210 osd_h=params.height; |
205 } else s_pos_y=0; | 211 } else s_pos_y=0; |
206 | 212 |
207 printf("[vo] position mapping: %d;%d => %d;%d\n",s_pos_x,s_pos_y,d_pos_x,d_pos_y); | 213 printf("[vo] position mapping: %d;%d => %d;%d\n",s_pos_x,s_pos_y,d_pos_x,d_pos_y); |
208 | 214 |
209 /* open it */ | 215 /* open it */ |
210 if (avcodec_open(&codec_context, codec) < 0) { | 216 |
211 fprintf(stderr, "could not open codec\n"); | |
212 return -1; | |
213 } | |
214 | |
215 outbuf_size=10000+width*height; // must be enough! | 217 outbuf_size=10000+width*height; // must be enough! |
216 outbuf = malloc(outbuf_size); | 218 outbuf = malloc(outbuf_size); |
217 | 219 |
218 size = codec_context.width*codec_context.height; | 220 fame_init(ctx,¶ms,outbuf,outbuf_size); |
221 | |
222 size = params.width*params.height; | |
219 picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */ | 223 picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */ |
220 | 224 |
221 memset(picture_buf,0,size); // clear Y | 225 memset(picture_buf,0,size); // clear Y |
222 memset(picture_buf+size,128,size/2); // clear UV | 226 memset(picture_buf+size,128,size/2); // clear UV |
227 | |
228 yuv.w=params.width; | |
229 yuv.h=params.height; | |
230 yuv.y=picture_buf; | |
231 yuv.u=yuv.y+size; | |
232 yuv.v=yuv.u+size/4; | |
223 | 233 |
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 } | 234 } |
232 #endif | 235 #endif |
233 return 0; | 236 return 0; |
234 } | 237 } |
235 | 238 |
237 get_info(void) | 240 get_info(void) |
238 { | 241 { |
239 return &vo_info; | 242 return &vo_info; |
240 } | 243 } |
241 | 244 |
242 #ifdef USE_LIBAVCODEC | 245 #ifdef USE_LIBFAME |
243 static void draw_alpha(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){ | 246 static void draw_alpha(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){ |
244 int x,y; | 247 int x,y; |
245 vo_draw_alpha_yv12(w,h,src,srca,stride, | 248 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]); | 249 yuv.y+(x0+d_pos_x)+(y0+d_pos_y)*yuv.w,yuv.w); |
247 } | 250 } |
248 #endif | 251 #endif |
249 | 252 |
250 static void draw_osd(void) | 253 static void draw_osd(void) |
251 { | 254 { |
252 #ifdef USE_LIBAVCODEC | 255 #ifdef USE_LIBFAME |
253 if(picture_buf){ // YV12 only: | 256 if(picture_buf){ // YV12 only: |
254 vo_draw_text(osd_w,osd_h,draw_alpha); | 257 vo_draw_text(osd_w,osd_h,draw_alpha); |
255 } | 258 } |
256 #endif | 259 #endif |
257 } | 260 } |
423 return 0; | 426 return 0; |
424 } | 427 } |
425 | 428 |
426 static void flip_page (void) | 429 static void flip_page (void) |
427 { | 430 { |
428 #ifdef USE_LIBAVCODEC | 431 #ifdef USE_LIBFAME |
429 if(picture_buf){ // YV12 only: | 432 if(picture_buf){ // YV12 only: |
430 int out_size; | 433 int out_size; |
431 // static int fno=0; | 434 // static int fno=0; |
432 /* encode the image */ | 435 /* encode the image */ |
433 out_size = avcodec_encode_video(&codec_context, outbuf, outbuf_size, &picture); | 436 out_size = fame_encode_frame(ctx, &yuv, NULL); |
434 // send_pes_packet(outbuf,out_size,0x1E0,fno*(90000/25));++fno; | 437 // send_pes_packet(outbuf,out_size,0x1E0,fno*(90000/25));++fno; |
435 send_pes_packet(outbuf,out_size,0x1E0,vo_pts); | 438 send_pes_packet(outbuf,out_size,0x1E0,vo_pts); |
436 // printf("frame size: %d \n",out_size); | 439 // printf("frame size: %d \n",out_size); |
437 } | 440 } |
438 #endif | 441 #endif |
439 } | 442 } |
440 | 443 |
441 static uint32_t draw_slice(uint8_t *srcimg[], int stride[], int w,int h,int x0,int y0) | 444 static uint32_t draw_slice(uint8_t *srcimg[], int stride[], int w,int h,int x0,int y0) |
442 { | 445 { |
443 #ifdef USE_LIBAVCODEC | 446 #ifdef USE_LIBFAME |
444 int y; | 447 int y; |
445 unsigned char* s; | 448 unsigned char* s; |
446 unsigned char* d; | 449 unsigned char* d; |
447 | 450 |
448 x0+=d_pos_x; | 451 x0+=d_pos_x; |
449 y0+=d_pos_y; | 452 y0+=d_pos_y; |
450 if(x0+w>picture.linesize[0]) w=picture.linesize[0]-x0; // !! | 453 if(x0+w>yuv.w) w=yuv.w-x0; // !! |
451 if(y0+h>codec_context.height) h=codec_context.height-y0; | 454 if(y0+h>params.height) h=params.height-y0; |
452 | 455 |
453 // Y | 456 // Y |
454 s=srcimg[0]+s_pos_x+s_pos_y*stride[0]; | 457 s=srcimg[0]+s_pos_x+s_pos_y*stride[0]; |
455 d=picture.data[0]+x0+y0*picture.linesize[0]; | 458 d=yuv.y+x0+y0*yuv.w; |
456 for(y=0;y<h;y++){ | 459 for(y=0;y<h;y++){ |
457 memcpy(d,s,w); | 460 memcpy(d,s,w); |
458 s+=stride[0]; | 461 s+=stride[0]; |
459 d+=picture.linesize[0]; | 462 d+=yuv.w; |
460 } | 463 } |
461 | 464 |
462 w/=2;h/=2;x0/=2;y0/=2; | 465 w/=2;h/=2;x0/=2;y0/=2; |
463 | 466 |
464 // U | 467 // U |
465 s=srcimg[1]+(s_pos_x/2)+(s_pos_y/2)*stride[1]; | 468 s=srcimg[1]+(s_pos_x/2)+(s_pos_y/2)*stride[1]; |
466 d=picture.data[1]+x0+y0*picture.linesize[1]; | 469 d=yuv.u+x0+y0*(yuv.w>>1); |
467 for(y=0;y<h;y++){ | 470 for(y=0;y<h;y++){ |
468 memcpy(d,s,w); | 471 memcpy(d,s,w); |
469 s+=stride[1]; | 472 s+=stride[1]; |
470 d+=picture.linesize[1]; | 473 d+=(yuv.w>>1); |
471 } | 474 } |
472 | 475 |
473 // V | 476 // V |
474 s=srcimg[2]+(s_pos_x/2)+(s_pos_y/2)*stride[2]; | 477 s=srcimg[2]+(s_pos_x/2)+(s_pos_y/2)*stride[2]; |
475 d=picture.data[2]+x0+y0*picture.linesize[2]; | 478 d=yuv.v+x0+y0*(yuv.w>>1); |
476 for(y=0;y<h;y++){ | 479 for(y=0;y<h;y++){ |
477 memcpy(d,s,w); | 480 memcpy(d,s,w); |
478 s+=stride[2]; | 481 s+=stride[2]; |
479 d+=picture.linesize[2]; | 482 d+=(yuv.w>>1); |
480 } | 483 } |
481 #endif | 484 #endif |
482 return 0; | 485 return 0; |
483 } | 486 } |
484 | 487 |
485 | 488 |
486 static uint32_t | 489 static uint32_t |
487 query_format(uint32_t format) | 490 query_format(uint32_t format) |
488 { | 491 { |
489 if(format==IMGFMT_MPEGPES) return 1|256; | 492 if(format==IMGFMT_MPEGPES) return 1|256; |
490 #ifdef USE_LIBAVCODEC | 493 #ifdef USE_LIBFAME |
491 if(format==IMGFMT_YV12) return 1|256; | 494 if(format==IMGFMT_YV12) return 1|256; |
492 #endif | 495 #endif |
493 return 0; | 496 return 0; |
494 } | 497 } |
495 | 498 |
496 static void | 499 static void |
497 uninit(void) | 500 uninit(void) |
498 { | 501 { |
499 #ifdef USE_LIBAVCODEC | 502 #ifdef USE_LIBFAME |
500 if(picture_buf){ // YV12 only: | 503 if(picture_buf){ // YV12 only: |
501 free(outbuf); | 504 free(outbuf); |
502 free(picture_buf); | 505 free(picture_buf); |
506 fame_close(ctx); ctx=NULL; | |
503 } | 507 } |
504 #endif | 508 #endif |
505 if(vo_mpegpes_fd>=0){ close(vo_mpegpes_fd);vo_mpegpes_fd=-1;} | 509 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;} | 510 if(vo_mpegpes_fd2>=0){ close(vo_mpegpes_fd2);vo_mpegpes_fd2=-1;} |
507 } | 511 } |