is the a way for solving android h264 decoder delay?

Viewed 256

I'm working on video streaming application client that receive h264 frames by 1 frame/sec rate. The very first frame is I frame and all following frames are P frames. Frames are encoded using openh264 with realtime setting and are decode'able without need for next P Frame(s) (I'm decoding frames correctly on time on windows application using openh264 DecodeFrameNoDelay function). What I'm seeing on Android decoder side is decoder wont produce output unless it buffer next 4 or 5 P frames and it cause my application to have huge and unacceptable delay in result. I'm pretty sure there is no need for next frames at-least in my case. What I've tried: I tried feeding the decoder with some meaningless h264 nals and could decrease the delay from 3 to 1 seconds but it doesn't work all times and if we do it more codec will encounter error and stop finally.

byte[] frame = h264Data.toByteArray();
// Now we need to give it to the Codec to decode into the surface

for (int i = 0; i < 2; i++) 
{
  // Get the input buffer from the decoder
  // Pass -1 here as here we don't have a playback time reference
  int inputIndex = m_codec.dequeueInputBuffer(-1);
  
  // If  the buffer index is valid use the buffer
  if (inputIndex >= 0) 
  {
    ByteBuffer buffer;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP){
      buffer = m_codec.getInputBuffer(inputIndex);
    } else {
      ByteBuffer[] bbuf = m_codec.getInputBuffers();
      buffer = bbuf[inputIndex];
    }
    buffer.put(frame);

    // tell the decoder to process the frame
    m_codec.queueInputBuffer(inputIndex, 0, frame.length, 0, 0);
    
    //Now filling the frame with effectless h264 NAL to deceive decoder
    frame = new byte[]{(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x0C, (byte) 0x00, (byte) 0x00, (byte) 0x00};
  }
  MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
  int outputIndex = m_codec.dequeueOutputBuffer(info, 0);
  if (outputIndex >= 0) {
    m_codec.releaseOutputBuffer(outputIndex, true);
  }
}
0 Answers
Related