Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Reaper

By: a guest on Nov 9th, 2010  |  syntax: None  |  size: 22.04 KB  |  views: 133  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. Index: libmpcodecs/vd.c
  2. ===================================================================
  3. --- libmpcodecs/vd.c.orig       2010-03-12 07:47:10.000000000 -0800
  4. +++ libmpcodecs/vd.c    2010-03-12 07:48:02.000000000 -0800
  5. @@ -43,6 +43,7 @@
  6.  extern const vd_functions_t mpcodecs_vd_ffmpeg;
  7.  extern const vd_functions_t mpcodecs_vd_theora;
  8.  extern const vd_functions_t mpcodecs_vd_dshow;
  9. +extern const vd_functions_t mpcodecs_vd_dshowserver;
  10.  extern const vd_functions_t mpcodecs_vd_dmo;
  11.  extern const vd_functions_t mpcodecs_vd_vfw;
  12.  extern const vd_functions_t mpcodecs_vd_vfwex;
  13. @@ -74,6 +75,7 @@
  14.  #ifdef CONFIG_OGGTHEORA
  15.         &mpcodecs_vd_theora,
  16.  #endif
  17. +        &mpcodecs_vd_dshowserver,
  18.  #ifdef CONFIG_WIN32DLL
  19.          &mpcodecs_vd_dshow,
  20.          &mpcodecs_vd_dmo,
  21. Index: Makefile
  22. ===================================================================
  23. --- Makefile.orig       2010-03-12 07:47:19.000000000 -0800
  24. +++ Makefile    2010-03-12 07:48:02.000000000 -0800
  25. @@ -20,6 +20,7 @@
  26.  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  27.  
  28.  include config.mak
  29. +EXTRALIBS += -lrt
  30.  
  31.  .SUFFIXES:
  32.  
  33. @@ -515,6 +516,7 @@
  34.                stream/stream_mf.c \
  35.                stream/stream_null.c \
  36.                stream/url.c \
  37. +              libmpcodecs/vd_dshowserver.c \
  38.                sub/eosd.c \
  39.                sub/find_sub.c \
  40.                sub/osd.c \
  41. @@ -904,6 +906,7 @@
  42.  libdvdread4/%: CFLAGS := -Ilibdvdread4 -D_GNU_SOURCE $(CFLAGS_LIBDVDCSS_DVDREAD) $(CFLAGS)
  43.  libfaad2/%:    CFLAGS := -Ilibfaad2 -DHAVE_CONFIG_H $(CFLAGS_FAAD_FIXED) $(CFLAGS)
  44.  
  45. +libmpcodecs/%: CFLAGS := $(CFLAGS) -g -O0
  46.  loader/%: CFLAGS += -fno-omit-frame-pointer $(CFLAGS_NO_OMIT_LEAF_FRAME_POINTER)
  47.  #loader/%: CFLAGS += -Ddbg_printf=__vprintf -DTRACE=__vprintf -DDETAILED_OUT
  48.  loader/win32%: CFLAGS += $(CFLAGS_STACKREALIGN)
  49. Index: libmpcodecs/vd_dshowserver.c
  50. ===================================================================
  51. --- /dev/null   1970-01-01 00:00:00.000000000 +0000
  52. +++ libmpcodecs/vd_dshowserver.c        2010-03-12 07:56:33.000000000 -0800
  53. @@ -0,0 +1,295 @@
  54. +/*
  55. + * Copyright Alan Nisota 2006 - 2010
  56. + * To use this code, make sureyour codecs.conf file has been updated with this section:
  57. + * videocodec coreserve
  58. + *  info "CoreAVC DShowServer"
  59. + *  status untested
  60. + *  format 0x10000005
  61. + *  fourcc H264,h264
  62. + *  fourcc X264,x264
  63. + *  fourcc avc1,AVC1 AVC1
  64. + *  fourcc davc,DAVC
  65. + *  fourcc VSSH
  66. + *  driver dshowserver
  67. + *  dll "CoreAVCDecoder.ax"
  68. + *  guid 0x09571a4b, 0xf1fe, 0x4c60, 0x97, 0x60, 0xde, 0x6d, 0x31, 0x0c, 0x7c, 0x31
  69. + *  out YV12,IYUV,I420,YUY2
  70. + *
  71. + * Codec is very sensitive to the fourcc value.  As of 2009-08-30, mplayer incorrectly reports
  72. + * AVC1 as H264 when using lavf decoder, resulting in breakage.
  73. + * this can be corrected by using an alternate demuxer (-demuxer mov for example)
  74. + * or by adding this to the above file:
  75. + *  fourcc H264,h264 AVC1
  76. + * though that may break regular h264 playback
  77. + */
  78. +
  79. +#include <stdio.h>
  80. +#include <stdlib.h>
  81. +#include <stdarg.h>
  82. +#include <sys/mman.h>
  83. +#include <pthread.h>
  84. +
  85. +#include <sys/types.h>
  86. +#include <unistd.h>
  87. +#include <sys/stat.h>
  88. +#include <fcntl.h>
  89. +#include <time.h>
  90. +#include <sys/wait.h>
  91. +
  92. +#include "config.h"
  93. +
  94. +#include "mp_msg.h"
  95. +
  96. +#include "vd_internal.h"
  97. +
  98. +struct vd_struct {
  99. +  union {
  100. +    uint32_t ret;
  101. +    uint32_t cmd;
  102. +  };
  103. +  uint32_t buflen;
  104. +  uint64_t pts;
  105. +  uint32_t unused[8];
  106. +} __attribute__((__packed__));
  107. +
  108. +enum {
  109. +  VD_END = 1,
  110. +  VD_DECODE = 2,
  111. +  VD_SEEK = 3,
  112. +  VD_HAS_BIH = 0x10000,
  113. +  VD_VERSION_MASK = 0xFFFF,
  114. +};
  115. +#include "timeout_sem.c"
  116. +
  117. +static vd_info_t info = {
  118. +       "DirectShowServer video codecs",
  119. +       "dshowserver",
  120. +       "Alan Nisota",
  121. +       "based on dshow",
  122. +       "win32 codecs"
  123. +};
  124. +
  125. +LIBVD_EXTERN(dshowserver)
  126. +typedef struct {
  127. +    int fd;
  128. +    void *mem;
  129. +    char *data;
  130. +    char *picture;
  131. +    int picsize;
  132. +    int pagesize;
  133. +    void *sem;
  134. +    struct vd_struct *vd;
  135. +} ds_mpi_t;
  136. +static ds_mpi_t *ds_mpi;
  137. +
  138. +// to set/get/query special features/parameters
  139. +static int control(sh_video_t *sh __attribute((unused)),int cmd,void* arg __attribute((unused)),...){
  140. +    switch(cmd){
  141. +    case VDCTRL_RESYNC_STREAM:
  142. +      printf("Seek now\n");
  143. +      ds_mpi->vd->cmd = VD_SEEK; //'3' is cmd for seek
  144. +      timed_sempost(ds_mpi->sem);
  145. +      timed_semwait(ds_mpi->sem, 10);
  146. +      return CONTROL_TRUE;
  147. +    case VDCTRL_QUERY_MAX_PP_LEVEL:
  148. +       return 4;
  149. +    case VDCTRL_QUERY_UNSEEN_FRAMES:
  150. +       return 10;
  151. +
  152. +    }
  153. +    return CONTROL_UNKNOWN;
  154. +}
  155. +
  156. +static int my_system(const char *command)
  157. +{
  158. +    pid_t child = fork();
  159. +
  160. +    if (child < 0)
  161. +    {
  162. +        /* Fork failed */
  163. +        return child;
  164. +    }
  165. +    else if (child == 0)
  166. +    {
  167. +        /* Child */
  168. +        int i;
  169. +        /* Close all open file descriptors except stdout/stderr */
  170. +        for (i = sysconf(_SC_OPEN_MAX) - 1; i > 2; i--)
  171. +            close(i);
  172. +
  173. +        /* Attach stdin to /dev/null */
  174. +        /*
  175. +        close(0);
  176. +        int fd = open("/dev/null", O_RDONLY);
  177. +        dup2(fd, 0);
  178. +        if (fd != 0)
  179. +            close(fd);
  180. +        */
  181. +        /* Run command */
  182. +        execl("/bin/sh", "sh", "-c", command, NULL);
  183. +        _exit(0);
  184. +    }
  185. +    else
  186. +    {
  187. +        /* Parent */
  188. +        int status;
  189. +
  190. +        waitpid(child, &status, 0);
  191. +        return status;
  192. +    }
  193. +
  194. +    return 1;
  195. +}
  196. +
  197. +// init driver
  198. +static int init(sh_video_t *sh){
  199. +    int ret;
  200. +    char cmd[255], shm[80], id[80];
  201. +    uint32_t out_fmt;
  202. +    int bpp, w, h;
  203. +    int extra = 0;
  204. +    int numpages = 10;
  205. +    int port = 0;
  206. +    int memsize;
  207. +
  208. +    init_twait();
  209. +    w = sh->disp_w; h = sh->disp_h;
  210. +    if(!mpcodecs_config_vo(sh,w,h,IMGFMT_YUY2)) return 0;
  211. +    out_fmt = sh->codec->outfmt[sh->outfmtidx];
  212. +    switch(out_fmt){
  213. +      case IMGFMT_YUY2:
  214. +      case IMGFMT_UYVY:
  215. +       bpp = 16; break;
  216. +      case IMGFMT_YV12:
  217. +      case IMGFMT_I420:
  218. +      case IMGFMT_IYUV:
  219. +       bpp = 12; break;
  220. +      case IMGFMT_YVU9:
  221. +        bpp = 9; break;
  222. +      default:
  223. +        bpp = 24; break;
  224. +    }
  225. +    sprintf(id, "%x", *(int *)pthread_self());
  226. +    snprintf(shm, 80, "/dshow_shm.%s", id);
  227. +
  228. +    ds_mpi = (ds_mpi_t *) malloc(sizeof(ds_mpi_t));
  229. +    ds_mpi->fd = shm_open(shm, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
  230. +    ds_mpi->picsize =  w * h * bpp / 8;
  231. +    ds_mpi->pagesize = ds_mpi->picsize + 1024;
  232. +    memsize = sizeof(struct vd_struct) + w * h + ds_mpi->picsize + extra + ds_mpi->pagesize * numpages;
  233. +    ftruncate(ds_mpi->fd, memsize);
  234. +    ds_mpi->mem = mmap(NULL, memsize, PROT_READ | PROT_WRITE, MAP_SHARED, ds_mpi->fd, 0);
  235. +    if(ds_mpi->mem == MAP_FAILED) {
  236. +      perror("mmap");
  237. +      return 0;
  238. +    }
  239. +    memset((char *)ds_mpi->mem, 0, sizeof(struct vd_struct));
  240. +    if (extra)
  241. +      memset((char *)ds_mpi->mem + (memsize - extra), 0, extra);
  242. +    ds_mpi->vd = (struct vd_struct *)ds_mpi->mem;
  243. +    ds_mpi->data = ((char *)ds_mpi->mem) + sizeof(struct vd_struct);
  244. +    ds_mpi->picture = ds_mpi->data + w * h;
  245. +    if(sh->bih->biWidth && sh->bih->biHeight) {
  246. +      ds_mpi->vd->cmd |= VD_HAS_BIH; //Use embedded bih
  247. +      memcpy(ds_mpi->data, sh->bih, sh->bih->biSize);
  248. +    }
  249. +
  250. +    ds_mpi->sem = timed_seminit(DS_SOCKET, &port, 1);
  251. +    //ds_mpi->sem = timed_seminit(DS_SEMAPHORE, id, 1);
  252. +
  253. +    snprintf(cmd, 255, "dshowserver --codec %s --size %dx%d "
  254. +             "--guid %08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x "
  255. +             "--fourc 0x%08x --bits %d --outfmt 0x%08x --pid %d --id %s "
  256. +             "--numpages %d --port %d %s&",
  257. +             sh->codec->dll, w, h,
  258. +             (unsigned int)sh->codec->guid.f1, sh->codec->guid.f2, sh->codec->guid.f3,
  259. +             sh->codec->guid.f4[0], sh->codec->guid.f4[1], sh->codec->guid.f4[2], sh->codec->guid.f4[3],
  260. +             sh->codec->guid.f4[4], sh->codec->guid.f4[5], sh->codec->guid.f4[6], sh->codec->guid.f4[7],
  261. +             (unsigned int)sh->format, bpp, out_fmt, getpid(), id, numpages, port, "");
  262. +    printf("%s\n", cmd);
  263. +    my_system(cmd);
  264. +    ret = timed_semwait(ds_mpi->sem, 10);
  265. +    shm_unlink(shm);
  266. +    if(ret <= 0) {
  267. +      printf("DirectShow filter failed");
  268. +      return 0;
  269. +    } else {
  270. +      printf("Found DirectShow filter");
  271. +      return 1;
  272. +    }
  273. +}
  274. +
  275. +// uninit driver
  276. +static void uninit(sh_video_t *sh __attribute((unused))){
  277. +    if(ds_mpi) {
  278. +      printf("Destroying filter");
  279. +      ds_mpi->vd->cmd = VD_END; //'1' is cmd for terminating
  280. +      timed_sempost(ds_mpi->sem);
  281. +      close(ds_mpi->fd);
  282. +      timed_semdelete(ds_mpi->sem);
  283. +      free(ds_mpi);
  284. +      ds_mpi = NULL;
  285. +    }
  286. +}
  287. +
  288. +//mp_image_t* mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag, int w, int h);
  289. +
  290. +// decode a frame
  291. +static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){
  292. +   mp_image_t* mpi = NULL;
  293. +   int ret;
  294. +   unsigned char *t;
  295. +
  296. +   if(len<=0) return NULL; // skipped frame
  297. +
  298. +   ds_mpi->vd->cmd = VD_DECODE; //'2' is cmd for decoding
  299. +   ds_mpi->vd->pts = (uint64_t)(1E9* (sh->num_buffered_pts ? sh->buffered_pts[0] : sh->pts));
  300. +   memcpy(ds_mpi->data, data, len);
  301. +   if (0) {
  302. +      static int count = 0;
  303. +      char f[80];
  304. +      FILE *fh;
  305. +
  306. +      if(count == 100)
  307. +          exit(1);
  308. +      sprintf(f, "/tmp/mplayer.%d", count++);
  309. +      fh = fopen(f, "w+");
  310. +      fwrite(data, len, 1, fh);
  311. +      fclose(fh);
  312. +   }
  313. +   ds_mpi->vd->buflen = len;
  314. +   timed_sempost(ds_mpi->sem);
  315. +   ret = timed_semwait(ds_mpi->sem, 10);
  316. +   if(flags&3) {
  317. +      // framedrop:
  318. +      return NULL;
  319. +   }
  320. +   //printf("len: %d, PTS (ret:%d,vd_ret:%d): %f -> %f\n", len, ret, ds_mpi->vd->ret, sh->buffered_pts[0], (double)ds_mpi->vd->pts/1E9);
  321. +   //printf("PTS (%d): %f(%d) -> %d\n", ds_mpi->vd->ret, sh->buffered_pts[0], pts-1, ds_mpi->vd->pts);
  322. +   if(ret == 1 && ds_mpi->vd->ret && ! (ds_mpi->vd->ret & (1<<31))) {
  323. +     if(ds_mpi->vd->pts)
  324. +       sh->buffered_pts[0] = (double)ds_mpi->vd->pts/1E9;
  325. +       mpi=mpcodecs_get_image(sh, MP_IMGTYPE_EXPORT, MP_IMGFLAG_COMMON_PLANE|MP_IMGFLAG_COMMON_STRIDE,
  326. +                            sh->disp_w, sh->disp_h);
  327. +     if(ds_mpi->vd->ret & 0x02) {
  328. +       unsigned char page = ds_mpi->vd->ret >> 8;
  329. +       mpi->planes[0]=ds_mpi->picture + ds_mpi->picsize + page * ds_mpi->pagesize;
  330. +     } else {
  331. +       mpi->planes[0]=ds_mpi->picture;
  332. +     }
  333. +     if (mpi->flags&MP_IMGFLAG_PLANAR) {
  334. +       mpi->stride[0] = mpi->width;
  335. +       mpi->stride[1] = mpi->stride[2] = mpi->width >> mpi->chroma_x_shift;
  336. +       mpi->planes[2] = mpi->planes[0] + mpi->stride[0] * mpi->height;
  337. +       mpi->planes[1] = mpi->planes[2] + (mpi->width >> mpi->chroma_x_shift) * (mpi->height >> mpi->chroma_y_shift);
  338. +       if (mpi->flags&MP_IMGFLAG_SWAPPED) {
  339. +         t = mpi->planes[1];
  340. +         mpi->planes[1] = mpi->planes[2];
  341. +         mpi->planes[2] = t;
  342. +       }
  343. +     } else {
  344. +       mpi->stride[0]=mpi->bpp*mpi->width/8;
  345. +     }
  346. +   }
  347. +   return mpi;
  348. +}
  349. Index: libmpcodecs/timeout_sem.c
  350. ===================================================================
  351. --- /dev/null   1970-01-01 00:00:00.000000000 +0000
  352. +++ libmpcodecs/timeout_sem.c   2010-03-12 08:03:16.000000000 -0800
  353. @@ -0,0 +1,397 @@
  354. +#include <stdio.h>
  355. +#include <stdlib.h>
  356. +#include <unistd.h>
  357. +#include <fcntl.h>
  358. +#include <errno.h>
  359. +#include <string.h>
  360. +
  361. +#ifndef __MINGW32__
  362. +  #include <netdb.h>
  363. +  #include <netinet/in.h>
  364. +  #include <sys/socket.h>
  365. +  #include <arpa/inet.h>
  366. +  #include <sys/wait.h>
  367. +
  368. +  #define DS_EINPROGRESS EINPROGRESS
  369. +  #define DS_ETIMEDOUT   ETIMEDOUT
  370. +  #define DS_EWOULDBLOCK EWOULDBLOCK
  371. +#else
  372. +  #define _WIN32_WINNT 0x0501
  373. +  #include <windows.h>
  374. +  #include <winsock2.h>
  375. +  #include <ws2tcpip.h>
  376. +
  377. +  #define DS_EINPROGRESS WSAEINPROGRESS
  378. +  #define DS_ETIMEDOUT   WSAETIMEDOUT
  379. +  #define DS_EWOULDBLOCK WSAEWOULDBLOCK
  380. +#endif
  381. +
  382. +#include "timeout_sem.h"
  383. +#ifdef __MINGW32__
  384. +  #undef DS_SEMAPHORE
  385. +#endif
  386. +
  387. +#ifdef DS_SEMAPHORE
  388. +#include <time.h>
  389. +#include <semaphore.h>
  390. +#endif
  391. +
  392. +struct sem {
  393. +  int type;
  394. +  int initialized;
  395. +  int sockfd;
  396. +  int listenfd;
  397. +  void *id;
  398. +  char mutex_rx[1];
  399. +  char mutex_tx[1];
  400. +#ifdef DS_SEMAPHORE
  401. +  sem_t *sem_rd;
  402. +  sem_t *sem_wr;
  403. +#endif /*DS_SEMAPHORE*/
  404. +};
  405. +
  406. +#ifdef DS_SEMAPHORE
  407. +#ifdef __APPLE__
  408. +  static void ALRMhandler(int sig) {
  409. +  }
  410. +  static int sem_twait(sem_t *sem, int t) {
  411. +    int ret;
  412. +    alarm(t);
  413. +    ret = sem_wait(sem);
  414. +    printf("twait complete\n");
  415. +    return ret;
  416. +  }
  417. +  static void init_twait() {
  418. +    sigset_t none;
  419. +    struct sigaction sa;
  420. +    sigemptyset(&none);
  421. +    sigprocmask(SIG_SETMASK, &none, 0);
  422. +
  423. +    sa.sa_handler = ALRMhandler;
  424. +    sa.sa_flags = 0;
  425. +    sigemptyset(&sa.sa_mask);
  426. +    sigaction(SIGALRM, &sa, 0);
  427. +  }
  428. +#else
  429. +  static int sem_twait(sem_t *sem, int t) {
  430. +    struct timespec ts;
  431. +    clock_gettime(CLOCK_REALTIME, &ts);
  432. +    ts.tv_sec += t;
  433. +    return(sem_timedwait(sem, &ts));
  434. +  }
  435. +  static void init_twait() {}
  436. +#endif
  437. +#endif /*DS_SEMAPHORE */
  438. +
  439. +static int setblocking(int sock, int block)
  440. +{
  441. +       unsigned long opts;
  442. +#ifndef __MINGW32__
  443. +       opts = fcntl(sock,F_GETFL);
  444. +       if (opts < 0) {
  445. +               perror("fcntl(F_GETFL)");
  446. +               exit(EXIT_FAILURE);
  447. +       }
  448. +       opts = block ? (opts & ~O_NONBLOCK)
  449. +                     : (opts | O_NONBLOCK);
  450. +       if (fcntl(sock,F_SETFL,opts) < 0) {
  451. +               perror("fcntl(F_SETFL)");
  452. +               exit(EXIT_FAILURE);
  453. +       }
  454. +#else
  455. +       opts = !(block);
  456. +       if ( ioctlsocket( sock, FIONBIO, &opts ) == SOCKET_ERROR )
  457. +       {
  458. +               perror("ioctlsocket");
  459. +               exit(EXIT_FAILURE);
  460. +       }
  461. +#endif
  462. +       return 0;
  463. +}
  464. +
  465. +static int timed_connect(int sockfd, const struct sockaddr *serv_addr,
  466. +                   socklen_t addrlen, int secs) {
  467. +  //Socket should already be non-blocking
  468. +  int res;
  469. +  fd_set myset;
  470. +  struct timeval tv;
  471. +  int valopt;
  472. +  socklen_t lon;
  473. +
  474. +  // Trying to connect with timeout
  475. +  res = connect(sockfd, serv_addr, addrlen);
  476. +  if (res < 0 ) {
  477. +     if (errno == DS_EINPROGRESS || errno == DS_EWOULDBLOCK || errno == 0) {
  478. +        fprintf(stderr, "EINPROGRESS in connect() - selecting\n");
  479. +        do {
  480. +           tv.tv_sec = secs;
  481. +           tv.tv_usec = 0;
  482. +           FD_ZERO(&myset);
  483. +           FD_SET(sockfd, &myset);
  484. +           res = select(sockfd+1, NULL, &myset, &myset, &tv);
  485. +           if (res < 0 && errno != EINTR) {
  486. +              fprintf(stderr, "Error connecting (select) %d - %s\n", errno, strerror(errno));
  487. +              return -1;
  488. +           }
  489. +           else if (res > 0) {
  490. +              // Socket selected for write
  491. +              lon = sizeof(int);
  492. +              if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon) < 0) {
  493. +                 fprintf(stderr, "Error in getsockopt() %d - %s\n", errno, strerror(errno));
  494. +                 return -1;
  495. +              }
  496. +              // Check the value returned...
  497. +              if (valopt) {
  498. +                 fprintf(stderr, "Error in delayed connection() %d - %s\n", valopt, strerror(valopt)
  499. +);
  500. +                 return -1;
  501. +              }
  502. +              break;
  503. +           }
  504. +           else {
  505. +              fprintf(stderr, "Timeout in select() - Cancelling!\n");
  506. +              return -1;
  507. +           }
  508. +        } while (1);
  509. +     }
  510. +     else {
  511. +        fprintf(stderr, "Error connecting (connect) %d - %s\n", errno, strerror(errno));
  512. +        return -1;
  513. +     }
  514. +  }
  515. +  // I hope that is all
  516. +  return 0;
  517. +}
  518. +static int timed_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int secs) {
  519. +  //Socket should already be non-blocking
  520. +  int res;
  521. +  fd_set myset;
  522. +  struct timeval tv;
  523. +
  524. +  tv.tv_sec = secs;
  525. +  tv.tv_usec = 0;
  526. +  FD_ZERO(&myset);
  527. +  FD_SET(sockfd, &myset);
  528. +  res = select(sockfd+1, &myset, NULL, NULL, &tv);
  529. +  if (res < 0 && errno != EINTR) {
  530. +    fprintf(stderr, "Error accepting %d - %s\n", errno, strerror(errno));
  531. +    return -1;
  532. +  }
  533. +  else if (res > 0) {
  534. +    // Socket selected for read
  535. +    return accept(sockfd, NULL, NULL);
  536. +  }
  537. +  errno = DS_ETIMEDOUT;
  538. +  return -1;
  539. +}
  540. +static int timed_recv(int sockfd, void *buf, size_t len, int flags, int secs) {
  541. +  //Socket should already be non-blocking
  542. +  int res;
  543. +  fd_set myset;
  544. +  struct timeval tv;
  545. +
  546. +  tv.tv_sec = secs;
  547. +  tv.tv_usec = 0;
  548. +  FD_ZERO(&myset);
  549. +  FD_SET(sockfd, &myset);
  550. +  res = select(sockfd+1, &myset, NULL, NULL, &tv);
  551. +  if (res < 0 && errno != EINTR) {
  552. +    fprintf(stderr, "Error accepting %d - %s\n", errno, strerror(errno));
  553. +    return -1;
  554. +  }
  555. +  else if (res > 0) {
  556. +    // Socket selected for read
  557. +    return recv(sockfd, buf, len, flags);
  558. +  }
  559. +  errno = DS_ETIMEDOUT;
  560. +  return -1;
  561. +}
  562. +
  563. +static int timed_sockinit(int *port, int is_server)
  564. +{
  565. +    int sockfd;  // listen on sock_fd
  566. +    struct sockaddr_in my_addr;
  567. +    socklen_t peer_addr_size = sizeof(struct sockaddr_in);
  568. +    int yes=1;
  569. +
  570. +#ifdef __MINGW32__
  571. +    WSADATA wsaData;
  572. +    if(WSAStartup(MAKEWORD(2, 2), &wsaData) !=0) {
  573. +      printf("WSAStartup failed\n");
  574. +      exit(1);
  575. +    }
  576. +#endif
  577. +
  578. +    memset(&my_addr, 0, sizeof(my_addr));
  579. +    my_addr.sin_family = AF_INET;
  580. +    my_addr.sin_addr.s_addr=INADDR_ANY;
  581. +    my_addr.sin_port = *port;
  582. +    if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
  583. +            perror("server: socket");
  584. +            exit(1);
  585. +    }
  586. +
  587. +    setblocking(sockfd, 0);
  588. +    if (is_server) {
  589. +      if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&yes,
  590. +              sizeof(int)) == -1) {
  591. +        perror("setsockopt");
  592. +        exit(1);
  593. +      }
  594. +
  595. +      if (bind(sockfd, (struct sockaddr *) &my_addr,  sizeof(struct sockaddr_in)) == -1) {
  596. +              close(sockfd);
  597. +              perror("server: bind");
  598. +              exit(1);
  599. +      }
  600. +      if (listen(sockfd, 1) == -1) {
  601. +        perror("listen");
  602. +        exit(1);
  603. +      }
  604. +      if (getsockname(sockfd, (struct sockaddr *)&my_addr, &peer_addr_size) == -1) {
  605. +        perror("getsockname");
  606. +        exit(1);
  607. +      }
  608. +      if(my_addr.sin_port == 0) {
  609. +        printf("Failed to get port\n");
  610. +        exit(1);
  611. +      }
  612. +      *port = my_addr.sin_port;
  613. +    } else {
  614. +      if (timed_connect(sockfd, (struct sockaddr *) &my_addr,  sizeof(struct sockaddr_in), 10) == -1)
  615. +      {
  616. +        close(sockfd);
  617. +        perror("client: connect");
  618. +        exit(1);
  619. +      }
  620. +    }
  621. +
  622. +    return sockfd;
  623. +}
  624. +
  625. +int timed_semwait(void *_sem, int secs) {
  626. +  struct sem *sem = (struct sem *)_sem;
  627. +  int ok = -1;
  628. +  if(sem->type == DS_SOCKET) {
  629. +    if(! sem->initialized) {
  630. +      ok = timed_accept(sem->sockfd, NULL, NULL, secs);
  631. +      if(ok != -1) {
  632. +        sem->listenfd = sem->sockfd;
  633. +        sem->sockfd = ok;
  634. +        ok = 1;
  635. +        sem->initialized = 1;
  636. +      }
  637. +    } else {
  638. +      ok = (timed_recv(sem->sockfd, sem->mutex_rx, 1, 0, secs) == 1);
  639. +    }
  640. +  }
  641. +#ifdef DS_SEMAPHORE
  642. +  else if(sem->type == DS_SEMAPHORE) {
  643. +    ok = (sem_twait(sem->sem_rd, secs) == 0);
  644. +    if(! sem->initialized) {
  645. +      timed_semclean(sem);
  646. +      sem->initialized = 1;
  647. +    }
  648. +  }
  649. +#endif
  650. +  if(!ok && errno == DS_ETIMEDOUT) {
  651. +    ok = DS_TIMEOUT;
  652. +  }
  653. +  return ok;
  654. +}
  655. +
  656. +void timed_sempost(void *_sem) {
  657. +  struct sem *sem = (struct sem *)_sem;
  658. +  if(sem->type == DS_SOCKET) {
  659. +    send(sem->sockfd, sem->mutex_tx, 1, 0);
  660. +  }
  661. +#ifdef DS_SEMAPHORE
  662. +  else if(sem->type == DS_SEMAPHORE) {
  663. +    sem_post(sem->sem_wr);
  664. +  }
  665. +#endif
  666. +}
  667. +
  668. +void timed_semclean(void * _sem) {
  669. +#ifdef DS_SEMAPHORE
  670. +  struct sem *sem = (struct sem *) _sem;
  671. +  if(sem->type == DS_SEMAPHORE) {
  672. +    char sem1[80], sem2[80];
  673. +    snprintf(sem1, 80, "/dshow_sem1.%s", (char *)sem->id);
  674. +    snprintf(sem2, 80, "/dshow_sem2.%s", (char *)sem->id);
  675. +    sem_unlink(sem1);
  676. +    sem_unlink(sem2);
  677. +  }
  678. +#endif
  679. +}
  680. +
  681. +void *timed_seminit(unsigned int semtype, void *id, int is_host) {
  682. +  struct sem *sem;
  683. +  sem = (struct sem *)malloc(sizeof(struct sem));
  684. +  memset(sem, 0, sizeof(struct sem));
  685. +  sem->type = semtype;
  686. +  sem->id = id;
  687. +  sem->initialized = !(is_host);
  688. +  if(semtype == DS_SOCKET) {
  689. +    sem->listenfd = -1;
  690. +    sem->sockfd = timed_sockinit((int *)id, is_host);
  691. +    if(sem->sockfd == -1) {
  692. +      perror("sock_init");
  693. +      exit(1);
  694. +    }
  695. +  }
  696. +#ifdef DS_SEMAPHORE
  697. +  else if(semtype == DS_SEMAPHORE) {
  698. +    char semrd[80], semwr[80];
  699. +    init_twait();
  700. +    snprintf(semrd, 80, "/dshow_sem%d.%s", is_host ? 2 : 1, (char *)id);
  701. +    snprintf(semwr, 80, "/dshow_sem%d.%s", is_host ? 1 : 2, (char *)id);
  702. +    if(is_host) {
  703. +      sem->sem_rd = sem_open(semrd, O_CREAT, 0644, 0);
  704. +      sem->sem_wr = sem_open(semwr, O_CREAT, 0644, 0);
  705. +    } else {
  706. +      sem->sem_rd = sem_open(semrd, 0);
  707. +      sem->sem_wr = sem_open(semwr, 0);
  708. +      sem_unlink(semwr);
  709. +      sem_unlink(semrd);
  710. +    }
  711. +    if(sem->sem_rd == SEM_FAILED) {
  712. +      timed_semclean(sem);
  713. +      perror("sem_open(1)");
  714. +      exit(1);
  715. +    }
  716. +    if(sem->sem_wr == SEM_FAILED) {
  717. +      timed_semclean(sem);
  718. +      perror("sem_open(2)");
  719. +      exit(1);
  720. +    }
  721. +    //tell calling procedure that we are awake;
  722. +    if(! is_host) {
  723. +      sem_post(sem->sem_wr);
  724. +    }
  725. +  }
  726. +#endif /*DS_SEMAPHORE*/
  727. +  else {
  728. +    fprintf(stderr, "Unknown type specified: %d\n", semtype);
  729. +    exit(1);
  730. +  }
  731. +  return sem;
  732. +}
  733. +
  734. +void timed_semdelete(void *_sem) {
  735. +  struct sem *sem = (struct sem *) _sem;
  736. +  if(sem->type == DS_SOCKET) {
  737. +    close(sem->sockfd);
  738. +    if(sem->listenfd != -1)
  739. +      close(sem->listenfd);
  740. +#ifdef DS_SEMAPHORE
  741. +  } else if(sem->type == DS_SEMAPHORE) {
  742. +    if(! sem->initialized)
  743. +      timed_semclean(sem);
  744. +    sem_close(sem->sem_wr);
  745. +    sem_close(sem->sem_rd);
  746. +#endif
  747. +  }
  748. +  free(sem);
  749. +}
  750. +
  751. Index: libmpcodecs/timeout_sem.h
  752. ===================================================================
  753. --- /dev/null   1970-01-01 00:00:00.000000000 +0000
  754. +++ libmpcodecs/timeout_sem.h   2010-03-12 07:48:02.000000000 -0800
  755. @@ -0,0 +1,10 @@
  756. +#define DS_SOCKET 0x01
  757. +#define DS_SEMAPHORE 0x02
  758. +
  759. +#define DS_TIMEOUT -1
  760. +
  761. +void *timed_seminit(unsigned int semtype, void *id, int is_host);
  762. +void timed_semclean(void *_sem);
  763. +void timed_sempost(void *_sem);
  764. +int timed_semwait(void *_sem, int secs);
  765. +void timed_semdelete(void *_sem);
clone this paste RAW Paste Data