Example #1
0
static GstFlowReturn
gst_kate_tiger_video_chain (GstPad * pad, GstBuffer * buf)
{
  GstKateTiger *tiger = GST_KATE_TIGER (gst_pad_get_parent (pad));
  GstFlowReturn rflow = GST_FLOW_OK;
  unsigned char *ptr;
  int ret;

  g_mutex_lock (tiger->mutex);

  GST_LOG_OBJECT (tiger, "got video frame, %u bytes", GST_BUFFER_SIZE (buf));

  /* draw on it */
  buf = gst_buffer_make_writable (buf);
  if (G_UNLIKELY (!buf)) {
    GST_WARNING_OBJECT (tiger, "Failed to make video buffer writable");
  } else {
    ptr = GST_BUFFER_DATA (buf);
    if (!ptr) {
      GST_WARNING_OBJECT (tiger,
          "Failed to get a pointer to video buffer data");
    } else {
      ret = tiger_renderer_set_buffer (tiger->tr, ptr, tiger->video_width, tiger->video_height, tiger->video_width * 4, 0);     // TODO: stride ?
      if (G_UNLIKELY (ret < 0)) {
        GST_WARNING_OBJECT (tiger,
            "Tiger renderer failed to set buffer to video frame: %d", ret);
      } else {
        kate_float t = GST_BUFFER_TIMESTAMP (buf) / (gdouble) GST_SECOND;
        ret = tiger_renderer_update (tiger->tr, t, 1);
        if (G_UNLIKELY (ret < 0)) {
          GST_WARNING_OBJECT (tiger, "Tiger renderer failed to update: %d",
              ret);
        } else {
          ret = tiger_renderer_render (tiger->tr);
          if (G_UNLIKELY (ret < 0)) {
            GST_WARNING_OBJECT (tiger,
                "Tiger renderer failed to render to video frame: %d", ret);
          } else {
            GST_LOG_OBJECT (tiger,
                "Tiger renderer rendered on video frame at %f", t);
          }
        }
      }
    }
  }
  rflow = gst_pad_push (tiger->srcpad, buf);

  gst_object_unref (tiger);

  g_mutex_unlock (tiger->mutex);

  return rflow;
}
Example #2
0
OggPlayErrorCode
oggplay_data_update_tiger(OggPlayKateDecode *decode, int active, ogg_int64_t presentation_time, OggPlayCallbackInfo *info) {

  OggPlayOverlayRecord  * record = NULL;
  OggPlayOverlayData    * data = NULL;
  size_t                size = sizeof (OggPlayOverlayRecord);
  int                   track = active && decode->use_tiger;
  int                   ret;
  kate_float            t = OGGPLAY_TIME_FP_TO_INT(presentation_time) / 1000.0f;

  if (!decode->decoder.initialised) return -1;

  if (track) {
    if (info) {
      if (info->required_records>0) {
        OggPlayDataHeader *header = info->records[0];
        data = (OggPlayOverlayData*)(header+1);
        if (decode->tr && data->rgb) {
#if WORDS_BIGENDIAN || IS_BIG_ENDIAN
          tiger_renderer_set_buffer(decode->tr, data->rgb, data->width, data->height, data->stride, 0);
#else
          tiger_renderer_set_buffer(decode->tr, data->rgb, data->width, data->height, data->stride, 1);
#endif
        }
        else {
          /* we're supposed to overlay on a frame, but the available frame has no RGB buffer */
          /* fprintf(stderr,"no RGB buffer found for video frame\n"); */
          return -1;
        }
      }
      else {
        /* we're supposed to overlay on a frame, but there is no frame available */
        /* fprintf(stderr,"no video frame to overlay on\n"); */
        return -1;
      }
    }
    else {
      // TODO: some way of knowing the size of the video we'll be drawing onto, if any
      int width = decode->k_state.ki->original_canvas_width;
      int height = decode->k_state.ki->original_canvas_height;
      long overlay_size;
      if (width <= 0 || height <= 0) {
        /* some default resolution if we're not overlaying onto a video and the canvas size is unknown */
        if (decode->default_width > 0 && decode->default_height > 0) {
          width = decode->default_width;
          height = decode->default_height;
        }
        else {
          width = 640;
          height = 480;
        }
      }
      /* check for integer overflow */
      ret = oggplay_mul_signed_overflow (width, height, &overlay_size);
      if (ret == E_OGGPLAY_TYPE_OVERFLOW) {
        return ret;
      }
      
      ret = oggplay_mul_signed_overflow (overlay_size, 4, &overlay_size);
      if (ret == E_OGGPLAY_TYPE_OVERFLOW) {
        return E_OGGPLAY_TYPE_OVERFLOW;
      }
      
      ret = oggplay_check_add_overflow (size, overlay_size, &size);
      if (ret == E_OGGPLAY_TYPE_OVERFLOW) {
        return E_OGGPLAY_TYPE_OVERFLOW;
      }

      record = (OggPlayOverlayRecord*)oggplay_calloc (1, size);
      if (!record)
        return E_OGGPLAY_OUT_OF_MEMORY;

      record->header.samples_in_record = 1;
      data= &(record->data);
      oggplay_data_initialise_header((OggPlayDecode *)decode, &(record->header));

      data->rgba = (unsigned char*)(record+1);
      data->rgb = NULL;
      data->width = width;
      data->height = height;
      data->stride = width*4;

      if (decode->tr && data->rgba) {
        tiger_renderer_set_buffer(decode->tr, data->rgba, data->width, data->height, data->stride, decode->swap_rgb);
      }

      oggplay_data_add_to_list(&decode->decoder, &(record->header));
      record->header.presentation_time=presentation_time;
    }
  }

  if (decode->tr) {
    tiger_renderer_update(decode->tr, t, track);
  }

  if (track) {
    /* buffer was either calloced, so already cleared, or already filled with video, so no clearing */
    if (decode->tr) {
      tiger_renderer_render(decode->tr);
    }
  }
  
  return E_OGGPLAY_CONTINUE;
}