Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement specific options for different encoders #3725

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/main/java/io/antmedia/AntMediaApplicationAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ public class AntMediaApplicationAdapter extends MultiThreadedApplicationAdapter

public static final String DEFAULT_LOCALHOST = "127.0.0.1";

protected static final String[] POSSIBLE_TUNE_LIST = new String[]{"zerolatency", "film", "animation", "grain", "stillimage", "fastdecode", "psnr", "ssim"};
protected static final String[] POSSIBLE_PRESET_LIST = new String[]{"ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow", "ll"};
protected static final String[] POSSIBLE_PROFILE_LIST = new String[]{"main", "high", "baseline"};



protected static Logger logger = LoggerFactory.getLogger(AntMediaApplicationAdapter.class);
private ServerSettings serverSettings;
public static final String VOD = "VoD";
Expand Down Expand Up @@ -1420,6 +1426,40 @@ private boolean isEncoderSettingsValid(List<EncoderSettings> encoderSettingsList
logger.error("Unexpected encoder parameter. None of the parameters(height:{}, video bitrate:{}, audio bitrate:{}) can be zero or less", encoderSettings.getHeight(), encoderSettings.getVideoBitrate(), encoderSettings.getAudioBitrate());
return false;
}
if(encoderSettings.getTune() != null && !encoderSettings.getTune().isEmpty()){
for(int i = 0; i < POSSIBLE_TUNE_LIST.length; i++){
if(encoderSettings.getTune().equals(POSSIBLE_TUNE_LIST[i])){
break;
}
if(i == (POSSIBLE_TUNE_LIST.length - 1) ) {
logger.error("Unexpected encoder parameter. Tune can't be {}", encoderSettings.getTune());
return false;
}
}
}
if(encoderSettings.getPreset() != null && !encoderSettings.getPreset().isEmpty()){
for(int i = 0; i < POSSIBLE_PRESET_LIST.length; i++){
if(encoderSettings.getPreset().equals(POSSIBLE_PRESET_LIST[i])){
break;
}
if(i == (POSSIBLE_PRESET_LIST.length - 1) ){
logger.error("Unexpected encoder parameter. Preset can't be {}", encoderSettings.getPreset());
return false;
}
}
}

