mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-20 03:23:07 +00:00
Add configurable ffmpeg performance options
This commit is contained in:
parent
c8b94217cf
commit
fb8b6fd7f5
@ -20,15 +20,24 @@ struct SwsContext* scaler_ctx;
|
|||||||
#define RENDER_PIX_FMT AV_PIX_FMT_RGBA
|
#define RENDER_PIX_FMT AV_PIX_FMT_RGBA
|
||||||
#define BYTES_PER_PIXEL 4
|
#define BYTES_PER_PIXEL 4
|
||||||
|
|
||||||
#define VERY_LOW_PERF 0
|
// Disables the deblocking filter at the cost of image quality
|
||||||
#define LOW_PERF 1
|
#define DISABLE_LOOP_FILTER 0x1
|
||||||
#define MED_PERF 2
|
// Uses the low latency decode flag (disables multithreading)
|
||||||
#define HIGH_PERF 3
|
#define LOW_LATENCY_DECODE 0x2
|
||||||
|
// Threads process each slice, rather than each frame
|
||||||
|
#define SLICE_THREADING 0x4
|
||||||
|
// Uses nonstandard speedup tricks
|
||||||
|
#define FAST_DECODE 0x8
|
||||||
|
// Uses bilinear filtering instead of bicubic
|
||||||
|
#define BILINEAR_FILTERING 0x10
|
||||||
|
// Uses a faster bilinear filtering with lower image quality
|
||||||
|
#define FAST_BILINEAR_FILTERING 0x20
|
||||||
|
|
||||||
// This function must be called before
|
// This function must be called before
|
||||||
// any other decoding functions
|
// any other decoding functions
|
||||||
int nv_avc_init(int width, int height, int perf_lvl) {
|
int nv_avc_init(int width, int height, int perf_lvl, int thread_count) {
|
||||||
int err;
|
int err;
|
||||||
|
int filtering;
|
||||||
|
|
||||||
pthread_mutex_init(&mutex, NULL);
|
pthread_mutex_init(&mutex, NULL);
|
||||||
|
|
||||||
@ -53,24 +62,25 @@ int nv_avc_init(int width, int height, int perf_lvl) {
|
|||||||
// Show frames even before a reference frame
|
// Show frames even before a reference frame
|
||||||
decoder_ctx->flags2 |= CODEC_FLAG2_SHOW_ALL;
|
decoder_ctx->flags2 |= CODEC_FLAG2_SHOW_ALL;
|
||||||
|
|
||||||
if (perf_lvl <= LOW_PERF) {
|
if (perf_lvl & DISABLE_LOOP_FILTER) {
|
||||||
// Skip the loop filter for performance reasons
|
// Skip the loop filter for performance reasons
|
||||||
decoder_ctx->skip_loop_filter = AVDISCARD_ALL;
|
decoder_ctx->skip_loop_filter = AVDISCARD_ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (perf_lvl <= MED_PERF) {
|
if (perf_lvl & LOW_LATENCY_DECODE) {
|
||||||
// Run 2 threads for decoding
|
|
||||||
decoder_ctx->thread_count = 2;
|
|
||||||
decoder_ctx->thread_type = FF_THREAD_FRAME;
|
|
||||||
|
|
||||||
// Use some tricks to make things faster
|
|
||||||
decoder_ctx->flags2 |= CODEC_FLAG2_FAST;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Use low delay single threaded encoding
|
// Use low delay single threaded encoding
|
||||||
decoder_ctx->flags |= CODEC_FLAG_LOW_DELAY;
|
decoder_ctx->flags |= CODEC_FLAG_LOW_DELAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (perf_lvl & SLICE_THREADING) {
|
||||||
|
decoder_ctx->thread_type = FF_THREAD_SLICE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
decoder_ctx->thread_type = FF_THREAD_FRAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
decoder_ctx->thread_count = thread_count;
|
||||||
|
|
||||||
decoder_ctx->width = width;
|
decoder_ctx->width = width;
|
||||||
decoder_ctx->height = height;
|
decoder_ctx->height = height;
|
||||||
decoder_ctx->pix_fmt = PIX_FMT_YUV420P;
|
decoder_ctx->pix_fmt = PIX_FMT_YUV420P;
|
||||||
@ -114,13 +124,23 @@ int nv_avc_init(int width, int height, int perf_lvl) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (perf_lvl & FAST_BILINEAR_FILTERING) {
|
||||||
|
filtering = SWS_FAST_BILINEAR;
|
||||||
|
}
|
||||||
|
else if (perf_lvl & BILINEAR_FILTERING) {
|
||||||
|
filtering = SWS_BILINEAR;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
filtering = SWS_BICUBIC;
|
||||||
|
}
|
||||||
|
|
||||||
scaler_ctx = sws_getContext(decoder_ctx->width,
|
scaler_ctx = sws_getContext(decoder_ctx->width,
|
||||||
decoder_ctx->height,
|
decoder_ctx->height,
|
||||||
decoder_ctx->pix_fmt,
|
decoder_ctx->pix_fmt,
|
||||||
decoder_ctx->width,
|
decoder_ctx->width,
|
||||||
decoder_ctx->height,
|
decoder_ctx->height,
|
||||||
RENDER_PIX_FMT,
|
RENDER_PIX_FMT,
|
||||||
SWS_BICUBIC,
|
filtering,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
if (scaler_ctx == NULL) {
|
if (scaler_ctx == NULL) {
|
||||||
__android_log_write(ANDROID_LOG_ERROR, "NVAVCDEC",
|
__android_log_write(ANDROID_LOG_ERROR, "NVAVCDEC",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
|
|
||||||
int nv_avc_init(int width, int height, int perf_lvl);
|
int nv_avc_init(int width, int height, int perf_lvl, int thread_count);
|
||||||
void nv_avc_destroy(void);
|
void nv_avc_destroy(void);
|
||||||
void nv_avc_redraw(JNIEnv *env, jobject surface);
|
void nv_avc_redraw(JNIEnv *env, jobject surface);
|
||||||
int nv_avc_decode(unsigned char* indata, int inlen);
|
int nv_avc_decode(unsigned char* indata, int inlen);
|
||||||
|
@ -7,9 +7,9 @@
|
|||||||
// any other decoding functions
|
// any other decoding functions
|
||||||
JNIEXPORT jint JNICALL
|
JNIEXPORT jint JNICALL
|
||||||
Java_com_limelight_nvstream_av_video_AvcDecoder_init(JNIEnv *env, jobject this, jint width,
|
Java_com_limelight_nvstream_av_video_AvcDecoder_init(JNIEnv *env, jobject this, jint width,
|
||||||
jint height, jint perflvl)
|
jint height, jint perflvl, jint threadcount)
|
||||||
{
|
{
|
||||||
return nv_avc_init(width, height, perflvl);
|
return nv_avc_init(width, height, perflvl, threadcount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function must be called after
|
// This function must be called after
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -15,7 +15,20 @@ public class AvcDecoder {
|
|||||||
System.loadLibrary("nv_avc_dec");
|
System.loadLibrary("nv_avc_dec");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static native int init(int width, int height, int perflvl);
|
/** Disables the deblocking filter at the cost of image quality */
|
||||||
|
public static final int DISABLE_LOOP_FILTER = 0x1;
|
||||||
|
/** Uses the low latency decode flag (disables multithreading) */
|
||||||
|
public static final int LOW_LATENCY_DECODE = 0x2;
|
||||||
|
/** Threads process each slice, rather than each frame */
|
||||||
|
public static final int SLICE_THREADING = 0x4;
|
||||||
|
/** Uses nonstandard speedup tricks */
|
||||||
|
public static final int FAST_DECODE = 0x8;
|
||||||
|
/** Uses bilinear filtering instead of bicubic */
|
||||||
|
public static final int BILINEAR_FILTERING = 0x10;
|
||||||
|
/** Uses a faster bilinear filtering with lower image quality */
|
||||||
|
public static final int FAST_BILINEAR_FILTERING = 0x20;
|
||||||
|
|
||||||
|
public static native int init(int width, int height, int perflvl, int threadcount);
|
||||||
public static native void destroy();
|
public static native void destroy();
|
||||||
public static native void redraw(Surface surface);
|
public static native void redraw(Surface surface);
|
||||||
public static native int decode(byte[] indata, int inoff, int inlen);
|
public static native int decode(byte[] indata, int inoff, int inlen);
|
||||||
|
@ -73,7 +73,25 @@ public class CpuDecoderRenderer implements DecoderRenderer {
|
|||||||
this.renderTarget = renderTarget;
|
this.renderTarget = renderTarget;
|
||||||
this.perfLevel = findOptimalPerformanceLevel();
|
this.perfLevel = findOptimalPerformanceLevel();
|
||||||
|
|
||||||
int err = AvcDecoder.init(width, height, perfLevel);
|
int flags = 0;
|
||||||
|
switch (perfLevel) {
|
||||||
|
case LOW_PERF:
|
||||||
|
flags = AvcDecoder.DISABLE_LOOP_FILTER |
|
||||||
|
AvcDecoder.FAST_BILINEAR_FILTERING |
|
||||||
|
AvcDecoder.FAST_DECODE |
|
||||||
|
AvcDecoder.LOW_LATENCY_DECODE;
|
||||||
|
break;
|
||||||
|
case MED_PERF:
|
||||||
|
flags = AvcDecoder.LOW_LATENCY_DECODE |
|
||||||
|
AvcDecoder.FAST_DECODE |
|
||||||
|
AvcDecoder.BILINEAR_FILTERING;
|
||||||
|
break;
|
||||||
|
case HIGH_PERF:
|
||||||
|
flags = AvcDecoder.LOW_LATENCY_DECODE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int err = AvcDecoder.init(width, height, flags, 2);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
throw new IllegalStateException("AVC decoder initialization failure: "+err);
|
throw new IllegalStateException("AVC decoder initialization failure: "+err);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user