summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers
diff options
context:
space:
mode:
authorLeo Liu <[email protected]>2016-07-04 16:32:48 -0400
committerLeo Liu <[email protected]>2016-07-12 09:27:53 -0400
commit55f0b97b407efedf1c4807604ed9d631fefe7ac3 (patch)
treefe96477baf05ae2ddcc94c2628c0aa51e6bd8aaa /src/gallium/state_trackers
parent82f875f4d800d05b04a8174e8863b2b70276bbb0 (diff)
st/omx/dec: convert decoder video buffer to progressive
with encode tunneling 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 <[email protected]> Acked-by: Christian König <[email protected]> Tested-by: Julien Isorce <[email protected]>
Diffstat (limited to 'src/gallium/state_trackers')
-rw-r--r--src/gallium/state_trackers/omx/vid_dec.c65
-rw-r--r--src/gallium/state_trackers/omx/vid_dec.h6
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 a989c107037..78429668bd1 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 649d745dfc0..d268925ab26 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);