2013-02-15 4 views
5

Ich habe versucht, libstagefright zu verwenden, um h264 komprimierte Bilder zu dekodieren. Ich habe keine MP4-Datei, stattdessen möchte ich Frame für Frame decodieren. Ich habe die Probe von a link untersucht. Dieses Beispiel verwendet ffmpeg, um MP4-Datei zu analysieren. und benutze ffmpegs avcodeccontext, den er gesetzt hat, und finde die erforderlichen Metadaten. Jetzt möchte ich kKeyAVCC, kKeyWidth, kKeyHeight, kKeyIsSyncFrame und kKeyTime setzen. Ich bin über jeden dieser Parameter nicht klar. Alles was ich wissen will ist, ob all diese Parameter gesetzt werden müssen. Welchen Zweck haben diese Parameter und was wird für die Metadaten für die Frame-für-Frame-Decodierung in sie eingestellt? Wenn ich kKeyTime nicht festlege, stürzt omxcodec beim Lesen des Mediabuffers ab. Und wenn ich beim Lesevorgang Erfolg habe, bekomme ich nicht die Metadaten-Werte, die ich in MediaBuffers abgeleiteter Lesemethode eingestellt habe. Ich bekomme Video-Dimesionen des Frames und den Fehlercode von INFO_FORMAT_CHANGED.Um HW-Decoder in Android über libstagefright zu verwenden, was für kKeyAVCC in Metadaten für Frame-Basis-Decodierung anstelle von MP4-Wiedergabe festlegen?

Antwort

9

Wenn ein neuer Codec erstellt wird, werden die Metadaten als Teil der OMXCodec::Create-Methode vom Parser an den Decoder übergeben. Ich nehme an, in Ihrer Implementierung hätten Sie darauf geachtet, die Metadaten in MetaData Format übergeben, wie in der Plain Vanilla android Implementierung angegeben.

Zum Beispiel finden Sie unter AwesomePlayer::initVideoDecoder in dem mVideoTrack->getFormat() aufgerufen wird, um die Metadaten der Videospur zu erhalten. Bitte beachten Sie, dass dies nicht Teil einer MediaBuffer ist, sondern als separates Objekt übergeben wird. Wenn der Decoder erstellt wurde, wird configureCodec aufgerufen. Bei dieser Methode liest OMXCodec verschiedene Konfigurationsparameter, um den Decoder zu initialisieren.

kKeyAVCC entspricht dem Codec Specific Data oder csd, die im wesentlichen die SPS und PPS des zugrunde liegenden H.264 Strom.

kKeyWidth und kKeyHeight entspricht der width und height des Videoframes. Zur Initialisierung des Decoders können Sie weitere zusätzliche Parameter einstellen. Wenn Sie beispielsweise einen spezifischen colorFormat für den Ausgang des Decoders festlegen, können Sie denselben über kKeyColorFormat festlegen.

Sobald der Decoder erstellt wurde, müssen Sie die einzelnen Frames durch die Standard-Schnittstellen openmax übergeben. Der Decoder wird mit dem Aufruf der Methode OMXCodec::read gestartet, die die Eingangs- und Ausgangspuffer überfluten wird.

Der Eingabepuffer wird über die OMXCodec::drainInputBuffer-Methode gefüllt, die eine MediaBuffer vom Parser-Modul liest (was in Ihrem Fall Ihr spezifisches Modul ist). Der Inhalt der MediaBuffer wird in den Puffer kopiert, der auf der input port der Komponente OMX aufgefüllt ist. Zusammen mit diesen Daten wird auch der timestamp dieses Puffers übergeben. Die Zeitstempelinformationen werden über den Parameter kKeyTime gelesen, der zusammen mit der MediaBuffer übergeben wird.

Daher müssen Sie für jeden Rahmen, der in einer MediaBuffer übergeben wird, sicherstellen, dass auch ein gültiger timestamp an den zugrunde liegenden Decoder übergeben wird, der auf dem Ausgabeport des Decoders reflektiert wird.

In Ihrer Frage hatten Sie über kKeyIsSyncFrame abgefragt. Dieses Flag wird durch einen Encoder als Teil des FillBufferDone Callbacks gesetzt, d.h.Wenn ein Codierer einen Schlüsselframe wie IDR frame codiert, dann übermittelt er diese Information über dieses spezifische Flag als Teil des Rückrufs am Ausgabeport des Codierers. Für die Dekodierung ist dies nicht relevant.

Wenn Sie weitere Protokolle mit aktivierten OMXCodec Protokollen veröffentlichen können, ist es möglicherweise einfacher, eine genauere Antwort anzugeben.

P.S. Im android-Framework gibt es ein Befehlszeilenprogramm namens Stagefright, das einen Parser und einen Dekodierer erstellt und eine Dekodierung der Befehlszeile ohne Rendering durchführt. Dies könnte eine gute Referenz für Sie sein, um Ihren eigenen Parser zu pluginieren.

+0

Zunächst einmal vielen Dank für die ausführliche Antwort. Sie haben sehr gute Informationen zur Verfügung gestellt. Ich verbinde libstagfight.so über android.mk in meinem Projekt. Ich muss alle entsprechenden Include-Header von Android-Quelle einschließen. Ich habe zwei Klassen geschrieben, CustomMediaSource und CustomDecoder. CustomMediaSource wird von MediaSource abgeleitet und implementiert die Lesemethode, während ich in CustomDecoder die Methode OMXCodec :: Create aufruft. Nun, mein Zweifel ist, ob LibstageFright für alle Android-Geräte stabil ist. Ich meine, kann es laut Hersteller wie TI, Qualcom etc. sehr gut gehen? – sam18

+0

Aus einer 'API'-Perspektive ist die libstagefright-Bibliothek die gleiche, unabhängig von den Anbietern. Wenn Sie sich jedoch einige Leistungszahlen ansehen, könnte es für den Hersteller-SoC spezifische Anpassungen geben. Ich sage nicht, dass dies immer der Fall sein wird, aber wahrscheinlich ist. Wenn Sie keinen Zugriff auf Quellen haben, können Sie möglicherweise nicht unterscheiden. – Ganesh

+0

Gut Danke. Ich möchte eine plattformunabhängige Android-App entwickeln. Daher wird es wichtig, stabile Apis zu bevorzugen. Also, wie Sie gesagt haben, werde ich libstagefright.so in allen Android-Handys finden und es wird die gleichen API-Strukturen haben und ich kann Media Source ableiten und die abgeleitete Klasseninstanz für OMXCodec :: Create-Methode verwenden. . . Recht? – sam18

Verwandte Themen