summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/video_image_frame.cc22
-rw-r--r--libs/canvas/canvas/image.h22
-rw-r--r--libs/canvas/image.cc14
3 files changed, 42 insertions, 16 deletions
diff --git a/gtk2_ardour/video_image_frame.cc b/gtk2_ardour/video_image_frame.cc
index b10b546857..c892bacfa6 100644
--- a/gtk2_ardour/video_image_frame.cc
+++ b/gtk2_ardour/video_image_frame.cc
@@ -35,6 +35,13 @@
using namespace std;
using namespace ARDOUR;
+static void freedata_cb (uint8_t *d, void *arg) {
+ /* later this can be used with libharvid
+ * the buffer/videocacheline instead of freeing it
+ */
+ free (d);
+}
+
VideoImageFrame::VideoImageFrame (PublicEditor& ed, ArdourCanvas::Group& parent, int w, int h, std::string vsurl, std::string vfn)
: editor (ed)
, _parent(&parent)
@@ -117,7 +124,7 @@ VideoImageFrame::draw_line ()
const int rowstride = img->stride;
const int clip_height = img->height;
uint8_t *pixels, *p;
- pixels = img->data.get();
+ pixels = img->data;
int y;
for (y = 0;y < clip_height; y++) {
@@ -133,7 +140,7 @@ VideoImageFrame::fill_frame (const uint8_t r, const uint8_t g, const uint8_t b)
const int clip_height = img->height;
const int clip_width = img->width;
uint8_t *pixels, *p;
- pixels = img->data.get();
+ pixels = img->data;
int x,y;
for (y = 0; y < clip_height; ++y) {
@@ -152,7 +159,7 @@ VideoImageFrame::draw_x ()
const int clip_width = img->width;
const int clip_height = img->height;
uint8_t *pixels, *p;
- pixels = img->data.get();
+ pixels = img->data;
for (x = 0;x < clip_width; x++) {
y = clip_height * x / clip_width;
@@ -173,7 +180,7 @@ VideoImageFrame::cut_rightend ()
const int clip_height = img->height;
const int clip_width = img->width;
uint8_t *pixels, *p;
- pixels = img->data.get();
+ pixels = img->data;
if (rightend > clip_width) { return; }
int x,y;
@@ -233,10 +240,9 @@ VideoImageFrame::http_download_done (char *data){
cut_rightend();
image->put_image(img);
} else {
- img = image->get_image();
- /* TODO - have curl write directly to the shared memory region */
- memcpy((void*) img->data.get(), data, img->stride * img->height);
- free(data);
+ img = image->get_image(false);
+ img->data = (uint8_t*) data;
+ img->destroy_callback = &freedata_cb;
draw_line();
cut_rightend();
image->put_image(img);
diff --git a/libs/canvas/canvas/image.h b/libs/canvas/canvas/image.h
index a3b1a269ba..0dcf8e51b3 100644
--- a/libs/canvas/canvas/image.h
+++ b/libs/canvas/canvas/image.h
@@ -25,27 +25,42 @@
#include "canvas/item.h"
+typedef void (*ImageReleaseCallback)(uint8_t *d, void *arg);
+
namespace ArdourCanvas {
+
class Image : public Item
{
public:
Image (Group *, Cairo::Format, int width, int height);
struct Data {
- Data (boost::shared_array<uint8_t> d, int w, int h, int s, Cairo::Format fmt)
+ Data (uint8_t *d, int w, int h, int s, Cairo::Format fmt)
: data (d)
, width (w)
, height (h)
, stride (s)
, format (fmt)
+ , destroy_callback(NULL)
+ , destroy_arg(NULL)
{}
- boost::shared_array<uint8_t> data;
+ virtual ~Data () {
+ if (destroy_callback) {
+ destroy_callback(data, destroy_arg);
+ } else {
+ free(data);
+ }
+ }
+
+ uint8_t* data;
int width;
int height;
int stride;
Cairo::Format format;
+ ImageReleaseCallback destroy_callback;
+ void* destroy_arg;
};
/**
@@ -59,7 +74,8 @@ public:
* ... to avoid collisions with Image deletion, some synchronization method
* may be required or the use of shared_ptr<Image> or similar.
*/
- boost::shared_ptr<Data> get_image ();
+ boost::shared_ptr<Data> get_image (bool allocate_data = true);
+
/**
* Queues a Data object to be used to redraw this Image item
diff --git a/libs/canvas/image.cc b/libs/canvas/image.cc
index 71a5df64dd..b13859aeda 100644
--- a/libs/canvas/image.cc
+++ b/libs/canvas/image.cc
@@ -36,7 +36,7 @@ void
Image::render (Rect const& area, Cairo::RefPtr<Cairo::Context> context) const
{
if (_need_render && _pending) {
- _surface = Cairo::ImageSurface::create (_pending->data.get(),
+ _surface = Cairo::ImageSurface::create (_pending->data,
_pending->format,
_pending->width,
_pending->height,
@@ -59,14 +59,18 @@ Image::compute_bounding_box () const
}
boost::shared_ptr<Image::Data>
-Image::get_image ()
+Image::get_image (bool allocate_data)
{
/* can be called by any thread */
int stride = Cairo::ImageSurface::format_stride_for_width (_format, _width);
- boost::shared_ptr<Data> d (new Data (boost::shared_array<uint8_t> (new uint8_t[stride*_height]), _width, _height, stride, _format));
-
- return d;
+ if (allocate_data) {
+ boost::shared_ptr<Data> d (new Data (new uint8_t[stride*_height], _width, _height, stride, _format));
+ return d;
+ } else {
+ boost::shared_ptr<Data> d (new Data (NULL, _width, _height, stride, _format));
+ return d;
+ }
}
void