提交 148353ca 编写于 作者: Z Zhang Rui

ijkmedia: ffplay: introduce pkt_queue

上级 7e59d851
......@@ -4,7 +4,10 @@ include $(CLEAR_VARS)
LOCAL_C_INCLUDES += $(LOCAL_PATH) $(MY_APP_FFMPEG_INCLUDE_PATH)
# LOCAL_LDLIBS += -ldl -llog
LOCAL_SRC_FILES := ffplay.c
LOCAL_SRC_FILES := pkt_queue.c
LOCAL_SRC_FILES += ffplay.c
LOCAL_SHARED_LIBRARIES := ffmpeg
LOCAL_MODULE := ffplay
include $(BUILD_SHARED_LIBRARY)
\ No newline at end of file
/*****************************************************************************
* pkt_queue.c
*****************************************************************************
*
* copyright (c) 2001 Fabrice Bellard
* copyright (c) 2013 Zhang Rui <bbcallen@gmail.com>
*
* Based on ffmpeg/ffplay.c
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "pkt_queue.h"
AVPacket g_flush_pkt;
int packet_queue_put(PacketQueue *q, AVPacket *pkt);
int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
{
MyAVPacketList *pkt1;
if (q->abort_request)
return -1;
pkt1 = av_malloc(sizeof(MyAVPacketList));
if (!pkt1)
return -1;
pkt1->pkt = *pkt;
pkt1->next = NULL;
if (pkt == &g_flush_pkt)
q->serial++;
pkt1->serial = q->serial;
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 */
pthread_cond_signal(&q->cond);
return 0;
}
int packet_queue_put(PacketQueue *q, AVPacket *pkt)
{
int ret;
/* duplicate the packet */
if (pkt != &g_flush_pkt && av_dup_packet(pkt) < 0)
return -1;
pthread_mutex_lock(&q->mutex);
ret = packet_queue_put_private(q, pkt);
pthread_mutex_unlock(&q->mutex);
if (pkt != &g_flush_pkt && ret < 0)
av_free_packet(pkt);
return ret;
}
/* packet queue handling */
void packet_queue_init(PacketQueue *q)
{
memset(q, 0, sizeof(PacketQueue));
pthread_mutex_init(&q->mutex, NULL);
pthread_cond_init(&q->cond, NULL);
q->abort_request = 1;
}
void packet_queue_flush(PacketQueue *q)
{
MyAVPacketList *pkt, *pkt1;
pthread_mutex_lock(&q->mutex);
for (pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
pkt1 = pkt->next;
av_free_packet(&pkt->pkt);
av_freep(&pkt);
}
q->last_pkt = NULL;
q->first_pkt = NULL;
q->nb_packets = 0;
q->size = 0;
pthread_mutex_unlock(&q->mutex);
}
void packet_queue_destroy(PacketQueue *q)
{
packet_queue_flush(q);
pthread_mutex_destroy(&q->mutex);
pthread_cond_destroy(&q->cond);
}
void packet_queue_abort(PacketQueue *q)
{
pthread_mutex_lock(&q->mutex);
q->abort_request = 1;
pthread_cond_signal(&q->cond);
pthread_mutex_unlock(&q->mutex);
}
void packet_queue_start(PacketQueue *q)
{
pthread_mutex_lock(&q->mutex);
q->abort_request = 0;
packet_queue_put_private(q, &g_flush_pkt);
pthread_mutex_unlock(&q->mutex);
}
/* return < 0 if aborted, 0 if no packet and > 0 if packet. */
int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial)
{
MyAVPacketList *pkt1;
int ret;
pthread_mutex_lock(&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);
*pkt = pkt1->pkt;
if (serial)
*serial = pkt1->serial;
av_free(pkt1);
ret = 1;
break;
} else if (!block) {
ret = 0;
break;
} else {
pthread_cond_wait(&q->cond, &q->mutex);
}
}
pthread_mutex_unlock(&q->mutex);
return ret;
}
/*****************************************************************************
* pkt_queue.h
*****************************************************************************
*
* copyright (c) 2001 Fabrice Bellard
* copyright (c) 2013 Zhang Rui <bbcallen@gmail.com>
*
* Based on ffmpeg/ffplay.c
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef PKT_QUEUE_H
#define PKT_QUEUE_H
#include <pthread.h>
#include <libavformat/avformat.h>
typedef struct MyAVPacketList {
AVPacket pkt;
struct MyAVPacketList *next;
int serial;
} MyAVPacketList;
typedef struct PacketQueue {
MyAVPacketList *first_pkt, *last_pkt;
int nb_packets;
int size;
int abort_request;
int serial;
pthread_mutex_t mutex;
pthread_cond_t cond;
} PacketQueue;
void packet_queue_init(PacketQueue *q);
void packet_queue_destroy(PacketQueue *q);
void packet_queue_start(PacketQueue *q);
void packet_queue_abort(PacketQueue *q);
void packet_queue_flush(PacketQueue *q);
int packet_queue_put(PacketQueue *q, AVPacket *pkt);
int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial);
#endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册