X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Flibzmpeg3%2Fyy.C;fp=cinelerra-5.1%2Flibzmpeg3%2Fyy.C;h=0359f0339a505752719be450ef3290bf285a5178;hb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;hp=0000000000000000000000000000000000000000;hpb=52fcc46226f9df46f9ce9d0566dc568455a7db0b;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/libzmpeg3/yy.C b/cinelerra-5.1/libzmpeg3/yy.C new file mode 100644 index 00000000..0359f033 --- /dev/null +++ b/cinelerra-5.1/libzmpeg3/yy.C @@ -0,0 +1,384 @@ +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +#include "libzmpeg3.h" +#else +#include "../libmpeg3/libmpeg3.h" +#define zmpeg3_t mpeg3_t +#endif + +#define AUDIO +#define VIDEO + +/* c++ `pkg-config --cflags --libs gtk+-2.0` y.C ./x86_64/libzmpeg3.a -lpthread -lasound -lm */ + +#ifdef AUDIO +snd_pcm_t *zpcm; +snd_pcm_uframes_t zpcm_ufrm_size; +snd_pcm_sframes_t zpcm_sbfr_size; +snd_pcm_sframes_t zpcm_sper_size; +unsigned int zpcm_rate; +static const char *zpcm_device = "plughw:0,0"; +static unsigned int zpcm_bfr_time_us = 500000; +static unsigned int zpcm_per_time_us = 200000; +static snd_pcm_channel_area_t *zpcm_areas = 0; +static int zpcm_channels = 0; +static short **zpcm_buffers = 0; +static short *zpcm_samples = 0; + +void alsa_close() +{ +#ifdef __cplusplus + if( zpcm_buffers != 0 ) { delete [] zpcm_buffers; zpcm_buffers = 0; } + if( zpcm_areas != 0 ) { delete [] zpcm_areas; zpcm_areas = 0; } + if( zpcm_samples != 0 ) { delete [] zpcm_samples; zpcm_samples = 0; } +#else + if( zpcm_buffers != 0 ) { free(zpcm_buffers); zpcm_buffers = 0; } + if( zpcm_areas != 0 ) { free(zpcm_areas); zpcm_areas = 0; } + if( zpcm_samples != 0 ) { free(zpcm_samples); zpcm_samples = 0; } +#endif + if( zpcm != 0 ) { snd_pcm_close(zpcm); zpcm = 0; } +} + +void alsa_open(int chs,int rate) +{ + int ich, bits, byts, dir, ret; + snd_pcm_format_t fmt = SND_PCM_FORMAT_S16; + snd_pcm_hw_params_t *phw; + snd_pcm_sw_params_t *psw; + snd_pcm_hw_params_alloca(&phw); + snd_pcm_sw_params_alloca(&psw); + + zpcm = 0; + ret = snd_pcm_open(&zpcm, zpcm_device, + SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); + if( ret >= 0 ) + ret = snd_pcm_hw_params_any(zpcm, phw); + if( ret >= 0 ) + ret = snd_pcm_hw_params_set_rate_resample(zpcm, phw, 1); + if( ret >= 0 ) + ret = snd_pcm_hw_params_set_access(zpcm, phw, + SND_PCM_ACCESS_RW_NONINTERLEAVED); + if( ret >= 0 ) + ret = snd_pcm_hw_params_set_format(zpcm, phw, fmt); + if( ret >= 0 ) { + zpcm_channels = chs; + ret = snd_pcm_hw_params_set_channels(zpcm, phw, chs); + } + if( ret >= 0 ) { + zpcm_rate = rate; + ret = snd_pcm_hw_params_set_rate_near(zpcm, phw, &zpcm_rate, 0); + if( (int)zpcm_rate != rate ) + printf("nearest audio_rate for %d is %u\n",rate,zpcm_rate); + } + if( ret >= 0 ) + ret = snd_pcm_hw_params_set_buffer_time_near(zpcm, phw, + &zpcm_bfr_time_us, &dir); + if( ret >= 0 ) + ret = snd_pcm_hw_params_get_buffer_size(phw, &zpcm_ufrm_size); + if( ret >= 0 ) { + zpcm_sbfr_size = zpcm_ufrm_size; + ret = snd_pcm_hw_params_set_period_time_near(zpcm, phw, + &zpcm_per_time_us, &dir); + } + if( ret >= 0 ) + ret = snd_pcm_hw_params_get_period_size(phw, &zpcm_ufrm_size, &dir); + if( ret >= 0 ) { + zpcm_sper_size = zpcm_ufrm_size; + ret = snd_pcm_hw_params(zpcm, phw); + } + if( ret >= 0 ) + ret = snd_pcm_sw_params_current(zpcm, psw); + if( ret >= 0 ) + ret = snd_pcm_sw_params_set_start_threshold(zpcm, psw, + (zpcm_sbfr_size / zpcm_sper_size) * zpcm_sper_size); + if( ret >= 0 ) + ret = snd_pcm_sw_params_set_avail_min(zpcm, psw, zpcm_sper_size); + if( ret >= 0 ) + ret = snd_pcm_sw_params(zpcm, psw); + /* snd_pcm_dump(zpcm, stdout); */ + + if( ret >= 0 ) { +#ifdef __cplusplus + zpcm_areas = new snd_pcm_channel_area_t[chs]; + byts = snd_pcm_format_physical_width(fmt) / 8; + zpcm_samples = new short[zpcm_sper_size * chs * byts/2]; + zpcm_buffers = new short *[chs]; +#else + zpcm_areas = calloc(chs, sizeof(snd_pcm_channel_area_t)); + bits = snd_pcm_format_physical_width(fmt); + byts = bits / 8; + zpcm_samples = malloc(zpcm_sper_size * chs * byts); + zpcm_buffers = malloc(chs * sizeof(short*)); +#endif + if( zpcm_samples ) { + for( ich = 0; ich < chs; ++ich ) { + zpcm_areas[ich].addr = zpcm_samples; + zpcm_areas[ich].first = ich * zpcm_sper_size * bits; + zpcm_areas[ich].step = bits; + zpcm_buffers[ich] = zpcm_samples + ich*zpcm_sper_size; + } + } + else { + fprintf(stderr,"alsa sample buffer allocation failure.\n"); + ret = -999; + } + } + if( ret < 0 ) { + if( ret > -999 ) + printf("audio error: %s\n", snd_strerror(ret)); + alsa_close(); + } +} + +short *alsa_bfr(int ch) +{ + return zpcm_buffers[ch]; +} + +int alsa_bfrsz() +{ + return zpcm_sper_size; +} + +int alsa_recovery(int ret) +{ + printf("alsa recovery\n"); + switch( ret ) { + case -ESTRPIPE: + /* wait until the suspend flag is released, then fall through */ + while( (ret=snd_pcm_resume(zpcm)) == -EAGAIN ) usleep(100000); + case -EPIPE: + ret = snd_pcm_prepare(zpcm); + if( ret < 0 ) + printf("underrun, prepare failed: %s\n", snd_strerror(ret)); + break; + default: + printf("unhandled error: %s\n",snd_strerror(ret)); + break; + } + return ret; +} + +int alsa_write(int len) +{ + int i, ret; +#ifdef __cplusplus + short *bfrs[zpcm_channels]; +#else + short **bfrs = alloca(zpcm_channels*sizeof(short *)); +#endif + ret = 0; + for( i=0; i 0 ) { + ret = snd_pcm_writen(zpcm,(void **)bfrs, len); + if( ret == -EAGAIN ) continue; + if ( ret < 0 ) { + alsa_recovery(ret); + break; + } + for( i=0; imem, + GDK_COLORSPACE_RGB,FALSE,8,owidth,oheight,owidth*3,NULL,NULL); + cap0 = gdk_pixbuf_get_pixels(pbuf0); + image = gtk_image_new_from_pixbuf(pbuf0); + /* double buffered */ + img1 = gdk_image_new(GDK_IMAGE_SHARED, visual, owidth, oheight); + pbuf1 = gdk_pixbuf_new_from_data((const guchar *)img1->mem, + GDK_COLORSPACE_RGB,FALSE,8,owidth,oheight,owidth*3,NULL,NULL); + cap1 = gdk_pixbuf_get_pixels(pbuf1); + + panel_hbox = gtk_hbox_new(FALSE,0); + gtk_container_add(GTK_CONTAINER(window), panel_hbox); + /* pack image into panel */ + gtk_box_pack_start(GTK_BOX(panel_hbox), image, TRUE, TRUE, 0); + + +#ifdef __cplusplus + row0 = new unsigned char *[oheight]; + row1 = new unsigned char *[oheight]; + int cmdl = zmpeg3_t::cmdl_RGB888; +#else + row0 = malloc(oheight*sizeof(unsigned char *)); + row1 = malloc(oheight*sizeof(unsigned char *)); + int cmdl = MPEG3_RGB888; +#endif + for( row=0; rowstyle->black_gc; + gdk_draw_rgb_image(image->window,blk, 0,0,owidth,oheight, + GDK_RGB_DITHER_NONE,cap,owidth*3); + *(unsigned long *)&cap ^= ((unsigned long)cap0 ^ (unsigned long)cap1); + *(unsigned long *)&rows ^= ((unsigned long)row0 ^ (unsigned long)row1); + now = the_time(); + znow = mpeg3_get_time(zsrc); + if( zstart < 0. ) zstart = znow; + delay = (znow-zstart) - (now-start); + if( delay > 0 ) usleep((int)(delay*100000.0)); + more_data |= !mpeg3_end_of_video(zsrc,0); +#endif + ++frame; +#ifdef VIDEO + } + else + gtk_main_iteration(); +#endif + } + +#ifdef AUDIO + alsa_close(); +#endif + mpeg3_close(zsrc); + return 0; +} +