slice.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:21k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. #include "../mpeg3private.h"
  2. #include "mpeg3video.h"
  3. #include "mpeg3videoprotos.h"
  4. #include "slice.h"
  5. #ifndef SDL_THREADS
  6. #include <pthread.h>
  7. #else
  8. #include "SDL.h"
  9. #include "SDL_thread.h"
  10. #endif
  11. #include <stdlib.h>
  12. #define CLIP(x)  ((x) >= 0 ? ((x) < 255 ? (x) : 255) : 0)
  13. #ifndef _MSC_VER
  14. static unsigned long long MMX_128 = 0x80008000800080LL;
  15. #else
  16. static u_int64_t MMX_128 = 0x80008000800080;
  17. #endif
  18. int mpeg3_new_slice_buffer(mpeg3_slice_buffer_t *slice_buffer)
  19. {
  20. #ifndef SDL_THREADS
  21. pthread_mutexattr_t mutex_attr;
  22. #endif
  23. slice_buffer->data = malloc(1024);
  24. slice_buffer->buffer_size = 0;
  25. slice_buffer->buffer_allocation = 1024;
  26. slice_buffer->current_position = 0;
  27. slice_buffer->bits_size = 0;
  28. slice_buffer->bits = 0;
  29. slice_buffer->done = 0;
  30. #ifndef SDL_THREADS
  31. pthread_mutexattr_init(&mutex_attr);
  32. // pthread_mutexattr_setkind_np(&mutex_attr, PTHREAD_MUTEX_FAST_NP);
  33. pthread_mutex_init(&(slice_buffer->completion_lock), &mutex_attr);
  34. #else
  35. slice_buffer->completion_lock = SDL_CreateMutex();
  36. #endif
  37. return 0;
  38. }
  39. int mpeg3_delete_slice_buffer(mpeg3_slice_buffer_t *slice_buffer)
  40. {
  41. free(slice_buffer->data);
  42. #ifndef SDL_THREADS
  43. pthread_mutex_destroy(&(slice_buffer->completion_lock));
  44. #else
  45. SDL_DestroyMutex(slice_buffer->completion_lock);
  46. #endif
  47. return 0;
  48. }
  49. int mpeg3_expand_slice_buffer(mpeg3_slice_buffer_t *slice_buffer)
  50. {
  51. int i;
  52. unsigned char *new_buffer = malloc(slice_buffer->buffer_allocation * 2);
  53. for(i = 0; i < slice_buffer->buffer_size; i++)
  54. new_buffer[i] = slice_buffer->data[i];
  55. free(slice_buffer->data);
  56. slice_buffer->data = new_buffer;
  57. slice_buffer->buffer_allocation *= 2;
  58. return 0;
  59. }
  60. /* limit coefficients to -2048..2047 */
  61. /* move/add 8x8-Block from block[comp] to refframe */
  62. static __inline int mpeg3video_addblock(mpeg3_slice_t *slice, 
  63. mpeg3video_t *video, 
  64. int comp, 
  65. int bx, 
  66. int by, 
  67. int dct_type, 
  68. int addflag)
  69. {
  70. int cc, i, iincr;
  71. unsigned char *rfp;
  72. short *bp;
  73. int spar = slice->sparse[comp];
  74. /* color component index */
  75.    cc = (comp < 4) ? 0 : (comp & 1) + 1; 
  76.    if(cc == 0)
  77. {   
  78. /* luminance */
  79.      if(video->pict_struct == FRAME_PICTURE)
  80. {
  81.        if(dct_type)
  82. {
  83. /* field DCT coding */
  84.          rfp = video->newframe[0] + 
  85.                video->coded_picture_width * (by + ((comp & 2) >> 1)) + bx + ((comp & 1) << 3);
  86.          iincr = (video->coded_picture_width << 1);
  87.        }
  88.        else
  89. {
  90. /* frame DCT coding */
  91.          rfp = video->newframe[0] + 
  92.               video->coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
  93.          iincr = video->coded_picture_width;
  94.        }
  95. }
  96.      else 
  97. {
  98. /* field picture */
  99.        rfp = video->newframe[0] + 
  100.             (video->coded_picture_width << 1) * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
  101.        iincr = (video->coded_picture_width << 1);
  102.      }
  103.   }
  104.    else 
  105. {
  106. /* chrominance */
  107. /* scale coordinates */
  108.      if(video->chroma_format != CHROMA444) bx >>= 1;
  109.      if(video->chroma_format == CHROMA420) by >>= 1;
  110.      if(video->pict_struct == FRAME_PICTURE)
  111. {
  112.      if(dct_type && (video->chroma_format != CHROMA420))
  113. {
  114. /* field DCT coding */
  115.          rfp = video->newframe[cc]
  116.                + video->chrom_width * (by + ((comp & 2) >> 1)) + bx + (comp & 8);
  117.          iincr = (video->chrom_width << 1);
  118.      }
  119.      else 
  120. {
  121. /* frame DCT coding */
  122.          rfp = video->newframe[cc]
  123.                + video->chrom_width * (by + ((comp & 2) << 2)) + bx + (comp & 8);
  124.          iincr = video->chrom_width;
  125.      }
  126.      }
  127.      else 
  128. {
  129. /* field picture */
  130.      rfp = video->newframe[cc]
  131.                + (video->chrom_width << 1) * (by + ((comp & 2) << 2)) + bx + (comp & 8);
  132.      iincr = (video->chrom_width << 1);
  133.      }
  134.    }
  135.    bp = slice->block[comp];
  136. if(addflag)
  137. {
  138. #ifdef HAVE_MMX
  139. if(video->have_mmx)
  140. {
  141.      if(spar)
  142. {
  143.         __asm__ __volatile__(
  144.              "movq       (%2),  %%mm6n"  /* 4 blockvals */
  145.              "pxor       %%mm4, %%mm4n"
  146.              "punpcklwd  %%mm6, %%mm6n"
  147.              "punpcklwd  %%mm6, %%mm6n"
  148.              ".align 8n"
  149.              "1:"
  150.                  "movq       (%1),  %%mm0n"     /* 8 rindex1 */
  151.                  "movq       %%mm0, %%mm2n"
  152.                  "punpcklbw  %%mm4, %%mm0n"
  153.                  "punpckhbw  %%mm4, %%mm2n"
  154.                  "paddw      %%mm6, %%mm0n"
  155.                  "paddw      %%mm6, %%mm2n"
  156.                  "packuswb   %%mm2, %%mm0n"
  157.                  "movq       %%mm0, (%1)n"
  158.                  "leal       (%1, %3), %1n"
  159.                "loop       1bn"
  160.                :              /* scr   dest */
  161.                : "c" (8),"r" (rfp), "r" (bp), "r" (iincr)
  162.                  );
  163.      }
  164.      else 
  165. {
  166.         __asm__ __volatile__(
  167.           "pxor    %%mm4, %%mm4n"
  168.           ".align 8n"
  169.           "1:"
  170.             "movq       (%2), %%mm0n"   /* 8 rfp 0 1 2 3 4 5 6 7*/
  171.             "movq       (%1), %%mm6n"   /* 4 blockvals 0 1 2 3 */
  172.             "movq       %%mm0, %%mm2n"
  173.             "movq       8(%1), %%mm5n"  /* 4 blockvals 0 1 2 3 */
  174.             "punpcklbw  %%mm4, %%mm0n"  /* 0 2 4 6 */
  175.             "punpckhbw  %%mm4, %%mm2n"  /* 1 3 5 7 */
  176.             "paddw      %%mm6, %%mm0n"
  177.             "paddw      %%mm5, %%mm2n"
  178.             "packuswb   %%mm2, %%mm0n"
  179.             "addl       $16, %1n"
  180.             "movq       %%mm0, (%2)n"
  181.             "leal       (%2,%3), %2n"
  182.           "loop       1bn"
  183.           :              /* scr   dest */
  184.           : "c" (8),"r" (bp), "r" (rfp), "r" (iincr)
  185.      );
  186.      }
  187. }
  188. else
  189. #endif
  190. for(i = 0; i < 8; i++)
  191. {
  192.      rfp[0] = CLIP(bp[0] + rfp[0]);
  193.      rfp[1] = CLIP(bp[1] + rfp[1]);
  194.      rfp[2] = CLIP(bp[2] + rfp[2]);
  195.      rfp[3] = CLIP(bp[3] + rfp[3]);
  196.      rfp[4] = CLIP(bp[4] + rfp[4]);
  197.      rfp[5] = CLIP(bp[5] + rfp[5]);
  198.      rfp[6] = CLIP(bp[6] + rfp[6]);
  199.      rfp[7] = CLIP(bp[7] + rfp[7]);
  200.      rfp += iincr;
  201.      bp += 8;
  202. }
  203.    }
  204.    else 
  205.    {
  206. /* libtool PIC causes problems here */
  207. #if defined(HAVE_MMX) && !defined(MPEG4IP)
  208. if(video->have_mmx)
  209. {
  210.      if(spar) 
  211. {
  212.             __asm__ __volatile__(
  213.              "movd       (%2),           %%mm0n"    /* " 0 0 0  v1" */
  214.              "punpcklwd  %%mm0,          %%mm0n"    /* " 0 0 v1 v1" */
  215.              "punpcklwd  %%mm0,          %%mm0n"
  216.              "paddw      MMX_128,        %%mm0n"
  217.              "packuswb   %%mm0,          %%mm0n"
  218.              "leal       (%0,%1,2),      %%eaxn"
  219.              "movq        %%mm0,         (%0, %1)n"
  220.              "movq        %%mm0,         (%%eax)n"
  221.              "leal        (%%eax,%1,2),  %0n"
  222.              "movq        %%mm0,         (%%eax, %1)n"
  223.              "movq        %%mm0,         (%0)n"
  224.              "leal        (%0,%1,2),     %%eaxn"
  225.              "movq        %%mm0,         (%0, %1)n"
  226.              "movq        %%mm0,         (%%eax)n"
  227.              "movq        %%mm0,         (%%eax, %1)n"
  228.              :
  229.              : "D" (rfp), "c" (iincr), "b" (bp)
  230.              : "eax");
  231.      }
  232.      else 
  233. {
  234.      __asm__ __volatile__(
  235.              "movq        MMX_128,%%mm4n"
  236.              ".align 8n"
  237.              "1:"
  238.                "movq      (%1),   %%mm0n"
  239.                "movq      8(%1),  %%mm1n"
  240.                "paddw     %%mm4,  %%mm0n"
  241.                "movq      16(%1), %%mm2n"
  242.                "paddw     %%mm4,  %%mm1n"
  243.                "movq      24(%1), %%mm3n"
  244.                "paddw     %%mm4,  %%mm2n"
  245.                "packuswb  %%mm1,  %%mm0n"
  246.                "paddw     %%mm4,  %%mm3n"
  247.                "addl $32, %1n"
  248.                "packuswb  %%mm3,  %%mm2n"
  249.                "movq   %%mm0, (%2)n"
  250.                "movq   %%mm2, (%2,%3)n"
  251.                "leal       (%2,%3,2), %2n"
  252.              "loop       1bn"
  253.              :
  254.              : "c" (4), "r" (bp), "r" (rfp), "r" (iincr)
  255.          );
  256.      }
  257. }
  258. else
  259. #endif /* HAVE_MMX */
  260.      for(i = 0; i < 8; i++)
  261. {
  262.      rfp[0] = CLIP(bp[0] + 128);
  263.      rfp[1] = CLIP(bp[1] + 128);
  264.      rfp[2] = CLIP(bp[2] + 128);
  265.      rfp[3] = CLIP(bp[3] + 128);
  266.      rfp[4] = CLIP(bp[4] + 128);
  267.      rfp[5] = CLIP(bp[5] + 128);
  268.      rfp[6] = CLIP(bp[6] + 128);
  269.      rfp[7] = CLIP(bp[7] + 128);
  270.      rfp+= iincr;
  271.      bp += 8;
  272.      }
  273.    }
  274. return 0;
  275. }
  276. int mpeg3_decode_slice(mpeg3_slice_t *slice)
  277. {
  278. mpeg3video_t *video = slice->video;
  279. int comp;
  280. int mb_type, cbp, motion_type = 0, dct_type;
  281. int macroblock_address, mba_inc, mba_max;
  282. int slice_vert_pos_ext;
  283. unsigned int code;
  284. int bx, by;
  285. int dc_dct_pred[3];
  286. int mv_count, mv_format, mvscale;
  287. int pmv[2][2][2], mv_field_sel[2][2];
  288. int dmv, dmvector[2];
  289. int qs;
  290. int stwtype, stwclass; 
  291. int snr_cbp;
  292. int i;
  293. mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
  294. /* number of macroblocks per picture */
  295.    mba_max = video->mb_width * video->mb_height;
  296. /* field picture has half as many macroblocks as frame */
  297. if(video->pict_struct != FRAME_PICTURE)
  298.     mba_max >>= 1; 
  299. /* macroblock address */
  300.    macroblock_address = 0; 
  301. /* first macroblock in slice is not skipped */
  302.    mba_inc = 0;
  303.    slice->fault = 0;
  304. code = mpeg3slice_getbits(slice_buffer, 32);
  305. /* decode slice header (may change quant_scale) */
  306.     slice_vert_pos_ext = mpeg3video_getslicehdr(slice, video);
  307. /* reset all DC coefficient and motion vector predictors */
  308.     dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;
  309.     pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
  310.     pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0;
  311.    for(i = 0; 
  312. slice_buffer->current_position < slice_buffer->buffer_size; 
  313. i++)
  314. {
  315. if(mba_inc == 0)
  316. {
  317. /* Done */
  318. if(!mpeg3slice_showbits(slice_buffer, 23)) return 0;
  319. /* decode macroblock address increment */
  320.      mba_inc = mpeg3video_get_macroblock_address(slice);
  321.          if(slice->fault) return 1;
  322.      if(i == 0)
  323. {
  324. /* Get the macroblock_address */
  325. macroblock_address = ((slice_vert_pos_ext << 7) + (code & 255) - 1) * video->mb_width + mba_inc - 1;
  326. /* first macroblock in slice: not skipped */
  327. mba_inc = 1;
  328. }
  329. }
  330.         if(slice->fault) return 1;
  331.      if(macroblock_address >= mba_max)
  332. {
  333. /* mba_inc points beyond picture dimensions */
  334.        /*fprintf(stderr, "mpeg3_decode_slice: too many macroblocks in picturen"); */
  335.        return 1;
  336.      }
  337. /* not skipped */
  338.      if(mba_inc == 1)
  339. {
  340. mpeg3video_macroblock_modes(slice, 
  341. video, 
  342. &mb_type, 
  343. &stwtype, 
  344. &stwclass,
  345.          &motion_type, 
  346. &mv_count, 
  347. &mv_format, 
  348. &dmv, 
  349. &mvscale, 
  350. &dct_type);
  351. if(slice->fault) return 1;
  352.        if(mb_type & MB_QUANT)
  353. {
  354.          qs = mpeg3slice_getbits(slice_buffer, 5);
  355.          if(video->mpeg2)
  356.                slice->quant_scale = video->qscale_type ? mpeg3_non_linear_mquant_table[qs] : (qs << 1);
  357.          else 
  358. slice->quant_scale = qs;
  359.          if(video->scalable_mode == SC_DP)
  360. /* make sure quant_scale is valid */
  361.            slice->quant_scale = slice->quant_scale;
  362.        }
  363. /* motion vectors */
  364. /* decode forward motion vectors */
  365.        if((mb_type & MB_FORWARD) || ((mb_type & MB_INTRA) && video->conceal_mv))
  366. {
  367.          if(video->mpeg2)
  368.          mpeg3video_motion_vectors(slice, 
  369. video, 
  370. pmv, 
  371. dmvector, 
  372. mv_field_sel, 
  373.              0, 
  374. mv_count, 
  375. mv_format, 
  376. video->h_forw_r_size, 
  377. video->v_forw_r_size, 
  378. dmv, 
  379. mvscale);
  380.          else
  381.             mpeg3video_motion_vector(slice, 
  382. video, 
  383. pmv[0][0], 
  384. dmvector, 
  385.              video->forw_r_size, 
  386. video->forw_r_size, 
  387. 0, 
  388. 0, 
  389. video->full_forw);
  390.      }
  391.        if(slice->fault) return 1;
  392. /* decode backward motion vectors */
  393.      if(mb_type & MB_BACKWARD)
  394. {
  395.          if(video->mpeg2)
  396.             mpeg3video_motion_vectors(slice, 
  397. video, 
  398. pmv, 
  399. dmvector, 
  400. mv_field_sel, 
  401.              1, 
  402. mv_count, 
  403. mv_format, 
  404. video->h_back_r_size, 
  405. video->v_back_r_size, 
  406. 0, 
  407. mvscale);
  408.          else
  409.             mpeg3video_motion_vector(slice, 
  410. video, 
  411. pmv[0][1], 
  412. dmvector, 
  413.              video->back_r_size, 
  414. video->back_r_size, 
  415. 0, 
  416. 0, 
  417. video->full_back);
  418.      }
  419.        if(slice->fault) return 1;
  420. /* remove marker_bit */
  421.        if((mb_type & MB_INTRA) && video->conceal_mv)
  422.          mpeg3slice_flushbit(slice_buffer);
  423. /* macroblock_pattern */
  424.        if(mb_type & MB_PATTERN)
  425. {
  426.          cbp = mpeg3video_get_cbp(slice);
  427.          if(video->chroma_format == CHROMA422)
  428. {
  429. /* coded_block_pattern_1 */
  430.             cbp = (cbp << 2) | mpeg3slice_getbits2(slice_buffer); 
  431.          }
  432.          else
  433. if(video->chroma_format == CHROMA444)
  434. {
  435. /* coded_block_pattern_2 */
  436.             cbp = (cbp << 6) | mpeg3slice_getbits(slice_buffer, 6); 
  437.          }
  438.      }
  439.      else
  440.             cbp = (mb_type & MB_INTRA) ? ((1 << video->blk_cnt) - 1) : 0;
  441.        if(slice->fault) return 1;
  442. /* decode blocks */
  443.        mpeg3video_clearblock(slice, 0, video->blk_cnt);
  444.        for(comp = 0; comp < video->blk_cnt; comp++)
  445. {
  446.          if(cbp & (1 << (video->blk_cnt - comp - 1)))
  447. {
  448.            if(mb_type & MB_INTRA)
  449. {
  450.              if(video->mpeg2)
  451. mpeg3video_getmpg2intrablock(slice, video, comp, dc_dct_pred);
  452.              else
  453. mpeg3video_getintrablock(slice, video, comp, dc_dct_pred);
  454.            }
  455.          else 
  456. {
  457.                 if(video->mpeg2) 
  458.    mpeg3video_getmpg2interblock(slice, video, comp);
  459.                 else           
  460.    mpeg3video_getinterblock(slice, video, comp);
  461.          }
  462.          if(slice->fault) return 1;
  463.          }
  464.        }
  465. /* reset intra_dc predictors */
  466. if(!(mb_type & MB_INTRA))
  467.             dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;
  468. /* reset motion vector predictors */
  469.      if((mb_type & MB_INTRA) && !video->conceal_mv)
  470. {
  471. /* intra mb without concealment motion vectors */
  472.          pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
  473.          pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0;
  474.      }
  475.      if((video->pict_type == P_TYPE) && !(mb_type & (MB_FORWARD | MB_INTRA)))
  476. {
  477. /* non-intra mb without forward mv in a P picture */
  478.          pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
  479. /* derive motion_type */
  480.          if(video->pict_struct == FRAME_PICTURE) 
  481. motion_type = MC_FRAME;
  482.          else
  483.          {
  484.          motion_type = MC_FIELD;
  485. /* predict from field of same parity */
  486.          mv_field_sel[0][0] = (video->pict_struct == BOTTOM_FIELD);
  487.          }
  488.        }
  489.      if(stwclass == 4)
  490.      {
  491. /* purely spatially predicted macroblock */
  492.          pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
  493.          pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0;
  494.      }
  495.      }
  496.      else 
  497. {
  498. /* mba_inc!=1: skipped macroblock */
  499.        mpeg3video_clearblock(slice, 0, video->blk_cnt);
  500. /* reset intra_dc predictors */
  501.        dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;
  502. /* reset motion vector predictors */
  503.        if(video->pict_type == P_TYPE)
  504.          pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
  505. /* derive motion_type */
  506.        if(video->pict_struct == FRAME_PICTURE)
  507.          motion_type = MC_FRAME;
  508.      else
  509.      {
  510.          motion_type = MC_FIELD;
  511. /* predict from field of same parity */
  512.          mv_field_sel[0][0] = mv_field_sel[0][1] = (video->pict_struct == BOTTOM_FIELD);
  513.      }
  514. /* skipped I are spatial-only predicted, */
  515. /* skipped P and B are temporal-only predicted */
  516.        stwtype = (video->pict_type == I_TYPE) ? 8 : 0;
  517. /* clear MB_INTRA */
  518.        mb_type &= ~MB_INTRA;
  519. /* no block data */
  520.        cbp = 0; 
  521.      }
  522.      snr_cbp = 0;
  523. /* pixel coordinates of top left corner of current macroblock */
  524.      bx = 16 * (macroblock_address % video->mb_width);
  525.      by = 16 * (macroblock_address / video->mb_width);
  526. /* motion compensation */
  527.      if(!(mb_type & MB_INTRA))
  528.         mpeg3video_reconstruct(video, 
  529. bx, 
  530. by, 
  531. mb_type, 
  532. motion_type, 
  533. pmv, 
  534. mv_field_sel, 
  535. dmvector, 
  536. stwtype);
  537. /* copy or add block data into picture */
  538.      for(comp = 0; comp < video->blk_cnt; comp++)
  539. {
  540.        if((cbp | snr_cbp) & (1 << (video->blk_cnt - 1 - comp)))
  541. {
  542. #ifdef HAVE_MMX
  543. if(video->have_mmx)
  544.       IDCT_mmx(slice->block[comp]);
  545. else
  546. #endif
  547.            mpeg3video_idct_conversion(slice->block[comp]);
  548.          mpeg3video_addblock(slice, 
  549. video, 
  550. comp, 
  551. bx, 
  552. by, 
  553. dct_type, 
  554. (mb_type & MB_INTRA) == 0);
  555.        }
  556.      }
  557. /* advance to next macroblock */
  558.      macroblock_address++;
  559.      mba_inc--;
  560.    }
  561. return 0;
  562. }
  563. void mpeg3_slice_loop(mpeg3_slice_t *slice)
  564. {
  565. mpeg3video_t *video = slice->video;
  566. int result = 1;
  567. while(!slice->done)
  568. {
  569. #ifndef SDL_THREADS
  570. pthread_mutex_lock(&(slice->input_lock));
  571. #else
  572. SDL_LockMutex(slice->input_lock);
  573. #endif
  574. if(!slice->done)
  575. {
  576. /* Get a buffer to decode */
  577. result = 1;
  578. #ifndef SDL_THREADS
  579. pthread_mutex_lock(&(video->slice_lock));
  580. #else
  581. SDL_LockMutex(video->slice_lock);
  582. #endif
  583. if(slice->buffer_step > 0)
  584. {
  585. while(slice->current_buffer <= slice->last_buffer)
  586. {
  587. if(!video->slice_buffers[slice->current_buffer].done &&
  588. slice->current_buffer <= slice->last_buffer)
  589. {
  590. result = 0;
  591. break;
  592. }
  593. slice->current_buffer += slice->buffer_step;
  594. }
  595. }
  596. else
  597. {
  598. while(slice->current_buffer >= slice->last_buffer)
  599. {
  600. if(!video->slice_buffers[slice->current_buffer].done &&
  601. slice->current_buffer >= slice->last_buffer)
  602. {
  603. result = 0;
  604. break;
  605. }
  606. slice->current_buffer += slice->buffer_step;
  607. }
  608. }
  609. /* Got one */
  610. if(!result && slice->current_buffer >= 0 && slice->current_buffer < video->total_slice_buffers)
  611. {
  612. slice->slice_buffer = &(video->slice_buffers[slice->current_buffer]);
  613. slice->slice_buffer->done = 1;
  614. #ifndef SDL_THREADS
  615. pthread_mutex_unlock(&(video->slice_lock));
  616. pthread_mutex_unlock(&(slice->input_lock));
  617. #else
  618. SDL_UnlockMutex(video->slice_lock);
  619. SDL_UnlockMutex(slice->input_lock);
  620. #endif
  621. mpeg3_decode_slice(slice);
  622. #ifndef SDL_THREADS
  623. pthread_mutex_unlock(&(slice->slice_buffer->completion_lock));
  624. #else
  625. SDL_UnlockMutex(slice->slice_buffer->completion_lock);
  626. #endif
  627. }
  628. else
  629. /* Finished with all */
  630. {
  631. #ifndef SDL_THREADS
  632. pthread_mutex_unlock(&(slice->completion_lock));
  633. pthread_mutex_unlock(&(video->slice_lock));
  634. #else
  635. SDL_UnlockMutex(slice->completion_lock);
  636. SDL_UnlockMutex(video->slice_lock);
  637. #endif
  638. }
  639. }
  640. #ifndef SDL_THREADS
  641. pthread_mutex_unlock(&(slice->output_lock));
  642. #else
  643. SDL_UnlockMutex(slice->output_lock);
  644. #endif
  645. }
  646. }
  647. int mpeg3_new_slice_decoder(void *video, mpeg3_slice_t *slice)
  648. {
  649. #ifndef SDL_THREADS
  650. pthread_attr_t  attr;
  651. pthread_mutexattr_t mutex_attr;
  652. #endif
  653. slice->video = video;
  654. slice->done = 0;
  655. #ifndef SDL_THREADS
  656. pthread_mutexattr_init(&mutex_attr);
  657. // pthread_mutexattr_setkind_np(&mutex_attr, PTHREAD_MUTEX_FAST_NP);
  658. pthread_mutex_init(&(slice->input_lock), &mutex_attr);
  659. pthread_mutex_lock(&(slice->input_lock));
  660. pthread_mutex_init(&(slice->output_lock), &mutex_attr);
  661. pthread_mutex_lock(&(slice->output_lock));
  662. pthread_mutex_init(&(slice->completion_lock), &mutex_attr);
  663. pthread_mutex_lock(&(slice->completion_lock));
  664. #else
  665. slice->input_lock = SDL_CreateMutex();
  666. SDL_LockMutex(slice->input_lock);
  667. slice->output_lock = SDL_CreateMutex();
  668. SDL_LockMutex(slice->output_lock);
  669. slice->completion_lock = SDL_CreateMutex();
  670. SDL_LockMutex(slice->completion_lock);
  671. #endif
  672. #ifndef SDL_THREADS
  673. pthread_attr_init(&attr);
  674. pthread_create(&(slice->tid), &attr, (void*)mpeg3_slice_loop, slice);
  675. #else
  676. slice->tid = SDL_CreateThread((void*)mpeg3_slice_loop, slice);
  677. #endif
  678. return 0;
  679. }
  680. int mpeg3_delete_slice_decoder(mpeg3_slice_t *slice)
  681. {
  682. slice->done = 1;
  683. #ifndef SDL_THREADS
  684. pthread_mutex_unlock(&(slice->input_lock));
  685. pthread_join(slice->tid, 0);
  686. pthread_mutex_destroy(&(slice->input_lock));
  687. pthread_mutex_destroy(&(slice->output_lock));
  688. #else
  689. SDL_UnlockMutex(slice->input_lock);
  690. SDL_WaitThread(slice->tid, NULL);
  691. SDL_DestroyMutex(slice->input_lock);
  692. SDL_DestroyMutex(slice->output_lock);
  693. #endif
  694. return 0;
  695. }