packet.cpp 3.9 KB

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