static int probe_matches(const ProbeInfo *ref, const ProbeInfo *cand, int i) { if (ref->width != cand->width || ref->height != cand->height || ref->frc != cand->frc || ref->asr != cand->asr || ref->codec != cand->codec) { tc_log_error(__FILE__, "video parameters mismatch"); dump_probeinfo(ref, -1, "old"); dump_probeinfo(cand, -1, "new"); return 0; } if (i > ref->num_tracks || i > cand->num_tracks) { tc_log_error(__FILE__, "track parameters mismatch (i=%i|ref=%i|cand=%i)", i, ref->num_tracks, cand->num_tracks); return 0; } if (ref->track[i].samplerate != cand->track[i].samplerate || ref->track[i].chan != cand->track[i].chan ) { // || ref->track[i].bits != cand->track[i].bits ) { // || ref->track[i].format != cand->track[i].format ) { XXX XXX XXX tc_log_error(__FILE__, "audio parameters mismatch"); dump_probeinfo(ref, i, "old"); dump_probeinfo(cand, i, "new"); return 0; } return 1; }
static int raw_stop(TCModuleInstance *self) { RawPrivateData *pd = NULL; int verr, aerr; TC_MODULE_SELF_CHECK(self, "stop"); pd = self->userdata; if (pd->fd_vid != -1) { verr = close(pd->fd_vid); if (verr) { tc_log_error(MOD_NAME, "closing video file: %s", strerror(errno)); return TC_ERROR; } pd->fd_vid = -1; } if (pd->fd_aud != -1) { aerr = close(pd->fd_aud); if (aerr) { tc_log_error(MOD_NAME, "closing audio file: %s", strerror(errno)); return TC_ERROR; } pd->fd_aud = -1; } return TC_OK; }
static int sdlview_init(TCModuleInstance *self, uint32_t features) { int err = 0; SDLPrivateData *pd = NULL; TC_MODULE_SELF_CHECK(self, "init"); TC_MODULE_INIT_CHECK(self, MOD_FEATURES, features); err = SDL_Init(SDL_INIT_VIDEO); if (err) { tc_log_error(MOD_NAME, "SDL initialization failed: %s", SDL_GetError()); return TC_ERROR; } pd = tc_malloc(sizeof(SDLPrivateData)); if (pd == NULL) { tc_log_error(MOD_NAME, "init: out of memory!"); return TC_ERROR; } pd->surface = NULL; pd->overlay = NULL; pd->w = 0; pd->h = 0; self->userdata = pd; if (verbose) { tc_log_info(MOD_NAME, "%s %s", MOD_VERSION, MOD_CAP); } return TC_OK; }
static int tc_x11_stop(TCModuleInstance *self) { TCX11PrivateData *priv = NULL; int ret = 0; TC_MODULE_SELF_CHECK(self, "stop"); priv = self->userdata; ret = tc_x11source_close(&priv->src); if (ret != 0) { tc_log_error(MOD_NAME, "stop: failed to close X11 connection"); return TC_ERROR; } ret = tc_timer_fini(&priv->timer); if (ret != 0) { tc_log_error(MOD_NAME, "stop: failed to stop timer"); return TC_ERROR; } if (verbose >= TC_DEBUG) { tc_log_info(MOD_NAME, "expired frames count: %lu", (unsigned long)priv->expired); } return TC_OK; }
static int yw_stop(TCModuleInstance *self) { YWPrivateData *pd = NULL; int verr, aerr; TC_MODULE_SELF_CHECK(self, "stop"); pd = self->userdata; if (pd->fd_vid != -1) { verr = close(pd->fd_vid); if (verr) { tc_log_error(MOD_NAME, "closing video file: %s", strerror(errno)); return TC_ERROR; } y4m_fini_frame_info(&pd->frameinfo); y4m_fini_stream_info(&(pd->streaminfo)); pd->fd_vid = -1; } if (pd->wav != NULL) { aerr = wav_close(pd->wav); if (aerr != 0) { tc_log_error(MOD_NAME, "closing audio file: %s", wav_strerror(wav_last_error(pd->wav))); return TC_ERROR; } pd->wav = NULL; } return TC_OK; }
void probe_ffmpeg(info_t *ipipe) { /* to be completed */ AVFormatContext *lavf_dmx_context = NULL; int ret = 0; close(ipipe->fd_in); TC_INIT_LIBAVCODEC; ret = av_open_input_file(&lavf_dmx_context, ipipe->name, NULL, 0, NULL); if (ret != 0) { tc_log_error(__FILE__, "unable to open '%s'" " (libavformat failure)", ipipe->name); ipipe->error = 1; return; } ret = av_find_stream_info(lavf_dmx_context); if (ret < 0) { tc_log_error(__FILE__, "unable to fetch informations from '%s'" " (libavformat failure)", ipipe->name); ipipe->error = 1; return; } translate_info(lavf_dmx_context, ipipe->probe_info); av_close_input_file(lavf_dmx_context); return; }
static int tc_v4l2_video_check_capabilities(V4L2Source *vs) { struct v4l2_capability caps; int err = 0; err = v4l2_ioctl(vs->video_fd, VIDIOC_QUERYCAP, &caps); if (err < 0) { tc_log_error(MOD_NAME, "driver does not support querying capabilities"); return TC_ERROR; } if (!(caps.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { tc_log_error(MOD_NAME, "driver does not support video capture"); return TC_ERROR; } if (!(caps.capabilities & V4L2_CAP_STREAMING)) { tc_log_error(MOD_NAME, "driver does not support streaming (mmap) video capture"); return TC_ERROR; } if (verbose_flag > TC_INFO) { tc_log_info(MOD_NAME, "v4l2 video grabbing, driver = %s, device = %s", caps.driver, caps.card); } return TC_OK; }
static int write_tmpfile(char* header, char* content, int content_size, int slot_id){ FILE* tmp = NULL; int i = 0; char* filename = NULL; filename = tc_malloc(sizeof(char)*(strlen(TMP_FILE) + TMP_STRING_SIZE)); if (!filename){ tc_log_error(MOD_NAME, "Out of memory !!!"); return -1; } if (verbose & TC_DEBUG) tc_log_info(MOD_NAME, "Temporary filename correctly allocated."); tc_snprintf(filename, strlen(TMP_FILE) + TMP_STRING_SIZE, "%s-%d.tmp", TMP_FILE, slot_id); tmp = fopen(filename, "w"); if (!tmp){ tc_log_error(MOD_NAME, "Cannot write temporary file !"); return -1; } for(i=0; i<strlen(header); i++) fputc(header[i], tmp); for(i=0; i< content_size; i++) fputc(content[i], tmp); fclose(tmp); free(filename); return 0; }
static int tc_x11_configure(TCModuleInstance *self, const char *options, vob_t *vob) { TCX11PrivateData *priv = NULL; int ret = 0, skew_lim = SKEW_LIM_DEFAULT; TC_MODULE_SELF_CHECK(self, "configure"); priv = self->userdata; if (options != NULL) { optstr_get(options, "skew_limit", "%i", &skew_lim); if (skew_lim < SKEW_LIM_MIN || skew_lim > SKEW_LIM_MAX) { tc_log_warn(MOD_NAME, "skew limit value out of range," " reset to defaults [%i]", SKEW_LIM_DEFAULT); } } priv->skew = 0; priv->reftime = 0; priv->expired = 0; priv->frame_delay = (uint64_t)(1000000.0 / vob->fps); /* microseconds */ priv->skew_limit = priv->frame_delay / frame_delay_divs[skew_lim]; if (verbose >= TC_DEBUG) { tc_log_info(MOD_NAME, "frame delay: %lu ms", (unsigned long)priv->frame_delay); tc_log_info(MOD_NAME, "skew limit: %li ms", (long)priv->skew_limit); } ret = tc_timer_init_soft(&priv->timer, 0); if (ret != 0) { tc_log_error(MOD_NAME, "configure: can't initialize timer"); return TC_ERROR; } /* nothing to do here, yet */ ret = tc_x11source_is_display_name(vob->video_in_file); if (ret == TC_FALSE) { tc_log_error(MOD_NAME, "configure: given source doesn't look like" " a DISPLAY specifier"); return TC_ERROR; } ret = tc_x11source_open(&priv->src, vob->video_in_file, TC_X11_MODE_BEST, vob->im_v_codec); if (ret != 0) { tc_log_error(MOD_NAME, "configure: failed to open X11 connection" " to '%s'", vob->video_in_file); return TC_ERROR; } return TC_OK; }
static int tc_x11source_init_shm(TCX11Source *handle) { Status ret; ret = XMatchVisualInfo(handle->dpy, handle->screen, handle->depth, DirectColor, &handle->vis_info); if (!ret) { tc_log_error(__FILE__, "Can't match visual information"); goto xshm_failed; } handle->image = XShmCreateImage(handle->dpy, handle->vis_info.visual, handle->depth, ZPixmap, NULL, &handle->shm_info, handle->width, handle->height); if (handle->image == NULL) { tc_log_error(__FILE__, "XShmCreateImage failed."); goto xshm_failed_image; } handle->shm_info.shmid = shmget(IPC_PRIVATE, handle->image->bytes_per_line * handle->image->height, IPC_CREAT | 0777); if (handle->shm_info.shmid < 0) { tc_log_error(__FILE__, "failed to create shared memory segment"); goto xshm_failed_image; } handle->shm_info.shmaddr = shmat(handle->shm_info.shmid, NULL, 0); if (handle->shm_info.shmaddr == (void*)-1) { tc_log_error(__FILE__, "failed to attach shared memory segment"); goto xshm_failed_image; } shmctl(handle->shm_info.shmid, IPC_RMID, 0); /* XXX */ handle->image->data = handle->shm_info.shmaddr; handle->shm_info.readOnly = False; ret = XShmAttach(handle->dpy, &handle->shm_info); if (!ret) { tc_log_error(__FILE__, "failed to attach SHM to Xserver"); goto xshm_failed_image; } XSync(handle->dpy, False); handle->mode = TC_X11_MODE_SHM; handle->acquire_image = tc_x11source_acquire_image_shm; handle->fini = tc_x11source_fini_shm; return 0; xshm_failed_image: XDestroyImage(handle->image); handle->image = NULL; xshm_failed: return -1; }
static int tc_im_configure(TCModuleInstance *self, const char *options, vob_t *vob, TCModuleExtraData *xdata[]) { TCCodecID id = TC_CODEC_ERROR; TCIMPrivateData *pd = NULL; int ret = 0; TC_MODULE_SELF_CHECK(self, "configure"); pd = self->userdata; pd->quality = DEFAULT_QUALITY; pd->width = vob->ex_v_width; pd->height = vob->ex_v_height; pd->img_fmt[0] = '\0'; ret = optstr_get(options, "format", "%15s", pd->img_fmt); if (ret != 1) { /* missing option, let's use the default */ strlcpy(pd->img_fmt, DEFAULT_FORMAT, sizeof(pd->img_fmt)); } else { /* the user gave us something */ id = tc_codec_from_string(pd->img_fmt); if (id == TC_CODEC_ERROR) { tc_log_error(MOD_NAME, "unknown format: `%s'", pd->img_fmt); return TC_ERROR; } if (!is_supported(id)) { tc_log_error(MOD_NAME, "unsupported format: `%s'", pd->img_fmt); return TC_ERROR; } } ret = optstr_get(options, "quality", "%lu", &pd->quality); if (ret != 1) { pd->quality = DEFAULT_QUALITY; } if (verbose >= TC_INFO) { tc_log_info(MOD_NAME, "encoding %s with quality %lu", pd->img_fmt, pd->quality); } ret = tc_magick_init(&pd->magick, pd->quality); if (ret != TC_OK) { tc_log_error(MOD_NAME, "cannot create Magick context"); return ret; } return TC_OK; }
static int raw_configure(TCModuleInstance *self, const char *options, vob_t *vob) { char vid_name[PATH_MAX]; char aud_name[PATH_MAX]; RawPrivateData *pd = NULL; TC_MODULE_SELF_CHECK(self, "configure"); pd = self->userdata; // XXX if (vob->audio_out_file == NULL || !strcmp(vob->audio_out_file, "/dev/null")) { /* use affine names */ tc_snprintf(vid_name, PATH_MAX, "%s.%s", vob->video_out_file, RAW_VID_EXT); tc_snprintf(aud_name, PATH_MAX, "%s.%s", vob->video_out_file, RAW_AUD_EXT); } else { /* copy names verbatim */ strlcpy(vid_name, vob->video_out_file, PATH_MAX); strlcpy(aud_name, vob->audio_out_file, PATH_MAX); } /* avoid fd loss in case of failed configuration */ if (pd->fd_vid == -1) { pd->fd_vid = open(vid_name, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if (pd->fd_vid == -1) { tc_log_error(MOD_NAME, "failed to open video stream file"); return TC_ERROR; } } /* avoid fd loss in case of failed configuration */ if (pd->fd_aud == -1) { pd->fd_aud = open(aud_name, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if (pd->fd_aud == -1) { tc_log_error(MOD_NAME, "failed to open audio stream file"); return TC_ERROR; } } if (vob->verbose >= TC_DEBUG) { tc_log_info(MOD_NAME, "video output: %s (%s)", vid_name, (pd->fd_vid == -1) ?"FAILED" :"OK"); tc_log_info(MOD_NAME, "audio output: %s (%s)", aud_name, (pd->fd_aud == -1) ?"FAILED" :"OK"); } return TC_OK; }
static int tc_v4l2_video_setup_image_format(V4L2Source *vs, int width, int height) { int err = 0; vs->width = width; vs->height = height; vs->v4l_convert = v4lconvert_create(vs->video_fd); if (!vs->v4l_convert) { return TC_ERROR; } memset(&(vs->v4l_dst_fmt), 0, sizeof(vs->v4l_dst_fmt)); vs->v4l_dst_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; vs->v4l_dst_fmt.fmt.pix.width = width; vs->v4l_dst_fmt.fmt.pix.height = height; vs->v4l_dst_fmt.fmt.pix.pixelformat = vs->v4l_dst_csp; err = v4lconvert_try_format(vs->v4l_convert, &(vs->v4l_dst_fmt), &(vs->v4l_src_fmt)); if (err) { tc_log_error(MOD_NAME, "unable to match formats: %s", v4lconvert_get_error_message(vs->v4l_convert)); return TC_ERROR; } err = v4l2_ioctl(vs->video_fd, VIDIOC_S_FMT, &(vs->v4l_src_fmt)); if (err < 0) { tc_log_error(MOD_NAME, "error while setting the cam image format"); return TC_ERROR; } if (!v4lconvert_needs_conversion(vs->v4l_convert, &(vs->v4l_src_fmt), &(vs->v4l_dst_fmt))) { tc_log_info(MOD_NAME, "fetch frames directly"); vs->fetch_data = tc_v4l2_fetch_data_memcpy; /* Into the near future we should aim for zero-copy. -- FR */ } else { char src_fcc[5] = { '\0' }; char dst_fcc[5] = { '\0' }; pixfmt_to_fourcc(vs->v4l_src_fmt.fmt.pix.pixelformat, src_fcc); pixfmt_to_fourcc(vs->v4l_dst_fmt.fmt.pix.pixelformat, dst_fcc); tc_log_info(MOD_NAME, "fetch frames using libv4lconvert " "[%s] -> [%s]", src_fcc, dst_fcc); vs->fetch_data = tc_v4l2_fetch_data_v4lconv; } return TC_OK; }
int tc_socket_init(const char *socket_path_) { struct sockaddr_un server_addr; client_sock = -1; server_sock = -1; tc_mutex_init(&tc_socket_msg_lock); if (tc_snprintf(socket_path, sizeof(socket_path), "%s", socket_path_) < 0){ tc_log_error(__FILE__, "Socket pathname too long (1)"); *socket_path = 0; return 0; } errno = 0; if (unlink(socket_path) != 0 && errno != ENOENT) { tc_log_error(__FILE__, "Unable to remove \"%s\": %s", socket_path, strerror(errno)); return 0; } server_addr.sun_family = AF_UNIX; if (tc_snprintf(server_addr.sun_path, sizeof(server_addr.sun_path), "%s", socket_path) < 0 ) { tc_log_error(__FILE__, "Socket pathname too long"); return 0; } server_sock = socket(AF_UNIX, SOCK_STREAM, 0); if (server_sock < 0) { tc_log_perror(__FILE__, "Unable to create server socket"); return 0; } if (bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) ) { tc_log_perror(__FILE__, "Unable to bind server socket"); close(server_sock); server_sock = -1; unlink(socket_path); // just in case return 0; } if (listen(server_sock, 5) < 0) { tc_log_perror(__FILE__, "Unable to activate server socket"); close(server_sock); unlink(socket_path); return 0; } return 1; }
static int nuv_configure(TCModuleInstance *self, const char *options, vob_t *vob) { PrivateData *pd; struct rtfileheader hdr; const char *filename = vob->video_in_file; TC_MODULE_SELF_CHECK(self, "configure"); pd = self->userdata; // FIXME: is this a good place for open()? And how do we know which // file (video or audio) to open? pd->fd = open(filename, O_RDONLY); if (pd->fd < 0) { tc_log_error(MOD_NAME, "Unable to open %s: %s", filename, strerror(errno)); return TC_OK; } if (read(pd->fd, &hdr, sizeof(hdr)) != sizeof(hdr)) { tc_log_error(MOD_NAME, "Unable to read file header from %s", filename); close(pd->fd); pd->fd = -1; return TC_OK; } if (strcmp(hdr.finfo, "NuppelVideo") != 0) { tc_log_error(MOD_NAME, "Bad file header in %s", filename); close(pd->fd); pd->fd = -1; return TC_OK; } if (strcmp(hdr.version, "0.05") != 0) { tc_log_error(MOD_NAME, "Bad format version in %s", filename); close(pd->fd); pd->fd = -1; return TC_OK; } pd->width = hdr.width; pd->height = hdr.height; pd->fps = hdr.fps; pd->tsoffset = 0; pd->framenum = 0; pd->have_vframe = 0; pd->audiorate = NUV_ARATE; pd->audiofrac = 0; memset(pd->cdata, 0, sizeof(pd->cdata)); pd->saved_vframelen = 0; pd->saved_vcomptype = 'N'; // black frame return TC_OK; }
int f_manage_input_xml(const char *p_name,int s_type,audiovideo_t *p_audiovideo) { static xmlDocPtr p_doc; xmlNodePtr p_node; xmlNsPtr ns; if (s_type) //read the file from p_name { p_doc = xmlParseFile(p_name); p_node = xmlDocGetRootElement(p_doc); if (p_node == NULL) { xmlFreeDoc(p_doc); tc_log_error(__FILE__,"Invalid file format"); return(-1); } ns = xmlSearchNsByHref(p_doc, p_node, (const xmlChar *) "http://www.w3.org/2001/SMIL20/Language"); if (ns == NULL) { xmlFreeDoc(p_doc); tc_log_error(__FILE__,"Invalid Namespace"); return(-1); } ns = xmlSearchNs(p_doc, p_node, (const xmlChar *) "smil2"); if (ns == NULL) { xmlFreeDoc(p_doc); tc_log_error(__FILE__,"Invalid Namespace"); return(-1); } if (xmlStrcmp(p_node->name, (const xmlChar *) "smil")) { xmlFreeDoc(p_doc); tc_log_error(__FILE__,"Invalid Namespace"); return(-1); } f_delete_unused_node(p_node); memset(p_audiovideo,'\0',sizeof(audiovideo_t)); if(f_parse_tree(p_node,p_audiovideo)) return(1); if (f_complete_tree(p_audiovideo)) return(1); } else { f_free_tree(p_audiovideo); xmlFreeDoc(p_doc); } return(0); }
static int tc_vorbis_configure(TCModuleInstance *self, const char *options, vob_t *vob) { VorbisPrivateData *pd = NULL; int samplerate = (vob->mp3frequency) ? vob->mp3frequency : vob->a_rate; float quality = TC_CLAMP(vob->mp3quality, 0.0, 9.9) / 10.0; int ret, br = vob->mp3bitrate * 1000; TC_MODULE_SELF_CHECK(self, "configure"); pd = self->userdata; if (vob->dm_bits != 16) { tc_log_error(MOD_NAME, "Only 16-bit samples supported"); return TC_ERROR; } pd->flush_flag = vob->encoder_flush; pd->end_of_stream = TC_FALSE; pd->channels = vob->dm_chan; pd->bits = vob->dm_bits; pd->packets = 0; pd->frames = 0; vorbis_info_init(&pd->vi); if (quality > ZERO_QUALITY) { ret = vorbis_encode_init_vbr(&pd->vi, pd->channels, samplerate, quality); } else { ret = vorbis_encode_init(&pd->vi, pd->channels, samplerate, -1, br, -1); } if (ret) { tc_log_error(MOD_NAME, "the Vorbis encoder could not set up a mode" " according to the requested settings."); ret = TC_ERROR; } else { vorbis_comment_init(&pd->vc); vorbis_comment_add_tag(&pd->vc, "ENCODER", PACKAGE " " VERSION); vorbis_analysis_init(&pd->vd, &pd->vi); vorbis_block_init(&pd->vd, &pd->vb); ret = tc_ogg_new_extradata(pd); if (ret == TC_OK) { /* publish it */ vob->ex_a_xdata = &(pd->xdata); } } return ret; }
METHOD int pvn_configure(TCModuleInstance *self, const char *options, vob_t *vob) { PrivateData *pd = NULL; char buf[TC_BUF_MAX]; int len; TC_MODULE_SELF_CHECK(self, "configure"); pd->width = vob->ex_v_width; pd->height = vob->ex_v_height; /* FIXME: stdout should be handled in a more standard fashion */ if (strcmp(vob->video_out_file, "-") == 0) { // allow /dev/stdout too? pd->fd = 1; } else { pd->fd = open(vob->video_out_file, O_WRONLY | O_CREAT | O_TRUNC, 0666); if (pd->fd < 0) { tc_log_error(MOD_NAME, "Unable to open %s: %s", vob->video_out_file, strerror(errno)); goto fail; } } len = tc_snprintf(buf, sizeof(buf), "PV%da\r\n%d %d\r\n", vob->decolor ? 5 : 6, pd->width, pd->height); if (len < 0) goto fail; if (tc_pwrite(pd->fd, buf, len) != len) { tc_log_error(MOD_NAME, "Unable to write header to %s: %s", vob->video_out_file, strerror(errno)); goto fail; } pd->framecount_pos = lseek(pd->fd, 0, SEEK_CUR); // failure okay len = tc_snprintf(buf, sizeof(buf), "%10d\r\n8\r\n%lf\r\n", 0, (double)vob->ex_fps); if (len < 0) goto fail; if (tc_pwrite(pd->fd, buf, len) != len) { tc_log_error(MOD_NAME, "Unable to write header to %s: %s", vob->video_out_file, strerror(errno)); goto fail; } return TC_OK; fail: pvn_stop(self); return TC_ERROR; }
int load_plugin(const char *path, int id, int verbose) { const char *error = NULL; char module[TC_BUF_MAX]; int n; if (filter[id].name == NULL) { tc_log_error(__FILE__, "bad filter#%i name (%s)", id, filter[id].name); return -1; } filter[id].options = NULL; /* replace "=" by "/0" in filter name */ for (n = 0; n < strlen(filter[id].name); n++) { if (filter[id].name[n] == '=') { filter[id].name[n] = '\0'; filter[id].options = filter[id].name + n + 1; break; } } tc_snprintf(module, sizeof(module), "%s/filter_%s.so", path, filter[id].name); /* try transcode's module directory */ filter[id].handle = dlopen(module, RTLD_LAZY); if (filter[id].handle != NULL) { filter[id].entry = dlsym(filter[id].handle, "tc_filter"); } else { if (verbose) { tc_log_error(__FILE__, "loading filter module '%s' failed (reason: %s)", module, dlerror()); } return -1; } error = dlerror(); if (error != NULL) { if (verbose) { tc_log_error(__FILE__, "error while loading '%s': %s\n", module, error); } return -1; } return 0; }
/* * configure_colorspace: find correct source colorspace, and setup * module private data accordingly * * Parameters: * pd: module private data to setup * fmt: internal transcode colorspace format * verbose: if nonzero, tc_log out operation. * Return Value: * TC_ERROR on failure (unknown internal format), TC_OK on success */ static int configure_colorspace(SDLPrivateData *pd, int fmt, int verbose) { const char *fmt_name = "unknown"; switch (fmt) { case TC_CODEC_YUV420P: pd->src_fmt = IMG_YUV420P; fmt_name = "YUV420"; break; case TC_CODEC_YUV422P: pd->src_fmt = IMG_YUV422P; fmt_name = "YUV422"; break; case TC_CODEC_RGB24: pd->src_fmt = IMG_RGB24; fmt_name = "RGB24"; break; default: tc_log_error(MOD_NAME, "unknown colorspace"); return TC_ERROR; } if (verbose) { tc_log_info(MOD_NAME, "colorspace conversion: %s -> YV12", fmt_name); } return TC_OK; }
int tc_x11source_close(TCX11Source *handle) { if (handle != NULL) { if (handle->dpy != NULL) { int ret = handle->fini(handle); if (ret != 0) { return ret; } tcv_free(handle->tcvhandle); XFreePixmap(handle->dpy, handle->pix); /* XXX */ XFreeGC(handle->dpy, handle->gc); /* XXX */ ret = XCloseDisplay(handle->dpy); if (ret == 0) { handle->dpy = NULL; } else { tc_log_error(__FILE__, "XCloseDisplay() failed: %i", ret); return -1; } } } return 0; }
static int tc_v4l2_video_init(V4L2Source *vs, int layout, const char *device, int width, int height, int fps, const char *options) { int ret = tc_v4l2_parse_options(vs, layout, options); RETURN_IF_FAILED(ret); vs->video_fd = v4l2_open(device, O_RDWR, 0); if (vs->video_fd < 0) { tc_log_error(MOD_NAME, "cannot open video device %s", device); return TC_ERROR; } ret = tc_v4l2_video_check_capabilities(vs); RETURN_IF_FAILED(ret); ret = tc_v4l2_video_setup_image_format(vs, width, height); RETURN_IF_FAILED(ret); ret = tc_v4l2_video_setup_stream_parameters(vs, fps); RETURN_IF_FAILED(ret); ret = tc_v4l2_video_get_capture_buffer_count(vs); RETURN_IF_FAILED(ret); ret = tc_v4l2_video_setup_capture_buffers(vs); RETURN_IF_FAILED(ret); return tc_v4l2_capture_start(vs); }
static int tc_v4l2_video_get_capture_buffer_count(V4L2Source *vs) { struct v4l2_requestbuffers reqbuf; int err = 0; reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; reqbuf.memory = V4L2_MEMORY_MMAP; reqbuf.count = TC_V4L2_BUFFERS_NUM; err = v4l2_ioctl(vs->video_fd, VIDIOC_REQBUFS, &reqbuf); if (err < 0) { tc_log_perror(MOD_NAME, "VIDIOC_REQBUFS"); return TC_ERROR; } vs->buffers_count = TC_MIN(reqbuf.count, TC_V4L2_BUFFERS_NUM); if (vs->buffers_count < 2) { tc_log_error(MOD_NAME, "not enough buffers for capture"); return TC_ERROR; } if (verbose_flag > TC_INFO) { tc_log_info(MOD_NAME, "%i buffers available (maximum supported: %i)", vs->buffers_count, TC_V4L2_BUFFERS_NUM); } return TC_OK; }
static int modrequest_scan(const char *modpath, const char *modstr, glob_t *globbuf) { char path_model[PATH_MAX]; char buf[TC_BUF_MIN]; const char *pc = NULL; int err = 0; pc = strchr(modstr, ':'); if (pc == NULL) { return 1; } if ((pc - modstr + 1) > sizeof(buf)) { return 2; /* XXX watch out here */ } strlcpy(buf, modstr, pc - modstr + 1); tc_snprintf(path_model, sizeof(path_model), "%s/%s_*.so", modpath, buf); err = glob(path_model, GLOB_ERR, NULL, globbuf); if (err) { tc_log_error(EXE, "error while scanning for modules: %s", (err == GLOB_NOSPACE) ?"can't get enough memory" : (err == GLOB_ABORTED) ?"read error" : /* GLOB_NOMATCH */ "no modules found"); return -1; } return 0; }
/* XXX */ static int check_module_pair(const ModRequest *head, const ModRequest *tail, const ModRequest *ref, int verbose) { int ret = 0; if (head->module == NULL || tail->module == NULL) { tc_log_error(EXE, "check_module_pair: missing module handle"); return -1; } ret = tc_module_info_match(TC_CODEC_ANY, tc_module_get_info(head->module), tc_module_get_info(tail->module)); if (verbose >= TC_DEBUG) { tc_log_info(EXE, "%s:%s | %s:%s [%s]", head->type, head->name, tail->type, tail->name, (ret == 1) ?"OK" :"MISMATCH"); } else if (verbose >= TC_INFO) { if (ret == 1) { printf("%s\n", ref->name); } } return ret; }
static int tc_v4l2_video_get_frame(V4L2Source *vs, uint8_t *data, size_t size) { int ret; int buffers_filled = tc_v4l2_video_count_buffers(vs); if (buffers_filled == -1) { tc_log_warn(MOD_NAME, "unable to get the capture buffers count," " assuming OK"); buffers_filled = 0; } if (buffers_filled > (vs->buffers_count * 3 / 4)) { tc_log_error(MOD_NAME, "running out of capture buffers (%d left from %d total), " "stopping capture", vs->buffers_count - buffers_filled, vs->buffers_count); ret = tc_v4l2_capture_stop(vs); } else { ret = tc_v4l2_video_grab_frame(vs, data, size); vs->video_sequence++; } return ret; }
static int deshake_init(TCModuleInstance *self, uint32_t features) { DeshakeData* sd = NULL; TC_MODULE_SELF_CHECK(self, "init"); TC_MODULE_INIT_CHECK(self, MOD_FEATURES, features); sd = tc_zalloc(sizeof(DeshakeData)); // allocation with zero values if (!sd) { if (verbose > TC_INFO) tc_log_error(MOD_NAME, "init: out of memory!"); return TC_ERROR; } sd->vob = tc_get_vob(); if (!sd->vob) return TC_ERROR; /**** Initialise private data structure */ self->userdata = sd; if (verbose & TC_INFO){ tc_log_info(MOD_NAME, "%s %s", MOD_VERSION, MOD_CAP); } return TC_OK; }
void probe_bktr(info_t * ipipe) { struct bktr_capture_area caparea; unsigned short status, fps; close(ipipe->fd_in); ipipe->fd_in = open(ipipe->name, O_RDONLY, 0); if (ipipe->fd_in < 0) { tc_log_error(__FILE__, "cannot open device: %s", strerror(errno)); goto error; } /* try a bktr ioctl */ if (ipipe->verbose & TC_DEBUG) tc_log_msg(__FILE__, "checking if bktr ioctls are supported..."); if (ioctl(ipipe->fd_in, METEORSTATUS, &status) < 0) { if (ipipe->verbose & TC_DEBUG) tc_log_msg(__FILE__, "... no"); goto error; } else { if (ipipe->verbose & TC_DEBUG) tc_log_msg(__FILE__, "... yes"); } if (ioctl(ipipe->fd_in, BT848_GCAPAREA, &caparea) < 0) { tc_log_perror(__FILE__, "BT848_GCAPAREA"); goto error; } ipipe->probe_info->width = caparea.x_size; ipipe->probe_info->height = caparea.y_size; if (ioctl(ipipe->fd_in, METEORGFPS, &fps) < 0) { tc_log_perror(__FILE__, "METEORGFPS"); goto error; } ipipe->probe_info->fps = fps; switch(fps) { case 30: ipipe->probe_info->frc = 4; break; case 25: ipipe->probe_info->frc = 3; break; default: break; } ipipe->probe_info->magic = TC_MAGIC_BKTR_VIDEO; return; error: ipipe->error = 1; ipipe->probe_info->codec = TC_CODEC_UNKNOWN; ipipe->probe_info->magic = TC_MAGIC_UNKNOWN; return; }
void probe_bktr(info_t * ipipe) { tc_log_error(__FILE__, "No support for bktr compiled in"); ipipe->probe_info->codec = TC_CODEC_UNKNOWN; ipipe->probe_info->magic = TC_MAGIC_UNKNOWN; }
static int tc_frame_audio_add_ogg_packet(VorbisPrivateData *pd, TCFrameAudio *f, ogg_packet *op) { int16_t *pkt_num = (int16_t*)f->audio_buf; double ts = vorbis_granule_time(&(pd->vd), op->granulepos); int needed = sizeof(*op) + op->bytes; int avail = f->audio_size - f->audio_len; TC_FRAME_SET_TIMESTAMP_DOUBLE(f, ts); if (avail < needed) { tc_log_error(__FILE__, "(%s) no buffer in frame: (avail=%i|needed=%i)", __func__, avail, needed); return TC_ERROR; } ac_memcpy(f->audio_buf + f->audio_len, op, sizeof(*op)); f->audio_len += sizeof(*op); ac_memcpy(f->audio_buf + f->audio_len, op->packet, op->bytes); f->audio_len += op->bytes; *pkt_num += 1; if (op->e_o_s) { f->attributes |= TC_FRAME_IS_END_OF_STREAM; // useless? } return TC_OK; }