@@ -62,8 +62,10 @@ class MediaCodecBridge {
62
62
private static final String KEY_CROP_TOP = "crop-top" ;
63
63
64
64
private final Object mNativeBridgeLock = new Object ();
65
+
65
66
@ GuardedBy ("mNativeBridgeLock" )
66
67
private long mNativeMediaCodecBridge ;
68
+
67
69
private final SynchronizedHolder <MediaCodec , IllegalStateException > mMediaCodec =
68
70
new SynchronizedHolder <>(() -> new IllegalStateException ("MediaCodec was destroyed" ));
69
71
@@ -290,9 +292,7 @@ private String errorMessage() {
290
292
}
291
293
292
294
public MediaCodecBridge (
293
- long nativeMediaCodecBridge ,
294
- MediaCodec mediaCodec ,
295
- int tunnelModeAudioSessionId ) {
295
+ long nativeMediaCodecBridge , MediaCodec mediaCodec , int tunnelModeAudioSessionId ) {
296
296
if (mediaCodec == null ) {
297
297
throw new IllegalArgumentException ();
298
298
}
@@ -400,6 +400,15 @@ public static boolean isFrameRenderedCallbackEnabled() {
400
400
return Build .VERSION .SDK_INT >= 34 ;
401
401
}
402
402
403
+ private boolean isDecodeOnlyFlagEnabled () {
404
+ // Right now, we only enable BUFFER_FLAG_DECODE_ONLY for tunneling playback.
405
+ if (!mIsTunnelingPlayback ) {
406
+ return false ;
407
+ }
408
+ // BUFFER_FLAG_DECODE_ONLY is added in Android 14.
409
+ return Build .VERSION .SDK_INT >= 34 ;
410
+ }
411
+
403
412
@ CalledByNative
404
413
public static void createVideoMediaCodecBridge (
405
414
long nativeMediaCodecBridge ,
@@ -466,10 +475,7 @@ public static void createVideoMediaCodecBridge(
466
475
}
467
476
468
477
MediaCodecBridge bridge =
469
- new MediaCodecBridge (
470
- nativeMediaCodecBridge ,
471
- mediaCodec ,
472
- tunnelModeAudioSessionId );
478
+ new MediaCodecBridge (nativeMediaCodecBridge , mediaCodec , tunnelModeAudioSessionId );
473
479
MediaFormat mediaFormat =
474
480
createVideoDecoderFormat (mime , widthHint , heightHint , videoCapabilities );
475
481
@@ -739,9 +745,14 @@ private ByteBuffer getOutputBuffer(int index) {
739
745
740
746
@ CalledByNative
741
747
private int queueInputBuffer (
742
- int index , int offset , int size , long presentationTimeUs , int flags ) {
748
+ int index , int offset , int size , long presentationTimeUs , int flags , boolean is_decode_only ) {
743
749
resetLastPresentationTimeIfNeeded (presentationTimeUs );
744
750
try {
751
+ if (isDecodeOnlyFlagEnabled ()
752
+ && is_decode_only
753
+ && (flags & MediaCodec .BUFFER_FLAG_END_OF_STREAM ) == 0 ) {
754
+ flags |= MediaCodec .BUFFER_FLAG_DECODE_ONLY ;
755
+ }
745
756
mMediaCodec .get ().queueInputBuffer (index , offset , size , presentationTimeUs , flags );
746
757
} catch (Exception e ) {
747
758
Log .e (TAG , "Failed to queue input buffer" , e );
@@ -762,7 +773,8 @@ private int queueSecureInputBuffer(
762
773
int cipherMode ,
763
774
int blocksToEncrypt ,
764
775
int blocksToSkip ,
765
- long presentationTimeUs ) {
776
+ long presentationTimeUs ,
777
+ boolean is_decode_only ) {
766
778
resetLastPresentationTimeIfNeeded (presentationTimeUs );
767
779
try {
768
780
CryptoInfo cryptoInfo = new CryptoInfo ();
@@ -776,7 +788,14 @@ private int queueSecureInputBuffer(
776
788
return MediaCodecStatus .ERROR ;
777
789
}
778
790
779
- mMediaCodec .get ().queueSecureInputBuffer (index , offset , cryptoInfo , presentationTimeUs , 0 );
791
+ int flags = 0 ;
792
+ if (isDecodeOnlyFlagEnabled () && is_decode_only ) {
793
+ flags |= MediaCodec .BUFFER_FLAG_DECODE_ONLY ;
794
+ }
795
+
796
+ mMediaCodec
797
+ .get ()
798
+ .queueSecureInputBuffer (index , offset , cryptoInfo , presentationTimeUs , flags );
780
799
} catch (MediaCodec .CryptoException e ) {
781
800
int errorCode = e .getErrorCode ();
782
801
if (errorCode == MediaCodec .CryptoException .ERROR_NO_KEY ) {
@@ -1043,7 +1062,10 @@ private int getAudioFormat(int channelCount) {
1043
1062
@ NativeMethods
1044
1063
interface Natives {
1045
1064
void onMediaCodecError (
1046
- long nativeMediaCodecBridge , boolean isRecoverable , boolean isTransient , String diagnosticInfo );
1065
+ long nativeMediaCodecBridge ,
1066
+ boolean isRecoverable ,
1067
+ boolean isTransient ,
1068
+ String diagnosticInfo );
1047
1069
1048
1070
void onMediaCodecInputBufferAvailable (long nativeMediaCodecBridge , int bufferIndex );
1049
1071
0 commit comments