packet.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. #include "packet.h"
  2. int packet_queue_init(packet_queue_t *q, CMediaHostApi* hostapi)
  3. {
  4. memset(q, 0, sizeof(packet_queue_t));
  5. q->mutex = SDL_CreateMutex();
  6. if (!q->mutex)
  7. {
  8. hostapi->Debug("SDL_CreateMutex(): %s.", SDL_GetError());
  9. return AVERROR(ENOMEM);
  10. }
  11. q->cond = SDL_CreateCond();
  12. if (!q->cond)
  13. {
  14. hostapi->Debug("SDL_CreateCond(): %s.", SDL_GetError());
  15. return AVERROR(ENOMEM);
  16. }
  17. q->abort_request = 0;
  18. return 0;
  19. }
  20. // 写队列尾部。pkt是一包还未解码的音频数据
  21. int packet_queue_put(packet_queue_t *q, AVPacket *pkt, CMediaHostApi* hostapi)
  22. {
  23. AVPacketList* pkt_list = NULL;
  24. if (av_packet_make_refcounted(pkt) < 0)
  25. {
  26. hostapi->Debug("[pkt] is not refrence counted.");
  27. return -1;
  28. }
  29. pkt_list = (AVPacketList*)av_malloc(sizeof(AVPacketList));
  30. if (!pkt_list)
  31. {
  32. return -1;
  33. }
  34. pkt_list->pkt = *pkt;
  35. pkt_list->next = NULL;
  36. SDL_LockMutex(q->mutex);
  37. if (!q->last_pkt) // 队列为空
  38. {
  39. q->first_pkt = pkt_list;
  40. }
  41. else
  42. {
  43. q->last_pkt->next = pkt_list;
  44. }
  45. q->last_pkt = pkt_list;
  46. q->nb_packets++;
  47. q->size += pkt_list->pkt.size;
  48. // 发个条件变量的信号:重启等待q->cond条件变量的一个线程
  49. //printf("packet queue put new pkt, CondSignal cond.pkt == 0x%0x, pkt_list->pkt.data == 0x%0x,(pkt->data == 0x%0x) pkt_list->pkt.size = %d, (pkt->size == %d)\n\n\n",pkt, pkt_list->pkt.data, pkt->data, pkt_list->pkt.size, pkt->size);
  50. //printf("packet queue put new pkt, CondSignal cond.\n");
  51. SDL_CondSignal(q->cond);
  52. SDL_UnlockMutex(q->mutex);
  53. return 0;
  54. }
  55. // 读队列头部。
  56. int packet_queue_get(packet_queue_t *q, AVPacket *pkt, int block)
  57. {
  58. AVPacketList *p_pkt_node = NULL;
  59. int ret = -1;
  60. SDL_LockMutex(q->mutex);
  61. while (0 == q->abort_request)
  62. {
  63. p_pkt_node = q->first_pkt;
  64. if (p_pkt_node) // 队列非空,取一个出来
  65. {
  66. //printf("packet queue is not empty, get one.\n");
  67. q->first_pkt = p_pkt_node->next;
  68. if (!q->first_pkt)
  69. {
  70. q->last_pkt = NULL;
  71. }
  72. q->nb_packets--;
  73. q->size -= p_pkt_node->pkt.size;
  74. *pkt = p_pkt_node->pkt;
  75. av_free(p_pkt_node);
  76. ret = 1;
  77. break;
  78. }
  79. else if (!block) // 队列空且阻塞标志无效,则立即退出
  80. {
  81. //printf("packet queue is empty, and block flag is invalid, break.\n");
  82. ret = 0;
  83. break;
  84. }
  85. else // 队列空且阻塞标志有效,则等待
  86. {
  87. //printf("packet queue is empty, and block flag is valid, continue wait.\n");
  88. SDL_CondWait(q->cond, q->mutex);
  89. }
  90. }
  91. SDL_UnlockMutex(q->mutex);
  92. return ret;
  93. }
  94. int packet_queue_put_nullpacket(packet_queue_t *q, int stream_index, CMediaHostApi* hostapi)
  95. {
  96. AVPacket pkt1, *pkt = &pkt1;
  97. av_init_packet(pkt);
  98. pkt->data = NULL;
  99. pkt->size = 0;
  100. pkt->stream_index = stream_index;
  101. return packet_queue_put(q, pkt, hostapi);
  102. }
  103. void packet_queue_flush(packet_queue_t *q)
  104. {
  105. AVPacketList *pkt, *pkt1;
  106. SDL_LockMutex(q->mutex);
  107. for (pkt = q->first_pkt; pkt; pkt = pkt1) {
  108. pkt1 = pkt->next;
  109. //av_packet_unref(&pkt->pkt);
  110. //av_freep(&pkt);
  111. }
  112. q->last_pkt = NULL;
  113. q->first_pkt = NULL;
  114. q->nb_packets = 0;
  115. q->size = 0;
  116. q->duration = 0;
  117. SDL_UnlockMutex(q->mutex);
  118. }
  119. void packet_queue_destroy(packet_queue_t *q, CMediaHostApi* m_hostapi)
  120. {
  121. packet_queue_flush(q);
  122. SDL_DestroyMutex(q->mutex);
  123. SDL_DestroyCond(q->cond);
  124. m_hostapi->Debug("packet queue destroy.");
  125. }
  126. void packet_queue_abort(packet_queue_t *q, CMediaHostApi* m_hostapi)
  127. {
  128. SDL_LockMutex(q->mutex);
  129. q->abort_request = 1;
  130. //m_hostapi->Debug("packet_queue_abort, CondSignal cond.");
  131. SDL_CondSignal(q->cond);
  132. SDL_UnlockMutex(q->mutex);
  133. }