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,&params,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 }