# HG changeset patch # User arpi # Date 1000061435 0 # Node ID 220475b1676a523e78731128c80a8fbee5603afa # Parent 73c77105006566bec13b64916c8830a80b4e2a1f PS multiplexing fixed diff -r 73c771050065 -r 220475b1676a libvo/vo_mpegpes.c --- a/libvo/vo_mpegpes.c Sun Sep 09 18:02:50 2001 +0000 +++ b/libvo/vo_mpegpes.c Sun Sep 09 18:50:35 2001 +0000 @@ -1,8 +1,43 @@ +//#define HAVE_DVB +#define PES_MAX_SIZE 2048 +/* + * Based on: + * + * test_av.c - Test program for new API + * + * Copyright (C) 2000 Ralph Metzler + * & Marcus Metzler + * for convergence integrated media GmbH + * + * libav - MPEG-PS multiplexer, part of ffmpeg + * Copyright Gerard Lantau (see http://ffmpeg.sf.net) + * + */ #include #include #include +#include +#include +#include +#include + +#ifdef HAVE_DVB + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#endif + #include "config.h" #include "video_out.h" #include "video_out_internal.h" @@ -10,11 +45,16 @@ LIBVO_EXTERN (mpegpes) int vo_mpegpes_fd=-1; +int vo_mpegpes_fd2=-1; static vo_info_t vo_info = { +#ifdef HAVE_DVB + "Mpeg-PES to DVB card", +#else "Mpeg-PES file", - "mpgpes", +#endif + "mpegpes", "A'rpi", "" }; @@ -22,11 +62,59 @@ 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) { - vo_mpegpes_fd=open("grab.mpg","ab"); +#ifdef HAVE_DVB + //|O_NONBLOCK + if((vo_mpegpes_fd = open("/dev/ost/video",O_RDWR)) < 0){ + perror("DVB VIDEO DEVICE: "); + return -1; + } + if((vo_mpegpes_fd2 = open("/dev/ost/audio",O_RDWR|O_NONBLOCK)) < 0){ + perror("DVB AUDIO DEVICE: "); + return -1; + } + if ( (ioctl(vo_mpegpes_fd,VIDEO_SET_BLANK, false) < 0)){ + perror("DVB VIDEO SET BLANK: "); + return -1; + } + if ( (ioctl(vo_mpegpes_fd,VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY) < 0)){ + perror("DVB VIDEO SELECT SOURCE: "); + return -1; + } +#if 1 + if ( (ioctl(vo_mpegpes_fd2,AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY) < 0)){ + perror("DVB AUDIO SELECT SOURCE: "); + return -1; + } + if ( (ioctl(vo_mpegpes_fd2,AUDIO_PLAY) < 0)){ + perror("DVB AUDIO PLAY: "); + return -1; + } +#else + if ( (ioctl(vo_mpegpes_fd2,AUDIO_STOP,0) < 0)){ + perror("DVB AUDIO STOP: "); + return -1; + } +#endif + if ( (ioctl(vo_mpegpes_fd,VIDEO_PLAY) < 0)){ + perror("DVB VIDEO PLAY: "); + return -1; + } + if ( (ioctl(vo_mpegpes_fd2,AUDIO_SET_AV_SYNC, false) < 0)){ + perror("DVB AUDIO SET AV SYNC: "); + return -1; + } + if ( (ioctl(vo_mpegpes_fd2,AUDIO_SET_MUTE, false) < 0)){ + perror("DVB AUDIO SET MUTE: "); + return -1; + } + +#else + vo_mpegpes_fd=open("grab.mpg",O_WRONLY|O_CREAT); if(vo_mpegpes_fd<0){ perror("vo_mpegpes"); return -1; } +#endif return 0; } @@ -49,41 +137,80 @@ return 0; } +#define NFD 2 + static void my_write(unsigned char* data,int len){ + struct pollfd pfd[NFD]; + +// printf("write %d bytes \n",len); + + pfd[0].fd = vo_mpegpes_fd; + pfd[0].events = POLLOUT; + + pfd[1].fd = vo_mpegpes_fd2; + pfd[1].events = POLLOUT; + while(len>0){ - int ret=write(vo_mpegpes_fd,data,len); - if(ret<=0) break; // error - len-=ret; data+=ret; + if (poll(pfd,NFD,1)){ + if (pfd[0].revents & POLLOUT){ + int ret=write(vo_mpegpes_fd,data,len); +// printf("ret=%d \n",ret); + if(ret<=0){ + perror("write"); + usleep(0); + } else { + len-=ret; data+=ret; + } + } else usleep(1000); + } } } +static unsigned char pes_header[PES_MAX_SIZE]; + +static void send_pes_packet(unsigned char* data,int len,int id,int timestamp){ + int x; + + pes_header[0]=pes_header[1]=0; + pes_header[2]=id>>8; pes_header[3]=id&255; + + while(1){ + int payload_size=len+5; // data + PTS + if(6+payload_size>PES_MAX_SIZE) payload_size=PES_MAX_SIZE-6; + + // construct PES header: (code from ffmpeg's libav) + // startcode: + // packetsize: + pes_header[4]=(payload_size)>>8; + pes_header[5]=(payload_size)&255; + // stuffing: + // presentation time stamp: + x=(0x02 << 4) | (((timestamp >> 30) & 0x07) << 1) | 1; + pes_header[6]=x; + x=((((timestamp >> 15) & 0x7fff) << 1) | 1); + pes_header[7]=x>>8; pes_header[8]=x&255; + x=((((timestamp) & 0x7fff) << 1) | 1); + pes_header[9]=x>>8; pes_header[10]=x&255; + + payload_size-=5; + memcpy(&pes_header[6+5],data,payload_size); + my_write(pes_header,6+5+payload_size); + + len-=payload_size; data+=payload_size; + if(len<=0) break; + } + +// printf("PES: draw frame! pts=%d size=%d \n",timestamp,len); + +} + static uint32_t draw_frame(uint8_t * src[]) { vo_mpegpes_t *p=(vo_mpegpes_t *)src[0]; - int payload_size=p->size+5; - int x; - unsigned char pes_header[4+2+5]; - - // construct PES header: - // startcode: - pes_header[0]=pes_header[1]=0; - pes_header[2]=p->id>>8; pes_header[3]=p->id&255; - // packetsize: - pes_header[4]=payload_size>>8; - pes_header[5]=payload_size&255; - // stuffing: - // presentation time stamp: - x=(0x02 << 4) | (((p->timestamp >> 30) & 0x07) << 1) | 1; - pes_header[6]=x; - x=((((p->timestamp >> 15) & 0x7fff) << 1) | 1); - pes_header[7]=x>>8; pes_header[8]=x&255; - x=((((p->timestamp) & 0x7fff) << 1) | 1); - pes_header[9]=x>>8; pes_header[10]=x&255; - my_write(pes_header,4+2+5); - // data: - my_write(p->data,p->size); - -// printf("PES: draw frame! pts=%d size=%d \n",p->timestamp,p->size); + unsigned char *data=p->data; +// int tmp=-1; + send_pes_packet(p->data,p->size,p->id,p->timestamp); // video data +// send_pes_packet(&tmp,0,0x1C0,p->timestamp+30000); // fake audio data return 0; } @@ -98,8 +225,8 @@ static void uninit(void) { - close(vo_mpegpes_fd); - vo_mpegpes_fd=-1; + if(vo_mpegpes_fd>=0){ close(vo_mpegpes_fd);vo_mpegpes_fd=-1;} + if(vo_mpegpes_fd2>=0){ close(vo_mpegpes_fd2);vo_mpegpes_fd2=-1;} }