[PD-cvs] externals/pidip/modules pdp_fqt.c,NONE,1.1

sevyves at users.sourceforge.net sevyves at users.sourceforge.net
Thu Oct 23 19:12:30 CEST 2003


Update of /cvsroot/pure-data/externals/pidip/modules
In directory sc8-pr-cvs1:/tmp/cvs-serv3316

Added Files:
	pdp_fqt.c 
Log Message:
New in PiDiP 0.12.10

--- NEW FILE: pdp_fqt.c ---
/*
 *   Pure Data Packet module.
 *   Copyright (c) by Yves Degoyon <ydegoyon at free.fr>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */



#include "pdp.h"
#include "pdp_llconv.h"
#include <quicktime/lqt.h>
#include <quicktime/colormodels.h>

typedef struct pdp_fqt_data
{
    short int gain[4];
} t_pdp_fqt_data;

typedef struct pdp_fqt_struct
{
    t_object x_obj;
    t_float x_f;

    t_outlet *x_outlet0;
    t_outlet *x_outlet1;
    t_outlet *x_outlet2;

    int packet0;
    bool initialized;

    unsigned int x_vwidth;
    unsigned int x_vheight;

    bool loop;

    unsigned char * qt_rows[3];

    unsigned char * qt_frame;
    quicktime_t *qt;
    int qt_cmodel;

    t_pdp_fqt_data *state_data;

} t_pdp_fqt;



static void pdp_fqt_close(t_pdp_fqt *x)
{
    if (x->initialized){
	quicktime_close(x->qt);
	free(x->qt_frame);
	x->initialized = false;
    }

}

static void pdp_fqt_open(t_pdp_fqt *x, t_symbol *name)
{
    unsigned int size;

    post("pdp_fqt: opening %s", name->s_name);

    pdp_fqt_close(x);

    x->qt = quicktime_open(name->s_name, 1, 0);

    if (!(x->qt)){
	post("pdp_fqt: error opening qt file");
	x->initialized = false;
	return;
    }

    if (!quicktime_has_video(x->qt)) {
	post("pdp_fqt: no video stream");
	quicktime_close(x->qt);
	x->initialized = false;
	return;
	
    }
    else if (!quicktime_supported_video(x->qt,0)) {
	post("pdp_fqt: unsupported video codec\n");
	quicktime_close(x->qt);
	x->initialized = false;
	return;
    }
    else 
    {
	x->qt_cmodel = BC_YUV420P;
	x->x_vwidth  = quicktime_video_width(x->qt,0);
	x->x_vheight = quicktime_video_height(x->qt,0);
	x->qt_frame = (unsigned char*)malloc(x->x_vwidth*x->x_vheight*4);
	size = x->x_vwidth * x->x_vheight;
	x->qt_rows[0] = &x->qt_frame[0];
	x->qt_rows[2] = &x->qt_frame[size];
	x->qt_rows[1] = &x->qt_frame[size + (size>>2)];
    
	quicktime_set_cmodel(x->qt, x->qt_cmodel);
	x->initialized = true;
	outlet_float(x->x_outlet2, (float)quicktime_video_length(x->qt,0));

    }
}


static void pdp_fqt_bang(t_pdp_fqt *x)
{
  unsigned int w, h, nbpixels, packet_size;
  int object, length, pos, i, j;
  short int* data;
  t_pdp* header;

  static short int gain[4] = {0x7fff, 0x7fff, 0x7fff, 0x7fff};

    if (!(x->initialized)){
	//post("pdp_fqt: no qt file opened");
	return;
    }

    w = x->x_vwidth;
    h = x->x_vheight;
    nbpixels = w * h;
    packet_size = (nbpixels + (nbpixels >> 1)) << 1;

    object = pdp_packet_new_image_YCrCb( x->x_vwidth, x->x_vheight );
    header = pdp_packet_header(object);
    data = (short int *) pdp_packet_data(object);

    header->info.image.encoding = PDP_IMAGE_YV12;
    header->info.image.width = w;
    header->info.image.height = h;

    length = quicktime_video_length(x->qt,0);
    pos = quicktime_video_position(x->qt,0);
    // post("pdp_fqt : video position : %d length =%d", pos, length );

    if (pos >= length){
	pos = (x->loop) ? 0 : length - 1;
        // post("pdp_fqt : setting video position to %d", pos);
	quicktime_set_video_position(x->qt, pos, 0);
    }

    lqt_decode_video(x->qt, x->qt_rows, 0);

    switch(x->qt_cmodel){
    case BC_YUV420P:
        pdp_llconv(x->qt_frame, RIF_YVU__P411_U8, data, RIF_YVU__P411_S16, x->x_vwidth, x->x_vheight);
        break;

    case BC_YUV422:
        pdp_llconv(x->qt_frame, RIF_YUYV_P____U8, data, RIF_YVU__P411_S16, x->x_vwidth, x->x_vheight);
        break;

    case BC_RGB888:
        pdp_llconv(x->qt_frame, RIF_RGB__P____U8, data, RIF_YVU__P411_S16, x->x_vwidth, x->x_vheight);
        break;

    default:
        post("pdp_fqt : error on decode: unkown colour model");
        break;
    }
    
    outlet_float(x->x_outlet1, (float)pos);
    pdp_packet_pass_if_valid(x->x_outlet0, &object);

}

