Ejemplo n.º 1
0
/** call control(FLUSH), and then process() to pop out all buffers */
static gboolean
codec_flush (GstDucatiVidDec * self, gboolean eos)
{
  gint err;

  GST_DEBUG_OBJECT (self, "flush: eos=%d", eos);

  /* note: flush is synchronized against _chain() to avoid calling
   * the codec from multiple threads
   */
  GST_PAD_STREAM_LOCK (self->sinkpad);

  if (G_UNLIKELY (self->first_in_buffer)) {
    return TRUE;
  }

  if (G_UNLIKELY (!self->codec)) {
    GST_WARNING_OBJECT (self, "no codec");
    return TRUE;
  }

  err = VIDDEC3_control (self->codec, XDM_FLUSH,
      self->dynParams, self->status);
  if (err) {
    GST_ERROR_OBJECT (self, "failed XDM_FLUSH");
    goto out;
  }

  self->inBufs->descs[0].bufSize.bytes = 0;
  self->inArgs->numBytes = 0;
  self->inArgs->inputID = 0;

  do {
    err = codec_process (self, eos, TRUE);
  } while (err != XDM_EFAIL);

  /* on a flush, it is normal (and not an error) for the last _process() call
   * to return an error..
   */
  err = XDM_EOK;

out:
  GST_PAD_STREAM_UNLOCK (self->sinkpad);
  GST_DEBUG_OBJECT (self, "done");

  return !err;
}
Ejemplo n.º 2
0
static void
gst_ducati_viddec_get_property (GObject * obj,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  GstDucatiVidDec *self = GST_DUCATIVIDDEC (obj);

  switch (prop_id) {
    case PROP_VERSION: {
      int err;
      char *version = gst_ducati_alloc_1d (VERSION_LENGTH);

      /* in case something fails: */
      snprintf (version, VERSION_LENGTH, "unsupported");

      if (! self->engine)
        engine_open (self);

      if (! self->codec)
        codec_create (self);

      if (self->codec) {
        self->status->data.buf = (XDAS_Int8 *) TilerMem_VirtToPhys (version);
        self->status->data.bufSize = VERSION_LENGTH;

        err = VIDDEC3_control (self->codec, XDM_GETVERSION,
            self->dynParams, self->status);
        if (err) {
          GST_ERROR_OBJECT (self, "failed XDM_GETVERSION");
        }

        self->status->data.buf = NULL;
        self->status->data.bufSize = 0;
      }

      g_value_set_string (value, version);

      MemMgr_Free (version);

      break;
    }
    default: {
      G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
      break;
    }
  }
}
Ejemplo n.º 3
0
static gboolean
codec_create (GstDucatiVidDec * self)
{
  gint err;
  const gchar *codec_name;

  codec_delete (self);

  if (G_UNLIKELY (!self->engine)) {
    GST_ERROR_OBJECT (self, "no engine");
    return FALSE;
  }

  /* these need to be set before VIDDEC3_create */
  self->params->maxWidth = self->width;
  self->params->maxHeight = self->height;

  codec_name = GST_DUCATIVIDDEC_GET_CLASS (self)->codec_name;

  /* create codec: */
  GST_DEBUG_OBJECT (self, "creating codec: %s", codec_name);
  self->codec = VIDDEC3_create (self->engine, (String)codec_name, self->params);

  if (!self->codec) {
    return FALSE;
  }

  err = VIDDEC3_control (self->codec, XDM_SETPARAMS, self->dynParams, self->status);
  if (err) {
    GST_ERROR_OBJECT (self, "failed XDM_SETPARAMS");
    return FALSE;
  }

  self->first_in_buffer = TRUE;
  self->first_out_buffer = TRUE;

  /* allocate input buffer and initialize inBufs: */
  self->inBufs->numBufs = 1;
  self->input = gst_ducati_alloc_1d (self->width * self->height);
  self->inBufs->descs[0].buf = (XDAS_Int8 *) TilerMem_VirtToPhys (self->input);
  self->inBufs->descs[0].memType = XDM_MEMTYPE_RAW;

  return TRUE;
}
Ejemplo n.º 4
0
static gint
codec_process (GstDucatiVidDec * self, gboolean send, gboolean flush)
{
  gint err;
  GstClockTime t;
  GstBuffer *outbuf = NULL;
  gint i;

  self->outArgs->outputID[0] = 0;
  self->outArgs->freeBufID[0] = 0;

  t = gst_util_get_timestamp ();
  err = VIDDEC3_process (self->codec,
      self->inBufs, self->outBufs, self->inArgs, self->outArgs);
  GST_INFO_OBJECT (self, "%10dns", (gint) (gst_util_get_timestamp () - t));

  if (err) {
    GST_WARNING_OBJECT (self, "err=%d, extendedError=%08x",
        err, self->outArgs->extendedError);

    err = VIDDEC3_control (self->codec, XDM_GETSTATUS,
        self->dynParams, self->status);

    GST_WARNING_OBJECT (self, "XDM_GETSTATUS: err=%d, extendedError=%08x",
        err, self->status->extendedError);

    if (XDM_ISFATALERROR (self->outArgs->extendedError) || flush) {
      /* we are processing for display and it is a non-fatal error, so lets
       * try to recover.. otherwise return the error
       */
      err = XDM_EFAIL;
    }
  }

  for (i = 0; self->outArgs->outputID[i]; i++) {
    if (G_UNLIKELY (self->first_out_buffer) && send) {
      /* send region of interest to sink on first buffer: */
      XDM_Rect *r = &(self->outArgs->displayBufs.bufDesc[0].activeFrameRegion);

      GST_DEBUG_OBJECT (self, "setting crop to %d, %d, %d, %d",
          r->topLeft.x, r->topLeft.y, r->bottomRight.x, r->bottomRight.y);

      gst_pad_push_event (self->srcpad,
          gst_event_new_crop (r->topLeft.y, r->topLeft.x,
              r->bottomRight.x - r->topLeft.x,
              r->bottomRight.y - r->topLeft.y));

      self->first_out_buffer = FALSE;
    }

    outbuf = codec_get_outbuf (self, self->outArgs->outputID[i]);
    if (send) {
      if (GST_IS_DUCATIBUFFER (outbuf)) {
        outbuf = gst_ducati_buffer_get (GST_DUCATIBUFFER (outbuf));
      }
      GST_DEBUG_OBJECT (self, "got buffer: %d %p (%" GST_TIME_FORMAT ")",
          i, outbuf, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)));
      gst_pad_push (self->srcpad, outbuf);
    } else {
      GST_DEBUG_OBJECT (self, "free buffer: %d %p", i, outbuf);
      gst_buffer_unref (outbuf);
    }
  }

  for (i = 0; self->outArgs->freeBufID[i]; i++) {
    codec_unlock_outbuf (self, self->outArgs->freeBufID[i]);
  }

  return err;
}
Ejemplo n.º 5
0
/*
 *  ======== call ========
 */
