Rockchip · AI & Linux Hub

Kameras und Video

Rockchip MPP: Medienplattform, Codec-APIs, Speicher und Fehlersuche

Vollständige MPP-V1.4.2-Referenz zu Architektur, MPI, Speicher, Dekodierung, Kodierung, Parametertabellen, Beispielen, Build und FAQ mit Originalabbildungen und Code.

· ArmSoM Editorial · Rockchip source documentation · 86 Min. Lesezeit

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:

Original-Technikabbildung, englisches PDF, Seite 7

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:

Original-Technikabbildung, englisches PDF, Seite 9

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.

Original-Technikabbildung, englisches PDF, Seite 10

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:

Original-Technikabbildung, englisches PDF, Seite 11

Abbildung 4: Normale Verwendung von MppBuffer

Pseudocode des Ablaufs:

Original-Technikabbildung, englisches PDF, Seite 11

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:

Original-Technikabbildung, englisches PDF, Seite 12

Abbildung 5: Externer Import mit MppBuffer

Der Pseudocode des Ablaufs folgt:

Original-Technikabbildung, englisches PDF, Seite 13

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:

Original-Technikabbildung, englisches PDF, Seite 14

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:

Original-Technikabbildung, englisches PDF, Seite 15

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:

Original-Technikabbildung, englisches PDF, Seite 15

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.

Original-Technikabbildung, englisches PDF, Seite 15

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.

Original-Technikabbildung, englisches PDF, Seite 16

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.

Original-Technikabbildung, englisches PDF, Seite 17

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.

Original-Technikabbildung, englisches PDF, Seite 18

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;

Original-Technikabbildung, englisches PDF, Seite 18

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.

Original-Technikabbildung, englisches PDF, Seite 19

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.

Original-Technikabbildung, englisches PDF, Seite 19

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.

Original-Technikabbildung, englisches PDF, Seite 20

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.

Original-Technikabbildung, englisches PDF, Seite 23

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.

Original-Technikabbildung, englisches PDF, Seite 24

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:

Original-Technikabbildung, englisches PDF, Seite 27

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.

Original-Technikabbildung, englisches PDF, Seite 29

Original-Technikabbildung, englisches PDF, Seite 29

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.

Original-Technikabbildung, englisches PDF, Seite 30

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.

Original-Technikabbildung, englisches PDF, Seite 30

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.

Original-Technikabbildung, englisches PDF, Seite 31

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.

Original-Technikabbildung, englisches PDF, Seite 31

Abbildung 16: Schema der vollständig externen Speicherzuweisung

Original-Technikabbildung, englisches PDF, Seite 32

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.

Original-Technikabbildung, englisches PDF, Seite 36

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.

Original-Technikabbildung, englisches PDF, Seite 38

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;

Original-Technikabbildung, englisches PDF, Seite 38

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;

Original-Technikabbildung, englisches PDF, Seite 38

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;

Original-Technikabbildung, englisches PDF, Seite 38

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.

Original-Technikabbildung, englisches PDF, Seite 39

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;

Original-Technikabbildung, englisches PDF, Seite 39

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.

Original-Technikabbildung, englisches PDF, Seite 41

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:

Original-Technikabbildung, englisches PDF, Seite 42

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.

Original-Technikabbildung, englisches PDF, Seite 44

Original-Technikabbildung, englisches PDF, Seite 45

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.

Original-Technikabbildung, englisches PDF, Seite 47

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.

Original-Technikabbildung, englisches PDF, Seite 48

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.

Original-Technikabbildung, englisches PDF, Seite 50

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.

Original-Technikabbildung, englisches PDF, Seite 53

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.

Dieses Thema entdecken → · Lernpfade →