关于我
 

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

linux coreavc


各种折腾·archlinuxlinux

本文最后编辑于超过4125天以前,部分内容可能已经失效

上网本的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也需要更改。

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


推广:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元

打赏我

评论

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

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

允许使用以下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

本博客是言论不自由博客,评论只接受询问及赞同,不同观点请出门左转微博/发表于自己的博客。谢谢合作!

评论意味着你 同意 上传部分私人数据,包括邮箱和 IP, 这些数据不会被分享给第三方,不会用于商业用途或再推广用途。

更多相似文章

 

隐私设置 [关闭]


开博客就是为了装逼,装逼自然要支持 GDPR 隐私政策。请选择以下的隐私设置: