Feature: remove useless code

pull/221/head
xufuji456 2 years ago
parent e661b3211a
commit 1a9f81ec2f
  1. 3
      README.md
  2. 13
      app/src/main/cpp/CMakeLists.txt
  3. 192
      app/src/main/cpp/ffplayer/FFMessageQueue.cpp
  4. 96
      app/src/main/cpp/ffplayer/FFMessageQueue.h
  5. 50
      app/src/main/cpp/ffplayer/clock/MediaClock.cpp
  6. 45
      app/src/main/cpp/ffplayer/clock/MediaClock.h
  7. 98
      app/src/main/cpp/ffplayer/ffplay_define.h
  8. 93
      app/src/main/cpp/ffplayer/queue/FrameQueue.cpp
  9. 66
      app/src/main/cpp/ffplayer/queue/FrameQueue.h
  10. 142
      app/src/main/cpp/ffplayer/queue/PacketQueue.cpp
  11. 62
      app/src/main/cpp/ffplayer/queue/PacketQueue.h
  12. BIN
      picture/ffmpeg_group.png

@ -28,6 +28,9 @@ WebRTC设计传输协议有SDP、SRTP、ICE、NAT、STUN等,常用视频编码
### 音视频开源库:
![preview](https://github.com/xufuji456/FFmpegAndroid/blob/master/picture/multimedia_library.png)
### 音视频教程:
[一起学习音视频](https://ke.qq.com/course/5613182#term_id=105809583)
### Joining the group to learn FFmpeg:
![preview](https://github.com/xufuji456/FFmpegAndroid/blob/master/picture/ffmpeg_group.png)

@ -32,18 +32,7 @@ set(SRC_METADATA
metadata/metadata_util.c
metadata/ffmpeg_media_retriever.c)
set(SRC_FFPLAYER
ffplayer/queue/FrameQueue.cpp
ffplayer/queue/PacketQueue.cpp
ffplayer/decode/BaseDecoder.cpp
ffplayer/decode/FFAudioDecoder.cpp
ffplayer/decode/FFVideoDecoder.cpp
ffplayer/clock/MediaClock.cpp
ffplayer/clock/AVSync.cpp
ffplayer/render/AudioRender.cpp
ffplayer/ff_mediaplayer_jni.cpp
ffplayer/FFMessageQueue.cpp
ffplayer/FFMediaPlayer.cpp)
set(SRC_FFPLAYER ffplayer)
add_library( # Sets the name of the library.
media-handle

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 145 KiB

Loading…
Cancel
Save