Anwendbarkeit auf ArmSoM und Quelle
Dies ist eine Rockchip-Plattformreferenz, kein ArmSoM-Testbericht. Quelle ist das MPP-Entwicklerhandbuch V1.4.2 mit 53 chinesischen und 57 englischen Seiten. Chinesisch folgt dem chinesischen Original; Englisch dem englischen Original, das vollständig ins Russische und Deutsche übersetzt wurde. Chinesisch verwendet chinesische Originalabbildungen; Englisch, Russisch und Deutsch verwenden englische Originalabbildungen. Die SoC-Liste, Android/Linux-Umgebungen und Funktionen der Quelle bleiben nachfolgend erhalten. Für konkrete ArmSoM-Boards wird jedoch keine Kombination aus SDK/BSP und Kernel festgelegt. Codec-Hardware, Kerneltreiber, MPP-Version, Formatunterstützung und Build-Umgebung sind zu prüfen. Sämtliche Protokolle, Geschwindigkeiten, Bildraten und Speicherwerte sind Quellbeispiele; weder Code noch Hardwaretests wurden ausgeführt.
Redaktioneller Hinweis: Dies sind beibehaltene Quellbeispiele, keine geprüfte, unmittelbar ausführbare Korrekturfassung. Die Quelle enthält widersprüchliche Plattform-/Formatlisten, verdächtige Zeichen in Aufzählungen und fragliche Parameterbeschreibungen. Vor dem Kopieren von Befehlen oder Konfigurationen die redaktionellen Hinweise und das tatsächliche SDK prüfen.
EDITORIAL-NOTES · ArmSoM Documentation
1. Einführung in MPP
1.1 Übersicht
Die Media Process Platform (MPP) von Rockchip ist eine allgemeine Medienverarbeitungsplattform für Rockchip-Chips. Sie verbirgt die komplexe chipspezifische Verarbeitung auf niedriger Ebene vor Anwendungen, gleicht Unterschiede zwischen Chips aus und bietet eine einheitliche Media Process Interface (MPI). MPP stellt folgende Funktionen bereit:
Videodekodierung
H.265/H.264/H.263/AV1/VP9/VP8/AVS2/AVS/AVS+ /MPEG-4/MPEG-2/MPEG-1/VC1/MJPEG
Videokodierung
H.265/H.264/VP8/MJPEG
Videoverarbeitung
Kopieren und Skalieren von Video, Farbraumkonvertierung und Deinterlacing
1.2 Systemarchitektur
Die Einordnung der MPP-Plattform in die Systemarchitektur zeigt die folgende Abbildung:

Abbildung 1: MPP-Systemarchitektur
Hardwareebene
Die Hardwareebene umfasst Rockchip-Beschleuniger für Videokodierung und -dekodierung, darunter vdpu, vepu, rkvdec, rkvenc und weitere Hardwareblöcke mit unterschiedlichen Funktionen.
Kerneltreiberebene
Der Linux-Kerneltreiber der Codec-Hardware umfasst den Gerätetreiber sowie zugehörige MMU-, Speicher-, Takt- und Energieverwaltungsmodule. Hauptsächlich unterstützt werden die Linux-Kernelversionen 3.10, 4.4, 4.19, 5.10 und 6.1. Die MPP-Bibliotheken hängen von den Kerneltreibern ab.
MPP-Ebene
MPP im Benutzerraum verbirgt Unterschiede zwischen Betriebssystemen und Chipplattformen und stellt der darüberliegenden Anwendung eine einheitliche MPI bereit. Die MPP-Ebene umfasst MPI, OSAL, HAL, Video Decoder / Video Encoder und Video Processing.
Betriebssystemebene
Ausführungsplattformen von MPP im Benutzerraum sind Android und Linux-Distributionen wie Debian.
Anwendungsebene
Über MPI lässt sich MPP an Middleware wie OpenMax, ffmpeg und gstreamer anbinden oder direkt von der übergeordneten Benutzeranwendung aufrufen.
1.3 Unterstützte Plattformen
1.3.1 Softwareplattformen
MPP unterstützt unterschiedliche Android-Versionen und reine Linux-Plattformen.
Unterstützt werden die Rockchip-Linux-Kernel 3.10, 4.4, 4.19 und 5.10; Voraussetzung sind der Gerätetreiber vcodec_service und die passende DTS-Konfiguration.
1.3.2 Hardwareplattformen
Unterstützt werden folgende verbreitete Rockchip-Chipfamilien:
Familien RK3288, RK3368, RK3399, RK3588
Familien RK30xx, RK312x, RK322x, RK332x
Familien RV1109/RV1126 (Hinweis: Die Unterstützung für RV1107/RV1108 wird schrittweise eingestellt)
1.4 Unterstützte Funktionen
Die Kodier- und Dekodierfunktionen von MPP unterscheiden sich je nach Chipplattform erheblich. Siehe dazu den Multimedia Benchmark des jeweiligen Chips.
1.5 Hinweise
Für einen schnellen Einstieg in MPP und die Beispiele siehe Kapitel 4 mit den MPP-Demoprogrammen.
Für einen schnellen Einstieg in Kompilierung und Nutzung von MPP siehe Kapitel 5. Einzelheiten zum Aufbau und zu den Entwurfsprinzipien stehen in readme.txt im MPP-Quellverzeichnis, den Textdokumenten unter doc und den Kommentaren der Headerdateien.
2. Schnittstellenentwurf
Dieses Kapitel beschreibt die unmittelbar für MPP-Anwender sichtbaren Datenstrukturen und ihre Verwendung.
Videokodierung, -dekodierung und -verarbeitung erfordern umfangreichen Austausch von Bitstrom-, Bild- und Speicherdaten sowie die Zusammenarbeit zwischen Anwendung und Kerneltreiber. Deshalb stellt MPP die MPI für den übergeordneten Anwendungsteil bereit. Dieses Kapitel erläutert ihre Datenstrukturen und Entwurfsprinzipien.
2.1 Übersicht der Schnittstellenstrukturen
Die folgende Abbildung zeigt die wichtigsten Datenstrukturen der MPI:

Abbildung 2: Datenstrukturen der MPI
MppMem kapselt mit malloc aus der C-Bibliothek zugewiesenen Speicher.
MppBuffer kapselt dmabuf-Speicher für die Hardware.
MppPacket kapselt einen eindimensionalen Puffer, der aus MppMem und MapBuffer erzeugt werden kann. Er dient hauptsächlich zur Darstellung von Bitstromdaten. Die Bezeichnung MapBuffer stammt aus der Vorlage.
MppFrame kapselt zweidimensionale Bilddaten, die aus MppMem und MapBuffer erzeugt werden können, und dient hauptsächlich zur Bilddarstellung. Die Bezeichnung MapBuffer stammt aus der Vorlage.
Mit MppPacket und MapFrame lässt sich allgemeine Videokodierung und -dekodierung einfach und effizient umsetzen (MapFrame ist die Schreibweise der Vorlage).
Beim Dekodieren werden beispielsweise Adresse und Größe des Eingangsbitstroms an MppPacket übergeben. Die Eingabe erfolgt über put_packet; am Ausgang wird das Bild als MppFrame über get_frame abgeholt. Dies bildet den einfachsten Videodekodierablauf.

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
Input thread:
Allocate input stream memory;
Initialize MppPacket pkt;
While (!EOF) {
Read file to pkt;
Setup pkt valid length;
Setup pkt EOS flag;
RESEND_PKT:
ret = decode_put_packet(pkt);
IF (ret == NOT_OK)
Wait and goto RESEND_PKT;
}
Deinitialize pkt;
Release input stream memory;
Output thread:
MppFrame frm;
While (!EOS) {
ret = decode_get_frame(&frm);
IF (ret == OK && frm != NULL) {
Write frm to file or display frm;
Read EOS flag from frm;
Release frm;
}
}
Abbildung 3: Videodekodierung über die einfache Schnittstelle
MppMeta und MPTask sind erweiterte kombinierte Schnittstellen für Ein-/Ausgabeaufgaben und komplexe Anwendungsfälle, etwa vorgegebene Ein- und Ausgabemodi. Sie werden nur gelegentlich benötigt.
Hinweis: Für Erweiterbarkeit und Vorwärtskompatibilität werden die genannten Schnittstellenstrukturen über void*handle referenziert. Der Zugriff auf ihre Mitglieder erfolgt über Schnittstellen wie mpp_xxx_set/get_xxx.
2.2 Speicherstruktur MppBuffer
MppBuffer beschreibt Speicherblöcke für die Hardware und bietet Speicherzuweisung und -freigabe sowie Erhöhen und Verringern des Referenzzählers. Unterstützt werden ion/drm-Allokatoren. Wichtige Parameter:
| Parametername | Parametertyp | Beschreibung |
|---|---|---|
| ptr | void * | Virtuelle Adresse des Speicherblocks. |
| size | size_t | Größe des Speicherblocks. |
| fd | int | Dateideskriptor des Speicherblocks im Benutzerraum. |
Beim Dekodieren werden Bildpuffer üblicherweise in einem festen Pufferpool wiederverwendet. Dafür definiert MPP MppBufferGroup auf Grundlage von MppBuffer. Es gibt die folgenden zwei Verwendungsarten:

Abbildung 4: Normale Verwendung von MppBuffer
Pseudocode des Ablaufs:

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
MppBuffer normal usage
MppBufferGroup group = NULL;
// Acquire buffer pool and limit buffer size and buffer count
mpp_buffer_group_get_internal(&group, type);
mpp_buffer_group_limit_config(group, size, count);
// Configure buffer pool to decoder, let decoder get buffer from
// buffer pool to decode.
mpi->control(dec, MPP_DEC_SET_EXT_BUF_GROUP, group);
// Start decoding process
while (!end_of_decoding) {
{ // MPP decoder behave is within brackets.
// MPP decoder uses buffer data.
MppBuffer buffer_in_mpp_decoder;
// Decoder get buffer from buffer pool internally.
mpp_buffer_get(group, &buffer_in_mpp_decoder);
// Decode image data to buffer.
...
}
mpi->decode_get_frame(&frame);
// Output MppBuffer to external user
MppBuffer buffer_of_user = mpp_frame_get_buffer(frame);
// Process to image pixel data
......
// User release reference of MppBuffer and MppFrame
mpp_buffer_put(buffer_of_user);
mpp_frame_deinit(frame);
}
// Release buffer pool
mpp_buffer_group_put(group);
Dieses Verfahren ermöglicht eine Zero-Copy-Ausgabe des Dekoders: Der ausgegebene Frame entspricht dem intern verwendeten Referenzframe. Eine Zero-Copy-Anzeige ist jedoch schwieriger, da der ausgegebene Frame eventuell nicht direkt angezeigt werden kann. Außerdem muss der Anwender den Speicherbedarf des Dekoders kennen.
Eine weitere Möglichkeit besteht darin, MppBufferGroup ausschließlich als Verwaltung für extern importierte Puffer zu verwenden. Der Ablauf ist nachfolgend dargestellt:

Abbildung 5: Externer Import mit MppBuffer
Der Pseudocode des Ablaufs folgt:

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
MppBuffer usage of import external buffer (Zero-copy display)
MppBufferGroup group = NULL;
MppBufferInfo info[16];
// Acquire the buffer pool.
mpp_buffer_group_get_external(&group, type);
// import extern buffer to the buffer pool
mpp_buffer_commit(group, &info[0]);
mpp_buffer_commit(group, &info[1]);
...
...
// Configure buffer pool to decoder let decoder get buffer to
// decode from buffer pool
mpi->control(dec, MPP_DEC_SET_EXT_BUF_GROUP, group);
// Start decoding procedural.
while (!end_of_decoding) {
{ // MPP decoder behave is within brackets.
// MPP decoder uses buffer data.
MppBuffer buffer_in_mpp_decoder;
// Decoder get buffer from buffer pool internally.
mpp_buffer_get(group, &buffer_in_mpp_decoder);
// Decode image data to buffer.
...
}
mpi->decode_get_frame(&frame);
// Output MppBuffer to external user
MppBuffer buffer_of_user = mpp_frame_get_buffer(frame);
// Process to image pixel data
......
// User release reference of MppBuffer and MppFrame
mpp_buffer_put(buffer_of_user);
mpp_frame_deinit(frame);
}
// Release buffer pool
mpp_buffer_group_put(group);
Dieser Ablauf ermöglicht externe Dekoderpuffer, die Anbindung an OpenMax/ffmpeg/gstreamer und die einfache Integration in Benutzeranwendungen. Auch eine Zero-Copy-Anzeige lässt sich damit leichter umsetzen.
2.3 Bitstromstruktur MppPacket
MppPacket beschreibt eindimensionale Bitstromdaten, insbesondere Position und Länge der gültigen Daten. Wichtige Parameter sind nachfolgend aufgeführt:
| Parametername | Parametertyp | Beschreibung |
|---|---|---|
| data | void * | Anfangsadresse des Pufferbereichs. |
| size | size_t | Größe des Pufferbereichs. |
| pos | void * | Anfangsadresse gültiger Daten im Pufferbereich. |
| length | size_t | Länge gültiger Daten im Pufferbereich. Wird die Länge nach dem Aufruf von decode_put_packet zu 0, wurde der Paketdatenstrom verbraucht. |
Der Zusammenhang der Parameter ist nachfolgend dargestellt:

Abbildung 6: Wichtige Parameter von MppPacket
Weitere Konfigurationsparameter von MppPacket:
| Parametername | Parametertyp | Beschreibung |
|---|---|---|
| pts | RK_U64 | Zeitstempel der Darstellung (Present Time Stamp). |
| dts | RK_U64 | Zeitstempel der Dekodierung (Decoding Time Stamp). |
| eos | RK_U32 | Kennzeichen für das Datenstromende (End Of Stream). |
| buffer | MppBuffer | Mit MppPacket verknüpfter MppBuffer. |
| flag | RK_U32 | Intern in MPP verwendete Flag-Bits, einschließlich: #define MPP_PACKET_FLAG_EOS (0x00000001) #define MPP_PACKET_FLAG_EXTRA_DATA (0x00000002) #define MPP_PACKET_FLAG_INTERNAL (0x00000004) #define MPP_PACKET_FLAG_INTRA (0x00000008) |
MppPacket beschreibt eindimensionalen Speicher und muss mit bereits zugewiesenem Speicher oder MppBuffer-Speicher initialisiert werden. Bei der Freigabe sind folgende Fälle zu unterscheiden:
Wird MppPacket mit einer externen malloc-Adresse konfiguriert, wird dieser Speicher nicht freigegeben. Beispiel:

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
void *data = malloc(size);
MppPacket pkt = NULL;
mpp_packet_init(&pkt, data, size);
mpp_packet_deinit(&pkt); // <<-- NOT release data
free(data);
Wird MppPacket durch copy_init erzeugt, wird der während des Kopierens zugewiesene Speicher laut Vorlagentext nach Abschluss des Kopierens freigegeben. Beispiel:

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
void *data = malloc(size);
MppPacket pkt = NULL;
MppPacket pkt_copy = NULL;
mpp_packet_init(&pkt, data, size);
mpp_packet_copy_init(&pkt_copy, pkt);
mpp_packet_deinit(&pkt); // <<-- NOT release data
mpp_packet_deinit(&pkt_copy); // <<-- release allocated memory
free(data);
Wird MppPacket aus MppBuffer erzeugt, erhält MppBuffer beim Erzeugen eine zusätzliche Referenz; beim Freigeben von MppPacket wird diese Referenz entfernt.

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
MppBuffer buffer;
MppPacket pkt = NULL;
mpp_buffer_get(NULL, &buffer, size);
mpp_packet_init_with_buffer(&pkt, buffer); // <<-- Auto increase reference
mpp_packet_deinit(&pkt); // <<-- Auto decrease reference
mpp_buffer_put(buffer);
2.4 Bildstruktur MppFrame
MppFrame beschreibt einen zweidimensionalen Bildpuffer sowie Position und Länge der gültigen Daten. Wichtige Parameter:
| Parametername | Parametertyp | Beschreibung |
|---|---|---|
| width | RK_U32 | Anzahl der Pixel in horizontaler Richtung, in Pixeln. |
| height | RK_U32 | Anzahl der Pixel in vertikaler Richtung, in Pixeln. |
| hor_stride | RK_U32 | Abstand zwischen zwei benachbarten Zeilen in vertikaler Richtung, in Bytes. |
| ver_stride | RK_U32 | Anzahl der Zeilenabstände zwischen Bildkomponenten; Einheit: 1. |

