Exemple #1
0
static void
vlVdpDecoderFixVC1Startcode(uint32_t *num_buffers, const void *buffers[], unsigned sizes[])
{
   static const uint8_t vc1_startcode[] = { 0x00, 0x00, 0x01, 0x0D };
   struct vl_vlc vlc;
   unsigned i;

   /* search the first 64 bytes for a startcode */
   vl_vlc_init(&vlc, *num_buffers, buffers, sizes);
   while (vl_vlc_search_byte(&vlc, 64*8, 0x00) && vl_vlc_bits_left(&vlc) >= 32) {
      uint32_t value = vl_vlc_peekbits(&vlc, 32);
      if (value == 0x0000010D ||
          value == 0x0000010C ||
          value == 0x0000010B)
         return;
      vl_vlc_eatbits(&vlc, 8);
   }

   /* none found, ok add one manually */
   VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Manually adding VC-1 startcode\n");
   for (i = *num_buffers; i > 0; --i) {
      buffers[i] = buffers[i - 1];
      sizes[i] = sizes[i - 1];
   }
   ++(*num_buffers);
   buffers[0] = vc1_startcode;
   sizes[0] = 4;
}
Exemple #2
0
static unsigned int
bufHasStartcode(vlVaBuffer *buf, unsigned int code, unsigned int bits)
{
   struct vl_vlc vlc = {0};
   int i;

   /* search the first 64 bytes for a startcode */
   vl_vlc_init(&vlc, 1, (const void * const*)&buf->data, &buf->size);
   for (i = 0; i < 64 && vl_vlc_bits_left(&vlc) >= bits; ++i) {
      if (vl_vlc_peekbits(&vlc, bits) == code)
         return 1;
      vl_vlc_eatbits(&vlc, 8);
      vl_vlc_fillbits(&vlc);
   }

   return 0;
}
Exemple #3
0
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;
}
Exemple #4
0
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;
}