提交 25cf5140 编写于 作者: Z Zhang Rui

ios: show async cache in hud

上级 eb742679
......@@ -68,4 +68,6 @@
#define FFP_PROP_INT64_VIDEO_CACHED_PACKETS 20009
#define FFP_PROP_INT64_AUDIO_CACHED_PACKETS 20010
#define FFP_PROP_INT64_BIT_RATE 20100
#endif
......@@ -2586,6 +2586,7 @@ static int read_thread(void *arg)
}
#endif
ijkmeta_set_avformat_context_l(ffp->meta, ic);
ffp->stat.bit_rate = ic->bit_rate;
if (st_index[AVMEDIA_TYPE_VIDEO] >= 0)
ijkmeta_set_int64_l(ffp->meta, IJKM_KEY_VIDEO_STREAM, st_index[AVMEDIA_TYPE_VIDEO]);
if (st_index[AVMEDIA_TYPE_AUDIO] >= 0)
......@@ -4002,6 +4003,8 @@ int64_t ffp_get_property_int64(FFPlayer *ffp, int id, int64_t default_value)
if (!ffp)
return default_value;
return ffp->stat.audio_cached_packets;
case FFP_PROP_INT64_BIT_RATE:
return ffp ? ffp->stat.bit_rate : default_value;
default:
return default_value;
}
......
......@@ -450,6 +450,7 @@ typedef struct FFStatistic
float vdps;
float avdelay;
float avdiff;
int bit_rate;
int64_t video_cached_duration;
int64_t audio_cached_duration;
......
......@@ -37,6 +37,9 @@
#include "url.h"
#include <stdint.h>
#include "ijkplayer/ijkavutil/opt.h"
#include "ijkavformat.h"
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
......@@ -78,6 +81,9 @@ typedef struct Context {
int abort_request;
AVIOInterruptCB interrupt_callback;
/* options */
int64_t opaque;
} Context;
static int ring_init(RingBuffer *ring, unsigned int capacity, int read_back_capacity)
......@@ -173,6 +179,23 @@ static int wrapped_url_read(void *src, void *dst, int size)
return ret;
}
static void call_inject(URLContext *h)
{
Context *c = h->priv_data;
IjkAVInjectCallback inject_callback = ijkav_get_inject_callback();
void *opaque = (void *) (intptr_t) c->opaque;
if (opaque && inject_callback) {
IJKAVInject_AsyncStatistic stat;
stat.size = sizeof(stat);
stat.buf_forwards = ring_size(&c->ring);
stat.buf_backwards = ring_size_of_read_back(&c->ring);
stat.buf_capacity = BUFFER_CAPACITY + READ_BACK_CAPACITY;
inject_callback(opaque, IJKAVINJECT_ASYNC_STATISTIC, &stat, sizeof(stat));
}
}
static void *async_buffer_task(void *arg)
{
URLContext *h = arg;
......@@ -235,6 +258,8 @@ static void *async_buffer_task(void *arg)
pthread_cond_signal(&c->cond_wakeup_main);
pthread_mutex_unlock(&c->mutex);
call_inject(h);
}
return NULL;
......@@ -252,6 +277,9 @@ static int async_open(URLContext *h, const char *arg, int flags, AVDictionary **
if (ret < 0)
goto fifo_fail;
if (c->opaque)
av_dict_set_int(options, "ijkinject-opaque", c->opaque, 0);
/* wrap interrupt callback */
c->interrupt_callback = h->interrupt_callback;
ret = ffurl_open(&c->inner, arg, flags, &interrupt_callback, options);
......@@ -370,6 +398,7 @@ static int async_read_internal(URLContext *h, void *dest, int size, int read_com
pthread_cond_signal(&c->cond_wakeup_background);
pthread_mutex_unlock(&c->mutex);
call_inject(h);
return ret;
}
......@@ -425,6 +454,7 @@ static int64_t async_seek(URLContext *h, int64_t pos, int whence)
} else {
// fast seek backwards
ring_drain(ring, pos_delta);
call_inject(h);
c->logical_pos = new_logical_pos;
}
......@@ -462,6 +492,7 @@ static int64_t async_seek(URLContext *h, int64_t pos, int whence)
pthread_mutex_unlock(&c->mutex);
call_inject(h);
return ret;
}
......@@ -469,6 +500,8 @@ static int64_t async_seek(URLContext *h, int64_t pos, int whence)
#define D AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
{ "ijkinject-opaque", "private data of user, passed with custom callback",
OFFSET(opaque), IJKAV_OPTION_INT64(0, INT64_MIN, INT64_MAX) },
{NULL},
};
......
......@@ -63,6 +63,19 @@ typedef struct IJKAVInject_OnUrlOpenData {
#define IJKAVINJECT_ON_HTTP_RETRY 0x10003
#define IJKAVINJECT_ON_LIVE_RETRY 0x10004
/**
* Statistic
*/
typedef struct IJKAVInject_AsyncStatistic {
size_t size;
int64_t buf_backwards;
int64_t buf_forwards;
int64_t buf_capacity;
} IJKAVInject_AsyncStatistic;
#define IJKAVINJECT_ASYNC_STATISTIC 0x11000
typedef int (*IjkAVInjectCallback)(void *opaque, int message, void *data, size_t data_size);
IjkAVInjectCallback ijkav_register_inject_callback(IjkAVInjectCallback callback);
......
......@@ -65,6 +65,7 @@ static const char *kIJKFFRequiredFFmpegVersion = "ff2.8--ijk0.4.1.1--dev0.3.3--r
NSMutableArray *_registeredNotifications;
IJKAVInject_AsyncStatistic _asyncStat;
BOOL _shouldShowHudView;
NSTimer *_hudTimer;
}
......@@ -179,6 +180,7 @@ void IJKFFIOStatCompleteRegister(void (*cb)(const char *url,
// init fields
_scalingMode = IJKMPMovieScalingModeAspectFit;
_shouldAutoplay = YES;
memset(&_asyncStat, 0, sizeof(_asyncStat));
// init media resource
_urlString = aUrlString;
......@@ -566,8 +568,18 @@ inline static int getPlayerOption(IJKFFOptionCategory category)
if (!_mediaPlayer)
return 0.0f;
NSTimeInterval ret = ijkmp_get_playable_duration(_mediaPlayer);
return ret / 1000;
NSTimeInterval demux_cache = ((NSTimeInterval)ijkmp_get_playable_duration(_mediaPlayer)) / 1000;
int64_t buf_forwards = _asyncStat.buf_forwards;
if (buf_forwards > 0) {
int64_t bit_rate = ijkmp_get_property_int64(_mediaPlayer, FFP_PROP_INT64_BIT_RATE, 0);
if (bit_rate > 0) {
NSTimeInterval io_cache = ((float)buf_forwards) * 8 / bit_rate;
return io_cache + demux_cache;
}
}
return demux_cache;
}
- (CGSize)naturalSize
......@@ -636,6 +648,24 @@ inline static int getPlayerOption(IJKFFOptionCategory category)
return _glView.fps;
}
inline static NSString *formatedDurationMilli(long duration) {
if (duration >= 1000) {
return [NSString stringWithFormat:@"%.2f sec", ((float)duration) / 1000];
} else {
return [NSString stringWithFormat:@"%ld msec", duration];
}
}
inline static NSString *formatedSize(int64_t bytes) {
if (bytes >= 100 * 1000) {
return [NSString stringWithFormat:@"%.2f MB", ((float)bytes) / 1000 / 1000];
} else if (bytes >= 100) {
return [NSString stringWithFormat:@"%.1f KB", ((float)bytes) / 1000];
} else {
return [NSString stringWithFormat:@"%ld B", (long)bytes];
}
}
- (void)refreshHudView
{
if (_mediaPlayer == nil)
......@@ -669,14 +699,30 @@ inline static int getPlayerOption(IJKFFOptionCategory category)
int64_t acached = ijkmp_get_property_int64(_mediaPlayer, FFP_PROP_INT64_AUDIO_CACHED_DURATION, 0);
int64_t vcachep = ijkmp_get_property_int64(_mediaPlayer, FFP_PROP_INT64_VIDEO_CACHED_PACKETS, 0);
int64_t acachep = ijkmp_get_property_int64(_mediaPlayer, FFP_PROP_INT64_AUDIO_CACHED_PACKETS, 0);
[_glView setHudValue:[NSString stringWithFormat:@"%"PRId64" ms, %"PRId64" bytes, %"PRId64" packets", vcached, vcacheb, vcachep]
[_glView setHudValue:[NSString stringWithFormat:@"%@, %@, %"PRId64" packets",
formatedDurationMilli(vcached),
formatedSize(vcacheb),
vcachep]
forKey:@"v-cache"];
[_glView setHudValue:[NSString stringWithFormat:@"%"PRId64" ms, %"PRId64" bytes, %"PRId64" packets", acached, acacheb, acachep]
[_glView setHudValue:[NSString stringWithFormat:@"%@, %@, %"PRId64" packets",
formatedDurationMilli(acached),
formatedSize(acacheb),
acachep]
forKey:@"a-cache"];
float avdelay = ijkmp_get_property_float(_mediaPlayer, FFP_PROP_FLOAT_AVDELAY, .0f);
float avdiff = ijkmp_get_property_float(_mediaPlayer, FFP_PROP_FLOAT_AVDIFF, .0f);
[_glView setHudValue:[NSString stringWithFormat:@"%.3f %.3f", avdelay, -avdiff] forKey:@"delay"];
int64_t bit_rate = ijkmp_get_property_int64(_mediaPlayer, FFP_PROP_INT64_BIT_RATE, 0);
[_glView setHudValue:[NSString stringWithFormat:@"-%@, %@",
formatedSize(_asyncStat.buf_backwards),
formatedDurationMilli(((float)_asyncStat.buf_backwards) * 8 * 1000 / bit_rate)]
forKey:@"async-backward"];
[_glView setHudValue:[NSString stringWithFormat:@"+%@, %@",
formatedSize(_asyncStat.buf_forwards),
formatedDurationMilli(((float)_asyncStat.buf_forwards) * 8 * 1000 / bit_rate)]
forKey:@"async-forward"];
}
- (void)startHudTimer
......@@ -1071,6 +1117,16 @@ static int onInjectUrlOpen(IJKFFMoviePlayerController *mpc, id<IJKMediaUrlOpenDe
return 0;
}
static int onInjectAsyncStatistic(IJKFFMoviePlayerController *mpc, int type, void *data, size_t data_size)
{
IJKAVInject_AsyncStatistic *realData = data;
assert(realData);
assert(sizeof(IJKAVInject_AsyncStatistic) == data_size);
mpc->_asyncStat = *realData;
return 0;
}
// NOTE: could be called from multiple thread
static int ijkff_inject_callback(void *opaque, int message, void *data, size_t data_size)
{
......@@ -1085,6 +1141,8 @@ static int ijkff_inject_callback(void *opaque, int message, void *data, size_t d
return onInjectUrlOpen(mpc, mpc.httpOpenDelegate, message, data, data_size);
case IJKAVINJECT_ON_LIVE_RETRY:
return onInjectUrlOpen(mpc, mpc.liveOpenDelegate, message, data, data_size);
case IJKAVINJECT_ASYNC_STATISTIC:
return onInjectAsyncStatistic(mpc, message, data, data_size);
default: {
return 0;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册