Mit MediaCodec zu retten Reihe von Bildern, die als Video

Ich versuche, mit MediaCodec zum speichern einer Serie von Bildern, gespeichert als Byte-Arrays in eine Datei zu einer video-Datei. Ich habe getestet, diese Bilder auf einer SurfaceView (Sie spielen in der Serie) und ich Sie sehen kann, in Ordnung. Ich habe mir viele Beispiele mit MediaCodecund hier ist, was ich verstehe (bitte korrigiert mich wenn ich falsch Liege):

Bekommen InputBuffers von MediaCodec Objekt -> füllen Sie es mit Ihrem Rahmen ist
Bild-Daten -> Warteschlange der Eingabe-Puffer -> codierte Ausgabe-Puffer ->
schreiben Sie es in eine Datei -> Erhöhung Präsentation Zeit und wiederholen Sie

Allerdings habe ich getestet, eine Menge, und ich am Ende mit einem von zwei Fällen:

  • Alle Beispiel-Projekte, die ich versuchte zu imitieren verursacht haben Media server zu sterben, wenn der Aufruf queueInputBuffer zum zweiten mal.
  • Ich habe versucht, den Aufruf codec.flush() am Ende (nach dem speichern der Puffer für die Ausgabe in Datei, obwohl keines der Beispiele, die ich gesehen habe) und der media-server nicht sterben, aber ich bin nicht in der Lage, öffnen Sie die Ausgabe-video-Datei mit media-player, so dass etwas falsch ist.

Hier ist mein code:

MediaCodec codec = MediaCodec.createEncoderByType(MIMETYPE);
        MediaFormat mediaFormat = null;
        if(CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P)){
            mediaFormat = MediaFormat.createVideoFormat(MIMETYPE, 1280 , 720);
        } else {
            mediaFormat = MediaFormat.createVideoFormat(MIMETYPE, 720, 480);
        }


        mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 700000);
        mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 10);
        mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar);
        mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
        codec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);

        codec.start();

        ByteBuffer[] inputBuffers = codec.getInputBuffers();
        ByteBuffer[] outputBuffers = codec.getOutputBuffers();
        boolean sawInputEOS = false;
        int inputBufferIndex=-1,outputBufferIndex=-1;
        BufferInfo info=null;

                    //loop to read YUV byte array from file

            inputBufferIndex = codec.dequeueInputBuffer(WAITTIME);
            if(bytesread<=0)sawInputEOS=true;

            if(inputBufferIndex >= 0){
                if(!sawInputEOS){
                    int samplesiz=dat.length;
                    inputBuffers[inputBufferIndex].put(dat);
                    codec.queueInputBuffer(inputBufferIndex, 0, samplesiz, presentationTime, 0);
                    presentationTime += 100;

                    info = new BufferInfo();
                    outputBufferIndex = codec.dequeueOutputBuffer(info, WAITTIME);
                    Log.i("BATA", "outputBufferIndex="+outputBufferIndex);
                    if(outputBufferIndex >= 0){
                        byte[] array = new byte[info.size];
                        outputBuffers[outputBufferIndex].get(array);

                        if(array != null){
                            try {
                                dos.write(array);
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }

                        codec.releaseOutputBuffer(outputBufferIndex, false);
                        inputBuffers[inputBufferIndex].clear();
                        outputBuffers[outputBufferIndex].clear();

                        if(sawInputEOS) break;
                    }
                }else{
                    codec.queueInputBuffer(inputBufferIndex, 0, 0, presentationTime, MediaCodec.BUFFER_FLAG_END_OF_STREAM);

                    info = new BufferInfo();
                    outputBufferIndex = codec.dequeueOutputBuffer(info, WAITTIME);

                    if(outputBufferIndex >= 0){
                        byte[] array = new byte[info.size];
                        outputBuffers[outputBufferIndex].get(array);

                        if(array != null){
                            try {
                                dos.write(array);
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }

                        codec.releaseOutputBuffer(outputBufferIndex, false);
                        inputBuffers[inputBufferIndex].clear();
                        outputBuffers[outputBufferIndex].clear();
                        break;
                    }
                }


            }
        }

        codec.flush();

        try {
            fstream2.close();
            dos.flush();
            dos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        codec.stop();
        codec.release();
        codec = null;

        return true;

    }

Meine Frage ist, wie bekomme ich ein funktionierendes video von einem Strom von Bildern mit MediaCodec. Was mache ich falsch?

Andere Frage (wenn ich nicht zu gierig ist), würde ich gerne hinzufügen einer Tonspur zu diesem video, es kann getan werden, mit MediaCodec als gut, oder muss ich FFmpeg?

Hinweis: ich weiß über MediaMux in Android 4.3 ist es allerdings keine option für mich, da meine App muss die Arbeit auf Android 4.1+.

Update
Dank fadden Antwort, ich war in der Lage zu erreichen, EOS, ohne Medien-server sterben (Obige code wird nach der änderung). Aber die Datei, die ich erhalte ist die Produktion von Kauderwelsch. Hier ein snapshot aus dem video, das ich bekommen (funktioniert nur als .h264 Datei).

Mit MediaCodec zu retten Reihe von Bildern, die als Video

Mein Input-Bild wird im format YUV-Bild (NV21 von der Kamera-Vorschau). Ich kann es nicht erhalten, werden alle spielbaren format. Ich habe versucht, alle COLOR_FormatYUV420 Formate und gleiche Kauderwelsch-Ausgang. Und ich kann immer noch nicht finden sich (mit MediaCodec) auf "audio hinzufügen".

InformationsquelleAutor der Frage Mohamed_AbdAllah | 2013-09-13

Schreibe einen Kommentar