#include <vlc_block_helper.h>
#include <vlc_cpu.h>
#include "../h264_nal.h"
+#include "../hevc_nal.h"
#include "omxil.h"
#include "omxil_core.h"
#include <dlfcn.h>
#include <jni.h>
#include "android_opaque.h"
+#include "../../video_output/android/android_window.h"
#endif
#ifndef NDEBUG
#if defined(USE_IOMX)
/* JNI functions to get/set an Android Surface object. */
-extern JavaVM *myVm;
+#define THREAD_NAME "omxil"
+extern int jni_attach_thread(JNIEnv **env, const char *thread_name);
+extern void jni_detach_thread();
extern jobject jni_LockAndGetAndroidJavaSurface();
extern void jni_UnlockAndroidSurface();
-extern void jni_SetAndroidSurfaceSize(int width, int height, int visible_width, int visible_height, int sar_num, int sar_den);
extern bool jni_IsVideoPlayerActivityCreated();
#endif
#if defined(USE_IOMX)
static void *DequeueThread( void *data );
-static void DisplayCallback( picture_sys_t* p_picsys );
-static void UnlockCallback( picture_sys_t* p_picsys );
+static void UnlockPicture( picture_t* p_pic, bool b_render );
static void HwBuffer_Init( decoder_t *p_dec, OmxPort *p_port );
static void HwBuffer_Destroy( decoder_t *p_dec, OmxPort *p_port );
static int HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port );
p_port->i_port_index, 0,
p_port->definition.nBufferSize, (void*)1);
OMX_DBG( "OMX_UseBuffer(%d) %p, %p", def->eDir,
- p_port->pp_buffers[i], p_port->pp_buffers[i]->pBuffer );
+ p_port->pp_buffers[i], p_port->pp_buffers[i] ?
+ p_port->pp_buffers[i]->pBuffer : NULL );
}
else
{
p_port->i_port_index, 0,
p_port->definition.nBufferSize);
OMX_DBG( "OMX_AllocateBuffer(%d) %p, %p", def->eDir,
- p_port->pp_buffers[i], p_port->pp_buffers[i]->pBuffer );
+ p_port->pp_buffers[i], p_port->pp_buffers[i] ?
+ p_port->pp_buffers[i]->pBuffer : NULL );
}
if(omx_error != OMX_ErrorNone)
if( p_buffer )
{
if (p_buffer->pAppPrivate != NULL)
- decoder_DeletePicture( p_dec, p_buffer->pAppPrivate );
+ picture_Release( p_buffer->pAppPrivate );
omx_error = OMX_FreeBuffer( p_port->omx_handle,
p_port->i_port_index, p_buffer );
p_header->pBuffer, p_header->nAllocLen,
(uint32_t*) &p_header->nFilledLen, NULL );
}
+ else if( p_dec->fmt_in.i_codec == VLC_CODEC_HEVC && !p_sys->in.b_direct )
+ {
+ p_header->nFilledLen = 0;
+ convert_hevc_nal_units( p_dec, p_dec->fmt_in.p_extra,
+ p_dec->fmt_in.i_extra,
+ p_header->pBuffer, p_header->nAllocLen,
+ (uint32_t*) &p_header->nFilledLen,
+ &p_sys->i_nal_size_length );
+ }
else if(p_sys->in.b_direct)
{
p_header->pOutputPortPrivate = p_header->pBuffer;
if (invalid_picture) {
invalid_picture->date = VLC_TS_INVALID;
picture_sys_t *p_picsys = invalid_picture->p_sys;
- p_picsys->pf_display_callback = NULL;
- p_picsys->pf_unlock_callback = NULL;
- p_picsys->p_dec = NULL;
- p_picsys->i_index = -1;
- p_picsys->b_valid = false;
+ p_picsys->pf_lock_pic = NULL;
+ p_picsys->pf_unlock_pic = NULL;
+ p_picsys->priv.hw.p_dec = NULL;
+ p_picsys->priv.hw.i_index = -1;
+ p_picsys->priv.hw.b_valid = false;
} else {
/* If we cannot return a picture we must free the
block since the decoder will proceed with the
goto error;
}
- (*myVm)->AttachCurrentThread( myVm, &p_env, NULL );
+ jni_attach_thread( &p_env, THREAD_NAME );
p_port->p_hwbuf->window = p_port->p_hwbuf->native_window.winFromSurface( p_env, surf );
- (*myVm)->DetachCurrentThread( myVm );
+ jni_detach_thread();
jni_UnlockAndroidSurface();
if( !p_port->p_hwbuf->window ) {
msg_Warn( p_dec, "winFromSurface failed" );
goto error;
}
- p_port->p_hwbuf->anwpriv.connect( p_port->p_hwbuf->window );
+ p_port->p_hwbuf->window_priv =
+ p_port->p_hwbuf->anwpriv.connect( p_port->p_hwbuf->window );
+ if( !p_port->p_hwbuf->window_priv ) {
+ msg_Warn( p_dec, "connect failed" );
+ p_port->p_hwbuf->native_window.winRelease( p_port->p_hwbuf->window );
+ p_port->p_hwbuf->window = NULL;
+ goto error;
+ }
omx_error = pf_enable_graphic_buffers( p_port->omx_handle,
p_port->i_port_index, OMX_TRUE );
HwBuffer_Stop( p_dec, p_port );
HwBuffer_FreeBuffers( p_dec, p_port );
HwBuffer_Join( p_dec, p_port );
- p_port->p_hwbuf->anwpriv.disconnect( p_port->p_hwbuf->window );
+ p_port->p_hwbuf->anwpriv.disconnect( p_port->p_hwbuf->window_priv );
pf_enable_graphic_buffers( p_port->omx_handle,
p_port->i_port_index, OMX_FALSE );
p_port->p_hwbuf->native_window.winRelease( p_port->p_hwbuf->window );
default:
i_angle = 0;
}
- p_port->p_hwbuf->anwpriv.setOrientation( p_port->p_hwbuf->window,
+ p_port->p_hwbuf->anwpriv.setOrientation( p_port->p_hwbuf->window_priv,
i_angle );
- video_format_ApplyRotation( &p_port->p_hwbuf->fmt_out,
- &p_port->p_fmt->video );
- } else
- p_port->p_hwbuf->fmt_out = p_port->p_fmt->video;
-
- if( p_port->p_hwbuf->anwpriv.setup( p_port->p_hwbuf->window,
- def->format.video.nFrameWidth,
- def->format.video.nFrameHeight,
- colorFormat,
- (int) i_hw_usage ) != 0 )
- {
- msg_Err( p_dec, "can't setup OMXHWBuffer" );
+ }
+
+ if( p_port->p_hwbuf->anwpriv.setUsage( p_port->p_hwbuf->window_priv,
+ true, (int) i_hw_usage ) != 0 )
+ {
+ msg_Err( p_dec, "can't set usage" );
+ goto error;
+ }
+ if( p_port->p_hwbuf->anwpriv.setBuffersGeometry( p_port->p_hwbuf->window_priv,
+ def->format.video.nFrameWidth,
+ def->format.video.nFrameHeight,
+ colorFormat ) != 0 )
+ {
+ msg_Err( p_dec, "can't set buffers geometry" );
goto error;
}
- if( p_port->p_hwbuf->anwpriv.getMinUndequeued( p_port->p_hwbuf->window,
+ if( p_port->p_hwbuf->anwpriv.getMinUndequeued( p_port->p_hwbuf->window_priv,
&min_undequeued ) != 0 )
{
msg_Err( p_dec, "can't get min_undequeued" );
omx_error, ErrorToString(omx_error) );
}
- if( p_port->p_hwbuf->anwpriv.setBufferCount( p_port->p_hwbuf->window,
+ if( p_port->p_hwbuf->anwpriv.setBufferCount( p_port->p_hwbuf->window_priv,
def->nBufferCountActual ) != 0 )
{
msg_Err( p_dec, "can't set buffer_count" );
goto error;
}
- jni_SetAndroidSurfaceSize( p_port->p_hwbuf->fmt_out.i_width,
- p_port->p_hwbuf->fmt_out.i_height,
- p_port->p_hwbuf->fmt_out.i_visible_width,
- p_port->p_hwbuf->fmt_out.i_visible_height,
- p_port->p_hwbuf->fmt_out.i_sar_num,
- p_port->p_hwbuf->fmt_out.i_sar_den );
-
p_port->p_hwbuf->i_buffers = p_port->definition.nBufferCountActual;
p_port->p_hwbuf->i_max_owned = p_port->p_hwbuf->i_buffers - min_undequeued;
{
void *p_handle = NULL;
- if( p_port->p_hwbuf->anwpriv.dequeue( p_port->p_hwbuf->window,
+ if( p_port->p_hwbuf->anwpriv.dequeue( p_port->p_hwbuf->window_priv,
&p_handle ) != 0 )
{
msg_Err( p_dec, "OMXHWBuffer_dequeue Fail" );
for(; i < p_port->p_hwbuf->i_buffers; i++)
{
OMX_DBG( "canceling buffer(%d)", i );
- p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window,
+ p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window_priv,
p_port->p_hwbuf->pp_handles[i] );
}
if( p_handle && p_port->p_hwbuf->i_states[i] == BUF_STATE_OWNED )
{
- p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window, p_handle );
+ p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window_priv, p_handle );
HwBuffer_ChangeState( p_dec, p_port, i, BUF_STATE_NOT_OWNED );
}
}
if( p_header && p_port->p_hwbuf->i_states[i] == BUF_STATE_OWNED )
{
- if( p_port->p_hwbuf->anwpriv.lock( p_port->p_hwbuf->window,
+ if( p_port->p_hwbuf->anwpriv.lock( p_port->p_hwbuf->window_priv,
p_header->pBuffer ) != 0 )
{
msg_Err( p_dec, "lock failed" );
if( p_pic ) {
picture_sys_t *p_picsys = p_pic->p_sys;
if( p_picsys ) {
- void *p_handle = p_port->pp_buffers[p_picsys->i_index]->pBuffer;
+ void *p_handle = p_port->pp_buffers[p_picsys->priv.hw.i_index]->pBuffer;
if( p_handle )
{
- p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window, p_handle );
- HwBuffer_ChangeState( p_dec, p_port, p_picsys->i_index,
+ p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window_priv, p_handle );
+ HwBuffer_ChangeState( p_dec, p_port, p_picsys->priv.hw.i_index,
BUF_STATE_NOT_OWNED );
}
- p_picsys->b_valid = false;
+ p_picsys->priv.hw.b_valid = false;
}
p_port->p_hwbuf->inflight_picture[i] = NULL;
}
p_pic->date = FromOmxTicks( p_header->nTimeStamp );
p_picsys = p_pic->p_sys;
- p_picsys->pf_display_callback = DisplayCallback;
- p_picsys->pf_unlock_callback = UnlockCallback;
- p_picsys->p_dec = p_dec;
- p_picsys->i_index = i_index;
- p_picsys->b_valid = true;
+ p_picsys->pf_lock_pic = NULL;
+ p_picsys->pf_unlock_pic = UnlockPicture;
+ p_picsys->priv.hw.p_dec = p_dec;
+ p_picsys->priv.hw.i_index = i_index;
+ p_picsys->priv.hw.b_valid = true;
HWBUFFER_LOCK();
p_port->p_hwbuf->inflight_picture[i_index] = p_pic;
{
VLC_UNUSED( p_dec );
- p_port->p_hwbuf->anwpriv.setCrop( p_port->p_hwbuf->window,
+ p_port->p_hwbuf->anwpriv.setCrop( p_port->p_hwbuf->window_priv,
p_rect->nLeft, p_rect->nTop,
p_rect->nWidth, p_rect->nHeight );
}
/* The thread can be stuck here. It shouldn't happen since we make sure
* we call the dequeue function if there is at least one buffer
* available. */
- err = p_port->p_hwbuf->anwpriv.dequeue( p_port->p_hwbuf->window, &p_handle );
+ err = p_port->p_hwbuf->anwpriv.dequeue( p_port->p_hwbuf->window_priv, &p_handle );
if( err == 0 )
- err = p_port->p_hwbuf->anwpriv.lock( p_port->p_hwbuf->window, p_handle );
+ err = p_port->p_hwbuf->anwpriv.lock( p_port->p_hwbuf->window_priv, p_handle );
HWBUFFER_LOCK();
if( !p_port->p_hwbuf->b_run )
{
- p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window, p_handle );
+ p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window_priv, p_handle );
continue;
}
/*****************************************************************************
* vout callbacks
*****************************************************************************/
-static void DisplayBuffer( picture_sys_t* p_picsys, bool b_render )
+static void UnlockPicture( picture_t* p_pic, bool b_render )
{
- decoder_t *p_dec = p_picsys->p_dec;
+ picture_sys_t *p_picsys = p_pic->p_sys;
+ decoder_t *p_dec = p_picsys->priv.hw.p_dec;
decoder_sys_t *p_sys = p_dec->p_sys;
OmxPort *p_port = &p_sys->out;
void *p_handle;
- if( !p_picsys->b_valid ) return;
+ if( !p_picsys->priv.hw.b_valid ) return;
HWBUFFER_LOCK();
/* Picture might have been invalidated while waiting on the mutex. */
- if (!p_picsys->b_valid) {
+ if (!p_picsys->priv.hw.b_valid) {
HWBUFFER_UNLOCK();
return;
}
- p_handle = p_port->pp_buffers[p_picsys->i_index]->pBuffer;
+ p_handle = p_port->pp_buffers[p_picsys->priv.hw.i_index]->pBuffer;
OMX_DBG( "DisplayBuffer: %s %p",
b_render ? "render" : "cancel", p_handle );
}
if( b_render )
- p_port->p_hwbuf->anwpriv.queue( p_port->p_hwbuf->window, p_handle );
+ p_port->p_hwbuf->anwpriv.queue( p_port->p_hwbuf->window_priv, p_handle );
else
- p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window, p_handle );
+ p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window_priv, p_handle );
- HwBuffer_ChangeState( p_dec, p_port, p_picsys->i_index, BUF_STATE_NOT_OWNED );
+ HwBuffer_ChangeState( p_dec, p_port, p_picsys->priv.hw.i_index, BUF_STATE_NOT_OWNED );
HWBUFFER_BROADCAST( p_port );
- p_port->p_hwbuf->inflight_picture[p_picsys->i_index] = NULL;
+ p_port->p_hwbuf->inflight_picture[p_picsys->priv.hw.i_index] = NULL;
end:
- p_picsys->b_valid = false;
- p_picsys->i_index = -1;
+ p_picsys->priv.hw.b_valid = false;
+ p_picsys->priv.hw.i_index = -1;
HWBUFFER_UNLOCK();
}
-static void UnlockCallback( picture_sys_t* p_picsys )
-{
- DisplayBuffer( p_picsys, false );
-}
-
-static void DisplayCallback( picture_sys_t* p_picsys )
-{
- DisplayBuffer( p_picsys, true );
-}
-
#endif // USE_IOMX