Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ android {
applicationId "com.openipc.decoder"
minSdk 21
targetSdk 36
versionCode 41
versionName "2.16"
versionCode 42
versionName "2.17"

buildConfigField "String", "GIT_HASH", "\"${getGitHash()}\""
}
Expand Down
2 changes: 2 additions & 0 deletions android/app/src/main/java/com/openipc/decoder/Decoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ protected void onCreate(Bundle savedInstanceState) {
@Override public void onDecoderStarted() { removeClearOverlay(); }
@Override public void onDecoderFailed() {}
});
// Single view: streams above 1080p on decoders that need to know it up front (#166)
videoDecoder.allowLargeFrames(true);
audioManager = new AudioManager();
rtspClient = new RtspClient(framePool, nalAssembler, nalQueue);
rtspClient.setListener(new RtspClient.Listener() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ class MediaCodecManager {

// Surface set by the owning activity
private volatile Surface surface;
/**
* Single view (#166): announce the largest picture the decoder supports (up to 4K) as
* KEY_MAX_WIDTH/HEIGHT. Configured at 1280×720 without it, some hardware decoders
* (Rockchip OMX) never give a frame for streams above 1080p, e.g. 2304×1296. Off in the
* grid: nine decoders with 4K buffers would not fit in memory.
*/
private volatile boolean largeFrames;

/** Frames rendered so far (#82): with the frames received this gives the real decode rate. */
private volatile int framesOut;
Expand Down Expand Up @@ -255,6 +262,27 @@ void setSurface(Surface s) {
this.surface = s;
}

/** See {@link #largeFrames}; takes effect with the next decoder. */
void allowLargeFrames(boolean on) {
largeFrames = on;
}

/** Largest supported size up to 3840×2160 (a few steps down), or null if none above 1080p. */
static int[] maxFrameSize(MediaCodec codec, String mime) {
try {
MediaCodecInfo.VideoCapabilities video =
codec.getCodecInfo().getCapabilitiesForType(mime).getVideoCapabilities();
if (video == null) return null;
int[][] sizes = {{3840, 2160}, {2560, 1920}, {2560, 1440}, {2304, 1296}};
for (int[] size : sizes) {
if (video.isSizeSupported(size[0], size[1])) return size;
}
} catch (Exception ignored) {
// Capabilities unknown: keep the decoder's defaults
}
return null;
}

/** Enable or disable decoding; disabling also releases the decoder. */
/**
* Enable or disable decoding. Never blocks the caller (the UI thread): disabling only
Expand Down Expand Up @@ -374,6 +402,13 @@ void createDecoder(boolean codecH265) {
Log.i(TAG, "Start video decoder (" + type + ")");
local = MediaCodec.createDecoderByType(type);
learnLimits(local, type);
int[] max = largeFrames ? maxFrameSize(local, type) : null;
if (max != null) {
format.setInteger(MediaFormat.KEY_MAX_WIDTH, max[0]);
format.setInteger(MediaFormat.KEY_MAX_HEIGHT, max[1]);
Log.i(TAG, "Decoder " + local.getName() + ": pictures up to "
+ max[0] + "×" + max[1]);
}
}
try {
local.configure(format, s, null, 0);
Expand Down
Loading