Qu’est-ce que le HDR et pourquoi est-ce important
La technologie de streaming s’est considérablement améliorée, donnant lieu à des résolutions vidéo de plus en plus élevées, allant de celles à 480p ou moins (connues sous le nom de définition standard ou SD en abrégé) à celles à 720p ou au-dessus (haute définition ou HD en abrégé).
La résolution vidéo est vitale pour toutes les applications. Les recherches que j’ai récemment rencontrées le confirment : 62 % des personnes sont plus susceptibles de percevoir négativement une marque qui offre une expérience vidéo de mauvaise qualité, tandis que 57 % des personnes sont moins susceptibles de partager une vidéo de mauvaise qualité. Dans cet esprit, il n’est pas étonnant qu’il existe tant de solutions émergentes pour améliorer la résolution vidéo.
Une solution est HDR – plage dynamique élevée. Il s’agit d’une méthode de post-traitement utilisée en imagerie et en photographie, qui imite ce qu’un œil humain peut voir en donnant plus de détails aux zones sombres et en améliorant le contraste. Lorsqu’il est utilisé dans un lecteur vidéo, le HDR peut fournir des vidéos plus riches avec une résolution plus élevée.
De nombreuses solutions HDR, cependant, sont déçues par des restrictions gênantes. Ceux-ci peuvent inclure un manque de spécifications techniques unifiées, un niveau élevé de difficulté à les mettre en œuvre et une exigence de vidéos en ultra-haute définition. J’ai essayé de chercher une solution sans de telles restrictions et heureusement, j’en ai trouvé une. C’est le SDK HDR Vivid de HMS Core Video Kit. Cette solution est dotée de fonctionnalités de traitement d’image telles que la fonction de transfert optoélectronique (OETF), le mappage des tons et le HDR2SDR. Grâce à ces fonctionnalités, le SDK peut équiper un lecteur vidéo de couleurs plus riches, d’un niveau de détail plus élevé, etc.
J’ai utilisé le SDK avec le SDK HDR Ability (qui peut également être utilisé indépendamment) pour essayer la fonction de réglage de la luminosité de ce dernier et j’ai découvert qu’ils pouvaient offrir une expérience de lecture vidéo HDR encore meilleure. Et sur cette note, j’aimerais partager comment j’ai utilisé ces deux SDK pour créer un lecteur vidéo.
Avant le développement
1. Configurez les informations de l’application selon vos besoins dans AppGallery Connect.
2. Intégrez le SDK HMS Core.
Pour Android Studio, le SDK peut être intégré via le référentiel Maven. Avant la procédure de développement, le SDK doit être intégré au projet Android Studio.
3. Configurez les scripts d’obscurcissement.
4. Ajoutez des autorisations, y compris celles permettant d’accéder à Internet, d’obtenir l’état du réseau, d’accéder au réseau Wi-Fi, d’écrire des données dans le stockage externe, de lire des données à partir du stockage externe, de lire des informations sur l’appareil, de vérifier si un appareil est rooté et obtenir le wakelock. (Les trois dernières autorisations sont facultatives.)
Développement d’applications
Les préparatifs
1. Vérifiez si l’appareil est capable de décoder une vidéo HDR Vivid. Si l’appareil a une telle capacité, la fonction suivante renverra vrai.
public boolean isSupportDecode() {
// Check whether the device supports MediaCodec.
MediaCodecList mcList = new MediaCodecList(MediaCodecList.ALL_CODECS);
MediaCodecInfo[] mcInfos = mcList.getCodecInfos();
for (MediaCodecInfo mci : mcInfos) {
// Filter out the encoder.
if (mci.isEncoder()) {
continue;
}
String[] types = mci.getSupportedTypes();
String typesArr = Arrays.toString(types);
// Filter out the non-HEVC decoder.
if (!typesArr.contains("hevc")) {
continue;
}
for (String type : types) {
// Check whether 10-bit HEVC decoding is supported.
MediaCodecInfo.CodecCapabilities codecCapabilities = mci.getCapabilitiesForType(type);
for (MediaCodecInfo.CodecProfileLevel codecProfileLevel : codecCapabilities.profileLevels) {
if (codecProfileLevel.profile == HEVCProfileMain10
|| codecProfileLevel.profile == HEVCProfileMain10HDR10
|| codecProfileLevel.profile == HEVCProfileMain10HDR10Plus) {
// true means supported.
return true;
}
}
}
}
// false means unsupported.
return false;
}
2. Analysez une vidéo pour obtenir des informations sur sa résolution, son OETF, son espace colorimétrique et son format de couleur. Enregistrez ensuite les informations dans une variable personnalisée. Dans l’exemple ci-dessous, la variable est nommée comme Infos vidéo.
public class VideoInfo {
private int width;
private int height;
private int tf;
private int colorSpace;
private int colorFormat;
private long durationUs;
}
3. Créez un SurfaceView objet qui sera utilisé par le SDK pour traiter les images rendues.
// surface_view is defined in a layout file.
SurfaceView surfaceView = (SurfaceView) view.findViewById(R.id.surface_view);
4. Créez un fil pour analyser les flux vidéo d’une vidéo.
Rendu et transcodage d’une vidéo
1. Créez puis initialisez une instance de HdrVifRendu.
HdrVividRender hdrVividRender = new HdrVividRender();
hdrVividRender.init();
2. Configurez l’OETF et la résolution de la source vidéo.
// Configure the OETF.
hdrVividRender.setTransFunc(2);
// Configure the resolution.
hdrVividRender.setInputVideoSize(3840, 2160);
Lorsque le SDK est utilisé sur un appareil Android, seul le mode de rendu pour l’entrée est pris en charge.
3. Configurez la luminosité de la sortie. Cette étape est facultative.
hdrVividRender.setBrightness(700);
4. Créez un Surface objet, qui servira d’entrée. Cette méthode est appelée lorsque HdrVifRendu fonctionne en mode de rendu, et le créé Surface l’objet est passé en tant que surface d’entrée paramètre de configurer au SDK.
Surface inputSurface = hdrVividRender.createInputSurface();
5. Configurez les paramètres de sortie.
- Définir les dimensions du rendu Surface objet. Cette étape est nécessaire dans le mode de rendu pour la sortie.
// surfaceView is the video playback window.
hdrVividRender.setOutputSurfaceSize(surfaceView.getWidth(), surfaceView.getHeight());
- Définissez l’espace colorimétrique pour la vidéo de sortie mise en mémoire tampon, qui peut être définie dans le mode de transcodage pour la sortie. Cette étape est facultative. Cependant, lorsqu’aucun espace colorimétrique n’est défini, BT.709 est utilisé par défaut.
hdrVividRender.setColorSpace(HdrVividRender.COLORSPACE_P3);
- Définissez le format de couleur pour la vidéo de sortie mise en mémoire tampon, qui peut être définie dans le mode de transcodage pour la sortie. Cette étape est facultative. Cependant, lorsqu’aucun format de couleur n’est spécifié, R8G8B8A8 est utilisé par défaut.
hdrVividRender.setColorFormat(HdrVividRender.COLORFORMAT_R8G8B8A8);
6. Lorsque le mode de rendu est utilisé comme mode de sortie, les API suivantes sont requises.
hdrVividRender.configure(inputSurface, new HdrVividRender.InputCallback() {
@Override
public int onGetDynamicMetaData(HdrVividRender hdrVividRender, long pts) {
// Set the static metadata, which needs to be obtained from the video source.
HdrVividRender.StaticMetaData lastStaticMetaData = new HdrVividRender.StaticMetaData();
hdrVividRender.setStaticMetaData(lastStaticMetaData);
// Set the dynamic metadata, which also needs to be obtained from the video source.
ByteBuffer dynamicMetaData = ByteBuffer.allocateDirect(10);
hdrVividRender.setDynamicMetaData(20000, dynamicMetaData);
return 0;
}
}, surfaceView.getHolder().getSurface(), null);
7. Lorsque le mode de transcodage est utilisé comme mode de sortie, appelez les API suivantes.
hdrVividRender.configure(inputSurface, new HdrVividRender.InputCallback() {
@Override
public int onGetDynamicMetaData(HdrVividRender hdrVividRender, long pts) {
// Set the static metadata, which needs to be obtained from the video source.
HdrVividRender.StaticMetaData lastStaticMetaData = new HdrVividRender.StaticMetaData();
hdrVividRender.setStaticMetaData(lastStaticMetaData);
// Set the dynamic metadata, which also needs to be obtained from the video source.
ByteBuffer dynamicMetaData = ByteBuffer.allocateDirect(10);
hdrVividRender.setDynamicMetaData(20000, dynamicMetaData);
return 0;
}
}, null, new HdrVividRender.OutputCallback() {
@Override
public void onOutputBufferAvailable(HdrVividRender hdrVividRender, ByteBuffer byteBuffer,
HdrVividRender.BufferInfo bufferInfo) {
// Process the buffered data.
}
});
nouveau HdrVividRender.OutputCallback() est utilisé pour traiter de manière asynchrone les données renvoyées en mémoire tampon. Si cette méthode n’est pas utilisée, le lis méthode peut être utilisée à la place. Par exemple:
hdrVividRender.read(new BufferInfo(), 10); // 10 is a timestamp, which is determined by your app.
8. Démarrez le flux de traitement.
9. Arrêtez le flux de traitement.
10. Libérez les ressources qui ont été occupées.
hdrVividRender.release();
hdrVividRender = null;
Au cours des étapes ci-dessus, j’ai remarqué que lorsque les dimensions de Surface monnaie, setOutputSurfaceSize doit être appelé pour reconfigurer les dimensions du Surface production.
De plus, dans le mode de rendu pour la sortie, lorsque WisePlayer passe de l’arrière-plan au premier plan ou vice versa, le Surface l’objet sera détruit puis recréé. Dans ce cas, il est possible que le HdrVifRendu l’instance n’est pas détruite. Si oui, le setOutputSurface L’API doit être appelée pour qu’un nouveau Surface sortie peut être réglée.
Configuration des capacités HDR
Les capacités HDR sont fournies dans la classe HdrCapacité. Il peut être utilisé pour régler la luminosité lorsque le SDK HDR Vivid rend ou transcode une vidéo HDR Vivid.
1. Initialisez la fonction de réglage de la luminosité.
HdrAbility.init(getApplicationContext());
2. Activez la fonction HDR sur le…