parent
e661b3211a
commit
1a9f81ec2f
@ -1,192 +0,0 @@ |
||||
|
||||
#include "FFMessageQueue.h" |
||||
|
||||
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)); |
||||
} |
||||
|
||||
void FFMessageQueue::init() { |
||||
memset(q, 0, sizeof(MessageQueue)); |
||||
q->abort_request = 1; |
||||
} |
||||
|
||||
void FFMessageQueue::start() { |
||||
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); |
||||
} |
||||
|
||||
void FFMessageQueue::flush() { |
||||
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; |
||||
} |
||||
|
||||
void FFMessageQueue::sendMessage1(int what) { |
||||
AVMessage msg; |
||||
msg_init_msg(&msg); |
||||
msg.what = what; |
||||
msg_queue_put(q, &msg); |
||||
} |
||||
|
||||
void FFMessageQueue::sendMessage2(int what, int arg1) { |
||||
AVMessage msg; |
||||
msg_init_msg(&msg); |
||||
msg.what = what; |
||||
msg.arg1 = arg1; |
||||
msg_queue_put(q, &msg); |
||||
} |
||||
|
||||
void FFMessageQueue::sendMessage3(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); |
||||
} |
||||
|
||||
int FFMessageQueue::get(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; |
||||
} |
||||
|
||||
void FFMessageQueue::remove(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; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void FFMessageQueue::abort() { |
||||
std::unique_lock<std::mutex> lock(q->mutex); |
||||
q->abort_request = 1; |
||||
q->cond.notify_all(); |
||||
} |
||||
|
||||
void FFMessageQueue::destroy() { |
||||
flush(); |
||||
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); |
||||
} |
||||
} |
@ -1,96 +0,0 @@ |
||||
|
||||
#ifndef FFMPEGANDROID_FFMESSAGEQUEUE_H |
||||
#define FFMPEGANDROID_FFMESSAGEQUEUE_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_DECODER_OPEN_ERROR 412 |
||||
#define FFP_MSG_DEMUX_ERROR 413 |
||||
|
||||
#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_MSG_OPEN_ERROR 901 |
||||
|
||||
#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; |
||||
|
||||
class FFMessageQueue { |
||||
|
||||
private: |
||||
MessageQueue *q; |
||||
|
||||
public: |
||||
|
||||
void init(); |
||||
|
||||
void start(); |
||||
|
||||
void flush(); |
||||
|
||||
void sendMessage1(int what); |
||||
|
||||
void sendMessage2(int what, int arg1); |
||||
|
||||
void sendMessage3(int what, int arg1, int arg2); |
||||
|
||||
int get(AVMessage *msg, int block); |
||||
|
||||
void remove(int what); |
||||
|
||||
void abort(); |
||||
|
||||
void destroy(); |
||||
}; |
||||
|
||||
|
||||
#endif //FFMPEGANDROID_FFMESSAGEQUEUE_H
|
@ -1,50 +0,0 @@ |
||||
|
||||
#include <ffplay_define.h> |
||||
#include "MediaClock.h" |
||||
|
||||
MediaClock::MediaClock() { |
||||
m_speed = 1.0; |
||||
m_pause = false; |
||||
setClock(NAN); |
||||
} |
||||
|
||||
void MediaClock::setClock(double pts) { |
||||
double time = (double) av_gettime_relative() / 1000000.0; |
||||
setClock(pts, time); |
||||
} |
||||
|
||||
void MediaClock::setClock(double pts, double time) { |
||||
m_pts = pts; |
||||
m_last_update = time; |
||||
m_pts_drift = m_pts - time; |
||||
} |
||||
|
||||
double MediaClock::getClock() const { |
||||
if (m_pause) { |
||||
return m_pts; |
||||
} else { |
||||
double time = (double) av_gettime_relative() / 1000000.0; |
||||
return m_pts_drift + time - (time - m_last_update) * (1.0 - m_speed); |
||||
} |
||||
} |
||||
|
||||
void MediaClock::setSpeed(double speed) { |
||||
setClock(getClock()); |
||||
m_speed = speed; |
||||
} |
||||
|
||||
double MediaClock::getSpeed() const { |
||||
return m_speed; |
||||
} |
||||
|
||||
void MediaClock::syncToSlave(MediaClock *slave) { |
||||
double clock = getClock(); |
||||
double slave_clock = slave->getClock(); |
||||
if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD)) { |
||||
setClock(slave_clock); |
||||
} |
||||
} |
||||
|
||||
MediaClock::~MediaClock() { |
||||
|
||||
} |
@ -1,45 +0,0 @@ |
||||
|
||||
#ifndef FFMPEGANDROID_MEDIACLOCK_H |
||||
#define FFMPEGANDROID_MEDIACLOCK_H |
||||
|
||||
#include <math.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
#include <libavutil/time.h> |
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
class MediaClock { |
||||
|
||||
private: |
||||
bool m_pause; |
||||
double m_pts; |
||||
double m_speed; |
||||
double m_pts_drift; |
||||
double m_last_update; |
||||
|
||||
public: |
||||
|
||||
MediaClock(); |
||||
|
||||
void setClock(double pts); |
||||
|
||||
void setClock(double pts, double time); |
||||
|
||||
double getClock() const; |
||||
|
||||
void setSpeed(double speed); |
||||
|
||||
double getSpeed() const; |
||||
|
||||
void syncToSlave(MediaClock *slave); |
||||
|
||||
virtual ~MediaClock(); |
||||
|
||||
}; |
||||
|
||||
|
||||
#endif //FFMPEGANDROID_MEDIACLOCK_H
|
@ -1,98 +0,0 @@ |
||||
|
||||
#ifndef FFMPEGANDROID_FFPLAY_DEFINE_H |
||||
#define FFMPEGANDROID_FFPLAY_DEFINE_H |
||||
|
||||
#include <mutex> |
||||
#include "FFMessageQueue.h" |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
#include <libavformat/avformat.h> |
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#define PACKET_QUEUE_SIZE 16 |
||||
#define FRAME_QUEUE_SIZE 16 |
||||
|
||||
#define VIDEO_QUEUE_SIZE 5 |
||||
#define SAMPLE_QUEUE_SIZE 9 |
||||
|
||||
#define MAX_QUEUE_SIZE (15 * 1024 * 1024) |
||||
#define MIN_FRAMES 25 |
||||
|
||||
#define AUDIO_MIN_BUFFER_SIZE 512 |
||||
#define AUDIO_MAX_CALLBACKS_PER_SEC 30 |
||||
|
||||
#define REFRESH_RATE 0.01 |
||||
|
||||
#define AV_SYNC_THRESHOLD_MIN 0.04 |
||||
#define AV_SYNC_THRESHOLD_MAX 0.1 |
||||
#define AV_SYNC_FRAMEDUP_THRESHOLD 0.1 |
||||
#define AV_NOSYNC_THRESHOLD 10.0 |
||||
|
||||
#define EXTERNAL_CLOCK_MIN_FRAMES 2 |
||||
#define EXTERNAL_CLOCK_MAX_FRAMES 10 |
||||
#define EXTERNAL_CLOCK_SPEED_MIN 0.900 |
||||
#define EXTERNAL_CLOCK_SPEED_MAX 1.010 |
||||
#define EXTERNAL_CLOCK_SPEED_STEP 0.001 |
||||
|
||||
struct AVDictionary { |
||||
int count; |
||||
AVDictionaryEntry *elements; |
||||
}; |
||||
|
||||
typedef enum { |
||||
AV_SYNC_AUDIO, // 同步到音频时钟
|
||||
AV_SYNC_VIDEO, // 同步到视频时钟
|
||||
AV_SYNC_EXTERNAL, // 同步到外部时钟
|
||||
} SyncType; |
||||
|
||||
class PlayerParams { |
||||
|
||||
public: |
||||
std::mutex mutex; |
||||
|
||||
FFMessageQueue *messageQueue; |
||||
int64_t videoDuration; |
||||
|
||||
AVInputFormat *iformat; |
||||
const char *url; |
||||
int64_t offset; |
||||
const char *headers; |
||||
|
||||
const char *audioCodecName; |
||||
const char *videoCodecName; |
||||
|
||||
int abortRequest; |
||||
int pauseRequest; |
||||
SyncType syncType; |
||||
int64_t startTime; |
||||
int64_t duration; |
||||
int realTime; |
||||
int infiniteBuffer; |
||||
int audioDisable; |
||||
int videoDisable; |
||||
int displayDisable; |
||||
|
||||
int fast; |
||||
int genpts; |
||||
int lowres; |
||||
|
||||
float playbackRate; |
||||
float playbackPitch; |
||||
|
||||
int seekByBytes; |
||||
int seekRequest; |
||||
int seekFlags; |
||||
int64_t seekPos; |
||||
int64_t seekRel; |
||||
|
||||
int autoExit; |
||||
int loop; |
||||
int mute; |
||||
int reorderVideoPts; |
||||
}; |
||||
|
||||
#endif //FFMPEGANDROID_FFPLAY_DEFINE_H
|
@ -1,93 +0,0 @@ |
||||
|
||||
#include "FrameQueue.h" |
||||
|
||||
FrameQueue::FrameQueue(int max_size, int keep_last):m_size(0), |
||||
m_show_idx(0), |
||||
m_read_idx(0), |
||||
m_write_idx(0), |
||||
m_keep_last(keep_last), |
||||
m_abort_request(0) { |
||||
m_max_size = FFMIN(max_size, FRAME_QUEUE_SIZE); |
||||
memset(m_queue, 0, sizeof(Frame) * FRAME_QUEUE_SIZE); |
||||
|
||||
for (int i = 0; i < this->m_max_size; ++i) { |
||||
m_queue[i].frame = av_frame_alloc(); |
||||
} |
||||
} |
||||
|
||||
void FrameQueue::start() { |
||||
std::lock_guard<std::mutex> lock(m_mutex); |
||||
m_abort_request = 0; |
||||
} |
||||
|
||||
void FrameQueue::abort() { |
||||
std::lock_guard<std::mutex> lock(m_mutex); |
||||
m_abort_request = 1; |
||||
} |
||||
|
||||
Frame *FrameQueue::currentFrame() { |
||||
return &m_queue[(m_read_idx + m_show_idx) % m_max_size]; |
||||
} |
||||
|
||||
Frame *FrameQueue::nextFrame() { |
||||
return &m_queue[(m_read_idx + m_show_idx + 1) % m_max_size]; |
||||
} |
||||
|
||||
Frame *FrameQueue::lastFrame() { |
||||
return &m_queue[m_read_idx]; |
||||
} |
||||
|
||||
Frame *FrameQueue::peekWritable() { |
||||
if (m_abort_request) { |
||||
return nullptr; |
||||
} |
||||
|
||||
return &m_queue[m_write_idx]; |
||||
} |
||||
|
||||
void FrameQueue::pushFrame() { |
||||
std::unique_lock<std::mutex> lock(m_mutex); |
||||
if (++m_write_idx == m_max_size) { |
||||
m_write_idx = 0; |
||||
} |
||||
m_size++; |
||||
} |
||||
|
||||
void FrameQueue::popFrame() { |
||||
std::unique_lock<std::mutex> lock(m_mutex); |
||||
if (m_keep_last && !m_show_idx) { |
||||
m_show_idx = 1; |
||||
return; |
||||
} |
||||
unrefFrame(&m_queue[m_read_idx]); |
||||
if (++m_read_idx == m_max_size) { |
||||
m_read_idx = 0; |
||||
} |
||||
m_size--; |
||||
} |
||||
|
||||
void FrameQueue::flush() { |
||||
while (getFrameSize() > 0) { |
||||
popFrame(); |
||||
} |
||||
} |
||||
|
||||
int FrameQueue::getFrameSize() { |
||||
return m_size - m_show_idx; |
||||
} |
||||
|
||||
int FrameQueue::getShowIndex() const { |
||||
return m_show_idx; |
||||
} |
||||
|
||||
void FrameQueue::unrefFrame(Frame *vp) { |
||||
av_frame_unref(vp->frame); |
||||
} |
||||
|
||||
FrameQueue::~FrameQueue() { |
||||
for (int i = 0; i < m_max_size; ++i) { |
||||
Frame *vp = &m_queue[i]; |
||||
unrefFrame(vp); |
||||
av_frame_free(&vp->frame); |
||||
} |
||||
} |
@ -1,66 +0,0 @@ |
||||
|
||||
#ifndef FFMPEGANDROID_FRAMEQUEUE_H |
||||
#define FFMPEGANDROID_FRAMEQUEUE_H |
||||
|
||||
#include <mutex> |
||||
#include "ffplay_define.h" |
||||
|
||||
extern "C" { |
||||
#include "libavcodec/avcodec.h" |
||||
} |
||||
|
||||
typedef struct Frame { |
||||
double pts; |
||||
int width; |
||||
int height; |
||||
int format; |
||||
AVFrame *frame; |
||||
double duration; |
||||
} Frame; |
||||
|
||||
class FrameQueue { |
||||
|
||||
private: |
||||
std::mutex m_mutex; |
||||
int m_abort_request; |
||||
int m_read_idx; |
||||
int m_write_idx; |
||||
int m_size; |
||||
int m_max_size; |
||||
int m_keep_last; |
||||
int m_show_idx; |
||||
Frame m_queue[FRAME_QUEUE_SIZE]; |
||||
|
||||
void unrefFrame(Frame *vp); |
||||
|
||||
public: |
||||
FrameQueue(int max_size, int keep_last); |
||||
|
||||
virtual ~FrameQueue(); |
||||
|
||||
void start(); |
||||
|
||||
void abort(); |
||||
|
||||
Frame *currentFrame(); |
||||
|
||||
Frame *nextFrame(); |
||||
|
||||
Frame *lastFrame(); |
||||
|
||||
Frame *peekWritable(); |
||||
|
||||
void pushFrame(); |
||||
|
||||
void popFrame(); |
||||
|
||||
void flush(); |
||||
|
||||
int getFrameSize(); |
||||
|
||||
int getShowIndex() const; |
||||
|
||||
}; |
||||
|
||||
|
||||
#endif //FFMPEGANDROID_FRAMEQUEUE_H
|
@ -1,142 +0,0 @@ |
||||
|
||||
#include "PacketQueue.h" |
||||
|
||||
PacketQueue::PacketQueue():m_size(0), |
||||
m_duration(0), |
||||
m_nb_packets(0), |
||||
m_abort_request(0), |
||||
last_pkt_list(nullptr), |
||||
first_pkt_list(nullptr) { |
||||
} |
||||
|
||||
int PacketQueue::put(AVPacket *pkt) { |
||||
PacketList *pkt1; |
||||
|
||||
if (m_abort_request) { |
||||
return -1; |
||||
} |
||||
|
||||
pkt1 = (PacketList *) av_malloc(sizeof(PacketList)); |
||||
if (!pkt1) { |
||||
return -1; |
||||
} |
||||
pkt1->pkt = *pkt; |
||||
pkt1->next = nullptr; |
||||
|
||||
if (!last_pkt_list) { |
||||
first_pkt_list = pkt1; |
||||
} else { |
||||
last_pkt_list->next = pkt1; |
||||
} |
||||
|
||||
m_nb_packets++; |
||||
last_pkt_list = pkt1; |
||||
m_size += pkt1->pkt.size + sizeof(*pkt1); |
||||
m_duration += pkt1->pkt.duration; |
||||
return 0; |
||||
} |
||||
|
||||
int PacketQueue::pushPacket(AVPacket *pkt) { |
||||
std::unique_lock<std::mutex> lock(m_mutex); |
||||
int ret = put(pkt); |
||||
if (ret < 0) { |
||||
av_packet_unref(pkt); |
||||
} |
||||
m_cond.notify_all(); |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
int PacketQueue::pushEmptyPacket(int stream_idx) { |
||||
AVPacket pkt1; |
||||
AVPacket*pkt = &pkt1; |
||||
av_init_packet(pkt); |
||||
|
||||
pkt->size = 0; |
||||
pkt->data = nullptr; |
||||
pkt->stream_index = stream_idx; |
||||
|
||||
return pushPacket(pkt); |
||||
} |
||||
|
||||
int PacketQueue::popPacket(AVPacket *pkt) { |
||||
std::unique_lock<std::mutex> lock(m_mutex); |
||||
int ret; |
||||
PacketList *pkt1; |
||||
|
||||
for (;;) { |
||||
if (m_abort_request) { |
||||
ret = -1; |
||||
break; |
||||
} |
||||
|
||||
pkt1 = first_pkt_list; |
||||
if (pkt1) { |
||||
first_pkt_list = pkt1->next; |
||||
if (!first_pkt_list) { |
||||
last_pkt_list = nullptr; |
||||
} |
||||
m_nb_packets--; |
||||
m_size -= pkt1->pkt.size + sizeof(*pkt1); |
||||
m_duration -= pkt1->pkt.duration; |
||||
*pkt = pkt1->pkt; |
||||
av_free(pkt1); |
||||
ret = 1; |
||||
break; |
||||
} else { |
||||
m_cond.wait(lock); |
||||
} |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
void PacketQueue::flush() { |
||||
std::unique_lock<std::mutex> lock(m_mutex); |
||||
PacketList *pkt, *pkt1; |
||||
|
||||
for (pkt = first_pkt_list; pkt; pkt = pkt1) { |
||||
pkt1 = pkt->next; |
||||
av_packet_unref(&pkt->pkt); |
||||
av_freep(&pkt); |
||||
} |
||||
|
||||
m_size = 0; |
||||
m_duration = 0; |
||||
m_nb_packets = 0; |
||||
last_pkt_list = nullptr; |
||||
first_pkt_list = nullptr; |
||||
m_cond.notify_all(); |
||||
} |
||||
|
||||
void PacketQueue::start() { |
||||
std::lock_guard<std::mutex> lock(m_mutex); |
||||
m_abort_request = 0; |
||||
} |
||||
|
||||
void PacketQueue::abort() { |
||||
std::lock_guard<std::mutex> lock(m_mutex); |
||||
m_abort_request = 1; |
||||
} |
||||
|
||||
int PacketQueue::getSize() { |
||||
std::lock_guard<std::mutex> lock(m_mutex); |
||||
return m_size; |
||||
} |
||||
|
||||
int PacketQueue::getPacketSize() { |
||||
std::lock_guard<std::mutex> lock(m_mutex); |
||||
return m_nb_packets; |
||||
} |
||||
|
||||
int64_t PacketQueue::getDuration() { |
||||
return m_duration; |
||||
} |
||||
|
||||
int PacketQueue::isAbortRequest() { |
||||
return m_abort_request; |
||||
} |
||||
|
||||
PacketQueue::~PacketQueue() { |
||||
abort(); |
||||
flush(); |
||||
} |
@ -1,62 +0,0 @@ |
||||
|
||||
#ifndef FFMPEGANDROID_PACKETQUEUE_H |
||||
#define FFMPEGANDROID_PACKETQUEUE_H |
||||
|
||||
|
||||
#include <queue> |
||||
#include <mutex> |
||||
|
||||
extern "C" { |
||||
#include <libavcodec/avcodec.h> |
||||
} |
||||
|
||||
typedef struct PacketList { |
||||
AVPacket pkt; |
||||
struct PacketList *next; |
||||
} PacketList; |
||||
|
||||
class PacketQueue { |
||||
|
||||
private: |
||||
std::mutex m_mutex; |
||||
std::condition_variable m_cond; |
||||
|
||||
int m_size; |
||||
int m_nb_packets; |
||||
int64_t m_duration; |
||||
int m_abort_request; |
||||
PacketList *first_pkt_list; |
||||
PacketList *last_pkt_list; |
||||
|
||||
int put(AVPacket *pkt); |
||||
|
||||
public: |
||||
|
||||
PacketQueue(); |
||||
|
||||
int pushPacket(AVPacket *pkt); |
||||
|
||||
int pushEmptyPacket(int stream_idx); |
||||
|
||||
int popPacket(AVPacket *pkt); |
||||
|
||||
void flush(); |
||||
|
||||
void start(); |
||||
|
||||
void abort(); |
||||
|
||||
int getSize(); |
||||
|
||||
int getPacketSize(); |
||||
|
||||
int64_t getDuration(); |
||||
|
||||
int isAbortRequest(); |
||||
|
||||
virtual ~PacketQueue(); |
||||
|
||||
}; |
||||
|
||||
|
||||
#endif //FFMPEGANDROID_PACKETQUEUE_H
|
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 145 KiB |
Loading…
Reference in new issue