1package eu.siacs.conversations.utils;
2
3import android.media.MediaCodecInfo;
4import android.media.MediaFormat;
5import android.os.Build;
6import android.util.Log;
7
8import androidx.annotation.RequiresApi;
9
10import net.ypresto.androidtranscoder.format.MediaFormatExtraConstants;
11import net.ypresto.androidtranscoder.format.MediaFormatStrategy;
12import net.ypresto.androidtranscoder.format.OutputFormatUnavailableException;
13
14import eu.siacs.conversations.Config;
15
16public class Android720pFormatStrategy implements MediaFormatStrategy {
17
18 private static final int LONGER_LENGTH = 1280;
19 private static final int SHORTER_LENGTH = 720;
20 private static final int DEFAULT_VIDEO_BITRATE = 2000 * 1000;
21 private static final int DEFAULT_AUDIO_BITRATE = 192 * 1000;
22 private final int mVideoBitrate;
23 private final int mAudioBitrate;
24 private final int mAudioChannels;
25
26 public Android720pFormatStrategy() {
27 mVideoBitrate = DEFAULT_VIDEO_BITRATE;
28 mAudioBitrate = DEFAULT_AUDIO_BITRATE;
29 mAudioChannels = 2;
30 }
31
32 @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
33 @Override
34 public MediaFormat createVideoOutputFormat(MediaFormat inputFormat) {
35 int width = inputFormat.getInteger(MediaFormat.KEY_WIDTH);
36 int height = inputFormat.getInteger(MediaFormat.KEY_HEIGHT);
37 int longer, shorter, outWidth, outHeight;
38 if (width >= height) {
39 longer = width;
40 shorter = height;
41 outWidth = LONGER_LENGTH;
42 outHeight = SHORTER_LENGTH;
43 } else {
44 shorter = width;
45 longer = height;
46 outWidth = SHORTER_LENGTH;
47 outHeight = LONGER_LENGTH;
48 }
49 if (longer * 9 != shorter * 16) {
50 throw new OutputFormatUnavailableException("This video is not 16:9, and is not able to transcode. (" + width + "x" + height + ")");
51 }
52 if (shorter <= SHORTER_LENGTH) {
53 Log.d(Config.LOGTAG, "This video is less or equal to 720p, pass-through. (" + width + "x" + height + ")");
54 return null;
55 }
56 MediaFormat format = MediaFormat.createVideoFormat("video/avc", outWidth, outHeight);
57 format.setInteger(MediaFormat.KEY_BIT_RATE, mVideoBitrate);
58 format.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
59 format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 3);
60 format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
61 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
62 format.setInteger(MediaFormat.KEY_PROFILE ,MediaCodecInfo.CodecProfileLevel.AVCProfileBaseline);
63 format.setInteger(MediaFormat.KEY_LEVEL, MediaCodecInfo.CodecProfileLevel.AVCLevel13);
64 }
65 return format;
66 }
67
68 @Override
69 public MediaFormat createAudioOutputFormat(MediaFormat inputFormat) {
70 final MediaFormat format = MediaFormat.createAudioFormat(MediaFormatExtraConstants.MIMETYPE_AUDIO_AAC, inputFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE), mAudioChannels);
71 format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
72 format.setInteger(MediaFormat.KEY_BIT_RATE, mAudioBitrate);
73 return format;
74 }
75
76}