提交 1a3ef752 编写于 作者: Z Zhang Rui

jni: ijkplayer: use ffmpeg locking api

上级 6e0a693d
...@@ -24,147 +24,4 @@ ...@@ -24,147 +24,4 @@
#include "ffplay_pkt_queue.h" #include "ffplay_pkt_queue.h"
static AVPacket flush_pkt; AVPacket flush_pkt;
int packet_queue_put(PacketQueue *q, AVPacket *pkt);
static 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 == &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 */
SDL_CondSignal(q->cond);
return 0;
}
int packet_queue_put(PacketQueue *q, AVPacket *pkt)
{
int ret;
/* duplicate the packet */
if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
return -1;
SDL_LockMutex(q->mutex);
ret = packet_queue_put_private(q, pkt);
SDL_UnlockMutex(q->mutex);
if (pkt != &flush_pkt && ret < 0)
av_free_packet(pkt);
return ret;
}
/* packet queue handling */
void packet_queue_init(PacketQueue *q)
{
memset(q, 0, sizeof(PacketQueue));
q->mutex = SDL_CreateMutex();
q->cond = SDL_CreateCond();
q->abort_request = 1;
}
void packet_queue_flush(PacketQueue *q)
{
MyAVPacketList *pkt, *pkt1;
SDL_LockMutex(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;
SDL_UnlockMutex(q->mutex);
}
void packet_queue_destroy(PacketQueue *q)
{
packet_queue_flush(q);
SDL_DestroyMutex(q->mutex);
SDL_DestroyCond(q->cond);
}
void packet_queue_abort(PacketQueue *q)
{
SDL_LockMutex(q->mutex);
q->abort_request = 1;
SDL_CondSignal(q->cond);
SDL_UnlockMutex(q->mutex);
}
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);
}
/* 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;
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);
*pkt = pkt1->pkt;
if (serial)
*serial = pkt1->serial;
av_free(pkt1);
ret = 1;
break;
} else if (!block) {
ret = 0;
break;
} else {
SDL_CondWait(q->cond, q->mutex);
}
}
SDL_UnlockMutex(q->mutex);
return ret;
}
AVPacket *packet_get_flush_pkt()
{
return &flush_pkt;
}
...@@ -44,16 +44,150 @@ typedef struct PacketQueue { ...@@ -44,16 +44,150 @@ typedef struct PacketQueue {
SDL_cond *cond; SDL_cond *cond;
} PacketQueue; } PacketQueue;
void packet_queue_init(PacketQueue *q); AVPacket flush_pkt;
void packet_queue_destroy(PacketQueue *q);
void packet_queue_start(PacketQueue *q); inline static int packet_queue_put(PacketQueue *q, AVPacket *pkt);
void packet_queue_abort(PacketQueue *q);
void packet_queue_flush(PacketQueue *q);
int packet_queue_put(PacketQueue *q, AVPacket *pkt); inline static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block, int *serial); {
MyAVPacketList *pkt1;
AVPacket *packet_get_flush_pkt(); if (q->abort_request)
return -1;
pkt1 = av_malloc(sizeof(MyAVPacketList));
if (!pkt1)
return -1;
pkt1->pkt = *pkt;
pkt1->next = NULL;
if (pkt == &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 */
SDL_CondSignal(q->cond);
return 0;
}
inline static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
{
int ret;
/* duplicate the packet */
if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
return -1;
SDL_LockMutex(q->mutex);
ret = packet_queue_put_private(q, pkt);
SDL_UnlockMutex(q->mutex);
if (pkt != &flush_pkt && ret < 0)
av_free_packet(pkt);
return ret;
}
/* packet queue handling */
inline static void packet_queue_init(PacketQueue *q)
{
memset(q, 0, sizeof(PacketQueue));
q->mutex = SDL_CreateMutex();
q->cond = SDL_CreateCond();
q->abort_request = 1;
}
inline static void packet_queue_flush(PacketQueue *q)
{
MyAVPacketList *pkt, *pkt1;
SDL_LockMutex(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;
SDL_UnlockMutex(q->mutex);
}
inline static void packet_queue_destroy(PacketQueue *q)
{
packet_queue_flush(q);
SDL_DestroyMutex(q->mutex);
SDL_DestroyCond(q->cond);
}
inline static void packet_queue_abort(PacketQueue *q)
{
SDL_LockMutex(q->mutex);
q->abort_request = 1;
SDL_CondSignal(q->cond);
SDL_UnlockMutex(q->mutex);
}
inline 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);
}
/* return < 0 if aborted, 0 if no packet and > 0 if packet. */
inline 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);
*pkt = pkt1->pkt;
if (serial)
*serial = pkt1->serial;
av_free(pkt1);
ret = 1;
break;
} else if (!block) {
ret = 0;
break;
} else {
SDL_CondWait(q->cond, q->mutex);
}
}
SDL_UnlockMutex(q->mutex);
return ret;
}
inline static void packet_queue_global_init()
{
av_init_packet(&flush_pkt);
flush_pkt.data = (uint8_t *)(intptr_t)"FLUSH";
}
#endif #endif
...@@ -379,7 +379,7 @@ static int audio_decode_frame(VideoState *is) ...@@ -379,7 +379,7 @@ static int audio_decode_frame(VideoState *is)
if ((new_packet = packet_queue_get(&is->audioq, pkt, 1, &is->audio_pkt_temp_serial)) < 0) if ((new_packet = packet_queue_get(&is->audioq, pkt, 1, &is->audio_pkt_temp_serial)) < 0)
return -1; return -1;
if (pkt->data == packet_get_flush_pkt()->data) { if (pkt->data == flush_pkt.data) {
avcodec_flush_buffers(dec); avcodec_flush_buffers(dec);
flush_complete = 0; flush_complete = 0;
} }
...@@ -874,15 +874,15 @@ int ijkff_read_thread(void *arg) ...@@ -874,15 +874,15 @@ int ijkff_read_thread(void *arg)
} else { } else {
if (is->audio_stream >= 0) { if (is->audio_stream >= 0) {
packet_queue_flush(&is->audioq); packet_queue_flush(&is->audioq);
packet_queue_put(&is->audioq, packet_get_flush_pkt()); packet_queue_put(&is->audioq, &flush_pkt);
} }
if (is->subtitle_stream >= 0) { if (is->subtitle_stream >= 0) {
packet_queue_flush(&is->subtitleq); packet_queue_flush(&is->subtitleq);
packet_queue_put(&is->subtitleq, packet_get_flush_pkt()); packet_queue_put(&is->subtitleq, &flush_pkt);
} }
if (is->video_stream >= 0) { if (is->video_stream >= 0) {
packet_queue_flush(&is->videoq); packet_queue_flush(&is->videoq);
packet_queue_put(&is->videoq, packet_get_flush_pkt()); packet_queue_put(&is->videoq, &flush_pkt);
} }
if (is->seek_flags & AVSEEK_FLAG_BYTE) { if (is->seek_flags & AVSEEK_FLAG_BYTE) {
update_external_clock_pts(is, NAN); update_external_clock_pts(is, NAN);
......
...@@ -27,20 +27,48 @@ ...@@ -27,20 +27,48 @@
#include <stdbool.h> #include <stdbool.h>
static bool g_ffmpeg_global_inited = false; static bool g_ffmpeg_global_inited = false;
static pthread_mutex_t g_avcodec_mutex;
static int lockmgr(void **mtx, enum AVLockOp op)
{
switch(op) {
case AV_LOCK_CREATE:
*mtx = SDL_CreateMutex();
if(!*mtx)
return 1;
return 0;
case AV_LOCK_OBTAIN:
return !!SDL_LockMutex(*mtx);
case AV_LOCK_RELEASE:
return !!SDL_UnlockMutex(*mtx);
case AV_LOCK_DESTROY:
SDL_DestroyMutex(*mtx);
return 0;
}
return 1;
}
void ijkff_global_init() void ijkff_global_init()
{ {
if (g_ffmpeg_global_inited) if (g_ffmpeg_global_inited)
return; return;
pthread_mutex_init(&g_avcodec_mutex, NULL); /* register all codecs, demux and protocols */
av_register_all();
avcodec_register_all(); avcodec_register_all();
#if CONFIG_AVDEVICE
avdevice_register_all();
#endif
#if CONFIG_AVFILTER
avfilter_register_all();
#endif
av_register_all();
avformat_network_init(); avformat_network_init();
av_lockmgr_register(lockmgr);
/* FIXME: SDL_Init() */
packet_queue_global_init();
g_ffmpeg_global_inited = true; g_ffmpeg_global_inited = true;
} }
...@@ -49,20 +77,14 @@ void ijkff_global_uninit() ...@@ -49,20 +77,14 @@ void ijkff_global_uninit()
if (!g_ffmpeg_global_inited) if (!g_ffmpeg_global_inited)
return; return;
pthread_mutex_destroy(&g_avcodec_mutex); av_lockmgr_register(NULL);
g_ffmpeg_global_inited = false;
}
void ijkff_avcodec_lock() #if CONFIG_AVFILTER
{ avfilter_uninit();
if (!g_ffmpeg_global_inited) av_freep(&vfilters);
return; #endif
pthread_mutex_lock(&g_avcodec_mutex); avformat_network_deinit();
} /* FIXME: SDL_Quit(); */
void ijkff_avcodec_unlock() g_ffmpeg_global_inited = false;
{
if (!g_ffmpeg_global_inited)
return;
pthread_mutex_unlock(&g_avcodec_mutex);
} }
...@@ -142,22 +142,5 @@ inline static void ijkff_reset(FFPlayer *ffp) ...@@ -142,22 +142,5 @@ inline static void ijkff_reset(FFPlayer *ffp)
void ijkff_global_init(); void ijkff_global_init();
void ijkff_global_uninit(); void ijkff_global_uninit();
/*
* ffmpeg api listed below must be locked
*
* av_set_cpu_flags_mask();
* av_register_all();
* avcodec_register_all();
*
* avcodec_open
* avcodec_open2
* avcodec_close
*
* avformat_find_stream_info
* av_find_stream_info
*/
void ijkff_avcodec_lock();
void ijkff_avcodec_unlock();
#endif #endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册