不知道是我的原因还是那个项目作者改的,AVFormat.h中的AVPacketList的AVPacket成员被加了个指针。
AVFormat.h(源码中的):
typedef struct AVPacketList {
AVPacket pkt;
struct AVPacketList *next;
} AVPacketList;
AVFormat.h(被修改的)
typedef struct AVPacketList {
AVPacket *pkt;
struct AVPacketList *next;
} AVPacketList;
这导致了ffplay源码中处理packet链表由直接取地址赋值变为深拷贝:
ffplay.c(源码中的)
static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
{
AVPacketList *pkt1;
if (q->abort_request)
return -1;
//PacketList将Packet组成一个链表
//每个PacketList只有一个Packet
pkt1 = (AVPacketList*)av_malloc(sizeof(AVPacketList));
if (!pkt1)
return -1;
pkt1->pkt = *pkt;
pkt1->next = NULL;
if (!q->last_pkt)
//第一个
q->first_pkt = pkt1;
else
//其他情况
q->last_pkt->next = pkt1;
q->last_pkt = pkt1;
q->nb_packets++;
q->size += pkt1->pkt.size + sizeof(*pkt1);
/* XXX: should duplicate packet data in DV case */
SDL_CondSignal(q->cond);
return 0;
}
ffplay.c(修改后的)
int packet_queue_put(PacketQueue *q, AVPacket *pkt)
{
AVPacketList *pkt1;
//if (pkt != flush_pkt && av_packet_ref(pkt, flush_pkt) < 0) {
// return -1;
//}
pkt1 = (AVPacketList*)av_malloc(sizeof(AVPacketList));
if (!pkt1)
return -1;
pkt1->pkt = (AVPacket*)av_packet_alloc(); //这里做法其实不好,这里是将avformat.h中的AVPacket pkt改为AVPacket *pkt。所以导致下面要做深拷贝,没办法直结构体赋值。
av_copy_packet(pkt1->pkt ,pkt);
pkt1->next = NULL;
SDL_LockMutex(q->mutex);
if (!q->last_pkt)
q->first_pkt = pkt1;
else
q->last_pkt->next = pkt1;
q->last_pkt = pkt1;
q->nb_packets++;
q->size += pkt1->pkt->size;
SDL_CondSignal(q->cond);
SDL_UnlockMutex(q->mutex);
return 0;
}
结构体赋值和packet_copy其实做的都是深拷贝,只不过结构体赋值的方式更简单,而且底层还可以充分利用栈的特性。
网友评论