if(encoderSettings.getProfile() != null && !encoderSettings.getProfile().isEmpty()){
for(int i = 0; i < POSSIBLE_PROFILE_LIST.length; i++){
if(encoderSettings.getProfile().equals(POSSIBLE_PROFILE_LIST[i])){
break;
}
if(i == (POSSIBLE_PROFILE_LIST.length - 1) ) {
logger.error("Unexpected encoder parameter. Profile can't be {}", encoderSettings.getProfile());
return false;
}
}
}
}
}
return true;
Expand Down
21 changes: 19 additions & 2 deletions src/main/java/io/antmedia/AppSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -1530,6 +1530,9 @@ public static String encodersList2Str(List<EncoderSettings> encoderSettingsList)
encoderJSON.put(EncoderSettings.VIDEO_BITRATE, encoderSettings.getVideoBitrate());
encoderJSON.put(EncoderSettings.AUDIO_BITRATE, encoderSettings.getAudioBitrate());
encoderJSON.put(EncoderSettings.FORCE_ENCODE, encoderSettings.isForceEncode());
encoderJSON.put(EncoderSettings.ENC_PROFILE, encoderSettings.getProfile());
encoderJSON.put(EncoderSettings.ENC_TUNE, encoderSettings.getTune());
encoderJSON.put(EncoderSettings.ENC_PRESET, encoderSettings.getPreset());
jsonArray.add(encoderJSON);
}
return jsonArray.toJSONString();
Expand All @@ -1544,6 +1547,9 @@ public static List<EncoderSettings> encodersStr2List(String encoderSettingsStrin
int videoBitrate;
int audioBitrate;
boolean forceEncode;
String profile = null;
String preset = null;
String tune = null;
List<EncoderSettings> encoderSettingsList = new ArrayList<>();

try {
Expand All @@ -1557,7 +1563,18 @@ public static List<EncoderSettings> encodersStr2List(String encoderSettingsStrin
videoBitrate = Integer.parseInt(jsObject.get(EncoderSettings.VIDEO_BITRATE).toString());
audioBitrate = Integer.parseInt(jsObject.get(EncoderSettings.AUDIO_BITRATE).toString());
forceEncode = (boolean)jsObject.get(EncoderSettings.FORCE_ENCODE);
encoderSettingsList.add(new EncoderSettings(height,videoBitrate,audioBitrate,forceEncode));
if(jsObject.get(EncoderSettings.ENC_PROFILE) != null){
profile = jsObject.get(EncoderSettings.ENC_PROFILE).toString();
}

if(jsObject.get(EncoderSettings.ENC_TUNE) != null){
tune = jsObject.get(EncoderSettings.ENC_TUNE).toString();
}
if(jsObject.get(EncoderSettings.ENC_PRESET) != null){
preset = jsObject.get(EncoderSettings.ENC_PRESET).toString();
}

encoderSettingsList.add(new EncoderSettings(height,videoBitrate,audioBitrate,forceEncode, profile, tune, preset));
}
}
catch (ParseException e) {
Expand All @@ -1571,7 +1588,7 @@ public static List<EncoderSettings> encodersStr2List(String encoderSettingsStrin
videoBitrate = Integer.parseInt(values[i]);
i++;
audioBitrate = Integer.parseInt(values[i]);
encoderSettingsList.add(new EncoderSettings(height, videoBitrate, audioBitrate,true));
encoderSettingsList.add(new EncoderSettings(height, videoBitrate, audioBitrate,true, null, null, null));
}
}
}
Expand Down
23 changes: 22 additions & 1 deletion src/main/java/io/antmedia/EncoderSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ public class EncoderSettings implements Serializable{
private int height;
private int videoBitrate;
private int audioBitrate;
private String profile;
private String tune;
private String preset;

/*
* Enable/Disable stream resolution check flag
Expand All @@ -19,16 +22,22 @@ public class EncoderSettings implements Serializable{
public static final String VIDEO_BITRATE = "videoBitrate";
public static final String AUDIO_BITRATE = "audioBitrate";
public static final String FORCE_ENCODE = "forceEncode";
public static final String ENC_PROFILE = "profile";
public static final String ENC_TUNE = "tune";
public static final String ENC_PRESET = "preset";

public EncoderSettings() {

}

public EncoderSettings(int height, int videoBitrate, int audioBitrate, boolean forceEncode) {
public EncoderSettings(int height, int videoBitrate, int audioBitrate, boolean forceEncode, String profile, String tune, String preset) {
this.height = height;
this.videoBitrate = videoBitrate;
this.audioBitrate = audioBitrate;
this.forceEncode = forceEncode;
this.preset = preset;
this.tune = tune;
this.profile = profile;
}

public int getHeight() {
Expand Down Expand Up @@ -63,4 +72,16 @@ public void setForceEncode(boolean forceEncode) {
this.forceEncode = forceEncode;
}

public void setTune(String tune){ this.tune = tune;}

public String getTune(){return tune;}

public void setProfile(String profile){ this.profile = profile;}

public String getProfile(){return profile;}

public void setPreset(String preset){this.preset = preset;}

public String getPreset(){return preset;}

}
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ public void testAdaptiveMasterFileBug()


List<EncoderSettings> settingsList = new ArrayList<>();
settingsList.add(new EncoderSettings(240, 300000, 64000,true));
settingsList.add(new EncoderSettings(240, 300000, 64000,true, null, null, null));
appSettingsModel.setEncoderSettings(settingsList);
result = ConsoleAppRestServiceTest.callSetAppSettings("LiveApp", appSettingsModel);
assertTrue(result.isSuccess());
Expand Down Expand Up @@ -464,7 +464,7 @@ public void testSendRTMPStream() {
appSettingsModel.setMp4MuxingEnabled(true);

List<EncoderSettings> settingsList = new ArrayList<>();
settingsList.add(new EncoderSettings(240, 300000, 64000,true));
settingsList.add(new EncoderSettings(240, 300000, 64000,true, null, null,null));
appSettingsModel.setEncoderSettings(settingsList);
result = ConsoleAppRestServiceTest.callSetAppSettings("LiveApp", appSettingsModel);
assertTrue(result.isSuccess());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,7 @@ public void testZeroEncoderSettings() {
int size = appSettings.getEncoderSettings().size();
List<EncoderSettings> settingsList = new ArrayList<>();

settingsList.add(new EncoderSettings(0, 200000, 300000,true));
settingsList.add(new EncoderSettings(0, 200000, 300000,true, null, null, null));

appSettings.setEncoderSettings(settingsList);
Result result = callSetAppSettings(appName, appSettings);
Expand All @@ -609,7 +609,7 @@ public void testZeroEncoderSettings() {



settingsList.add(new EncoderSettings(480, 0, 300000,true));
settingsList.add(new EncoderSettings(480, 0, 300000,true, "baseline", "zerolatency", "veryfast"));
appSettings.setEncoderSettings(settingsList);
result = callSetAppSettings(appName, appSettings);
assertFalse(result.isSuccess());
Expand All @@ -618,7 +618,7 @@ public void testZeroEncoderSettings() {
assertEquals(encoderSettingSize, appSettings.getEncoderSettings().size());


settingsList.add(new EncoderSettings(480, 2000, 0,true));
settingsList.add(new EncoderSettings(480, 2000, 0,true, "baseline", "zerolatency", "veryfast"));
appSettings.setEncoderSettings(settingsList);
result = callSetAppSettings(appName, appSettings);
assertFalse(result.isSuccess());
Expand All @@ -628,7 +628,7 @@ public void testZeroEncoderSettings() {


settingsList.clear();
settingsList.add(new EncoderSettings(480, 2000, 30000,true));
settingsList.add(new EncoderSettings(480, 2000, 30000,true, "baseline", "zerolatency", "veryfast"));
appSettings.setEncoderSettings(settingsList);

result = callSetAppSettings(appName, appSettings);
Expand Down Expand Up @@ -772,7 +772,7 @@ public void testChangePreviewOverwriteSettings() {
AppSettings appSettingsModel = callGetAppSettings("LiveApp");


appSettingsModel.setEncoderSettings(Arrays.asList(new EncoderSettings(240, 300000, 64000,true)));
appSettingsModel.setEncoderSettings(Arrays.asList(new EncoderSettings(240, 300000, 64000,true, "baseline", "zerolatency", "veryfast")));

appSettingsModel.setGeneratePreview(true);

Expand Down Expand Up @@ -1913,7 +1913,7 @@ public void testRTSPSourceWithAdaptiveBitrate() {
return;
}

rtspSource(Arrays.asList(new EncoderSettings(144, 150000, 16000,true)));
rtspSource(Arrays.asList(new EncoderSettings(144, 150000, 16000,true, "baseline", "zerolatency", "veryfast")));

} catch (Exception e) {
e.printStackTrace();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.antmedia.test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
Expand Down Expand Up @@ -30,6 +31,7 @@
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;

import io.antmedia.EncoderSettings;
import org.apache.commons.lang3.RandomUtils;
import org.apache.http.HttpEntity;
import org.apache.http.StatusLine;
Expand Down Expand Up @@ -210,9 +212,63 @@ public void testAppSettings()
spyAdapter.setStorageClient(storageClient);

spyAdapter.setAppSettings(settings);

//Test Not Updating the settings because of the wrong encoder settings
//----------------------------------------------------------------------
int height1 = 480;
int videoBitrate1= 500000;
int audioBitrate1 = 128000;
boolean forceEncode1 = false;
String profile1 = "baseline";
//Provide wrong tune
String tune1 = "zeroatency";
String preset1 = "fast";

//Try with new format settings
String newFormatEncoderSettingString ="[{\"videoBitrate\":"+videoBitrate1+",\"forceEncode\":"+forceEncode1+",\"profile\":\""+profile1+"\",\"preset\":\""+preset1+"\",\"audioBitrate\":"+audioBitrate1+",\"tune\":\""+tune1+"\",\"height\":"+height1+"}]";
List<EncoderSettings> list = AppSettings.encodersStr2List(newFormatEncoderSettingString);
newSettings.setEncoderSettings(list);

spyAdapter.setScope(scope);
spyAdapter.updateSettings(newSettings, true, false);

boolean result = spyAdapter.updateSettings(newSettings, true, false);

assertFalse(result);
AppSettings set = spyAdapter.getAppSettings();
assertNotEquals(set.getEncoderSettings(), list);

profile1 = "baseline";
tune1 = "zerolatency";
preset1 = "fart";

newFormatEncoderSettingString ="[{\"videoBitrate\":"+videoBitrate1+",\"forceEncode\":"+forceEncode1+",\"profile\":\""+profile1+"\",\"preset\":\""+preset1+"\",\"audioBitrate\":"+audioBitrate1+",\"tune\":\""+tune1+"\",\"height\":"+height1+"}]";
list = AppSettings.encodersStr2List(newFormatEncoderSettingString);
newSettings.setEncoderSettings(list);

spyAdapter.setScope(scope);
result = spyAdapter.updateSettings(newSettings, true, false);

assertFalse(result);
set = spyAdapter.getAppSettings();
assertNotEquals(set.getEncoderSettings(), list);

profile1 = "baselie";
tune1 = "zerolatency";
preset1 = "fast";

newFormatEncoderSettingString ="[{\"videoBitrate\":"+videoBitrate1+",\"forceEncode\":"+forceEncode1+",\"profile\":\""+profile1+"\",\"preset\":\""+preset1+"\",\"audioBitrate\":"+audioBitrate1+",\"tune\":\""+tune1+"\",\"height\":"+height1+"}]";
list = AppSettings.encodersStr2List(newFormatEncoderSettingString);
newSettings.setEncoderSettings(list);

spyAdapter.setScope(scope);
result = spyAdapter.updateSettings(newSettings, true, false);

assertFalse(result);
set = spyAdapter.getAppSettings();
assertNotEquals(set.getEncoderSettings(), list);

newSettings.setEncoderSettingsString("");

//----------------------------------------------------------------------


IClusterNotifier clusterNotifier = mock(IClusterNotifier.class);
Expand Down
54 changes: 49 additions & 5 deletions src/test/java/io/antmedia/test/AppSettingsUnitTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ public void testEncodeSettings() {
int videoBitrate1= 500000;
int audioBitrate1 = 128000;
boolean forceEncode1 = false;
String profile1 = "baseline";
String tune1 = "zerolatency";
String preset1 = "fast";

int height2 = 360;
int videoBitrate2 = 400000;
Expand All @@ -157,25 +160,59 @@ public void testEncodeSettings() {


//Try with new format settings
String newFormatEncoderSettingString ="[{\"videoBitrate\":"+videoBitrate1+",\"forceEncode\":"+forceEncode1+",\"audioBitrate\":"+audioBitrate1+",\"height\":"+height1+"},{\"videoBitrate\":"+videoBitrate2+",\"forceEncode\":"+forceEncode2+",\"audioBitrate\":"+audioBitrate2+",\"height\":"+height2+"},{\"videoBitrate\":"+videoBitrate3+",\"forceEncode\":"+forceEncode3+",\"audioBitrate\":"+audioBitrate3+",\"height\":"+height3+"}]";
String newFormatEncoderSettingString ="[{\"videoBitrate\":"+videoBitrate1+",\"forceEncode\":"+forceEncode1+",\"profile\":\""+profile1+"\",\"preset\":\""+preset1+"\",\"audioBitrate\":"+audioBitrate1+",\"tune\":\""+tune1+"\",\"height\":"+height1+"},{\"videoBitrate\":"+videoBitrate2+",\"forceEncode\":"+forceEncode2+",\"profile\":\""+profile1+"\",\"preset\":\""+preset1+"\",\"audioBitrate\":"+audioBitrate2+",\"tune\":\""+tune1+"\",\"height\":"+height2+"},{\"videoBitrate\":"+videoBitrate3+",\"forceEncode\":"+forceEncode3+",\"profile\":\""+profile1+"\",\"preset\":\""+preset1+"\",\"audioBitrate\":"+audioBitrate3+",\"tune\":\""+tune1+"\",\"height\":"+height3+"}]";

List<EncoderSettings> list = AppSettings.encodersStr2List(newFormatEncoderSettingString);

assertEquals(3, list.size());
assertEquals(480, list.get(0).getHeight());
assertEquals(500000, list.get(0).getVideoBitrate());
assertEquals(128000, list.get(0).getAudioBitrate());

assertEquals(profile1, list.get(0).getProfile());
assertEquals(preset1, list.get(0).getPreset());
assertEquals(tune1, list.get(0).getTune());

assertEquals(360, list.get(1).getHeight());
assertEquals(400000, list.get(1).getVideoBitrate());
assertEquals(64000, list.get(1).getAudioBitrate());

assertEquals(profile1, list.get(1).getProfile());
assertEquals(preset1, list.get(1).getPreset());
assertEquals(tune1, list.get(1).getTune());


assertEquals(240, list.get(2).getHeight());
assertEquals(300000, list.get(2).getVideoBitrate());
assertEquals(32000, list.get(2).getAudioBitrate());
assertEquals(profile1, list.get(2).getProfile());
assertEquals(preset1, list.get(2).getPreset());
assertEquals(tune1, list.get(2).getTune());

assertEquals(newFormatEncoderSettingString, appSettings.encodersList2Str(list));


EncoderSettings encSettings = new EncoderSettings(height1,videoBitrate1, audioBitrate1, forceEncode1, profile1,tune1,preset1);
assertEquals(480, encSettings.getHeight());
assertEquals(500000, encSettings.getVideoBitrate());
assertEquals(128000, encSettings.getAudioBitrate());
assertEquals(profile1, encSettings.getProfile());
assertEquals(preset1, encSettings.getPreset());
assertEquals(tune1, encSettings.getTune());

encSettings.setAudioBitrate(audioBitrate2);
encSettings.setForceEncode(forceEncode2);
encSettings.setHeight(height2);
encSettings.setPreset("veryfast");
encSettings.setProfile("high");
encSettings.setTune("film");
encSettings.setVideoBitrate(videoBitrate2);

assertEquals(360, encSettings.getHeight());
assertEquals(400000, encSettings.getVideoBitrate());
assertEquals(64000, encSettings.getAudioBitrate());
assertEquals("high", encSettings.getProfile());
assertEquals("veryfast", encSettings.getPreset());
assertEquals("film", encSettings.getTune());


//Try with old format settings
String oldFormatEncoderSettingString = height1+"," + videoBitrate1 + "," + audioBitrate1
+ "," + height2 +"," + videoBitrate2 + "," + audioBitrate2
Expand All @@ -194,7 +231,14 @@ public void testEncodeSettings() {
assertEquals(240, list.get(2).getHeight());
assertEquals(300000, list.get(2).getVideoBitrate());
assertEquals(32000, list.get(2).getAudioBitrate());


//There are no setting for encoder options in old format so make it null
profile1 = null;
tune1 = null;
preset1 = null;
newFormatEncoderSettingString ="[{\"videoBitrate\":"+videoBitrate1+",\"forceEncode\":"+forceEncode1+",\"profile\":"+profile1+",\"preset\":"+preset1+",\"audioBitrate\":"+audioBitrate1+",\"tune\":"+tune1+",\"height\":"+height1+"},{\"videoBitrate\":"+videoBitrate2+",\"forceEncode\":"+forceEncode2+",\"profile\":"+profile1+",\"preset\":"+preset1+",\"audioBitrate\":"+audioBitrate2+",\"tune\":"+tune1+",\"height\":"+height2+"},{\"videoBitrate\":"+videoBitrate3+",\"forceEncode\":"+forceEncode3+",\"profile\":"+profile1+",\"preset\":"+preset1+",\"audioBitrate\":"+audioBitrate3+",\"tune\":"+tune1+",\"height\":"+height3+"}]";


//It will convert new json format
list.get(0).setForceEncode(false);
list.get(1).setForceEncode(true);
Expand Down