当前位置:网站首页>Ijkplayer source code ---packetqueue
Ijkplayer source code ---packetqueue
2022-06-13 02:43:00 【Original general breaking】
We will not discuss in this article PacketQueue stay ijk Where to use , Only from PacketQueue Start with the code
Let's start with two structures
typedef struct MyAVPacketList {
AVPacket pkt;
struct MyAVPacketList *next;
int serial;
} MyAVPacketList;
You can see through the structure MyAVPacketList Is a node of a linked list , Each node contains unpacked AVPacket
typedef struct PacketQueue {
MyAVPacketList *first_pkt, *last_pkt; //first_pkt Point to MyAVPacketList Is the head node of the node ,last_pkt Point to the tail node
int nb_packets; // How many are there at the moment AVPacket
int size; // How much memory does the current linked list and the data in the linked list occupy
int64_t duration;
int abort_request;
int serial;
SDL_mutex *mutex; // The mutex
SDL_cond *cond; // Semaphore
MyAVPacketList *recycle_pkt; //MyAVPacketList Recycling linked list of , Avoid creating... Every time MyAVPacketList, Speed up
int recycle_count; // Reuse several MyAVPacketList
int alloc_count;
int is_buffer_indicator;
} PacketQueue;
static int packet_queue_init(PacketQueue *q)
{
memset(q, 0, sizeof(PacketQueue));
q->mutex = SDL_CreateMutex();
if (!q->mutex) {
av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
return AVERROR(ENOMEM);
}
q->cond = SDL_CreateCond();
if (!q->cond) {
av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
return AVERROR(ENOMEM);
}
q->abort_request = 1;
return 0;
} Initialization is to initialize PacketQueue Members in are set to 0, Create a lock , Semaphore, etc
static void packet_queue_start(PacketQueue *q)
{
SDL_LockMutex(q->mutex);
q->abort_request = 0;
packet_queue_put_private(q, &flush_pkt);
SDL_UnlockMutex(q->mutex);
}packet_queue_start stay PacketQueue Put... First flush_pkt
What is? flush_pkt?
av_init_packet(&flush_pkt);
flush_pkt.data = (uint8_t *)&flush_pkt;
data Points to real data
flush_pkt.data = (uint8_t *)&flush_pkt; This explanation data Points to its own AvPacket
Let's take a look at packet_queue_put_private
static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
{
MyAVPacketList *pkt1;
// Termination request , So long no longer PacketQueue Put the data in
if (q->abort_request)
return -1;
//ffplay The source code of is to create a new node each time , and ijk Optimized , If recycle_pkt If there are available nodes, use , If not, allocate , also alloc_count Add 1,
#ifdef FFP_MERGE
pkt1 = av_malloc(sizeof(MyAVPacketList));
#else
pkt1 = q->recycle_pkt;
if (pkt1) {
q->recycle_pkt = pkt1->next;
q->recycle_count++;
} else {
q->alloc_count++;
pkt1 = av_malloc(sizeof(MyAVPacketList));
}
#ifdef FFP_SHOW_PKT_RECYCLE
int total_count = q->recycle_count + q->alloc_count;
if (!(total_count % 50)) {
av_log(ffp, AV_LOG_DEBUG, "pkt-recycle \t%d + \t%d = \t%d\n", q->recycle_count, q->alloc_count, total_count);
}
#endif
#endif
if (!pkt1)
return -1;
pkt1->pkt = *pkt;
pkt1->next = NULL;
// If it is currently flush_pkt, then serial++
if (pkt == &flush_pkt)
q->serial++;
pkt1->serial = q->serial;
If it's the first node , So it's first_pkt assignment
if (!q->last_pkt)
q->first_pkt = pkt1;
else
q->last_pkt->next = pkt1;
q->last_pkt = pkt1;
q->nb_packets++; // How many packages are there currently
q->size += pkt1->pkt.size + sizeof(*pkt1); // How much memory does the data in the current linked list occupy
q->duration += FFMAX(pkt1->pkt.duration, MIN_PKT_DURATION); // How long can the current linked list be played
/* XXX: should duplicate packet data in DV case */
SDL_CondSignal(q->cond);
return 0;
}From the above, we can know that the final linked list should be like this 、

