Android Software Decoder (OMX.google.h264.decoder) Fails to decode H264 video -


i experiencing issues when trying extract , decode h264 video using androids software decoder (omx.google.h264.decoder). issue seems span multiple devices.

this video playback fine using nexus 5 hardware decoder (omx.qcom.video.decoder.avc).

the sample code below exhibits issue , standard example of using android mediacodec , mediaextractor classes.

the exception illegal state exception when first buffer passed decoder.

the video 720x480 20fps encoded @ baseline profile should meet compatibility guidelines.

here video sample accompany code

i appreciate guidance on getting software video decoder correctly working h264 video.

public void domp4test() {     try     {         //string filename = "webserver_h264.mp4";         string filename = "toodee-720p.mp4";         mediaextractor extractor = new mediaextractor();         extractor.setdatasource(constants.rootdirectory + file.separator + filename);           mediacodec decoder = null;          (int = 0; < extractor.gettrackcount(); i++)         {             mediaformat format = extractor.gettrackformat(i);             string mime = format.getstring(mediaformat.key_mime);             if (mime.startswith("video/"))             {                 extractor.selecttrack(i);                 decoder = mediacodec.createbycodecname("omx.google.h264.decoder");                 // decoder = mediacodec.createdecoderbytype("omx.qcom.video.decoder.avc"); // working decoder type                 decoder.configure(format, m_surface, null, 0);                 break;             }         }          if (decoder == null)         {             log.e("decodeactivity", "can't find video info!");             return;         }          decoder.start();          bytebuffer[] inputbuffers = decoder.getinputbuffers();         bytebuffer[] outputbuffers = decoder.getoutputbuffers();         bufferinfo info = new bufferinfo();         boolean iseos = false;         long startms = system.currenttimemillis();          while (!thread.interrupted())         {             if (!iseos)             {                 int inindex = decoder.dequeueinputbuffer(10000);                 if (inindex >= 0)                 {                     bytebuffer buffer = inputbuffers[inindex];                     int samplesize = extractor.readsampledata(buffer, 0);                     if (samplesize < 0)                     {                         log.d("decodeactivity", "inputbuffer buffer_flag_end_of_stream");                         decoder.queueinputbuffer(inindex, 0, 0, 0, mediacodec.buffer_flag_end_of_stream);                         iseos = true;                     }                     else                     {                         int flags = 0;// extractor.getsampleflags();                         decoder.queueinputbuffer(inindex, 0, samplesize, extractor.getsampletime(), flags);                         extractor.advance();                     }                 }             }              int outindex = decoder.dequeueoutputbuffer(info, 10000);             switch (outindex)             {             case mediacodec.info_output_buffers_changed:                 log.d("decodeactivity", "info_output_buffers_changed");                 outputbuffers = decoder.getoutputbuffers();                 break;             case mediacodec.info_output_format_changed:                 log.d("decodeactivity", "new format " + decoder.getoutputformat());                 break;             case mediacodec.info_try_again_later:                 log.d("decodeactivity", "dequeueoutputbuffer timed out!");                 break;             default:                 bytebuffer buffer = outputbuffers[outindex];                 log.v("decodeactivity", "we can't use buffer render due api limit, " + buffer);                  // use simple clock keep video fps, or                 // video                 // playback fast                 while (info.presentationtimeus / 1000 > system.currenttimemillis() - startms)                 {                     try                     {                         thread.sleep(10);                     }                     catch (interruptedexception e)                     {                         e.printstacktrace();                         break;                     }                 }                 decoder.releaseoutputbuffer(outindex, true);                 break;             }              if ((info.flags & mediacodec.buffer_flag_end_of_stream) != 0)             {                 log.d("decodeactivity", "outputbuffer buffer_flag_end_of_stream");                 break;             }         }            decoder.stop();           decoder.release();           extractor.release();     }     catch (exception e)     {         e.printstacktrace();     }    } 

looking @ video ffprobe looks high profile rather base profile:

stream #0:0(eng): video: h264 (high) (avc1 / 0x31637661), yuv420p, 720x480 [sar 1:1 dar 3:2], 515 kb/s, 24.66 fps, 1000k tbr, 1000k tbn, 2000k tbc (default)

as aside, video seems play display black blank screen when playing on couple of browsers when tried on laptop.


Comments