Abbildung 7: Wichtige Parameter von MppFrame
Weitere Konfigurationsparameter von MppFrame:
| Parametername | Parametertyp | Beschreibung |
|---|---|---|
| mode | RK_U32 | Bilddaten-Eigenschaften für Frame/Feld: |
| pts | RK_U64 | Darstellungszeitstempel des Bildes (Present Time Stamp). |
| dts | RK_U64 | Dekodierungszeitstempel des Bildes (Decoding Time Stamp). |
| eos | RK_U32 | Kennzeichen für das Ende des Bilddatenstroms (End Of Stream). |
| errinfo | RK_U32 | Bildfehlerkennzeichen: ob im Bild ein Dekodierungsfehler vorliegt. |
| discard | RK_U32 | Verwerfungskennzeichen des Bildes. Erfüllen die Referenzbeziehungen bei der Bilddekodierung die Anforderungen nicht, wird das Bild zum Verwerfen ohne Anzeige markiert. |
| buf_size | size_t | Größe des für das Bild zu allokierenden Puffers; abhängig vom Bildformat und vom Format der dekodierten Daten. |
| info_change | RK_U32 | Bei einem wahren Wert ist der aktuelle MppFrame eine beschreibende Struktur für Änderungen der Bitstrominformationen: Breite, Höhe, Stride oder Bildformat. Mögliche Ursachen von info_change: 1. Änderung der Breite und Höhe der Bildfolge. 2. Änderung des Bildfolgenformats, etwa von 8 Bit auf 10 Bit. Nach info_change muss der vom Decoder verwendete Speicherpool neu allokiert werden. |

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
/*
* bit definition for mode flag in MppFrame
*/
/* progressive frame */
#define MPP_FRAME_FLAG_FRAME (0x00000000)
/* top field only */
#define MPP_FRAME_FLAG_TOP_FIELD (0x00000001)
/* bottom field only */
#define MPP_FRAME_FLAG_BOT_FIELD (0x00000002)
/* paired field */
#define MPP_FRAME_FLAG_PAIRED_FIELD (MPP_FRAME_FLAG_TOP_FIELD|MPP_FRAME_FLAG_BOT_FIELD)
/* paired field with field order of top first */
#define MPP_FRAME_FLAG_TOP_FIRST (0x00000004)
/* paired field with field order of bottom first */
#define MPP_FRAME_FLAG_BOT_FIRST (0x00000008)
/* paired field with unknown field order (MBAFF) */
#define MPP_FRAME_FLAG_DEINTERLACED (MPP_FRAME_FLAG_TOP_FIRST|MPP_FRAME_FLAG_BOT_FIRST)
#define MPP_FRAME_FLAG_FIELD_ORDER_MASK (0x0000000C)
// for multi-view stream
#define MPP_FRAME_FLAG_VIEW_ID_MASK (0x000000f0)
| Parametername | Parametertyp | Beschreibung |
|---|---|---|
| fmt | MppFrameFormat | Farbraumformat und Speicheranordnung des Bildes: |
| color_range | MppFrameColorRange | Farbraumbereich der Bilddaten: Voller YUV-Bereich: 0 ~ 255 (8 Bit) Begrenzter YUV-Bereich: 16 ~ 235 (8 Bit) |
| buffer | MppBuffer | Dem MppFrame entsprechender MppBuffer. |

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
typedef enum {
MPP_FMT_YUV420SP = MPP_FRAME_FMT_YUV, /* YYYY... UV... (NV12) */
/*
* A rockchip specific pixel format, without gap between pixel against
* the P010_10LE/P010_10BE
*/
MPP_FMT_YUV420SP_10BIT,
MPP_FMT_YUV422SP, /* YYYY... UVUV... (NV24) */
MPP_FMT_YUV422SP_10BIT, ///< Not part of ABI
MPP_FMT_YUV420P, /* YYYY... U...V... (I420) */
MPP_FMT_YUV420SP_VU, /* YYYY... VUVUVU... (NV21) */
MPP_FMT_YUV422P, /* YYYY... UU...VV... (422P) */
MPP_FMT_YUV422SP_VU, /* YYYY... VUVUVU... (NV42) */
MPP_FMT_YUV422_YUYV, /* YUYVYUYV... (YUY2) */
MPP_FMT_YUV422_UYVY, /* UYVYUYVY... (UYVY) */
MPP_FMT_YUV400SP, /* YYYY... */
MPP_FMT_YUV440SP, /* YYYY... UVUV... */
MPP_FMT_YUV411SP, /* YYYY... UV... */
MPP_FMT_YUV444SP, /* YYYY... UVUVUVUV... */
MPP_FMT_YUV_BUTT,
MPP_FMT_RGB565 = MPP_FRAME_FMT_RGB, /* 16-bit RGB */
MPP_FMT_BGR565, /* 16-bit RGB */
MPP_FMT_RGB555, /* 15-bit RGB */
MPP_FMT_BGR555, /* 15-bit RGB */
MPP_FMT_RGB444, /* 12-bit RGB */
MPP_FMT_BGR444, /* 12-bit RGB */
MPP_FMT_RGB888, /* 24-bit RGB */
MPP_FMT_BGR888, /* 24-bit RGB */
MPP_FMT_RGB101010, /* 30-bit RGB */
MPP_FMT_BGR101010, /* 30-bit RGB */
MPP_FMT_ARGB8888, /* 32-bit RGB */
MPP_FMT_ABGR8888, /* 32-bit RGB */
MPP_FMT_RGB_BUTT,
/* similar to I420, but Pixels are grouped in macroblocks of 8x4 size */
MPP_FMT_YUV420_8Z4 = MPP_FRAME_FMT_COMPLEX,
/* The end of these formats have a complex layout */
MPP_FMT_COMPLEX_BUTT,
MPP_FMT_BUTT = MPP_FMT_COMPLEX_BUTT,
} ? end MppFrameFormat ? MppFrameFormat;

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
/*
* MPEG vs JPEG YUV range.
*/
typedef enum {
MPP_FRAME_RANGE_UNSPECIFIED = 0,
MPP_FRAME_RANGE_MPEG = 1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges
MPP_FRAME_RANGE_JPEG = 2, ///< the normal 2^n-1 "JPEG" YUV ranges
MPP_FRAME_RANGE_NB, ///< Not part of ABI
} MppFrameColorRange;
Für den Dekoder ist MppFrame die Ausgabestruktur. Sie übermittelt dem Aufrufer dekodierte Informationen einschließlich Pixeldaten, pts, Fehlerdaten und weiterer Angaben. PTS/DTS und EOS werden vom zugehörigen Eingangs-MppPacket übernommen.
Ändert sich die Auflösung des Eingangsbitstroms, wird info_change in MppFrame gesetzt. Der Anwender erhält ein info_change-Ereignis und muss den Pufferpool anpassen.
2.5 Erweiterte Aufgabenstruktur MppTask
Reichen MppPacket und MppFrame nicht aus, dient MppTask als Datencontainer für komplexere Ein-/Ausgabeanforderungen. MppTask wird zusammen mit poll/dequeuer/enqueue verwendet. Gegenüber einfachen Ablaufschnittstellen wie put_packet/get_frame ist der Ablauf komplexer und weniger effizient; dies ist der Preis für die zusätzlichen Möglichkeiten.

Abbildung 8: Ein- und Ausgabe mit MppTask
MppTask lässt sich durch Schlüsselwerte vom Typ MppMetaKey erweitern. Zusätzliche Datentypen ermöglichen komplexe Anforderungen höherer Ebenen. Auf die Daten der verschiedenen Schlüssel wird über mpp_task_meta_set/get_xxx zugegriffen.

Abbildung 9: Unterstützte Daten- und Schlüsseltypen von MppTask
In der Praxis wird MppTask zunächst über dequeue vom MPP-Eingangsport abgeholt, mit mpp_task_meta_set_xxx befüllt und per enqueue zur Verarbeitung an die MPP-Instanz übergeben. Der Ausgangsport arbeitet entsprechend; zum Auslesen werden jedoch mpp_task_meta_get_xxx statt mpp_task_meta_set_xxx verwendet.
Der praktische Encoderzugriff und die MJPEG-Dekodierung sind derzeit mit MppTask umgesetzt.
2.6 Instanzkontext MppCtx
MppCtx ist das Kontexthandle einer MPP-Instanz als Dekoder oder Encoder. mpp_create erzeugt MppCtx und MppApi; mpp_init initialisiert Kodier-/Dekodiertyp und Format. Anschließend erfolgt der Zugriff über decode_xxx/encode_xx oder poll/dequeuer/enqueue. Am Ende wird die Instanz mit mpp_destroy zerstört.

Abbildung 10: Verwendung von MppCtx
2.7 API-Struktur MppApi (MPI)
MppApi kapselt die API von MPP. Die Videocodec-Funktion wird über die Funktionszeiger dieser nachfolgend dargestellten Struktur genutzt:
| Parametername | Parametertyp | Beschreibung |
|---|---|---|
| size | RK_U32 | Größe der MppApi-Struktur. |
| version | RK_U32 | Version der MppApi-Struktur. |
| decode | Funktionszeiger | MPP_RET (decode)(MppCtx ctx, MppPacket packet, MppFrame frame) Videodekodierschnittstelle mit gleichzeitiger Ein- und Ausgabe; allein verwendet. ctx: Kontext der MPP-Instanz. packet: Eingangsbitstrom. frame: Ausgabebild. Rückgabewert: 0 bedeutet Erfolg, ein Wert ungleich null ist ein Fehlercode. |
| decode_put_packet | Funktionszeiger | MPP_RET (*decode_put_packet)(MppCtx ctx, MppPacket packet) Eingabeschnittstelle der Videodekodierung; zusammen mit decode_get_frame verwendet. ctx: Kontext der MPP-Instanz. packet: Eingangsbitstrom. Rückgabewert: 0 bedeutet Erfolg und Verarbeitung des Datenstroms durch MPP; ein Wert ungleich null bedeutet einen Fehler und einen noch nicht verarbeiteten Datenstrom, der erneut gesendet werden muss. |
| decode_get_frame | Funktionszeiger | MPP_RET (*decode_get_frame)(MppCtx ctx, MppFrame *frame) Ausgabeschnittstelle der Videodekodierung; zusammen mit decode_put_packet verwendet. ctx: Kontext der MPP-Instanz. frame: Ausgabebild. Rückgabewert: 0 bedeutet einen erfolgreichen Ausgabeabruf; es muss geprüft werden, ob der Zeiger frame einen Wert hat. Ein Wert ungleich null ist ein Fehlercode. |
| encode | Funktionszeiger | MPP_RET (encode)(MppCtx ctx, MppFrame frame, MppPacket packet) Videokodierschnittstelle mit gleichzeitiger Ein- und Ausgabe; separat verwendet. ctx: Kontext der MPP-Instanz. frame: Eingabebild. packet: Ausgangsbitstrom. Rückgabewert: 0 bedeutet Erfolg, ein Wert ungleich null ist ein Fehlercode. |
| encode_put_frame | Funktionszeiger | MPP_RET (*encode_put_frame)(MppCtx ctx, MppFrame frame) Eingabeschnittstelle der Videokodierung; zusammen mit encode_get_packet verwendet. ctx: Kontext der MPP-Instanz. frame: Eingabebild. Rückgabewert: 0 bedeutet Erfolg, ein Wert ungleich null ist ein Fehlercode. |
| Parametername | Parametertyp | Beschreibung |
|---|---|---|
| encode_get_packet | Funktionszeiger | MPP_RET (*encode_get_packet)(MppCtx ctx, MppPacket *packet) Ausgabeschnittstelle der Videokodierung; zusammen mit encode_put_frame verwendet. ctx: Kontext der MPP-Instanz. packet: Ausgangsbitstrom. Rückgabewert: 0 bedeutet Erfolg, ein Wert ungleich null ist ein Fehlercode. |
| poll | Funktionszeiger | MPP_RET (*poll)(MppCtx ctx, MppPortType type, MppPollType timeout) Port-Abfrageschnittstelle: prüft, ob Daten zur Entnahme aus der Port-Warteschlange bereitstehen. ctx: Kontext der MPP-Instanz. type: Porttyp, entweder Eingangs- oder Ausgangsport. timeout: Abfragezeitlimit; -1 bedeutet blockierende Abfrage, 0 nicht blockierende Abfrage, ein positiver Wert das Zeitlimit in Millisekunden. Rückgabewert: 0 bedeutet Erfolg und abrufbare Daten; ein Wert ungleich null ist ein Fehlercode. |
| dequeue | Funktionszeiger | MPP_RET (dequeue)(MppCtx ctx, MppPortType type, MppTask task) Die Port-Dequeue-Schnittstelle entnimmt die MppTask-Struktur aus der Port-Warteschlange. ctx: Kontext der MPP-Instanz. type: Porttyp, entweder Eingangs- oder Ausgangsport. task: MppTask. Rückgabewert: 0 bedeutet Erfolg, ein Wert ungleich null ist ein Fehlercode. |
| enqueue | Funktionszeiger | MPP_RET (*enqueue)( MppCtx ctx, MppPortType type, MppTask task) Die Port-Enqueue-Schnittstelle übergibt die MppTask-Struktur an die Port-Warteschlange. ctx: Kontext der MPP-Instanz. type: Porttyp, entweder Eingangs- oder Ausgangsport. task: MppTask. Rückgabewert: 0 bedeutet Erfolg, ein Wert ungleich null ist ein Fehlercode. |
| reset | Funktionszeiger | MPP_RET (*reset)(MppCtx ctx) Die Reset-Schnittstelle setzt den internen Zustand von MppCtx auf einen verfügbaren, initialisierten Zustand zurück. HINWEIS: reset ist eine blockierende synchrone Schnittstelle. ctx: Kontext der MPP-Instanz. Rückgabewert: 0 bedeutet Erfolg, ein Wert ungleich null ist ein Fehlercode. |
| Parametername | Parametertyp | Beschreibung |
|---|---|---|
| control | Funktionszeiger | MPP_RET (*control)(MppCtx ctx, MpiCmd cmd, MppParam param) Steuerschnittstelle für zusätzliche Steueroperationen an MPP-Instanzen. ctx: Kontext der MPP-Instanz. cmd: Mpi-Befehls-ID für unterschiedliche Arten von Steuerbefehlen. param: Mpi-Befehlsparameter als zusätzlicher Parameter des Steuerbefehls. Rückgabewert: 0 bedeutet Erfolg, ein Wert ungleich null ist ein Fehlercode. |
3. Verwendung der MPI
Dieses Kapitel beschreibt den konkreten MPI-Ablauf und wichtige Nutzungshinweise. MPI (Media Process Interface) ist die Benutzerschnittstelle von MPP für Hardwarekodierung, -dekodierung und zugehörige Funktionen. Sie wird über Funktionszeiger in einer C-Struktur bereitgestellt. MppCtx und MppApi ermöglichen die Implementierung von Dekoder und Encoder.

Abbildung 11: Umfang der MPI
In der Abbildung verwalten mpp_create, mpp_init und mpp_destroy den MppCtx. mpp_create liefert außerdem die MppApi-Struktur. Die eigentliche Kodierung und Dekodierung erfolgt über deren Funktionszeiger im rot umrandeten Bereich. Dieser umfasst die Codec-Datenschnittstellen put/get_packet/frame sowie Steuer- und Rücksetzschnittstellen. Nachfolgend werden die Schnittstellen und wichtige Betriebsaspekte erläutert.
3.1 Datenflussschnittstelle des Dekoders
Die Dekoderschnittstelle nimmt Bitströme entgegen und gibt Bilder aus. Sie umfasst decode_put_packet, decode_get_frame und decode in MppApi und stellt die einfachste Dekodierfunktion bereit.
3.1.1 decode_put_packet
| Schnittstellendefinition | MPP_RET decode_put_packet(MppCtx ctx, MppPacket packet) |
|---|---|
| Eingabeparameter | ctx: MPP-Decoderinstanz; packet: einzugebende Bitstromdaten. |
| Rückgabeparameter | Laufzeitfehlercode. |
| Funktion | Ein Datenstrompaket an die MPP-Decoderinstanz ctx übergeben. |
3.1.1.1 Form des Eingangsbitstroms
MPP erhält einen Rohbitstrom ohne Containerinformationen. Es gibt zwei Eingabeformen:
1. Vollständige Frames
Die Daten sind bereits in Frames unterteilt: Jeder an decode_put_packet übergebene MppPacket enthält genau einen vollständigen Frame. MPP kann die Pakete unmittelbar verarbeiten. Dies ist der Standardmodus.
2. Aufgeteilte Frames
Die Daten sind nach Länge aufgeteilt, sodass ein MppPacket nicht zwingend genau einen vollständigen Frame enthält. MPP muss die Framegrenzen intern bestimmen. Dieser Modus wird unterstützt; vor mpp_init muss jedoch need_split über MPP_DEC_SET_PARSER_SPLIT_MODE der control-Schnittstelle gesetzt werden.

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
// NOTE: decoder split mode need to be set before init
RK_U32 need_split = 1;
mpi_cmd = MPP_DEC_SET_PARSER_SPLIT_MODE;
param = &need_split;
ret = mpi->control(ctx, mpi_cmd, param);
if (MPP_OK != ret) {
mpp_err("mpi->control failed\n");
goto MPP_TEST_OUT;
}
Dann werden die über decode_put_packet gelieferten MppPacket intern in einzelne Frames zerlegt und anschließend wie vollständige Frames verarbeitet.
Werden diese beiden Modi verwechselt, entstehen Bitstrom-Dekodierfehler.
Vollständige Frames werden effizienter verarbeitet, erfordern jedoch vor der Eingabe ein Parsen und Aufteilen. Aufgeteilte Frames sind einfacher zuzuführen, beeinträchtigen aber die Effizienz.
mpi_dec_test verwendet standardmäßig aufgeteilte Frames, das Rockchip Android SDK vollständige Frames. Die Auswahl richtet sich nach Anwendung und Plattform.
3.1.1.2 Verbrauch des Eingangsbitstroms
Die gültige Datenlänge eines MppPacket ist length. Wird der Bitstrom durch decode_put_packet erfolgreich übernommen, gibt die Funktion null (MPP_OK) zurück und setzt length auf null. Andernfalls wird ein Fehlercode ungleich null zurückgegeben und length bleibt unverändert.
3.1.1.3 Betriebsart des Funktionsaufrufs
decode_put_packet übergibt den Rohbitstrom an die MPP-Instanz. Kann diese zeitweise keine weiteren Daten annehmen, gibt die nicht blockierende Funktion sofort einen Fehler zurück. Der Anwender sollte den Fehlercode auswerten, kurz warten und die Daten erneut senden, um unnötigen Aufwand zu vermeiden.
3.1.1.4 Maximale Anzahl gepufferter Pakete
Standardmäßig nimmt die Verarbeitungswarteschlange von MPP vier Eingangspakete auf. Bei zu schneller Eingabe wird ein Fehler gemeldet; kurz warten und erneut senden.
3.1.2 decode_get_frame
| Schnittstellendefinition | MPP_RET decode_get_frame(MppCtx ctx, MppFrame *frame) |
|---|---|
| Eingabeparameter | ctx: MPP-Decoderinstanz. frame: Zeiger zum Abruf von MppFrame-Instanzen. |
| Rückgabeparameter | Laufzeitfehlercode. |
| Funktion | Beschreibungsinformationen des dekodierten Frames von der MPP-Decoderinstanz ctx abrufen. |
Das dekodierte Bild wird durch MppFrame beschrieben. Dieselbe Struktur dient als Ausgabekanal für Informationen des MPP-Dekoders, einschließlich Bildfehlern und Parameteränderungen.
Fehlerinformationen des Ausgabebildes
errinfo zeigt an, ob beim Dekodieren des Bildes ein Fehler aufgetreten ist. Ein errInfo ungleich null bedeutet einen Fehler im zugehörigen Bitstrom; das fehlerhafte Bild kann verworfen werden.
Speicherbedarf des dekodierten Bildes
Der Dekoder benötigt Speicher für die Pixel des Ausgabebildes. Der Anwender muss einen ausreichend großen Puffer bereitstellen. MPP berechnet den Bedarf abhängig von Chip und Videoformat und liefert ihn über buf_size in MppFrame. Der Speicher ist entsprechend diesem Wert zuzuweisen.
Änderung der Ausgabebildinformationen (Info change)
Ändern sich Breite, Höhe, Format oder Pixelbittiefe des Bitstroms, meldet dies der Dekoder. Der Anwender muss den verwendeten Speicherpool durch neue Puffer aktualisieren. Das Verfahren ist im Abschnitt über Bildspeicherzuweisung und Benutzerinteraktion beschrieben; die Vorlage verweist dabei auf „3..2“.
3.1.3 decode
decode kombiniert decode_put_packet und decode_get_frame in einem gemeinsamen Aufruf. Der interne Ablauf:
1. Versuchen, ein Ausgabebild abzuholen;
2. Bei erfolgreichem Abholen zurückkehren;
3. Wenn der Bitstrom bereits erfolgreich gesendet wurde, zurückkehren;
4. Eingangsbitstrom senden;
5. Erfolg des Sendens prüfen und zu Schritt 1 zurückkehren.
Aus Anwendersicht versucht decode zuerst, ein dekodiertes Bild abzuholen, und gibt es bevorzugt zurück. Liegt kein Bild vor, wird der Bitstrom gesendet, erneut ein Bild angefordert und der Aufruf beendet.
3.2 Dekoder-Steuerschnittstelle
3.2.1 control
Die Enumeration MpiCmd in rk_mpi_cmd.h definiert die Befehle der control-Schnittstelle. Befehle für Dekoder und Dekodierablauf:

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
MPP_DEC_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_DEC,
MPP_DEC_SET_FRAME_INFO, /* vpu api legacy control for buffer slot dimension init */
MPP_DEC_SET_EXT_BUF_GROUP, /* IMPORTANT: set external buffer group to mpp decoder */
MPP_DEC_SET_INFO_CHANGE_READY,
MPP_DEC_SET_PRESENT_TIME_ORDER, /* use input time order for output */
MPP_DEC_SET_PARSER_SPLIT_MODE, /* Need to setup before init */
MPP_DEC_SET_PARSER_FAST_MODE, /* Need to setup before init */
MPP_DEC_GET_STREAM_COUNT,
MPP_DEC_GET_VPUMEM_USED_COUNT,
MPP_DEC_SET_VC1_EXTRA_DATA,
MPP_DEC_SET_OUTPUT_FORMAT,
MPP_DEC_SET_DISABLE_ERROR, /* When set it will disable sw/hw error (H.264 / H.265) */
MPP_DEC_SET_IMMEDIATE_OUT,
MPP_DEC_CMD_END,
MPP_DEC_SET_FRAME_INFO
Der Befehlsparameter ist MppFrame. Damit werden Standardbreite und -höhe des Dekoders konfiguriert. Der zurückgegebene MppFrame enthält die erforderliche Bildpuffergröße. Üblicher Aufrufzeitpunkt: direkt nach mpp_init und vor decode_put_packet.
MPP_DEC_SET_EXT_BUF_GROUP
Der Parameter MppBufferGroup legt den Pufferpool des Dekoders fest. Der Aufrufzeitpunkt hängt vom Bildspeicher-Zuweisungsmodus ab.
MPP_DEC_SET_INFO_CHANGE_READY
Dieser Befehl hat keinen Parameter. Er signalisiert, dass MppBufferGroup nach Info change neu eingerichtet wurde und der Dekoder fortfahren kann. Der Aufrufzeitpunkt hängt vom Speicherzuweisungsmodus ab.
MPP_DEC_SET_PRESENT_TIME_ORDER
Der Parameter RK_U32* dient zur Behandlung besonderer Bitstrom-Zeitstempelfälle.
MPP_DEC_SET_PARSER_SPLIT_MODE
Der Parameter RK_U32* aktiviert die interne Frameaufteilung durch den MPP-Parser. Standardmäßig werden bereits aufgeteilte vollständige Frames erwartet. Der Befehl wird vor mpp_init aufgerufen.
MPP_DEC_SET_PARSER_FAST_MODE
Der Parameter RK_U32* aktiviert schnelles Frameparsen und erhöht die Parallelität von Dekoderhardware und -software. Da dies die Kennzeichnung fehlerhafter Bitströme beeinflussen kann, ist der Modus standardmäßig deaktiviert. Aufruf vor mpp_init.
MPP_DEC_GET_STREAM_COUT
Parameter RK_U32*. Externe Anwendungen fragen damit die Anzahl noch nicht verarbeiteter Bitstrompakete ab. Historische Altschnittstelle.
MPP_DEC_GET_VPUMEM_USED_COUT
Parameter RK_U32*. Externe Anwendungen fragen die Anzahl der von MPP verwendeten MppBuffer ab. Historische Altschnittstelle.
MPP_DEC_SET_VC1_EXTRA_DATA
Noch nicht implementiert. Historische Altschnittstelle.
MPP_DEC_SET_OUTPUT_FORMAT
Parameter MppFrameFormat. Externe Anwendungen konfigurieren damit das Ausgabebildformat des JPEG-Dekoders. Standardmäßig nicht verwendet.
MPP_DEC_SET_DISABLE_ERROR
Der Parameter RK_U32* deaktiviert die Fehlerbehandlung des MPP-Dekoders. Danach ignoriert dieser Bitstromfehler, gibt alle dekodierbaren Bilder aus und setzt kein errinfo im Ausgabe-MppFrame. Aufruf vor decode_put_packet.
MPP_DEC_SET_IMMEDIATE_OUT
Der Parameter RK_U32* aktiviert die sofortige H.264-Ausgabe. Der Dekoder ignoriert Unterbrechungen der Framefolge durch verworfene Frames oder picture order count und gibt das aktuelle dekodierte Bild sofort aus. Aufruf vor decode_put_packet.
MPP_DEC_SET_ENABLE_FAST_PLAY
Der Parameter FastPlayMode* aktiviert die schnelle H.264-Wiedergabe, ohne vor der Ausgabe auf einen gefüllten dpb zu warten. Wird ein Frame nach dem I-Frame dekodiert, soll aber davor angezeigt werden, können Frames verloren gehen. Aufruf vor decode_put_packet.
3.2.2 reset
reset versetzt den Dekoder in den Zustand nach regulärer Initialisierung zurück.
Nach Übergabe und Verarbeitung des letzten MppPacket mit EOS-Markierung wechselt der Dekoder in den EOS-Zustand und nimmt keine weiteren Bitströme an. Erst nach einem Reset kann ein neuer Bitstrom verarbeitet werden.
3.3 Wichtige Hinweise zur Dekodernutzung
Bei der Dekodernutzung sind folgende Punkte zu beachten:
3.3.1 Ein- und mehrthreadige Dekodernutzung
Die MPI des MPP-Dekoders ist threadsicher und kann in mehreren Threads verwendet werden. mpi_dec_test zeigt den Einthreadmodus, mpi_dec_mt_test den Mehrthreadmodus.


Abbildung 12: Ein- und mehrthreadige Dekodernutzung
3.3.2 Bildspeicherzuweisung und Benutzerinteraktion
Der Dekoder benötigt Speicher zum Schreiben der Pixel. Nach dem Dekodieren wird dieser an den Anwender übergeben und nach dessen Nutzung an den Dekoder zurückgegeben. Beim Schließen des Dekoders wird der gesamte Speicher freigegeben. So ist eine Zero-Copy-Interaktion möglich. MPP unterstützt drei Modi der Speicherzuweisung und Benutzerinteraktion:
3.3.2.1 Modus 1: vollständig interne Speicherzuweisung
Der Bildspeicher wird direkt vom MPP-Decoder zugewiesen. Der Benutzer erhält das Ausgabebild des Decoders und gibt es unmittelbar nach der Verwendung frei.

Abbildung 13: Schema der vollständig internen Speicherzuweisung
In diesem Modus muss der Benutzer den Befehl MPP_DEC_SET_EXT_BUF_GROUP der Decoder-Steuerschnittstelle nicht aufrufen. Wenn der Decoder eine info change meldet, genügt der direkte Aufruf von MPP_DEC_SET_INFO_CHANGE_READY über die Steuerschnittstelle.
Der Decoder weist den Speicher automatisch intern zu; der Benutzer muss die erhaltenen Daten jedes Frames unmittelbar freigeben.

Abbildung 14: Programmablauf bei vollständig interner Zuweisung des Decoder-Bildspeichers
Vorteil:
Das Verfahren ist einfach. Ein Demonstrationsprogramm zur Bewertung der Decoderleistung lässt sich schnell einrichten. Nachteile:
1. Der Speicher wird intern vom Decoder zugewiesen. Wurde er beim Zerstören des Decoders noch nicht freigegeben, kann ein Speicherleck oder Absturz auftreten.
2. Der Speicherverbrauch des Decoders lässt sich nicht steuern; er kann Speicher uneingeschränkt verwenden. Wird der Bitstrom schnell zugeführt und gibt der Benutzer den Speicher dekodierter Bilder nicht rechtzeitig frei, verbraucht der Decoder rasch den gesamten verfügbaren Speicher.
3. Eine Anzeige ohne Kopieren ist schwer umzusetzen, da der Speicher intern vom Decoder zugewiesen wird und möglicherweise nicht mit dem Anzeigesystem des Benutzers kompatibel ist.
3.3.2.2 Modus 2: teilweise interne Speicherzuweisung
Dies ist der Standardmodus des Demonstrationsprogramms mpi_dec_test. Der Benutzer muss anhand von buf_size des von get_frame zurückgegebenen MppFrame eine MppBufferGroup erstellen und sie über MPP_DEC_SET_EXT_BUF_GROUP der Steuerschnittstelle im Decoder konfigurieren. Über mpp_buffer_group_limit_config lässt sich der Speicherverbrauch des Decoders begrenzen.

Abbildung 15: Decoder-Ablauf bei teilweise interner Speicherzuweisung
Vorteil:
Das Verfahren ist einfach und gut zugänglich; der Speicherverbrauch lässt sich in gewissem Umfang begrenzen. Nachteile:
1. Die Begrenzung des Speicherumfangs ist nicht exakt. Die Speicherauslastung ist nicht fest auf 100% eingestellt, sondern schwankt.
2. Auch eine Anzeige ohne Kopieren ist schwer umzusetzen.
3.3.2.3 Modus 3: vollständig externe Speicherzuweisung
In diesem Modus wird eine leere MppBufferGroup im externen Modus erstellt, über die der Decoder die vom Benutzer bereitgestellten Dateihandles des externen Speicherzuweisers, üblicherweise dmabuf/ion/drm, importiert. Unter Android bezieht Mediaserver den Anzeigespeicher über gralloc von SurfaceFlinger, übergibt die von gralloc erhaltenen Dateihandles an MppBufferGroup und konfiguriert die Gruppe im Decoder mit MPP_DEC_SET_EXT_BUF_GROUP über die Steuerschnittstelle. Anschließend verwendet der MPP-Decoder den von gralloc bezogenen Speicher wieder.

Abbildung 16: Schema der vollständig externen Speicherzuweisung

Abbildung 17: Decoder-Ablauf bei vollständig externer Speicherzuweisung
Vorteil:
Durch direkte Verwendung des Speichers des externen Anzeigesystems lässt sich ein Betrieb ohne Kopieren einfach umsetzen. Nachteile:
1. Der Modus ist schwer zu verstehen und anzuwenden.
2. Das Benutzerprogramm muss geändert werden. Der Ablauf mancher Programme schränkt die Verwendung der vollständig externen Speicherzuweisung ein.
Hinweise zur vollständig externen Speicherzuweisung:
1. Wird der Bildspeicherpool vor dem Decoder erstellt, ist ein zusätzlicher Weg zur Ermittlung der Größe des Bildspeichers erforderlich.
Allgemeine Berechnung des Speicherbedarfs eines YUV420-Bildes: Bildpixeldaten — hor_stride * ver_stride * 3 / 2; Zusatzinformationen — hor_stride * ver_stride / 2.
2. Die Anzahl der Speicherblöcke muss sowohl die Anforderungen der Dekodierung als auch der Anzeige berücksichtigen. Im englischen Original steht wörtlich, der Decoder könne bei „genügend“ (enough) Speicherblöcken hängen bleiben. Dieser verdächtige Widerspruch bleibt zur Prüfung kenntlich; eine vermutlich fehlende Verneinung ist keine bestätigte Korrektur.
Für H.264/H.265 mit mehr Referenzframes sind 20+ Speicherblöcke erforderlich, um die Dekodierung sicherzustellen. Andere Protokolle benötigen dafür 10+ Speicherblöcke.
3. Tritt beim Dekodieren des Bitstroms eine info change auf, muss die vorhandene MppBufferGroup zurückgesetzt werden. Neue Bildspeicherpuffer sind zu übergeben und die externe Anzeige entsprechend anzupassen.
3.4 Encoder-Datenflussschnittstelle
Die Encoder-Schnittstelle stellt Funktionen für die Bildeingabe und Bitstromausgabe bereit: encode_put_frame, encode_get_packet und encode in der Struktur MppApi. Diese Funktionen ermöglichen eine einfache Kodierung; die Steuerschnittstelle bietet die Konfiguration des Encoders.
3.4.1 encode_put_frame
| Schnittstellendefinition | MPP_RET encode_put_frame(MppCtx ctx, MppFrame frame) |
|---|---|
| Eingabeparameter | ctx: MPP-Decoderinstanz. ,frame: einzugebende Bilddaten. |
| Rückgabeparameter | Laufzeitfehlercode. |
| Funktion | Bilddaten eines Frames an die durch ctx angegebene MPP-Encoderinstanz übergeben. |
3.4.1.1 Arbeitsweise der Funktion
Das Eingabebild des Encoders ist normalerweise sehr groß; Kopieren würde die Effizienz erheblich verringern. Deshalb muss die Eingabefunktion warten, bis die Encoder-Hardware die Nutzung des Eingabebildspeichers abgeschlossen hat, bevor sie zurückkehren kann. Das verwendete Bild wird an den Aufrufer zurückgegeben. Aus diesen Gründen ist encode_put_frame blockierend: Der Aufruf bleibt bis zum Ende der Nutzung des Eingabebildes blockiert. Dies verhindert bis zu einem gewissen Grad den parallelen Betrieb von Software und Hardware und verringert die Effizienz.
3.4.1.2 Eingabe mit und ohne Kopieren
Der Encoder-Eingang unterstützt keinen von der CPU zugewiesenen Speicher. Soll eine von der CPU zugewiesene Adresse verwendet werden, muss ein MppBuffer zugewiesen und müssen die Daten hineinkopiert werden. Dies beeinträchtigt die Effizienz erheblich. Bevorzugt wird Eingabespeicher in Form von dmabuf/ion/drm, der eine Kodierung ohne Kopieren mit minimalem Zusatzaufwand ermöglicht.
3.4.2 encode_get_packet
| Schnittstellendefinition | MPP_RET encode_get_packet(MppCtx ctx, MppPacket *packet) |
|---|---|
| Eingabeparameter | ctx: MPP-Decoderinstanz. ,packet: Zeiger zum Abruf einer MppPacket-Instanz. |
| Rückgabeparameter | Laufzeitfehlermodus. |
| Funktion | Paketbeschreibungsinformationen der abgeschlossenen Kodierung von der durch ctx angegebenen MPP-Encoderinstanz abrufen. |
3.4.2.1 Headerinformationen und Bilddaten
Am Beispiel des H.264-Encoders bestehen die Ausgabedaten aus zwei Teilen: dem Bitstrom der Headerinformationen (sps/pps) und dem Bilddatenbitstrom (I/P slice). Die Headerinformationen werden über MPP_ENC_GET_EXTRA_INFO der Steuerschnittstelle abgerufen, die Bilddaten über encode_get_packet. Der Headerabruf erfolgt nach Abschluss der Parameterkonfigurationsbefehle SET_RC_CFG/SET_PREP_CFG/SET_CODEC_CFG der Steuerschnittstelle. Beim Aufruf eines Konfigurationsbefehls aktualisiert der Encoder die Parameter. Nach Abschluss der Aktualisierung lassen sich die neuesten Headerinformationen mit folgendem Befehl abrufen:
MPP_ENC_GET_EXTRA_INFO
3.4.2.2 Ausgabeformat des H.264-Encoders
In der beschriebenen Implementierung gibt die Hardware einen Bitstrom mit dem festen Startcode 00 00 00 01 aus; encode_get_packet liefert daher einen Bitstrom mit dem Startcode 00 00 00 01. Soll der Startcode entfernt werden, können die Daten ab der unmittelbar folgenden Adresse kopiert werden.
3.4.2.3 Bitstromdaten ohne Kopieren
Bei Verwendung von encode_put_frame und encode_get_packet lässt sich der Ausgabepuffer nicht konfigurieren; deshalb wird bei encode_get_packet kopiert. Der Ausgabebitstrom des Encoders ist im Allgemeinen gegenüber dem Eingabebild klein, sodass das Kopieren akzeptabel ist. Wird eine Schnittstelle ohne Kopieren benötigt, sind enqueue/dequeue und die Struktur MppTask zu verwenden.
3.4.3 encode
Noch nicht implementiert.
3.5 Encoder-Steuerschnittstelle
Encoder unterscheiden sich von Decodern und erfordern die Konfiguration bestimmter Parameter durch den Benutzer. Vor Beginn der Kodierung muss die Encoder-Konfiguration über die Steuerschnittstelle eingestellt werden.
3.5.1 Steuerung und MppEncCfg
MPP empfiehlt, die Encoder-Konfiguration mit der gekapselten Struktur MppEncCfg über die Befehle MPP_ENC_SET_CFG/MPP_ENC_GET_CFG der Steuerschnittstelle vorzunehmen.
Wegen der konfigurierbaren Optionen und Parameter des Encoders führen feste Strukturen häufig zu Änderungen der Schnittstellenstruktur. Dadurch lässt sich die Binärkompatibilität nicht gewährleisten; die Versionsverwaltung wird komplizierter und der Wartungsaufwand steigt erheblich.
Zur Entschärfung dieses Problems verwendet MppEncCfg den Typ (void *) und eine Schlüsselzuordnung im Format <string-value>. Die Funktionsschnittstellen sind nach s32/u32/s64/u64/ptr/st unterteilt; die zugehörigen Funktionen bilden zwei Gruppen, set und get, wie nachfolgend gezeigt:
MPP_RET mpp_enc_cfg_set_s32(MppEncCfg cfg, const char *name, RK_S32 val);
MPP_RET mpp_enc_cfg_set_u32(MppEncCfg cfg, const char *name, RK_U32 val);
MPP_RET mpp_enc_cfg_set_s64(MppEncCfg cfg, const char *name, RK_S64 val);
MPP_RET mpp_enc_cfg_set_u64(MppEncCfg cfg, const char *name, RK_U64 val);
MPP_RET mpp_enc_cfg_set_ptr(MppEncCfg cfg, const char *name, void *val);
MPP_RET mpp_enc_cfg_set_st(MppEncCfg cfg, const char *name, void *val);
MPP_RET mpp_enc_cfg_get_s32(MppEncCfg cfg, const char *name, RK_S32 *val);
MPP_RET mpp_enc_cfg_get_u32(MppEncCfg cfg, const char *name, RK_U32 *val);
MPP_RET mpp_enc_cfg_get_s64(MppEncCfg cfg, const char *name, RK_S64 *val);
MPP_RET mpp_enc_cfg_get_u64(MppEncCfg cfg, const char *name, RK_U64 *val);
MPP_RET mpp_enc_cfg_get_ptr(MppEncCfg cfg, const char *name, void **val);
MPP_RET mpp_enc_cfg_get_st(MppEncCfg cfg, const char *name, void *val);
Die Zeichenfolge wird üblicherweise als [type:parameter] definiert. Die unterstützten Zeichenfolgen und Parametertypen sind nachfolgend aufgeführt:
| Parameterzeichenkette | Schnittstelle | Tatsächlicher Typ | Beschreibung |
|---|---|---|---|
| rc:mode | S32 | MppEncRcMode | Modus der Bitratensteuerung; derzeit werden CBR und VBR unterstützt: CBR bedeutet Constant Bit Rate, also konstante Bitrate. In diesem Modus ist die Zielbitrate ausschlaggebend. VBR bedeutet Variable Bit Rate, also variable Bitrate. Hier sind die maximale und minimale Bitrate ausschlaggebend. FIX_QP ist ein Modus mit festem QP für Debugging und Leistungsbewertung. |
| rc:bps_target | S32 | RK_S32 | Zielbitrate im CBR-Modus. |
| rc:bps_max | S32 | RK_S32 | Höchste Bitrate im VBR-Modus. |
| rc:bps_min | S32 | RK_S32 | Niedrigste Bitrate im VBR-Modus. |
| rc:fps_in_flex | S32 | RK_S32 | Kennzeichen für eine variable Eingangsbildrate, standardmäßig 0. 0: feste Eingangsbildrate, berechnet als fps_in_num/fps_in_denom; damit sind gebrochene Bildraten darstellbar. 1: variable Eingangsbildrate; die Bildrate ist nicht fest, und die zugehörige Bitratenberechnung und -zuteilung richtet sich nach der tatsächlichen Zeit. |
| rc:fps_in_flex | S32 | RK_S32 | Kennzeichen für eine variable Eingangsbildrate, standardmäßig 0. 0: feste Eingangsbildrate, berechnet als fps_in_num/fps_in_denom; damit sind gebrochene Bildraten darstellbar. 1: variable Eingangsbildrate; die Bildrate ist nicht fest, und die zugehörige Bitratenberechnung und -zuteilung richtet sich nach der tatsächlichen Zeit. |
| rc:fps_in_num | S32 | RK_S32 | Zähler des gebrochenen Werts der Eingangsbildrate; beispielsweise bedeutet 0 die standardmäßigen 30fps. |
| rc:fps_in_denom | S32 | RK_S32 | Nenner des gebrochenen Werts der Eingangsbildrate. Bei 0 wird 1 verwendet. |

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
typedef enum MppEncRcMode_e {
MPP_ENC_RC_MODE_VBR,
MPP_ENC_RC_MODE_CBR,
MPP_ENC_RC_MODE_FIXQP,
MPP_ENC_RC_MODE_AVBR,
MPP_ENC_RC_MODE_BUTT
} MppEncRcMode;
| Parameterzeichenkette | Schnittstelle | Tatsächlicher Typ | Beschreibung |
|---|---|---|---|
| rc:fps_out_flex | S32 | RK_S32 | Kennzeichen für eine variable Ausgangsbildrate, standardmäßig 0. 0: feste Ausgangsbildrate, berechnet als fps_out_num/fps_out_denom; damit sind gebrochene Bildraten darstellbar. 1: variable Ausgangsbildrate; die Bildrate ist nicht fest, und der zugehörige Ausgabezeitpunkt des Bitstroms wird anhand der tatsächlichen Zeit berechnet. |
| rc:fps_out_num | S32 | RK_S32 | Zähler des gebrochenen Werts der Ausgangsbildrate; beispielsweise bedeutet 0 die standardmäßigen 30fps. |
| rc:fps_out_denom | S32 | RK_S32 | Nenner des gebrochenen Werts der Ausgangsbildrate. Bei 0 wird 1 verwendet. |
| rc:gop | RK_S32 | Group Of Picture, also der Abstand zwischen zwei I-Frames: 0 — nur ein I-Frame, alle übrigen Frames sind P-Frames. 1 — ausschließlich I-Frames. 2 — Folge I P I P I P… 3 — Folge I P P I P P I P P… Üblicherweise wird gop als ganzzahliges Vielfaches der Eingangsbildrate gewählt. |
|
| rc:max_reenc_times | U32 | RK_U32 | Maximale Anzahl erneuter Kodierungen eines Bildes. |
| prep:width | S32 | RK_S32 | Anzahl horizontaler Pixel des Eingabebildes, in Pixeln. |
| prep:height | S32 | RK_S32 | Anzahl vertikaler Pixel des Eingabebildes, in Pixeln. |
| prep:hor_stride | S32 | RK_S32 | Abstand zwischen zwei benachbarten Zeilen des Eingabebildes in vertikaler Richtung, in Bytes. |
| prep:ver_stride | S32 | RK_S32 | Anzahl der Zeilen zwischen Komponenten des Eingabebildes; Einheit: 1. |
| Parameterzeichenkette | Schnittstelle | Tatsächlicher Typ | Beschreibung |
|---|---|---|---|
| prep:format | S32 | MppFrameFormat | Farbraumformat und Speicherlayout des Eingabebildes. |
| prep:color | S32 | MppFrameColorSpace | Farbraumbereich der Eingabebilddaten. |
| prep:range | S32 | MppFrameColorRange | Ob das Eingabebild den vollen oder den begrenzten Wertebereich verwendet. |
| prep:rotation | S32 | MppEncRotationCfg | Rotationseigenschaft des Eingabebildes; Standardwert 0 bedeutet keine Rotation. |
| prep:mirroring | S32 | RK_S32 | Spiegelungseigenschaft des Eingabebildes; standardmäßig keine Spiegelung. |

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
typedef enum {
MPP_FMT_YUV420SP = (MPP_FRAME_FMT_YUV + 0), /* YYYY... UV... (NV12) */
/*
* A rockchip specific pixel format, without gap between pixel against
* the P010_10LE/P010_10BE
*/
MPP_FMT_YUV420SP_10BIT = (MPP_FRAME_FMT_YUV + 1),
MPP_FMT_YUV422SP = (MPP_FRAME_FMT_YUV + 2), /* YYYY... UVUV... (NV16) */
MPP_FMT_YUV422SP_10BIT = (MPP_FRAME_FMT_YUV + 3), ///< Not part of ABI
MPP_FMT_YUV420P = (MPP_FRAME_FMT_YUV + 4), /* YYYY... U...V... (I420) */
MPP_FMT_YUV420SP_VU = (MPP_FRAME_FMT_YUV + 5), /* YYYY... VUVUVU... (NV21) */
MPP_FMT_YUV422P = (MPP_FRAME_FMT_YUV + 6), /* YYYY... UUU...VVV... (422P) */
MPP_FMT_YUV422SP_VU = (MPP_FRAME_FMT_YUV + 7), /* YYYY... VUVUVU... (NV61) */
MPP_FMT_YUV422_YUYV = (MPP_FRAME_FMT_YUV + 8), /* YUYVYUYV... (YUY2) */
MPP_FMT_YUV422_UYVY = (MPP_FRAME_FMT_YUV + 9), /* UYVYUYVY... (UYVY) */
MPP_FMT_YUV422_YVYU = (MPP_FRAME_FMT_YUV + 10), /* YVYUYVYU... (YVYU) */
MPP_FMT_YUV422_VYUY = (MPP_FRAME_FMT_YUV + 11), /* VYUYVYUY... (VYUY) */
MPP_FMT_YUV400 = (MPP_FRAME_FMT_YUV + 12), /* YYYY... */
MPP_FMT_YUV440SP = (MPP_FRAME_FMT_YUV + 13), /* YYYY... UVUV... */
MPP_FMT_YUV411SP = (MPP_FRAME_FMT_YUV + 14), /* YYYY... UV... */
MPP_FMT_YUV444SP = (MPP_FRAME_FMT_YUV + 15), /* YYYY... UVUVUVUV... */
MPP_FMT_YUV444P = (MPP_FRAME_FMT_YUV + 16), /* YYYY... UUUU... VVVV... */
MPP_FMT_YUV_BUTT,
MPP_FMT_RGB565 = (MPP_FRAME_FMT_RGB + 0), /* 16-bit RGB */
MPP_FMT_BGR565 = (MPP_FRAME_FMT_RGB + 1), /* 16-bit RGB */
MPP_FMT_RGB555 = (MPP_FRAME_FMT_RGB + 2), /* 15-bit RGB */
MPP_FMT_BGR555 = (MPP_FRAME_FMT_RGB + 3), /* 15-bit RGB */
MPP_FMT_RGB444 = (MPP_FRAME_FMT_RGB + 4), /* 12-bit RGB */
MPP_FMT_BGR444 = (MPP_FRAME_FMT_RGB + 5), /* 12-bit RGB */
MPP_FMT_RGB888 = (MPP_FRAME_FMT_RGB + 6), /* 24-bit RGB */
MPP_FMT_BGR888 = (MPP_FRAME_FMT_RGB + 7), /* 24-bit RGB */
MPP_FMT_RGB101010 = (MPP_FRAME_FMT_RGB + 8), /* 30-bit RGB */
MPP_FMT_BGR101010 = (MPP_FRAME_FMT_RGB + 9), /* 30-bit RGB */
MPP_FMT_ARGB8888 = (MPP_FRAME_FMT_RGB + 10), /* 32-bit RGB */
MPP_FMT_ABGR8888 = (MPP_FRAME_FMT_RGB + 11), /* 32-bit RGB */
MPP_FMT_BGRA8888 = (MPP_FRAME_FMT_RGB + 12), /* 32-bit RGB */
MPP_FMT_RGBA8888 = (MPP_FRAME_FMT_RGB + 13), /* 32-bit RGB */
MPP_FMT_RGB_BUTT,
MPP_FMT_BUTT,
} MppFrameFormat;

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
/*
* MPEG vs JPEG YUV range.
*/
typedef enum {
MPP_FRAME_RANGE_UNSPECIFIED = 0,
MPP_FRAME_RANGE_MPEG = 1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges
MPP_FRAME_RANGE_JPEG = 2, ///< the normal 2^n-1 "JPEG" YUV ranges
MPP_FRAME_RANGE_NB, ///< Not part of ABI
} MppFrameColorRange;

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
/*
* input frame rotation parameter
* 0 - disable rotation
* 1 - 90 degree
* 2 - 180 degree
* 3 - 270 degree
*/
typedef enum MppEncRotationCfg_t {
MPP_ENC_ROT_0,
MPP_ENC_ROT_90,
MPP_ENC_ROT_180,
MPP_ENC_ROT_270,
MPP_ENC_ROT_BUTT
} MppEncRotationCfg;

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
/*
* input frame mirroring parameter
* 0 - disable mirroring
* 1 - horizontal mirroring
* 2 - vertical mirroring
*/
| Parameterzeichenkette | Schnittstelle | Tatsächlicher Typ | Beschreibung |
|---|---|---|---|
| codec:type | S32 | MppCodingType | Der MppEncCodecCfg entsprechende Protokolltyp; muss mit den Parametern der MppCtx-Initialisierungsfunktion mpp_init übereinstimmen. |
| h264:stream_type | S32 | RK_S32 | Typ des eingehenden H.264-Datenstromformats, standardmäßig 0. 0 — Annex-B-Format mit vorangestelltem Startcode 00 00 00 01. 1 — Format ohne Startcode. Derzeit ist intern das Annex-B-Format fest eingestellt. |
| h264:profile | S32 | RK_S32 | Parameter profile_idc in SPS: 66 — Baseline-Profil. 77 — Main-Profil. 100 — High-Profil. |
| h264:level | S32 | RK_S32 | Parameter level_idc in SPS; 10 steht für Level 1.0: 10/11/12/13 – qcif@15fps / cif@7.5fps / cif@15fps / cif@30fps 20/21/22 – cif@30fps / half-D1@25fps / D1@12.5fps 30/31/32 – D1@25fps / 720p@30fps / 720p@60fps 40/41/42 – 1080p@30fps / 1080p@30fps / 1080p@60fps 50/51/52 – 4K@30fps / 4K@30fps / 4K@60fps Üblicherweise wird Level 4.1 konfiguriert, um die Anforderungen zu erfüllen. |
| h264:cabac_en | S32 | RK_S32 | Vom Encoder verwendetes Entropiekodierungsformat: 0 – CAVLC, adaptive Kodierung mit variabler Länge. 1 – CABAC, adaptive arithmetische Kodierung. |
| h264:cabac_idc | S32 | RK_S32 | cabac_init_idc in der Protokollsyntax gilt bei cabac_en gleich 1; gültiger Bereich: 0~2. |
| h264:trans8x8 | S32 | RK_S32 | Aktivierungskennzeichen der 8x8-Transformation in der Protokollsyntax. |

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
typedef enum {
MPP_VIDEO_CodingUnused, /**< Value when coding is N/A */
MPP_VIDEO_CodingAutoDetect, /**< Autodetection of coding type */
MPP_VIDEO_CodingMPEG2, /**< AKA: H.262 */
MPP_VIDEO_CodingH263, /**< H.263 */
MPP_VIDEO_CodingMPEG4, /**< MPEG-4 */
MPP_VIDEO_CodingWMV, /**< Windows Media Video (WMV1,WMV2,WMV3)*/
MPP_VIDEO_CodingRV, /**< all versions of Real Video */
MPP_VIDEO_CodingAVC, /**< H.264/AVC */
MPP_VIDEO_CodingMJPEG, /**< Motion JPEG */
MPP_VIDEO_CodingVP8, /**< VP8 */
MPP_VIDEO_CodingVP9, /**< VP9 */
MPP_VIDEO_CodingVC1 = 0x01000000, /**< Windows Media Video (WMV1,WMV2,WMV3)*/
MPP_VIDEO_CodingFLV1, /**< Sorenson H.263 */
MPP_VIDEO_CodingDIVX3, /**< DIVX3 */
MPP_VIDEO_CodingVP6,
MPP_VIDEO_CodingHEVC, /**< H.265/HEVC */
MPP_VIDEO_CodingAVSPLUS, /**< AVS+ */
MPP_VIDEO_CodingAVS, /**< AVS profile=0x20 */
MPP_VIDEO_CodingAVS2, /**< AVS2 */
MPP_VIDEO_CodingAV1, /**< av1 */
MPP_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
MPP_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
MPP_VIDEO_CodingMax = 0x7FFFFFFF
} MppCodingType;

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
typedef enum h264_profile_t {
H264_PROFILE_FREXT_CAVLC444 = 44, //!< YUV 4:4:4/14 "CAVLC 4:4:4"
H264_PROFILE_BASELINE = 66, //!< YUV 4:2:0/8 "Baseline"
H264_PROFILE_MAIN = 77, //!< YUV 4:2:0/8 "Main"
H264_PROFILE_EXTENDED = 88, //!< YUV 4:2:0/8 "Extended"
H264_PROFILE_HIGH = 100, //!< YUV 4:2:0/8 "High"
H264_PROFILE_HIGH10 = 110, //!< YUV 4:2:0/10 "High 10"
H264_PROFILE_HIGH422 = 122, //!< YUV 4:2:2/10 "High 4:2:2"
H264_PROFILE_HIGH444 = 244, //!< YUV 4:4:4/14 "High 4:4:4"
H264_PROFILE_MVC_HIGH = 118, //!< YUV 4:2:0/8 "Multiview High"
H264_PROFILE_STEREO_HIGH = 128 //!< YUV 4:2:0/8 "Stereo High"
} H264Profile;
| Parameterzeichenkette | Schnittstelle | Tatsächlicher Typ | Beschreibung | ||
| h264:const_intra | S32 | RK_S32 | 0 — deaktivieren; in den Profilen Baseline/Main immer deaktiviert. | ||
| h264:scaling_list | S32 | RK_S32 | 1 — aktivieren; im High-Profil kann die Aktivierung gewählt werden. | ||
| h264:cb_qp_offset | S32 | RK_S32 | Aktivierungskennzeichen des Modus constrained_intra_pred_mode in der Protokollsyntax. | ||
| h264:cr_qp_offset | S32 | RK_S32 | 0 — aus, 1 — ein. | ||
| h264:dblk_disable | S32 | RK_S32 | Modus scaling_list_matrix in der Protokollsyntax. | ||
| h264:dblk_alpha | S32 | RK_S32 | 0 — flache Matrix, 1 — Standardmatrix. | ||
| h264:dblk_beta | S32 | RK_S32 | Wert deblock_offset_beta in der Protokollsyntax. | ||
| h264:qp_init | S32 | RK_S32 | Gültiger Bereich: [-6, 6]. | ||
| h264:qp_max | S32 | RK_S32 | Anfänglicher QP-Wert. Unter normalen Umständen nicht konfigurieren. | ||
| h264:qp_min | S32 | RK_S32 | Maximaler QP-Wert. Unter normalen Umständen nicht konfigurieren. | ||
| h264:qp_max_i | S32 | RK_S32 | Minimaler QP-Wert. Unter normalen Umständen nicht konfigurieren. | ||
| h264:qp_min_i | S32 | RK_S32 | Maximaler QP-Wert eines I-Frames. Unter normalen Umständen nicht konfigurieren. | ||
| h264:qp_step | S32 | RK_S32 | Minimaler QP-Wert eines I-Frames. Unter normalen Umständen nicht konfigurieren. | ||
| h265:profile | S32 | RK_S32 | Stärke der QP-Änderung auf Frame-Ebene zwischen zwei benachbarten Frames. | ||
| h265:level | S32 | RK_S32 | Parameter profile_idc in VPS: | ||
| h265:scaling_list | S32 | RK_S32 | Fest auf 1 eingestellt, Main-Profil. | ||
| h265:cb_qp_offset | S32 | RK_S32 | Parameter level_idc in VPS. | ||
| h265:cr_qp_offset | S32 | RK_S32 | Modus scaling_list_matrix in der Protokollsyntax. | ||
| h265:dblk_disable | S32 | RK_S32 | 0 — flache Matrix, 1 — Standardmatrix. | ||
| h265:dblk_alpha | S32 | RK_S32 | Wert chroma_cb_qp_offset in der Protokollsyntax. | ||
| h265:dblk_beta | S32 | RK_S32 | Gültiger Bereich: [-12, 12]. | ||
| h265:qp_init | S32 | RK_S32 | Wert chroma_cr_qp_offset in der Protokollsyntax. | ||
| h265:qp_max | S32 | RK_S32 | Gültiger Bereich: [-12, 12]. | ||
| h265:qp_min | S32 | RK_S32 | Kennzeichen deblock_disable in der Protokollsyntax; gültiger Bereich: [0, 2]. | ||
| Parameterzeichenkette | Schnittstelle | Tatsächlicher Typ | Beschreibung |
|---|---|---|---|
| h265:qp_max_i | S32 | RK_S32 | 0 — Deblocking ist aktiviert. |
| h265:qp_min_i | S32 | RK_S32 | Minimaler QP-Wert eines I-Frames. Unter normalen Umständen nicht konfigurieren. |
| h265:qp_step | S32 | RK_S32 | Stärke der QP-Änderung auf Frame-Ebene zwischen zwei benachbarten Frames. |
| h265:qp_delta_ip | S32 | RK_S32 | QP-Differenz zwischen dem I-Frame und dem vorhergehenden P-Frame. |
| jpeg: quant | S32 | RK_S32 | Stufe des vom JPEG-Encoder verwendeten Quantisierungsparameters. Der Encoder besitzt insgesamt 11 Stufen von Quantisierungskoeffiziententabellen, von 0 bis 10; die Bildqualität steigt von schlecht zu gut. |
| split:mode | U32 | MppEncSplitMode | Slice-Aufteilungsmodus für H.264/H.265: 0 — keine Aufteilung. 1 — BY_BYTE teilt anhand der Slice-Größe auf. 2 — BY_CTU teilt anhand der Anzahl von Makroblöcken oder CTUs auf. |
| split:arg | U32 | RK_U32 | Parameter der Slice-Aufteilung: Im Modus BY_BYTE gibt der Parameter die maximale Größe jedes Slices an. Im Modus BY_CTU gibt er die Anzahl von Makroblöcken oder CTUs in jedem Slice an. |

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
typedef enum MppEncSplitMode_e {
MPP_ENC_SPLIT_NONE,
MPP_ENC_SPLIT_BY_BYTE,
MPP_ENC_SPLIT_BY_CTU,
} MppEncSplitMode;
Weitere Zeichenfolgen und Parameter werden später ergänzt.
3.5.2 Weitere Steuerbefehle
Der Aufzählungstyp MpiCmd in rk_mpi_cmd.h definiert die Befehlskennungen der Steuerschnittstelle. Die Befehle für den Encoder und den Kodierungsprozess sind nachfolgend aufgeführt:

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
MPP_ENC_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_ENC,
/* basic encoder setup control */
MPP_ENC_SET_CFG, /* set MppEncCfg structure */
MPP_ENC_GET_CFG, /* get MppEncCfg structure */
MPP_ENC_SET_PREP_CFG, /* deprecated set MppEncPrepCfg structure, use MPP_ENC_SET_CFG instead */
MPP_ENC_GET_PREP_CFG, /* deprecated get MppEncPrepCfg structure, use MPP_ENC_GET_CFG instead */
MPP_ENC_SET_RC_CFG, /* deprecated set MppEncRcCfg structure, use MPP_ENC_SET_CFG instead */
MPP_ENC_GET_RC_CFG, /* deprecated get MppEncRcCfg structure, use MPP_ENC_GET_CFG instead */
MPP_ENC_SET_CODEC_CFG, /* deprecated set MppEncCodecCfg structure, use MPP_ENC_SET_CFG instead */
MPP_ENC_GET_CODEC_CFG, /* deprecated get MppEncCodecCfg structure, use MPP_ENC_GET_CFG instead */
/* runtime encoder setup control */
MPP_ENC_SET_IDR_FRAME, /* next frame will be encoded as intra frame */
MPP_ENC_SET_OSD_LEGACY_0, /* deprecated */
MPP_ENC_SET_OSD_LEGACY_1, /* deprecated */
MPP_ENC_SET_OSD_LEGACY_2, /* deprecated */
MPP_ENC_GET_HDR_SYNC, /* get vps / sps / pps which has better sync behavior parameter is MppPacket */
MPP_ENC_GET_EXTRA_INFO, /* deprecated */
MPP_ENC_SET_SEI_CFG, /* SEI: Supplement Enhancement Information, parameter is MppSeiMode */
MPP_ENC_GET_SEI_DATA, /* SEI: Supplement Enhancement Information, parameter is MppPacket */
MPP_ENC_PRE_ALLOC_BUFF, /* allocate buffers before encoding */
MPP_ENC_SET_QP_RANGE, /* used for adjusting qp range, the parameter can be 1 or 2 */
MPP_ENC_SET_ROI_CFG, /* set MppEncROICfg structure */
MPP_ENC_SET_CTU_QP, /* for H265 Encoder,set CTU's size and QP */
Die Befehle von MPP_ENC_CMD_BASE bis MPP_ENC_CMD_END gehören zur Encoder-Steuerschnittstelle. MPP_ENC_SET/GET_CFG wurde in Abschnitt 3.5.1 bereits als grundlegender Konfigurationsbefehl vorgestellt. Die übrigen Befehle werden nachfolgend kurz erläutert. Sie sind von der Encoder-Hardware abhängig und werden nur von bestimmten Hardwarevarianten unterstützt.
Im beschriebenen Stand der Quelle unterstützt MPP Encoder-Hardware der Familien vepu und rkvenc. Die vepu-Familie unterstützt H.264-, vp8- und jpeg-Kodierung und ist in den meisten RK-Chips vorhanden. Laut Quelle unterstützt rkvenc ausschließlich H.264 und ist nur auf den SoCs RV1109/RV1126 verfügbar; es bietet mehr Kodierungsfunktionen als vepu. Dies ist die historische Beschreibung der Quelle, keine Aussage über den aktuellen Umfang aller Plattformen.
Kurzbeschreibung einiger CMD-Befehle:
MPP_ENC_SET_PREP_CFG/ MPP_ENC_GET_PREP_CFG MPP_ENC_SET_RC_CFG/ MPP_ENC_GET_RC_CFG MPP_ENC_SET_CODEC_CFG/ MPP_ENC_GET_CODEC_CFG
Veraltete Befehle, zur Vorwärtskompatibilität beibehalten; nicht verwenden.
MPP_ENC_SET_IDR_FRAME
Der Befehl hat keinen Parameter und fordert beim Encoder einen IDR-Frame an. Nach Empfang der Anforderung kodiert der Encoder den nächsten Frame als IDR-Frame. Von sämtlicher Hardware unterstützt.
MPP_ENC_SET_OSD_LEGACY_0 MPP_ENC_SET_OSD_LEGACY_1 MPP_ENC_SET_OSD_LEGACY_2
Veraltete Befehle, zur Vorwärtskompatibilität beibehalten; nicht verwenden.
MPP_ENC_GET_HDR_SYNC/ MPP_ENC_GET_EXTRA_INFO
Befehle zum separaten Abruf der Headerdaten des Bitstroms. MPP_ENC_GET_EXTRA_INFO ist ein alter Befehl und wird nicht empfohlen.
Der Eingabeparameter von MPP_ENC_GET_HDR_SYNC ist ein MppPacket. Der externe Benutzer muss Speicher zuweisen, ihn als MppPacket kapseln und über control an den Encoder übergeben. Bei Rückkehr der Steuerschnittstelle ist die Datenkopie abgeschlossen; der Vorgang ist threadsicher. Der Aufruf erfolgt nach Abschluss der grundlegenden Encoder-Konfiguration. Den zuvor zugewiesenen MppPacket muss der Benutzer selbst freigeben. Der Eingabeparameter von MPP_ENC_GET_EXTRA_INFO ist ein MppPacket*: Damit wird der interne MppPacket des Encoders für den Zugriff abgerufen. Auch dieser Aufruf erfolgt nach Abschluss der grundlegenden Encoder-Konfiguration. Der hier erhaltene MppPacket gehört zum internen Speicher von MPP und darf nicht vom Benutzer freigegeben werden.
Bei Mehrthreadbetrieb kann der über MPP_ENC_GET_EXTRA_INFO erhaltene MppPacket während des Lesens durch andere Steueraufrufe verändert werden. Der Befehl ist daher nicht threadsicher und dient nur der Kompatibilität mit der alten vpu_api. Er soll nicht mehr verwendet werden.
MPP_ENC_SET_SEI_CFG/MPP_ENC_GET_SEI_DATA
Veraltete Befehle, zur Vorwärtskompatibilität beibehalten; nicht verwenden.
MPP_ENC_PRE_ALLOC_BUFF/MPP_ENC_SET_QP_RANGE/MPP_ENC_SET_ROI_CFG/ MPP_ENC_SET_CTU_QP
Veraltete Befehle, zur Vorwärtskompatibilität beibehalten; nicht verwenden.
MPP_ENC_GET_RC_API_ALL
API-Informationen zu sämtlichen derzeit von MPP unterstützten Bitratenregelungsstrategien abfragen. Einen RcApiQueryAll*-Zeiger übergeben; beim Rücksprung wird die Struktur gefüllt.
MPP_ENC_GET_RC_API_BY_TYPE
API-Informationen aller Bitratenregelungsstrategien eines angegebenen MppCodingType abfragen. RcApiQueryType* übergeben und MppCodingType angeben; die Struktur wird beim Rücksprung gefüllt.
MPP_ENC_SET_RC_API_CFG
API einer externen Bitratenregelungsstrategie mit RcImplApi* registrieren. Die Funktionszeiger der Struktur definieren das Verhalten des Plug-ins. Die registrierte Strategie kann anschließend abgefragt und aktiviert werden.
MPP_ENC_GET_RC_API_CURRENT
API-Informationen der aktuell verwendeten Bitratenregelungsstrategie abfragen. RcApiBrief* übergeben; die Struktur wird beim Rücksprung gefüllt.
MPP_ENC_SET_RC_API_CURRENT
API einer Bitratenregelungsstrategie mit angegebenem Namen aktivieren. RcApiBrief* übergeben; der Encoder sucht das darin als Zeichenkette angegebene API und aktiviert es als aktuelle Strategie.
MPP_ENC_SET_HEADER_MODE/MPP_ENC_GET_HEADER_MODE
Laut Quellbeschreibung Ausgabeart der SEI-Debuginformationen des H.264/H.265-Encoders konfigurieren beziehungsweise abfragen. Der Debugschalter soll künftig durch Umgebungsvariablen ersetzt werden; nicht verwenden. Die Abweichung zum Befehlsnamen HEADER_MODE bleibt dokumentiert.
MPP_ENC_SET_SPLIT/ MPP_ENC_GET_SPLIT
Slice-Aufteilung des H.264/H265-Encoders konfigurieren beziehungsweise abfragen. Durch split:mode und split:arg in MppEncCfg ersetzt; nicht verwenden.
MPP_ENC_SET_REF_CFG
Erweiterten Referenzframe-Modus konfigurieren. Standardmäßig nicht erforderlich; für besondere Beziehungen zwischen lang- und kurzfristigen Referenzframes vorgesehen. Dies ist eine erweiterte Schnittstelle, zu der die Quelle weitere Dokumentation ankündigt.
MPP_ENC_SET_OSD_PLT_CFG
Der Befehlsparameter MppEncOSDPlt konfiguriert die OSD-Palette der rkvenc-Hardware. Die Quelle wiederholt diese Beschreibung zweimal. Üblicherweise einmal zu Beginn konfigurieren und während der gesamten Codierung dieselbe Palette verwenden. Nur RV1109/RV1126 unterstützt.
MPP_ENC_GET_OSD_PLT_CFG
Laut Quelltext zum separaten Abruf der Bitstream-Headerdaten; MPP_ENC_GET_EXTRA_INFO ist ein alter, nicht empfohlener Befehl. Die Abweichung zur Überschrift GET_OSD_PLT_CFG bleibt erhalten.
MPP_ENC_SET_OSD_DATA_CFG
MppEncOSDData konfiguriert OSD-Daten der rkvenc-Hardware; die Quelle wiederholt diese Aussage. Für jeden Frame und nach jeder Framecodierung erneut konfigurieren. Der Befehl wurde durch KEY_OSD_DATA in dem von MppFrame getragenen MppMeta ersetzt und wird nicht mehr verwendet.
3.6 Wichtige Hinweise zur Encoderverwendung
3.6.1 Breite, Höhe und Stride des Eingangsbilds
Breiten- und Höheneinstellungen müssen der Speicheranordnung der Bilddaten entsprechen. Für ein YUV420-Bild mit 1920x1080 ergeben sich unter Bezug auf die MppFrame-Parameter aus Abbildung 7 folgende zwei Fälle.


