Beispiel #1
0
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;
}
Beispiel #11
0
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;
}
Beispiel #14
0
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;
}
Beispiel #16
0
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;
}
Beispiel #19
0
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;
}
Beispiel #27
0
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;
}
Beispiel #28
0
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;

}
Beispiel #29
0
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;
}