void bg_recorder_video_cleanup(bg_recorder_t * rec) { bg_recorder_video_stream_t * vs = &rec->vs; if(vs->flags & STREAM_INPUT_OPEN) vs->input_plugin->close(vs->input_handle->priv); if(vs->pipe_frame_priv) gavl_video_frame_destroy(vs->pipe_frame_priv); if(vs->monitor_frame_priv) gavl_video_frame_destroy(vs->monitor_frame_priv); vs->pipe_frame_priv = NULL; vs->monitor_frame_priv = NULL; if(vs->flags & STREAM_MONITOR_OPEN) vs->monitor_plugin->close(vs->monitor_handle->priv); if(vs->enc_frame) { gavl_video_frame_destroy(vs->enc_frame); vs->enc_frame = NULL; } vs->flags &= ~(STREAM_INPUT_OPEN | STREAM_ENCODE_OPEN | STREAM_MONITOR_OPEN | STREAM_SNAPSHOT_INIT); }
void gavl_video_deinterlacer_destroy(gavl_video_deinterlacer_t * d) { gavl_video_frame_destroy(d->src_field); gavl_video_frame_destroy(d->dst_field); if(d->scaler) gavl_video_scaler_destroy(d->scaler); free(d); }
static void set_format(void * priv, const gavl_video_format_t * format) { swapfields_priv_t * vp; vp = priv; vp->framerate_mult = 1; vp->noop = 0; gavl_video_format_copy(&vp->format, format); gavl_get_field_format(format, &vp->field_format[0], 0); gavl_get_field_format(format, &vp->field_format[1], 1); if(vp->format.interlace_mode == GAVL_INTERLACE_TOP_FIRST) { vp->format.interlace_mode = GAVL_INTERLACE_BOTTOM_FIRST; /* Top first -> bottom first: Delay bottom field */ vp->delay_field = 1; } else if(vp->format.interlace_mode == GAVL_INTERLACE_BOTTOM_FIRST) { vp->format.interlace_mode = GAVL_INTERLACE_TOP_FIRST; /* Bottom first -> top first: Delay top field */ vp->delay_field = 0; } else { bg_log(BG_LOG_WARNING, LOG_DOMAIN, "Unsupported interlace mode, need top-first or bottom-first"); vp->noop = 1; } if(!vp->noop) { if(vp->format.frame_duration % 2) { vp->framerate_mult = 2; vp->format.timescale *= 2; vp->format.frame_duration *= 2; } } if(vp->fields[0]) { gavl_video_frame_destroy(vp->fields[0]); vp->fields[0] = NULL; } if(vp->fields[1]) { gavl_video_frame_destroy(vp->fields[1]); vp->fields[1] = NULL; } vp->init = 1; }
static void gavf_stream_free(gavf_stream_t * s) { if(s->asrc) gavl_audio_source_destroy(s->asrc); if(s->vsrc) gavl_video_source_destroy(s->vsrc); if(s->psrc) gavl_packet_source_destroy(s->psrc); if(s->asink) gavl_audio_sink_destroy(s->asink); if(s->vsink) gavl_video_sink_destroy(s->vsink); if(s->psink) gavl_packet_sink_destroy(s->psink); if(s->pb) gavf_packet_buffer_destroy(s->pb); if(s->aframe) { gavl_audio_frame_null(s->aframe); gavl_audio_frame_destroy(s->aframe); } if(s->vframe) { gavl_video_frame_null(s->vframe); gavl_video_frame_destroy(s->vframe); } }
void bg_ov_destroy_overlay(bg_ov_t * ov, int id, gavl_overlay_t * ovl) { if(ov->flags & FLAG_EMULATE_OVL) gavl_video_frame_destroy(ovl); else ov->plugin->destroy_overlay(ov->priv, id, ovl); }
void bg_ov_close(bg_ov_t * ov) { LOCK(ov); ov->plugin->close(ov->priv); UNLOCK(ov); if(ov->still_frame) { gavl_video_frame_destroy(ov->still_frame); ov->still_frame = NULL; } if(ov->num_ovl_str) { int i; for(i = 0; i < ov->num_ovl_str; i++) { if(ov->ovl_str[i].ctx) gavl_overlay_blend_context_destroy(ov->ovl_str[i].ctx); } free(ov->ovl_str); ov->ovl_str = NULL; ov->num_ovl_str = 0; } if(ov->sink_ext) { gavl_video_sink_destroy(ov->sink_ext); ov->sink_ext = NULL; } }
void gavf_close(gavf_t * g) { int i; if(g->wr) { if(g->streams) { /* Flush packets if any */ gavf_flush_packets(g, NULL); /* Append final sync header */ write_sync_header(g, -1, NULL); } /* Write footer */ if(!gavf_footer_write(g)) return; } /* Free stuff */ if(g->streams) { for(i = 0; i < g->ph.num_streams; i++) gavf_stream_free(&g->streams[i]); free(g->streams); } gavf_sync_index_free(&g->si); gavf_packet_index_free(&g->pi); gavf_program_header_free(&g->ph); if(g->cl) gavl_chapter_list_destroy(g->cl); if(g->write_vframe) { gavl_video_frame_null(g->write_vframe); gavl_video_frame_destroy(g->write_vframe); } if(g->write_aframe) { gavl_audio_frame_null(g->write_aframe); gavl_audio_frame_destroy(g->write_aframe); } if(g->sync_pts) free(g->sync_pts); gavl_packet_free(&g->write_pkt); gavf_buffer_free(&g->pkt_buf); gavf_buffer_free(&g->meta_buf); gavl_metadata_free(&g->metadata); free(g); }
static void destroy_swapfields(void * priv) { swapfields_priv_t * vp; vp = priv; if(vp->cpy_field) { gavl_video_frame_null(vp->cpy_field); gavl_video_frame_destroy(vp->cpy_field); } if(vp->fields[0]) gavl_video_frame_destroy(vp->fields[0]); if(vp->fields[1]) gavl_video_frame_destroy(vp->fields[1]); if(vp->out_src) gavl_video_source_destroy(vp->out_src); free(vp); }
void gavl_video_scaler_destroy(gavl_video_scaler_t * s) { int i, j; gavl_video_frame_null(s->src); gavl_video_frame_null(s->dst); gavl_video_frame_destroy(s->src); gavl_video_frame_destroy(s->dst); for(i = 0; i < 3; i++) { for(j = 0; j < GAVL_MAX_PLANES; j++) { gavl_video_scale_context_cleanup(&s->contexts[i][j]); } } free(s); }
livido_deinit_f deinit_instance( livido_port_t *my_instance ) { scale0tilt_instance_t *inst = NULL; livido_property_get( my_instance, "PLUGIN_private", 0, &inst ); gavl_video_scaler_destroy(inst->video_scaler); gavl_video_frame_null( inst->frame_src ); gavl_video_frame_destroy( inst->frame_src ); gavl_video_frame_null( inst->frame_dst ); gavl_video_frame_destroy( inst->frame_dst ); gavl_video_frame_null( inst->temp ); gavl_video_frame_destroy( inst->temp ); gavl_video_frame_null( inst->temp_alpha ); gavl_video_frame_destroy( inst->temp_alpha ); free(inst); livido_property_set( my_instance, "PLUGIN_private", LIVIDO_ATOM_TYPE_VOIDPTR, 0, NULL ); return LIVIDO_NO_ERROR; }
static Pixmap make_mask(bg_x11_window_t * win, const gavl_video_frame_t * icon, const gavl_video_format_t * format) { gavl_video_frame_t * alpha_frame; gavl_video_format_t alpha_format; char * image_data; Pixmap ret; int bytes_per_line; /* Extract alpha */ if(!gavl_get_color_channel_format(format, &alpha_format, GAVL_CCH_ALPHA)) return None; /* No alpha */ alpha_frame = gavl_video_frame_create(&alpha_format); gavl_video_frame_extract_channel(format, GAVL_CCH_ALPHA, icon, alpha_frame); /* Create image */ bytes_per_line = (format->image_width + 7) / 8; image_data = calloc(1, bytes_per_line * format->image_height); switch(alpha_format.pixelformat) { case GAVL_GRAY_8: create_mask_8(&alpha_format, alpha_frame, image_data, bytes_per_line); break; case GAVL_GRAY_16: create_mask_16(&alpha_format, alpha_frame, image_data, bytes_per_line); break; case GAVL_GRAY_FLOAT: create_mask_float(&alpha_format, alpha_frame, image_data, bytes_per_line); break; default: break; } ret = XCreateBitmapFromData(win->dpy, win->root, image_data, format->image_width, format->image_height); gavl_video_frame_destroy(alpha_frame); free(image_data); return ret; }
static void close_schroedinger(bgav_stream_t * s) { schroedinger_priv_t * priv; priv = s->decoder_priv; if(priv->dec) schro_decoder_free(priv->dec); gavl_video_frame_null(priv->frame); gavl_video_frame_destroy(priv->frame); free(priv); }
static void video_converter_cleanup(gavl_video_converter_t* cnv) { gavl_video_convert_context_t * ctx; while(cnv->first_context) { ctx = cnv->first_context->next; if(cnv->first_context->scaler) gavl_video_scaler_destroy(cnv->first_context->scaler); if(cnv->first_context->output_frame && cnv->first_context->next) gavl_video_frame_destroy(cnv->first_context->output_frame); free(cnv->first_context); cnv->first_context = ctx; } cnv->last_context = NULL; cnv->num_contexts = 0; }
ReadMedia::~ReadMedia() { printf("killing the media..\n"); setCommand( CMD_QUIT ); signalDispatcher(); // signal dispatcher joins the opener and AV threads pthread_join( m_thread_dispatch, NULL); //printf("joined dispatcher\n"); if (m_audio_frame != NULL) { gavl_audio_frame_destroy(m_audio_frame); } if (m_video_frame != NULL) { gavl_video_frame_destroy(m_video_frame); } if (m_file != NULL) { bgav_close(m_file); } //printf("now, on to deleting fifo...\n"); if( m_fifoaudio != NULL) delete m_fifoaudio; if( m_fifovideo != NULL) delete m_fifovideo; // these are created only once bgav_options_destroy(m_opt); pthread_cond_destroy(&m_cond_dispatch); pthread_mutex_destroy(&m_condmut_dispatch); pthread_cond_destroy(&m_cond_a); pthread_cond_destroy(&m_cond_v); pthread_mutex_destroy(&m_condmut_a); pthread_mutex_destroy(&m_condmut_v); pthread_mutex_destroy(&m_av_mut); pthread_mutex_destroy(&m_state_mut); printf("killed the media..\n"); }
int main(int argc, char ** argv) { char * tmp_path; bg_cfg_registry_t * cfg_reg = NULL; bg_cfg_section_t * cfg_section; bg_plugin_registry_t * plugin_reg = NULL; gavl_video_format_t format; gavl_video_frame_t * frame = NULL; bg_ocr_t * ocr = NULL; char * ret = NULL; bg_parameter_value_t val; /* Create config registry */ cfg_reg = bg_cfg_registry_create(); tmp_path = bg_search_file_read("generic", "config.xml"); bg_cfg_registry_load(cfg_reg, tmp_path); if(tmp_path) free(tmp_path); /* Get the config section for the plugins */ cfg_section = bg_cfg_registry_find_section(cfg_reg, "plugins"); /* Create plugin registry */ plugin_reg = bg_plugin_registry_create(cfg_section); /* Create ocr */ ocr = bg_ocr_create(plugin_reg); val.val_str = "."; bg_ocr_set_parameter(ocr, "tmpdir", &val); if(!ocr) goto fail; /* Load image */ memset(&format, 0, sizeof(format)); frame = bg_plugin_registry_load_image(plugin_reg, argv[1], &format, NULL); if(!bg_ocr_init(ocr, &format, "deu")) return -1; if(!bg_ocr_run(ocr, &format, frame, &ret)) return -1; fprintf(stderr, "Got string: %s\n", ret); fail: if(ocr) bg_ocr_destroy(ocr); if(frame) gavl_video_frame_destroy(frame); if(plugin_reg) bg_plugin_registry_destroy(plugin_reg); if(cfg_reg) bg_cfg_registry_destroy(cfg_reg); if(ret) free(ret); return 0; }
static int write_image_tga(void * priv, gavl_video_frame_t * frame) { tga_t * tga = priv; gavl_video_frame_t * tmp_frame; int result, ret = 1; errno = 0; if(tga->format.pixelformat == GAVL_RGBA_32) { tmp_frame = gavl_video_frame_create(&tga->format); gavl_video_frame_copy(&tga->format, tmp_frame, frame); if(tga->rle) { result = tga_write_rgb(tga->filename, tmp_frame->planes[0], tga->format.image_width, tga->format.image_height, 32, frame->strides[0]); } else { result =tga_write_rgb_rle(tga->filename, tmp_frame->planes[0], tga->format.image_width, tga->format.image_height, 32, frame->strides[0]); } gavl_video_frame_destroy(tmp_frame); } else { if(tga->rle) { result = tga_write_bgr(tga->filename, frame->planes[0], tga->format.image_width, tga->format.image_height, 24, frame->strides[0]); } else { result = tga_write_bgr_rle(tga->filename, frame->planes[0], tga->format.image_width, tga->format.image_height, 24, frame->strides[0]); } } if(result != TGA_NOERR) { if(errno) bg_log(BG_LOG_ERROR, LOG_DOMAIN, "Cannot save %s: %s", tga->filename, strerror(errno)); else bg_log(BG_LOG_ERROR, LOG_DOMAIN, "Cannot save %s: %s", tga->filename, tga_error(result)); ret = 0; } free(tga->filename); tga->filename = NULL; return ret; }
bool ReadMedia::initFormat() { const gavl_audio_format_t * open_audio_format; const gavl_video_format_t * open_video_format; // we use the m_vfifosize to see if the user app wants video or not // then, we set m_video_stream_count to 0 if he doesn't want video if (m_video_stream_count > 0 && m_vfifosize > 0) { open_video_format = bgav_get_video_format(m_file, 0); if (open_video_format->pixelformat == GAVL_PIXELFORMAT_NONE) { printf("!!!sorry, pixelformat is not recognized.\n"); return false; } // let's check to see if the formats are the same, if they are the same // there is no reason to recreate the fifo or frames if ( gavl_video_formats_equal( &m_video_format, open_video_format) == 0 ) { // the formats are different gavl_video_format_copy (&m_video_format, open_video_format); if (m_video_frame != NULL) gavl_video_frame_destroy(m_video_frame); m_video_frame = gavl_video_frame_create(&m_video_format); gavl_video_frame_clear( m_video_frame, &m_video_format); if (m_fifovideo != NULL) delete m_fifovideo; m_fifovideo= new FifoVideoFrames( m_vfifosize , &m_video_format); } } else { m_video_stream_count = 0; m_veof = true; } // we use the m_afifosize to see if the user app wants audio or not // then, we set m_audio_stream_count to 0 if he doesn't want audio if (m_audio_stream_count > 0 && m_afifosize > 0) { open_audio_format = bgav_get_audio_format(m_file, 0); // we can get audio formats that are unkown if ( open_audio_format->sample_format == GAVL_SAMPLE_NONE) { printf("sorry, this file has unsupported audio.\n"); return false; } if ( gavl_audio_formats_equal(&m_audio_format, open_audio_format) == 0 ) { // audio formats are different // save the old spf int spf = m_audio_format.samples_per_frame; gavl_audio_format_copy(&m_audio_format, open_audio_format); if (m_audio_frame != NULL) { gavl_audio_frame_destroy(m_audio_frame); } // set it back to original m_audio_format.samples_per_frame = spf ; m_audio_frame = gavl_audio_frame_create(&m_audio_format); gavl_audio_frame_mute( m_audio_frame, &m_audio_format); if( m_fifoaudio != NULL ) delete m_fifoaudio; m_fifoaudio = new FifoAudioFrames( m_afifosize , &m_audio_format); } } else { // user doesn't want audio m_audio_stream_count = 0; m_aeof=true; } m_length_in_gavltime = bgav_get_duration ( m_file, 0);; m_length_in_seconds = gavl_time_to_seconds( m_length_in_gavltime ); m_num_samples = 0; m_num_frames = 0; if (m_audio_stream_count) { if ( bgav_can_seek_sample(m_file) == 1 ) { m_num_samples= bgav_audio_duration ( m_file, 0) ; } else { m_num_samples= gavl_time_to_samples( m_audio_format.samplerate , bgav_get_duration ( m_file, 0) ); } } // set frames WE NEED TO take care here for non-constant frame-rates if(m_video_stream_count) { if ( bgav_can_seek_sample(m_file) == 1 && m_video_format.framerate_mode == GAVL_FRAMERATE_CONSTANT) { m_num_frames = bgav_video_duration ( m_file, 0)/ m_video_format.frame_duration; } else if ( bgav_can_seek_sample(m_file) == 1 && m_video_format.framerate_mode == GAVL_FRAMERATE_VARIABLE ) { // FIXME what to do with non constant frame rates? m_num_frames=0; } else { m_num_frames = gavl_time_to_frames( m_video_format.timescale, m_video_format.frame_duration , bgav_get_duration ( m_file, 0) ); } } // printf("m_num_frames =%lld, duration = %lld , vid_duration=%lld\n", // m_num_frames, bgav_get_duration ( m_file, 0), bgav_video_duration ( m_file, 0) ); // set seconds if ( bgav_can_seek_sample(m_file) == 1) { gavl_time_t atime=0,vtime=0; if ( m_audio_stream_count ) atime = gavl_samples_to_time( m_audio_format.samplerate, m_num_samples ); if (m_video_stream_count && m_video_format.frame_duration > 0) { vtime = gavl_frames_to_time( m_video_format.timescale, m_video_format.frame_duration, m_num_frames ); } else if ( m_video_stream_count ) { // non constant framerate vtime = bgav_video_duration( m_file, 0); } // else rely on audio time m_length_in_gavltime = atime > vtime ? atime :vtime; m_length_in_seconds = gavl_time_to_seconds( m_length_in_gavltime ); //printf("atime=%ld, vtime=%ld, l_in_sec=%f\n", atime, vtime, m_length_in_seconds); } m_pcm_seek = SEEK_NOTHING; m_frame_seek = SEEK_NOTHING; return true; }
static Pixmap make_icon(bg_x11_window_t * win, const gavl_video_frame_t * icon, const gavl_video_format_t * format) { XImage * im; gavl_video_format_t out_format; gavl_video_converter_t * cnv; gavl_video_options_t * opt; int do_convert; const gavl_video_frame_t * image_frame; gavl_video_frame_t * out_frame; Pixmap ret; /* Create converter */ cnv = gavl_video_converter_create(); opt = gavl_video_converter_get_options(cnv); gavl_video_options_set_alpha_mode(opt, GAVL_ALPHA_IGNORE); /* Create pixmap */ ret = XCreatePixmap(win->dpy, win->root, format->image_width, format->image_height, win->depth); /* Set up format and converter */ gavl_video_format_copy(&out_format, format); out_format.pixelformat = bg_x11_window_get_pixelformat(win->dpy, win->visual, win->depth); do_convert = gavl_video_converter_init(cnv, format, &out_format); if(do_convert) { out_frame = gavl_video_frame_create(&out_format); image_frame = out_frame; gavl_video_convert(cnv, icon, out_frame); } else { image_frame = icon; out_frame = NULL; } /* Make image */ im = XCreateImage(win->dpy, win->visual, win->depth, ZPixmap, 0, (char*)(image_frame->planes[0]), format->image_width, format->image_height, 32, image_frame->strides[0]); XPutImage(win->dpy, /* dpy */ ret, /* d */ win->gc, /* gc */ im, /* image */ 0, /* src_x */ 0, /* src_y */ 0, /* dst_x */ 0, /* dst_y */ format->image_width, /* src_width */ format->image_height); /* src_height */ /* Cleanup */ gavl_video_converter_destroy(cnv); if(out_frame) gavl_video_frame_destroy(out_frame); im->data = NULL; XDestroyImage(im); /* Return */ return ret; }
static char * save_image(bg_db_t * db, gavl_video_frame_t * in_frame, gavl_video_format_t * in_format, gavl_video_format_t * out_format, gavl_video_converter_t * cnv, int64_t id, const char * mimetype) { int result = 0; int do_convert; gavl_video_frame_t * output_frame = NULL; bg_image_writer_plugin_t * output_plugin; bg_plugin_handle_t * output_handle = NULL; const bg_plugin_info_t * plugin_info; iw_t iw; bg_iw_callbacks_t cb; char * out_file_base = bg_sprintf("gmerlin-db/thumbnails/%016"PRId64, id); out_file_base = bg_db_filename_to_abs(db, out_file_base); memset(&iw, 0, sizeof(iw)); memset(&cb, 0, sizeof(cb)); cb.create_output_file = create_file; cb.data = &iw; out_format->pixel_width = 1; out_format->pixel_height = 1; out_format->interlace_mode = GAVL_INTERLACE_NONE; out_format->frame_width = out_format->image_width; out_format->frame_height = out_format->image_height; plugin_info = bg_plugin_find_by_mimetype(db->plugin_reg, mimetype, BG_PLUGIN_IMAGE_WRITER); if(!plugin_info) { bg_log(BG_LOG_ERROR, LOG_DOMAIN, "No plugin for %s", mimetype); goto end; } output_handle = bg_plugin_load(db->plugin_reg, plugin_info); if(!output_handle) { bg_log(BG_LOG_ERROR, LOG_DOMAIN, "Loading %s failed", plugin_info->long_name); goto end; } output_plugin = (bg_image_writer_plugin_t*)output_handle->plugin; output_plugin->set_callbacks(output_handle->priv, &cb); if(!output_plugin->write_header(output_handle->priv, out_file_base, out_format, NULL)) { bg_log(BG_LOG_ERROR, LOG_DOMAIN, "Writing image header failed"); goto end; } /* Initialize video converter */ do_convert = gavl_video_converter_init(cnv, in_format, out_format); if(do_convert) { output_frame = gavl_video_frame_create(out_format); gavl_video_frame_clear(output_frame, out_format); gavl_video_convert(cnv, in_frame, output_frame); if(!output_plugin->write_image(output_handle->priv, output_frame)) { bg_log(BG_LOG_ERROR, LOG_DOMAIN, "Writing image failed"); goto end; } } else { if(!output_plugin->write_image(output_handle->priv, in_frame)) { bg_log(BG_LOG_ERROR, LOG_DOMAIN, "Writing image failed"); goto end; } } result = 1; end: if(output_frame) gavl_video_frame_destroy(output_frame); if(output_handle) bg_plugin_unref(output_handle); if(out_file_base) free(out_file_base); if(result) return iw.filename; if(iw.filename) free(iw.filename); return NULL; }
static void * make_thumbnail(bg_db_t * db, bg_db_object_t * obj, int max_width, int max_height, const char * mimetype) { bg_db_file_t * thumb; int ret = 0; /* Formats */ gavl_video_format_t input_format; gavl_video_format_t output_format; /* Frames */ gavl_video_frame_t * input_frame = NULL; gavl_video_converter_t * cnv = 0; const char * src_ext; bg_db_image_file_t * image = (bg_db_image_file_t *)obj; char * path_abs; bg_db_scan_item_t item; double ext_x, ext_y; double ar; src_ext = strrchr(image->file.path, '.'); if(src_ext) src_ext++; /* Return early */ if(image->file.mimetype && !strcasecmp(image->file.mimetype, mimetype) && (image->width <= max_width) && (image->height <= max_height)) { bg_db_object_ref(image); return obj; } memset(&input_format, 0, sizeof(input_format)); cnv = gavl_video_converter_create(); input_frame = bg_plugin_registry_load_image(db->plugin_reg, image->file.path, &input_format, NULL); ar = (double)input_format.image_width / (double)input_format.image_height; gavl_video_format_copy(&output_format, &input_format); ext_x = (double)input_format.image_width / (double)max_width; ext_y = (double)input_format.image_height / (double)max_height; if((ext_x > 1.0) || (ext_y > 1.0)) { if(ext_x > ext_y) // Fit to max_width { output_format.image_width = max_width; output_format.image_height = (int)((double)max_width / ar + 0.5); } else // Fit to max_height { output_format.image_height = max_height; output_format.image_width = (int)((double)max_height * ar + 0.5); } } /* Save image */ thumb = bg_db_object_create(db); path_abs = save_image(db, input_frame, &input_format, &output_format, cnv, bg_db_object_get_id(thumb), mimetype); if(!path_abs) goto end; /* Create a new image object */ memset(&item, 0, sizeof(item)); if(!bg_db_scan_item_set(&item, path_abs)) goto end; bg_log(BG_LOG_INFO, LOG_DOMAIN, "Made thumbnail %dx%d in %s", output_format.image_width, output_format.image_height, path_abs); thumb = bg_db_file_create_from_object(db, (bg_db_object_t*)thumb, ~0, &item, -1); if(!thumb) goto end; bg_db_object_set_type(thumb, BG_DB_OBJECT_THUMBNAIL); thumb->obj.ref_id = bg_db_object_get_id(image); bg_db_object_set_parent_id(db, thumb, -1); bg_db_scan_item_free(&item); ret = 1; end: if(input_frame) gavl_video_frame_destroy(input_frame); if(cnv) gavl_video_converter_destroy(cnv); if(!ret) { bg_db_object_delete(db, thumb); return NULL; } return thumb; }
gavl_video_frame_t * read_png(const char * filename, gavl_video_format_t * format, gavl_pixelformat_t pixelformat) { int i; unsigned char ** rows; gavl_video_converter_t * cnv; gavl_video_options_t * opt; gavl_video_format_t format_1; gavl_video_frame_t * frame, * frame_1; int bit_depth; int color_type; int has_alpha = 0; png_structp png_ptr; png_infop info_ptr; png_infop end_info; FILE * file; file = fopen(filename, "rb"); if(!file) { fprintf(stderr, "Cannot open file %s\n", filename); return NULL; } png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); setjmp(png_jmpbuf(png_ptr)); info_ptr = png_create_info_struct(png_ptr); end_info = png_create_info_struct(png_ptr); png_init_io(png_ptr, file); png_read_info(png_ptr, info_ptr); format->frame_width = png_get_image_width(png_ptr, info_ptr); format->frame_height = png_get_image_height(png_ptr, info_ptr); format->image_width = format->frame_width; format->image_height = format->frame_height; format->pixel_width = 1; format->pixel_height = 1; bit_depth = png_get_bit_depth(png_ptr, info_ptr); color_type = png_get_color_type(png_ptr, info_ptr); switch(color_type) { case PNG_COLOR_TYPE_GRAY: /* (bit depths 1, 2, 4, 8, 16) */ if(bit_depth < 8) #if GAVL_MAKE_BUILD(PNG_LIBPNG_VER_MAJOR, PNG_LIBPNG_VER_MINOR, PNG_LIBPNG_VER_RELEASE) < GAVL_MAKE_BUILD(1,2,9) png_set_gray_1_2_4_to_8(png_ptr); #else png_set_expand_gray_1_2_4_to_8(png_ptr); #endif if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { png_set_tRNS_to_alpha(png_ptr); has_alpha = 1; } png_set_gray_to_rgb(png_ptr); break; case PNG_COLOR_TYPE_GRAY_ALPHA: /* (bit depths 8, 16) */ if(bit_depth == 16) png_set_strip_16(png_ptr); png_set_gray_to_rgb(png_ptr); break; case PNG_COLOR_TYPE_PALETTE: /* (bit depths 1, 2, 4, 8) */ png_set_palette_to_rgb(png_ptr); if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { png_set_tRNS_to_alpha(png_ptr); has_alpha = 1; } break; case PNG_COLOR_TYPE_RGB: /* (bit_depths 8, 16) */ if(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { png_set_tRNS_to_alpha(png_ptr); has_alpha = 1; } if(bit_depth == 16) png_set_strip_16(png_ptr); break; case PNG_COLOR_TYPE_RGB_ALPHA: /* (bit_depths 8, 16) */ if(bit_depth == 16) png_set_strip_16(png_ptr); has_alpha = 1; break; } if(has_alpha) format->pixelformat = GAVL_RGBA_32; else format->pixelformat = GAVL_RGB_24; frame = gavl_video_frame_create(format); rows = malloc(format->frame_height * sizeof(*rows)); for(i = 0; i < format->frame_height; i++) rows[i] = frame->planes[0] + i * frame->strides[0]; png_read_image(png_ptr, rows); png_read_end(png_ptr, end_info); png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(file); free(rows); /* Check wether to set up the converter */ if(format->pixelformat != pixelformat) { cnv = gavl_video_converter_create(); opt = gavl_video_converter_get_options(cnv); gavl_video_options_set_alpha_mode(opt, GAVL_ALPHA_BLEND_COLOR); gavl_video_format_copy(&format_1, format); format_1.pixelformat = pixelformat; frame_1 = gavl_video_frame_create(&format_1); gavl_video_converter_init(cnv, format, &format_1); gavl_video_convert(cnv, frame, frame_1); gavl_video_converter_destroy(cnv); format->pixelformat = pixelformat; } else frame_1 = NULL; if(frame_1) { gavl_video_frame_destroy(frame); return frame_1; } else return frame; }
void write_png(char * filename, gavl_video_format_t * format, gavl_video_frame_t * frame) { int i; unsigned char ** rows; gavl_video_options_t * opt; int color_type; FILE * output; png_structp png_ptr; png_infop info_ptr; gavl_video_converter_t * cnv; gavl_video_format_t format_1; gavl_video_frame_t * frame_1 = NULL; if((format->pixelformat != GAVL_RGB_24) && (format->pixelformat != GAVL_RGBA_32)) { cnv = gavl_video_converter_create(); gavl_video_format_copy(&format_1, format); if(gavl_pixelformat_has_alpha(format->pixelformat)) { format_1.pixelformat = GAVL_RGBA_32; color_type = PNG_COLOR_TYPE_RGBA; } else { format_1.pixelformat = GAVL_RGB_24; color_type = PNG_COLOR_TYPE_RGB; } frame_1 = gavl_video_frame_create(&format_1); opt = gavl_video_converter_get_options(cnv); gavl_video_options_set_alpha_mode(opt, GAVL_ALPHA_BLEND_COLOR); gavl_video_converter_init(cnv, format, &format_1); gavl_video_convert(cnv, frame, frame_1); gavl_video_converter_destroy(cnv); } else if(format->pixelformat == GAVL_RGB_24) { color_type = PNG_COLOR_TYPE_RGB; } else { color_type = PNG_COLOR_TYPE_RGBA; } output = fopen(filename, "wb"); if(!output) return; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); info_ptr = png_create_info_struct(png_ptr); setjmp(png_jmpbuf(png_ptr)); png_init_io(png_ptr, output); png_set_IHDR(png_ptr, info_ptr, format->image_width, format->image_height, 8, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); rows = malloc(format->image_height * sizeof(*rows)); if(frame_1) { for(i = 0; i < format->image_height; i++) rows[i] = frame_1->planes[0] + i * frame_1->strides[0]; } else { for(i = 0; i < format->image_height; i++) rows[i] = frame->planes[0] + i * frame->strides[0]; } png_set_rows(png_ptr, info_ptr, rows); png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); png_destroy_write_struct(&png_ptr, &info_ptr); fclose(output); free(rows); if(frame_1) gavl_video_frame_destroy(frame_1); }
int main(int argc, char ** argv) { int i, j; bg_cfg_registry_t * cfg_reg; bg_cfg_section_t * cfg_section; bg_plugin_registry_t * plugin_reg; char * tmp_string; gavl_video_frame_t * in_frame; gavl_video_frame_t * tmp_frame = NULL; gavl_video_frame_t * out_frame; gavl_video_frame_t * f; gavl_video_format_t in_format; gavl_video_format_t tmp_format; gavl_video_format_t out_format; int do_convert; int num_formats; gavl_video_converter_t * cnv; gavl_video_options_t * opt; if(argc != 2) { fprintf(stderr, "Usage: %s <image>\n", argv[0]); return -1; } /* Create registries */ cfg_reg = bg_cfg_registry_create(); tmp_string = bg_search_file_read("generic", "config.xml"); bg_cfg_registry_load(cfg_reg, tmp_string); if(tmp_string) free(tmp_string); cfg_section = bg_cfg_registry_find_section(cfg_reg, "plugins"); plugin_reg = bg_plugin_registry_create(cfg_section); /* Load input image */ in_frame = bg_plugin_registry_load_image(plugin_reg, argv[1], &in_format, NULL); if(!in_frame) { fprintf(stderr, "Couldn't load %s\n", argv[1]); return -1; } gavl_video_format_copy(&tmp_format, &in_format); /* Create converter */ cnv = gavl_video_converter_create(); opt = gavl_video_converter_get_options(cnv); gavl_video_options_set_alpha_mode(opt, GAVL_ALPHA_BLEND_COLOR); num_formats = gavl_num_pixelformats(); for(i = 0; i < num_formats; i++) { tmp_format.pixelformat = gavl_get_pixelformat(i); do_convert = gavl_video_converter_init(cnv, &in_format, &tmp_format); if(do_convert) { tmp_frame = gavl_video_frame_create(&tmp_format); gavl_video_convert(cnv, in_frame, tmp_frame); f = tmp_frame; } else f = in_frame; for(j = 0; j < num_channels; j++) { /* Check if channel is available */ if(!gavl_get_color_channel_format(&tmp_format, &out_format, channels[j].ch)) continue; out_frame = gavl_video_frame_create(&out_format); if(!gavl_video_frame_extract_channel(&tmp_format, channels[j].ch, f, out_frame)) { fprintf(stderr, "Huh? Extracting %s from %s failed\n", channels[j].name, gavl_pixelformat_to_string(tmp_format.pixelformat)); return -1; } tmp_string = bg_sprintf("%s_%s.gavi", gavl_pixelformat_to_string(tmp_format.pixelformat), channels[j].name); bg_plugin_registry_save_image(plugin_reg, tmp_string, out_frame, &out_format, NULL); fprintf(stderr, "Wrote %s\n", tmp_string); free(tmp_string); gavl_video_frame_destroy(out_frame); } if(tmp_frame) { gavl_video_frame_destroy(tmp_frame); tmp_frame = NULL; } } gavl_video_frame_destroy(in_frame); gavl_video_converter_destroy(cnv); bg_plugin_registry_destroy(plugin_reg); bg_cfg_registry_destroy(cfg_reg); return 0; }