Skip to content

Commit

Permalink
Merge pull request #1371 from v-novaltd:dsparano-exo207
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 669352191
  • Loading branch information
copybara-github committed Aug 30, 2024
2 parents 5eba716 + f165473 commit 854566d
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 1 deletion.
3 changes: 3 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@
`Surface` in `configure` and calls to a new method `detachOutputSurface`
to remove a previously set `Surface` if the codec supports this
(`MediaCodecInfo.detachedSurfaceSupported`).
* Use `MediaCodecAdapter` supplied pixel aspect ratio values if provided
when processing `onOutputFormatChanged`
([#1371](https://github.com/androidx/media/pull/1371)).
* Text:
* Add a custom `VoiceSpan` and populate it for
[WebVTT voice spans](https://www.w3.org/TR/webvtt1/#webvtt-cue-voice-span)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1342,7 +1342,17 @@ protected void onOutputFormatChanged(Format format, @Nullable MediaFormat mediaF
? mediaFormat.getInteger(KEY_CROP_BOTTOM) - mediaFormat.getInteger(KEY_CROP_TOP) + 1
: mediaFormat.getInteger(MediaFormat.KEY_HEIGHT);
}

pixelWidthHeightRatio = format.pixelWidthHeightRatio;
if (Util.SDK_INT >= 30
&& mediaFormat != null
&& mediaFormat.containsKey(MediaFormat.KEY_PIXEL_ASPECT_RATIO_WIDTH)
&& mediaFormat.containsKey(MediaFormat.KEY_PIXEL_ASPECT_RATIO_HEIGHT)) {
pixelWidthHeightRatio =
(float) mediaFormat.getInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_WIDTH)
/ mediaFormat.getInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_HEIGHT);
}

// The decoder applies the rotation when rendering to the surface. For 90 and 270 degree
// rotations, we need to flip the width, height and pixel aspect ratio to reflect the rotation
// that was applied.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import androidx.media3.common.TrackGroup;
import androidx.media3.common.VideoSize;
import androidx.media3.common.util.Clock;
import androidx.media3.common.util.Util;
import androidx.media3.decoder.CryptoInfo;
import androidx.media3.exoplayer.DecoderCounters;
import androidx.media3.exoplayer.ExoPlaybackException;
Expand Down Expand Up @@ -100,6 +101,7 @@
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowDisplay;
import org.robolectric.shadows.ShadowLooper;
import org.robolectric.shadows.ShadowSystemClock;
Expand All @@ -114,6 +116,7 @@ public class MediaCodecVideoRendererTest {
.setSampleMimeType(MimeTypes.VIDEO_H264)
.setWidth(1920)
.setHeight(1080)
.setPixelWidthHeightRatio(1.0f)
.build();

private static final TrackGroup TRACK_GROUP_H264 = new TrackGroup(VIDEO_H264);
Expand Down Expand Up @@ -747,6 +750,84 @@ public void render_sendsVideoSizeChangeWithCurrentFormatValues() throws Exceptio
new VideoSize(VIDEO_H264.width, VIDEO_H264.height, VIDEO_H264.pixelWidthHeightRatio));
}

@Config(minSdk = 30)
@Test
public void
render_withMediaCodecModifyingPixelAspectRatioWidthHeight_sendsVideoSizeChangeWithMediaFormatValues()
throws Exception {
MediaCodecAdapter.Factory codecAdapterFactory =
configuration ->
new ForwardingSynchronousMediaCodecAdapter(
new SynchronousMediaCodecAdapter.Factory().createAdapter(configuration)) {
@Override
public MediaFormat getOutputFormat() {
MediaFormat mediaFormat = adapter.getOutputFormat();
if (Util.SDK_INT >= 30) {
// Change to 9:16 Ratio
mediaFormat.setInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_WIDTH, 9);
mediaFormat.setInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_HEIGHT, 16);
}
return mediaFormat;
}
};
MediaCodecVideoRenderer mediaCodecVideoRendererWithCustomAdapter =
new MediaCodecVideoRenderer(
ApplicationProvider.getApplicationContext(),
codecAdapterFactory,
mediaCodecSelector,
/* allowedJoiningTimeMs= */ 0,
/* enableDecoderFallback= */ false,
/* eventHandler= */ new Handler(testMainLooper),
/* eventListener= */ eventListener,
/* maxDroppedFramesToNotify= */ 1) {
@Override
protected @Capabilities int supportsFormat(
MediaCodecSelector mediaCodecSelector, Format format) {
return RendererCapabilities.create(C.FORMAT_HANDLED);
}
};
mediaCodecVideoRendererWithCustomAdapter.init(/* index= */ 0, PlayerId.UNSET, Clock.DEFAULT);
mediaCodecVideoRendererWithCustomAdapter.handleMessage(
Renderer.MSG_SET_VIDEO_OUTPUT, new Surface(new SurfaceTexture(/* texName= */ 0)));
FakeSampleStream fakeSampleStream =
new FakeSampleStream(
new DefaultAllocator(/* trimOnReset= */ true, /* individualAllocationSize= */ 1024),
/* mediaSourceEventDispatcher= */ null,
DrmSessionManager.DRM_UNSUPPORTED,
new DrmSessionEventListener.EventDispatcher(),
/* initialFormat= */ VIDEO_H264,
ImmutableList.of(
oneByteSample(/* timeUs= */ 0, C.BUFFER_FLAG_KEY_FRAME), END_OF_STREAM_ITEM));
fakeSampleStream.writeData(/* startPositionUs= */ 0);
mediaCodecVideoRendererWithCustomAdapter.enable(
RendererConfiguration.DEFAULT,
new Format[] {VIDEO_H264},
fakeSampleStream,
/* positionUs= */ 0,
/* joining= */ false,
/* mayRenderStartOfStream= */ true,
/* startPositionUs= */ 0,
/* offsetUs= */ 0,
new MediaSource.MediaPeriodId(new Object()));
mediaCodecVideoRendererWithCustomAdapter.setCurrentStreamFinal();
mediaCodecVideoRendererWithCustomAdapter.start();

int positionUs = 0;
do {
mediaCodecVideoRendererWithCustomAdapter.render(
positionUs, SystemClock.elapsedRealtime() * 1000);
positionUs += 10;
} while (!mediaCodecVideoRendererWithCustomAdapter.isEnded());
shadowOf(testMainLooper).idle();

verify(eventListener)
.onVideoSizeChanged(
new VideoSize(
VIDEO_H264.width,
VIDEO_H264.height,
/* pixelWidthHeightRatio= */ VIDEO_H264.pixelWidthHeightRatio * (9.0f / 16.0f)));
}

@Test
public void
render_withMultipleQueued_sendsVideoSizeChangedWithCorrectPixelAspectRatioWhenMultipleQueued()
Expand Down Expand Up @@ -1903,7 +1984,7 @@ public int dequeueOutputBufferIndex(MediaCodec.BufferInfo bufferInfo) {

private abstract static class ForwardingSynchronousMediaCodecAdapter
implements MediaCodecAdapter {
private final MediaCodecAdapter adapter;
protected final MediaCodecAdapter adapter;

ForwardingSynchronousMediaCodecAdapter(MediaCodecAdapter adapter) {
this.adapter = adapter;
Expand Down

0 comments on commit 854566d

Please sign in to comment.