static void packet_queue_flush(PacketQueue *q)
{
MyAVPacketList *pkt, *pkt1;
SDL_LockMutex(q->mutex);
for (pkt = q->first_pkt; pkt; pkt = pkt1) {
pkt1 = pkt->next;
av_packet_unref(&pkt->pkt);
#ifdef FFP_MERGE
av_freep(&pkt);
#else
pkt->next = q->recycle_pkt;
q->recycle_pkt = pkt;
#endif
}
q->last_pkt = NULL;
q->first_pkt = NULL;
q->nb_packets = 0;
q->size = 0;
q->duration = 0;
SDL_UnlockMutex(q->mutex);
}// Looking at the code means that PacketQueue Medium first_pkt In the list AVPacket Release , And put MyAVPacketList Put the node in recycle_pkt, Other fields are set to 0
static void packet_queue_destroy(PacketQueue *q)
{
// hold PacketQueue Medium first_pkt In the list AVPacket Release , And put MyAVPacketList Put the node in recycle_pkt, Other fields are set to 0
packet_queue_flush(q);
SDL_LockMutex(q->mutex);
// Release all recycle_pkt The nodes in the
while(q->recycle_pkt) {
MyAVPacketList *pkt = q->recycle_pkt;
if (pkt)
q->recycle_pkt = pkt->next;
av_freep(&pkt);
}
SDL_UnlockMutex(q->mutex);
SDL_DestroyMutex(q->mutex);
SDL_DestroyCond(q->cond);
}
static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
{
MyAVPacketList *pkt1;
int ret;
SDL_LockMutex(q->mutex);
for (;;) {
if (q->abort_request) {
ret = -1;
break;
}
pkt1 = q->first_pkt;
if (pkt1) {
q->first_pkt = pkt1->next;
if (!q->first_pkt)
q->last_pkt = NULL;
q->nb_packets--;
q->size -= pkt1->pkt.size + sizeof(*pkt1);
q->duration -= FFMAX(pkt1->pkt.duration, MIN_PKT_DURATION);
*pkt = pkt1->pkt;
if (serial)
*serial = pkt1->serial;
#ifdef FFP_MERGE
av_free(pkt1);
#else
pkt1->next = q->recycle_pkt;
q->recycle_pkt = pkt1;
#endif
ret = 1;
break;
} else if (!block) {
ret = 0;
break;
} else {
SDL_CondWait(q->cond, q->mutex);
}
}
SDL_UnlockMutex(q->mutex);
return ret;
}
//
static int packet_queue_get_or_buffering(FFPlayer *ffp, PacketQueue *q, AVPacket *pkt, int *serial, int *finished)
{
assert(finished);
if (!ffp->packet_buffering)
return packet_queue_get(q, pkt, 1, serial);
while (1) {
int new_packet = packet_queue_get(q, pkt, 0, serial);
if (new_packet < 0)
return -1;
else if (new_packet == 0) {
if (q->is_buffer_indicator && !*finished)
ffp_toggle_buffering(ffp, 1);
new_packet = packet_queue_get(q, pkt, 1, serial);
if (new_packet < 0)
return -1;
}
if (*finished == *serial) {
av_packet_unref(pkt);
continue;
}
else
break;
}
return 1;
}// Take out first_pkt The node pointed to corresponds to AVPacket, And release the MyAVPacketList Put in recycle_pkt
static int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
{
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);
}// Put a... In the queue AVPacket Of data by null The data of
边栏推荐
- Uni app Foundation
- How did you spend your winter vacation perfectly?
- Logiciel professionnel de gestion de base de données: Valentina Studio Pro pour Mac
- Multiple knapsack problem
- House raiding
- Opencv 08 demonstrates the effect of opening and closing operations of erode, dilate and morphological function morphologyex.
- Word splitting problem
- Detailed explanation of UCI datasets and their data processing (with 148 datasets and processing codes attached)
- redis.conf总配置详解
- regular expression
猜你喜欢

02 优化微信开发者工具默认的结构

How to destroy a fragment- How to destroy Fragment?

在IDEA使用C3P0连接池连接SQL数据库后却不能显示数据库内容

05 tabbar navigation bar function

Logiciel professionnel de gestion de base de données: Valentina Studio Pro pour Mac

Detailed explanation of data processing in machine learning (I) -- missing value processing (complete code attached)
![Leetcode 473. Match to square [violence + pruning]](/img/3a/975b91dd785e341c561804175b6439.png)
Leetcode 473. Match to square [violence + pruning]

L1 regularization and its sparsity

Opencvsharp4 handwriting recognition

数仓笔记|针对客户维度建模需要关注的5个因素
随机推荐
[common tools] pyautogui tutorial
The weight of the input and textarea components of the applet is higher than that of the fixed Z-index
[thoughts in the essay] mourn for development technology expert Mao Xingyun
小程序 input,textarea组件权重比fixed的z-index都高
Laravel 权限导出
在IDEA使用C3P0连接池连接SQL数据库后却不能显示数据库内容
regular expression
Ffmpeg principle
Detailed explanation of data processing in machine learning (I) -- missing value processing (complete code attached)
Retrofit easy to use
Opencvsharp4 pixel read / write and memory structure of color image and gray image
遍历数组,删除某元素,直到删除为止
Traverse the array and delete an element until it is deleted
数字IC设计——FIFO的设计
OneNote使用指南(一)
[data analysis and visualization] key points of data drawing 3- spaghetti map
Word splitting problem
Principle and steps of principal component analysis (PCA)
Change the topic of change tax
Hstack, vstack and dstack in numpy