13
0

ArdourCanvas::Image allow to set custom data instead of class pre-allocated memory.

This commit is contained in:
Robin Gareus 2013-04-17 20:26:09 +02:00
parent 9727a23111
commit 8f2a2877b5
3 changed files with 42 additions and 16 deletions

View File

@ -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);

View File

@ -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

View File

@ -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