aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/Makefile7
-rw-r--r--modules/Makefile.in7
-rw-r--r--modules/pdp_ascii.c1
-rw-r--r--modules/pdp_compose.c47
-rw-r--r--modules/pdp_ctrack.c4
-rw-r--r--modules/pdp_ffmpeg~.c42
-rw-r--r--modules/pdp_form.c18
-rw-r--r--modules/pdp_i.c49
-rw-r--r--modules/pdp_live~.c324
-rw-r--r--modules/pdp_o.c25
-rw-r--r--modules/pdp_ocanvas.c22
-rw-r--r--modules/pdp_pen.c22
-rw-r--r--modules/pdp_rec~.c5
-rw-r--r--modules/pdp_shape.c29
-rw-r--r--modules/pdp_text.c20
-rw-r--r--modules/pdp_underwatch.c7
-rw-r--r--modules/pdp_yqt.c5
17 files changed, 439 insertions, 195 deletions
diff --git a/modules/Makefile b/modules/Makefile
index 1bca11a..66847ff 100644
--- a/modules/Makefile
+++ b/modules/Makefile
@@ -15,7 +15,10 @@ OBJECTS = pdp_intrusion.o pdp_yqt.o pdp_simura.o pdp_underwatch.o \
pdp_capture.o pdp_smuck.o pdp_lumafilt.o \
pdp_transition.o pdp_imgloader.o pdp_imgsaver.o pdp_cache.o \
pdp_canvas.o pdp_pen.o pdp_shape.o pdp_fqt.o pdp_fcqt.o \
- pdp_ocanvas.o pdp_spotlight.o pdp_colorgrid.o pdp_live~.o pdp_ffmpeg~.o
- # pdp_xcanvas.o pdp_aa.o
+ pdp_ocanvas.o pdp_spotlight.o pdp_colorgrid.o \
+ pdp_binary.o pdp_erode.o pdp_dilate.o pdp_hitandmiss.o \
+ pdp_disintegration.o pdp_distance.o pdp_theorin~.o \
+ pdp_theorout~.o pdp_cropper.o pdp_background.o \
+ pdp_live~.o pdp_ffmpeg~.o # pdp_xcanvas.o pdp_aa.o
all_modules: $(OBJECTS)
diff --git a/modules/Makefile.in b/modules/Makefile.in
index 7d9daad..56fe02b 100644
--- a/modules/Makefile.in
+++ b/modules/Makefile.in
@@ -15,7 +15,10 @@ OBJECTS = pdp_intrusion.o pdp_yqt.o pdp_simura.o pdp_underwatch.o \
pdp_capture.o pdp_smuck.o pdp_lumafilt.o \
pdp_transition.o pdp_imgloader.o pdp_imgsaver.o pdp_cache.o \
pdp_canvas.o pdp_pen.o pdp_shape.o pdp_fqt.o pdp_fcqt.o \
- pdp_ocanvas.o pdp_spotlight.o pdp_colorgrid.o @PDP_STREAMING_OBJECTS@
- # pdp_xcanvas.o pdp_aa.o
+ pdp_ocanvas.o pdp_spotlight.o pdp_colorgrid.o \
+ pdp_binary.o pdp_erode.o pdp_dilate.o pdp_hitandmiss.o \
+ pdp_disintegration.o pdp_distance.o pdp_theorin~.o \
+ pdp_theorout~.o pdp_cropper.o pdp_background.o \
+ @PDP_STREAMING_OBJECTS@ # pdp_xcanvas.o pdp_aa.o
all_modules: $(OBJECTS)
diff --git a/modules/pdp_ascii.c b/modules/pdp_ascii.c
index a43956c..e81d3f2 100644
--- a/modules/pdp_ascii.c
+++ b/modules/pdp_ascii.c
@@ -27,6 +27,7 @@
#include "yuv.h"
#include "default.map"
#include <math.h>
+#include <stdio.h>
#define LINE_MAX_LENGTH 1024
diff --git a/modules/pdp_compose.c b/modules/pdp_compose.c
index aad03a9..998c3a3 100644
--- a/modules/pdp_compose.c
+++ b/modules/pdp_compose.c
@@ -61,7 +61,9 @@ typedef struct pdp_compose_struct
t_float x_f;
t_int x_packet0;
+ t_int x_packet1;
t_int x_dropped;
+ t_int x_queue_id;
t_int x_vwidth;
t_int x_vheight;
@@ -228,6 +230,8 @@ static void pdp_compose_process_yv12(t_pdp_compose *x)
{
t_pdp *header = pdp_packet_header(x->x_packet0);
short int *data = (short int *)pdp_packet_data(x->x_packet0);
+ t_pdp *newheader = pdp_packet_header(x->x_packet1);
+ short int *newdata = (short int *)pdp_packet_data(x->x_packet1);
t_int i, cf;
t_int px=0, py=0, ppx=0, ppy=0, found=0, xcell=0, ycell=0;
t_int celldiff=0, cellwidth=0, cellheight=0;
@@ -285,9 +289,9 @@ static void pdp_compose_process_yv12(t_pdp_compose *x)
pfY = x->x_frame;
pfV = x->x_frame+x->x_vsize;
pfU = x->x_frame+x->x_vsize+(x->x_vsize>>2);
- pdY = data;
- pdV = data+x->x_vsize;
- pdU = data+x->x_vsize+(x->x_vsize>>2);
+ pdY = newdata;
+ pdV = newdata+x->x_vsize;
+ pdU = newdata+x->x_vsize+(x->x_vsize>>2);
prY = x->x_right_frame;
prV = x->x_right_frame+x->x_vsize;
prU = x->x_right_frame+x->x_vsize+(x->x_vsize>>2);
@@ -326,11 +330,18 @@ static void pdp_compose_process_yv12(t_pdp_compose *x)
}
}
- pdp_packet_pass_if_valid(x->x_pdp_output, &x->x_packet0);
-
return;
}
+static void pdp_compose_sendpacket(t_pdp_compose *x)
+{
+ pdp_packet_mark_unused(x->x_packet0);
+ x->x_packet0=-1;
+
+ /* unregister and propagate if valid dest packet */
+ pdp_packet_pass_if_valid(x->x_pdp_output, &x->x_packet1);
+}
+
static void pdp_compose_process(t_pdp_compose *x)
{
int encoding;
@@ -344,7 +355,8 @@ static void pdp_compose_process(t_pdp_compose *x)
switch(pdp_packet_header(x->x_packet0)->info.image.encoding){
case PDP_IMAGE_YV12:
- pdp_compose_process_yv12(x);
+ x->x_packet1 = pdp_packet_clone_rw(x->x_packet0);
+ pdp_queue_add(x, pdp_compose_process_yv12, pdp_compose_sendpacket, &x->x_queue_id);
break;
case PDP_IMAGE_GREY:
@@ -365,20 +377,24 @@ static void pdp_compose_input_1(t_pdp_compose *x, t_symbol *s, t_floatarg f)
{
short int *rightdata = (short int *)pdp_packet_data((int)f);
- if (s== gensym("register_rw")) memcpy(x->x_right_frame, rightdata, (x->x_vsize + (x->x_vsize>>1))<<1 );
+ if ( s== gensym("register_rw") )
+ {
+ memcpy(x->x_right_frame, rightdata, (x->x_vsize + (x->x_vsize>>1))<<1 );
+ }
+
+ pdp_packet_mark_unused( (int)f );
}
static void pdp_compose_input_0(t_pdp_compose *x, t_symbol *s, t_floatarg f)
{
- /* if this is a register_ro message or register_rw message, register with packet factory */
-
- if (s== gensym("register_rw"))
+ if ( s== gensym("register_rw") )
+ {
x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") );
+ }
- if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){
-
+ if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped))
+ {
pdp_compose_process(x);
-
}
}
@@ -386,7 +402,8 @@ static void pdp_compose_free(t_pdp_compose *x)
{
int i;
- pdp_packet_mark_unused(x->x_packet0);
+ pdp_queue_finish(x->x_queue_id);
+ pdp_packet_mark_unused(x->x_packet1);
pdp_compose_free_ressources( x );
}
@@ -416,6 +433,8 @@ void *pdp_compose_new(void)
x->x_colorV = (yuv_RGBtoV( (x->x_colorR << 16) + (x->x_colorG << 8) + x->x_colorB )-128)<<8;
x->x_packet0 = -1;
+ x->x_packet1 = -1;
+ x->x_queue_id = -1;
x->x_cursX = -1;
x->x_cursY = -1;
diff --git a/modules/pdp_ctrack.c b/modules/pdp_ctrack.c
index ed35c9b..fa56ea6 100644
--- a/modules/pdp_ctrack.c
+++ b/modules/pdp_ctrack.c
@@ -86,8 +86,8 @@ typedef struct pdp_ctrack_struct
t_outlet *x_x2; // output x2 coordinate of block which has been detected
t_outlet *x_y2; // output y2 coordinate of block which has been detected
t_outlet *x_R; // output R component of selected color
- t_outlet *x_G; // output R component of selected color
- t_outlet *x_B; // output R component of selected color
+ t_outlet *x_G; // output G component of selected color
+ t_outlet *x_B; // output B component of selected color
t_canvas *x_canvas;
diff --git a/modules/pdp_ffmpeg~.c b/modules/pdp_ffmpeg~.c
index 58cdd61..3e229af 100644
--- a/modules/pdp_ffmpeg~.c
+++ b/modules/pdp_ffmpeg~.c
@@ -441,9 +441,18 @@ static void pdp_ffmpeg_process_yv12(t_pdp_ffmpeg *x)
oheight = x->x_avcontext->streams[i]->codec.height;
if (x->x_img_resample_ctx) img_resample_close(x->x_img_resample_ctx);
+
+#if LIBAVCODEC_BUILD > 4715
+ x->x_img_resample_ctx = img_resample_full_init(
+ owidth, oheight,
+ x->x_vwidth, x->x_vheight,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0);
+#else
x->x_img_resample_ctx = img_resample_full_init(
owidth, oheight,
x->x_vwidth, x->x_vheight, 0, 0, 0, 0);
+#endif
size = avpicture_get_size(x->x_avcontext->streams[i]->codec.pix_fmt,
owidth, oheight );
@@ -472,6 +481,9 @@ static void pdp_ffmpeg_process_yv12(t_pdp_ffmpeg *x)
// encode and send the picture
{
AVFrame aframe;
+#if LIBAVCODEC_BUILD > 4715
+ AVPacket vpkt;
+#endif
t_int fsize, ret;
memset(&aframe, 0, sizeof(AVFrame));
@@ -482,7 +494,21 @@ static void pdp_ffmpeg_process_yv12(t_pdp_ffmpeg *x)
fsize = avcodec_encode_video(&x->x_avcontext->streams[i]->codec,
x->x_video_buffer, VIDEO_BUFFER_SIZE,
&aframe);
+
+#if LIBAVCODEC_BUILD > 4715
+ av_init_packet(&vpkt);
+
+ vpkt.pts = aframe.pts;
+ if((&x->x_avcontext->streams[i]->codec)->coded_frame->key_frame)
+ vpkt.flags |= PKT_FLAG_KEY;
+ vpkt.stream_index= i;
+ vpkt.data= (uint8_t *)x->x_video_buffer;
+ vpkt.size= fsize;
+
+ if ( ( ret = av_write_frame( x->x_avcontext, &vpkt) ) < 0 )
+#else
if ( ( ret = av_write_frame( x->x_avcontext, i, x->x_video_buffer, fsize) ) < 0 )
+#endif
{
post ("pdp_ffmpeg~ : error : could not send frame : (ret=%d)", ret );
return;
@@ -549,10 +575,26 @@ static void pdp_ffmpeg_process_yv12(t_pdp_ffmpeg *x)
while (fifo_read(&x->x_audio_fifo[saudioindex], (uint8_t*)pencbuf, framebytes,
&x->x_audio_fifo[saudioindex].rptr) == 0)
{
+#if LIBAVCODEC_BUILD > 4715
+ AVPacket apkt;
+#endif
encsize = avcodec_encode_audio(&x->x_avcontext->streams[i]->codec,
(uint8_t*)&x->x_audio_out, sizeof(x->x_audio_out),
(short *)pencbuf);
+#if LIBAVCODEC_BUILD > 4715
+ av_init_packet(&apkt);
+
+ apkt.pts = etime.tv_sec*1000000 + etime.tv_usec;
+ if((&x->x_avcontext->streams[i]->codec)->coded_frame->key_frame)
+ apkt.flags |= PKT_FLAG_KEY;
+ apkt.stream_index= i;
+ apkt.data= (uint8_t *)x->x_audio_out;
+ apkt.size= encsize;
+
+ av_write_frame(x->x_avcontext, &apkt);
+#else
av_write_frame(x->x_avcontext, i, x->x_audio_out, encsize);
+#endif
}
saudioindex++;
}
diff --git a/modules/pdp_form.c b/modules/pdp_form.c
index ccbd510..b3a59b3 100644
--- a/modules/pdp_form.c
+++ b/modules/pdp_form.c
@@ -74,6 +74,7 @@ typedef struct pdp_form_struct
t_int x_nbforms;
t_int x_current;
t_int x_capacity;
+ t_float x_alpha;
/* imlib data */
Imlib_Image x_image;
@@ -312,6 +313,14 @@ static void pdp_form_delete(t_pdp_form *x, t_floatarg fnum )
}
}
+static void pdp_form_alpha(t_pdp_form *x, t_floatarg falpha )
+{
+ if ( ( falpha >= 0. ) && ( falpha <= 1. ) )
+ {
+ x->x_alpha = falpha;
+ }
+}
+
static void pdp_form_resize(t_pdp_form *x, t_floatarg fnewsize )
{
t_form *forms;
@@ -448,11 +457,11 @@ static void pdp_form_process_yv12(t_pdp_form *x)
u = yuv_RGBtoU(imdata[py*x->x_vwidth+px]);
v = yuv_RGBtoV(imdata[py*x->x_vwidth+px]);
- *(pY) = y<<7;
+ *(pY) = (y<<7)*x->x_alpha + (*pY)*(1-x->x_alpha);
if ( (px%2==0) && (py%2==0) )
{
- *(pV) = (v-128)<<8;
- *(pU) = (u-128)<<8;
+ *(pV) = ((v-128)<<8)*x->x_alpha + (*pV)*(1-x->x_alpha);
+ *(pU) = ((u-128)<<8)*x->x_alpha + (*pU)*(1-x->x_alpha);
}
}
pY++;
@@ -549,6 +558,7 @@ void *pdp_form_new(void)
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("r"));
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("g"));
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("b"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("alpha"));
x->x_outlet0 = outlet_new(&x->x_obj, &s_anything);
x->x_packet0 = -1;
@@ -567,6 +577,7 @@ void *pdp_form_new(void)
x->x_nbforms = 0;
x->x_current = -1;
+ x->x_alpha = 1.;
return (void *)x;
}
@@ -601,6 +612,7 @@ void pdp_form_setup(void)
class_addmethod(pdp_form_class, (t_method)pdp_form_clear, gensym("clear"), A_NULL);
class_addmethod(pdp_form_class, (t_method)pdp_form_delete, gensym("delete"), A_DEFFLOAT, A_NULL);
class_addmethod(pdp_form_class, (t_method)pdp_form_resize, gensym("resize"), A_DEFFLOAT, A_NULL);
+ class_addmethod(pdp_form_class, (t_method)pdp_form_alpha, gensym("alpha"), A_DEFFLOAT, A_NULL);
class_sethelpsymbol( pdp_form_class, gensym("pdp_form.pd") );
}
diff --git a/modules/pdp_i.c b/modules/pdp_i.c
index e18a077..a89a56c 100644
--- a/modules/pdp_i.c
+++ b/modules/pdp_i.c
@@ -178,7 +178,7 @@ static void pdp_i_recv(t_pdp_i *x)
t_hpacket *pheader;
if ( ( ret = recv(x->x_socket, (void*) (x->x_inbuffer + x->x_inwriteposition),
- (size_t)((x->x_inbuffersize-x->x_inwriteposition)),
+ (size_t)((x->x_inbuffersize-x->x_inwriteposition-1)),
MSG_NOSIGNAL) ) < 0 )
{
post( "pdp_i : receive error" );
@@ -189,7 +189,7 @@ static void pdp_i_recv(t_pdp_i *x)
{
// post( "pdp_i : received %d bytes at %d on %d ( up to %d)",
// ret, x->x_inwriteposition, x->x_socket,
- // x->x_inbuffersize-x->x_inwriteposition*sizeof( unsigned long) );
+ // x->x_inbuffersize-x->x_inwriteposition );
if ( ret == 0 )
{
@@ -197,29 +197,34 @@ static void pdp_i_recv(t_pdp_i *x)
outlet_float( x->x_connection_status, 0 );
pdp_i_closesocket( x->x_socket );
sys_rmpollfn(x->x_socket);
+ post( "pdp_i : lost the connection." );
x->x_socket = -1;
}
else
{
// check we don't overflow input buffer
- if ( x->x_inwriteposition+ret >= x->x_inbuffersize )
+ if ( x->x_inwriteposition+ret >= x->x_inbuffersize/2 )
{
post( "pdp_i : too much input...resetting" );
x->x_inwriteposition=0;
+ memset( (char*) x->x_inbuffer, 0x00, x->x_inbuffersize );
return;
}
x->x_inwriteposition += ret;
- if ( pheader = (t_hpacket*) strstr( (char*) x->x_inbuffer, PDP_PACKET_START ) )
+ if ( ( ( pheader = (t_hpacket*) strstr( (char*) x->x_inbuffer, PDP_PACKET_START ) ) != NULL ) ||
+ ( ( pheader = (t_hpacket*) strstr( (char*) x->x_inbuffer, PDP_PACKET_DIFF ) ) != NULL ) )
{
// check if a full packet is present
- if ( x->x_inwriteposition >= (int)((char*)pheader - (char*)(x->x_inbuffer)) + (int)sizeof(t_hpacket) + (int)pheader->clength )
+ if ( x->x_inwriteposition >=
+ (int)((char*)pheader - (char*)(x->x_inbuffer)) +
+ (int)sizeof(t_hpacket) + (int)ntohl(pheader->clength) )
{
- if ( ( x->x_vwidth != pheader->width ) ||
- ( x->x_vheight != pheader->height ) )
+ if ( ( x->x_vwidth != (t_int)ntohl(pheader->width) ) ||
+ ( x->x_vheight != (t_int)ntohl(pheader->height) ) )
{
pdp_i_free_ressources(x);
- x->x_vheight = pheader->height;
- x->x_vwidth = pheader->width;
+ x->x_vheight = ntohl(pheader->height);
+ x->x_vwidth = ntohl(pheader->width);
x->x_vsize = x->x_vheight*x->x_vwidth;
pdp_i_allocate(x);
post( "pdp_i : allocated buffers : vsize=%d : hsize=%d", x->x_vsize, x->x_hsize );
@@ -230,18 +235,18 @@ static void pdp_i_recv(t_pdp_i *x)
x->x_data = (short int *)pdp_packet_data(x->x_packet);
memcpy( x->x_data, x->x_bdata, x->x_bsize );
- // post( "pdp_i : decompress %d in %d bytes", pheader->clength, x->x_hsize );
+ // post( "pdp_i : decompress %d in %d bytes", ntohl(pheader->clength), x->x_hsize );
x->x_bzsize = x->x_hsize;
if ( ( ret = BZ2_bzBuffToBuffDecompress( (char*)x->x_hdata,
&x->x_bzsize,
(char *) pheader+sizeof(t_hpacket),
- pheader->clength,
+ ntohl(pheader->clength),
0, 0 ) ) == BZ_OK )
{
- // post( "pdp_i : bz2 decompression (%d)->(%d)", pheader->clength, x->x_bzsize );
+ // post( "pdp_i : bz2 decompression (%d)->(%d)", ntohl(pheader->clength), x->x_bzsize );
- switch( pheader->encoding )
+ switch( ntohl(pheader->encoding) )
{
case REGULAR :
memcpy( x->x_ddata, x->x_hdata, x->x_bzsize );
@@ -285,8 +290,8 @@ static void pdp_i_recv(t_pdp_i *x)
x->x_header->info.image.width = x->x_vwidth;
x->x_header->info.image.height = x->x_vheight;
- pdp_packet_pass_if_valid(x->x_pdp_output, &x->x_packet);
// post( "pdp_i : propagate packet : %d", x->x_packet );
+ pdp_packet_pass_if_valid(x->x_pdp_output, &x->x_packet);
outlet_float( x->x_frames, ++x->x_framesreceived );
}
else
@@ -297,8 +302,20 @@ static void pdp_i_recv(t_pdp_i *x)
memcpy( x->x_bdata, x->x_data, x->x_bsize );
// roll buffer
- x->x_inwriteposition -= (int)((char*)pheader-(char*)(x->x_inbuffer)) + sizeof(t_hpacket) + pheader->clength;
- memcpy( x->x_inbuffer, pheader+sizeof(t_hpacket) + pheader->clength, x->x_inwriteposition );
+ x->x_inwriteposition -= (int)((char*)pheader-(char*)(x->x_inbuffer)) + sizeof(t_hpacket) + ntohl(pheader->clength);
+ if ( x->x_inwriteposition > 0 )
+ {
+ memcpy( x->x_inbuffer, pheader+sizeof(t_hpacket) + ntohl(pheader->clength), x->x_inwriteposition );
+ }
+ else
+ {
+ x->x_inwriteposition = 0;
+ memset( (char*) x->x_inbuffer, 0x00, x->x_inbuffersize );
+ }
+ }
+ else
+ {
+ // post( "pdp_i : not a full frame" );
}
}
}
diff --git a/modules/pdp_live~.c b/modules/pdp_live~.c
index cae6a65..c403a15 100644
--- a/modules/pdp_live~.c
+++ b/modules/pdp_live~.c
@@ -35,6 +35,8 @@
#include <sys/time.h>
#include <sys/resource.h>
#include <avformat.h>
+#include <sys/types.h>
+#include <signal.h>
#define VIDEO_BUFFER_SIZE (1024*1024)
#define MAX_AUDIO_PACKET_SIZE (128 * 1024)
@@ -46,8 +48,8 @@
#define DEFAULT_HEIGHT 240
#define DEFAULT_FRAME_RATE 25
#define END_OF_STREAM 20
-#define MIN_PRIORITY -20
-#define DEFAULT_PRIORITY 0
+#define MIN_PRIORITY 0
+#define DEFAULT_PRIORITY 1
#define MAX_PRIORITY 20
/* a trick to cope with ffmpeg versions */
@@ -66,7 +68,7 @@ typedef struct pdp_live_struct
t_int x_dropped;
t_pdp *x_header;
- short int *x_data;
+ unsigned char *x_data;
t_int x_vwidth;
t_int x_vheight;
t_int x_vsize;
@@ -82,10 +84,14 @@ typedef struct pdp_live_struct
pthread_t x_connectchild; // thread used for connecting to a stream
pthread_t x_decodechild; // stream decoding thread
t_int x_usethread; // flag to activate decoding in a thread
+ t_int x_autoplay; // flag to autoplay the file ( default = true )
+ t_int x_nextimage; // flag to play next image in manual mode
t_int x_priority; // priority of decoding thread
char *x_url;
t_int x_streaming; // streaming flag
+ t_int x_decoding; // decoding flag
+ t_int x_loop; // looping flag ( default = on )
t_int x_nopackets; // no packet to decode
t_int x_endofstream; // end of the stream reached
t_int x_nbframes; // number of frames emitted
@@ -108,6 +114,7 @@ typedef struct pdp_live_struct
AVPicture x_picture_decoded;
long long int x_pts; // presentation time stamp
long long int x_previouspts; // previous presentation time stamp
+ long long int x_firstpts; // first presentation time stamp ( time origin )
t_int x_newpicture;
/* audio structures */
@@ -137,19 +144,80 @@ static void pdp_live_threadify(t_pdp_live *x, t_floatarg fusethread )
static void pdp_live_audio(t_pdp_live *x, t_floatarg faudio )
{
- if ( ( faudio == 0.0 ) || ( faudio == 1 ) )
+ if ( ( faudio == 0. ) || ( faudio == 1. ) )
{
x->x_audio = (int)faudio;
}
}
+static void pdp_live_autoplay(t_pdp_live *x, t_floatarg fautoplay )
+{
+ if ( ( fautoplay == 0. ) || ( fautoplay == 1. ) )
+ {
+ x->x_autoplay = (int)fautoplay;
+ }
+}
+
+static void pdp_live_loop(t_pdp_live *x, t_floatarg floop )
+{
+ if ( ( floop == 0. ) || ( floop == 1. ) )
+ {
+ x->x_loop = (int)floop;
+ }
+}
+
+static void pdp_live_bang(t_pdp_live *x)
+{
+ if ( x->x_nextimage == 1 )
+ {
+ // post( "pdp_live~ : banging too fast, previous image is not decoded yet... ignored" );
+ return;
+ }
+ x->x_nextimage = 1;
+}
+
+static void pdp_live_frame_cold(t_pdp_live *x, t_floatarg frameindex)
+{
+ int frame = (int)frameindex;
+ int ret;
+ uint64_t newpts;
+
+ if (!(x->x_streaming)) return;
+
+#if FFMPEG_VERSION_INT >= 0x000409
+ if ( ( ( x->x_avcontext->iformat->flags & AVFMT_NOFILE ) == 0 ) && ( x->x_videoindex != -1 ) )
+ {
+ if ( x->x_framerate != 0 )
+ {
+ newpts = x->x_firstpts + ( frame * 1000000 ) / x->x_framerate;
+ }
+ else
+ {
+ post( "pdp_live~ : couldn't seek requested frame ( framerate = %d )", x->x_framerate );
+ return;
+ }
+ if ( ( ret = av_seek_frame(x->x_avcontext, x->x_videoindex, newpts) ) < 0 )
+ {
+ post( "pdp_live~ : couldn't seek the requested frame (ret=%d)", ret );
+ }
+ }
+#else
+ post( "pdp_live~ : no seek function with ffmpeg < 4.0.9");
+#endif
+}
+
static t_int pdp_live_decode_packet(t_pdp_live *x)
{
- t_int chunksize=0, length;
+ t_int chunksize=0, length, err, ret;
t_int audiosize, sizeout, imagesize, pictureok;
AVFrame frame;
uint8_t *pcktptr;
- struct timeval etime;
+ unsigned char *pY, *pU, *pV;
+ uint8_t *psY, *psU, *psV;
+ t_int px, py;
+ long long tplaying;
+ long long ttheoretical;
+ struct timeval ctime;
struct timespec mwait;
if ( !x->x_streaming )
@@ -159,13 +227,35 @@ static t_int pdp_live_decode_packet(t_pdp_live *x)
// post( "pdp_live~ : trying to read packet" );
// read new packet on the stream
- if (av_read_packet(x->x_avcontext, &x->x_pkt) < 0)
+ if ( x->x_streaming && av_read_packet(x->x_avcontext, &x->x_pkt) < 0)
{
x->x_nopackets++;
// post( "pdp_live~ : decoding thread : nothing to decode : no packets :%d", x->x_nopackets );
if ( x->x_nopackets > END_OF_STREAM )
{
x->x_endofstream = 1;
+ if ( x->x_loop )
+ {
+
+#if FFMPEG_VERSION_INT >= 0x000409
+
+ if ( ( x->x_avcontext->iformat->flags & AVFMT_NOFILE ) == 0 )
+ {
+ post( "pdp_live~ : looping file reading..." );
+ if ( ( ret = av_seek_frame(x->x_avcontext, x->x_videoindex, 0) ) < 0 )
+ {
+ post( "pdp_live~ : couldn't seek the requested frame (ret=%d)", ret );
+ }
+ else
+ {
+ x->x_endofstream = 0;
+ }
+ }
+
+#else
+ post( "pdp_live~ : no seek function with ffmpeg < 4.0.9");
+#endif
+ }
}
return -1;
}
@@ -182,6 +272,7 @@ static t_int pdp_live_decode_packet(t_pdp_live *x)
pcktptr = x->x_pkt.data;
while (length > 0)
{
+ if ( !x->x_streaming ) break;
switch(x->x_avcontext->streams[x->x_pkt.stream_index]->codec.codec_type)
{
case CODEC_TYPE_AUDIO:
@@ -240,7 +331,7 @@ static t_int pdp_live_decode_packet(t_pdp_live *x)
post( "pdp_live~ : audio overflow : packet ignored...");
x->x_audioin_position = 0;
}
- if ( ( x->x_audioin_position > x->x_blocksize ) && (!x->x_audioon) )
+ if ( ( x->x_audioin_position > 4*x->x_blocksize ) && (!x->x_audioon) )
{
x->x_audioon = 1;
// post( "pdp_live~ : audio on" );
@@ -253,20 +344,9 @@ static t_int pdp_live_decode_packet(t_pdp_live *x)
x->x_avcontext->streams[x->x_pkt.stream_index]->codec.height * 3) / 2; // yuv planar
x->x_framerate = x->x_avcontext->streams[x->x_pkt.stream_index]->codec.frame_rate / 10000;
+ if ( x->x_framerate == 0 ) x->x_framerate = DEFAULT_FRAME_RATE;
x->x_videoindex = x->x_pkt.stream_index;
- // calculate actual frame rate
- // if ( gettimeofday(&etime, NULL) == -1)
- // {
- // post("pdp_live~ : could not read time" );
- // }
- // if ( ( etime.tv_sec - x->x_starttime.tv_sec ) > 0 )
- // {
- // x->x_framerate = x->x_nbframes / ( etime.tv_sec - x->x_starttime.tv_sec );
- // }
- // if ( x->x_framerate == 0 ) x->x_framerate = 1;
- // post ("pdp_live~ : frame rate is %d", x->x_framerate );
-
chunksize = avcodec_decode_video(
&x->x_avcontext->streams[x->x_pkt.stream_index]->codec,
&frame, &pictureok,
@@ -304,37 +384,74 @@ static t_int pdp_live_decode_packet(t_pdp_live *x)
else
{
x->x_newpicture=1;
- x->x_previouspts = x->x_pts;
- x->x_pts = frame.pts;
- // post( "pdp_live : frame pts : %ld", x->x_pts );
x->x_vwidth = x->x_avcontext->streams[x->x_pkt.stream_index]->codec.width;
x->x_vheight = x->x_avcontext->streams[x->x_pkt.stream_index]->codec.height;
x->x_vsize = x->x_vwidth*x->x_vheight;
- if ( x->x_previouspts != -1 )
+ // create a new pdp packet from BITMAP YV12 image format
+ x->x_packet0 = pdp_packet_new_bitmap_yv12( x->x_vwidth, x->x_vheight );
+ x->x_header = pdp_packet_header(x->x_packet0);
+ x->x_data = (unsigned char *)pdp_packet_data(x->x_packet0);
+
+ pY = x->x_data;
+ pV = x->x_data+x->x_vsize;
+ pU = x->x_data+x->x_vsize+(x->x_vsize>>2);
+
+ psY = x->x_picture_decoded.data[0];
+ psU = x->x_picture_decoded.data[1];
+ psV = x->x_picture_decoded.data[2];
+
+ for ( py=0; py<x->x_vheight; py++)
+ {
+ memcpy( (void*)pY, (void*)psY, x->x_vwidth );
+ pY += x->x_vwidth;
+ psY += x->x_picture_decoded.linesize[0];
+ if ( py%2==0 )
+ {
+ memcpy( (void*)pU, (void*)psU, (x->x_vwidth>>1) );
+ memcpy( (void*)pV, (void*)psV, (x->x_vwidth>>1) );
+ pU += (x->x_vwidth>>1);
+ pV += (x->x_vwidth>>1);
+ psU += x->x_picture_decoded.linesize[1];
+ psV += x->x_picture_decoded.linesize[2];
+ }
+ }
+
+ if ( x->x_firstpts == -1 )
{
- mwait.tv_sec = 0;
- mwait.tv_nsec = (x->x_pts - x->x_previouspts)*1000;
-
- if ( ( x->x_pts == 0 ) )
- {
- // post("pdp_live~ : no presentation time stamp, using framerate :%d",
- // x->x_framerate );
- mwait.tv_sec = 0;
- mwait.tv_nsec = 1000000000/((x->x_framerate+5)); // the +5 is experimental
- // it comes from the time used in decoding
- }
-
- nanosleep( &mwait, NULL ); // wait between the two successive frames
- // i know, cheap flow control
+ x->x_firstpts = x->x_pts;
}
+ x->x_previouspts = x->x_pts;
+ x->x_pts = frame.pts;
+ // post( "pdp_live : frame pts : %ld", x->x_pts );
+ if ( x->x_nbframes > 0 )
+ {
+ if ( gettimeofday(&ctime, NULL) == -1)
+ {
+ post("pdp_theorin~ : could not read time" );
+ }
+
+ tplaying = ( ctime.tv_sec-x->x_starttime.tv_sec )*1000 +
+ ( ctime.tv_usec-x->x_starttime.tv_usec )/1000;
+ ttheoretical = ((x->x_nbframes)*1000 )/x->x_framerate;
+ // post( "pdp-theorin~ : %d playing since : %lldms ( theory : %lldms )",
+ // x->x_nbframes, tplaying, ttheoretical );
+
+ if ( tplaying < ttheoretical )
+ {
+ mwait.tv_sec = 0;
+ mwait.tv_nsec = (ttheoretical - tplaying)*1000000;
+
+ // wait between the two successive frames
+ if ( x->x_autoplay ) nanosleep( &mwait, NULL );
+ }
+ }
}
break;
}
pcktptr += chunksize;
length -= chunksize;
- if ( !x->x_streaming ) break;
}
av_free_packet(&x->x_pkt);
@@ -353,18 +470,10 @@ static void *pdp_decode_stream_from_url(void *tdata)
twait.tv_sec = 0;
twait.tv_nsec = 10000000; // 10 ms
- schedprio.sched_priority = 0;
- if ( sched_setscheduler(0,SCHED_OTHER,&schedprio) == -1)
- {
- post("pdp_live~ : couldn't set scheduler for decoding thread.\n");
- }
- if ( setpriority( PRIO_PROCESS, 0, x->x_priority ) < 0 )
- {
- post("pdp_live~ : couldn't set priority to %d for decoding thread.\n", x->x_priority );
- }
- else
+ schedprio.sched_priority = sched_get_priority_min(SCHED_FIFO) + x->x_priority;
+ if ( sched_setscheduler(0,SCHED_FIFO,&schedprio) == -1)
{
- post("pdp_live~ : priority set to %d for thread %d.\n", x->x_priority, x->x_decodechild );
+ post("pdp_theorin~ : couldn't set priority for decoding thread.");
}
if ( ! (x->x_avcontext->iformat->flags & AVFMT_NOHEADER ) )
@@ -376,19 +485,27 @@ static void *pdp_decode_stream_from_url(void *tdata)
post( "pdp_live~ : read header." );
}
- while ( x->x_streaming )
+ while ( x->x_decodechild )
{
- while ( x->x_newpicture ) nanosleep( &twait, NULL );
+ if ( ( x->x_streaming ) && ( ( x->x_autoplay ) || ( x->x_nextimage == 1 ) ) )
+ {
+ x->x_decoding = 1;
+ while ( x->x_newpicture ) nanosleep( &twait, NULL );
- // decode incoming packets
- if ( pdp_live_decode_packet( x ) < 0 )
+ // decode incoming packets
+ if ( ( x->x_streaming ) && ( pdp_live_decode_packet( x ) < 0 ) )
+ {
+ nanosleep( &twait, NULL ); // nothing to read, just wait
+ }
+ x->x_nextimage = -1;
+ }
+ else
{
- nanosleep( &twait, NULL ); // nothing to read, just wait
+ x->x_decoding = 0;
+ nanosleep( &twait, NULL ); // nothing to do, just wait
}
-
}
- post( "pdp_live~ : decoding thread %d exiting....", x->x_decodechild );
x->x_decodechild = 0;
pthread_exit(NULL);
}
@@ -419,7 +536,6 @@ static void *pdp_live_connect_to_url(void *tdata)
if ( err == -5 ) post( "pdp_live~ : not enough memory" );
if ( err == -6 ) post( "pdp_live~ : unknown format ( stream not found? )" );
x->x_connectchild = 0;
- x->x_avcontext = av_mallocz(sizeof(AVFormatContext));
pthread_exit(NULL);
}
/* If not enough info to get the stream parameters, we decode the
@@ -507,11 +623,13 @@ static void *pdp_live_connect_to_url(void *tdata)
x->x_nopackets = 0;
x->x_endofstream = 0;
x->x_nbframes = 0;
+ x->x_pts = -1;
+ x->x_previouspts = -1;
+ x->x_firstpts = -1;
- x->x_connectchild = 0;
-
- if ( x->x_usethread )
+ if ( x->x_usethread && ( x->x_decodechild == 0 ))
{
+ x->x_decodechild = 1; // trick & treets
// launch decoding thread
if ( pthread_attr_init( &decode_child_attr ) < 0 )
{
@@ -556,15 +674,15 @@ static void pdp_live_disconnect(t_pdp_live *x)
{
x->x_streaming = 0;
x->x_newpicture = 0;
- post("pdp_live~ : waiting for the end of decoding thread..." );
- while ( x->x_decodechild && ( count < 100 ) )
+ post("pdp_live~ : waiting end of decoding..." );
+ while ( x->x_decoding ) nanosleep( &twait, NULL );
+ /* close each decoder */
+ for(i=0;i<x->x_avcontext->nb_streams;i++)
{
- count++;
- sleep( 1 );
- }
- if ( x->x_decodechild )
- {
- post("pdp_live~ : zombie thread, i guess" );
+ if (avcodec_close(&x->x_avcontext->streams[i]->codec) < 0)
+ {
+ post("pdp_live~ : error while closing codec for stream #%d", i);
+ }
}
post("pdp_live~ : closing input file..." );
av_close_input_file(x->x_avcontext);
@@ -631,9 +749,6 @@ static t_int *pdp_live_perform(t_int *w)
t_float *out2 = (t_float *)(w[2]); // right audio inlet
t_pdp_live *x = (t_pdp_live *)(w[3]);
int n = (int)(w[4]); // number of samples
- short int *pY, *pU, *pV;
- uint8_t *psY, *psU, *psV;
- t_int pixRGB, px, py;
short sampleL, sampleR;
struct timeval etime;
t_int sn;
@@ -650,7 +765,6 @@ static t_int *pdp_live_perform(t_int *w)
if ( x->x_audioon )
{
sn=0;
- n=n*DEFAULT_CHANNELS;
while (n--)
{
sampleL=x->x_audio_in[ sn++ ];
@@ -670,7 +784,7 @@ static t_int *pdp_live_perform(t_int *w)
memcpy( &x->x_audio_in[0], &x->x_audio_in[sn], 4*MAX_AUDIO_PACKET_SIZE-sn );
x->x_audioin_position-=sn;
// post( "pdp_live~ : audio in position : %d", x->x_audioin_position );
- if ( x->x_audioin_position <= sn )
+ if ( x->x_audioin_position <= 0 )
{
x->x_audioon = 0;
// post( "pdp_live~ : audio off" );
@@ -694,7 +808,7 @@ static t_int *pdp_live_perform(t_int *w)
if ( etime.tv_sec != x->x_cursec )
{
x->x_cursec = etime.tv_sec;
- if (x->x_streaming) outlet_float( x->x_outlet_framerate, x->x_framerate );
+ if (x->x_streaming) outlet_float( x->x_outlet_framerate, x->x_secondcount );
x->x_secondcount = 0;
}
if ( x->x_secondcount >= x->x_framerate )
@@ -705,45 +819,13 @@ static t_int *pdp_live_perform(t_int *w)
// output image if there's a new one decoded
if ( x->x_newpicture )
{
- // create a new pdp packet from PIX_FMT_YUV420P image format
- x->x_packet0 = pdp_packet_new_image_YCrCb( x->x_vwidth, x->x_vheight );
- x->x_header = pdp_packet_header(x->x_packet0);
- x->x_data = (short int *)pdp_packet_data(x->x_packet0);
-
- pY = x->x_data;
- pV = x->x_data+x->x_vsize;
- pU = x->x_data+x->x_vsize+(x->x_vsize>>2);
-
- psY = x->x_picture_decoded.data[0];
- psU = x->x_picture_decoded.data[1];
- psV = x->x_picture_decoded.data[2];
-
- for ( py=0; py<x->x_vheight; py++)
- {
- for ( px=0; px<x->x_vwidth; px++)
- {
- *(pY) = ( *(psY+px) << 7 );
- *(pV) = ( ((*(psV+(px>>1)))-128) << 8 );
- *(pU) = ( ((*(psU+(px>>1)))-128) << 8 );
- pY++;
- if ( (px%2==0) && (py%2==0) )
- {
- pV++; pU++;
- }
- }
- psY += x->x_picture_decoded.linesize[0];
- if ( py%2==0 ) psU += x->x_picture_decoded.linesize[1];
- if ( py%2==0 ) psV += x->x_picture_decoded.linesize[2];
- }
-
pdp_packet_pass_if_valid(x->x_pdp_out, &x->x_packet0);
+ x->x_newpicture = 0;
// update streaming status
x->x_nbframes++;
x->x_secondcount++;
outlet_float( x->x_outlet_nbframes, x->x_nbframes );
-
- x->x_newpicture = 0;
}
outlet_float( x->x_outlet_streaming, x->x_streaming );
outlet_float( x->x_outlet_endofstream, x->x_endofstream );
@@ -760,18 +842,19 @@ static void pdp_live_free(t_pdp_live *x)
{
int i;
+ if ( x->x_decodechild )
+ {
+ x->x_decodechild = 0;
+ x->x_decoding = 0;
+ sleep( 5 ); // let the decoding thread exiting
+ }
+
if ( x->x_streaming )
{
pdp_live_disconnect(x);
- sleep(3);
}
post( "pdp_live~ : freeing object" );
pdp_packet_mark_unused(x->x_packet0);
- if (x->x_audio_resample_ctx)
- {
- audio_resample_close(x->x_audio_resample_ctx);
- x->x_audio_resample_ctx = NULL;
- }
av_free_static();
}
@@ -783,6 +866,8 @@ void *pdp_live_new(void)
t_pdp_live *x = (t_pdp_live *)pd_new(pdp_live_class);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("frame_cold"));
+
x->x_pdp_out = outlet_new(&x->x_obj, &s_anything);
x->x_outlet_left = outlet_new(&x->x_obj, &s_signal);
@@ -796,6 +881,7 @@ void *pdp_live_new(void)
x->x_packet0 = -1;
x->x_connectchild = 0;
x->x_decodechild = 0;
+ x->x_decoding = 0;
x->x_usethread = 1;
x->x_priority = DEFAULT_PRIORITY;
x->x_framerate = DEFAULT_FRAME_RATE;
@@ -807,15 +893,19 @@ void *pdp_live_new(void)
x->x_secondcount = 0;
x->x_audio_resample_ctx = NULL;
x->x_nbvideostreams = 0;
- x->x_videoindex = 0;
+ x->x_videoindex = -1;
x->x_audioin_position = 0;
x->x_newpicture = 0;
x->x_endofstream = 0;
x->x_nopackets = 0;
x->x_blocksize = MIN_AUDIO_SIZE;
+ x->x_autoplay = 1;
+ x->x_loop = 1;
+ x->x_nextimage = 0;
x->x_pts = -1;
x->x_previouspts = -1;
+ x->x_firstpts = -1;
x->x_avcontext = av_mallocz(sizeof(AVFormatContext));
if ( !x->x_avcontext )
@@ -851,7 +941,11 @@ void pdp_live_tilde_setup(void)
class_addmethod(pdp_live_class, (t_method)pdp_live_disconnect, gensym("disconnect"), A_NULL);
class_addmethod(pdp_live_class, (t_method)pdp_live_priority, gensym("priority"), A_FLOAT, A_NULL);
class_addmethod(pdp_live_class, (t_method)pdp_live_audio, gensym("audio"), A_FLOAT, A_NULL);
+ class_addmethod(pdp_live_class, (t_method)pdp_live_autoplay, gensym("autoplay"), A_FLOAT, A_NULL);
+ class_addmethod(pdp_live_class, (t_method)pdp_live_loop, gensym("loop"), A_FLOAT, A_NULL);
class_addmethod(pdp_live_class, (t_method)pdp_live_threadify, gensym("thread"), A_FLOAT, A_NULL);
+ class_addmethod(pdp_live_class, (t_method)pdp_live_bang, gensym("bang"), A_NULL);
+ class_addmethod(pdp_live_class, (t_method)pdp_live_frame_cold, gensym("frame_cold"), A_FLOAT, A_NULL);
class_sethelpsymbol( pdp_live_class, gensym("pdp_live~.pd") );
}
diff --git a/modules/pdp_o.c b/modules/pdp_o.c
index ee5e084..30157cf 100644
--- a/modules/pdp_o.c
+++ b/modules/pdp_o.c
@@ -182,7 +182,7 @@ static void pdp_o_smoothe(t_pdp_o *x, short int *source, t_int size )
static int pdp_o_huffman(t_pdp_o *x, char *source, char *dest, t_int size, t_int *csize )
{
t_int i;
- char value = source[0];
+ int value = source[0];
char count = 0;
t_int tcount=0;
char *pcount=dest;
@@ -198,14 +198,14 @@ static int pdp_o_huffman(t_pdp_o *x, char *source, char *dest, t_int size, t_int
}
else
{
- value=source[i];
*(pcount)=count;
*(pvalue) = value;
tcount+=count;
- count=1;
pcount+=2;
pvalue+=2;
*(csize)+=2;
+ value=source[i];
+ count=1;
}
}
*(pcount)=count;
@@ -221,7 +221,7 @@ static int pdp_o_huffman(t_pdp_o *x, char *source, char *dest, t_int size, t_int
else
{
// post( "pdp_o : huffman : compression ratio %d/%d : %f (total count=%d)", size, (*csize),
- // (t_float)size/(t_float)(*csize), tcount );
+ // (t_float)size/(t_float)(*csize), tcount );
return HUFFMAN;
}
}
@@ -349,7 +349,8 @@ static void pdp_o_process_yv12(t_pdp_o *x)
{
// post( "pdp_o : y value out of range : %d", downvalue );
}
- if ( data[i] != x->x_previous_frame[i] )
+ if ( ( data[i] != x->x_previous_frame[i] ) ||
+ ( !strcmp( x->x_hpacket.tag, PDP_PACKET_TAG ) ) )
{
x->x_diff_frame[i] = (char)downvalue;
}
@@ -368,7 +369,8 @@ static void pdp_o_process_yv12(t_pdp_o *x)
{
// post( "pdp_o : y value out of range : %d", downvalue );
}
- if ( data[i] != x->x_previous_frame[i] )
+ if ( ( data[i] != x->x_previous_frame[i] ) ||
+ ( !strcmp( x->x_hpacket.tag, PDP_PACKET_TAG ) ) )
{
x->x_diff_frame[i] = (char)downvalue;
}
@@ -378,8 +380,8 @@ static void pdp_o_process_yv12(t_pdp_o *x)
}
}
- x->x_hpacket.width = x->x_vwidth;
- x->x_hpacket.height = x->x_vheight;
+ x->x_hpacket.width = htonl(x->x_vwidth);
+ x->x_hpacket.height = htonl(x->x_vheight);
if ( gettimeofday(&x->x_hpacket.etime, NULL) == -1)
{
post("pdp_o : could not set emit time" );
@@ -391,13 +393,16 @@ static void pdp_o_process_yv12(t_pdp_o *x)
x->x_bandwidthcount = 0;
}
+ x->x_hpacket.etime.tv_sec = htonl( x->x_hpacket.etime.tv_sec );
+ x->x_hpacket.etime.tv_usec = htonl( x->x_hpacket.etime.tv_usec );
+
// do not send the frame if too many frames
// have been sent in the current second
if ( x->x_secondcount < x->x_framerate )
{
// try a huffman coding
- x->x_hpacket.encoding = pdp_o_huffman(x, x->x_diff_frame, x->x_hdata, x->x_vsize+(x->x_vsize>>1), &x->x_hsize );
+ x->x_hpacket.encoding = htonl( pdp_o_huffman(x, x->x_diff_frame, x->x_hdata, x->x_vsize+(x->x_vsize>>1), &x->x_hsize ) );
x->x_hpacket.clength = (x->x_vsize+(x->x_vsize>>1))*1.01+600;
// compress the graphic data
@@ -415,6 +420,7 @@ static void pdp_o_process_yv12(t_pdp_o *x)
memcpy( x->x_previous_frame, data, (x->x_vsize+(x->x_vsize>>1))<<1 );
// send header
+ x->x_hpacket.clength = htonl( x->x_hpacket.clength );
count = send(x->x_fd, &x->x_hpacket, sizeof(x->x_hpacket), MSG_NOSIGNAL);
if(count < 0)
{
@@ -430,6 +436,7 @@ static void pdp_o_process_yv12(t_pdp_o *x)
}
x->x_bandwidthcount += count/1024;
}
+ x->x_hpacket.clength = ntohl( x->x_hpacket.clength );
// send data
count = send(x->x_fd, x->x_cdata, x->x_hpacket.clength, MSG_NOSIGNAL);
diff --git a/modules/pdp_ocanvas.c b/modules/pdp_ocanvas.c
index c92253b..598821e 100644
--- a/modules/pdp_ocanvas.c
+++ b/modules/pdp_ocanvas.c
@@ -53,6 +53,7 @@ typedef struct pdp_ocanvas_struct
t_int *x_heights;
t_float *x_xoffsets;
t_float *x_yoffsets;
+ t_float *x_alphas;
t_int *x_sizes;
t_int x_owidth;
@@ -105,7 +106,7 @@ static void pdp_ocanvas_process_yv12(t_pdp_ocanvas *x)
piU = idata+x->x_sizes[ii]+(x->x_sizes[ii]>>2);
ppx = px-(int)x->x_xoffsets[ii];
ppy = py-(int)x->x_yoffsets[ii];
- *(pY+py*x->x_owidth+px) += *(piY+ppy*x->x_widths[ii]+ppx);
+ *(pY+py*x->x_owidth+px) += *(piY+ppy*x->x_widths[ii]+ppx)*x->x_alphas[ii];
if ( (px%2==0) && (py%2==0) )
{
*(pU+(py>>1)*(x->x_owidth>>1)+(px>>1)) +=
@@ -175,6 +176,21 @@ static void pdp_ocanvas_offset(t_pdp_ocanvas *x, t_floatarg ni, t_floatarg xoffs
x->x_yoffsets[(int)ni-1] = yoffset;
}
+static void pdp_ocanvas_alpha(t_pdp_ocanvas *x, t_floatarg ni, t_floatarg xalpha)
+{
+ if ( ( ni < 1 ) || ( ni > x->x_nbinputs ) )
+ {
+ post( "pdp_ocanvas : alpha : wrong source : %d : must be between 1 and %d", ni, x->x_nbinputs );
+ return;
+ }
+ if ( ( xalpha < .0 ) || ( xalpha > 1.0 ) )
+ {
+ post( "pdp_ocanvas : alpha : wrong alpha value : %f : must be between 0 and 1", xalpha );
+ return;
+ }
+ x->x_alphas[(int)ni-1] = xalpha;
+}
+
static void pdp_ocanvas_select(t_pdp_ocanvas *x, t_floatarg X, t_floatarg Y)
{
t_int ii;
@@ -324,6 +340,7 @@ static void pdp_ocanvas_free(t_pdp_ocanvas *x)
if ( x->x_sizes ) freebytes( x->x_sizes, x->x_nbinputs*sizeof(t_int) );
if ( x->x_xoffsets ) freebytes( x->x_xoffsets, x->x_nbinputs*sizeof(t_float) );
if ( x->x_yoffsets ) freebytes( x->x_yoffsets, x->x_nbinputs*sizeof(t_float) );
+ if ( x->x_alphas ) freebytes( x->x_alphas, x->x_nbinputs*sizeof(t_float) );
}
t_class *pdp_ocanvas_class;
@@ -381,6 +398,7 @@ void *pdp_ocanvas_new(t_symbol *s, int argc, t_atom *argv)
x->x_sizes = ( t_int* ) getbytes( x->x_nbinputs*sizeof(t_int) );
x->x_xoffsets = ( t_float* ) getbytes( x->x_nbinputs*sizeof(t_float) );
x->x_yoffsets = ( t_float* ) getbytes( x->x_nbinputs*sizeof(t_float) );
+ x->x_alphas = ( t_float* ) getbytes( x->x_nbinputs*sizeof(t_float) );
x->x_opacket = pdp_packet_new_image_YCrCb( x->x_owidth, x->x_oheight );
@@ -391,6 +409,7 @@ void *pdp_ocanvas_new(t_symbol *s, int argc, t_atom *argv)
x->x_packets[ii] = -1;
x->x_xoffsets[ii] = 0.;
x->x_yoffsets[ii] = 0.;
+ x->x_alphas[ii] = 1.;
}
x->x_current = -1;
x->x_average = 0;
@@ -426,6 +445,7 @@ void pdp_ocanvas_setup(void)
class_addmethod(pdp_ocanvas_class, (t_method)pdp_ocanvas_input8, gensym("pdp8"), A_SYMBOL, A_DEFFLOAT, A_NULL);
class_addmethod(pdp_ocanvas_class, (t_method)pdp_ocanvas_input9, gensym("pdp9"), A_SYMBOL, A_DEFFLOAT, A_NULL);
class_addmethod(pdp_ocanvas_class, (t_method)pdp_ocanvas_offset, gensym("offset"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_NULL);
+ class_addmethod(pdp_ocanvas_class, (t_method)pdp_ocanvas_alpha, gensym("alpha"), A_DEFFLOAT, A_DEFFLOAT, A_NULL);
class_addmethod(pdp_ocanvas_class, (t_method)pdp_ocanvas_select, gensym("select"), A_DEFFLOAT, A_DEFFLOAT, A_NULL);
class_addmethod(pdp_ocanvas_class, (t_method)pdp_ocanvas_drag, gensym("drag"), A_DEFFLOAT, A_DEFFLOAT, A_NULL);
class_addmethod(pdp_ocanvas_class, (t_method)pdp_ocanvas_unselect, gensym("unselect"), A_NULL);
diff --git a/modules/pdp_pen.c b/modules/pdp_pen.c
index dad5167..6aa263c 100644
--- a/modules/pdp_pen.c
+++ b/modules/pdp_pen.c
@@ -52,6 +52,7 @@ typedef struct pdp_pen_struct
t_int x_blue;
t_int x_xoffset;
t_int x_yoffset;
+ t_float x_alpha;
t_int x_pwidth;
t_int x_mode; // 0=draw ( default), 1=erase
@@ -317,6 +318,14 @@ static void pdp_pen_yoffset(t_pdp_pen *x, t_floatarg yoffset)
x->x_yoffset = (int) yoffset;
}
+static void pdp_pen_alpha(t_pdp_pen *x, t_floatarg falpha)
+{
+ if ( falpha >= 0. && falpha <= 1. )
+ {
+ x->x_alpha = falpha;
+ }
+}
+
static void pdp_pen_mode(t_pdp_pen *x, t_floatarg mode)
{
if ( ( mode == 0. ) || ( mode == 1. ) )
@@ -394,11 +403,15 @@ static void pdp_pen_process_yv12(t_pdp_pen *x)
{
if ( *(pbY+(py-x->x_yoffset)*x->x_vwidth+(px-x->x_xoffset)) != 0 )
{
- *(pnY+py*x->x_vwidth+px) = *(pbY+(py-x->x_yoffset)*x->x_vwidth+(px-x->x_xoffset));
+ *(pnY+py*x->x_vwidth+px) =
+ (*(pbY+(py-x->x_yoffset)*x->x_vwidth+(px-x->x_xoffset))*x->x_alpha) +
+ (*(pnY+py*x->x_vwidth+px)*(1-x->x_alpha));
*(pnU+(py>>1)*(x->x_vwidth>>1)+(px>>1)) =
- *(pbU+((py-x->x_yoffset)>>1)*(x->x_vwidth>>1)+((px-x->x_xoffset)>>1));
+ (*(pbU+((py-x->x_yoffset)>>1)*(x->x_vwidth>>1)+((px-x->x_xoffset)>>1))*x->x_alpha) +
+ (*(pnU+(py>>1)*(x->x_vwidth>>1)+(px>>1))*(1-x->x_alpha));
*(pnV+(py>>1)*(x->x_vwidth>>1)+(px>>1)) =
- *(pbV+((py-x->x_yoffset)>>1)*(x->x_vwidth>>1)+((px-x->x_xoffset)>>1));
+ (*(pbV+((py-x->x_yoffset)>>1)*(x->x_vwidth>>1)+((px-x->x_xoffset)>>1))*x->x_alpha) +
+ (*(pnV+(py>>1)*(x->x_vwidth>>1)+(px>>1))*(1-x->x_alpha));
}
}
}
@@ -482,6 +495,7 @@ void *pdp_pen_new(void)
x->x_outlet0 = outlet_new(&x->x_obj, &s_anything);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("xoffset"));
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("yoffset"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("alpha"));
x->x_packet0 = -1;
x->x_packet1 = -1;
@@ -498,6 +512,7 @@ void *pdp_pen_new(void)
x->x_pwidth = 3;
x->x_mode = 0;
+ x->x_alpha = 1.;
return (void *)x;
}
@@ -525,6 +540,7 @@ void pdp_pen_setup(void)
class_addmethod(pdp_pen_class, (t_method)pdp_pen_mode, gensym("mode"), A_DEFFLOAT, A_NULL);
class_addmethod(pdp_pen_class, (t_method)pdp_pen_xoffset, gensym("xoffset"), A_DEFFLOAT, A_NULL);
class_addmethod(pdp_pen_class, (t_method)pdp_pen_yoffset, gensym("yoffset"), A_DEFFLOAT, A_NULL);
+ class_addmethod(pdp_pen_class, (t_method)pdp_pen_alpha, gensym("alpha"), A_DEFFLOAT, A_NULL);
}
diff --git a/modules/pdp_rec~.c b/modules/pdp_rec~.c
index 2a0d68e..5b217dd 100644
--- a/modules/pdp_rec~.c
+++ b/modules/pdp_rec~.c
@@ -445,8 +445,8 @@ static t_int *pdp_rec_perform(t_int *w)
if (fsample < -1.0) { fsample = -1.0; }
isample=(short) (32767.0 * fsample);
x->x_audio_buf[1][x->x_audioin_position]=isample;
- x->x_audioin_position=(x->x_audioin_position+1)%(2*MAX_AUDIO_PACKET_SIZE);
- if ( x->x_audioin_position == 2*MAX_AUDIO_PACKET_SIZE-1 )
+ x->x_audioin_position=(x->x_audioin_position+1)%(MAX_AUDIO_PACKET_SIZE);
+ if ( x->x_audioin_position == MAX_AUDIO_PACKET_SIZE-1 )
{
post( "pdp_rec~ : reaching end of audio buffer" );
}
@@ -624,6 +624,7 @@ static void pdp_rec_free(t_pdp_rec *x)
pdp_packet_mark_unused(x->x_packet0);
// close video file if existing
pdp_rec_close(x);
+ pdp_rec_free_ressources(x);
for ( i=0; i<x->x_channels; i++)
{
if ( x->x_audio_buf[i] ) freebytes( x->x_audio_buf[i], MAX_AUDIO_PACKET_SIZE*sizeof(int16_t) );
diff --git a/modules/pdp_shape.c b/modules/pdp_shape.c
index 27239c4..5f21518 100644
--- a/modules/pdp_shape.c
+++ b/modules/pdp_shape.c
@@ -26,7 +26,7 @@
#include "yuv.h"
#include <math.h>
-static char *pdp_shape_version = "pdp_shape: version 0.1, shape recongnition object written by Yves Degoyon (ydegoyon@free.fr)";
+static char *pdp_shape_version = "pdp_shape: version 0.1, shape recognition object written by Yves Degoyon (ydegoyon@free.fr)";
typedef struct pdp_shape_struct
{
@@ -79,15 +79,15 @@ static void pdp_shape_allocate(t_pdp_shape *x, t_int newsize)
{
int i;
- if ( x->x_bdata ) freebytes( x->x_bdata, (( x->x_vsize + (x->x_vsize>>1))<<1));
- if ( x->x_bbdata ) freebytes( x->x_bbdata, (( x->x_vsize + (x->x_vsize>>1))<<1));
- if ( x->x_checked ) freebytes( x->x_checked, x->x_vsize );
+ if ( x->x_bdata ) free( x->x_bdata );
+ if ( x->x_bbdata ) free( x->x_bbdata );
+ if ( x->x_checked ) free( x->x_checked );
x->x_vsize = newsize;
- x->x_bdata = (short int *)getbytes((( x->x_vsize + (x->x_vsize>>1))<<1));
- x->x_bbdata = (short int *)getbytes((( x->x_vsize + (x->x_vsize>>1))<<1));
- x->x_checked = (char *)getbytes( x->x_vsize );
+ x->x_bdata = (short int *)malloc((( x->x_vsize + (x->x_vsize>>1))<<1));
+ x->x_bbdata = (short int *)malloc((( x->x_vsize + (x->x_vsize>>1))<<1));
+ x->x_checked = (char *)malloc( x->x_vsize );
}
static void pdp_shape_tolerance(t_pdp_shape *x, t_floatarg ftolerance )
@@ -451,12 +451,15 @@ static void pdp_shape_process_yv12(t_pdp_shape *x)
if ( x->x_cursX != -1 ) pdp_shape_frame_detect( x, x->x_cursX, x->x_cursY );
// paint cursor in red for debug purpose
- pbbY = x->x_bbdata;
- pbbU = (x->x_bbdata+x->x_vsize);
- pbbV = (x->x_bbdata+x->x_vsize+(x->x_vsize>>2));
- *(pbbY+x->x_cursY*x->x_vwidth+x->x_cursX) = (yuv_RGBtoY( 0xff ))<<7;
- *(pbbU+(x->x_cursY>>1)*(x->x_vwidth>>1)+(x->x_cursX>>1)) = ((yuv_RGBtoU( 0xff )-128)<<8);
- *(pbbV+(x->x_cursY>>1)*(x->x_vwidth>>1)+(x->x_cursX>>1)) = ((yuv_RGBtoV( 0xff )-128)<<8);
+ if ( x->x_cursX != -1 )
+ {
+ pbbY = x->x_bbdata;
+ pbbU = (x->x_bbdata+x->x_vsize);
+ pbbV = (x->x_bbdata+x->x_vsize+(x->x_vsize>>2));
+ *(pbbY+x->x_cursY*x->x_vwidth+x->x_cursX) = (yuv_RGBtoY( 0xff ))<<7;
+ *(pbbU+(x->x_cursY>>1)*(x->x_vwidth>>1)+(x->x_cursX>>1)) = ((yuv_RGBtoU( 0xff )-128)<<8);
+ *(pbbV+(x->x_cursY>>1)*(x->x_vwidth>>1)+(x->x_cursX>>1)) = ((yuv_RGBtoV( 0xff )-128)<<8);
+ }
memcpy( newdata, x->x_bbdata, (x->x_vsize+(x->x_vsize>>1))<<1 );
diff --git a/modules/pdp_text.c b/modules/pdp_text.c
index d4eef94..5d2d633 100644
--- a/modules/pdp_text.c
+++ b/modules/pdp_text.c
@@ -60,6 +60,7 @@ typedef struct pdp_text_struct
t_int *x_g;
t_int *x_b;
t_float *x_angle;
+ t_float x_alpha;
t_int *x_scroll;
t_int x_nbtexts;
@@ -154,7 +155,7 @@ static void pdp_text_add(t_pdp_text *x, t_symbol *s, int argc, t_atom *argv)
{
x->x_angle[x->x_nbtexts] = argv[6].a_w.w_float;
}
- if ( (argc>=8) && (argv[7].a_type == A_FLOAT) )
+ if ( (argc>=8) && (argv[7].a_type == A_FLOAT) )
{
x->x_scroll[x->x_nbtexts] = (int)argv[7].a_w.w_float;
}
@@ -224,6 +225,14 @@ static void pdp_text_angle(t_pdp_text *x, t_floatarg fangle )
}
}
+static void pdp_text_alpha(t_pdp_text *x, t_floatarg falpha )
+{
+ if ( ( falpha >= 0. ) && ( falpha <= 1. ) )
+ {
+ x->x_alpha = falpha;
+ }
+}
+
static void pdp_text_scroll(t_pdp_text *x, t_floatarg fscroll )
{
if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_nbtexts ) )
@@ -456,11 +465,11 @@ static void pdp_text_process_yv12(t_pdp_text *x)
u = yuv_RGBtoU(imdata[py*x->x_vwidth+px]);
v = yuv_RGBtoV(imdata[py*x->x_vwidth+px]);
- *(pY) = y<<7;
+ *(pY) = ((y)<<7)*x->x_alpha + (*pY)*(1-x->x_alpha);
if ( (px%2==0) && (py%2==0) )
{
- *(pV) = (v-128)<<8;
- *(pU) = (u-128)<<8;
+ *(pV) = ((v-128)<<8)*x->x_alpha + *(pV)*(1-x->x_alpha);
+ *(pU) = ((u-128)<<8)*x->x_alpha + *(pU)*(1-x->x_alpha);
}
}
pY++;
@@ -557,6 +566,7 @@ void *pdp_text_new(void)
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("textb"));
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("angle"));
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("scroll"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("alpha"));
x->x_outlet0 = outlet_new(&x->x_obj, &s_anything);
x->x_packet0 = -1;
@@ -585,6 +595,7 @@ void *pdp_text_new(void)
x->x_nbtexts = 0;
x->x_current = -1;
+ x->x_alpha = 1.;
return (void *)x;
}
@@ -618,6 +629,7 @@ void pdp_text_setup(void)
class_addmethod(pdp_text_class, (t_method)pdp_text_resize, gensym("resize"), A_DEFFLOAT, A_NULL);
class_addmethod(pdp_text_class, (t_method)pdp_text_font, gensym("font"), A_SYMBOL, A_NULL);
class_addmethod(pdp_text_class, (t_method)pdp_text_angle, gensym("angle"), A_DEFFLOAT, A_NULL);
+ class_addmethod(pdp_text_class, (t_method)pdp_text_alpha, gensym("alpha"), A_DEFFLOAT, A_NULL);
class_addmethod(pdp_text_class, (t_method)pdp_text_scroll, gensym("scroll"), A_DEFFLOAT, A_NULL);
class_addmethod(pdp_text_class, (t_method)pdp_text_dither, gensym("dither"), A_DEFFLOAT, A_NULL);
class_addmethod(pdp_text_class, (t_method)pdp_text_blend, gensym("blend"), A_DEFFLOAT, A_NULL);
diff --git a/modules/pdp_underwatch.c b/modules/pdp_underwatch.c
index 674582f..c999ceb 100644
--- a/modules/pdp_underwatch.c
+++ b/modules/pdp_underwatch.c
@@ -73,19 +73,12 @@ static void pdp_underwatch_process_yv12(t_pdp_underwatch *x)
short int *p=0, *po=0, *pu=0, *pv=0, *pou=0, *pov=0;
int i;
- unsigned int u_offset;
- unsigned int v_offset;
- unsigned int totnbpixels;
int px, py, pd, t;
x->x_vwidth = header->info.image.width;
x->x_vheight = header->info.image.height;
x->x_vsize = x->x_vwidth*x->x_vheight;
- u_offset = x->x_vsize;
- v_offset = x->x_vsize + (x->x_vsize>>2);
- totnbpixels = x->x_vsize + (x->x_vsize>>1);
-
newheader->info.image.encoding = header->info.image.encoding;
newheader->info.image.width = x->x_vwidth;
newheader->info.image.height = x->x_vheight;
diff --git a/modules/pdp_yqt.c b/modules/pdp_yqt.c
index d0ada83..8795f77 100644
--- a/modules/pdp_yqt.c
+++ b/modules/pdp_yqt.c
@@ -237,7 +237,7 @@ static void pdp_yqt_bang(t_pdp_yqt *x)
if ( gettimeofday(&etime, NULL) == -1)
{
- post("pdp_fcqt : could not get time" );
+ post("pdp_yqt : could not get time" );
}
if ( etime.tv_sec != x->x_cursec )
{
@@ -248,7 +248,6 @@ static void pdp_yqt_bang(t_pdp_yqt *x)
x->x_framescount++;
outlet_float(x->x_curframe, (float)pos);
- pdp_packet_pass_if_valid(x->x_outlet0, &object);
// fills in the audio buffer with a chunk if necessary
if ( x->x_audio && x->x_outunread < MIN_AUDIO_INPUT )
@@ -285,6 +284,8 @@ static void pdp_yqt_bang(t_pdp_yqt *x)
}
}
+ pdp_packet_pass_if_valid(x->x_outlet0, &object);
+
}
static void pdp_yqt_loop(t_pdp_yqt *x, t_floatarg loop)