audioDataSources = new ArrayList<>();
@@ -117,6 +125,7 @@ public static class Builder {
private TimeInterpolator timeInterpolator;
private AudioStretcher audioStretcher;
private AudioResampler audioResampler;
+ private VideoScaler videoScaler;
Builder(@NonNull String outPath) {
this.dataSink = new DefaultDataSink(outPath);
@@ -199,13 +208,13 @@ public Builder setAudioTrackStrategy(@Nullable TrackStrategy trackStrategy) {
* Sets the video output strategy. If absent, this defaults to the 16:9
* strategy returned by {@link DefaultVideoStrategies#for720x1280()}.
*
- * @param trackStrategy the desired strategy
+ * @param videoTrackStrategy the desired strategy
* @return this for chaining
*/
@NonNull
@SuppressWarnings("unused")
- public Builder setVideoTrackStrategy(@Nullable TrackStrategy trackStrategy) {
- this.videoTrackStrategy = trackStrategy;
+ public Builder setVideoTrackStrategy(@Nullable TrackStrategy videoTrackStrategy) {
+ this.videoTrackStrategy = videoTrackStrategy;
return this;
}
@@ -318,6 +327,18 @@ public Builder setAudioResampler(@NonNull AudioResampler audioResampler) {
return this;
}
+ /**
+ * Set an {@link VideoScaler} to change the resolution of the video frames
+ * so that they fit the new resolution
+ *
+ */
+ @NonNull
+ @SuppressWarnings("unused")
+ public Builder setVideoScaler(@NonNull VideoScaler videoScaler) {
+ this.videoScaler = videoScaler;
+ return this;
+ }
+
/**
* Generates muted audio data sources if needed
* @return The list of audio data sources including the muted sources
@@ -389,6 +410,9 @@ public TranscoderOptions build() {
if (audioResampler == null) {
audioResampler = new DefaultAudioResampler();
}
+ if (videoScaler == null) {
+ videoScaler = new UpVideoScaler();
+ }
TranscoderOptions options = new TranscoderOptions();
options.listener = listener;
options.audioDataSources = buildAudioDataSources();
@@ -402,6 +426,7 @@ public TranscoderOptions build() {
options.timeInterpolator = timeInterpolator;
options.audioStretcher = audioStretcher;
options.audioResampler = audioResampler;
+ options.videoScaler = videoScaler;
return options;
}
diff --git a/lib/src/main/java/com/otaliastudios/transcoder/engine/Engine.java b/lib/src/main/java/com/otaliastudios/transcoder/engine/Engine.java
index 742fd1cf..18e2e683 100644
--- a/lib/src/main/java/com/otaliastudios/transcoder/engine/Engine.java
+++ b/lib/src/main/java/com/otaliastudios/transcoder/engine/Engine.java
@@ -171,6 +171,7 @@ private void openCurrentStep(@NonNull TrackType type, @NonNull TranscoderOptions
case VIDEO:
transcoder = new VideoTrackTranscoder(dataSource, mDataSink,
interpolator,
+ options.getVideoScaler(),
options.getVideoRotation());
break;
case AUDIO:
diff --git a/lib/src/main/java/com/otaliastudios/transcoder/scale/DownVideoScaler.java b/lib/src/main/java/com/otaliastudios/transcoder/scale/DownVideoScaler.java
new file mode 100644
index 00000000..b239dc23
--- /dev/null
+++ b/lib/src/main/java/com/otaliastudios/transcoder/scale/DownVideoScaler.java
@@ -0,0 +1,20 @@
+package com.otaliastudios.transcoder.scale;
+
+import androidx.annotation.NonNull;
+
+import com.otaliastudios.transcoder.transcode.internal.VideoDecoderOutput;
+
+/**
+ * An {@link VideoScaler} that scale the video down so that no side exceed the new resolution
+ * Sides that are too small will have black borders
+ */
+public class DownVideoScaler implements VideoScaler {
+ @Override
+ public void scaleOutput(@NonNull VideoDecoderOutput videoDecoderOutput, float scaleX, float scaleY, boolean flipped) {
+ if (flipped) { // The drawable is not affected by the flip so we need to reverse it
+ videoDecoderOutput.setDrawableScale(1.0F / scaleX, 1.0F / scaleY);
+ } else {
+ videoDecoderOutput.setDrawableScale(1.0F / scaleY, 1.0F / scaleX);
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/src/main/java/com/otaliastudios/transcoder/scale/StretchVideoScaler.java b/lib/src/main/java/com/otaliastudios/transcoder/scale/StretchVideoScaler.java
new file mode 100644
index 00000000..8862f229
--- /dev/null
+++ b/lib/src/main/java/com/otaliastudios/transcoder/scale/StretchVideoScaler.java
@@ -0,0 +1,16 @@
+package com.otaliastudios.transcoder.scale;
+
+import androidx.annotation.NonNull;
+
+import com.otaliastudios.transcoder.transcode.internal.VideoDecoderOutput;
+
+/**
+ * An {@link VideoScaler} that strech the video so that they match the video resolution
+ * at the cost of deforming the images
+ */
+public class StretchVideoScaler implements VideoScaler {
+ @Override
+ public void scaleOutput(@NonNull VideoDecoderOutput videoDecoderOutput, float scaleX, float scaleY, boolean flipped) {
+ //No scaling will automatically stretch the frames to fill all the drawable space
+ }
+}
\ No newline at end of file
diff --git a/lib/src/main/java/com/otaliastudios/transcoder/scale/UpVideoScaler.java b/lib/src/main/java/com/otaliastudios/transcoder/scale/UpVideoScaler.java
new file mode 100644
index 00000000..444eab65
--- /dev/null
+++ b/lib/src/main/java/com/otaliastudios/transcoder/scale/UpVideoScaler.java
@@ -0,0 +1,16 @@
+package com.otaliastudios.transcoder.scale;
+
+import androidx.annotation.NonNull;
+
+import com.otaliastudios.transcoder.transcode.internal.VideoDecoderOutput;
+
+/**
+ * An {@link VideoScaler} that scale the video up so that it touches all sides
+ * of the new resolution and exceeding parts will be truncated
+ */
+public class UpVideoScaler implements VideoScaler {
+ @Override
+ public void scaleOutput(@NonNull VideoDecoderOutput videoDecoderOutput, float scaleX, float scaleY, boolean flipped) {
+ videoDecoderOutput.setScale(scaleX, scaleY);
+ }
+}
diff --git a/lib/src/main/java/com/otaliastudios/transcoder/scale/VideoScaler.java b/lib/src/main/java/com/otaliastudios/transcoder/scale/VideoScaler.java
new file mode 100644
index 00000000..b012361f
--- /dev/null
+++ b/lib/src/main/java/com/otaliastudios/transcoder/scale/VideoScaler.java
@@ -0,0 +1,22 @@
+package com.otaliastudios.transcoder.scale;
+
+import androidx.annotation.NonNull;
+
+import com.otaliastudios.transcoder.transcode.internal.VideoDecoderOutput;
+
+/**
+ * Scale the frames when they are not of the expected resolution
+ */
+public interface VideoScaler {
+ /**
+ * Apply the scaling to the video decoder output
+ *
+ * It can be done using VideoDecoderOutput.setScale or VideoDecoderOutput.setDrawableScale
+ *
+ * @param videoDecoderOutput the video decoder output
+ * @param scaleX the input width/height
+ * @param scaleY the output width/height
+ * @param flipped whether or not the frame was rotated by 90 degrees
+ */
+ void scaleOutput(@NonNull VideoDecoderOutput videoDecoderOutput, float scaleX, float scaleY, boolean flipped);
+}
diff --git a/lib/src/main/java/com/otaliastudios/transcoder/strategy/DefaultVideoStrategy.java b/lib/src/main/java/com/otaliastudios/transcoder/strategy/DefaultVideoStrategy.java
index bbab7255..5335b3ed 100644
--- a/lib/src/main/java/com/otaliastudios/transcoder/strategy/DefaultVideoStrategy.java
+++ b/lib/src/main/java/com/otaliastudios/transcoder/strategy/DefaultVideoStrategy.java
@@ -16,6 +16,7 @@
import com.otaliastudios.transcoder.strategy.size.Resizer;
import com.otaliastudios.transcoder.internal.Logger;
import com.otaliastudios.transcoder.internal.MediaFormatConstants;
+import com.otaliastudios.transcoder.transcode.internal.VideoDecoderOutput;
import androidx.annotation.NonNull;
diff --git a/lib/src/main/java/com/otaliastudios/transcoder/strategy/TrackStrategy.java b/lib/src/main/java/com/otaliastudios/transcoder/strategy/TrackStrategy.java
index fa2df2a4..a2210e51 100644
--- a/lib/src/main/java/com/otaliastudios/transcoder/strategy/TrackStrategy.java
+++ b/lib/src/main/java/com/otaliastudios/transcoder/strategy/TrackStrategy.java
@@ -2,12 +2,11 @@
import android.media.MediaFormat;
+import androidx.annotation.NonNull;
+
import com.otaliastudios.transcoder.engine.TrackStatus;
import com.otaliastudios.transcoder.strategy.size.Resizer;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
import java.util.List;
/**
diff --git a/lib/src/main/java/com/otaliastudios/transcoder/transcode/VideoTrackTranscoder.java b/lib/src/main/java/com/otaliastudios/transcoder/transcode/VideoTrackTranscoder.java
index 1f782566..c4e1e573 100644
--- a/lib/src/main/java/com/otaliastudios/transcoder/transcode/VideoTrackTranscoder.java
+++ b/lib/src/main/java/com/otaliastudios/transcoder/transcode/VideoTrackTranscoder.java
@@ -16,20 +16,20 @@
package com.otaliastudios.transcoder.transcode;
import android.media.MediaCodec;
-import android.media.MediaExtractor;
import android.media.MediaFormat;
import androidx.annotation.NonNull;
import com.otaliastudios.transcoder.engine.TrackType;
+import com.otaliastudios.transcoder.internal.Logger;
import com.otaliastudios.transcoder.internal.MediaCodecBuffers;
+import com.otaliastudios.transcoder.internal.MediaFormatConstants;
+import com.otaliastudios.transcoder.scale.VideoScaler;
import com.otaliastudios.transcoder.sink.DataSink;
import com.otaliastudios.transcoder.source.DataSource;
import com.otaliastudios.transcoder.time.TimeInterpolator;
import com.otaliastudios.transcoder.transcode.internal.VideoDecoderOutput;
import com.otaliastudios.transcoder.transcode.internal.VideoEncoderInput;
-import com.otaliastudios.transcoder.internal.Logger;
-import com.otaliastudios.transcoder.internal.MediaFormatConstants;
import com.otaliastudios.transcoder.transcode.internal.VideoFrameDropper;
import java.nio.ByteBuffer;
@@ -46,6 +46,7 @@ public class VideoTrackTranscoder extends BaseTrackTranscoder {
private MediaCodec mEncoder; // Keep this since we want to signal EOS on it.
private VideoFrameDropper mFrameDropper;
private final TimeInterpolator mTimeInterpolator;
+ private final VideoScaler mVideoScaler;
private final int mSourceRotation;
private final int mExtraRotation;
@@ -53,9 +54,11 @@ public VideoTrackTranscoder(
@NonNull DataSource dataSource,
@NonNull DataSink dataSink,
@NonNull TimeInterpolator timeInterpolator,
+ @NonNull VideoScaler videoScaler,
int rotation) {
super(dataSource, dataSink, TrackType.VIDEO);
mTimeInterpolator = timeInterpolator;
+ mVideoScaler = videoScaler;
mSourceRotation = dataSource.getOrientation();
mExtraRotation = rotation;
}
@@ -130,7 +133,7 @@ protected void onCodecsStarted(@NonNull MediaFormat inputFormat, @NonNull MediaF
} else if (inputRatio < outputRatio) { // Input taller. We have a scaleY.
scaleY = outputRatio / inputRatio;
}
- mDecoderOutputSurface.setScale(scaleX, scaleY);
+ mVideoScaler.scaleOutput(mDecoderOutputSurface, scaleX, scaleY, flip);
}
@Override
diff --git a/lib/src/main/java/com/otaliastudios/transcoder/transcode/internal/VideoDecoderOutput.java b/lib/src/main/java/com/otaliastudios/transcoder/transcode/internal/VideoDecoderOutput.java
index 7f052561..efa20220 100644
--- a/lib/src/main/java/com/otaliastudios/transcoder/transcode/internal/VideoDecoderOutput.java
+++ b/lib/src/main/java/com/otaliastudios/transcoder/transcode/internal/VideoDecoderOutput.java
@@ -87,6 +87,21 @@ public void setScale(float scaleX, float scaleY) {
mScaleY = scaleY;
}
+ /**
+ * Scale the canvas along the two axes.
+ * @param scaleX x scale
+ * @param scaleY y scale
+ */
+ @SuppressWarnings("unused")
+ public void setDrawableScale(float scaleX, float scaleY) {
+ mDrawable.setRect(
+ -1.0F * scaleX,
+ -1.0F * scaleY,
+ 1.0F * scaleX,
+ 1.0F * scaleY
+ );
+ }
+
/**
* Sets the desired frame rotation with respect
* to its natural orientation.
pFad - Phonifier reborn
Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy