是否有人使用过良好的开源Java库,允许NAL> H264转换?
我见过很多lib,但大多数都不完整或很难使用(没有文档等)。
我想要的是传递NAL有效载荷并获得实际的H.264原始视频。下一步是将它放入MP4容器中。
答案 0 :(得分:2)
从评论中的讨论中我重新提出你的问题并将其分成两部分:
我该怎么做?有图书馆吗?
这些数据包的有效负载在RFC3984中指定。
我不知道任何开箱即用的Java库。但只要包装类型不是交错的,实现就相当简单:
RFC3984允许三种包装类型
只要您的数据包源以单NAL单元模式或非交错模式发送,您就可以从数据包中提取NAL单元而无需进一步处理,并将它们转储到磁盘,并将0x00,0x00,0x00,0x01作为分隔符他们。
如果包装类型是交错的,那么您需要投入更多的工作,因为您必须查看NAL并将它们重新排序为解码顺序。
您可以使用我的mp4parser项目从附件B格式生成MP4。看看H264Example - 应该让您了解如何使用它。
答案 1 :(得分: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