16
16
package androidx .media3 .transformer .mh ;
17
17
18
18
import static androidx .media3 .effect .DefaultVideoFrameProcessor .WORKING_COLOR_SPACE_ORIGINAL ;
19
+ import static androidx .media3 .test .utils .DecodeOneFrameUtil .decodeOneMediaItemFrame ;
19
20
import static androidx .media3 .test .utils .TestUtil .retrieveTrackFormat ;
20
21
import static androidx .media3 .transformer .AndroidTestUtil .FORCE_TRANSCODE_VIDEO_EFFECTS ;
21
22
import static androidx .media3 .transformer .AndroidTestUtil .MP4_ASSET_1080P_5_SECOND_HLG10 ;
30
31
import static androidx .media3 .transformer .mh .HdrCapabilitiesUtil .assumeDeviceSupportsHdrEditing ;
31
32
import static androidx .test .core .app .ApplicationProvider .getApplicationContext ;
32
33
import static com .google .common .truth .Truth .assertThat ;
34
+ import static java .util .Collections .max ;
33
35
34
36
import android .content .Context ;
37
+ import android .media .MediaFormat ;
35
38
import android .net .Uri ;
39
+ import android .view .Surface ;
36
40
import androidx .annotation .Nullable ;
37
41
import androidx .media3 .common .C ;
38
42
import androidx .media3 .common .Format ;
39
43
import androidx .media3 .common .MediaItem ;
40
44
import androidx .media3 .common .MimeTypes ;
41
45
import androidx .media3 .common .util .Util ;
42
46
import androidx .media3 .effect .DefaultVideoFrameProcessor ;
47
+ import androidx .media3 .exoplayer .video .PlaceholderSurface ;
48
+ import androidx .media3 .test .utils .DecodeOneFrameUtil ;
43
49
import androidx .media3 .transformer .Composition ;
44
50
import androidx .media3 .transformer .EditedMediaItem ;
45
51
import androidx .media3 .transformer .EncoderUtil ;
50
56
import androidx .media3 .transformer .TransformerAndroidTestRunner ;
51
57
import androidx .test .core .app .ApplicationProvider ;
52
58
import androidx .test .ext .junit .runners .AndroidJUnit4 ;
59
+ import java .nio .ByteBuffer ;
60
+ import java .util .ArrayList ;
61
+ import java .util .List ;
53
62
import java .util .Objects ;
54
63
import java .util .concurrent .atomic .AtomicBoolean ;
64
+ import java .util .concurrent .atomic .AtomicReference ;
65
+ import org .junit .After ;
55
66
import org .junit .AssumptionViolatedException ;
56
67
import org .junit .Before ;
57
68
import org .junit .Rule ;
@@ -69,12 +80,20 @@ public final class HdrEditingTest {
69
80
@ Rule public final TestName testName = new TestName ();
70
81
71
82
private String testId ;
83
+ @ Nullable private Surface placeholderSurface ;
72
84
73
85
@ Before
74
86
public void setUpTestId () {
75
87
testId = testName .getMethodName ();
76
88
}
77
89
90
+ @ After
91
+ public void tearDown () {
92
+ if (placeholderSurface != null ) {
93
+ placeholderSurface .release ();
94
+ }
95
+ }
96
+
78
97
@ Test
79
98
public void export_transmuxHdr10File () throws Exception {
80
99
Context context = ApplicationProvider .getApplicationContext ();
@@ -154,12 +173,12 @@ public void exportAndTranscode_hdr10File_whenHdrEditingIsSupported() throws Exce
154
173
new TransformerAndroidTestRunner .Builder (context , transformer )
155
174
.build ()
156
175
.run (testId , editedMediaItem );
157
- @ C . ColorTransfer
158
- int actualColorTransfer =
159
- retrieveTrackFormat ( context , exportTestResult . filePath , C . TRACK_TYPE_VIDEO )
160
- . colorInfo
161
- . colorTransfer ;
162
- assertThat ( actualColorTransfer ) .isEqualTo (C .COLOR_TRANSFER_ST2084 );
176
+ MediaFormat mediaFormat = getVideoMediaFormatFromDecoder ( context , exportTestResult . filePath );
177
+ ByteBuffer hdrStaticInfo = mediaFormat . getByteBuffer ( MediaFormat . KEY_HDR_STATIC_INFO );
178
+
179
+ assertThat ( max ( byteList ( hdrStaticInfo ))). isAtLeast (( byte ) 1 );
180
+ assertThat ( mediaFormat . getInteger ( MediaFormat . KEY_COLOR_TRANSFER ))
181
+ .isEqualTo (MediaFormat .COLOR_TRANSFER_ST2084 );
163
182
}
164
183
165
184
@ Test
@@ -246,10 +265,14 @@ public void exportAndTranscode_dolbyVisionFile_whenHdrEditingIsSupported() throw
246
265
new TransformerAndroidTestRunner .Builder (context , transformer )
247
266
.build ()
248
267
.run (testId , editedMediaItem );
268
+ MediaFormat mediaFormat = getVideoMediaFormatFromDecoder (context , exportTestResult .filePath );
269
+ ByteBuffer hdrStaticInfo = mediaFormat .getByteBuffer (MediaFormat .KEY_HDR_STATIC_INFO );
270
+
249
271
Format outputFormat =
250
272
retrieveTrackFormat (context , exportTestResult .filePath , C .TRACK_TYPE_VIDEO );
251
273
assertThat (outputFormat .colorInfo .colorTransfer ).isEqualTo (C .COLOR_TRANSFER_ST2084 );
252
274
assertThat (outputFormat .sampleMimeType ).isEqualTo (MimeTypes .VIDEO_H265 );
275
+ assertThat (max (byteList (hdrStaticInfo ))).isAtLeast ((byte ) 1 );
253
276
}
254
277
255
278
@ Test
@@ -401,4 +424,39 @@ public void onFallbackApplied(
401
424
throw exception ;
402
425
}
403
426
}
427
+
428
+ private static List <Byte > byteList (ByteBuffer buffer ) {
429
+ ArrayList <Byte > outputBytes = new ArrayList <>();
430
+ while (buffer .hasRemaining ()) {
431
+ outputBytes .add (buffer .get ());
432
+ }
433
+ return outputBytes ;
434
+ }
435
+
436
+ /**
437
+ * Returns the {@link MediaFormat} corresponding to the video track in {@code filePath}.
438
+ *
439
+ * <p>HDR metadata is optional in both the container and bitstream. Return the {@link MediaFormat}
440
+ * produced by the decoder which should include any metadata from either container or bitstream.
441
+ */
442
+ private MediaFormat getVideoMediaFormatFromDecoder (Context context , String filePath )
443
+ throws Exception {
444
+ AtomicReference <MediaFormat > decodedFrameFormat = new AtomicReference <>();
445
+ if (placeholderSurface == null ) {
446
+ placeholderSurface = PlaceholderSurface .newInstance (context , false );
447
+ }
448
+ decodeOneMediaItemFrame (
449
+ MediaItem .fromUri (filePath ),
450
+ new DecodeOneFrameUtil .Listener () {
451
+ @ Override
452
+ public void onContainerExtracted (MediaFormat mediaFormat ) {}
453
+
454
+ @ Override
455
+ public void onFrameDecoded (MediaFormat mediaFormat ) {
456
+ decodedFrameFormat .set (mediaFormat );
457
+ }
458
+ },
459
+ placeholderSurface );
460
+ return decodedFrameFormat .get ();
461
+ }
404
462
}
0 commit comments