Java video coding - h.264

I am trying to create a program that can encode and decode h.264 video so that I can edit this video. Can someone tell me how I do this if I want to make this program in java?

+4
source share
4 answers

You can use JCodec ( http://jcodec.org ).

To decode a video sequence, go to:

int frameNumber = 10000; FileChannelWrapper ch = null; try { ch = NIOUtils.readableFileChannel(new File(path to mp4)); FrameGrab frameGrab = new FrameGrab(ch); frameGrab.seek(frameNumber); Picture frame; for (int i = 0; (frame = frameGrab.getNativeFrame()) != null && i < 200; i++) { // Do something } } finally { NIOUtils.closeQuietly(ch); } 

To encode a sequence:

 public class SequenceEncoder { private SeekableByteChannel ch; private Picture toEncode; private RgbToYuv420 transform; private H264Encoder encoder; private ArrayList<ByteBuffer> spsList; private ArrayList<ByteBuffer> ppsList; private CompressedTrack outTrack; private ByteBuffer _out; private int frameNo; private MP4Muxer muxer; public SequenceEncoder(File out) throws IOException { this.ch = NIOUtils.writableFileChannel(out); // Transform to convert between RGB and YUV transform = new RgbToYuv420(0, 0); // Muxer that will store the encoded frames muxer = new MP4Muxer(ch, Brand.MP4); // Add video track to muxer outTrack = muxer.addTrackForCompressed(TrackType.VIDEO, 25); // Allocate a buffer big enough to hold output frames _out = ByteBuffer.allocate(1920 * 1080 * 6); // Create an instance of encoder encoder = new H264Encoder(); // Encoder extra data ( SPS, PPS ) to be stored in a special place of // MP4 spsList = new ArrayList<ByteBuffer>(); ppsList = new ArrayList<ByteBuffer>(); } public void encodeImage(Picture bi) throws IOException { if (toEncode == null) { toEncode = Picture.create(bi.getWidth(), bi.getHeight(), ColorSpace.YUV420); } // Perform conversion ( RGB -> YUV ) transform.transform(bi, toEncode); // Encode image into H.264 frame, the result is stored in '_out' buffer _out.clear(); ByteBuffer result = encoder.encodeFrame(_out, toEncode); // Based on the frame above form correct MP4 packet spsList.clear(); ppsList.clear(); H264Utils.encodeMOVPacket(result, spsList, ppsList); // Add packet to video track outTrack.addFrame(new MP4Packet(result, frameNo, 25, 1, frameNo, true, null, frameNo, 0)); frameNo++; } public void finish() throws IOException { // Push saved SPS/PPS to a special storage in MP4 outTrack.addSampleEntry(H264Utils.createMOVSampleEntry(spsList, ppsList)); // Write MP4 header and finalize recording muxer.writeHeader(); NIOUtils.closeQuietly(ch); } } 

And finally, to convert TO and OT images:

 public static Picture fromBitmap(Bitmap src) { Picture dst = Picture.create((int)src.getWidth(), (int)src.getHeight(), RGB); fromBitmap(src, dst); return dst; } public static void fromBitmap(Bitmap src, Picture dst) { int[] dstData = dst.getPlaneData(0); int[] packed = new int[src.getWidth() * src.getHeight()]; src.getPixels(packed, 0, src.getWidth(), 0, 0, src.getWidth(), src.getHeight()); for (int i = 0, srcOff = 0, dstOff = 0; i < src.getHeight(); i++) { for (int j = 0; j < src.getWidth(); j++, srcOff++, dstOff += 3) { int rgb = packed[srcOff]; dstData[dstOff] = (rgb >> 16) & 0xff; dstData[dstOff + 1] = (rgb >> 8) & 0xff; dstData[dstOff + 2] = rgb & 0xff; } } } public static Bitmap toBitmap(Picture src) { Bitmap dst = Bitmap.create(pic.getWidth(), pic.getHeight(), ARGB_8888); toBitmap(src, dst); return dst; } public static void toBitmap(Picture src, Bitmap dst) { int[] srcData = src.getPlaneData(0); int[] packed = new int[src.getWidth() * src.getHeight()]; for (int i = 0, dstOff = 0, srcOff = 0; i < src.getHeight(); i++) { for (int j = 0; j < src.getWidth(); j++, dstOff++, srcOff += 3) { packed[dstOff] = (srcData[srcOff] << 16) | (srcData[srcOff + 1] << 8) | srcData[srcOff + 2]; } } dst.setPixels(packed, 0, src.getWidth(), 0, 0, src.getWidth(), src.getHeight()); } 

FINALLY, when decoding, you will get a YUV frame to convert it to an RGB frame:

 Transform transform = ColorUtil.getTransform(pic.getColor(), ColorSpace.RGB); Picture rgb = Picture.create(pic.getWidth(), pic.getHeight(), ColorSpace.RGB); transform.transform(pic, rgb); 

And make sure you download the JAR with all the folders: http://jcodec.org/downloads/jcodec-0.1.3-uberjar.jar

+7
source

Get or write a class that can encode and decode the desired format. Make sure this is the service provider's interface. Add it to the application runtime class. Play it using the default JMF player. Not too sure about editing it.

+1
source
+1
source

Check out the ffmpeg and x264 library. Compile and compile these libraries. It has a very good video encoding / decoding API. If you only compile ffmpeg, you cannot encode h.264, but only decode. To encode h264, you need to compile the x264 library. http://ubuntuforums.org/showthread.php?t=786095 Pretty good tutorial. This is a C API, but you can use your own methods to call it.

Regards, and sorry for my English.

0
source

Source: https://habr.com/ru/post/1392715/


All Articles