Abbildung 18: Speicheranordnung des Encoder-Eingangsframes
Links: Luminanzbreite 1920, Höhe 1080. Luminanz- und Chromadaten schließen nicht direkt aneinander an; dazwischen liegen 8 Leerzeilen.
Hier beträgt der horizontale Stride 1920 und der vertikale 1088. Die Anwendung allokiert und befüllt 192010883/2 Speicher. Mit width 1920, height 1080, horizontal stride 1920 und vertical stride 1088 kann regulär codiert werden.
Rechts: Luminanzbreite 1920, Höhe 1080. Luminanz- und Chromadaten schließen ohne Leerzeilen direkt aneinander an.
Hier ist der horizontale Stride 1920 und der vertikale 1080. Der Encoder greift jedoch mit 16er-Ausrichtung zu: Am unteren Luminanzrand werden Chromadaten und am unteren Chromarand Daten außerhalb dieses Bereichs gelesen. Daher zusätzlichen Padding-Speicher bereitstellen: 192010803/2+1920*4, damit kein Zugriff auf unallokierten Speicher erfolgt.
3.6.2 Eingabe und Erweiterung von Encoder-Steuerinformationen
Steuerinformationen werden auf zwei Arten übergeben:
Globale Informationen wie Bitrate und Bildabmessungen wirken auf den gesamten Encoder und Codierprozess. Temporäre Informationen wie frameweises OSD oder Benutzerdaten wirken nur auf die Codierung eines einzelnen Frames.
Die erste Gruppe wird vorwiegend über control konfiguriert, die zweite über die von MppFrame getragenen MppMeta-Daten.
Künftige Erweiterungen der Steuerinformationen folgen diesen beiden Regeln.
3.6.3 Ein- und Ausgabeablauf des Encoders
Laut Quelle unterstützt der Encoder-Eingang derzeit nur blockierende Aufrufe. Der Ausgang unterstützt blockierende und nichtblockierende Aufrufe, standardmäßig nichtblockierend. Der Datenabruf kann deshalb erfolglos bleiben; bei der Nutzung berücksichtigen.
3.6.4 Plug-in-Mechanismus für eigene Bitratenregelungsstrategien
MPP erlaubt eigene Bitratenregelungsstrategien. RcImplApi definiert mehrere Hook-Funktionen im Codierablauf, um benutzerdefinierte Verarbeitung an festgelegten Stellen einzufügen. Als Beispiel dienen die Standardstrategien für H.264/H.265, Strukturen default_h264e/default_h265e.
Der Plug-in-Mechanismus ist in MPP vorgesehen, Schnittstelle und Ablauf sind jedoch instabil; weitere häufige Änderungen sind absehbar. Nur für Nutzer empfohlen, die den Code lesen, verstehen und den Mechanismus fortlaufend pflegen können. Für allgemeine Nutzer nicht empfohlen.
4. MPP-Demoprogramme
Die Demoprogramme ändern sich schnell. Die Beschreibung dient nur als Referenz; maßgeblich ist die tatsächliche Ausführung. Die Quellbeispiele basieren auf Android 32bit.
4.1 Decoder-Demo
Die Decoder-Demos umfassen mpi_dec_test: die einthreadige mpi_dec_test mit decode_put_packet/decode_get_frame, die mehrthreadige mpi_dec_mt_test und die Mehrinstanzvariante mpi_dec_multi_test.
Android-Beispiel: Zunächst mpi_dec_test direkt ausführen; die Hilfe erscheint wie nachfolgend im Log.

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
--------- beginning of main
08-16 05:00:51.320 2150 2150 I mpi_dec_utils: usage: mpi_dec_test [options]
08-16 05:00:51.321 2150 2150 I mpi_dec_utils: -i input_file input bitstream file
08-16 05:00:51.321 2150 2150 I mpi_dec_utils: -o output_file output decoded frame file
08-16 05:00:51.321 2150 2150 I mpi_dec_utils: -w width the width of input bitstream
08-16 05:00:51.321 2150 2150 I mpi_dec_utils: -h height the height of input bitstream
08-16 05:00:51.321 2150 2150 I mpi_dec_utils: -t type input stream coding type
08-16 05:00:51.321 2150 2150 I mpi_dec_utils: -f format output frame format type
08-16 05:00:51.321 2150 2150 I mpi_dec_utils: -n frame_number max output frame number
08-16 05:00:51.321 2150 2150 I mpi_dec_utils: -s instance_nb number of instances
08-16 05:00:51.321 2150 2150 I mpi_dec_utils: -v trace option q - quiet f - show fps
08-16 05:00:51.321 2150 2150 I mpi_dec_utils: -slt slt file slt verify data file
08-16 05:00:51.321 2150 2150 I mpi_dec_utils: -help help show help
08-16 05:00:51.321 2150 2150 I mpi : mpp coding type support list:
08-16 05:00:51.321 2150 2150 I mpi : type: dec id 0 coding: mpeg2 id 2
08-16 05:00:51.321 2150 2150 I mpi : type: dec id 0 coding: mpeg4 id 4
08-16 05:00:51.321 2150 2150 I mpi : type: dec id 0 coding: h.263 id 3
08-16 05:00:51.321 2150 2150 I mpi : type: dec id 0 coding: h.264/AVC id 7
08-16 05:00:51.321 2150 2150 I mpi : type: dec id 0 coding: h.265/HEVC id 16777220
08-16 05:00:51.321 2150 2150 I mpi : type: dec id 0 coding: vp8 id 9
08-16 05:00:51.321 2150 2150 I mpi : type: dec id 0 coding: VP9 id 10
08-16 05:00:51.321 2150 2150 I mpi : type: dec id 0 coding: avs+ id 16777221
08-16 05:00:51.321 2150 2150 I mpi : type: dec id 0 coding: avs2 id 16777223
08-16 05:00:51.321 2150 2150 I mpi : type: dec id 0 coding: jpeg id 8
08-16 05:00:51.321 2150 2150 I mpi : type: dec id 0 coding: av1 id 16777224
08-16 05:00:51.321 2150 2150 I mpi : type: enc id 1 coding: h.264/AVC id 7
08-16 05:00:51.322 2150 2150 I mpi : type: enc id 1 coding: jpeg id 8
08-16 05:00:51.322 2150 2150 I mpi : type: enc id 1 coding: h265 id 16777220
08-16 05:00:51.322 2150 2150 I mpi : type: enc id 1 coding: vp8 id 9
Die Hilfe besteht aus zwei Teilen: Befehlsparameter von mpi_dec_test und unterstützte Codiertypen der Eingangsbitstreamdatei.
Die Befehlsparameter folgen.
| Befehlsparameter | Beschreibung |
|---|---|
| -i | Datei des Eingangsbitstroms. |
| -o | Ausgabedatei der dekodierten Frames. |
| -w | Breite des Eingangsbitstroms in Pixeln. |
| -h | Höhe des Eingangsbitstroms in Pixeln. |
| -t | Kodierungstyp des Eingangsbitstroms. |
| -f | Formattyp des Ausgabeframes, standardmäßig NV12. |
| -n | Maximale Anzahl von Ausgabeframes. Ist der Eingangsbitstrom zu lang, werden nur die ersten n Frames dekodiert. |
| -s | Anzahl der Instanzen, standardmäßig 1. |
| -v | Trace-Option: q — ohne Ausgabe; f — fps anzeigen. |
| -slt | slt-Prüfdatendatei zum dekodierten Ausgabeframe. |
| -help | Hilfe anzeigen. |
Bei mpi_dec_test sind Eingangsdatei (i) und Codiertyp (t) Pflichtparameter. Ausgangsdatei (o), Breite (w), Höhe (h), Anzahl decodierter Frames (n) und weitere Parameter sind optional und weniger bestimmend.
In der Ausgabe bzw. den Parametern von mpi_dec_test: Die slt-Verifikationsdatei enthält aus den Ausgangsframes abgeleitete CRC-Codes, siehe utils/utils.c. Sie ist meist nur wenige kB groß. Beim slt-Chiptest ersetzt ihr Vergleich den Vergleich vollständiger Framedateien und verkürzt den Testzyklus deutlich.
Die folgende Ausgabe nennt die Formate der MPP-Bibliothek: MPEG2/4-, H.263/4/5- und VP8/9-Decodierung. Die Zahl nach id entspricht dem -t-Wert des Formats und stammt aus OMX-Definitionen. HEVC- und AVS-Werte unterscheiden sich deutlich von den übrigen; dies beachten.
Beispiel: 30 Frames aus ocrean.h264 unter /data/ decodieren. Befehl:
mpi_dec_test -t 7 -i /data/ocrean.h264 -n 30
Dabei bedeutet -t 7 einen H.264-Bitstream, -i die Eingangsdatei und -n 30 das Decodieren von 30 Frames. Bei regulärem Ablauf folgt folgendes Ergebnis.

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
08-17 11:58:03.511 2801 2801 I mpi_dec_utils: input file /data/ocrean.h264 size 38052414
08-17 11:58:03.512 2801 2801 I mpi_dec_utils: cmd parse result:
08-17 11:58:03.512 2801 2801 I mpi_dec_utils: input file name: /data/ocrean.h264
08-17 11:58:03.512 2801 2801 I mpi_dec_utils: output file name:
08-17 11:58:03.512 2801 2801 I mpi_dec_utils: width : 0
08-17 11:58:03.512 2801 2801 I mpi_dec_utils: height : 0
08-17 11:58:03.512 2801 2801 I mpi_dec_utils: type : 7
08-17 11:58:03.512 2801 2801 I mpi_dec_utils: max frames : 30
08-17 11:58:03.512 2801 2801 I mpi_dec_test: mpi_dec_test start
08-17 11:58:03.512 2801 2801 I mpp_info: mpp version: 6cc173d1 author: Ding Wei 2022-08-29 [hal_avsd]: Fix crash on avsd ref err path
08-17 11:58:03.512 2801 2801 I mpi_dec_test: 0xf1c40730 mpi_dec_test decoder test start w 0 h 0 type 7
08-17 11:58:03.538 2801 2805 I mpi_dec_test: 0xf1c40730 decode_get_frame get info changed found
08-17 11:58:03.538 2801 2805 I mpi_dec_test: 0xf1c40730 decoder require buffer w:h [1920:1088] stride [1920:1088] buf_size 4177920
08-17 11:58:03.538 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 0
08-17 11:58:03.585 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 1
08-17 11:58:03.585 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 2
08-17 11:58:03.585 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 3
08-17 11:58:03.585 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 4
08-17 11:58:03.586 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 5
08-17 11:58:03.601 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 6
08-17 11:58:03.608 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 7
08-17 11:58:03.616 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 8
08-17 11:58:03.624 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 9
08-17 11:58:03.640 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 10
08-17 11:58:03.647 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 11
08-17 11:58:03.655 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 12
08-17 11:58:03.664 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 13
08-17 11:58:03.673 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 14
08-17 11:58:03.681 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 15
08-17 11:58:03.689 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 16
08-17 11:58:03.698 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 17
08-17 11:58:03.698 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 18
08-17 11:58:03.706 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 19
08-17 11:58:03.713 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 20
08-17 11:58:03.726 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 21
08-17 11:58:03.726 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 22
08-17 11:58:03.734 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 23
08-17 11:58:03.742 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 24
08-17 11:58:03.749 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 25
08-17 11:58:03.756 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 26
08-17 11:58:03.764 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 27
08-17 11:58:03.771 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 28
08-17 11:58:03.778 2801 2805 I mpi_dec_test: 0xf1c40730 decode get frame 29
08-17 11:58:03.778 2801 2801 I mpi_dec_test: decode 30 frames time 263 ms delay 69 ms fps 113.99
08-17 11:58:03.781 2801 2801 I mpi_dec_test: test success max memory 19.92 MB
Die Ausgabe enthält Versionsinformationen der MPP-Bibliothek:
I mpp_info: mpp version: 6cc173d1 author: Ding Wei 2022-08-29 [hal_avsd]: Fix crash on avsd
ref err path
I mpi_dec_test: 0xeebc01c0 decode_get_frame get info changed found
Die mpi_dec_test-Ausgabe meldet ein info-change-Ereignis des MPP-Decoders.
I mpi_dec_test: 0xeebc01c0 decoder require buffer w:h [1920:1080] stride [1920:1088]
buf_size 4177920
Die mpi_dec_test-Ausgabe zeigt die vom MPP-Decoder benötigten Bildspeicherbedingungen.
I mpi_dec_test: 0xf1c40730 decode get frame 0
Die mpi_dec_test-Ausgabe zeigt reguläres Decodieren und Ausgeben von Bildern.
I mpi_dec_test: decode 30 frames time 263ms delay 69ms fps 113.99
In der Ausgabe bzw. den Parametern von mpi_dec_test: Laut Quellbeispiel decodierte der Decoder 30 Frames in 263ms, mit 69ms Erstframelatenz und 113.99 fps. Dies sind Quellwerte, keine ArmSoM-Messungen.
I mpi_dec_test: test success max memory 19.92 MB
In der Ausgabe bzw. den Parametern von mpi_dec_test: Laut Quellausgabe beträgt der maximale Decodierspeicher 19.92 MB.
Der ausführliche Decoder-Democode steht in test/mpi_dec_test.c.
4.2 Encoder-Demo
Die Encoder-Demos der Reihe mpi_enc_test umfassen die einthreadige mpi_enc_test und die Mehrinstanzvariante mpi_enc_multi_test.
Im Android-Beispiel zunächst mpi_enc_test direkt ausführen; die Ausgabe folgt.

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
08-16 10:41:16.339 2526 2526 I mpi_enc_utils: usage: mpi_enc_test [options]
08-16 10:41:16.339 2526 2526 I mpi_enc_utils: -i input_file input frame file
08-16 10:41:16.339 2526 2526 I mpi_enc_utils: -o output_file output encoded bitstream file
08-16 10:41:16.339 2526 2526 I mpi_enc_utils: -w width the width of input picture
08-16 10:41:16.339 2526 2526 I mpi_enc_utils: -h height the height of input picture
08-16 10:41:16.339 2526 2526 I mpi_enc_utils: -hstride hor_stride the horizontal stride of input picture
08-16 10:41:16.339 2526 2526 I mpi_enc_utils: -vstride ver_stride the vertical stride of input picture
08-16 10:41:16.339 2526 2526 I mpi_enc_utils: -f format the format of input picture
08-16 10:41:16.339 2526 2526 I mpi_enc_utils: -t type output stream coding type
08-16 10:41:16.339 2526 2526 I mpi_enc_utils: -tsrc source type input file source coding type
08-16 10:41:16.339 2526 2526 I mpi_enc_utils: -n max frame number max encoding frame number
08-16 10:41:16.339 2526 2526 I mpi_enc_utils: -g gop reference mode gop_mode:gop_len:vi_len
08-16 10:41:16.339 2526 2526 I mpi_enc_utils: -rc rate control mode set rc_mode
08-16 10:41:16.339 2526 2526 I mpi_enc_utils: -bps bps target:min:max set target/min/max bps and rc_mode
08-16 10:41:16.339 2526 2526 I mpi_enc_utils: -fps in/output fps set input and output frame rate
08-16 10:41:16.339 2526 2526 I mpi_enc_utils: -q quality control set qp_init/min/max/min_i/max_i
08-16 10:41:16.339 2526 2526 I mpi_enc_utils: -s instance_nb number of instances
08-16 10:41:16.339 2526 2526 I mpi_enc_utils: -v trace option q - quiet f - show fps
08-16 10:41:16.339 2526 2526 I mpi_enc_utils: -l loop count looping times for each frame
08-16 10:41:16.339 2526 2526 I mpi_enc_utils: -ini ini file encoder extra ini config file
08-16 10:41:16.339 2526 2526 I mpi_enc_utils: -slt slt file slt verify data file
08-16 10:41:16.339 2526 2526 I mpi : mpp coding type support list:
08-16 10:41:16.339 2526 2526 I mpi : type: dec id 0 coding: mpeg2 id 2
08-16 10:41:16.340 2526 2526 I mpi : type: dec id 0 coding: mpeg4 id 4
08-16 10:41:16.340 2526 2526 I mpi : type: dec id 0 coding: h.263 id 3
08-16 10:41:16.340 2526 2526 I mpi : type: dec id 0 coding: h.264/AVC id 7
08-16 10:41:16.340 2526 2526 I mpi : type: dec id 0 coding: h.265/HEVC id 16777220
08-16 10:41:16.340 2526 2526 I mpi : type: dec id 0 coding: vp8 id 9
08-16 10:41:16.340 2526 2526 I mpi : type: dec id 0 coding: VP9 id 10
08-16 10:41:16.340 2526 2526 I mpi : type: dec id 0 coding: avs+ id 16777221
08-16 10:41:16.340 2526 2526 I mpi : type: dec id 0 coding: avs2 id 16777223
08-16 10:41:16.340 2526 2526 I mpi : type: dec id 0 coding: jpeg id 8
08-16 10:41:16.340 2526 2526 I mpi : type: dec id 0 coding: av1 id 16777224
08-16 10:41:16.340 2526 2526 I mpi : type: enc id 1 coding: h.264/AVC id 7
08-16 10:41:16.340 2526 2526 I mpi : type: enc id 1 coding: jpeg id 8
08-16 10:41:16.340 2526 2526 I mpi : type: enc id 1 coding: h265 id 16777220
08-16 10:41:16.340 2526 2526 I mpi : type: enc id 1 coding: vp8 id 9
08-16 10:41:16.340 2526 2526 I mpi : mpp color support list:
08-16 10:41:16.340 2526 2526 I mpi : color: id 0 0x00000 YUV420SP, NV12
08-16 10:41:16.340 2526 2526 I mpi : color: id 1 0x00001 YUV420SP-10bit
08-16 10:41:16.340 2526 2526 I mpi : color: id 2 0x00002 YUV422SP, NV24
08-16 10:41:16.340 2526 2526 I mpi : color: id 3 0x00003 YUV422SP-10bit
08-16 10:41:16.340 2526 2526 I mpi : color: id 4 0x00004 YUV420P, I420
08-16 10:41:16.340 2526 2526 I mpi : color: id 5 0x00005 YUV420SP, NV21
08-16 10:41:16.340 2526 2526 I mpi : color: id 6 0x00006 YUV422P, 422P
08-16 10:41:16.340 2526 2526 I mpi : color: id 7 0x00007 YUV422SP, NV42
08-16 10:41:16.340 2526 2526 I mpi : color: id 8 0x00008 YUV422-YUYV, YUY2
08-16 10:41:16.340 2526 2526 I mpi : color: id 10 0x0000a YUV422-UYVY, UYVY
08-16 10:41:16.340 2526 2526 I mpi : color: id 12 0x0000c YUV400-Y8, Y800
08-16 10:41:16.340 2526 2526 I mpi : color: id 15 0x0000f YUV444SP
08-16 10:41:16.340 2526 2526 I mpi : color: id 16 0x00010 YUV444P
08-16 10:41:16.340 2526 2526 I mpi : color: id 65536 0x10000 RGB565
08-16 10:41:16.340 2526 2526 I mpi : color: id 65537 0x10001 BGR565
08-16 10:41:16.340 2526 2526 I mpi : color: id 65538 0x10002 RGB555
08-16 10:41:16.340 2526 2526 I mpi : color: id 65539 0x10003 BGR555
08-16 10:41:16.340 2526 2526 I mpi : color: id 65542 0x10006 RGB888
08-16 10:41:16.340 2526 2526 I mpi : color: id 65543 0x10007 BGR888
08-16 10:41:16.340 2526 2526 I mpi : color: id 65546 0x1000a ARGB8888
08-16 10:41:16.340 2526 2526 I mpi : color: id 65547 0x1000b ABGR8888
08-16 10:41:16.340 2526 2526 I mpi : color: id 65548 0x1000c BGRA8888
08-16 10:41:16.340 2526 2526 I mpi : color: id 65549 0x1000d RGBA8888
Die Hilfe gliedert sich in drei Teile:
(1) Befehlsparameter von mpi_enc_test;
(2) Codiertyp der Ausgangsbitstreamdatei;
(3) Format des Eingangsbilds.
Die Befehlsparameter folgen.
| Befehlsparameter | Beschreibung |
|---|---|
| -i | Datei der Eingabeframes. |
| -o | Kodierter Ausgangsbitstrom. |
| -w | Breite des Eingangsbitstroms in Pixeln. |
| -h | Höhe des Eingangsbitstroms in Pixeln. |
| -hstride | Horizontaler Stride des Eingabebildes in Bytes. |
| -vstride | Vertikaler Stride des Eingabebildes; Einheit: 1. |
| -f | Format des Eingabebildes, standardmäßig NV12. |
| -t | Kodierungstyp des Ausgangsdatenstroms. |
| -tsrc | Quellkodierungstyp der Eingabedatei; nur im Codec-Leistungstest verwendet (siehe mpi_rc2_test.c). |
| -n | Maximale Anzahl zu kodierender Frames. Ist der Eingangsbitstrom zu lang, können nur die ersten n Frames dekodiert werden. |
| -g | gop-Referenzmodus. |
| -rc | rc_mode festlegen: 0:vbr 1:cbr 2:fixqp 3:avbr. |
| -bps | Bitrate festlegen. |
| -fps | Eingangs- und Ausgangsbildrate festlegen, standardmäßig 30. Dieser Befehlsparameter beschreibt nur das proportionale Verhältnis zwischen Eingangs- und Ausgangsbildrate; die Quelle nennt dabei einen Bezug zur tatsächlichen Bildrate. |
| -qc | Qualitätssteuerung festlegen. |
| -s | Anzahl der Instanzen, standardmäßig 1. |
| -v | Trace-Option: q — ohne Ausgabe; f — fps anzeigen. |
| -ini | Zusätzliche ini-Konfigurationsdatei des Encoders (noch nicht wirksam). |
| -slt | slt-Prüfdatendatei zum kodierten Ausgangsbitstrom. |
Bei mpi_enc_test sind Breite (w), Höhe (h) und Codiertyp (t) Pflichtparameter. Eingangsdatei (i), Ausgangsdatei (o), Frameanzahl (n) und Eingangsbildformat (f) sind optional. Ohne Eingangsdatei erzeugt mpi_enc_test ein Standard-Farbbalkenbild zur Codierung.
mpi_enc_test bietet verschiedene Bitratenregelungen über Modus und Begrenzungsparameter. Modi: variable Bitrate VBR, konstante Bitrate CBR, fester QP FIXQP und adaptive Bitrate AVBR; Standard ist VBR. Die Begrenzungsparameter dienen als Referenz für die internen Bitratengrenzen von MPP.
Format der Ein-/Ausgangsbildratensteuerung (fps) in mpi_enc_test:
-fps fps_in_num:fps_in_den:fps_in_flex/fps_out_num:fps_out_den:fps_out_flex
in/out bezeichnet Eingang/Ausgang, num den Zähler und den den Nenner. flex=0 bedeutet feste, flex=1 variable Bildrate. Standardwerte für Ein- und Ausgang sind num=30 und den=1, also jeweils 30. Der Parameter beschreibt nur das Verhältnis von Ein- zu Ausgangsbildrate, unabhängig von der tatsächlichen Bildrate.
Die Qualitätssteuerung in mpi_enc_test wirkt nur für H.264-, H.265-, VP8- oder JPEG-Ausgabe. Befehlsformat:
-qc qp_init/min/max/min_i/max_i
qp bezeichnet Qualitätsparameter, init den Anfangswert, min das Minimum und max das Maximum. Die Quelle beschreibt den Suffix i als Maximalwert für I-Frames; ohne Suffix sind B- und P-Frames gemeint. Die unklare Quellformulierung bleibt erhalten.
Für mpi_enc_test: Bei Protokolloption (v) = q wird die gewöhnliche MPP-Protokollierung abgeschaltet. Bei f werden einmal pro Sekunde mittlere und aktuelle Bildrate ausgegeben.
Farbraumformate gliedern sich in YUV und RGB. MPP unterstützt mehrere Formate (f), deren Parameterwerte verschiedene Speicherlayouts bezeichnen. Insbesondere unterscheiden sich YUV- und RGB-Parameterwerte deutlich.
Beispiel: 30 Frames aus ocrean.yuv unter /data codieren. Startbefehl:
mpi_enc_test -w 1920 -h 1080 -t 7 -i /data/ocrean.yuv -o /data/out.h264 -n 30
Bei regulärer Ausführung folgt dieses Ergebnis.

