Android360pFormatStrategy.java

 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 Android360pFormatStrategy implements MediaFormatStrategy {
17
18    private static final int LONGER_LENGTH = 640;
19    private static final int SHORTER_LENGTH = 360;
20    private static final int DEFAULT_VIDEO_BITRATE = 1000 * 1000;
21    private static final int DEFAULT_AUDIO_BITRATE = 128 * 1000;
22    private final int mVideoBitrate;
23    private final int mAudioBitrate;
24    private final int mAudioChannels;
25
26    public Android360pFormatStrategy() {
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 360p, 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}