Remix audio remuxing into its own feature flag.

This commit is contained in:
Nicholas Tinsley 2024-02-03 13:10:18 -05:00
parent 3c5cbc3114
commit 4545e70384
6 changed files with 37 additions and 14 deletions

View file

@ -258,7 +258,7 @@ public final class AttachmentCompressionJob extends BaseJob {
}
if (FeatureFlags.useStreamingVideoMuxer()) {
StreamingTranscoder transcoder = new StreamingTranscoder(dataSource, options, constraints.getCompressedVideoMaxSize(context));
StreamingTranscoder transcoder = new StreamingTranscoder(dataSource, options, constraints.getCompressedVideoMaxSize(context), FeatureFlags.allowAudioRemuxing());
if (transcoder.isTranscodeRequired()) {
Log.i(TAG, "Compressing with streaming muxer");

View file

@ -120,6 +120,7 @@ public final class FeatureFlags {
private static final String CALLING_RAISE_HAND = "android.calling.raiseHand";
private static final String USE_ACTIVE_CALL_MANAGER = "android.calling.useActiveCallManager.2";
private static final String GIF_SEARCH = "global.gifSearch";
private static final String AUDIO_REMUXING = "android.media.audioRemux";
/**
* We will only store remote values for flags in this set. If you want a flag to be controllable
@ -192,7 +193,8 @@ public final class FeatureFlags {
CALLING_RAISE_HAND,
PHONE_NUMBER_PRIVACY,
USE_ACTIVE_CALL_MANAGER,
GIF_SEARCH
GIF_SEARCH,
AUDIO_REMUXING
);
@VisibleForTesting
@ -693,6 +695,11 @@ public final class FeatureFlags {
return getBoolean(GIF_SEARCH, true);
}
/** Allow media converters to remux audio instead of transcoding it. */
public static boolean allowAudioRemuxing() {
return getBoolean(AUDIO_REMUXING, false);
}
/** Only for rendering debug info. */
public static synchronized @NonNull Map<String, Object> getMemoryValues() {
return new TreeMap<>(REMOTE_VALUES);

View file

@ -86,9 +86,9 @@ class TranscodeWorker(ctx: Context, params: WorkerParameters) : CoroutineWorker(
}
val transcoder = if (resolution > 0 && desiredBitrate > 0) {
StreamingTranscoder(datasource, null, desiredBitrate, resolution)
StreamingTranscoder(datasource, null, desiredBitrate, resolution, false)
} else {
StreamingTranscoder(datasource, null, DEFAULT_FILE_SIZE_LIMIT)
StreamingTranscoder(datasource, null, DEFAULT_FILE_SIZE_LIMIT, true)
}
setForeground(createForegroundInfo(-1, notificationId))

View file

@ -39,17 +39,20 @@ public final class StreamingTranscoder {
private final boolean transcodeRequired;
private final long fileSizeEstimate;
private final @Nullable TranscoderOptions options;
private final boolean allowAudioRemux;
/**
* @param upperSizeLimit A upper size to transcode to. The actual output size can be up to 10% smaller.
*/
public StreamingTranscoder(@NonNull MediaDataSource dataSource,
@Nullable TranscoderOptions options,
long upperSizeLimit)
long upperSizeLimit,
boolean allowAudioRemux)
throws IOException, VideoSourceException
{
this.dataSource = dataSource;
this.options = options;
this.allowAudioRemux = allowAudioRemux;
final MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
try {
@ -81,11 +84,13 @@ public final class StreamingTranscoder {
public StreamingTranscoder(@NonNull MediaDataSource dataSource,
@Nullable TranscoderOptions options,
int videoBitrate,
int shortEdge)
int shortEdge,
boolean allowAudioRemux)
throws IOException, VideoSourceException
{
this.dataSource = dataSource;
this.options = options;
this.dataSource = dataSource;
this.options = options;
this.allowAudioRemux = allowAudioRemux;
final MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
try {
@ -142,7 +147,7 @@ public final class StreamingTranscoder {
final long startTime = System.currentTimeMillis();
final MediaConverter converter = new MediaConverter();
final MediaConverter converter = new MediaConverter();
converter.setInput(new MediaDataSourceMediaInput(dataSource));
final CountingOutputStream outStream;
@ -155,6 +160,7 @@ public final class StreamingTranscoder {
converter.setVideoResolution(targetQuality.getOutputResolution());
converter.setVideoBitrate(targetQuality.getTargetVideoBitRate());
converter.setAudioBitrate(targetQuality.getTargetAudioBitRate());
converter.setAllowAudioRemux(allowAudioRemux);
if (options != null) {
if (options.endTimeUs > 0) {

View file

@ -41,7 +41,6 @@ final class AudioTrackConverter {
private final MediaCodec mAudioDecoder;
private final MediaCodec mAudioEncoder;
private final boolean skipTrancode;
private final ByteBuffer instanceSampleBuffer = ByteBuffer.allocateDirect(SAMPLE_BUFFER_SIZE);
private final MediaCodec.BufferInfo instanceBufferInfo = new MediaCodec.BufferInfo();
@ -57,8 +56,9 @@ final class AudioTrackConverter {
boolean mAudioExtractorDone;
private boolean mAudioDecoderDone;
boolean mAudioEncoderDone;
private boolean skipTrancode;
private int mOutputAudioTrack = -1;
private int mOutputAudioTrack = -1;
private int mPendingAudioDecoderOutputBufferIndex = -1;
long mMuxingAudioPresentationTime;
@ -164,8 +164,13 @@ final class AudioTrackConverter {
void step() throws IOException {
if (skipTrancode && mEncoderOutputAudioFormat != null) {
extractAndRemux();
return;
try {
extractAndRemux();
return;
} catch (IllegalArgumentException e) {
Log.w(TAG, "Remuxer threw an exception! Disabling remux.", e);
skipTrancode = false;
}
}
// Extract audio from file and feed to decoder.

View file

@ -63,6 +63,7 @@ public final class MediaConverter {
private int mVideoBitrate = 2000000; // 2Mbps
private @VideoCodec String mVideoCodec = VIDEO_CODEC_H264;
private int mAudioBitrate = 128000; // 128Kbps
private boolean mAllowAudioRemux = false;
private Listener mListener;
private boolean mCancelled;
@ -131,6 +132,10 @@ public final class MediaConverter {
mListener = listener;
}
public void setAllowAudioRemux(boolean allow) {
mAllowAudioRemux = allow;
}
@WorkerThread
@RequiresApi(23)
public void convert() throws EncodingException, IOException {
@ -144,7 +149,7 @@ public final class MediaConverter {
muxer = mOutput.createMuxer();
videoTrackConverter = VideoTrackConverter.create(mInput, mTimeFrom, mTimeTo, mVideoResolution, mVideoBitrate, mVideoCodec);
audioTrackConverter = AudioTrackConverter.create(mInput, mTimeFrom, mTimeTo, mAudioBitrate, muxer.supportsAudioRemux());
audioTrackConverter = AudioTrackConverter.create(mInput, mTimeFrom, mTimeTo, mAudioBitrate, mAllowAudioRemux && muxer.supportsAudioRemux());
if (videoTrackConverter == null && audioTrackConverter == null) {
throw new EncodingException("No video and audio tracks");