Kopierbare Transkription des Codes/Protokolls in der Abbildung (Quelltext beibehalten; keine Zusicherung unmittelbarer Ausführbarkeit):
08-17 11:54:12.841 2790 2790 I mpi_enc_utils: cmd parse result:
08-17 11:54:12.841 2790 2790 I mpi_enc_utils: input file name: /data/ocrean.yuv
08-17 11:54:12.841 2790 2790 I mpi_enc_utils: output file name: /data/out.h264
08-17 11:54:12.841 2790 2790 I mpi_enc_utils: width : 1920
08-17 11:54:12.841 2790 2790 I mpi_enc_utils: height : 1080
08-17 11:54:12.841 2790 2790 I mpi_enc_utils: format : 0
08-17 11:54:12.841 2790 2790 I mpi_enc_utils: type : 7
08-17 11:54:12.842 2790 2791 I mpi_enc_test: mpi_enc_test start
08-17 11:54:12.844 2790 2791 I mpp_info: mpp version: 6cc173d1 author: Ding Wei 2022-08-29 [hal_avsd]: Fix crash on avsd ref err path
08-17 11:54:12.844 2790 2791 I mpi_enc_test: 0xe9a806d0 encoder test start w 1920 h 1080 type 7
08-17 11:54:12.846 2790 2792 I mpp_enc : MPP_ENC_SET_RC_CFG bps 7776000 [486000 : 8262000] fps [30:30] gop 60
08-17 11:54:12.846 2790 2792 I h264e_api_v2: MPP_ENC_SET_PREP_CFG w:h [1920:1080] stride [1920:1080]
08-17 11:54:12.846 2790 2792 I mpp_enc : send header for set cfg change input/format/color
08-17 11:54:12.846 2790 2792 I mpp_enc : mode vbr bps [486000:7776000:8262000] fps fix [30/1] -> fix [30/1] gop i [60] v [0]
08-17 11:54:12.867 2790 2791 I mpi_enc_test: chn 0 encoded frame 0 size 218616 qp 11
08-17 11:54:12.878 2790 2791 I mpi_enc_test: chn 0 encoded frame 1 size 53379 qp 16
08-17 11:54:12.889 2790 2791 I mpi_enc_test: chn 0 encoded frame 2 size 44736 qp 18
08-17 11:54:12.899 2790 2791 I mpi_enc_test: chn 0 encoded frame 3 size 46086 qp 19
08-17 11:54:12.910 2790 2791 I mpi_enc_test: chn 0 encoded frame 4 size 49246 qp 19
08-17 11:54:12.921 2790 2791 I mpi_enc_test: chn 0 encoded frame 5 size 44351 qp 21
08-17 11:54:12.932 2790 2791 I mpi_enc_test: chn 0 encoded frame 6 size 45968 qp 21
08-17 11:54:12.945 2790 2791 I mpi_enc_test: chn 0 encoded frame 7 size 39819 qp 22
08-17 11:54:12.956 2790 2791 I mpi_enc_test: chn 0 encoded frame 8 size 40786 qp 22
08-17 11:54:12.968 2790 2791 I mpi_enc_test: chn 0 encoded frame 9 size 29039 qp 22
08-17 11:54:12.993 2790 2791 I mpi_enc_test: chn 0 encoded frame 10 size 30438 qp 23
08-17 11:54:13.017 2790 2791 I mpi_enc_test: chn 0 encoded frame 11 size 38220 qp 23
08-17 11:54:13.042 2790 2791 I mpi_enc_test: chn 0 encoded frame 12 size 35324 qp 24
08-17 11:54:13.068 2790 2791 I mpi_enc_test: chn 0 encoded frame 13 size 36299 qp 24
08-17 11:54:13.093 2790 2791 I mpi_enc_test: chn 0 encoded frame 14 size 36672 qp 24
08-17 11:54:13.120 2790 2791 I mpi_enc_test: chn 0 encoded frame 15 size 36288 qp 25
08-17 11:54:13.147 2790 2791 I mpi_enc_test: chn 0 encoded frame 16 size 30886 qp 26
08-17 11:54:13.173 2790 2791 I mpi_enc_test: chn 0 encoded frame 17 size 31390 qp 25
08-17 11:54:13.199 2790 2791 I mpi_enc_test: chn 0 encoded frame 18 size 32035 qp 26
08-17 11:54:13.223 2790 2791 I mpi_enc_test: chn 0 encoded frame 19 size 30808 qp 26
08-17 11:54:13.248 2790 2791 I mpi_enc_test: chn 0 encoded frame 20 size 32234 qp 26
08-17 11:54:13.272 2790 2791 I mpi_enc_test: chn 0 encoded frame 21 size 31154 qp 26
08-17 11:54:13.297 2790 2791 I mpi_enc_test: chn 0 encoded frame 22 size 30745 qp 26
08-17 11:54:13.323 2790 2791 I mpi_enc_test: chn 0 encoded frame 23 size 32082 qp 26
08-17 11:54:13.349 2790 2791 I mpi_enc_test: chn 0 encoded frame 24 size 31948 qp 26
08-17 11:54:13.374 2790 2791 I mpi_enc_test: chn 0 encoded frame 25 size 27847 qp 27
08-17 11:54:13.400 2790 2791 I mpi_enc_test: chn 0 encoded frame 26 size 31434 qp 27
08-17 11:54:13.427 2790 2791 I mpi_enc_test: chn 0 encoded frame 27 size 31533 qp 27
08-17 11:54:13.453 2790 2791 I mpi_enc_test: chn 0 encoded frame 28 size 31289 qp 27
08-17 11:54:13.478 2790 2791 I mpi_enc_test: chn 0 encoded frame 29 size 32659 qp 27
08-17 11:54:13.480 2790 2790 I mpi_enc_test: chn 0 encode 30 frames time 628 ms delay 4 ms fps 47.72 bps 10265048
08-17 11:54:13.481 2790 2790 I mpi_enc_test: mpi_enc_test average frame rate 47.72
Die bereits beim Decoder-Demo beschriebenen Logeinführungen lässt die Quelle hier aus.
I mpp_enc: MPP_ENC_SET_RC_CFG bps 7776000 [486000:8262000] fps [30:30] gop 60
Standard-Bitratenparameter des Encoders: Ziel 7.8 Mbps, untere Referenz 0.5 Mbps und obere Referenz 8.3 Mbps. Standard-Ein-/Ausgangsbildrate 30, GOP-Größe 60.
I mpi_enc_test: chn 0 encoded frame 0 size 218616 qp 11
Die mpi_enc_test-Ausgabe zeigt reguläres Codieren; die Bitstreamgröße eines Frames beträgt 0.2 M, der Qualitätsparameter 11.
I mpi_enc_test: chn 0 encode 30 frames time 628 ms delay 4 ms fps 47.72 bps 10265048
Ausgabe mpi_enc_test: Laut Quellbeispiel codierte der Encoder 30 Frames in 628 ms; Erstframelatenz 4 ms, Bildrate 47.72 fps und Bitrate 10.2 Mbps. Dies sind Quellwerte, kein ArmSoM-Test.
I mpi_enc_test: mpi_enc_test average frame rate 47.72
Die mpi_enc_test-Ausgabe nennt eine mittlere Encoder-Bildrate von 47.72 fps.
Encoder-Steuerparameter lassen sich auch über Umgebungsvariablen konfigurieren. Unter Android lautet der Befehl:
setprop <control parameter> value
Unter Linux werden die Umgebungsvariablen mit folgendem Befehl gesetzt:
export <control parameter>=value
Die zugehörigen Beschreibungen folgen.
| Steuerparameter | Typ | Beschreibung |
|---|---|---|
| constraint_set | RK_U32 | Nur für H.264-Bitströme wirksam; entspricht constraint_set0_flag bis constraint_set5_flag in der Syntax. Das Erzwingungskennzeichen force_flag und der erzwungene Constraint-Parameter constraint_force werden im Format | 00 | force_flag | 00 | constraint_force | gespeichert. Nur die unteren 6 Bits sind gültig; sie entsprechen constraint_set5_flag bis constraint_set0_flag. Bei force_flag gleich 1 wird das entsprechende constraint_set im Encoder konfiguriert. |
| split_mode | RK_U32 | Aufteilungsmodus des Encoders. 0: keine Aufteilung. 1: Aufteilung nach Slice-Größe. 2: Aufteilung nach Anzahl von Makroblöcken oder CTUs. |
| split_arg | RK_U32 | split_arg wirkt nur bei aktiviertem Encoder-split_mode. Bei byteweiser Aufteilung ist dies das Byte-Limit je Slice; bei CTU-Aufteilung das CTU-Limit je Slice. |
| split_out | RK_U32 | Ausgabemodus der Aufteilung, nur bei aktiviertem Encoder-Aufteilungsmodus wirksam. 1: Ausgabe mit geringer Verzögerung; 2: Ausgabe von Segmentinformationen. Im Modus mit geringer Verzögerung gibt der Encoder jedes Slice verzögerungsarm aus; im Segmentinformationsmodus kapselt er Segmentinformationen für jedes Slice. |
| sei_mode | RK_U32 | SEI-Schreibmodus. 0: kein SEI schreiben; 1: sequenzweises Schreiben; 2: frameweises Schreiben. Im Sequenzmodus gibt es nur ein SEI je GOP; im Framemodus wird bei geänderten SEI-Informationen auch vor jedem Frame SEI eingefügt. |
| gop_mode | RK_U32 | gop-Referenzmodus. Ist die Umgebungsvariable gop_mode nicht gesetzt, wird anhand des Befehlsparameters konfiguriert; andernfalls anhand der Umgebungsvariable. |
| osd_enable | RK_U32 | OSD-Palette aktivieren. |
| osd_mode | RK_U32 | Modus der OSD-Palette, nur nach Aktivierung der Palette wirksam. 0: Standardkonfiguration; 1: benutzerdefinierte Konfiguration. |
| roi_enable | RK_U32 | ROI-Test aktivieren und die plattformspezifische Standardkonfiguration von roi_type verwenden. |
| roi_type | RK_U32 | Konfiguration von roi_type erzwingen. |
| user_data_enable | RK_U32 | Benutzerdaten aktivieren. |
Der Encoder-Democode steht in test/mpi_enc_test.c. Laut Quelle verwendet die aktuelle Demo enqueue/dequeue; dies soll später geändert werden.
4.3 Hilfsprogramme
MPP stellt Hilfsprogramme für Unit-Tests der Hardware-/Softwareplattform und der MPP-Bibliothek selbst bereit.
mpp_info_test
Versionsinformationen der MPP-Bibliothek lesen und ausgeben. Bei einer Problemmeldung kann diese Ausgabe beigefügt werden.
mpp_buffer_test
Prüft die reguläre Funktion des Kernel-Speicherallokators.
mpp_mem_test
Prüft die reguläre Funktion des Speicherallokators der C-Bibliothek.
mpp_runtime_test
Prüft bestimmte Hardware- und Softwarebedingungen der Laufzeitumgebung.
mpp_platform_test
Liest die Chipplattforminformationen und prüft deren Plausibilität.
5. MPP-Bibliothek bauen und verwenden
5.1 Quellcode herunterladen
Offizielle Quellcodeadresse von MPP: https://github.com/rockchip-linux/mpp
Die Veröffentlichungsbranch heißt release, die Entwicklungsbranch develop; laut Quelle ist develop die Standardbranch.
Downloadbefehl: git clone https://github.com/rockchip-linux/mpp.git
5.2 Kompilierung
Für den Build wird cmake oberhalb Version 2.8.12 benötigt; empfohlen wird 3.x. Die Quelle nennt eine erfolgreiche Prüfung mit cmake-3.28. Neuere Versionen können mehr Warnungen erzeugen. Dies ist eine Quellangabe, keine Prüfung dieser Arbeit.
5.2.1 Cross-Kompilierung für Android
Zum Bau der Android-Bibliothek ist eine NDK-Umgebung erforderlich; das Standardskript verwendet android-ndk-r16b. Die Quelle nennt Prüfungen mit android-ndk-r16b und android-ndk-r25c: erstere für SDKs unter Android 14, letztere für SDKs über Android 14. Der Grenzfall Android 14 wird nicht gesondert definiert.
Beispiel für die r16b-NDK:
Der Downloadpfad der r16b-NDK steht in build/android/ndk_links.md des Quellverzeichnisses.
Die heruntergeladene NDK nach /home/pub/ndk/android-ndk-r16b entpacken oder den ANDROID_NDK-Pfad in build/android/env_setup.sh manuell anpassen.
Nach build/android/arm/ wechseln, make-Android.bash zur Makefile-Erzeugung ausführen und anschließend laut Quelltext make –j16 verwenden. Vor j16 steht in der Quelle ein langer Strich statt eines ASCII-Bindestrichs; vor Ausführung den Parameter mit dem Buildskript abgleichen.
5.2.2 Kompilierung unter Unix/Linux
Zunächst die Toolchain in build/linux/arm/arm.linux.cross.cmake konfigurieren, dann mit make-Makefiles.bash per cmake das Makefile erzeugen und abschließend laut Quelle make –j16 ausführen. Das lange Strichzeichen des Quellparameters nicht ungeprüft als validierten Befehl kopieren.
MPP unterstützt auch den direkten Build unter Debian auf dem Entwicklungsboard.
6. Häufig gestellte Fragen
F: Beim Aarch64-Build erscheint undefined reference to system_property_get.
A: Laut Quelle handelt es sich um ein Problem der Google-64bit-NDK: In libc.so fehlen bestimmte Symboldefinitionen. Siehe folgenden Problemverweis:
Quell-URL (Zeilenumbruch anhand der vollständigen Adresse des chinesischen Originals zusammengefügt): http://stackoverflow.com/questions/28413530/api-to-get-android-system-properties-is-removed-in-arm64-platforms
Quelllösung: MPP enthält die entsprechende libc.so unter build/android/aarch64/fix/. In path_to_ndk/platforms/android-21/arch-arm64/usr/lib/ kopieren und neu kompilieren. Dies ist eine historische SDK-Lösung, keine Empfehlung, Systembibliotheken beliebiger heutiger NDKs zu ersetzen.
F: Während der Ausführung erscheint folgendes Kernel-Log. Ist dies ein Problem?
vpu_service_ioctl:1844: error: unknow vpu service ioctl cmd 40086c01
A: Laut Quelle ist diese Meldung für sich genommen kein Problem. MPP hängt vom Kerneltreiber ab und versucht verschiedene Schnittstellenversionen. Schlägt ein Versuch fehl, folgt eine andere Schnittstelle. Diese Ausgabe erscheint beim Fehlschlag einmal und kann ignoriert werden.
F: Wie analysiert man eine fehlerhafte MPP-Ausführung?
A: Zuerst das Fehlerlog analysieren. Kann ein Kernelgerät nicht geöffnet werden, die Verfügbarkeit der Hardware-Gerätekonfiguration des Videocodecs der Kernelplattform prüfen; anschließend sieht die Quelle eine Problemmeldung in redmine vor. Nach Klärung der Laufzeitumgebung interne MPP-Probleme untersuchen.
