No encoder with nouveau driver so I cannot do a tunneling test but at least this does not break the decoder part so the 4 patches are: Tested-by: Julien Isorce <j.iso...@samsung.com> Thx!
On 6 July 2016 at 19:03, Leo Liu <leo....@amd.com> wrote: > The idea of encode tunneling is to use video buffer directly for encoder, > but currently the encoder doesn’t support interlaced surface, the OMX > decoder set progressive surface before on that purpose. > > Since now we are polling the driver for interlacing information for > decoder, we got the interlaced as preferred as other APIs(VDPAU, VA-API), > thus breaking the transcode with tunneling. > > The solution is when with tunnel detected, re-allocate progressive target > buffers, and then converting the interlaced decoder results to there. > > This has been tested with transcode results bit to bit matching as before > with surface from progressive to progressive. > > Signed-off-by: Leo Liu <leo....@amd.com> > --- > src/gallium/state_trackers/omx/vid_dec.c | 65 > +++++++++++++++++++++++++++++++- > src/gallium/state_trackers/omx/vid_dec.h | 6 ++- > 2 files changed, 68 insertions(+), 3 deletions(-) > > diff --git a/src/gallium/state_trackers/omx/vid_dec.c > b/src/gallium/state_trackers/omx/vid_dec.c > index a989c10..7842966 100644 > --- a/src/gallium/state_trackers/omx/vid_dec.c > +++ b/src/gallium/state_trackers/omx/vid_dec.c > @@ -167,6 +167,19 @@ static OMX_ERRORTYPE > vid_dec_Constructor(OMX_COMPONENTTYPE *comp, OMX_STRING nam > if (!priv->pipe) > return OMX_ErrorInsufficientResources; > > + if (!vl_compositor_init(&priv->compositor, priv->pipe)) { > + priv->pipe->destroy(priv->pipe); > + priv->pipe = NULL; > + return OMX_ErrorInsufficientResources; > + } > + > + if (!vl_compositor_init_state(&priv->cstate, priv->pipe)) { > + vl_compositor_cleanup(&priv->compositor); > + priv->pipe->destroy(priv->pipe); > + priv->pipe = NULL; > + return OMX_ErrorInsufficientResources; > + } > + > priv->sPortTypesParam[OMX_PortDomainVideo].nStartPortNumber = 0; > priv->sPortTypesParam[OMX_PortDomainVideo].nPorts = 2; > priv->ports = CALLOC(2, sizeof(omx_base_PortType *)); > @@ -218,8 +231,11 @@ static OMX_ERRORTYPE > vid_dec_Destructor(OMX_COMPONENTTYPE *comp) > priv->ports=NULL; > } > > - if (priv->pipe) > + if (priv->pipe) { > + vl_compositor_cleanup_state(&priv->cstate); > + vl_compositor_cleanup(&priv->compositor); > priv->pipe->destroy(priv->pipe); > + } > > if (priv->screen) > omx_put_screen(); > @@ -547,6 +563,25 @@ static void vid_dec_FillOutput(vid_dec_PrivateType > *priv, struct pipe_video_buff > } > } > > +static void vid_dec_deint(vid_dec_PrivateType *priv, struct > pipe_video_buffer *src_buf, > + struct pipe_video_buffer *dst_buf) > +{ > + struct vl_compositor *compositor = &priv->compositor; > + struct vl_compositor_state *s = &priv->cstate; > + struct pipe_surface **dst_surface; > + > + dst_surface = dst_buf->get_surfaces(dst_buf); > + vl_compositor_clear_layers(s); > + > + vl_compositor_set_yuv_layer(s, compositor, 0, src_buf, NULL, NULL, > true); > + vl_compositor_set_layer_dst_area(s, 0, NULL); > + vl_compositor_render(s, compositor, dst_surface[0], NULL, false); > + > + vl_compositor_set_yuv_layer(s, compositor, 0, src_buf, NULL, NULL, > false); > + vl_compositor_set_layer_dst_area(s, 0, NULL); > + vl_compositor_render(s, compositor, dst_surface[1], NULL, false); > +} > + > static void vid_dec_FrameDecoded(OMX_COMPONENTTYPE *comp, > OMX_BUFFERHEADERTYPE* input, > OMX_BUFFERHEADERTYPE* output) > { > @@ -562,7 +597,33 @@ static void vid_dec_FrameDecoded(OMX_COMPONENTTYPE > *comp, OMX_BUFFERHEADERTYPE* > > if (input->pInputPortPrivate) { > if (output->pInputPortPrivate) { > - struct pipe_video_buffer *tmp = output->pOutputPortPrivate; > + struct pipe_video_buffer *tmp, *vbuf, *new_vbuf; > + > + tmp = output->pOutputPortPrivate; > + vbuf = input->pInputPortPrivate; > + if (vbuf->interlaced) { > + /* re-allocate the progressive buffer */ > + omx_base_video_PortType *port; > + struct pipe_video_buffer templat = {}; > + > + port = (omx_base_video_PortType *) > + priv->ports[OMX_BASE_FILTER_INPUTPORT_INDEX]; > + memset(&templat, 0, sizeof(templat)); > + templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420; > + templat.width = port->sPortParam.format.video.nFrameWidth; > + templat.height = port->sPortParam.format.video.nFrameHeight; > + templat.buffer_format = PIPE_FORMAT_NV12; > + templat.interlaced = false; > + new_vbuf = priv->pipe->create_video_buffer(priv->pipe, > &templat); > + > + /* convert the interlaced to the progressive */ > + vid_dec_deint(priv, input->pInputPortPrivate, new_vbuf); > + priv->pipe->flush(priv->pipe, NULL, 0); > + > + /* set the progrssive buffer for next round */ > + vbuf->destroy(vbuf); > + input->pInputPortPrivate = new_vbuf; > + } > output->pOutputPortPrivate = input->pInputPortPrivate; > input->pInputPortPrivate = tmp; > } else { > diff --git a/src/gallium/state_trackers/omx/vid_dec.h > b/src/gallium/state_trackers/omx/vid_dec.h > index 649d745..d268925 100644 > --- a/src/gallium/state_trackers/omx/vid_dec.h > +++ b/src/gallium/state_trackers/omx/vid_dec.h > @@ -51,6 +51,8 @@ > #include "os/os_thread.h" > #include "util/list.h" > > +#include "vl/vl_compositor.h" > + > #define OMX_VID_DEC_BASE_NAME "OMX.mesa.video_decoder" > > #define OMX_VID_DEC_MPEG2_NAME "OMX.mesa.video_decoder.mpeg2" > @@ -108,7 +110,9 @@ DERIVEDCLASS(vid_dec_PrivateType, > omx_base_filter_PrivateType) > bool frame_finished; \ > bool frame_started; \ > unsigned bytes_left; \ > - const void *slice; > + const void *slice; \ > + struct vl_compositor compositor; \ > + struct vl_compositor_state cstate; > ENDCLASS(vid_dec_PrivateType) > > OMX_ERRORTYPE vid_dec_LoaderComponent(stLoaderComponentType *comp); > -- > 1.9.1 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev