From 566f20511901bbfad132f5742f35777d60849c8b Mon Sep 17 00:00:00 2001 From: arpi Date: Sat, 22 Sep 2001 18:50:09 +0000 Subject: YV12 support (using libavcodec for mpeg1-I encoding) git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@1936 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libvo/vo_mpegpes.c | 184 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 173 insertions(+), 11 deletions(-) (limited to 'libvo/vo_mpegpes.c') diff --git a/libvo/vo_mpegpes.c b/libvo/vo_mpegpes.c index d8bc0d4e51..7533c31167 100644 --- a/libvo/vo_mpegpes.c +++ b/libvo/vo_mpegpes.c @@ -1,4 +1,4 @@ -//#define HAVE_DVB +#define HAVE_DVB #define PES_MAX_SIZE 2048 /* * Based on: @@ -47,6 +47,24 @@ LIBVO_EXTERN (mpegpes) int vo_mpegpes_fd=-1; int vo_mpegpes_fd2=-1; +#ifdef USE_LIBAVCODEC + +#include "../libavcodec/avcodec.h" + +static unsigned char *picture_buf=NULL; +static unsigned char *outbuf=NULL; +static int outbuf_size = 100000; + +static int s_pos_x,s_pos_y; +static int d_pos_x,d_pos_y; + +static AVPicture picture; +static AVCodec *codec=NULL; +static AVCodecContext codec_context; +extern int avcodec_inited; + +#endif + static vo_info_t vo_info = { #ifdef HAVE_DVB @@ -60,7 +78,7 @@ static vo_info_t vo_info = }; static uint32_t -init(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t fullscreen, char *title, uint32_t format) +init(uint32_t s_width, uint32_t s_height, uint32_t width, uint32_t height, uint32_t fullscreen, char *title, uint32_t format) { #ifdef HAVE_DVB //|O_NONBLOCK @@ -114,6 +132,92 @@ init(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint3 perror("vo_mpegpes"); return -1; } +#endif + +#ifdef USE_LIBAVCODEC + picture_buf=NULL; +if(format==IMGFMT_YV12){ + int size; + + if(!avcodec_inited){ + avcodec_init(); + avcodec_register_all(); + avcodec_inited=1; + } + + /* find the mpeg1 video encoder */ + codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO); + if (!codec) { + fprintf(stderr, "mpeg1 codec not found\n"); + return -1; + } + memset(&codec_context,0,sizeof(codec_context)); + codec_context.bit_rate=100000; // not used + codec_context.frame_rate=25*FRAME_RATE_BASE; // !!!!! + codec_context.gop_size=0; // I frames only + codec_context.flags=CODEC_FLAG_QSCALE; + codec_context.quality=2; // quality! 1..31 (1=best,slowest) + +#if 0 + codec_context.width=width; + codec_context.height=height; +#else + if(width<=352 && height<=288){ + codec_context.width=352; + codec_context.height=288; + } else + if(width<=352 && height<=576){ + codec_context.width=352; + codec_context.height=576; + } else + if(width<=480 && height<=576){ + codec_context.width=480; + codec_context.height=576; + } else + if(width<=544 && height<=576){ + codec_context.width=544; + codec_context.height=576; + } else { + codec_context.width=704; + codec_context.height=576; + } +#endif + + d_pos_x=(codec_context.width-(int)s_width)/2; + if(d_pos_x<0){ + s_pos_x=-d_pos_x;d_pos_x=0; + } else s_pos_x=0; + + d_pos_y=(codec_context.height-(int)s_height)/2; + if(d_pos_y<0){ + s_pos_y=-d_pos_y;d_pos_y=0; + } else s_pos_y=0; + + printf("[vo] position mapping: %d;%d => %d;%d\n",s_pos_x,s_pos_y,d_pos_x,d_pos_y); + + /* open it */ + if (avcodec_open(&codec_context, codec) < 0) { + fprintf(stderr, "could not open codec\n"); + return -1; + } + + outbuf_size=10000+width*height; // must be enough! + outbuf = malloc(outbuf_size); + + size = codec_context.width*codec_context.height; + picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */ + + memset(picture_buf,0,size); // clear Y + memset(picture_buf+size,128,size/2); // clear UV + + picture.data[0] = picture_buf; + picture.data[1] = picture.data[0] + size; + picture.data[2] = picture.data[1] + size / 4; + picture.linesize[0] = codec_context.width; + picture.linesize[1] = codec_context.width / 2; + picture.linesize[2] = codec_context.width / 2; + +} #endif return 0; } @@ -128,15 +232,6 @@ static void draw_osd(void) { } -static void flip_page (void) -{ -} - -static uint32_t draw_slice(uint8_t *srcimg[], int stride[], int w,int h,int x,int y) -{ - return 0; -} - #define NFD 2 static void my_write(unsigned char* data,int len){ @@ -215,16 +310,83 @@ static uint32_t draw_frame(uint8_t * src[]) return 0; } +static void flip_page (void) +{ +#ifdef USE_LIBAVCODEC + if(picture_buf){ // YV12 only: + int out_size; + static int fno=0; + /* encode the image */ + out_size = avcodec_encode_video(&codec_context, outbuf, outbuf_size, &picture); + send_pes_packet(outbuf,out_size,0x1E0,fno*(90000/25));++fno; +// printf("frame size: %d \n",out_size); + } +#endif +} + +static uint32_t draw_slice(uint8_t *srcimg[], int stride[], int w,int h,int x0,int y0) +{ +#ifdef USE_LIBAVCODEC + int y; + unsigned char* s; + unsigned char* d; + + x0+=d_pos_x; + y0+=d_pos_y; + if(w>picture.linesize[0]) w=picture.linesize[0]; // !! + + // Y + s=srcimg[0]+s_pos_x+s_pos_y*stride[0]; + d=picture.data[0]+x0+y0*picture.linesize[0]; + for(y=0;y=0){ close(vo_mpegpes_fd);vo_mpegpes_fd=-1;} if(vo_mpegpes_fd2>=0){ close(vo_mpegpes_fd2);vo_mpegpes_fd2=-1;} } -- cgit v1.2.3