mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-28 02:30:35 +00:00
138 lines
2.7 KiB
C
138 lines
2.7 KiB
C
#include "packet_buffer.h"
|
|
|
|
struct AVPacketNode
|
|
{
|
|
AVPacket *data;
|
|
struct AVPacketNode *next;
|
|
struct AVPacketNode *previous;
|
|
};
|
|
|
|
typedef struct AVPacketNode AVPacketNode_t;
|
|
|
|
struct packet_buffer
|
|
{
|
|
AVPacketNode_t *head;
|
|
AVPacketNode_t *tail;
|
|
size_t size;
|
|
};
|
|
|
|
packet_buffer_t *packet_buffer_create(void)
|
|
{
|
|
packet_buffer_t *b = (packet_buffer_t*)malloc(sizeof(packet_buffer_t));
|
|
if (!b)
|
|
return NULL;
|
|
|
|
memset(b, 0, sizeof(packet_buffer_t));
|
|
|
|
return b;
|
|
}
|
|
|
|
void packet_buffer_destroy(packet_buffer_t *packet_buffer)
|
|
{
|
|
AVPacketNode_t *node;
|
|
|
|
if (!packet_buffer)
|
|
return;
|
|
|
|
if (packet_buffer->head)
|
|
{
|
|
node = packet_buffer->head;
|
|
while (node)
|
|
{
|
|
AVPacketNode_t *next = node->next;
|
|
av_packet_free(&node->data);
|
|
free(node);
|
|
node = next;
|
|
}
|
|
}
|
|
|
|
free(packet_buffer);
|
|
}
|
|
|
|
void packet_buffer_clear(packet_buffer_t **packet_buffer)
|
|
{
|
|
if (!packet_buffer)
|
|
return;
|
|
|
|
packet_buffer_destroy(*packet_buffer);
|
|
*packet_buffer = packet_buffer_create();
|
|
}
|
|
|
|
bool packet_buffer_empty(packet_buffer_t *packet_buffer)
|
|
{
|
|
if (!packet_buffer)
|
|
return true;
|
|
|
|
return packet_buffer->size == 0;
|
|
}
|
|
|
|
size_t packet_buffer_size(packet_buffer_t *packet_buffer)
|
|
{
|
|
if (!packet_buffer)
|
|
return 0;
|
|
|
|
return packet_buffer->size;
|
|
}
|
|
|
|
void packet_buffer_add_packet(packet_buffer_t *packet_buffer, AVPacket *pkt)
|
|
{
|
|
AVPacketNode_t *new_head = (AVPacketNode_t *) malloc(sizeof(AVPacketNode_t));
|
|
new_head->data = av_packet_alloc();
|
|
|
|
av_packet_move_ref(new_head->data, pkt);
|
|
|
|
if (packet_buffer->head)
|
|
{
|
|
new_head->next = packet_buffer->head;
|
|
packet_buffer->head->previous = new_head;
|
|
}
|
|
else
|
|
{
|
|
new_head->next = NULL;
|
|
packet_buffer->tail = new_head;
|
|
}
|
|
|
|
packet_buffer->head = new_head;
|
|
packet_buffer->head->previous = NULL;
|
|
packet_buffer->size++;
|
|
}
|
|
|
|
void packet_buffer_get_packet(packet_buffer_t *packet_buffer, AVPacket *pkt)
|
|
{
|
|
AVPacketNode_t *new_tail = NULL;
|
|
|
|
if (!packet_buffer->tail)
|
|
return;
|
|
|
|
av_packet_move_ref(pkt, packet_buffer->tail->data);
|
|
if (packet_buffer->tail->previous)
|
|
{
|
|
new_tail = packet_buffer->tail->previous;
|
|
new_tail->next = NULL;
|
|
}
|
|
else
|
|
packet_buffer->head = NULL;
|
|
|
|
av_packet_free(&packet_buffer->tail->data);
|
|
free(packet_buffer->tail);
|
|
|
|
packet_buffer->tail = new_tail;
|
|
packet_buffer->size--;
|
|
}
|
|
|
|
int64_t packet_buffer_peek_start_pts(packet_buffer_t *packet_buffer)
|
|
{
|
|
if (!packet_buffer->tail)
|
|
return 0;
|
|
|
|
return packet_buffer->tail->data->pts;
|
|
}
|
|
|
|
int64_t packet_buffer_peek_end_pts(packet_buffer_t *packet_buffer)
|
|
{
|
|
if (!packet_buffer->tail)
|
|
return 0;
|
|
|
|
return packet_buffer->tail->data->pts + packet_buffer->tail->data->duration;
|
|
}
|