123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- #include "packet.h"
- int packet_queue_init(packet_queue_t *q, CMediaHostApi* hostapi)
- {
- memset(q, 0, sizeof(packet_queue_t));
- q->mutex = SDL_CreateMutex();
- if (!q->mutex){
- hostapi->Debug(MEDIA_LOG_DEBUG, "SDL_CreateMutex(): %s.", SDL_GetError());
- return AVERROR(ENOMEM);
- }
- q->packet_cond = SDL_CreateCond();
- if (!q->packet_cond){
- hostapi->Debug(MEDIA_LOG_DEBUG, "SDL_CreateCond(): %s.", SDL_GetError());
- return AVERROR(ENOMEM);
- }
- q->abort_flag = 0;
- return 0;
- }
- // 写队列尾部。pkt是一包还未解码的音频数据
- int packet_queue_put(packet_queue_t *q, AVPacket *pkt, CMediaHostApi* hostapi)
- {
- AVPacketList* pkt_list = NULL;
- if (av_packet_make_refcounted(pkt) < 0){
- hostapi->Debug(MEDIA_LOG_DEBUG, "[pkt] is not refrence counted.");
- return -1;
- }
- pkt_list = (AVPacketList*)av_malloc(sizeof(AVPacketList));
- if (!pkt_list){
- return -1;
- }
-
- pkt_list->pkt = *pkt;
- pkt_list->next = NULL;
- SDL_LockMutex(q->mutex);
- // 队列为空
- if (!q->last_pkt){
- q->first_pkt = pkt_list;
- }
- else{
- q->last_pkt->next = pkt_list;
- }
- q->last_pkt = pkt_list;
- q->nb_packets++;
- q->packet_queue_size += pkt_list->pkt.size;
- // 发个条件变量的信号:重启等待q->cond条件变量的一个线程
- SDL_CondSignal(q->packet_cond);
- SDL_UnlockMutex(q->mutex);
- return 0;
- }
- // 读队列头部。
- int packet_queue_get(packet_queue_t *q, AVPacket *pkt, int block, CMediaHostApi* hostapi)
- {
- AVPacketList *p_pkt_node = NULL;
- int ret = -1;
- SDL_LockMutex(q->mutex);
- while (0 == q->abort_flag)
- {
- p_pkt_node = q->first_pkt;
- if (p_pkt_node) // 队列非空,取一个出来
- {
- q->first_pkt = p_pkt_node->next;
- if (!q->first_pkt)
- {
- q->last_pkt = NULL;
- }
- q->nb_packets--;
- q->packet_queue_size -= p_pkt_node->pkt.size;
- *pkt = p_pkt_node->pkt;
- av_free(p_pkt_node);
- ret = 1;
- break;
- }
- else if (!block) // 队列空且阻塞标志无效,则立即退出
- {
- ret = 0;
- break;
- }
- else // 队列空且阻塞标志有效,则等待
- {
- if (SDL_MUTEX_TIMEDOUT == SDL_CondWaitTimeout(q->packet_cond, q->mutex, 1000)){
- break;
- }
- }
- }
- SDL_UnlockMutex(q->mutex);
- return ret;
- }
- int packet_queue_put_nullpacket(packet_queue_t *q, int stream_index, CMediaHostApi* hostapi)
- {
- AVPacket pkt1, *pkt = &pkt1;
- av_init_packet(pkt);
- pkt->data = NULL;
- pkt->size = 0;
- pkt->stream_index = stream_index;
- return packet_queue_put(q, pkt, hostapi);
- }
- void packet_queue_flush(packet_queue_t *q)
- {
- AVPacketList *pkt, *pkt1;
- SDL_LockMutex(q->mutex);
- for (pkt = q->first_pkt; pkt; pkt = pkt1) {
- pkt1 = pkt->next;
- if (pkt->pkt.size > 0)
- {
- q->packet_queue_size -= pkt->pkt.size;
- av_packet_unref(&pkt->pkt);
- av_freep(&pkt);
- q->nb_packets--;
- }
- }
- q->last_pkt = NULL;
- q->first_pkt = NULL;
- q->nb_packets = 0;
- q->packet_queue_size = 0;
- q->duration = 0;
- SDL_UnlockMutex(q->mutex);
- }
- void packet_queue_destroy(packet_queue_t *q, CMediaHostApi* m_hostapi)
- {
- packet_queue_flush(q);
- SDL_DestroyMutex(q->mutex);
- SDL_DestroyCond(q->packet_cond);
- }
- void packet_queue_abort(packet_queue_t *q, CMediaHostApi* m_hostapi)
- {
- SDL_LockMutex(q->mutex);
- q->abort_flag = 1;
- SDL_CondSignal(q->packet_cond);
- SDL_UnlockMutex(q->mutex);
- }
|