static VISA_Status call(VISA_Handle visaHandle, VISA_Msg visaMsg)
{
    _VIDDEC3_Msg *msg  = (_VIDDEC3_Msg *)visaMsg;
    VIDDEC3_Handle handle = (VIDDEC3_Handle)visaHandle;
    Int i;
    XDM2_BufDesc inBufs;
    XDM2_BufDesc outBufs;
    IVIDDEC3_OutArgs *pOutArgs;
    IVIDDEC3_Status *pStatus;
    IVIDDEC3_CodecClassConfig *codecClassConfig;
    Int numBufs;
    Bool success;

    /* get stub/skeleton config data; can be NULL (for old codecs) */
    codecClassConfig =
            (IVIDDEC3_CodecClassConfig *)VISA_getCodecClassConfig(visaHandle);

    /* perform the requested VIDDEC2 operation by parsing message. */
    switch (msg->visa.cmd) {

        case _VIDDEC3_CPROCESS: {
            /* unmarshall inBufs and outBufs */
            inBufs           = msg->cmd.process.inBufs;
            outBufs          = msg->cmd.process.outBufs;

            /* invalidate cache for all input buffers */
            for (i = 0, numBufs = 0; i < XDM_MAX_IO_BUFFERS; i++) {
                if (inBufs.descs[i].buf != NULL) {
                    /* valid member of sparse array,
                     * invalidate it unless user configured it not to
                     */
                    if (codecClassConfig != NULL &&
                        codecClassConfig->manageInBufsCache[i] == FALSE) {
                       /* do nothing, i.e. don't invalidate */
                    } else {
                        if (inBufs.descs[i].memType == XDM_MEMTYPE_RAW) {
                            Memory_cacheInv(inBufs.descs[i].buf,
                                    inBufs.descs[i].bufSize.bytes);
                        } else {
                            /* TODO:H are tiled buffers cacheable? */
                        }
                    }

                    if (++numBufs == inBufs.numBufs) {
                        break;
                    }
                }
            }

            /* invalidate cache for all output buffers */
            for (i = 0, numBufs = 0; i < XDM_MAX_IO_BUFFERS; i++) {
                if (outBufs.descs[i].buf != NULL) {
                    /* valid member of sparse array,
                     * invalidate it unless user configured it not to
                     */
                    if (codecClassConfig != NULL &&
                        codecClassConfig->manageOutBufsCache[i] == FALSE) {
                       /* do nothing, i.e. don't invalidate */
                    } else {
                        if (outBufs.descs[i].memType == XDM_MEMTYPE_RAW) {
                            Memory_cacheInv(outBufs.descs[i].buf,
                                    outBufs.descs[i].bufSize.bytes);
                        } else {
                            /* TODO:H are tiled buffers cacheable? */
                        }
                    }

                    if (++numBufs == outBufs.numBufs) {
                        break;
                    }
                }
            }

            /* unmarshall outArgs based on the "size" of inArgs */
            pOutArgs = (IVIDDEC3_OutArgs *)((UInt)(&(msg->cmd.process.inArgs)) +
                msg->cmd.process.inArgs.size);

            /*
             * Note, there's no need to invalidate cache for
             * pOutArgs->decodedBuf bufs nor pOutArgs->displayBufs
             * bufs as the app doesn't provide OUT buffers to the
             * algorithm via these fields.
             */

            /* make the process call */
            msg->visa.status = VIDDEC3_process(handle,
                &inBufs, &outBufs, &(msg->cmd.process.inArgs), pOutArgs);

            /*
             * We probably should only be doing this if msg->visa.status
             * is IVIDDEC3_EOK or _EFAIL and .extendedError is non-fatal.
             */

            /*
             * Writeback cache for all output buffers:
             *   - .decodedBufs
             *   - .displayBufs
             */
            /*
             * ======== .decodedBufs ========
             */

            success = writebackVideo2BufDesc(&pOutArgs->decodedBufs);
            if (!success) {
                return (VISA_EFAIL);
            }

            /*
             * ======== .displayBufs ========
             */

            /* identify which mode the displayBufs are returned as */
            if (pOutArgs->displayBufsMode == IVIDDEC3_DISPLAYBUFS_EMBEDDED) {

                /* the display buffers are embedded in the outArgs struct */
                for (i = 0; (pOutArgs->outputID[i] != 0) &&
                        (i < IVIDEO2_MAX_IO_BUFFERS); i++) {

                    success = writebackVideo2BufDesc(
                            &(pOutArgs->displayBufs.bufDesc[i]));

                    if (!success) {
                        return (VISA_EFAIL);
                    }
                }
            }
            else {
                /* the display buffers are pointed to in the outArgs struct */
                for (i = 0; (pOutArgs->outputID[i] != 0) &&
                        (i < IVIDEO2_MAX_IO_BUFFERS); i++) {

                    success = writebackVideo2BufDesc(
                            pOutArgs->displayBufs.pBufDesc[i]);

                    if (!success) {
                        return (VISA_EFAIL);
                    }
                }
            }

            /*
             * Note that any changes to individual outBufs[i] values made by
             * the codec will automatically update msg->cmd.process.outBufs
             * as we pass the outBufs array by reference.
             */

            break;
        }

        case _VIDDEC3_CCONTROL: {
            /* unmarshall status based on the "size" of params */
            pStatus = (IVIDDEC3_Status *)((UInt)(&(msg->cmd.control.params)) +
                msg->cmd.control.params.size);

            /* invalidate data buffer */
            if (pStatus->data.buf != NULL) {
                Memory_cacheInv(pStatus->data.buf, pStatus->data.bufSize);
            }

            msg->visa.status = VIDDEC3_control(handle, msg->cmd.control.id,
                &(msg->cmd.control.params), pStatus);

            /* writeback data buffer */
            if ((pStatus->data.buf != NULL) &&
                XDM_ISACCESSMODE_WRITE(pStatus->data.accessMask)) {

                Memory_cacheWb(pStatus->data.buf, pStatus->data.bufSize);

                /*
                 * Since we've cacheWb this buffer, we arguably should
                 * reflect this cache state and clear the WRITE bit in
                 * the .accessMask field.  However, we know the stub
                 * doesn't propogate this field to the calling app, so
                 * this extra buffer management detail isn't necessary:
                 *
                 * XDM_CLEARACCESSMODE_WRITE(pStatus->data.accessMask);
                 */
            }

            break;
        }

        default: {
            msg->visa.status = VISA_EFAIL;

            break;
        }
    }
    return (VISA_EOK);
}