android - Incorrect decoding of H264 video stream on Nexus devices -
i'm trying use android mediacodec class decode h264 video stream of remote camera. code is:
public class remotecamera { public interface oncameralistener { void onconnected(); void onfailureconnection(); void ondisconnected(); void onready(); } private static final int max_nal_len = 1024 * 1024; private static final string tag = "remotecamera"; private outputthread moutputthread; private websocketmanager mwebsocketmanager; private oncameralistener moncameralistener; private int msearchstate = 0; private byte[] mnaldata; private int mnaldatapos; private mediacodec mdecoder; private mediaformat mformat; private surfaceview msurfaceview; private mediacodec.bufferinfo minfo = new mediacodec.bufferinfo(); private boolean miswaitingforsps = true; public remotecamera(final surfaceview surfaceview, final string wss) { msurfaceview = surfaceview; mwebsocketmanager = new websocketmanager(wss); mwebsocketmanager.setwslistener(new websocketmanager.onwslistener() { @override public void onopen() { if (moncameralistener != null) { moncameralistener.onconnected(); } } @override public void onclosed() { if (moncameralistener != null) { moncameralistener.ondisconnected(); } } @override public void onfailure() { if (moncameralistener != null) { moncameralistener.onfailureconnection(); } } @override public synchronized void onmessage(final bytestring bytes) { final bytebuffer bb = bytebuffer.wrap(bytes.tobytearray()); if (miswaitingforsps) { if (isspsunit(bb)) { miswaitingforsps = false; if (moncameralistener != null) { moncameralistener.onready(); } } else { return; } } parsedatagram(bb.array(), bytes.size()); } }); mnaldata = new byte[max_nal_len]; mnaldatapos = 0; try { mdecoder = mediacodec.createdecoderbytype("video/avc"); } catch (exception e) { log.d(tag, e.tostring()); return; } mformat = mediaformat.createvideoformat("video/avc", 320, 240); } public void setoncameralistener(final oncameralistener cameralistener) { moncameralistener = cameralistener; } public void startstreaming() { msurfaceview.getholder().addcallback(new surfaceholder.callback() { @override public void surfacecreated(surfaceholder surfaceholder) { try { mdecoder.configure(mformat, msurfaceview.getholder().getsurface(), null, 0); } catch (exception e) { log.d(tag, e.tostring()); return; } mwebsocketmanager.wsregister(); mdecoder.start(); moutputthread = new outputthread(); moutputthread.start(); } @override public void surfacechanged(surfaceholder surfaceholder, int i, int i1, int i2) { } @override public void surfacedestroyed(surfaceholder surfaceholder) { } }); } private void feeddecoder(byte[] n, int len) { (; ; ) { try { int inputbufferindex = mdecoder.dequeueinputbuffer(0); if (inputbufferindex >= 0) { final bytebuffer inputbuffer = mdecoder.getinputbuffer(inputbufferindex); inputbuffer.put(n, 0, len); mdecoder.queueinputbuffer(inputbufferindex, 0, len, system.currenttimemillis(), 0); break; } } catch (exception e) { log.d(tag, e.tostring()); } } } private void parsedatagram(byte[] p, int plen) { try { (int = 0; < plen; ++i) { mnaldata[mnaldatapos++] = p[i]; if (mnaldatapos == max_nal_len - 1) { mnaldatapos = 0; } switch (msearchstate) { case 0: case 1: case 2: if (p[i] == 0) msearchstate++; else msearchstate = 0; break; case 3: if (p[i] == 1) { mnaldata[0] = 0; mnaldata[1] = 0; mnaldata[2] = 0; mnaldata[3] = 1; feeddecoder(mnaldata, mnaldatapos - 4); mnaldatapos = 4; } msearchstate = 0; break; default: break; } } } catch (exception e) { log.d(tag, e.tostring()); } } private boolean isspsunit(final bytebuffer unit) { return unit.get(4) == 0x67; } private class outputthread extends thread { @override public void run() { while (true) { try { int outputbufferindex = mdecoder.dequeueoutputbuffer(minfo, 10); if (outputbufferindex >= 0) { mdecoder.releaseoutputbuffer(outputbufferindex, true); } } catch (exception e) { log.d(tag, e.tostring()); } } } }
i tested code on sony xperia z5 compact , yota phone 2, , works fine on these devices. picture got sony really good. tried video streamer on nexus 9 , nexus 7 devices, looks row moving top bottom. there no correct output on nexus devices: nexus results.
i know depends on native android media codec, should resolve problem , able show video on devices?
do not pass 0x00 0x00 0x00 0x01
nalu start code decoder.
Comments
Post a Comment