上网本的cpu确实是太弱了。弱到电影稍微清楚点,分辨率高点就卡得没法看。想装一个coreavc进行解码。
在google project上有coreavc-for-linux,wiki上也很详细,基本上照着来就能安装了。先安装dshowserver和coreavc,然后是mplayer。
在安装dshowserver时,把trunk下载下来以后需要把/loader/dshow中的文件拷到/loader中,否则无法make过去。用wine安装CoreAVC Professional Edition-x.x.x_Setup.exe的时候先把~/.wine给删除了,不然会提示bad file descriptor。
安装mplayer的时候,需要用到/mplayer/dshowserver.patch,但是因为mplayer更新了,所以这个patch也需要更改。
- Index: libmpcodecs/vd.c
- ===================================================================
- --- libmpcodecs/vd.c.orig 2010-03-12 07:47:10.000000000 -0800
- +++ libmpcodecs/vd.c 2010-03-12 07:48:02.000000000 -0800
- @@ -43,6 +43,7 @@
- extern const vd_functions_t mpcodecs_vd_ffmpeg;
- extern const vd_functions_t mpcodecs_vd_theora;
- extern const vd_functions_t mpcodecs_vd_dshow;
- +extern const vd_functions_t mpcodecs_vd_dshowserver;
- extern const vd_functions_t mpcodecs_vd_dmo;
- extern const vd_functions_t mpcodecs_vd_vfw;
- extern const vd_functions_t mpcodecs_vd_vfwex;
- @@ -74,6 +75,7 @@
- #ifdef CONFIG_OGGTHEORA
- &mpcodecs;_vd_theora,
- #endif
- + &mpcodecs;_vd_dshowserver,
- #ifdef CONFIG_WIN32DLL
- &mpcodecs;_vd_dshow,
- &mpcodecs;_vd_dmo,
- Index: Makefile
- ===================================================================
- --- Makefile.orig 2010-03-12 07:47:19.000000000 -0800
- +++ Makefile 2010-03-12 07:48:02.000000000 -0800
- @@ -20,6 +20,7 @@
- # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- include config.mak
- +EXTRALIBS += -lrt
-
- .SUFFIXES:
-
- @@ -476,6 +518,7 @@
- stream/stream_mf.c
- stream/stream_null.c
- stream/url.c
- + libmpcodecs/vd_dshowserver.c
- sub/eosd.c
-
- @@ -865,6 +868,7 @@
- libdvdread4/%: CFLAGS := -Ilibdvdread4 -D_GNU_SOURCE $(CFLAGS_LIBDVDCSS_DVDREAD) $(CFLAGS)
-
- +libmpcodecs/%: CFLAGS := $(CFLAGS) -g -O0
- loader/%: CFLAGS += -fno-omit-frame-pointer $(CFLAGS_NO_OMIT_LEAF_FRAME_POINTER)
- #loader/%: CFLAGS += -Ddbg_printf=__vprintf -DTRACE=__vprintf -DDETAILED_OUT
- loader/win32%: CFLAGS += $(CFLAGS_STACKREALIGN)
-
- Index: libmpcodecs/vd_dshowserver.c
- ===================================================================
- --- /dev/null 1970-01-01 00:00:00.000000000 +0000
- +++ libmpcodecs/vd_dshowserver.c 2010-03-12 07:56:33.000000000 -0800
- @@ -0,0 +1,295 @@
- +/*
- + * Copyright Alan Nisota 2006 - 2010
- + * To use this code, make sureyour codecs.conf file has been updated with this section:
- + * videocodec coreserve
- + * info "CoreAVC DShowServer"
- + * status untested
- + * format 0x10000005
- + * fourcc H264,h264
- + * fourcc X264,x264
- + * fourcc avc1,AVC1 AVC1
- + * fourcc davc,DAVC
- + * fourcc VSSH
- + * driver dshowserver
- + * dll "CoreAVCDecoder.ax"
- + * guid 0x09571a4b, 0xf1fe, 0x4c60, 0x97, 0x60, 0xde, 0x6d, 0x31, 0x0c, 0x7c, 0x31
- + * out YV12,IYUV,I420,YUY2
- + *
- + * Codec is very sensitive to the fourcc value. As of 2009-08-30, mplayer incorrectly reports
- + * AVC1 as H264 when using lavf decoder, resulting in breakage.
- + * this can be corrected by using an alternate demuxer (-demuxer mov for example)
- + * or by adding this to the above file:
- + * fourcc H264,h264 AVC1
- + * though that may break regular h264 playback
- + */
- +
- +#include
- +#include
- +#include
- +#include mman.h><span>
- +#include
- +
- +#include types.h><span>
- +#include
- +#include stat.h><span>
- +#include
- +#include
- +#include wait.h><span>
- +
- +#include "config.h"
- +
- +#include "mp_msg.h"
- +
- +#include "vd_internal.h"
- +
- +struct vd_struct {
- + union {
- + uint32_t ret;
- + uint32_t cmd;
- + };
- + uint32_t buflen;
- + uint64_t pts;
- + uint32_t unused[8];
- +} __attribute__((__packed__));
- +
- +enum {
- + VD_END = 1,
- + VD_DECODE = 2,
- + VD_SEEK = 3,
- + VD_HAS_BIH = 0x10000,
- + VD_VERSION_MASK = 0xFFFF,
- +};
- +#include "timeout_sem.c"
- +
- +static vd_info_t info = {
- + "DirectShowServer video codecs",
- + "dshowserver",
- + "Alan Nisota",
- + "based on dshow",
- + "win32 codecs"
- +};
- +
- +LIBVD_EXTERN(dshowserver)
- +typedef struct {
- + int fd;
- + void *mem;
- + char *data;
- + char *picture;
- + int picsize;
- + int pagesize;
- + void *sem;
- + struct vd_struct *vd;
- +} ds_mpi_t;
- +static ds_mpi_t *ds_mpi;
- +
- +// to set/get/query special features/parameters
- +static int control(sh_video_t *sh __attribute((unused)),int cmd,void* arg __attribute((unused)),...){
- + switch(cmd){
- + case VDCTRL_RESYNC_STREAM:
- + printf("Seek nown");
- + ds_mpi->vd->cmd = VD_SEEK; //'3' is cmd for seek
- + timed_sempost(ds_mpi->sem);
- + timed_semwait(ds_mpi->sem, 10);
- + return CONTROL_TRUE;
- + case VDCTRL_QUERY_MAX_PP_LEVEL:
- + return 4;
- + case VDCTRL_QUERY_UNSEEN_FRAMES:
- + return 10;
- +
- + }
- + return CONTROL_UNKNOWN;
- +}
- +
- +static int my_system(const char *command)
- +{
- + pid_t child = fork();
- +
- + if (child < 0)
- + {
- + /* Fork failed */
- + return child;
- + }
- + else if (child == 0)
- + {
- + /* Child */
- + int i;
- + /* Close all open file descriptors except stdout/stderr */
- + for (i = sysconf(_SC_OPEN_MAX) - 1; i > 2; i--)
- + close(i);
- +
- + /* Attach stdin to /dev/null */
- + /*
- + close(0);
- + int fd = open("/dev/null", O_RDONLY);
- + dup2(fd, 0);
- + if (fd != 0)
- + close(fd);
- + */
- + /* Run command */
- + execl("/bin/sh", "sh", "-c", command, NULL);
- + _exit(0);
- + }
- + else
- + {
- + /* Parent */
- + int status;
- +
- + waitpid(child, &status;, 0);
- + return status;
- + }
- +
- + return 1;
- +}
- +
- +// init driver
- +static int init(sh_video_t *sh){
- + int ret;
- + char cmd[255], shm[80], id[80];
- + uint32_t out_fmt;
- + int bpp, w, h;
- + int extra = 0;
- + int numpages = 10;
- + int port = 0;
- + int memsize;
- +
- + init_twait();
- + w = sh->disp_w; h = sh->disp_h;
- + if(!mpcodecs_config_vo(sh,w,h,IMGFMT_YUY2)) return 0;
- + out_fmt = sh->codec->outfmt[sh->outfmtidx];
- + switch(out_fmt){
- + case IMGFMT_YUY2:
- + case IMGFMT_UYVY:
- + bpp = 16; break;
- + case IMGFMT_YV12:
- + case IMGFMT_I420:
- + case IMGFMT_IYUV:
- + bpp = 12; break;
- + case IMGFMT_YVU9:
- + bpp = 9; break;
- + default:
- + bpp = 24; break;
- + }
- + sprintf(id, "%x", *(int *)pthread_self());
- + snprintf(shm, 80, "/dshow_shm.%s", id);
- +
- + ds_mpi = (ds_mpi_t *) malloc(sizeof(ds_mpi_t));
- + ds_mpi->fd = shm_open(shm, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
- + ds_mpi->picsize = w * h * bpp / 8;
- + ds_mpi->pagesize = ds_mpi->picsize + 1024;
- + memsize = sizeof(struct vd_struct) + w * h + ds_mpi->picsize + extra + ds_mpi->pagesize * numpages;
- + ftruncate(ds_mpi->fd, memsize);
- + ds_mpi->mem = mmap(NULL, memsize, PROT_READ | PROT_WRITE, MAP_SHARED, ds_mpi->fd, 0);
- + if(ds_mpi->mem == MAP_FAILED) {
- + perror("mmap");
- + return 0;
- + }
- + memset((char *)ds_mpi->mem, 0, sizeof(struct vd_struct));
- + if (extra)
- + memset((char *)ds_mpi->mem + (memsize - extra), 0, extra);
- + ds_mpi->vd = (struct vd_struct *)ds_mpi->mem;
- + ds_mpi->data = ((char *)ds_mpi->mem) + sizeof(struct vd_struct);
- + ds_mpi->picture = ds_mpi->data + w * h;
- + if(sh->bih->biWidth && sh->bih->biHeight) {
- + ds_mpi->vd->cmd |= VD_HAS_BIH; //Use embedded bih
- + memcpy(ds_mpi->data, sh->bih, sh->bih->biSize);
- + }
- +
- + ds_mpi->sem = timed_seminit(DS_SOCKET, &port;, 1);
- + //ds_mpi->sem = timed_seminit(DS_SEMAPHORE, id, 1);
- +
- + snprintf(cmd, 255, "dshowserver --codec %s --size %dx%d "
- + "--guid %08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x "
- + "--fourc 0x%08x --bits %d --outfmt 0x%08x --pid %d --id %s "
- + "--numpages %d --port %d %s&",
- + sh->codec->dll, w, h,
- + (unsigned int)sh->codec->guid.f1, sh->codec->guid.f2, sh->codec->guid.f3,
- + sh->codec->guid.f4[0], sh->codec->guid.f4[1], sh->codec->guid.f4[2], sh->codec->guid.f4[3],
- + sh->codec->guid.f4[4], sh->codec->guid.f4[5], sh->codec->guid.f4[6], sh->codec->guid.f4[7],
- + (unsigned int)sh->format, bpp, out_fmt, getpid(), id, numpages, port, "");
- + printf("%sn", cmd);
- + my_system(cmd);
- + ret = timed_semwait(ds_mpi->sem, 10);
- + shm_unlink(shm);
- + if(ret
- + printf("DirectShow filter failed");
- + return 0;
- + } else {
- + printf("Found DirectShow filter");
- + return 1;
- + }
- +}
- +
- +// uninit driver
- +static void uninit(sh_video_t *sh __attribute((unused))){
- + if(ds_mpi) {
- + printf("Destroying filter");
- + ds_mpi->vd->cmd = VD_END; //'1' is cmd for terminating
- + timed_sempost(ds_mpi->sem);
- + close(ds_mpi->fd);
- + timed_semdelete(ds_mpi->sem);
- + free(ds_mpi);
- + ds_mpi = NULL;
- + }
- +}
- +
- +//mp_image_t* mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag, int w, int h);
- +
- +// decode a frame
- +static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){
- + mp_image_t* mpi = NULL;
- + int ret;
- + unsigned char *t;
- +
- + if(len
- +
- + ds_mpi->vd->cmd = VD_DECODE; //'2' is cmd for decoding
- + ds_mpi->vd->pts = (uint64_t)(1E9* (sh->num_buffered_pts ? sh->buffered_pts[0] : sh->pts));
- + memcpy(ds_mpi->data, data, len);
- + if (0) {
- + static int count = 0;
- + char f[80];
- + FILE *fh;
- +
- + if(count == 100)
- + exit(1);
- + sprintf(f, "/tmp/mplayer.%d", count++);
- + fh = fopen(f, "w+");
- + fwrite(data, len, 1, fh);
- + fclose(fh);
- + }
- + ds_mpi->vd->buflen = len;
- + timed_sempost(ds_mpi->sem);
- + ret = timed_semwait(ds_mpi->sem, 10);
- + if(flags&3) {
- + // framedrop:
- + return NULL;
- + }
- + //printf("len: %d, PTS (ret:%d,vd_ret:%d): %f -> %fn", len, ret, ds_mpi->vd->ret, sh->buffered_pts[0], (double)ds_mpi->vd->pts/1E9);
- + //printf("PTS (%d): %f(%d) -> %dn", ds_mpi->vd->ret, sh->buffered_pts[0], pts-1, ds_mpi->vd->pts);
- + if(ret == 1 && ds_mpi->vd->ret && ! (ds_mpi->vd->ret & (1<
- + if(ds_mpi->vd->pts)
- + sh->buffered_pts[0] = (double)ds_mpi->vd->pts/1E9;
- + mpi=mpcodecs_get_image(sh, MP_IMGTYPE_EXPORT, MP_IMGFLAG_COMMON_PLANE|MP_IMGFLAG_COMMON_STRIDE,
- + sh->disp_w, sh->disp_h);
- + if(ds_mpi->vd->ret & 0x02) {
- + unsigned char page = ds_mpi->vd->ret >> 8;
- + mpi->planes[0]=ds_mpi->picture + ds_mpi->picsize + page * ds_mpi->pagesize;
- + } else {
- + mpi->planes[0]=ds_mpi->picture;
- + }
- + if (mpi->flags&MP;_IMGFLAG_PLANAR) {
- + mpi->stride[0] = mpi->width;
- + mpi->stride[1] = mpi->stride[2] = mpi->width >> mpi->chroma_x_shift;
- + mpi->planes[2] = mpi->planes[0] + mpi->stride[0] * mpi->height;
- + mpi->planes[1] = mpi->planes[2] + (mpi->width >> mpi->chroma_x_shift) * (mpi->height >> mpi->chroma_y_shift);
- + if (mpi->flags&MP;_IMGFLAG_SWAPPED) {
- + t = mpi->planes[1];
- + mpi->planes[1] = mpi->planes[2];
- + mpi->planes[2] = t;
- + }
- + } else {
- + mpi->stride[0]=mpi->bpp*mpi->width/8;
- + }
- + }
- + return mpi;
- +}
- Index: libmpcodecs/timeout_sem.c
- ===================================================================
- --- /dev/null 1970-01-01 00:00:00.000000000 +0000
- +++ libmpcodecs/timeout_sem.c 2010-03-12 08:03:16.000000000 -0800
- @@ -0,0 +1,397 @@
- +#include
- +#include
- +#include
- +#include
- +#include
- +#include
- +
- +#ifndef __MINGW32__
- + #include
- + #include in.h><span>
- + #include socket.h><span>
- + #include inet.h><span>
- + #include wait.h><span>
- +
- + #define DS_EINPROGRESS EINPROGRESS
- + #define DS_ETIMEDOUT ETIMEDOUT
- + #define DS_EWOULDBLOCK EWOULDBLOCK
- +#else
- + #define _WIN32_WINNT 0x0501
- + #include
- + #include
- + #include
- +
- + #define DS_EINPROGRESS WSAEINPROGRESS
- + #define DS_ETIMEDOUT WSAETIMEDOUT
- + #define DS_EWOULDBLOCK WSAEWOULDBLOCK
- +#endif
- +
- +#include "timeout_sem.h"
- +#ifdef __MINGW32__
- + #undef DS_SEMAPHORE
- +#endif
- +
- +#ifdef DS_SEMAPHORE
- +#include
- +#include
- +#endif
- +
- +struct sem {
- + int type;
- + int initialized;
- + int sockfd;
- + int listenfd;
- + void *id;
- + char mutex_rx[1];
- + char mutex_tx[1];
- +#ifdef DS_SEMAPHORE
- + sem_t *sem_rd;
- + sem_t *sem_wr;
- +#endif /*DS_SEMAPHORE*/
- +};
- +
- +#ifdef DS_SEMAPHORE
- +#ifdef __APPLE__
- + static void ALRMhandler(int sig) {
- + }
- + static int sem_twait(sem_t *sem, int t) {
- + int ret;
- + alarm(t);
- + ret = sem_wait(sem);
- + printf("twait completen");
- + return ret;
- + }
- + static void init_twait() {
- + sigset_t none;
- + struct sigaction sa;
- + sigemptyset(&none;);
- + sigprocmask(SIG_SETMASK, &none;, 0);
- +
- + sa.sa_handler = ALRMhandler;
- + sa.sa_flags = 0;
- + sigemptyset(&sa.sa;_mask);
- + sigaction(SIGALRM, &sa;, 0);
- + }
- +#else
- + static int sem_twait(sem_t *sem, int t) {
- + struct timespec ts;
- + clock_gettime(CLOCK_REALTIME, &ts;);
- + ts.tv_sec += t;
- + return(sem_timedwait(sem, &ts;));
- + }
- + static void init_twait() {}
- +#endif
- +#endif /*DS_SEMAPHORE */
- +
- +static int setblocking(int sock, int block)
- +{
- + unsigned long opts;
- +#ifndef __MINGW32__
- + opts = fcntl(sock,F_GETFL);
- + if (opts < 0) {
- + perror("fcntl(F_GETFL)");
- + exit(EXIT_FAILURE);
- + }
- + opts = block ? (opts & ~O_NONBLOCK)
- + : (opts | O_NONBLOCK);
- + if (fcntl(sock,F_SETFL,opts) < 0) {
- + perror("fcntl(F_SETFL)");
- + exit(EXIT_FAILURE);
- + }
- +#else
- + opts = !(block);
- + if ( ioctlsocket( sock, FIONBIO, &opts; ) == SOCKET_ERROR )
- + {
- + perror("ioctlsocket");
- + exit(EXIT_FAILURE);
- + }
- +#endif
- + return 0;
- +}
- +
- +static int timed_connect(int sockfd, const struct sockaddr *serv_addr,
- + socklen_t addrlen, int secs) {
- + //Socket should already be non-blocking
- + int res;
- + fd_set myset;
- + struct timeval tv;
- + int valopt;
- + socklen_t lon;
- +
- + // Trying to connect with timeout
- + res = connect(sockfd, serv_addr, addrlen);
- + if (res < 0 ) {
- + if (errno == DS_EINPROGRESS || errno == DS_EWOULDBLOCK || errno == 0) {
- + fprintf(stderr, "EINPROGRESS in connect() - selectingn");
- + do {
- + tv.tv_sec = secs;
- + tv.tv_usec = 0;
- + FD_ZERO(&myset;);
- + FD_SET(sockfd, &myset;);
- + res = select(sockfd+1, NULL, &myset;, &myset;, &tv;);
- + if (res < 0 && errno != EINTR) {
- + fprintf(stderr, "Error connecting (select) %d - %sn", errno, strerror(errno));
- + return -1;
- + }
- + else if (res > 0) {
- + // Socket selected for write
- + lon = sizeof(int);
- + if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)(&valopt;), &lon;) < 0) {
- + fprintf(stderr, "Error in getsockopt() %d - %sn", errno, strerror(errno));
- + return -1;
- + }
- + // Check the value returned...
- + if (valopt) {
- + fprintf(stderr, "Error in delayed connection() %d - %sn", valopt, strerror(valopt)
- +);
- + return -1;
- + }
- + break;
- + }
- + else {
- + fprintf(stderr, "Timeout in select() - Cancelling!n");
- + return -1;
- + }
- + } while (1);
- + }
- + else {
- + fprintf(stderr, "Error connecting (connect) %d - %sn", errno, strerror(errno));
- + return -1;
- + }
- + }
- + // I hope that is all
- + return 0;
- +}
- +static int timed_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int secs) {
- + //Socket should already be non-blocking
- + int res;
- + fd_set myset;
- + struct timeval tv;
- +
- + tv.tv_sec = secs;
- + tv.tv_usec = 0;
- + FD_ZERO(&myset;);
- + FD_SET(sockfd, &myset;);
- + res = select(sockfd+1, &myset;, NULL, NULL, &tv;);
- + if (res < 0 && errno != EINTR) {
- + fprintf(stderr, "Error accepting %d - %sn", errno, strerror(errno));
- + return -1;
- + }
- + else if (res > 0) {
- + // Socket selected for read
- + return accept(sockfd, NULL, NULL);
- + }
- + errno = DS_ETIMEDOUT;
- + return -1;
- +}
- +static int timed_recv(int sockfd, void *buf, size_t len, int flags, int secs) {
- + //Socket should already be non-blocking
- + int res;
- + fd_set myset;
- + struct timeval tv;
- +
- + tv.tv_sec = secs;
- + tv.tv_usec = 0;
- + FD_ZERO(&myset;);
- + FD_SET(sockfd, &myset;);
- + res = select(sockfd+1, &myset;, NULL, NULL, &tv;);
- + if (res < 0 && errno != EINTR) {
- + fprintf(stderr, "Error accepting %d - %sn", errno, strerror(errno));
- + return -1;
- + }
- + else if (res > 0) {
- + // Socket selected for read
- + return recv(sockfd, buf, len, flags);
- + }
- + errno = DS_ETIMEDOUT;
- + return -1;
- +}
- +
- +static int timed_sockinit(int *port, int is_server)
- +{
- + int sockfd; // listen on sock_fd
- + struct sockaddr_in my_addr;
- + socklen_t peer_addr_size = sizeof(struct sockaddr_in);
- + int yes=1;
- +
- +#ifdef __MINGW32__
- + WSADATA wsaData;
- + if(WSAStartup(MAKEWORD(2, 2), &wsaData;) !=0) {
- + printf("WSAStartup failedn");
- + exit(1);
- + }
- +#endif
- +
- + memset(&my;_addr, 0, sizeof(my_addr));
- + my_addr.sin_family = AF_INET;
- + my_addr.sin_addr.s_addr=INADDR_ANY;
- + my_addr.sin_port = *port;
- + if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
- + perror("server: socket");
- + exit(1);
- + }
- +
- + setblocking(sockfd, 0);
- + if (is_server) {
- + if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&yes;,
- + sizeof(int)) == -1) {
- + perror("setsockopt");
- + exit(1);
- + }
- +
- + if (bind(sockfd, (struct sockaddr *) &my;_addr, sizeof(struct sockaddr_in)) == -1) {
- + close(sockfd);
- + perror("server: bind");
- + exit(1);
- + }
- + if (listen(sockfd, 1) == -1) {
- + perror("listen");
- + exit(1);
- + }
- + if (getsockname(sockfd, (struct sockaddr *)&my;_addr, &peer;_addr_size) == -1) {
- + perror("getsockname");
- + exit(1);
- + }
- + if(my_addr.sin_port == 0) {
- + printf("Failed to get portn");
- + exit(1);
- + }
- + *port = my_addr.sin_port;
- + } else {
- + if (timed_connect(sockfd, (struct sockaddr *) &my;_addr, sizeof(struct sockaddr_in), 10) == -1)
- + {
- + close(sockfd);
- + perror("client: connect");
- + exit(1);
- + }
- + }
- +
- + return sockfd;
- +}
- +
- +int timed_semwait(void *_sem, int secs) {
- + struct sem *sem = (struct sem *)_sem;
- + int ok = -1;
- + if(sem->type == DS_SOCKET) {
- + if(! sem->initialized) {
- + ok = timed_accept(sem->sockfd, NULL, NULL, secs);
- + if(ok != -1) {
- + sem->listenfd = sem->sockfd;
- + sem->sockfd = ok;
- + ok = 1;
- + sem->initialized = 1;
- + }
- + } else {
- + ok = (timed_recv(sem->sockfd, sem->mutex_rx, 1, 0, secs) == 1);
- + }
- + }
- +#ifdef DS_SEMAPHORE
- + else if(sem->type == DS_SEMAPHORE) {
- + ok = (sem_twait(sem->sem_rd, secs) == 0);
- + if(! sem->initialized) {
- + timed_semclean(sem);
- + sem->initialized = 1;
- + }
- + }
- +#endif
- + if(!ok && errno == DS_ETIMEDOUT) {
- + ok = DS_TIMEOUT;
- + }
- + return ok;
- +}
- +
- +void timed_sempost(void *_sem) {
- + struct sem *sem = (struct sem *)_sem;
- + if(sem->type == DS_SOCKET) {
- + send(sem->sockfd, sem->mutex_tx, 1, 0);
- + }
- +#ifdef DS_SEMAPHORE
- + else if(sem->type == DS_SEMAPHORE) {
- + sem_post(sem->sem_wr);
- + }
- +#endif
- +}
- +
- +void timed_semclean(void * _sem) {
- +#ifdef DS_SEMAPHORE
- + struct sem *sem = (struct sem *) _sem;
- + if(sem->type == DS_SEMAPHORE) {
- + char sem1[80], sem2[80];
- + snprintf(sem1, 80, "/dshow_sem1.%s", (char *)sem->id);
- + snprintf(sem2, 80, "/dshow_sem2.%s", (char *)sem->id);
- + sem_unlink(sem1);
- + sem_unlink(sem2);
- + }
- +#endif
- +}
- +
- +void *timed_seminit(unsigned int semtype, void *id, int is_host) {
- + struct sem *sem;
- + sem = (struct sem *)malloc(sizeof(struct sem));
- + memset(sem, 0, sizeof(struct sem));
- + sem->type = semtype;
- + sem->id = id;
- + sem->initialized = !(is_host);
- + if(semtype == DS_SOCKET) {
- + sem->listenfd = -1;
- + sem->sockfd = timed_sockinit((int *)id, is_host);
- + if(sem->sockfd == -1) {
- + perror("sock_init");
- + exit(1);
- + }
- + }
- +#ifdef DS_SEMAPHORE
- + else if(semtype == DS_SEMAPHORE) {
- + char semrd[80], semwr[80];
- + init_twait();
- + snprintf(semrd, 80, "/dshow_sem%d.%s", is_host ? 2 : 1, (char *)id);
- + snprintf(semwr, 80, "/dshow_sem%d.%s", is_host ? 1 : 2, (char *)id);
- + if(is_host) {
- + sem->sem_rd = sem_open(semrd, O_CREAT, 0644, 0);
- + sem->sem_wr = sem_open(semwr, O_CREAT, 0644, 0);
- + } else {
- + sem->sem_rd = sem_open(semrd, 0);
- + sem->sem_wr = sem_open(semwr, 0);
- + sem_unlink(semwr);
- + sem_unlink(semrd);
- + }
- + if(sem->sem_rd == SEM_FAILED) {
- + timed_semclean(sem);
- + perror("sem_open(1)");
- + exit(1);
- + }
- + if(sem->sem_wr == SEM_FAILED) {
- + timed_semclean(sem);
- + perror("sem_open(2)");
- + exit(1);
- + }
- + //tell calling procedure that we are awake;
- + if(! is_host) {
- + sem_post(sem->sem_wr);
- + }
- + }
- +#endif /*DS_SEMAPHORE*/
- + else {
- + fprintf(stderr, "Unknown type specified: %dn", semtype);
- + exit(1);
- + }
- + return sem;
- +}
- +
- +void timed_semdelete(void *_sem) {
- + struct sem *sem = (struct sem *) _sem;
- + if(sem->type == DS_SOCKET) {
- + close(sem->sockfd);
- + if(sem->listenfd != -1)
- + close(sem->listenfd);
- +#ifdef DS_SEMAPHORE
- + } else if(sem->type == DS_SEMAPHORE) {
- + if(! sem->initialized)
- + timed_semclean(sem);
- + sem_close(sem->sem_wr);
- + sem_close(sem->sem_rd);
- +#endif
- + }
- + free(sem);
- +}
- +
- Index: libmpcodecs/timeout_sem.h
- ===================================================================
- --- /dev/null 1970-01-01 00:00:00.000000000 +0000
- +++ libmpcodecs/timeout_sem.h 2010-03-12 07:48:02.000000000 -0800
- @@ -0,0 +1,10 @@
- +#define DS_SOCKET 0x01
- +#define DS_SEMAPHORE 0x02
- +
- +#define DS_TIMEOUT -1
- +
- +void *timed_seminit(unsigned int semtype, void *id, int is_host);
- +void timed_semclean(void *_sem);
- +void timed_sempost(void *_sem);
- +int timed_semwait(void *_sem, int secs);
- +void timed_semdelete(void *_sem);
主要是makefile的第二个trunk的改动。
其他的按照google project上的wiki安装就行了。但是,毕竟软件上的提升效果有限,小本子如果cpu实在太差,这种硬件上的短板还是无法依靠软件来解决。所以我的小本子还是放不了很大的视频文件。