• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.android.exoplayer2.transformer;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import android.media.MediaCodecInfo;
22 import android.media.MediaFormat;
23 import android.util.Size;
24 import androidx.annotation.Nullable;
25 import androidx.test.ext.junit.runners.AndroidJUnit4;
26 import com.google.android.exoplayer2.util.MimeTypes;
27 import com.google.common.collect.ImmutableList;
28 import org.junit.Before;
29 import org.junit.Test;
30 import org.junit.runner.RunWith;
31 import org.robolectric.shadows.MediaCodecInfoBuilder;
32 import org.robolectric.shadows.ShadowMediaCodecList;
33 
34 /** Unit test for {@link EncoderUtil}. */
35 @RunWith(AndroidJUnit4.class)
36 public class EncoderUtilTest {
37   private static final String MIME_TYPE = MimeTypes.VIDEO_H264;
38 
39   @Before
setUp()40   public void setUp() {
41     MediaFormat avcFormat = new MediaFormat();
42     avcFormat.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_VIDEO_AVC);
43     MediaCodecInfo.CodecProfileLevel profileLevel = new MediaCodecInfo.CodecProfileLevel();
44     profileLevel.profile = MediaCodecInfo.CodecProfileLevel.AVCProfileHigh;
45     // Using Level4 gives us 8192 16x16 blocks. If using width 1920 uses 120 blocks, 8192 / 120 = 68
46     // blocks will be left for encoding height 1088.
47     profileLevel.level = MediaCodecInfo.CodecProfileLevel.AVCLevel4;
48 
49     ShadowMediaCodecList.addCodec(
50         MediaCodecInfoBuilder.newBuilder()
51             .setName("test.transformer.avc.encoder")
52             .setIsEncoder(true)
53             .setCapabilities(
54                 MediaCodecInfoBuilder.CodecCapabilitiesBuilder.newBuilder()
55                     .setMediaFormat(avcFormat)
56                     .setIsEncoder(true)
57                     .setColorFormats(
58                         new int[] {MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible})
59                     .setProfileLevels(new MediaCodecInfo.CodecProfileLevel[] {profileLevel})
60                     .build())
61             .build());
62   }
63 
64   @Test
getSupportedResolution_withSupportedResolution_succeeds()65   public void getSupportedResolution_withSupportedResolution_succeeds() {
66     ImmutableList<MediaCodecInfo> supportedEncoders = EncoderUtil.getSupportedEncoders(MIME_TYPE);
67     MediaCodecInfo encoderInfo = supportedEncoders.get(0);
68 
69     @Nullable
70     Size closestSupportedResolution =
71         EncoderUtil.getSupportedResolution(encoderInfo, MIME_TYPE, 1920, 1080);
72 
73     assertThat(closestSupportedResolution).isNotNull();
74     assertThat(closestSupportedResolution.getWidth()).isEqualTo(1920);
75     assertThat(closestSupportedResolution.getHeight()).isEqualTo(1080);
76   }
77 
78   @Test
getSupportedResolution_withUnalignedSize_findsMostCloselySupportedResolution()79   public void getSupportedResolution_withUnalignedSize_findsMostCloselySupportedResolution() {
80     ImmutableList<MediaCodecInfo> supportedEncoders = EncoderUtil.getSupportedEncoders(MIME_TYPE);
81     MediaCodecInfo encoderInfo = supportedEncoders.get(0);
82 
83     @Nullable
84     Size closestSupportedResolution =
85         EncoderUtil.getSupportedResolution(encoderInfo, MIME_TYPE, 1919, 1081);
86 
87     assertThat(closestSupportedResolution).isNotNull();
88     assertThat(closestSupportedResolution.getWidth()).isEqualTo(1920);
89     assertThat(closestSupportedResolution.getHeight()).isEqualTo(1080);
90   }
91 
92   @Test
getSupportedResolution_withWidthTooBig_findsTwoThirdsOfTheOriginalSize()93   public void getSupportedResolution_withWidthTooBig_findsTwoThirdsOfTheOriginalSize() {
94     ImmutableList<MediaCodecInfo> supportedEncoders = EncoderUtil.getSupportedEncoders(MIME_TYPE);
95     MediaCodecInfo encoderInfo = supportedEncoders.get(0);
96 
97     @Nullable
98     Size closestSupportedResolution =
99         EncoderUtil.getSupportedResolution(encoderInfo, MIME_TYPE, 1920, 1920);
100 
101     assertThat(closestSupportedResolution).isNotNull();
102     assertThat(closestSupportedResolution.getWidth()).isEqualTo(1440);
103     assertThat(closestSupportedResolution.getHeight()).isEqualTo(1440);
104   }
105 
106   @Test
getSupportedResolution_withWidthTooBig2_findsHalfOfTheOriginalSize()107   public void getSupportedResolution_withWidthTooBig2_findsHalfOfTheOriginalSize() {
108     ImmutableList<MediaCodecInfo> supportedEncoders = EncoderUtil.getSupportedEncoders(MIME_TYPE);
109     MediaCodecInfo encoderInfo = supportedEncoders.get(0);
110 
111     @Nullable
112     Size closestSupportedResolution =
113         EncoderUtil.getSupportedResolution(encoderInfo, MIME_TYPE, 3840, 2160);
114 
115     assertThat(closestSupportedResolution).isNotNull();
116     assertThat(closestSupportedResolution.getWidth()).isEqualTo(1920);
117     assertThat(closestSupportedResolution.getHeight()).isEqualTo(1080);
118   }
119 }
120