parent
795fe94d56
commit
6ce7f8e6b3
@ -0,0 +1,254 @@ |
||||
|
||||
#ifndef FFMSG_QUEUE_H |
||||
#define FFMSG_QUEUE_H |
||||
|
||||
#include <mutex> |
||||
#include <libavutil/mem.h> |
||||
|
||||
/**************** msg define begin ***************/ |
||||
|
||||
#define FFP_MSG_FLUSH 0 |
||||
#define FFP_MSG_ERROR 100 |
||||
#define FFP_MSG_PREPARED 200 |
||||
#define FFP_MSG_COMPLETED 300 |
||||
#define FFP_MSG_VIDEO_SIZE_CHANGED 400 |
||||
#define FFP_MSG_SAR_CHANGED 401 |
||||
#define FFP_MSG_VIDEO_RENDERING_START 402 |
||||
#define FFP_MSG_AUDIO_RENDERING_START 403 |
||||
#define FFP_MSG_VIDEO_ROTATION_CHANGED 404 |
||||
#define FFP_MSG_AUDIO_DECODED_START 405 |
||||
#define FFP_MSG_VIDEO_DECODED_START 406 |
||||
#define FFP_MSG_OPEN_INPUT 407 |
||||
#define FFP_MSG_FIND_STREAM_INFO 408 |
||||
#define FFP_MSG_COMPONENT_OPEN 409 |
||||
#define FFP_MSG_VIDEO_SEEK_RENDERING_START 410 |
||||
#define FFP_MSG_AUDIO_SEEK_RENDERING_START 411 |
||||
|
||||
#define FFP_MSG_BUFFERING_START 500 |
||||
#define FFP_MSG_BUFFERING_END 501 |
||||
#define FFP_MSG_BUFFERING_UPDATE 502 |
||||
#define FFP_MSG_BUFFERING_BYTES_UPDATE 503 |
||||
#define FFP_MSG_BUFFERING_TIME_UPDATE 504 |
||||
#define FFP_MSG_SEEK_COMPLETE 600 |
||||
#define FFP_MSG_PLAYBACK_STATE_CHANGED 700 |
||||
#define FFP_MSG_TIMED_TEXT 800 |
||||
#define FFP_MSG_VIDEO_DECODER_OPEN 900 |
||||
|
||||
#define FFP_REQ_START 1001 |
||||
#define FFP_REQ_PAUSE 1002 |
||||
#define FFP_REQ_SEEK 1003 |
||||
|
||||
/**************** msg define end *****************/ |
||||
|
||||
typedef struct AVMessage { |
||||
int what; |
||||
int arg1; |
||||
int arg2; |
||||
void *obj; |
||||
void (*free_l)(void *obj); |
||||
struct AVMessage *next; |
||||
} AVMessage; |
||||
|
||||
typedef struct MessageQueue { |
||||
AVMessage *first_msg, *last_msg; |
||||
int nb_messages; |
||||
int abort_request; |
||||
std::mutex mutex; |
||||
std::condition_variable cond; |
||||
|
||||
AVMessage *recycle_msg; |
||||
int recycle_count; |
||||
int alloc_count; |
||||
} MessageQueue; |
||||
|
||||
inline static void msg_free(AVMessage *msg) { |
||||
if (!msg || !msg->obj) |
||||
return; |
||||
assert(msg->free_l); |
||||
msg->free_l(msg->obj); |
||||
msg->obj = nullptr; |
||||
} |
||||
|
||||
inline static int msg_queue_put_private(MessageQueue *q, AVMessage *msg) { |
||||
AVMessage *msg1; |
||||
|
||||
if (q->abort_request) |
||||
return -1; |
||||
|
||||
msg1 = q->recycle_msg; |
||||
if (msg1) { |
||||
q->recycle_msg = msg1->next; |
||||
q->recycle_count++; |
||||
} else { |
||||
q->alloc_count++; |
||||
msg1 = static_cast<AVMessage *>(av_malloc(sizeof(AVMessage))); |
||||
} |
||||
|
||||
if (!msg1) |
||||
return -1; |
||||
|
||||
*msg1 = *msg; |
||||
msg1->next = nullptr; |
||||
|
||||
if (!q->last_msg) |
||||
q->first_msg = msg1; |
||||
else |
||||
q->last_msg->next = msg1; |
||||
q->last_msg = msg1; |
||||
q->nb_messages++; |
||||
q->cond.notify_all(); |
||||
return 0; |
||||
} |
||||
|
||||
inline static int msg_queue_put(MessageQueue *q, AVMessage *msg) { |
||||
int ret; |
||||
|
||||
std::lock_guard<std::mutex> lock(q->mutex); |
||||
ret = msg_queue_put_private(q, msg); |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
inline static void msg_init_msg(AVMessage *msg) { |
||||
memset(msg, 0, sizeof(AVMessage)); |
||||
} |
||||
|
||||
inline static void msg_queue_put_notify1(MessageQueue *q, int what) { |
||||
AVMessage msg; |
||||
msg_init_msg(&msg); |
||||
msg.what = what; |
||||
msg_queue_put(q, &msg); |
||||
} |
||||
|
||||
inline static void msg_queue_put_notify2(MessageQueue *q, int what, int arg1) { |
||||
AVMessage msg; |
||||
msg_init_msg(&msg); |
||||
msg.what = what; |
||||
msg.arg1 = arg1; |
||||
msg_queue_put(q, &msg); |
||||
} |
||||
|
||||
inline static void msg_queue_put_notify3(MessageQueue *q, int what, int arg1, int arg2) { |
||||
AVMessage msg; |
||||
msg_init_msg(&msg); |
||||
msg.what = what; |
||||
msg.arg1 = arg1; |
||||
msg.arg2 = arg2; |
||||
msg_queue_put(q, &msg); |
||||
} |
||||
|
||||
inline static void msg_queue_init(MessageQueue *q) { |
||||
memset(q, 0, sizeof(MessageQueue)); |
||||
q->abort_request = 1; |
||||
} |
||||
|
||||
inline static void msg_queue_flush(MessageQueue *q) { |
||||
AVMessage *msg, *msg1; |
||||
std::lock_guard<std::mutex> lock(q->mutex); |
||||
|
||||
for (msg = q->first_msg; msg != NULL; msg = msg1) { |
||||
msg1 = msg->next; |
||||
msg->next = q->recycle_msg; |
||||
q->recycle_msg = msg; |
||||
} |
||||
q->last_msg = nullptr; |
||||
q->first_msg = nullptr; |
||||
q->nb_messages = 0; |
||||
} |
||||
|
||||
inline static void msg_queue_abort(MessageQueue *q) { |
||||
std::unique_lock<std::mutex> lock(q->mutex); |
||||
q->abort_request = 1; |
||||
q->cond.notify_all(); |
||||
} |
||||
|
||||
inline static void msg_queue_start(MessageQueue *q) { |
||||
std::lock_guard<std::mutex> lock(q->mutex); |
||||
q->abort_request = 0; |
||||
|
||||
AVMessage msg; |
||||
msg_init_msg(&msg); |
||||
msg.what = FFP_MSG_FLUSH; |
||||
msg_queue_put_private(q, &msg); |
||||
} |
||||
|
||||
inline static int msg_queue_get(MessageQueue *q, AVMessage *msg, int block) { |
||||
AVMessage *msg1; |
||||
int ret; |
||||
|
||||
std::unique_lock<std::mutex> lock(q->mutex); |
||||
|
||||
for (;;) { |
||||
if (q->abort_request) { |
||||
ret = -1; |
||||
break; |
||||
} |
||||
|
||||
msg1 = q->first_msg; |
||||
if (msg1) { |
||||
q->first_msg = msg1->next; |
||||
if (!q->first_msg) |
||||
q->last_msg = nullptr; |
||||
q->nb_messages--; |
||||
*msg = *msg1; |
||||
msg1->obj = nullptr; |
||||
msg1->next = q->recycle_msg; |
||||
q->recycle_msg = msg1; |
||||
ret = 1; |
||||
break; |
||||
} else if (!block) { |
||||
ret = 0; |
||||
break; |
||||
} else { |
||||
q->cond.wait(lock); |
||||
} |
||||
} |
||||
lock.unlock(); |
||||
return ret; |
||||
} |
||||
|
||||
inline static void msg_queue_remove(MessageQueue *q, int what) { |
||||
AVMessage **p_msg, *msg, *last_msg; |
||||
std::lock_guard<std::mutex> lock(q->mutex); |
||||
|
||||
last_msg = q->first_msg; |
||||
|
||||
if (!q->abort_request && q->first_msg) { |
||||
p_msg = &q->first_msg; |
||||
while (*p_msg) { |
||||
msg = *p_msg; |
||||
|
||||
if (msg->what == what) { |
||||
*p_msg = msg->next; |
||||
msg_free(msg); |
||||
msg->next = q->recycle_msg; |
||||
q->recycle_msg = msg; |
||||
q->nb_messages--; |
||||
} else { |
||||
last_msg = msg; |
||||
p_msg = &msg->next; |
||||
} |
||||
} |
||||
|
||||
if (q->first_msg) { |
||||
q->last_msg = last_msg; |
||||
} else { |
||||
q->last_msg = nullptr; |
||||
} |
||||
} |
||||
} |
||||
|
||||
inline static void msg_queue_destroy(MessageQueue *q) { |
||||
msg_queue_flush(q); |
||||
std::lock_guard<std::mutex> lock(q->mutex); |
||||
|
||||
while(q->recycle_msg) { |
||||
AVMessage *msg = q->recycle_msg; |
||||
if (msg) |
||||
q->recycle_msg = msg->next; |
||||
msg_free(msg); |
||||
av_freep(&msg); |
||||
} |
||||
} |
||||
|
||||
#endif // FFMSG_QUEUE_H
|
Loading…
Reference in new issue