xjpvictor's Blog
小老鼠,上灯台,两只耳朵竖起来

linux coreavc


各种折腾·archlinuxlinux

本文发表于超过180天以前,部分内容可能已经失效

上网本的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实在太差,这种硬件上的短板还是无法依靠软件来解决。所以我的小本子还是放不了很大的视频文件。

本文 "linux coreavc" 由 K. Huang 首先发表于 xjpvictor's Blog 并以 CC BY-NC 4.0 许可证发布 © 2011
转载注明引用来源 https://blog.xjpvictor.info/2011/05/linux-coreavc/

赞助我

评论

你的邮箱地址不会被公开。必填项以 * 标出

无意义或不相关评论将被删除

取消 上传图片 或拖拽上传

* Some files will not be uploaded. Only png, gif, jpg are allowed and maximum 10 images, each file less than 10M.

你可以添加 10 个 png/gif/jpg 图片 (每个文件小于 10M)

允许使用以下html标签:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

你可以上传文件,粘贴代码或长文至 Drop.it.r

更多相似文章