void CDVDVideoCodecAndroidMediaCodec::ConfigureMediaCodec(void) { // setup a MediaFormat to match the video content, // used by codec during configure CJNIMediaFormat mediaformat = CJNIMediaFormat::createVideoFormat( m_mime.c_str(), m_hints.width, m_hints.height); // some android devices forget to default the demux input max size mediaformat.setInteger(CJNIMediaFormat::KEY_MAX_INPUT_SIZE, 0); // handle codec extradata if (m_hints.extrasize) { size_t size = m_hints.extrasize; void *src_ptr = m_hints.extradata; if (m_bitstream) { size = m_bitstream->GetExtraSize(); src_ptr = m_bitstream->GetExtraData(); } // Allocate a byte buffer via allocateDirect in java instead of NewDirectByteBuffer, // since the latter doesn't allocate storage of its own, and we don't know how long // the codec uses the buffer. CJNIByteBuffer bytebuffer = CJNIByteBuffer::allocateDirect(size); void *dts_ptr = xbmc_jnienv()->GetDirectBufferAddress(bytebuffer.get_raw()); memcpy(dts_ptr, src_ptr, size); // codec will automatically handle buffers as extradata // using entries with keys "csd-0", "csd-1", etc. mediaformat.setByteBuffer("csd-0", bytebuffer); } InitSurfaceTexture(); // configure and start the codec. // use the MediaFormat that we have setup. // use a null MediaCrypto, our content is not encrypted. // use a null Surface, we will extract the video picture data manually. int flags = 0; CJNIMediaCrypto crypto(jni::jhobject(NULL)); // our jni gets upset if we do this a different // way, do not mess with it. if (m_render_sw) { CJNISurface surface(jni::jhobject(NULL)); m_codec->configure(mediaformat, surface, crypto, flags); } else { m_codec->configure(mediaformat, *m_surface, crypto, flags); } m_codec->start(); // always, check/clear jni exceptions. if (xbmc_jnienv()->ExceptionOccurred()) xbmc_jnienv()->ExceptionClear(); }
bool CDVDVideoCodecAndroidMediaCodec::ConfigureMediaCodec(void) { // setup a MediaFormat to match the video content, // used by codec during configure CJNIMediaFormat mediaformat = CJNIMediaFormat::createVideoFormat( m_mime.c_str(), m_hints.width, m_hints.height); // some android devices forget to default the demux input max size mediaformat.setInteger(CJNIMediaFormat::KEY_MAX_INPUT_SIZE, 0); // handle codec extradata if (m_hints.extrasize) { size_t size = m_hints.extrasize; void *src_ptr = m_hints.extradata; if (m_bitstream) { size = m_bitstream->GetExtraSize(); src_ptr = m_bitstream->GetExtraData(); } // Allocate a byte buffer via allocateDirect in java instead of NewDirectByteBuffer, // since the latter doesn't allocate storage of its own, and we don't know how long // the codec uses the buffer. CJNIByteBuffer bytebuffer = CJNIByteBuffer::allocateDirect(size); void *dts_ptr = xbmc_jnienv()->GetDirectBufferAddress(bytebuffer.get_raw()); memcpy(dts_ptr, src_ptr, size); // codec will automatically handle buffers as extradata // using entries with keys "csd-0", "csd-1", etc. mediaformat.setByteBuffer("csd-0", bytebuffer); } InitSurfaceTexture(); // configure and start the codec. // use the MediaFormat that we have setup. // use a null MediaCrypto, our content is not encrypted. // use a null Surface, we will extract the video picture data manually. int flags = 0; CJNIMediaCrypto crypto(jni::jhobject(NULL)); // our jni gets upset if we do this a different // way, do not mess with it. if (m_render_sw) { CJNISurface surface(jni::jhobject(NULL)); m_codec->configure(mediaformat, surface, crypto, flags); } else { if (m_render_surface) m_codec->configure(mediaformat, m_videosurface, crypto, flags); else m_codec->configure(mediaformat, *m_surface, crypto, flags); } // always, check/clear jni exceptions. if (xbmc_jnienv()->ExceptionCheck()) { CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::ExceptionCheck: configure"); xbmc_jnienv()->ExceptionDescribe(); xbmc_jnienv()->ExceptionClear(); return false; } m_state = MEDIACODEC_STATE_CONFIGURED; m_codec->start(); // always, check/clear jni exceptions. if (xbmc_jnienv()->ExceptionCheck()) { CLog::Log(LOGERROR, "CDVDVideoCodecAndroidMediaCodec::ExceptionCheck: start"); xbmc_jnienv()->ExceptionDescribe(); xbmc_jnienv()->ExceptionClear(); return false; } m_state = MEDIACODEC_STATE_FLUSHED; // There is no guarantee we'll get an INFO_OUTPUT_FORMAT_CHANGED (up to Android 4.3) // Configure the output with defaults ConfigureOutputFormat(&mediaformat); return true; }
bool CDVDAudioCodecAndroidMediaCodec::ConfigureMediaCodec(void) { // setup a MediaFormat to match the audio content, // used by codec during configure CJNIMediaFormat mediaformat = CJNIMediaFormat::createAudioFormat( m_mime.c_str(), m_hints.samplerate, m_hints.channels); // handle codec extradata if (m_hints.extrasize) { size_t size = m_hints.extrasize; void *src_ptr = m_hints.extradata; // Allocate a byte buffer via allocateDirect in java instead of NewDirectByteBuffer, // since the latter doesn't allocate storage of its own, and we don't know how long // the codec uses the buffer. CJNIByteBuffer bytebuffer = CJNIByteBuffer::allocateDirect(size); void *dts_ptr = xbmc_jnienv()->GetDirectBufferAddress(bytebuffer.get_raw()); memcpy(dts_ptr, src_ptr, size); // codec will automatically handle buffers as extradata // using entries with keys "csd-0", "csd-1", etc. mediaformat.setByteBuffer("csd-0", bytebuffer); } else if (m_hints.codec == AV_CODEC_ID_AAC || m_hints.codec == AV_CODEC_ID_AAC_LATM) { mediaformat.setInteger(CJNIMediaFormat::KEY_IS_ADTS, 1); } // configure and start the codec. // use the MediaFormat that we have setup. // use a null MediaCrypto, our content is not encrypted. // use a null Surface int flags = 0; CJNIMediaCrypto crypto(jni::jhobject(NULL)); CJNISurface surface(jni::jhobject(NULL)); m_codec->configure(mediaformat, surface, crypto, flags); // always, check/clear jni exceptions. if (xbmc_jnienv()->ExceptionCheck()) { CLog::Log(LOGERROR, "CDVDAudioCodecAndroidMediaCodec::ExceptionCheck: configure"); xbmc_jnienv()->ExceptionDescribe(); xbmc_jnienv()->ExceptionClear(); return false; } m_codec->start(); // always, check/clear jni exceptions. if (xbmc_jnienv()->ExceptionCheck()) { CLog::Log(LOGERROR, "CDVDAudioCodecAndroidMediaCodec::ExceptionCheck: start"); xbmc_jnienv()->ExceptionDescribe(); xbmc_jnienv()->ExceptionClear(); return false; } // There is no guarantee we'll get an INFO_OUTPUT_FORMAT_CHANGED (up to Android 4.3) // Configure the output with defaults ConfigureOutputFormat(&mediaformat); return true; }