static void pdp_fqt_loop(t_pdp_fqt *x, t_floatarg loop)
{
    int loopi = (int)loop;
    x->loop = !(loopi == 0);
}

static void pdp_fqt_frame_cold(t_pdp_fqt *x, t_floatarg frameindex)
{
    int frame = (int)frameindex;
    int length;


    if (!(x->initialized)) return;

    length = quicktime_video_length(x->qt,0);

    frame = (frame >= length) ? length-1 : frame;
    frame = (frame < 0) ? 0 : frame;

    // post("pdp_fqt : frame cold : setting video position to : %d", frame );
    quicktime_set_video_position(x->qt, frame, 0);
}

static void pdp_fqt_frame(t_pdp_fqt *x, t_floatarg frameindex)
{
    // pdp_fqt_frame_cold(x, frameindex);
    pdp_fqt_bang(x);
}

static void pdp_fqt_gain(t_pdp_fqt *x, t_floatarg f)
{
    int i;
    short int g;
    float bound = (float)0x7fff;

    f *= (float)0x7fff;

    f = (f>bound) ? bound : f;
    f = (f<-bound) ? -bound : f;

    g = (short int)f;

    for (i=0; i<4; i++) x->state_data->gain[i] = g;
}

static void pdp_fqt_free(t_pdp_fqt *x)
{
    free (x->state_data);
    pdp_fqt_close(x);
}

t_class *pdp_fqt_class;

void *pdp_fqt_new(void)
{
    t_pdp_fqt *x = (t_pdp_fqt *)pd_new(pdp_fqt_class);

    inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("frame_cold"));
    inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("gain"));

    x->x_outlet0 = outlet_new(&x->x_obj, &s_anything);
    x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
    x->x_outlet2 = outlet_new(&x->x_obj, &s_float);

    x->packet0 = -1;

    x->initialized = false;

    x->loop = false;

    x->state_data = (t_pdp_fqt_data *)malloc(sizeof(t_pdp_fqt_data));
    pdp_fqt_gain(x, 1.0f);

    return (void *)x;
}

#ifdef __cplusplus
extern "C"
{
#endif


void pdp_fqt_setup(void)
{
    pdp_fqt_class = class_new(gensym("pdp_fqt"), (t_newmethod)pdp_fqt_new,
    	(t_method)pdp_fqt_free, sizeof(t_pdp_fqt), 0, A_NULL);

    class_addmethod(pdp_fqt_class, (t_method)pdp_fqt_bang, gensym("bang"), A_NULL);
    class_addmethod(pdp_fqt_class, (t_method)pdp_fqt_close, gensym("close"), A_NULL);
    class_addmethod(pdp_fqt_class, (t_method)pdp_fqt_open, gensym("open"), A_SYMBOL, A_NULL);
    class_addmethod(pdp_fqt_class, (t_method)pdp_fqt_loop, gensym("loop"), A_DEFFLOAT, A_NULL);
    class_addfloat (pdp_fqt_class, (t_method)pdp_fqt_frame);
    class_addmethod(pdp_fqt_class, (t_method)pdp_fqt_frame_cold, gensym("frame_cold"), A_FLOAT, A_NULL);
    class_addmethod(pdp_fqt_class, (t_method)pdp_fqt_gain, gensym("gain"), A_FLOAT, A_NULL);
    class_addmethod(pdp_fqt_class, nullfn, gensym("signal"), 0);
    class_sethelpsymbol( pdp_fqt_class, gensym("pdp_fqt.pd") );

}

#ifdef __cplusplus
}
#endif






More information about the Pd-cvs mailing list