packet.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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. // 发个条件变量的信号:重启等待q->cond条件变量的一个线程
  44. SDL_CondSignal(q->packet_cond);
  45. SDL_UnlockMutex(q->mutex);
  46. return 0;
  47. }
  48. // 读队列头部。
  49. int packet_queue_get(packet_queue_t *q, AVPacket *pkt, int block, CMediaHostApi* hostapi)
  50. {
  51. AVPacketList *p_pkt_node = NULL;
  52. int ret = -1;
  53. SDL_LockMutex(q->mutex);
  54. while (0 == q->abort_flag)
  55. {
  56. p_pkt_node = q->first_pkt;
  57. if (p_pkt_node) // 队列非空,取一个出来
  58. {
  59. q->first_pkt = p_pkt_node->next;
  60. if (!q->first_pkt)
  61. {
  62. q->last_pkt = NULL;
  63. }
  64. q->nb_packets--;
  65. q->packet_queue_size -= p_pkt_node->pkt.size;
  66. *pkt = p_pkt_node->pkt;
  67. av_free(p_pkt_node);
  68. ret = 1;
  69. break;
  70. }
  71. else if (!block) // 队列空且阻塞标志无效,则立即退出
  72. {
  73. ret = 0;
  74. break;
  75. }
  76. else // 队列空且阻塞标志有效,则等待
  77. {
  78. if (SDL_MUTEX_TIMEDOUT == SDL_CondWaitTimeout(q->packet_cond, q->mutex, 1000)){
  79. break;
  80. }
  81. }
  82. }
  83. SDL_UnlockMutex(q->mutex);
  84. return ret;
  85. }
  86. int packet_queue_put_nullpacket(packet_queue_t *q, int stream_index, CMediaHostApi* hostapi)
  87. {
  88. AVPacket pkt1, *pkt = &pkt1;
  89. av_init_packet(pkt);
  90. pkt->data = NULL;
  91. pkt->size = 0;
  92. pkt->stream_index = stream_index;
  93. return packet_queue_put(q, pkt, hostapi);
  94. }
  95. void packet_queue_flush(packet_queue_t *q)
  96. {
  97. AVPacketList *pkt, *pkt1;
  98. SDL_LockMutex(q->mutex);
  99. for (pkt = q->first_pkt; pkt; pkt = pkt1) {
  100. pkt1 = pkt->next;
  101. if (pkt->pkt.size > 0)
  102. {
  103. q->packet_queue_size -= pkt->pkt.size;
  104. av_packet_unref(&pkt->pkt);
  105. av_freep(&pkt);
  106. q->nb_packets--;
  107. }
  108. }
  109. q->last_pkt = NULL;
  110. q->first_pkt = NULL;
  111. q->nb_packets = 0;
  112. q->packet_queue_size = 0;
  113. q->duration = 0;
  114. SDL_UnlockMutex(q->mutex);
  115. }
  116. void packet_queue_destroy(packet_queue_t *q, CMediaHostApi* m_hostapi)
  117. {
  118. packet_queue_flush(q);
  119. SDL_DestroyMutex(q->mutex);
  120. SDL_DestroyCond(q->packet_cond);
  121. }
  122. void packet_queue_abort(packet_queue_t *q, CMediaHostApi* m_hostapi)
  123. {
  124. SDL_LockMutex(q->mutex);
  125. q->abort_flag = 1;
  126. SDL_CondSignal(q->packet_cond);
  127. SDL_UnlockMutex(q->mutex);
  128. }