int opengl_close() { int ret; if (!opengl.started) return 0; glc_log(opengl.glc, GLC_DEBUG, "opengl", "closing"); if (opengl.capturing) gl_capture_stop(opengl.gl_capture); gl_capture_destroy(opengl.gl_capture); if (opengl.unscaled) { if (lib.running) { if ((ret = glc_util_write_end_of_stream(opengl.glc, opengl.unscaled))) { glc_log(opengl.glc, GLC_ERROR, "opengl", "can't write end of stream: %s (%d)", strerror(ret), ret); return ret; } } else ps_buffer_cancel(opengl.unscaled); if (opengl.convert_ycbcr_420jpeg) { ycbcr_process_wait(opengl.ycbcr); ycbcr_destroy(opengl.ycbcr); } else { scale_process_wait(opengl.scale); scale_destroy(opengl.scale); } } else if (lib.running) { if ((ret = glc_util_write_end_of_stream(opengl.glc, opengl.buffer))) { glc_log(opengl.glc, GLC_ERROR, "opengl", "can't write end of stream: %s (%d)", strerror(ret), ret); return ret; } } else ps_buffer_cancel(opengl.buffer); if (opengl.unscaled) { ps_buffer_destroy(opengl.unscaled); free(opengl.unscaled); } return 0; }
int export_img(struct play_s *play) { /* Export img uses following pipeline: file -(uncompressed_buffer)-> reads data from stream file unpack -(uncompressed_buffer)-> decompresses lzo/quicklz packets rgb -(rgb)-> does conversion to BGR scale -(scale)-> does rescaling color -(color)-> applies color correction img writes separate image files for each frame */ ps_bufferattr_t attr; ps_buffer_t uncompressed_buffer, compressed_buffer, rgb_buffer, color_buffer, scale_buffer; img_t img; color_t color; scale_t scale; unpack_t unpack; rgb_t rgb; int ret = 0; if ((ret = ps_bufferattr_init(&attr))) goto err; /* buffers */ if ((ret = ps_bufferattr_setsize(&attr, play->compressed_size))) goto err; if ((ret = ps_buffer_init(&compressed_buffer, &attr))) goto err; if ((ret = ps_bufferattr_setsize(&attr, play->uncompressed_size))) goto err; if ((ret = ps_buffer_init(&uncompressed_buffer, &attr))) goto err; if ((ret = ps_buffer_init(&color_buffer, &attr))) goto err; if ((ret = ps_buffer_init(&rgb_buffer, &attr))) goto err; if ((ret = ps_buffer_init(&scale_buffer, &attr))) goto err; if ((ret = ps_bufferattr_destroy(&attr))) goto err; /* filters */ if ((ret = unpack_init(&unpack, &play->glc))) goto err; if ((ret = rgb_init(&rgb, &play->glc))) goto err; if ((ret = scale_init(&scale, &play->glc))) goto err; if (play->scale_width && play->scale_height) scale_set_size(scale, play->scale_width, play->scale_height); else scale_set_scale(scale, play->scale_factor); if ((ret = color_init(&color, &play->glc))) goto err; if (play->override_color_correction) color_override(color, play->brightness, play->contrast, play->red_gamma, play->green_gamma, play->blue_gamma); if ((ret = img_init(&img, &play->glc))) goto err; img_set_filename(img, play->export_filename_format); img_set_stream_id(img, play->export_video_id); img_set_format(img, play->img_format); img_set_fps(img, play->fps); /* pipeline... */ if ((ret = unpack_process_start(unpack, &compressed_buffer, &uncompressed_buffer))) goto err; if ((ret = rgb_process_start(rgb, &uncompressed_buffer, &rgb_buffer))) goto err; if ((ret = scale_process_start(scale, &rgb_buffer, &scale_buffer))) goto err; if ((ret = color_process_start(color, &scale_buffer, &color_buffer))) goto err; if ((ret = img_process_start(img, &color_buffer))) goto err; /* ok, read the file */ if ((ret = file_read(play->file, &compressed_buffer))) goto err; /* wait 'till its done and clean up the mess... */ if ((ret = img_process_wait(img))) goto err; if ((ret = color_process_wait(color))) goto err; if ((ret = scale_process_wait(scale))) goto err; if ((ret = rgb_process_wait(rgb))) goto err; if ((ret = unpack_process_wait(unpack))) goto err; unpack_destroy(unpack); rgb_destroy(rgb); scale_destroy(scale); color_destroy(color); img_destroy(img); ps_buffer_destroy(&compressed_buffer); ps_buffer_destroy(&uncompressed_buffer); ps_buffer_destroy(&color_buffer); ps_buffer_destroy(&scale_buffer); ps_buffer_destroy(&rgb_buffer); return 0; err: fprintf(stderr, "exporting images failed: %s (%d)\n", strerror(ret), ret); return ret; }
int export_yuv4mpeg(struct play_s *play) { /* Export yuv4mpeg uses following pipeline: file -(uncompressed_buffer)-> reads data from stream file unpack -(uncompressed_buffer)-> decompresses lzo/quicklz packets scale -(scale)-> does rescaling color -(color)-> applies color correction ycbcr -(ycbcr)-> does conversion to Y'CbCr (if necessary) yuv4mpeg writes yuv4mpeg stream */ ps_bufferattr_t attr; ps_buffer_t uncompressed_buffer, compressed_buffer, ycbcr_buffer, color_buffer, scale_buffer; yuv4mpeg_t yuv4mpeg; ycbcr_t ycbcr; scale_t scale; unpack_t unpack; color_t color; int ret = 0; if ((ret = ps_bufferattr_init(&attr))) goto err; /* buffers */ if ((ret = ps_bufferattr_setsize(&attr, play->compressed_size))) goto err; if ((ret = ps_buffer_init(&compressed_buffer, &attr))) goto err; if ((ret = ps_bufferattr_setsize(&attr, play->uncompressed_size))) goto err; if ((ret = ps_buffer_init(&uncompressed_buffer, &attr))) goto err; if ((ret = ps_buffer_init(&color_buffer, &attr))) goto err; if ((ret = ps_buffer_init(&ycbcr_buffer, &attr))) goto err; if ((ret = ps_buffer_init(&scale_buffer, &attr))) goto err; if ((ret = ps_bufferattr_destroy(&attr))) goto err; /* initialize filters */ if ((ret = unpack_init(&unpack, &play->glc))) goto err; if ((ret = ycbcr_init(&ycbcr, &play->glc))) goto err; ycbcr_set_levels(ycbcr, play->tv_levels); if ((ret = scale_init(&scale, &play->glc))) goto err; if (play->scale_width && play->scale_height) scale_set_size(scale, play->scale_width, play->scale_height); else scale_set_scale(scale, play->scale_factor); if ((ret = color_init(&color, &play->glc))) goto err; if (play->override_color_correction) color_override(color, play->brightness, play->contrast, play->red_gamma, play->green_gamma, play->blue_gamma); if ((ret = yuv4mpeg_init(&yuv4mpeg, &play->glc))) goto err; yuv4mpeg_set_fps(yuv4mpeg, play->fps); yuv4mpeg_set_stream_id(yuv4mpeg, play->export_video_id); yuv4mpeg_set_interpolation(yuv4mpeg, play->interpolate); yuv4mpeg_set_filename(yuv4mpeg, play->export_filename_format); /* construct the pipeline */ if ((ret = unpack_process_start(unpack, &compressed_buffer, &uncompressed_buffer))) goto err; if ((ret = scale_process_start(scale, &uncompressed_buffer, &scale_buffer))) goto err; if ((ret = color_process_start(color, &scale_buffer, &color_buffer))) goto err; if ((ret = ycbcr_process_start(ycbcr, &color_buffer, &ycbcr_buffer))) goto err; if ((ret = yuv4mpeg_process_start(yuv4mpeg, &ycbcr_buffer))) goto err; /* feed it with data */ if ((ret = file_read(play->file, &compressed_buffer))) goto err; /* threads will do the dirty work... */ if ((ret = yuv4mpeg_process_wait(yuv4mpeg))) goto err; if ((ret = color_process_wait(color))) goto err; if ((ret = scale_process_wait(scale))) goto err; if ((ret = ycbcr_process_wait(ycbcr))) goto err; if ((ret = unpack_process_wait(unpack))) goto err; unpack_destroy(unpack); ycbcr_destroy(ycbcr); scale_destroy(scale); color_destroy(color); yuv4mpeg_destroy(yuv4mpeg); ps_buffer_destroy(&compressed_buffer); ps_buffer_destroy(&uncompressed_buffer); ps_buffer_destroy(&color_buffer); ps_buffer_destroy(&scale_buffer); ps_buffer_destroy(&ycbcr_buffer); return 0; err: fprintf(stderr, "exporting yuv4mpeg failed: %s (%d)\n", strerror(ret), ret); return ret; }
int play_stream(struct play_s *play) { /* Playback uses following pipeline: file -(uncompressed)-> reads data from stream file unpack -(uncompressed)-> decompresses lzo/quicklz packets rgb -(rgb)-> does conversion to BGR scale -(scale)-> does rescaling color -(color)-> applies color correction demux -(...)-> gl_play, alsa_play Each filter, except demux and file, has glc_threads_hint(glc) worker threads. Packet order in stream is preserved. Demux creates separate buffer and _play handler for each video/audio stream. */ ps_bufferattr_t attr; ps_buffer_t uncompressed_buffer, compressed_buffer, rgb_buffer, color_buffer, scale_buffer; demux_t demux; color_t color; scale_t scale; unpack_t unpack; rgb_t rgb; int ret = 0; if ((ret = ps_bufferattr_init(&attr))) goto err; /* 'compressed_buffer' buffer holds raw data from file and has its own size. */ if ((ret = ps_bufferattr_setsize(&attr, play->compressed_size))) goto err; if ((ret = ps_buffer_init(&compressed_buffer, &attr))) goto err; /* rest use 'uncompressed_buffer' size */ if ((ret = ps_bufferattr_setsize(&attr, play->uncompressed_size))) goto err; if ((ret = ps_buffer_init(&uncompressed_buffer, &attr))) goto err; if ((ret = ps_buffer_init(&color_buffer, &attr))) goto err; if ((ret = ps_buffer_init(&rgb_buffer, &attr))) goto err; if ((ret = ps_buffer_init(&scale_buffer, &attr))) goto err; /* no longer necessary */ if ((ret = ps_bufferattr_destroy(&attr))) goto err; /* init filters */ if ((ret = unpack_init(&unpack, &play->glc))) goto err; if ((ret = rgb_init(&rgb, &play->glc))) goto err; if ((ret = scale_init(&scale, &play->glc))) goto err; if (play->scale_width && play->scale_height) scale_set_size(scale, play->scale_width, play->scale_height); else scale_set_scale(scale, play->scale_factor); if ((ret = color_init(&color, &play->glc))) goto err; if (play->override_color_correction) color_override(color, play->brightness, play->contrast, play->red_gamma, play->green_gamma, play->blue_gamma); if ((ret = demux_init(&demux, &play->glc))) goto err; demux_set_video_buffer_size(demux, play->uncompressed_size); demux_set_audio_buffer_size(demux, play->uncompressed_size / 10); demux_set_alsa_playback_device(demux, play->alsa_playback_device); /* construct a pipeline for playback */ if ((ret = unpack_process_start(unpack, &compressed_buffer, &uncompressed_buffer))) goto err; if ((ret = rgb_process_start(rgb, &uncompressed_buffer, &rgb_buffer))) goto err; if ((ret = scale_process_start(scale, &rgb_buffer, &scale_buffer))) goto err; if ((ret = color_process_start(color, &scale_buffer, &color_buffer))) goto err; if ((ret = demux_process_start(demux, &color_buffer))) goto err; /* the pipeline is ready - lets give it some data */ if ((ret = file_read(play->file, &compressed_buffer))) goto err; /* we've done our part - just wait for the threads */ if ((ret = demux_process_wait(demux))) goto err; /* wait for demux, since when it quits, others should also */ if ((ret = color_process_wait(color))) goto err; if ((ret = scale_process_wait(scale))) goto err; if ((ret = rgb_process_wait(rgb))) goto err; if ((ret = unpack_process_wait(unpack))) goto err; /* stream processed - clean up time */ unpack_destroy(unpack); rgb_destroy(rgb); scale_destroy(scale); color_destroy(color); demux_destroy(demux); ps_buffer_destroy(&compressed_buffer); ps_buffer_destroy(&uncompressed_buffer); ps_buffer_destroy(&color_buffer); ps_buffer_destroy(&scale_buffer); ps_buffer_destroy(&rgb_buffer); return 0; err: if (!ret) { fprintf(stderr, "playing stream failed: initializing filters failed\n"); return EAGAIN; } else { fprintf(stderr, "playing stream failed: %s (%d)\n", strerror(ret), ret); return ret; } }