static void vid_dec_FrameDecoded(OMX_COMPONENTTYPE *comp, OMX_BUFFERHEADERTYPE* input, OMX_BUFFERHEADERTYPE* output) { vid_dec_PrivateType *priv = comp->pComponentPrivate; bool eos = !!(input->nFlags & OMX_BUFFERFLAG_EOS); if (!input->pInputPortPrivate) input->pInputPortPrivate = priv->Flush(priv); if (input->pInputPortPrivate) { if (output->pInputPortPrivate) { struct pipe_video_buffer *tmp = output->pOutputPortPrivate; output->pOutputPortPrivate = input->pInputPortPrivate; input->pInputPortPrivate = tmp; } else { vid_dec_FillOutput(priv, input->pInputPortPrivate, output); } output->nFilledLen = output->nAllocLen; } if (eos && input->pInputPortPrivate) vid_dec_FreeInputPortPrivate(input); else input->nFilledLen = 0; }
static void release_input_headers(vid_dec_PrivateType* priv) { int i; for (i = 0; i < priv->num_in_buffers; i++) { assert(!priv->in_port_disabled_); if (priv->in_buffers[i]->pInputPortPrivate) { vid_dec_FreeInputPortPrivate(priv->in_buffers[i]); } (void) tiz_krn_release_buffer (tiz_get_krn (handleOf (priv)), OMX_VID_DEC_AVC_INPUT_PORT_INDEX, priv->in_buffers[i]); priv->in_buffers[i] = NULL; } priv->p_inhdr_ = NULL; priv->num_in_buffers = 0; }
static void vid_dec_FrameDecoded(OMX_COMPONENTTYPE *comp, OMX_BUFFERHEADERTYPE* input, OMX_BUFFERHEADERTYPE* output) { vid_dec_PrivateType *priv = comp->pComponentPrivate; bool eos = !!(input->nFlags & OMX_BUFFERFLAG_EOS); OMX_TICKS timestamp; if (!input->pInputPortPrivate) { input->pInputPortPrivate = priv->Flush(priv, ×tamp); if (timestamp != OMX_VID_DEC_TIMESTAMP_INVALID) input->nTimeStamp = timestamp; } if (input->pInputPortPrivate) { if (output->pInputPortPrivate && !priv->disable_tunnel) { 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 = {}; struct u_rect src_rect, dst_rect; 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 */ src_rect.x0 = dst_rect.x0 = 0; src_rect.x1 = dst_rect.x1 = templat.width; src_rect.y0 = dst_rect.y0 = 0; src_rect.y1 = dst_rect.y1 = templat.height; vl_compositor_yuv_deint_full(&priv->cstate, &priv->compositor, input->pInputPortPrivate, new_vbuf, &src_rect, &dst_rect, VL_COMPOSITOR_WEAVE); /* set the progrssive buffer for next round */ vbuf->destroy(vbuf); input->pInputPortPrivate = new_vbuf; } output->pOutputPortPrivate = input->pInputPortPrivate; input->pInputPortPrivate = tmp; } else { vid_dec_FillOutput(priv, input->pInputPortPrivate, output); } output->nFilledLen = output->nAllocLen; output->nTimeStamp = input->nTimeStamp; } if (eos && input->pInputPortPrivate) vid_dec_FreeInputPortPrivate(input); else input->nFilledLen = 0; }
static OMX_ERRORTYPE vid_dec_FreeDecBuffer(omx_base_PortType *port, OMX_U32 idx, OMX_BUFFERHEADERTYPE *buf) { vid_dec_FreeInputPortPrivate(buf); return base_port_FreeBuffer(port, idx, buf); }
static OMX_ERRORTYPE vid_dec_DecodeBuffer(omx_base_PortType *port, OMX_BUFFERHEADERTYPE *buf) { OMX_COMPONENTTYPE* comp = port->standCompContainer; vid_dec_PrivateType *priv = comp->pComponentPrivate; unsigned i = priv->num_in_buffers++; OMX_ERRORTYPE r; priv->in_buffers[i] = buf; priv->sizes[i] = buf->nFilledLen; priv->inputs[i] = buf->pBuffer; priv->timestamps[i] = buf->nTimeStamp; while (priv->num_in_buffers > (!!(buf->nFlags & OMX_BUFFERFLAG_EOS) ? 0 : 1)) { bool eos = !!(priv->in_buffers[0]->nFlags & OMX_BUFFERFLAG_EOS); unsigned min_bits_left = eos ? 32 : MAX2(buf->nFilledLen * 8, 32); struct vl_vlc vlc; vl_vlc_init(&vlc, priv->num_in_buffers, priv->inputs, priv->sizes); if (priv->slice) priv->bytes_left = vl_vlc_bits_left(&vlc) / 8; while (vl_vlc_bits_left(&vlc) > min_bits_left) { priv->Decode(priv, &vlc, min_bits_left); vl_vlc_fillbits(&vlc); } if (priv->slice) { unsigned bytes = priv->bytes_left - vl_vlc_bits_left(&vlc) / 8; priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base, 1, &priv->slice, &bytes); if (priv->num_in_buffers) priv->slice = priv->inputs[1]; else priv->slice = NULL; } if (eos && priv->frame_started) priv->EndFrame(priv); if (priv->frame_finished) { priv->frame_finished = false; priv->in_buffers[0]->nFilledLen = priv->in_buffers[0]->nAllocLen; r = base_port_SendBufferFunction(port, priv->in_buffers[0]); } else if (eos) { vid_dec_FreeInputPortPrivate(priv->in_buffers[0]); priv->in_buffers[0]->nFilledLen = priv->in_buffers[0]->nAllocLen; r = base_port_SendBufferFunction(port, priv->in_buffers[0]); } else { priv->in_buffers[0]->nFilledLen = 0; r = port->ReturnBufferFunction(port, priv->in_buffers[0]); } if (--priv->num_in_buffers) { unsigned delta = MIN2((min_bits_left - vl_vlc_bits_left(&vlc)) / 8, priv->sizes[1]); priv->in_buffers[0] = priv->in_buffers[1]; priv->sizes[0] = priv->sizes[1] - delta; priv->inputs[0] = priv->inputs[1] + delta; priv->timestamps[0] = priv->timestamps[1]; } if (r) return r; } return OMX_ErrorNone; }
static OMX_ERRORTYPE decode_frame(vid_dec_PrivateType*priv, OMX_BUFFERHEADERTYPE *in_buf) { unsigned i = priv->num_in_buffers++; priv->in_buffers[i] = in_buf; priv->sizes[i] = in_buf->nFilledLen; priv->inputs[i] = in_buf->pBuffer; priv->timestamps[i] = in_buf->nTimeStamp; while (priv->num_in_buffers > (!!(in_buf->nFlags & OMX_BUFFERFLAG_EOS) ? 0 : 1)) { priv->eos_ = !!(priv->in_buffers[0]->nFlags & OMX_BUFFERFLAG_EOS); unsigned min_bits_left = priv->eos_ ? 32 : MAX2(in_buf->nFilledLen * 8, 32); struct vl_vlc vlc; vl_vlc_init(&vlc, priv->num_in_buffers, priv->inputs, priv->sizes); if (priv->slice) priv->bytes_left = vl_vlc_bits_left(&vlc) / 8; while (vl_vlc_bits_left (&vlc) > min_bits_left) { vid_dec_h264_Decode(priv, &vlc, min_bits_left); vl_vlc_fillbits(&vlc); } if (priv->slice) { unsigned bytes = priv->bytes_left - vl_vlc_bits_left(&vlc) / 8; priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base, 1, &priv->slice, &bytes); if (priv->num_in_buffers) priv->slice = priv->inputs[1]; else priv->slice = NULL; } if (priv->eos_ && priv->frame_started) vid_dec_h264_EndFrame(priv); if (priv->frame_finished) { priv->frame_finished = false; h264d_manage_buffers(priv); } else if (priv->eos_) { vid_dec_FreeInputPortPrivate(priv->in_buffers[0]); h264d_manage_buffers(priv); } else { priv->in_buffers[0]->nFilledLen = 0; h264d_buffer_emptied(priv, priv->in_buffers[0]); } if (priv->out_port_disabled_) { /* In case out port is disabled, h264d_buffer_emptied will fail to release input port. * We need to wait before shifting the buffers in that case and check in * get_input_buffer when out port is enabled to release and shift the buffers. * Infinite looping occurs if buffer is not released */ if (priv->num_in_buffers == 2) { /* Set the delta value for use in get_input_buffer before exiting */ dec_frame_delta = MIN2((min_bits_left - vl_vlc_bits_left(&vlc)) / 8, priv->sizes[1]); } break; } h264d_shift_buffers_left(priv); } return OMX_ErrorNone; }