1

NAL > H264 変換を許可する優れたオープン ソース Java lib を使用したことがある人はいますか?

多くのライブラリを見てきましたが、それらのほとんどは不完全であるか、非常に使いにくいものです (ドキュメントがないなど)。

私が望むのは、NAL ペイロードを渡して、実際の H.264 生ビデオを取得することです。次のステップは、これを MP4 コンテナーに入れることです。

4

2 に答える 2

2

コメントの議論から、あなたの質問を言い換えて、2 つに分けます。

純粋な Java で H264 RTP パケットから NAL ユニットを抽出し、それらを Annex B H264 ファイルにダンプしたいと考えています。

それ、どうやったら出来るの?図書館はありますか?

これらのパケットのペイロードはRFC3984で指定されています。

これをすぐに実行できるJavaライブラリは知りません。ただし、パッケージ タイプがインターリーブされていない限り、実装はかなり単純です。

RFC3984 では 3 つのパッケージ タイプが許可されています

  • シングル NAL ユニット モード
  • 非インターリーブ モード
  • インターリーブ モード

パケット ソースがシングル NAL ユニット モードまたは非インターリーブ モードで送信している限り、パケットからそれ以上処理せずに NAL ユニットを抽出し、0x00,0x00,0x00,0x01 を区切りとしてディスクにダンプできます。

パッケージ タイプがインターリーブされている場合は、NAL を調べてデコード順になるように並べ替える必要があるため、より多くの作業を行う必要があります。

生のAnnex B H264ファイルを純粋なJavaのMP4コンテナーに多重化します

私のmp4parserプロジェクトを使用して、Annex B 形式から MP4 を生成できます。H264Exampleを見てください- 使い方のアイデアが得られるはずです。

于 2012-08-14T16:46:07.747 に答える
0

JCodec ( http://jcodec.org ) のサンプル で見つけたものは次のとおりです。

public class AVCMP4Mux {
    private static AvcCBox avcC;

    public static void main(String[] args) throws Exception {
        if (args.length < 2) {
            System.out.println("Syntax: <in.264> <out.mp4>\n" + "\tWhere:\n"
                    + "\t-q\tLook for stream parameters only in the beginning of stream");
            return;
        }

        File in = new File(args[0]);
        File out = new File(args[1]);

        SeekableByteChannel file = writableFileChannel(out);
        MP4Muxer muxer = new MP4Muxer(file);
        CompressedTrack track = muxer.addTrackForCompressed(TrackType.VIDEO, 25);

        mux(track, in);

        muxer.writeHeader();

        file.close();
    }

    private static void mux(CompressedTrack track, File f) throws IOException {
        MappedH264ES es = new MappedH264ES(NIOUtils.map(f));

        ArrayList<ByteBuffer> spsList = new ArrayList<ByteBuffer>();
        ArrayList<ByteBuffer> ppsList = new ArrayList<ByteBuffer>();
        Packet frame = null;
        while ((frame = es.nextFrame()) != null) {
            ByteBuffer wrap = frame.getData().duplicate();
            H264Utils.encodeMOVPacket(wrap, spsList, ppsList);
            MP4Packet pkt = new MP4Packet(new Packet(frame, wrap), frame.getPts(), 0);
            System.out.println(pkt.getFrameNo());
            track.addFrame(pkt);
        }
        addSampleEntry(track, es.getSps(), es.getPps());
    }

    private static void addSampleEntry(CompressedTrack track, SeqParameterSet[] spss, PictureParameterSet[] ppss) {
        SeqParameterSet sps = spss[0];
        Size size = new Size((sps.pic_width_in_mbs_minus1 + 1) << 4, getPicHeightInMbs(sps) << 4);

        SampleEntry se = MP4Muxer.videoSampleEntry("avc1", size, "JCodec");

        avcC = new AvcCBox(sps.profile_idc, 0, sps.level_idc, write(spss), write(ppss));
        se.add(avcC);
        track.addSampleEntry(se);
    }

    private static List<ByteBuffer> write(PictureParameterSet[] ppss) {
        List<ByteBuffer> result = new ArrayList<ByteBuffer>();
        for (PictureParameterSet pps : ppss) {
            ByteBuffer buf = ByteBuffer.allocate(1024);
            pps.write(buf);
            buf.flip();
            result.add(buf);
        }
        return result;
    }

    private static List<ByteBuffer> write(SeqParameterSet[] spss) {
        List<ByteBuffer> result = new ArrayList<ByteBuffer>();
        for (SeqParameterSet sps : spss) {
            ByteBuffer buf = ByteBuffer.allocate(1024);
            sps.write(buf);
            buf.flip();
            result.add(buf);
        }
        return result;
    }
}

ここから取得しました:https://github.com/jcodec/jcodec/blob/master/samples/main/java/org/jcodec/samples/mux/AVCMP4Mux.java

于 2013-05-22T06:21:43.440 に答える