Commit 890f8e0f authored by Thomas Guillem's avatar Thomas Guillem

android: remove get_android_opaque_mutex()

Replace it with a mutex per picture_sys_t. When doing direct rendering, the
picture_sys_t is refcounted between the vout and the decoder.
parent cad45d8a
...@@ -417,7 +417,7 @@ libiomx_plugin_la_LIBADD = $(libomxil_plugin_la_LIBADD) ...@@ -417,7 +417,7 @@ libiomx_plugin_la_LIBADD = $(libomxil_plugin_la_LIBADD)
libmediacodec_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/codec/omxil libmediacodec_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/codec/omxil
libmediacodec_plugin_la_SOURCES = codec/omxil/mediacodec.c codec/omxil/mediacodec.h \ libmediacodec_plugin_la_SOURCES = codec/omxil/mediacodec.c codec/omxil/mediacodec.h \
codec/omxil/mediacodec_jni.c codec/omxil/mediacodec_ndk.c codec/omxil/utils.c \ codec/omxil/mediacodec_jni.c codec/omxil/mediacodec_ndk.c codec/omxil/utils.c \
video_chroma/copy.c codec/omxil/android_opaque.c codec/omxil/android_opaque.h \ video_chroma/copy.c
video_output/android/utils.c video_output/android/utils.h video_output/android/utils.c video_output/android/utils.h
packetizer/h264_nal.c packetizer/h264_nal.h packetizer/h264_nal.c packetizer/h264_nal.h
packetizer/hevc_nal.c packetizer/hevc_nal.h packetizer/hevc_nal.c packetizer/hevc_nal.h
......
/*****************************************************************************
* android_opaque.c: shared structures between MediaCodec decoder
* and MediaCodec video output
*****************************************************************************
* Copyright (C) 2013 Felix Abecassis
*
* Authors: Felix Abecassis <felix.abecassis@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "android_opaque.h"
vlc_mutex_t* get_android_opaque_mutex()
{
static vlc_mutex_t s_mutex = VLC_STATIC_MUTEX;
return &s_mutex;
}
/*****************************************************************************
* android_opaque.h: shared structures between MediaCodec decoder
* and MediaCodec video output
*****************************************************************************
* Copyright (C) 2013 Felix Abecassis
*
* Authors: Felix Abecassis <felix.abecassis@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef ANDROID_OPAQUE_H_
#define ANDROID_OPAQUE_H_
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
vlc_mutex_t* get_android_opaque_mutex(void);
#endif
...@@ -46,7 +46,6 @@ ...@@ -46,7 +46,6 @@
#include <OMX_Core.h> #include <OMX_Core.h>
#include <OMX_Component.h> #include <OMX_Component.h>
#include "omxil_utils.h" #include "omxil_utils.h"
#include "android_opaque.h"
#include "../../video_output/android/android_window.h" #include "../../video_output/android/android_window.h"
/* JNI functions to get/set an Android Surface object. */ /* JNI functions to get/set an Android Surface object. */
...@@ -117,7 +116,7 @@ struct decoder_sys_t ...@@ -117,7 +116,7 @@ struct decoder_sys_t
size_t i_h264_profile; size_t i_h264_profile;
ArchitectureSpecificCopyData ascd; ArchitectureSpecificCopyData ascd;
/* stores the inflight picture for each output buffer or NULL */ /* stores the inflight picture for each output buffer or NULL */
picture_t** pp_inflight_pictures; picture_sys_t** pp_inflight_pictures;
unsigned int i_inflight_pictures; unsigned int i_inflight_pictures;
timestamp_fifo_t *timestamp_fifo; timestamp_fifo_t *timestamp_fifo;
} video; } video;
...@@ -150,7 +149,7 @@ static int Audio_ProcessOutput(decoder_t *, mc_api_out *, picture_t **, block_t ...@@ -150,7 +149,7 @@ static int Audio_ProcessOutput(decoder_t *, mc_api_out *, picture_t **, block_t
static block_t *DecodeAudio(decoder_t *, block_t **); static block_t *DecodeAudio(decoder_t *, block_t **);
static void InvalidateAllPictures(decoder_t *); static void InvalidateAllPictures(decoder_t *);
static int InsertInflightPicture(decoder_t *, picture_t *, unsigned int ); static void RemoveInflightPictures(decoder_t *);
/***************************************************************************** /*****************************************************************************
* Module descriptor * Module descriptor
...@@ -453,10 +452,10 @@ static void StopMediaCodec(decoder_t *p_dec) ...@@ -453,10 +452,10 @@ static void StopMediaCodec(decoder_t *p_dec)
{ {
decoder_sys_t *p_sys = p_dec->p_sys; decoder_sys_t *p_sys = p_dec->p_sys;
/* Invalidate all pictures that are currently in flight in order /* Remove all pictures that are currently in flight in order
* to prevent the vout from using destroyed output buffers. */ * to prevent the vout from using destroyed output buffers. */
if (p_sys->api->b_direct_rendering) if (p_sys->api->b_direct_rendering)
InvalidateAllPictures(p_dec); RemoveInflightPictures(p_dec);
p_sys->api->stop(p_sys->api); p_sys->api->stop(p_sys->api);
if (p_dec->fmt_in.i_cat == VIDEO_ES && p_sys->u.video.p_awh) if (p_dec->fmt_in.i_cat == VIDEO_ES && p_sys->u.video.p_awh)
...@@ -576,6 +575,8 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init) ...@@ -576,6 +575,8 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init)
p_sys->u.video.timestamp_fifo = timestamp_FifoNew(32); p_sys->u.video.timestamp_fifo = timestamp_FifoNew(32);
if (!p_sys->u.video.timestamp_fifo) if (!p_sys->u.video.timestamp_fifo)
goto bailout; goto bailout;
TAB_INIT( p_sys->u.video.i_inflight_pictures,
p_sys->u.video.pp_inflight_pictures );
if (p_dec->fmt_in.i_codec == VLC_CODEC_H264) if (p_dec->fmt_in.i_codec == VLC_CODEC_H264)
h264_get_profile_level(&p_dec->fmt_in, h264_get_profile_level(&p_dec->fmt_in,
...@@ -673,7 +674,6 @@ static void CloseDecoder(vlc_object_t *p_this) ...@@ -673,7 +674,6 @@ static void CloseDecoder(vlc_object_t *p_this)
{ {
ArchitectureSpecificCopyHooksDestroy(p_sys->u.video.i_pixel_format, ArchitectureSpecificCopyHooksDestroy(p_sys->u.video.i_pixel_format,
&p_sys->u.video.ascd); &p_sys->u.video.ascd);
free(p_sys->u.video.pp_inflight_pictures);
if (p_sys->u.video.timestamp_fifo) if (p_sys->u.video.timestamp_fifo)
timestamp_FifoRelease(p_sys->u.video.timestamp_fifo); timestamp_FifoRelease(p_sys->u.video.timestamp_fifo);
if (p_sys->u.video.p_awh) if (p_sys->u.video.p_awh)
...@@ -687,73 +687,48 @@ static void CloseDecoder(vlc_object_t *p_this) ...@@ -687,73 +687,48 @@ static void CloseDecoder(vlc_object_t *p_this)
/***************************************************************************** /*****************************************************************************
* vout callbacks * vout callbacks
*****************************************************************************/ *****************************************************************************/
static void UnlockPicture(picture_t* p_pic, bool b_render) static void ReleasePicture(decoder_t *p_dec, unsigned i_index, bool b_render)
{ {
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; decoder_sys_t *p_sys = p_dec->p_sys;
if (!p_picsys->priv.hw.b_valid)
return;
vlc_mutex_lock(get_android_opaque_mutex());
/* Picture might have been invalidated while waiting on the mutex. */
if (!p_picsys->priv.hw.b_valid) {
vlc_mutex_unlock(get_android_opaque_mutex());
return;
}
uint32_t i_index = p_picsys->priv.hw.i_index;
InsertInflightPicture(p_dec, NULL, i_index);
/* Release the MediaCodec buffer. */
p_sys->api->release_out(p_sys->api, i_index, b_render); p_sys->api->release_out(p_sys->api, i_index, b_render);
p_picsys->priv.hw.b_valid = false;
vlc_mutex_unlock(get_android_opaque_mutex());
} }
static void InvalidateAllPictures(decoder_t *p_dec) static void InvalidateAllPictures(decoder_t *p_dec)
{ {
decoder_sys_t *p_sys = p_dec->p_sys; decoder_sys_t *p_sys = p_dec->p_sys;
vlc_mutex_lock(get_android_opaque_mutex()); for (unsigned int i = 0; i < p_sys->u.video.i_inflight_pictures; ++i)
AndroidOpaquePicture_Release(p_sys->u.video.pp_inflight_pictures[i],
for (unsigned int i = 0; i < p_sys->u.video.i_inflight_pictures; ++i) { false);
picture_t *p_pic = p_sys->u.video.pp_inflight_pictures[i];
if (p_pic) {
if (p_pic->p_sys->priv.hw.b_valid)
{
p_sys->api->release_out(p_sys->api, p_pic->p_sys->priv.hw.i_index, false);
p_pic->p_sys->priv.hw.b_valid = false;
}
p_sys->u.video.pp_inflight_pictures[i] = NULL;
}
}
vlc_mutex_unlock(get_android_opaque_mutex());
} }
static int InsertInflightPicture(decoder_t *p_dec, picture_t *p_pic, static int InsertInflightPicture(decoder_t *p_dec, picture_sys_t *p_picsys)
unsigned int i_index)
{ {
decoder_sys_t *p_sys = p_dec->p_sys; decoder_sys_t *p_sys = p_dec->p_sys;
if (i_index >= p_sys->u.video.i_inflight_pictures) { if (!p_picsys->priv.hw.p_dec)
picture_t **pp_pics = realloc(p_sys->u.video.pp_inflight_pictures, {
(i_index + 1) * sizeof (picture_t *)); p_picsys->priv.hw.p_dec = p_dec;
if (!pp_pics) p_picsys->priv.hw.pf_release = ReleasePicture;
return -1; TAB_APPEND_CAST((picture_sys_t **),
if (i_index - p_sys->u.video.i_inflight_pictures > 0) p_sys->u.video.i_inflight_pictures,
memset(&pp_pics[p_sys->u.video.i_inflight_pictures], 0, p_sys->u.video.pp_inflight_pictures,
(i_index - p_sys->u.video.i_inflight_pictures) * sizeof (picture_t *)); p_picsys);
p_sys->u.video.pp_inflight_pictures = pp_pics; } /* else already attached */
p_sys->u.video.i_inflight_pictures = i_index + 1;
}
p_sys->u.video.pp_inflight_pictures[i_index] = p_pic;
return 0; return 0;
} }
static void RemoveInflightPictures(decoder_t *p_dec)
{
decoder_sys_t *p_sys = p_dec->p_sys;
for (unsigned int i = 0; i < p_sys->u.video.i_inflight_pictures; ++i)
AndroidOpaquePicture_DetachDecoder(p_sys->u.video.pp_inflight_pictures[i]);
TAB_CLEAN(p_sys->u.video.i_inflight_pictures,
p_sys->u.video.pp_inflight_pictures);
}
static int Video_ProcessOutput(decoder_t *p_dec, mc_api_out *p_out, static int Video_ProcessOutput(decoder_t *p_dec, mc_api_out *p_out,
picture_t **pp_out_pic, block_t **pp_out_block) picture_t **pp_out_pic, block_t **pp_out_block)
{ {
...@@ -816,16 +791,8 @@ static int Video_ProcessOutput(decoder_t *p_dec, mc_api_out *p_out, ...@@ -816,16 +791,8 @@ static int Video_ProcessOutput(decoder_t *p_dec, mc_api_out *p_out,
if (p_sys->api->b_direct_rendering) if (p_sys->api->b_direct_rendering)
{ {
picture_sys_t *p_picsys = p_pic->p_sys; p_pic->p_sys->priv.hw.i_index = p_out->u.buf.i_index;
p_picsys->pf_lock_pic = NULL; InsertInflightPicture(p_dec, p_pic->p_sys);
p_picsys->pf_unlock_pic = UnlockPicture;
p_picsys->priv.hw.p_dec = p_dec;
p_picsys->priv.hw.i_index = p_out->u.buf.i_index;
p_picsys->priv.hw.b_valid = true;
vlc_mutex_lock(get_android_opaque_mutex());
InsertInflightPicture(p_dec, p_pic, p_out->u.buf.i_index);
vlc_mutex_unlock(get_android_opaque_mutex());
} else { } else {
unsigned int chroma_div; unsigned int chroma_div;
GetVlcChromaSizes(p_dec->fmt_out.i_codec, GetVlcChromaSizes(p_dec->fmt_out.i_codec,
......
...@@ -45,7 +45,6 @@ ...@@ -45,7 +45,6 @@
#if defined(USE_IOMX) #if defined(USE_IOMX)
#include <dlfcn.h> #include <dlfcn.h>
#include <jni.h> #include <jni.h>
#include "android_opaque.h"
#include "../../video_output/android/android_window.h" #include "../../video_output/android/android_window.h"
#endif #endif
...@@ -91,7 +90,7 @@ static OMX_ERRORTYPE OmxFillBufferDone( OMX_HANDLETYPE, OMX_PTR, ...@@ -91,7 +90,7 @@ static OMX_ERRORTYPE OmxFillBufferDone( OMX_HANDLETYPE, OMX_PTR,
#if defined(USE_IOMX) #if defined(USE_IOMX)
static void *DequeueThread( void *data ); static void *DequeueThread( void *data );
static void UnlockPicture( picture_t* p_pic, bool b_render ); static void ReleasePicture( decoder_t *p_dec, unsigned int i_index, bool b_render );
static void HwBuffer_Init( decoder_t *p_dec, OmxPort *p_port ); static void HwBuffer_Init( decoder_t *p_dec, OmxPort *p_port );
static void HwBuffer_Destroy( 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 ); static int HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port );
...@@ -1611,11 +1610,8 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) ...@@ -1611,11 +1610,8 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
if (invalid_picture) { if (invalid_picture) {
invalid_picture->date = VLC_TS_INVALID; invalid_picture->date = VLC_TS_INVALID;
picture_sys_t *p_picsys = invalid_picture->p_sys; picture_sys_t *p_picsys = invalid_picture->p_sys;
p_picsys->pf_lock_pic = NULL;
p_picsys->pf_unlock_pic = NULL;
p_picsys->priv.hw.p_dec = NULL; p_picsys->priv.hw.p_dec = NULL;
p_picsys->priv.hw.i_index = -1; p_picsys->priv.hw.i_index = -1;
p_picsys->priv.hw.b_valid = false;
} else { } else {
/* If we cannot return a picture we must free the /* If we cannot return a picture we must free the
block since the decoder will proceed with the block since the decoder will proceed with the
...@@ -2240,7 +2236,7 @@ static int HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port ) ...@@ -2240,7 +2236,7 @@ static int HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port )
goto error; goto error;
p_port->p_hwbuf->inflight_picture = calloc( p_port->p_hwbuf->i_buffers, p_port->p_hwbuf->inflight_picture = calloc( p_port->p_hwbuf->i_buffers,
sizeof(picture_t*) ); sizeof(picture_sys_t*) );
if( !p_port->p_hwbuf->inflight_picture ) if( !p_port->p_hwbuf->inflight_picture )
goto error; goto error;
...@@ -2375,19 +2371,10 @@ static int HwBuffer_Stop( decoder_t *p_dec, OmxPort *p_port ) ...@@ -2375,19 +2371,10 @@ static int HwBuffer_Stop( decoder_t *p_dec, OmxPort *p_port )
/* invalidate and release all inflight pictures */ /* invalidate and release all inflight pictures */
if( p_port->p_hwbuf->inflight_picture ) { if( p_port->p_hwbuf->inflight_picture ) {
for( unsigned int i = 0; i < p_port->i_buffers; ++i ) { for( unsigned int i = 0; i < p_port->i_buffers; ++i ) {
picture_t *p_pic = p_port->p_hwbuf->inflight_picture[i]; picture_sys_t *p_picsys = p_port->p_hwbuf->inflight_picture[i];
if( p_pic ) { if( p_picsys )
picture_sys_t *p_picsys = p_pic->p_sys; {
if( p_picsys ) { AndroidOpaquePicture_DetachDecoder(p_picsys);
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_priv, p_handle );
HwBuffer_ChangeState( p_dec, p_port, p_picsys->priv.hw.i_index,
BUF_STATE_NOT_OWNED );
}
p_picsys->priv.hw.b_valid = false;
}
p_port->p_hwbuf->inflight_picture[i] = NULL; p_port->p_hwbuf->inflight_picture[i] = NULL;
} }
} }
...@@ -2454,13 +2441,11 @@ static int HwBuffer_GetPic( decoder_t *p_dec, OmxPort *p_port, ...@@ -2454,13 +2441,11 @@ static int HwBuffer_GetPic( decoder_t *p_dec, OmxPort *p_port,
p_pic->date = FromOmxTicks( p_header->nTimeStamp ); p_pic->date = FromOmxTicks( p_header->nTimeStamp );
p_picsys = p_pic->p_sys; p_picsys = p_pic->p_sys;
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.i_index = i_index;
p_picsys->priv.hw.b_valid = true; p_picsys->priv.hw.p_dec = p_dec;
p_picsys->priv.hw.pf_release = ReleasePicture;
p_port->p_hwbuf->inflight_picture[i_index] = p_pic; p_port->p_hwbuf->inflight_picture[i_index] = p_picsys;
*pp_pic = p_pic; *pp_pic = p_pic;
OMX_FIFO_GET( &p_port->fifo, p_header ); OMX_FIFO_GET( &p_port->fifo, p_header );
...@@ -2559,25 +2544,15 @@ static void *DequeueThread( void *data ) ...@@ -2559,25 +2544,15 @@ static void *DequeueThread( void *data )
/***************************************************************************** /*****************************************************************************
* vout callbacks * vout callbacks
*****************************************************************************/ *****************************************************************************/
static void UnlockPicture( picture_t* p_pic, bool b_render ) static void ReleasePicture( decoder_t *p_dec, unsigned int i_index,
bool b_render )
{ {
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; decoder_sys_t *p_sys = p_dec->p_sys;
OmxPort *p_port = &p_sys->out; OmxPort *p_port = &p_sys->out;
void *p_handle; void *p_handle;
HWBUFFER_LOCK( p_port ); HWBUFFER_LOCK( p_port );
if( !p_picsys->priv.hw.b_valid ) return; p_handle = p_port->pp_buffers[i_index]->pBuffer;
/* Picture might have been invalidated while waiting on the mutex. */
if (!p_picsys->priv.hw.b_valid) {
HWBUFFER_UNLOCK();
return;
}
p_handle = p_port->pp_buffers[p_picsys->priv.hw.i_index]->pBuffer;
OMX_DBG( "DisplayBuffer: %s %p", OMX_DBG( "DisplayBuffer: %s %p",
b_render ? "render" : "cancel", p_handle ); b_render ? "render" : "cancel", p_handle );
...@@ -2593,14 +2568,10 @@ static void UnlockPicture( picture_t* p_pic, bool b_render ) ...@@ -2593,14 +2568,10 @@ static void UnlockPicture( picture_t* p_pic, bool b_render )
else else
p_port->p_hwbuf->anwpriv->cancel( p_port->p_hwbuf->window_priv, p_handle ); 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 ); HwBuffer_ChangeState( p_dec, p_port, i_index, BUF_STATE_NOT_OWNED );
HWBUFFER_BROADCAST( p_port ); HWBUFFER_BROADCAST( p_port );
p_port->p_hwbuf->inflight_picture[p_picsys->priv.hw.i_index] = NULL;
end: end:
p_picsys->priv.hw.b_valid = false;
p_picsys->priv.hw.i_index = -1;
HWBUFFER_UNLOCK( p_port ); HWBUFFER_UNLOCK( p_port );
} }
......
...@@ -67,7 +67,7 @@ typedef struct HwBuffer ...@@ -67,7 +67,7 @@ typedef struct HwBuffer
bool b_run; bool b_run;
vlc_mutex_t lock; vlc_mutex_t lock;
vlc_cond_t wait; vlc_cond_t wait;
picture_t** inflight_picture; /**< stores the inflight picture for each output buffer or NULL */ picture_sys_t** inflight_picture; /**< stores the inflight picture for each output buffer or NULL */
unsigned int i_buffers; unsigned int i_buffers;
void **pp_handles; void **pp_handles;
......
...@@ -176,7 +176,26 @@ static int UpdateWindowSize(vout_display_sys_t *sys, video_format_t *p_fmt, ...@@ -176,7 +176,26 @@ static int UpdateWindowSize(vout_display_sys_t *sys, video_format_t *p_fmt,
return 0; return 0;
} }
static picture_t *PictureAlloc(vout_display_sys_t *sys, video_format_t *fmt) static void AndroidOpaquePicture_DetachVout(picture_t *p_pic)
{
picture_sys_t *p_picsys = p_pic->p_sys;
vlc_mutex_lock(&p_picsys->priv.hw.lock);
p_pic->p_sys->p_vd_sys = NULL;
/* Release p_picsys if references from VOUT and from decoder are NULL */
if (!p_picsys->p_vd_sys && !p_picsys->priv.hw.p_dec)
{
vlc_mutex_unlock(&p_picsys->priv.hw.lock);
vlc_mutex_destroy(&p_picsys->priv.hw.lock);
free(p_picsys);
}
else
vlc_mutex_unlock(&p_picsys->priv.hw.lock);
free(p_pic);
}
static picture_t *PictureAlloc(vout_display_sys_t *sys, video_format_t *fmt,
bool b_opaque)
{ {
picture_t *p_pic; picture_t *p_pic;
picture_resource_t rsc; picture_resource_t rsc;
...@@ -188,7 +207,14 @@ static picture_t *PictureAlloc(vout_display_sys_t *sys, video_format_t *fmt) ...@@ -188,7 +207,14 @@ static picture_t *PictureAlloc(vout_display_sys_t *sys, video_format_t *fmt)
p_picsys->p_vd_sys = sys; p_picsys->p_vd_sys = sys;
memset(&rsc, 0, sizeof(picture_resource_t)); memset(&rsc, 0, sizeof(picture_resource_t));
rsc.p_sys = p_picsys, rsc.p_sys = p_picsys;
if (b_opaque)
{
p_picsys->priv.hw.i_index = -1;
vlc_mutex_init(&p_picsys->priv.hw.lock);
rsc.pf_destroy = AndroidOpaquePicture_DetachVout;
}
p_pic = picture_NewFromResource(fmt, &rsc); p_pic = picture_NewFromResource(fmt, &rsc);
if (!p_pic) if (!p_pic)
...@@ -506,7 +532,7 @@ static int AndroidWindow_Setup(vout_display_sys_t *sys, ...@@ -506,7 +532,7 @@ static int AndroidWindow_Setup(vout_display_sys_t *sys,
if (!p_window->b_opaque) { if (!p_window->b_opaque) {
int align_pixels; int align_pixels;
picture_t *p_pic = PictureAlloc(sys, &p_window->fmt); picture_t *p_pic = PictureAlloc(sys, &p_window->fmt, false);
// For RGB (32 or 16) we need to align on 8 or 4 pixels, 16 pixels for YUV // For RGB (32 or 16) we need to align on 8 or 4 pixels, 16 pixels for YUV
align_pixels = (16 / p_pic->p[0].i_pixel_pitch) - 1; align_pixels = (16 / p_pic->p[0].i_pixel_pitch) - 1;
...@@ -751,37 +777,30 @@ static void Close(vlc_object_t *p_this) ...@@ -751,37 +777,30 @@ static void Close(vlc_object_t *p_this)
free(sys); free(sys);
} }
static int DefaultLockPicture(picture_t *p_pic)
{
picture_sys_t *p_picsys = p_pic->p_sys;
vout_display_sys_t *sys = p_picsys->p_vd_sys;
return AndroidWindow_LockPicture(sys, sys->p_window, p_pic);
}
static void DefaultUnlockPicture(picture_t *p_pic, bool b_render)
{
picture_sys_t *p_picsys = p_pic->p_sys;
vout_display_sys_t *sys = p_picsys->p_vd_sys;
AndroidWindow_UnlockPicture(sys, sys->p_window, p_pic, b_render);
}
static void UnlockPicture(picture_t *p_pic, bool b_render) static void UnlockPicture(picture_t *p_pic, bool b_render)
{ {
picture_sys_t *p_picsys = p_pic->p_sys; picture_sys_t *p_picsys = p_pic->p_sys;
vout_display_sys_t *sys = p_picsys->p_vd_sys;
if (p_picsys->b_locked && p_picsys->pf_unlock_pic) if (p_picsys->b_locked)
p_picsys->pf_unlock_pic(p_pic, b_render); {
p_picsys->b_locked = false; if (sys->p_window->b_opaque)
AndroidOpaquePicture_Release(p_picsys, b_render);
else
AndroidWindow_UnlockPicture(sys, sys->p_window, p_pic, b_render);
p_picsys->b_locked = false;
}
} }
static int PoolLockPicture(picture_t *p_pic) static int PoolLockPicture(picture_t *p_pic)
{ {
picture_sys_t *p_picsys = p_pic->p_sys; picture_sys_t *p_picsys = p_pic->p_sys;
vout_display_sys_t *sys = p_picsys->p_vd_sys;
if (p_picsys->pf_lock_pic && p_picsys->pf_lock_pic(p_pic) != 0) if (!sys->p_window->b_opaque
&& AndroidWindow_LockPicture(sys, sys->p_window, p_pic) != 0)
return -1; return -1;
p_picsys->b_locked = true; p_picsys->b_locked = true;
return 0; return 0;
} }
...@@ -811,13 +830,10 @@ static picture_pool_t *PoolAlloc(vout_display_t *vd, unsigned requested_count) ...@@ -811,13 +830,10 @@ static picture_pool_t *PoolAlloc(vout_display_t *vd, unsigned requested_count)
for (i = 0; i < requested_count; i++) for (i = 0; i < requested_count; i++)
{ {
picture_t *p_pic = PictureAlloc(sys, &sys->p_window->fmt); picture_t *p_pic = PictureAlloc(sys, &sys->p_window->fmt,
sys->p_window->b_opaque);
if (!p_pic) if (!p_pic)
goto error; goto error;
if (!sys->p_window->b_opaque) {
p_pic->p_sys->pf_lock_pic = DefaultLockPicture;
p_pic->p_sys->pf_unlock_pic = DefaultUnlockPicture;
}
pp_pics[i] = p_pic; pp_pics[i] = p_pic;
} }
...@@ -990,7 +1006,7 @@ static void Prepare(vout_display_t *vd, picture_t *picture, ...@@ -990,7 +1006,7 @@ static void Prepare(vout_display_t *vd, picture_t *picture,
if (!sys->p_sub_pic if (!sys->p_sub_pic
&& AndroidWindow_Setup(sys, sys->p_sub_window, 1) == 0) && AndroidWindow_Setup(sys, sys->p_sub_window, 1) == 0)
sys->p_sub_pic = PictureAlloc(sys, &sys->p_sub_window->fmt); sys->p_sub_pic = PictureAlloc(sys, &sys->p_sub_window->fmt, false);
if (!sys->p_spu_blend && sys->p_sub_pic) if (!sys->p_spu_blend && sys->p_sub_pic)
sys->p_spu_blend = filter_NewBlend(VLC_OBJECT(vd), sys->p_spu_blend = filter_NewBlend(VLC_OBJECT(vd),
&sys->p_sub_pic->format); &sys->p_sub_pic->format);
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
# include "config.h" # include "config.h"
#endif #endif
#include <assert.h>
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_vout_display.h> #include <vlc_vout_display.h>
#include <android/native_window.h> #include <android/native_window.h>
...@@ -39,14 +40,13 @@ struct picture_sys_t ...@@ -39,14 +40,13 @@ struct picture_sys_t
{ {
vout_display_sys_t *p_vd_sys; vout_display_sys_t *p_vd_sys;
int (*pf_lock_pic)(picture_t *);
void (*pf_unlock_pic)(picture_t *, bool b_render);
union { union {
struct { struct {
vlc_mutex_t lock;
decoder_t *p_dec; decoder_t *p_dec;
uint32_t i_index; int i_index;
bool b_valid; void (*pf_release)(decoder_t *p_dec, unsigned int i_index,
bool b_render);
} hw; } hw;
struct { struct {
void *p_handle; void *p_handle;
...@@ -56,4 +56,44 @@ struct picture_sys_t ...@@ -56,4 +56,44 @@ struct picture_sys_t
bool b_locked; bool b_locked;
}; };
static inline void
AndroidOpaquePicture_DetachDecoder(picture_sys_t *p_picsys)
{
vlc_mutex_lock(&p_picsys->priv.hw.lock);
if (p_picsys->priv.hw.i_index >= 0)
{
assert(p_picsys->priv.hw.pf_release && p_picsys->priv.hw.p_dec);
p_picsys->priv.hw.pf_release(p_picsys->priv.hw.p_dec,
(unsigned int) p_picsys->priv.hw.i_index,
false);
p_picsys->priv.hw.i_index = -1;
}
p_picsys->priv.hw.pf_release = NULL;
p_picsys->priv.hw.p_dec = NULL;
/* Release p_picsys if references from VOUT and from decoder are NULL */
if (!p_picsys->p_vd_sys && !p_picsys->priv.hw.p_dec)
{
vlc_mutex_unlock(&p_picsys->priv.hw.lock);
vlc_mutex_destroy(&p_picsys->priv.hw.lock);
free(p_picsys);
}
else
vlc_mutex_unlock(&p_picsys->priv.hw.lock);
}
static inline void
AndroidOpaquePicture_Release(picture_sys_t *p_picsys, bool b_render)
{
vlc_mutex_lock(&p_picsys->priv.hw.lock);
if (p_picsys->priv.hw.i_index >= 0)
{
assert(p_picsys->priv.hw.pf_release && p_picsys->priv.hw.p_dec);
p_picsys->priv.hw.pf_release(p_picsys->priv.hw.p_dec,
(unsigned int) p_picsys->priv.hw.i_index,
b_render);
p_picsys->priv.hw.i_index = -1;
}
vlc_mutex_unlock(&p_picsys->priv.hw.lock);
}
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment