Esempio n. 1
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;

}
Esempio n. 2
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;
}
Esempio n. 3
0
int bktr_stop()
{
    int c;

    /* shutdown signals first */

    c = METEOR_SIG_MODE_MASK;
    ioctl(bktr_vfd, METEORSSIGNAL, &c);

    alarm(0);

    c = METEOR_CAP_STOP_CONT;
    ioctl(bktr_vfd, METEORCAPTUR, &c);

    c = AUDIO_MUTE;
    if (ioctl(bktr_tfd, BT848_SAUDIO, &c) < 0) {
        tc_log_perror(MOD_NAME, "BT848_SAUDIO AUDIO_MUTE");
        return(1);
    }

    if (bktr_vfd > 0) {
        close(bktr_vfd);
        bktr_vfd = -1;
    }

    if (bktr_tfd > 0) {
        close(bktr_tfd);
        bktr_tfd = -1;
    }

    munmap(bktr_buffer, bktr_buffer_size);

    return(0);
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
static int tc_v4l2_video_setup_capture_buffers(V4L2Source *vs)
{
    struct v4l2_buffer buffer;
    int ix, err = 0;

    /* map the buffers */
    for (ix = 0; ix < vs->buffers_count; ix++) {
        buffer.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buffer.memory = V4L2_MEMORY_MMAP;
        buffer.index  = ix;

        err = v4l2_ioctl(vs->video_fd, VIDIOC_QUERYBUF, &buffer);
        if (err < 0) {
            tc_log_perror(MOD_NAME, "VIDIOC_QUERYBUF");
            return TC_ERROR;
        }

        vs->buffers[ix].length = buffer.length;
        vs->buffers[ix].start  = v4l2_mmap(0, buffer.length,
                                           PROT_READ|PROT_WRITE, MAP_SHARED,
                                           vs->video_fd, buffer.m.offset);

        if (vs->buffers[ix].start == MAP_FAILED) {
            tc_log_perror(MOD_NAME, "mmap");
            return TC_ERROR;
        }
    }

    /* then enqueue them all */
    for (ix = 0; ix < vs->buffers_count; ix++) {
        buffer.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buffer.memory = V4L2_MEMORY_MMAP;
        buffer.index  = ix;

        err = v4l2_ioctl(vs->video_fd, VIDIOC_QBUF, &buffer);
        if (err < 0) {
            tc_log_perror(MOD_NAME, "VIDIOC_QBUF");
            return TC_ERROR;
        }
    }

    return TC_OK;
}
Esempio n. 6
0
static int tc_v4l2_capture_stop(V4L2Source *vs)
{
    int err = 0, arg = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    err = v4l2_ioctl(vs->video_fd, VIDIOC_STREAMOFF, &arg);
    if (err < 0) {
        /* ugh, needs VIDEO_CAPTURE */
        tc_log_perror(MOD_NAME, "VIDIOC_STREAMOFF");
        return TC_ERROR;
    }

    return TC_OK;
}
static int astat_stop(TCModuleInstance *self)
{
    int ret = TC_OK; /* optimistism... */
    AStatPrivateData *pd = NULL;

    TC_MODULE_SELF_CHECK(self, "stop");

    pd = self->userdata;

    /* stats summary */
    if (pd->min >= pd->silence_limit && pd->max <= pd->silence_limit) {
        tc_log_info(MOD_NAME, "audio track seems only silence");
    } else if (pd->min == 0 || pd->max == 0) {
        tc_log_warn(MOD_NAME, "bad minimum/maximum value,"
                              " unable to find scale value");
        ret = TC_ERROR;
    } else {
        double fmin = -((double) pd->min)/TCA_S16LE_MAX;
        double fmax =  ((double) pd->max)/TCA_S16LE_MAX;
        /* FIXME: constantize in libtcaudio */
        double vol = (fmin < fmax) ? 1./fmax : 1./fmin;

        if (pd->filepath == NULL) {
            tc_log_info(MOD_NAME, "(min=%.3f/max=%.3f), "
                                  "normalize volume with \"-s %.3f\"",
                                  -fmin, fmax, vol);
        } else {
            FILE *fh = fopen(pd->filepath, "w");
            if (fh == NULL) {
                tc_log_perror(MOD_NAME, "unable to open scale value file");
                ret = TC_ERROR;
            } else {
                fprintf(fh, "%.3f\n", vol);
                fclose(fh); // XXX
                if (verbose) {
                    tc_log_info(MOD_NAME, "wrote audio scale value to '%s'", pd->filepath);
                }
            }

            tc_free(pd->filepath);
            pd->filepath = NULL;
        }
    }

    return TC_OK;
}
int execute(char *command)
{
FILE *pptr;

if(debug_flag)
	{
	tc_log_msg(MOD_NAME, "subtitler() execute(): arg command=%s\n", command);
	}

pptr = popen(command, "r");
if(pptr <= 0)
	{
	tc_log_perror(MOD_NAME, "command");

	return 0;
	}

pclose(pptr);

return 1;
} /* end function execute */
Esempio n. 9
0
static int tc_v4l2_video_count_buffers(V4L2Source *vs)
{
    struct v4l2_buffer buffer;
    int ix, ret, buffers_filled = 0;

    for (ix = 0; ix < vs->buffers_count; ix++) {
        buffer.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buffer.memory = V4L2_MEMORY_MMAP;
        buffer.index  = ix;

        ret = v4l2_ioctl(vs->video_fd, VIDIOC_QUERYBUF, &buffer);
        if (ret < 0) {
            tc_log_perror(MOD_NAME, 
                          "error in querying buffers"
                          " (ioctl(VIDIOC_QUERYBUF) failed)");
            return -1;
        }

        if (buffer.flags & V4L2_BUF_FLAG_DONE)
            buffers_filled++;
    }
    return buffers_filled;
}
Esempio n. 10
0
void extract_rgb(info_t *ipipe)
{
    uint8_t *video;
    avi_t *avifile = NULL;
    int key, error = 0;
    long frames, bytes, n;

    switch (ipipe->magic) {
      case TC_MAGIC_AVI:
	if (ipipe->nav_seek_file) {
            avifile = AVI_open_indexfd(ipipe->fd_in, 0, ipipe->nav_seek_file);
        } else {
            avifile = AVI_open_fd(ipipe->fd_in, 1);
        }
        if (NULL == avifile) {
            AVI_print_error("AVI open");
            import_exit(1);
        }

        frames = AVI_video_frames(avifile);
        if (ipipe->frame_limit[1] < frames) {
            frames = ipipe->frame_limit[1];
        }

        if (ipipe->verbose & TC_STATS) {
            tc_log_msg(__FILE__, "%ld video frames", frames);
        }

        video = tc_bufalloc(SIZE_RGB_FRAME);
        if (!video) {
            error = 1;
            break;
        }

        AVI_set_video_position(avifile, ipipe->frame_limit[0]);
        /* FIXME: should this be < rather than <= ? */
        for (n = ipipe->frame_limit[0]; n <= frames; n++) {
            bytes = AVI_read_frame(avifile, video, &key);
            if (bytes < 0) {
                error = 1;
                break;
            }
            if (tc_pwrite(ipipe->fd_out, video, bytes) != bytes) {
                error = 1;
                break;
            }
        }

        tc_buffree(video);
        break;

      case TC_MAGIC_RAW: /* fallthrough */
      default:
        if (ipipe->magic == TC_MAGIC_UNKNOWN) {
            tc_log_warn(__FILE__, "no file type specified, assuming %s",
			            filetype(TC_MAGIC_RAW));

            error = tc_preadwrite(ipipe->fd_in, ipipe->fd_out);
            break;
        }
    }

    if (error) {
        tc_log_perror(__FILE__, "error while writing data");
      	import_exit(error);
    }
}
Esempio n. 11
0
int bktr_init(int video_codec, const char *video_device,
              int width, int height,
              int fps, char *options)
{
    struct meteor_geomet geo;
    struct meteor_pixfmt pxf;
    struct sigaction act;
    int h_max, w_max;
    int rgb_idx = -1;
    int yuv422_idx = -1;
    int yuv_idx = -1;
    int i;

    if (options != NULL)
        if (bktr_parse_options(options))
            return(1);

    switch (bktr_format) {
    case METEOR_FMT_NTSC:
        h_max = 480;
        w_max = 640;
        break;
    case METEOR_FMT_PAL:
        h_max = 576;
        w_max = 768;
        break;
    default:
        h_max = 576;
        w_max = 768;
        break;
    }

    if (width > w_max) {
        tc_log_warn(MOD_NAME,
                    "import width '%d' too large! "
                    "PAL max width = 768, NTSC max width = 640",
                    width);
        return(1);
    }

    if (height > h_max) {
        tc_log_warn(MOD_NAME,
                    "import height %d too large! "
                    "PAL max height = 576, NTSC max height = 480",
                    height);
        return(1);
    }

    bktr_tcvhandle = tcv_init();
    if (!bktr_tcvhandle) {
        tcv_log_warn(MOD_NAME, "tcv_init() failed");
        return(1);
    }

    /* set the audio via the tuner.  opening the device unmutes it. */
    /* closing the device mutes it again.  so we hold it open */

    bktr_tfd = open(bktr_tuner, O_RDONLY);
    if (bktr_tfd < 0) {
        tc_log_perror(MOD_NAME, "open tuner");
        return(1);
    }

    if (ioctl(bktr_tfd, BT848_SAUDIO, &bktr_asource) < 0) {
        tc_log_perror(MOD_NAME, "BT848_SAUDIO asource");
        return(1);
    }

    if (bktr_mute) {
        i = AUDIO_MUTE;
        if (ioctl(bktr_tfd, BT848_SAUDIO, &i) < 0) {
            tc_log_perror(MOD_NAME, "BT848_SAUDIO AUDIO_MUTE");
            return(1);
        }
    } else {
        i = AUDIO_UNMUTE;
        if (ioctl(bktr_tfd, BT848_SAUDIO, &i) < 0) {
            tc_log_perror(MOD_NAME, "BT848_SAUDIO AUDIO_UNMUTE");
            return(1);
        }
    }

    /* open the video device */

    bktr_vfd = open(video_device, O_RDONLY);
    if (bktr_vfd < 0) {
        tc_log_perror(MOD_NAME, video_device);
        return(1);
    }

    /* get the indices of supported formats that transcode can use */

    for (i = 0; ; i++) {
        pxf.index = i;
        if (ioctl(bktr_vfd, METEORGSUPPIXFMT, &pxf) < 0) {
            if (errno == EINVAL)
                break;
            else
                return(1);
        }
        switch(pxf.type) {
        case METEOR_PIXTYPE_RGB:
            if ((pxf.Bpp == 4) && (pxf.swap_bytes == 0) &&
                    (pxf.swap_shorts == 0)) {
                rgb_idx = pxf.index;
            }
            break;
        case METEOR_PIXTYPE_YUV_PACKED:
            if ((pxf.swap_bytes == 0) && (pxf.swap_shorts == 1)) {
                yuv422_idx = pxf.index;
            }
            break;
        case METEOR_PIXTYPE_YUV_12:
            if ((pxf.swap_bytes == 1) && (pxf.swap_shorts == 1)) {
                yuv_idx = pxf.index;
            }
            break;
        case METEOR_PIXTYPE_YUV:
        default:
            break;
        }
    }

    /* set format, conversion function, and buffer size */

    switch(video_codec) {
    case CODEC_RGB:
        i = rgb_idx;
        bktr_convert = BKTR2RGB;
        bktr_buffer_size = width * height * 4;
        break;
    case CODEC_YUV422:
        i = yuv422_idx;
        bktr_convert = BKTR2YUV422;
        bktr_buffer_size = width * height * 2;
        break;
    case CODEC_YUV:
        i = yuv_idx;
        bktr_convert = BKTR2YUV;
        bktr_buffer_size = width * height * 3 / 2;
        break;
    default:
        tc_log_warn(MOD_NAME,
                    "video_codec (%d) must be %d or %d or %d\n",
                    video_codec, CODEC_RGB, CODEC_YUV422, CODEC_YUV);
        return(1);
    }

    if (ioctl(bktr_vfd, METEORSACTPIXFMT, &i) < 0) {
        tc_log_perror(MOD_NAME, "METEORSACTPIXFMT");
        return(1);
    }

    /* set the geometry */

    geo.rows = height;
    geo.columns = width;
    geo.frames = 1;
    geo.oformat = 0;

    if (verbose_flag & TC_DEBUG) {
        tc_log_info(MOD_NAME,
                    "geo.rows = %d, geo.columns = %d, "
                    "geo.frames = %d, geo.oformat = %ld",
                    geo.rows, geo.columns,
                    geo.frames, (long)geo.oformat);
    }

    if (ioctl(bktr_vfd, METEORSETGEO, &geo) < 0) {
        tc_log_perror(MOD_NAME, "METEORSETGEO");
        return(1);
    }

    /* extra options */

    if (bktr_vsource) {
        if (ioctl(bktr_vfd, METEORSINPUT, &bktr_vsource) < 0) {
            tc_log_perror(MOD_NAME, "METEORSINPUT");
            return(1);
        }
    }

    if (bktr_format) {
        if (ioctl(bktr_vfd, METEORSFMT, &bktr_format) < 0) {
            tc_log_perror(MOD_NAME, "METEORSFMT");
            return(1);
        }
    }

    if (bktr_hwfps) {
        if (ioctl(bktr_vfd, METEORSFPS, &fps) < 0) {
            tc_log_perror(MOD_NAME, "METEORSFPS");
            return(1);
        }
    }

    /* mmap the buffer */

    bktr_buffer = mmap(0, bktr_buffer_size, PROT_READ, MAP_SHARED, bktr_vfd, 0);

    if (bktr_buffer == MAP_FAILED) {
        tc_log_perror(MOD_NAME, "mmap bktr_buffer");
        return(1);
    }

    /* for sigsuspend() */
    sigfillset(&sa_mask);
    sigdelset(&sa_mask, SIGUSR1);
    sigdelset(&sa_mask, SIGALRM);

    /* signal handler to know when data is ready to be read() */

    memset(&act, 0, sizeof(act));
    sigemptyset(&act.sa_mask);
    act.sa_handler = catchsignal;
    sigaction(SIGUSR1, &act, NULL);
    sigaction(SIGALRM, &act, NULL);

    i = SIGUSR1;
    if (ioctl(bktr_vfd, METEORSSIGNAL, &i) < 0) {
        tc_log_perror(MOD_NAME, "METEORSSIGNAL");
        return(1);
    }

    /* let `er rip! */

    i = METEOR_CAP_CONTINOUS;
    if (ioctl(bktr_vfd, METEORCAPTUR, &i) < 0) {
        tc_log_perror(MOD_NAME, "METEORCAPTUR");
        return(1);
    }

    return(0);
}
Esempio n. 12
0
static int demux (uint8_t * buf, uint8_t * end, int flags)
{
    static int mpeg1_skip_table[16] = {
	0, 0, 4, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };

    /*
     * the demuxer keeps some state between calls:
     * if "state" = DEMUX_HEADER, then "head_buf" contains the first
     *     "bytes" bytes from some header.
     * if "state" == DEMUX_DATA, then we need to copy "bytes" bytes
     *     of ES data before the next header.
     * if "state" == DEMUX_SKIP, then we need to skip "bytes" bytes
     *     of data before the next header.
     *
     * NEEDBYTES makes sure we have the requested number of bytes for a
     * header. If we dont, it copies what we have into head_buf and returns,
     * so that when we come back with more data we finish decoding this header.
     *
     * DONEBYTES updates "buf" to point after the header we just parsed.
     */

#define DEMUX_HEADER 0
#define DEMUX_DATA 1
#define DEMUX_SKIP 2
    static int state = DEMUX_SKIP;
    static int state_bytes = 0;
    static uint8_t head_buf[264];

    uint8_t * header;
    int bytes;
    int len;

#define NEEDBYTES(x)						\
    do {							\
	int missing;						\
								\
	missing = (x) - bytes;					\
	if (missing > 0) {					\
	    if (header == head_buf) {				\
		if (missing <= end - buf) {			\
		    ac_memcpy (header + bytes, buf, missing);	\
		    buf += missing;				\
		    bytes = (x);				\
		} else {					\
		    ac_memcpy (header + bytes, buf, end - buf);	\
		    state_bytes = bytes + end - buf;		\
		    return 0;					\
		}						\
	    } else {						\
		ac_memcpy (head_buf, header, bytes);		\
		state = DEMUX_HEADER;				\
		state_bytes = bytes;				\
		return 0;					\
	    }							\
	}							\
    } while (0)

#define DONEBYTES(x)		\
    do {			\
	if (header != head_buf)	\
	    buf = header + (x);	\
    } while (0)

    if (flags & DEMUX_PAYLOAD_START)
	goto payload_start;
    switch (state) {
    case DEMUX_HEADER:
	if (state_bytes > 0) {
	    header = head_buf;
	    bytes = state_bytes;
	    goto continue_header;
	}
	break;
    case DEMUX_DATA:
	if (demux_pid || (state_bytes > end - buf)) {
	    if (fwrite (buf, end - buf, 1, stdout) != 1) {
		tc_log_perror(__FILE__, "Write error");
	    }
	    state_bytes -= end - buf;
	    return 0;
	}
	if (fwrite (buf, state_bytes, 1, stdout) != 1) {
	    tc_log_perror(__FILE__, "Write error");
	}
	buf += state_bytes;
	break;
    case DEMUX_SKIP:
	if (demux_pid || (state_bytes > end - buf)) {
	    state_bytes -= end - buf;
	    return 0;
	}
	buf += state_bytes;
	break;
    }

    while (1) {
	if (demux_pid) {
	    state = DEMUX_SKIP;
	    return 0;
	}
    payload_start:
	header = buf;
	bytes = end - buf;
    continue_header:
	NEEDBYTES (4);
	if (header[0] || header[1] || (header[2] != 1)) {
	    if (demux_pid) {
		state = DEMUX_SKIP;
		return 0;
	    } else if (header != head_buf) {
		buf++;
		goto payload_start;
	    } else {
		header[0] = header[1];
		header[1] = header[2];
		header[2] = header[3];
		bytes = 3;
		goto continue_header;
	    }
	}
	if (demux_pid) {
	    if ((header[3] >= 0xe0) && (header[3] <= 0xef))
		goto pes;
	    tc_log_error(__FILE__, "bad stream id %x", header[3]);
	    exit (1);
	}
	switch (header[3]) {
	case 0xb9:	/* program end code */
	    /* DONEBYTES (4); */
	    /* break;         */
	    return 1;
	case 0xba:	/* pack header */
	    NEEDBYTES (12);
	    if ((header[4] & 0xc0) == 0x40) {	/* mpeg2 */
		NEEDBYTES (14);
		len = 14 + (header[13] & 7);
		NEEDBYTES (len);
		DONEBYTES (len);
		/* header points to the mpeg2 pack header */
	    } else if ((header[4] & 0xf0) == 0x20) {	/* mpeg1 */
		DONEBYTES (12);
		/* header points to the mpeg1 pack header */
	    } else {
		tc_log_error(__FILE__, "weird pack header");
		exit (1);
	    }
	    break;
	default:
	    if (header[3] == demux_track) {
	    pes:
		NEEDBYTES (7);
		if ((header[6] & 0xc0) == 0x80) {	/* mpeg2 */
		    NEEDBYTES (9);
		    len = 9 + header[8];
		    NEEDBYTES (len);
		    /* header points to the mpeg2 pes header */
		} else {	/* mpeg1 */
		    len = 7;
		    while ((header-1)[len] == 0xff) {
			len++;
			NEEDBYTES (len);
			if (len > 23) {
			    tc_log_warn(__FILE__, "too much stuffing");
			    break;
			}
		    }
		    if (((header-1)[len] & 0xc0) == 0x40) {
			len += 2;
			NEEDBYTES (len);
		    }
		    len += mpeg1_skip_table[(header - 1)[len] >> 4];
		    NEEDBYTES (len);
		    /* header points to the mpeg1 pes header */
		}
		DONEBYTES (len);
		bytes = 6 + (header[4] << 8) + header[5] - len;
		if (demux_pid || (bytes > end - buf)) {
		    if (fwrite (buf, end - buf, 1, stdout) != 1) {
			tc_log_perror(__FILE__, "Write error");
		    }
		    state = DEMUX_DATA;
		    state_bytes = bytes - (end - buf);
		    return 0;
		} else if (bytes <= 0) {
		    continue;
		}
		if (fwrite (buf, bytes, 1, stdout) != 1) {
		    tc_log_perror(__FILE__, "Write error");
		}
		buf += bytes;
	    } else if (header[3] < 0xb9) {
		tc_log_info(__FILE__,
			    "looks like a video stream, not system stream");
		DONEBYTES (4);
	    } else {
		NEEDBYTES (6);
		DONEBYTES (6);
		bytes = (header[4] << 8) + header[5];
		if (bytes > end - buf) {
		    state = DEMUX_SKIP;
		    state_bytes = bytes - (end - buf);
		    return 0;
		}
		buf += bytes;
	    }
	}
Esempio n. 13
0
int chroma_key(int u, int v, double color,\
double color_window, double saturation)
{
double da, du, dv, ds;
double dcolor, dvector;
double dsine;

if(debug_flag)
	{
	tc_log_msg(MOD_NAME, "subtitler(): chroma_key(): arg\n\
	u=%d v=%d color=%.3f color_window=%.3f saturation=%.3f\n",\
	u, v, color, color_window, saturation);
	}

/*
The U and V signals were intended for quadrature modulation on the 4.43
PAL carrier, lets do it:
       color vector, angle alpha sets color, amplitude sets saturation
     u /
     |/ alpha
-v -- -- v
     |
    -u
*/

/* no color no action, prevent nan */
if( (u == 0) && (v == 0) ) return 0;

/* calculate the vector amplitude (hypotenusa) */
du = (double)u;
dv = (double)v;
dvector = sqrt( (du * du) + ( dv * dv ) );

/* calculate if enough saturation (chroma level) */

/* saturation is specified as 0-100% */
/* range 0-1 */
ds = saturation / 100.0;

/* multiply by maximum vector amplitude possible */
ds *= dmax_vector; // set in init

/* if not this much color, return no match */
if(dvector < ds) return 0;

/* calculate the sine */
dsine = (du / dvector);

/* dsine must be in the range -1 to +1, else errno. */

/* get the vector angle */
errno = 0;
dcolor = asin(dsine);
if(errno == EDOM)
	{
	tc_log_perror(MOD_NAME, "subtitler(): rotate_color(): asin NOT A NUMBER :-)");

	/* abort */
	exit(1);
	}

/* if V is negative, we move to the other 2 quadrants */
if(dv < 0) dcolor = M_PI - dcolor;

dcolor *= 180.0 / M_PI;

da = dcolor - color;

/* if color in range, return match */
if( fabs(da) < color_window) return 1;

return 0;
} /* end function chroma_key */
Esempio n. 14
0
void adjust_color(int *u, int *v, double degrees, double saturation)
{
double du, dv;
double dcolor, dsaturation;
double dsine;
double dsat;
int tmp_int;

if(debug_flag)
	{
	tc_log_msg(MOD_NAME, "subtitler(): adjust_color(): arg\n\
	*u=%d *v=%d degrees=%.3f saturation=%.3f\n",\
	*u, *v, degrees, saturation);
	}

/*
The U and V signals were intended for quadrature modulation on the 4.43
PAL carrier, lets do it:
       color vector, angle alpha sets color, amplitude sets saturation
     u /
     |/ alpha
-v -- -- v
     |
    -u
*/

/* no color no action, prevent nan */
if( (*u == 0) && (*v == 0) ) return;

/* calculate the vector amplitude (hypotenusa) */
du = (double)*u;
dv = (double)*v;
dsaturation = sqrt( (du * du) + ( dv * dv ) );

/* calc multiplyer from percentage 0-100 */
dsat  = saturation / 100.0;

/*
I wont apply a flipping vector each line, as in PAL, so as to keep our
quadrature modulator simple, we have no phase errors here to correct.
Phase errors in PAL cancel, but leave small saturation (vector amplitude)
errors.
*/

/* calculate the sine */
dsine = (du / dsaturation);

/* dsine must be in the range -1 to +1, else errno. */

/* get the vector angle */
errno = 0;
dcolor = asin(dsine);
if(errno == EDOM)
	{
	tc_log_perror(MOD_NAME, "subtitler(): rotate_color(): asin NOT A NUMBER :-)");

	/* abort */
	exit(1);
	}

/* if V is negative, we move to the other 2 quadrants */
if(dv < 0) dcolor = M_PI - dcolor;

/* add the hue to the vector angle, -PI/2 to PI/2 (inclusive) */
dcolor += (degrees * M_PI) / 180.0;

/* change saturation by changing the vector amplitude */
dsaturation *= dsat;

/* demodulate :) our quadrature demodulator */
tmp_int = sin(dcolor) * dsaturation;
*u = tmp_int;
tmp_int = cos(dcolor) * dsaturation;
*v = tmp_int;

/* and do this for each pixel...... */

return;
} /* end function adjust_color */
Esempio n. 15
0
int main(int argc, char *argv[])
{

    info_t ipipe;

    int user=0;

    long
	stream_stype = TC_STYPE_UNKNOWN,
	stream_magic = TC_MAGIC_UNKNOWN,
	stream_codec = TC_CODEC_UNKNOWN;

    int ch, done=0, track=0;
    char *magic=NULL, *codec=NULL, *name=NULL;

    //proper initialization
    memset(&ipipe, 0, sizeof(info_t));
    ipipe.frame_limit[0]=0;
    ipipe.frame_limit[1]=LONG_MAX;

    libtc_init(&argc, &argv);

    while ((ch = getopt(argc, argv, "d:x:i:f:a:vt:C:?h")) != -1) {

	switch (ch) {

	case 'i':

	  if(optarg[0]=='-') usage(EXIT_FAILURE);
	  name = optarg;

	  break;

	case 'd':

	  if(optarg[0]=='-') usage(EXIT_FAILURE);
	  verbose = atoi(optarg);

	  break;

	case 'x':

	  if(optarg[0]=='-') usage(EXIT_FAILURE);
	  codec = optarg;
	  break;

	case 'f':

	  if(optarg[0]=='-') usage(EXIT_FAILURE);
	  ipipe.nav_seek_file = optarg;

	  break;

	case 't':

	  if(optarg[0]=='-') usage(EXIT_FAILURE);
	  magic = optarg;
	  user=1;

	  break;

	case 'a':

	  if(optarg[0]=='-') usage(EXIT_FAILURE);
	  track = strtol(optarg, NULL, 0);
	  break;

        case 'C':

          if(optarg[0]=='-') usage(EXIT_FAILURE);
          if (2 != sscanf(optarg,"%ld-%ld", &ipipe.frame_limit[0], &ipipe.frame_limit[1])) usage(EXIT_FAILURE);
          if (ipipe.frame_limit[0] > ipipe.frame_limit[1])
          {
                tc_log_error(EXE, "Invalid -C options");
                usage(EXIT_FAILURE);
          }
          break;

	case 'v':
	  version();
	  exit(0);
	  break;

	case 'h':
	  usage(EXIT_SUCCESS);
	default:
	  usage(EXIT_FAILURE);
	}
    }

    ac_init(AC_ALL);

    /* ------------------------------------------------------------
     *
     * fill out defaults for info structure
     *
     * ------------------------------------------------------------*/

    // assume defaults
    if(name==NULL) stream_stype=TC_STYPE_STDIN;

    // no autodetection yet
    if(codec==NULL && magic==NULL) {
      tc_log_error(EXE, "invalid codec %s", codec);
      usage(EXIT_FAILURE);
    }

    if(codec==NULL) codec="";

    // do not try to mess with the stream
    if(stream_stype!=TC_STYPE_STDIN) {

      if(tc_file_check(name)) exit(1);

      if((ipipe.fd_in = xio_open(name, O_RDONLY))<0) {
	tc_log_perror(EXE, "file open");
	return(-1);
      }

      stream_magic = fileinfo(ipipe.fd_in, 0);

      if(verbose & TC_DEBUG)
	tc_log_msg(EXE, "(pid=%d) %s", getpid(), filetype(stream_magic));

    } else ipipe.fd_in = STDIN_FILENO;

    if(verbose & TC_DEBUG)
	tc_log_msg(EXE, "(pid=%d) starting, doing %s", getpid(), codec);

    // fill out defaults for info structure
    ipipe.fd_out = STDOUT_FILENO;

    ipipe.magic   = stream_magic;
    ipipe.stype   = stream_stype;
    ipipe.codec   = stream_codec;
    ipipe.track   = track;
    ipipe.select  = TC_VIDEO;

    ipipe.verbose = verbose;

    ipipe.name = name;

    /* ------------------------------------------------------------
     *
     * codec specific section
     *
     * note: user provided magic values overwrite autodetection!
     *
     * ------------------------------------------------------------*/

    if(magic==NULL) magic="";

    // OGM

    if (ipipe.magic == TC_MAGIC_OGG) {

	// dummy for video
	if(strcmp(codec, "raw")==0) ipipe.codec = TC_CODEC_RGB24;
	if((strcmp(codec, "vorbis")==0) || (strcmp(codec, "ogg")==0)) {
	    ipipe.codec = TC_CODEC_VORBIS;
	    ipipe.select = TC_AUDIO;
	}
	if(strcmp(codec, "mp3")==0) {
	    ipipe.codec = TC_CODEC_MP3;
	    ipipe.select = TC_AUDIO;
	}
	if(strcmp(codec, "pcm")==0) {
	    ipipe.codec = TC_CODEC_PCM;
	    ipipe.select = TC_AUDIO;
	}

	extract_ogm(&ipipe);
	done = 1;
    }

    // MPEG2
    if(strcmp(codec,"mpeg2")==0) {

      ipipe.codec = TC_CODEC_MPEG2;

      if(strcmp(magic, "vob")==0) ipipe.magic = TC_MAGIC_VOB;
      if(strcmp(magic, "m2v")==0) ipipe.magic = TC_MAGIC_M2V;
      if(strcmp(magic, "raw")==0) ipipe.magic = TC_MAGIC_RAW;

      extract_mpeg2(&ipipe);
      done = 1;
    }

    // PCM
    if(strcmp(codec,"pcm")==0) {

	ipipe.codec = TC_CODEC_PCM;
	ipipe.select = TC_AUDIO;

	if(strcmp(magic, "vob")==0) ipipe.magic = TC_MAGIC_VOB;
	if(strcmp(magic, "avi")==0) ipipe.magic = TC_MAGIC_AVI;
	if(strcmp(magic, "raw")==0) ipipe.magic = TC_MAGIC_RAW;
	if(strcmp(magic, "wav")==0) ipipe.magic = TC_MAGIC_WAV;

	extract_pcm(&ipipe);
	done = 1;
    }

    // SUBTITLE (private_stream_1)
    if(strcmp(codec,"ps1")==0) {

	ipipe.codec = TC_CODEC_PS1;
	ipipe.select = TC_AUDIO;

	if(strcmp(magic, "vob")==0) ipipe.magic = TC_MAGIC_VOB;
	if(strcmp(magic, "vdr")==0) ipipe.magic = TC_MAGIC_VDR;

	extract_ac3(&ipipe);
	done = 1;
    }


    // DV
    if(strcmp(codec,"dv")==0) {

	ipipe.codec = TC_CODEC_DV;

	if(strcmp(magic, "avi")==0) ipipe.magic = TC_MAGIC_AVI;
	if(strcmp(magic, "raw")==0) ipipe.magic = TC_MAGIC_RAW;

	extract_dv(&ipipe);
	done = 1;
    }


    // RGB
    if(strcmp(codec,"rgb")==0) {

	ipipe.codec = TC_CODEC_RGB24;

	if(strcmp(magic, "avi")==0) ipipe.magic = TC_MAGIC_AVI;
	if(strcmp(magic, "raw")==0) ipipe.magic = TC_MAGIC_RAW;
	if(strcmp(magic, "wav")==0) ipipe.magic = TC_MAGIC_WAV;

	extract_rgb(&ipipe);
	done = 1;
    }


    // DTS
    if(strcmp(codec,"dts")==0) {

	ipipe.codec = TC_CODEC_DTS;
	ipipe.select = TC_AUDIO;

	if(strcmp(magic, "raw")==0) ipipe.magic = TC_MAGIC_RAW;
	if(strcmp(magic, "vob")==0) ipipe.magic = TC_MAGIC_VOB;

	extract_ac3(&ipipe);
	done = 1;
    }

    // AC3
    if(strcmp(codec,"ac3")==0) {

	ipipe.codec = TC_CODEC_AC3;
	ipipe.select = TC_AUDIO;

	if(strcmp(magic, "raw")==0) ipipe.magic = TC_MAGIC_RAW;
	if(strcmp(magic, "vob")==0) ipipe.magic = TC_MAGIC_VOB;

	extract_ac3(&ipipe);
	done = 1;
    }

    // MP3
    if(strcmp(codec,"mp3")==0 || strcmp(codec,"mp2")==0) {

	ipipe.codec = TC_CODEC_MP3;
	ipipe.select = TC_AUDIO;

	if(strcmp(magic, "avi")==0) ipipe.magic = TC_MAGIC_AVI;
	if(strcmp(magic, "raw")==0) ipipe.magic = TC_MAGIC_RAW;
	if(strcmp(magic, "vob")==0) ipipe.magic = TC_MAGIC_VOB;

	extract_mp3(&ipipe);
	done = 1;
    }

    // YUV420P
    if(strcmp(codec,"yuv420p")==0) {

	ipipe.codec = TC_CODEC_YUV420P;

	if(strcmp(magic, "avi")==0) ipipe.magic = TC_MAGIC_AVI;
	if(strcmp(magic, "raw")==0) ipipe.magic = TC_MAGIC_RAW;
	if(strcmp(magic, "yuv4mpeg")==0) ipipe.magic = TC_MAGIC_YUV4MPEG;

	extract_yuv(&ipipe);
	done = 1;
    }

    // YUV422P
    if(strcmp(codec,"yuv422p")==0) {

	ipipe.codec = TC_CODEC_YUV422P;

	if(strcmp(magic, "avi")==0) ipipe.magic = TC_MAGIC_AVI;
	if(strcmp(magic, "raw")==0) ipipe.magic = TC_MAGIC_RAW;
	if(strcmp(magic, "yuv4mpeg")==0) ipipe.magic = TC_MAGIC_YUV4MPEG;

	extract_yuv(&ipipe);
	done = 1;
    }

    // UYVY
    if(strcmp(codec,"uyvy")==0) {

	ipipe.codec = TC_CODEC_UYVY;

	if(strcmp(magic, "avi")==0) ipipe.magic = TC_MAGIC_AVI;
	if(strcmp(magic, "raw")==0) ipipe.magic = TC_MAGIC_RAW;

	extract_yuv(&ipipe);
	done = 1;
    }


    // LZO
    if(strcmp(codec,"lzo")==0) {

	ipipe.codec = TC_CODEC_YUV420P;

	if(strcmp(magic, "avi")==0) ipipe.magic = TC_MAGIC_AVI;
	if(strcmp(magic, "raw")==0) ipipe.magic = TC_MAGIC_RAW;

	extract_lzo(&ipipe);
	done = 1;
    }


    // AVI extraction

    //need to check if there isn't a codec from the input option (if we have a file with TC_MAGIC_AVI and we specify -x pcm we have pcm and rgb output)
    if ((strcmp(magic, "avi")==0 || ipipe.magic==TC_MAGIC_AVI)&& (codec == NULL)) {

	ipipe.magic=TC_MAGIC_AVI;
	extract_avi(&ipipe);
	done = 1;
    }

    if (strcmp(codec, "raw")==0 || strcmp(codec, "video")==0) {
	ipipe.select=TC_VIDEO-1;
	ipipe.magic=TC_MAGIC_AVI;
	extract_avi(&ipipe);
	done = 1;
    }


    if(!done) {
	tc_log_error(EXE, "(pid=%d) unable to handle codec %s", getpid(), codec);
	exit(1);
    }

    if(ipipe.fd_in != STDIN_FILENO) xio_close(ipipe.fd_in);

    return(0);
}
Esempio n. 16
0
int main(int argc, char *argv[])
{
    info_t ipipe;
    int ch, n, user = 0, demux_mode = TC_DEMUX_SEQ_ADJUST;
    int npass = 0, *pass = NULL, *new_pass = NULL;
    int keep_initial_seq = 0, hard_fps_flag = 0, pack_sl = PACKAGE_ALL;
    int unit_seek = 0, resync_seq1 = 0, resync_seq2 = INT_MAX;
    int a_track = 0, v_track = 0, subid = 0x80;
    double fps = PAL_FPS;
    long stream_stype = TC_STYPE_UNKNOWN;
    long stream_codec = TC_CODEC_UNKNOWN;
    long stream_magic = TC_MAGIC_UNKNOWN;
    long x;
    char *magic = "", *codec = NULL, *name = NULL;
    char *logfile = SYNC_LOGFILE, *str = NULL, *end = NULL;
    //defaults:
    //proper initialization
    memset(&ipipe, 0, sizeof(info_t));

    libtc_init(&argc, &argv);

    while ((ch = getopt(argc, argv, "A:a:d:x:i:vt:S:M:f:P:WHs:O?h")) != -1) {
        switch (ch) {
          case 'i':
            if (optarg[0] == '-') usage(EXIT_FAILURE);
            name = optarg;
            break;

          case 'O':
            keep_initial_seq = 1;
            break;

          case 'P':
            if (optarg[0] == '-') usage(EXIT_FAILURE);
            logfile = optarg;
            break;

          case 'S':
            if (optarg[0] == '-') usage(EXIT_FAILURE);
            n = sscanf(optarg,"%d,%d-%d",
                       &unit_seek, &resync_seq1, &resync_seq2);
            if (n < 0) {
                tc_log_error(EXE, "invalid parameter for option -S");
                usage(EXIT_FAILURE);
            }

            if (unit_seek < 0) {
                tc_log_error(EXE, "invalid unit parameter for option -S");
                usage(EXIT_FAILURE);
            }

            if (resync_seq1 < 0 || resync_seq2 < 0
             || resync_seq1 >= resync_seq2) {
                tc_log_error(EXE, "invalid sequence parameter for option -S");
                usage(EXIT_FAILURE);
            }
            break;

          case 'd':
            if (optarg[0] == '-') usage(EXIT_FAILURE);
            verbose = atoi(optarg);
            break;

          case 'f':
            if (optarg[0] == '-') usage(EXIT_FAILURE);
            fps = atof(optarg);
            break;

          case 'W':
            demux_mode = TC_DEMUX_SEQ_LIST;
            logfile = NULL;
            break;

          case 'H':
            hard_fps_flag = 1;
            break;

          case 'x':
            if (optarg[0] == '-') usage(EXIT_FAILURE);
            codec = optarg;

            if (strcmp(codec,"ac3") == 0) {
                pack_sl = PACKAGE_AUDIO_AC3;
                stream_codec = TC_CODEC_AC3;
            }

            if (strcmp(codec,"mpeg2") == 0) {
                pack_sl = PACKAGE_VIDEO;
                stream_codec = TC_CODEC_MPEG2;
            }

            if (strcmp(codec,"mp3") == 0) {
                pack_sl = PACKAGE_AUDIO_MP3;
                stream_codec = TC_CODEC_MP3;
            }

            if (strcmp(codec,"pcm") == 0) {
                pack_sl = PACKAGE_AUDIO_PCM;
                stream_codec = TC_CODEC_PCM;
            }

            if (strcmp(codec,"ps1") == 0) {
                pack_sl = PACKAGE_SUBTITLE;
                stream_codec = TC_CODEC_SUB;
            }
            break;

          case 't':
            if (optarg[0] == '-') usage(EXIT_FAILURE);
            magic = optarg;
            user = 1;
            break;

          case 's':
            if (optarg[0] == '-') usage(EXIT_FAILURE);
            subid = strtol(optarg, NULL, 16);
            break;

          case 'A':
            if (optarg[0] == '-') usage(EXIT_FAILURE);
            while (1) {
                x = strtol(str, &end, 0);
                if ((end == str) || (x < 1) || (x > 0xff)) {
                    tc_log_error(EXE, "invalid parameter for option -A");
                    exit(1);
                }

                if (*end == '\0') {
                    break;
                }
                if (*end != ',') {
                    tc_log_error(EXE, "invalid parameter for option -A");
                    exit(1);
                }
                str = end + 1;
                new_pass = realloc(pass, (npass + 1) * sizeof (int));
                if (new_pass == NULL) {
                    tc_log_error(EXE, "out of memory");
                    exit(1);
                }
                pass = new_pass;
                pass[npass++] = (int)x;
            }
            break;

          case 'M':
            if (optarg[0] == '-') usage(EXIT_FAILURE);
            demux_mode = atoi(optarg);

            if (demux_mode == TC_DEMUX_OFF)
                verbose = TC_QUIET;
            if (demux_mode < 0 || demux_mode > TC_DEMUX_MAX_OPTS) {
                tc_log_error(EXE, "invalid parameter for option -M");
                exit(1);
            }
            break;

          case 'a':
            if (optarg[0] == '-') usage(EXIT_FAILURE);

            if ((n = sscanf(optarg,"%d,%d", &a_track, &v_track)) <= 0) {
                tc_log_error(EXE, "invalid parameter for option -a");
                exit(1);
            }
            break;

          case 'v':
            version();
            exit(0);
            break;

          case 'h':
            usage(EXIT_SUCCESS);
          default:
            usage(EXIT_FAILURE);
        }
    }

    ac_init(AC_ALL);

    /* ------------------------------------------------------------
     * fill out defaults for info structure
     * ------------------------------------------------------------*/

    // assume defaults
    if (name == NULL)
        stream_stype=TC_STYPE_STDIN;

    // no autodetection yet
    if (argc == 1) {
        usage(EXIT_FAILURE);
    }

    // do not try to mess with the stream
    if (stream_stype == TC_STYPE_STDIN) {
        ipipe.fd_in = STDIN_FILENO;
    } else {
        if (tc_file_check(name))
            exit(1);

        ipipe.fd_in = xio_open(name, O_RDONLY);
        if (ipipe.fd_in < 0) {
            tc_log_perror(EXE, "open file");
            exit(1);
        }

        // try to find out the filetype
        stream_magic = fileinfo(ipipe.fd_in, 0);

        if (verbose)
            tc_log_msg(EXE, "(pid=%d) %s", getpid(), filetype(stream_magic));
    }

    // fill out defaults for info structure
    ipipe.fd_out = STDOUT_FILENO;

    ipipe.magic = stream_magic;
    ipipe.stype = stream_stype;
    ipipe.codec = stream_codec;

    ipipe.verbose = verbose;

    ipipe.ps_unit = unit_seek;
    ipipe.ps_seq1 = resync_seq1;
    ipipe.ps_seq2 = resync_seq2;

    ipipe.demux  = demux_mode;
    ipipe.select = pack_sl;
    ipipe.keep_seq = keep_initial_seq;
    ipipe.subid = subid;
    ipipe.fps = fps;

    ipipe.hard_fps_flag = hard_fps_flag;
    ipipe.track = a_track;
    ipipe.name  = logfile;

    //FIXME: video defaults to 0

    /* ------------------------------------------------------------
     * main processing mode
     * ------------------------------------------------------------*/

    if (npass > 0)
        tcdemux_pass_through(&ipipe, pass, npass);
    else
        tcdemux_thread(&ipipe);

    return 0;
}
Esempio n. 17
0
/* FIXME: reorganize the layout */
static int tc_v4l2_video_grab_frame(V4L2Source *vs, uint8_t *dest, size_t length)
{
    static struct v4l2_buffer buffer; /* FIXME */
    int ix, err = 0, eio = 0, ret = TC_ERROR;

    // get buffer
    buffer.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    buffer.memory = V4L2_MEMORY_MMAP;

    err = v4l2_ioctl(vs->video_fd, VIDIOC_DQBUF, &buffer);
    if (err < 0) {
        tc_log_perror(MOD_NAME,
                      "error in setup grab buffer (ioctl(VIDIOC_DQBUF) failed)");

        if (errno != EIO) {
            return TC_OK;
        } else {
            eio = 1;

            for (ix = 0; ix < vs->buffers_count; ix++) {
                buffer.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                buffer.memory = V4L2_MEMORY_MMAP;
                buffer.index  = ix;
                buffer.flags  = 0;

                err = v4l2_ioctl(vs->video_fd, VIDIOC_DQBUF, &buffer);
                if (err < 0)
                    tc_log_perror(MOD_NAME,
                                  "error in recovering grab buffer (ioctl(DQBUF) failed)");
            }

            for (ix = 0; ix < vs->buffers_count; ix++) {
                buffer.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                buffer.memory = V4L2_MEMORY_MMAP;
                buffer.index  = ix;
                buffer.flags  = 0;

                err = v4l2_ioctl(vs->video_fd, VIDIOC_QBUF, &buffer);
                if (err < 0)
                    tc_log_perror(MOD_NAME,
                                  "error in recovering grab buffer (ioctl(QBUF) failed)");
            }
        }
    }

    ix  = buffer.index;

    ret = vs->fetch_data(vs,
                         vs->buffers[ix].start, buffer.bytesused,
                         dest, length);

    // enqueue buffer again
    if (!eio) {
        buffer.type     = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buffer.memory   = V4L2_MEMORY_MMAP;
        buffer.flags    = 0;

        err = v4l2_ioctl(vs->video_fd, VIDIOC_QBUF, &buffer);
        if (err < 0) {
            tc_log_perror(MOD_NAME, "error in enqueuing buffer (ioctl(VIDIOC_QBUF) failed)");
            return TC_OK;
        }
    }

    return ret;
}
Esempio n. 18
0
static void tc_socket_poll_internal(int blocking)
{
    fd_set rfds, wfds;
    char msgbuf[TC_BUF_MAX];
    int maxfd = -1, retval = -1;
    struct timeval tv = {0, 0}, *ptv = (blocking) ?NULL :&tv;

    FD_ZERO(&rfds);
    FD_ZERO(&wfds);
    
    FD_SET(server_sock, &rfds);
    maxfd = server_sock;

    if (client_sock >= 0) {
        FD_SET(client_sock, &rfds);
        //FD_SET(client_sock, &wfds);
        if (client_sock > maxfd)
            maxfd = client_sock;
    }
    retval = select(maxfd+1, &rfds, &wfds, NULL, ptv);

    if (retval == 0) {
        /* nothing interesting happened. It happens :) */
        return;
    }
    if (retval < 0 && errno != EINTR) {
        /* EINTR is an expected "exceptional" condition */
        tc_log_warn(__FILE__, "select(): %s", strerror(errno));
        return;
    }

    if (FD_ISSET(server_sock, &rfds)) {
        int newsock = accept(server_sock, NULL, 0);
        if (newsock < 0) {
            tc_log_warn(__FILE__, "Unable to accept new connection: %s",
                        strerror(errno));
            return;
        }
        if (client_sock >= 0) {
            /* We already have a connection, so drop this one */
            close(newsock);
        } else {
            client_sock = newsock;
        }
    }

    if (client_sock >= 0 && FD_ISSET(client_sock, &rfds)) {
        retval = recv(client_sock, msgbuf, sizeof(msgbuf)-1, 0);
        if (retval <= 0) {
            if (retval < 0)
                tc_log_perror(__FILE__, "Unable to read message from socket");
            close(client_sock);
            client_sock = -1;
        } else {
            if (retval > sizeof(msgbuf)-1)  // paranoia
                retval = sizeof(msgbuf)-1;
            msgbuf[retval] = 0;
            if (!handle(msgbuf)) {
                close(client_sock);
                client_sock = -1;
            }
        }
    }
}
int tc_filter(frame_list_t *ptr_, char *options)
{
	vframe_list_t *ptr = (vframe_list_t *)ptr_;
	int instance = ptr->filter_id;
	Image *pattern, *resized, *orig = 0;
	ImageInfo *image_info;

	PixelPacket *pixel_packet;
	pixelsMask *pixel_last;
	ExceptionInfo exception_info;

	if(ptr->tag & TC_FILTER_GET_CONFIG) {
		char buf[128];
		optstr_filter_desc(options, MOD_NAME, MOD_CAP, MOD_VERSION,
				   MOD_AUTHOR, "VRYMO", "1");

		tc_snprintf(buf, 128, "/dev/null");
		optstr_param(options, "pattern", "Pattern image file path", "%s", buf);
		tc_snprintf(buf, 128, "results.dat");
		optstr_param(options, "results", "Results file path" , "%s", buf);
		tc_snprintf(buf, 128, "%f", compare[instance]->delta);
		optstr_param(options, "delta", "Delta error", "%f",buf,"0.0", "100.0");
		return 0;
	}

	//----------------------------------
	//
	// filter init
	//
	//----------------------------------


	if(ptr->tag & TC_FILTER_INIT)
	{

		unsigned int t,r,index;
		pixelsMask *temp;

		compare[instance] = tc_malloc(sizeof(compareData));
		if(compare[instance] == NULL)
			return (-1);

		compare[instance]->vob = tc_get_vob();
		if(compare[instance]->vob ==NULL)
            return(-1);

		compare[instance]->delta=DELTA_COLOR;
		compare[instance]->step=1;
		compare[instance]->width=0;
		compare[instance]->height=0;
		compare[instance]->frames = 0;
		compare[instance]->pixel_mask = NULL;
		pixel_last = NULL;

		compare[instance]->width = compare[instance]->vob->ex_v_width;
		compare[instance]->height = compare[instance]->vob->ex_v_height;

		if (options != NULL) {
			char pattern_name[PATH_MAX];
			char results_name[PATH_MAX];
			memset(pattern_name,0,PATH_MAX);
			memset(results_name,0,PATH_MAX);

			if(verbose) tc_log_info(MOD_NAME, "options=%s", options);

			optstr_get(options, "pattern", "%[^:]", pattern_name);
			optstr_get(options, "results", "%[^:]", results_name);
			optstr_get(options, "delta", "%f", &compare[instance]->delta);

			if (verbose > 1) {
				tc_log_info(MOD_NAME, "Compare Image Settings:");
				tc_log_info(MOD_NAME, "      pattern = %s\n", pattern_name);
				tc_log_info(MOD_NAME, "      results = %s\n", results_name);
				tc_log_info(MOD_NAME, "        delta = %f\n", compare[instance]->delta);
			}

			if (strlen(results_name) == 0) {
				// Ponemos el nombre del fichero al original con extension dat
				strlcpy(results_name, "/tmp/compare.dat", sizeof(results_name));

			}
			if (!(compare[instance]->results = fopen(results_name, "w")))
			{
				tc_log_perror(MOD_NAME, "could not open file for writing");
			}

			InitializeMagick("");
			if (verbose > 1)
                tc_log_info(MOD_NAME, "Magick Initialized successfully");

			GetExceptionInfo(&exception_info);
			image_info = CloneImageInfo ((ImageInfo *) NULL);
			strlcpy(image_info->filename, pattern_name, MaxTextExtent);
			if (verbose > 1)
			     tc_log_info(MOD_NAME, "Trying to open image");
			orig = ReadImage(image_info,
					 &exception_info);

			if (orig == (Image *) NULL) {
				MagickWarning(exception_info.severity,
					      exception_info.reason,
					      exception_info.description);
				strlcpy(pattern_name, "/dev/null", sizeof(pattern_name));
			}else{
			       if (verbose > 1)
			       		tc_log_info(MOD_NAME, "Image loaded successfully");
			     }
		}

		else{
			tc_log_perror(MOD_NAME, "Not image provided");
		}

		if (options != NULL)
			if (optstr_lookup (options, "help")) {
				help_optstr();
			}


		fprintf(compare[instance]->results,"#fps:%f\n",compare[instance]->vob->fps);

		if (orig != NULL){
                        // Flip and resize
			if (compare[instance]->vob->im_v_codec == CODEC_YUV)
				TransformRGBImage(orig,YCbCrColorspace);
			if (verbose > 1) tc_log_info(MOD_NAME, "Resizing the Image");
			resized = ResizeImage(orig,
					      compare[instance]->width,
					      compare[instance]->height,
					      GaussianFilter,
					      1,
					      &exception_info);
			if (verbose > 1)
				tc_log_info(MOD_NAME, "Flipping the Image");
			pattern = FlipImage(resized, &exception_info);
			if (pattern == (Image *) NULL) {
				MagickError (exception_info.severity,
					     exception_info.reason,
					     exception_info.description);
			}

			// Filling the matrix with the pixels values not
			// alpha

			if (verbose > 1) tc_log_info(MOD_NAME, "GetImagePixels");
			pixel_packet = GetImagePixels(pattern,0,0,
						      pattern->columns,
						      pattern->rows);

			if (verbose > 1) tc_log_info(MOD_NAME, "Filling the Image matrix");
			for (t = 0; t < pattern->rows; t++)
				for (r = 0; r < pattern->columns; r++){
					index = t*pattern->columns + r;
					if (pixel_packet[index].opacity == 0){
						temp=tc_malloc(sizeof(struct pixelsMask));
						temp->row=t;
						temp->col=r;
						temp->r = (uint8_t)ScaleQuantumToChar(pixel_packet[index].red);
						temp->g = (uint8_t)ScaleQuantumToChar(pixel_packet[index].green);
						temp->b = (uint8_t)ScaleQuantumToChar(pixel_packet[index].blue);
						temp->next=NULL;

						if (pixel_last == NULL){
							pixel_last = temp;
							compare[instance]->pixel_mask = temp;
						}else{
							pixel_last->next = temp;
							pixel_last = temp;
						}
					}
				}

			if (verbose)
                tc_log_info(MOD_NAME, "%s %s",
					    MOD_VERSION, MOD_CAP);
		}
		return(0);
	}


	//----------------------------------
	//
	// filter close
	//
	//----------------------------------


	if(ptr->tag & TC_FILTER_CLOSE) {

		if (compare[instance] != NULL) {
			fclose(compare[instance]->results);
			free(compare[instance]);
		}
		DestroyMagick();
		compare[instance]=NULL;

		return(0);

	} /* filter close */

	//----------------------------------
	//
	// filter frame routine
	//
	//----------------------------------


	// tag variable indicates, if we are called before
	// transcodes internal video/audio frame processing routines
	// or after and determines video/audio context

	if((ptr->tag & TC_POST_M_PROCESS) && (ptr->tag & TC_VIDEO))  {
		// For now I only support RGB color space
		pixelsMask *item = NULL;
		double sr,sg,sb;
		double avg_dr,avg_dg,avg_db;

		if (compare[instance]->vob->im_v_codec == CODEC_RGB){

			int r,g,b,c;
			double width_long;

			if (compare[instance]->pixel_mask != NULL)
			{
				item = compare[instance]->pixel_mask;
				c = 0;

				sr = 0.0;
				sg = 0.0;
				sb = 0.0;

				width_long = compare[instance]->width*3;
				while(item){
					r = item->row*width_long + item->col*3;
					g = item->row*width_long
						+ item->col*3 + 1;
					b = item->row*width_long
						+ item->col*3 + 2;

				// diff between points
				// Interchange RGB values if necesary
					sr = sr + (double)abs((unsigned char)ptr->video_buf[r] - item->r);
					sg = sg + (double)abs((unsigned char)ptr->video_buf[g] - item->g);
					sb = sb + (double)abs((unsigned char)ptr->video_buf[b] - item->b);
					item = item->next;
					c++;
				}

				avg_dr = sr/(double)c;
				avg_dg = sg/(double)c;
				avg_db = sb/(double)c;

				if ((avg_dr < compare[instance]->delta) && (avg_dg < compare[instance]->delta) && (avg_db < compare[instance]->delta))
					fprintf(compare[instance]->results,"1");
				else
					fprintf(compare[instance]->results,"n");
				fflush(compare[instance]->results);
			}
			compare[instance]->frames++;
			return(0);
		}else{

                        // The colospace is YUV

                        // FIXME: Doesn't works, I need to code all this part
			// again

			int Y,Cr,Cb,c;

			if (compare[instance]->pixel_mask != NULL)
			{
				item = compare[instance]->pixel_mask;
				c = 0;

				sr = 0.0;
				sg = 0.0;
				sb = 0.0;

				while(item){
					Y  = item->row*compare[instance]->width + item->col;
					Cb = compare[instance]->height*compare[instance]->width
						+ (int)((item->row*compare[instance]->width + item->col)/4);
					Cr = compare[instance]->height*compare[instance]->width
						+ (int)((compare[instance]->height*compare[instance]->width)/4)
						+ (int)((item->row*compare[instance]->width + item->col)/4);

				        // diff between points
				        // Interchange RGB values if necesary

					sr = sr + (double)abs((unsigned char)ptr->video_buf[Y] - item->r);
					sg = sg + (double)abs((unsigned char)ptr->video_buf[Cb] - item->g);
					sb = sb + (double)abs((unsigned char)ptr->video_buf[Cr] - item->b);
					item = item->next;
					c++;
				}

				avg_dr = sr/(double)c;
				avg_dg = sg/(double)c;
				avg_db = sb/(double)c;

				if ((avg_dr < compare[instance]->delta) && (avg_dg < compare[instance]->delta) && (avg_db < compare[instance]->delta))
					fprintf(compare[instance]->results,"1");
				else
					fprintf(compare[instance]->results,"n");
			}
			compare[instance]->frames++;
			return(0);

		}
	}

	return(0);
}
Esempio n. 20
0
int probe_source_xml(vob_t *vob, int which)
{
    int retval = 1;
#ifdef HAVE_LIBXML2
    int tochild[2], fromchild[2];  /* pipes */
    pid_t pid;
    int resize;

    if (pipe(tochild) == -1) {
        tc_log_perror(PACKAGE, "probe_source_xml(): pipe(tochild) failed");
        return 0;
    }
    if (pipe(fromchild) == -1) {
        tc_log_perror(PACKAGE, "probe_source_xml(): pipe(fromchild) failed");
        close(tochild[0]);
        close(tochild[1]);
        return 0;
    }
    pid = fork();
    if (pid == -1) {
        tc_log_perror(PACKAGE, "probe_source_xml(): fork failed");
        return 0;
    } else if (pid > 0) {
        /* Child process */
        const char *new_argv[6];
        close(tochild[1]);
        close(fromchild[0]);
        if (tochild[0] != 0) {
            if (dup2(tochild[0], 0) == -1) {
                tc_log_perror(PACKAGE, "probe_source_xml(): dup2(0) failed");
                exit(-1);
            }
            close(tochild[0]);
        }
        if (fromchild[1] != 1) {  // theoretically always true, but JIC
            if (dup2(fromchild[1], 1) == -1) {
                tc_log_perror(PACKAGE, "probe_source_xml(): dup2(1) failed");
                exit(-1);
            }
            close(fromchild[1]);
        }
        new_argv[0] = "tcxmlcheck";
        new_argv[1] = "-i";
        new_argv[2] = vob->video_in_file;
        new_argv[3] = "-B";
        new_argv[4] = (which==PROBE_XML_VIDEO ? "-V" : "-A");
        new_argv[5] = NULL;
        execvp("tcxmlcheck", (char **)new_argv);
        tc_log_perror(PACKAGE, "probe_source_xml(): exec(tcxmlcheck) failed");
        exit(-1);
    }
    /* Parent process */
    retval = 0;
    close(tochild[0]);
    close(fromchild[1]);
    if (write(tochild[1], vob, sizeof(vob_t)) != sizeof(vob_t)) {
        tc_log_error(PACKAGE, "Error writing data to tcxmlcheck: %s",
                     strerror(errno));
        close(tochild[1]);
        close(fromchild[0]);
        /* Can't just return--need to reap the child */
        goto reapchild;
    }
    close(tochild[1]);
    if (read(fromchild[0], vob, sizeof(vob_t)) != sizeof(vob_t)) {
        tc_log_error(PACKAGE, "Error reading data from tcxmlcheck");
        close(fromchild[0]);
        goto reapchild;
    }
    if (read(fromchild[0], &resize, sizeof(int)) != sizeof(int)) {
	tc_log_error(PACKAGE, "Error reading data from tcxmlcheck 2");
        close(fromchild[0]);
        goto reapchild;
    }
    close(fromchild[0]);
    if (which == PROBE_XML_VIDEO && resize == 2) {
        // XML forced resize, clear command line parameters
        resize1 = TC_FALSE;
        resize2 = TC_FALSE;
        zoom = TC_FALSE;
        vob->resize1_mult = 32;
        vob->vert_resize1 = 0;
        vob->hori_resize1 = 0;
        vob->resize2_mult = 32;
        vob->vert_resize2 = 0;
        vob->hori_resize2 = 0;
        vob->zoom_width   = 0;
        vob->zoom_height  = 0;
        vob->zoom_filter  = TCV_ZOOM_LANCZOS3;
    }
    retval = 1;

  reapchild:  // clean up after the child process
    waitpid(pid, NULL, 0);
#endif  // HAVE_LIBXML2

    return retval;
}
Esempio n. 21
0
void
probe_oss(info_t * ipipe)
{
int encodings;
int encoding;
int precision;
int channels;
int sample_rate;

    close(ipipe->fd_in);
    ipipe->fd_in = open(ipipe->name, O_RDONLY, 0);
    if (ipipe->fd_in < 0) {
	tc_log_error(__FILE__, "cannot (re)open device: %s", strerror(errno));
	goto error;
    }

    /* try tc's defaults */
    encoding = AFMT_S16_LE;
    precision = 16;
    channels = 2;
    sample_rate = 48000;

    if (ioctl(ipipe->fd_in, SNDCTL_DSP_GETFMTS, &encodings) < 0) {
        tc_log_perror(__FILE__, "SNDCTL_DSP_SETFMT");
        goto error;
    }
    if (encodings & AFMT_S16_LE) {
        if (ioctl(ipipe->fd_in, SNDCTL_DSP_SETFMT, &encoding) < 0) {
            if (encodings & AFMT_U8) {
                encoding = AFMT_U8;
                precision = 8;
                if (ioctl(ipipe->fd_in, SNDCTL_DSP_SETFMT, &encoding) < 0) {
                    tc_log_perror(__FILE__, "SNDCTL_DSP_SETFMT");
                    goto error;
                }
            }
        }
    }

    if (ioctl(ipipe->fd_in, SNDCTL_DSP_CHANNELS, &channels) < 0) {
        tc_log_perror(__FILE__, "SNDCTL_DSP_CHANNELS");
        goto error;
    }

    if (ipipe->verbose & TC_DEBUG)
	tc_log_msg(__FILE__, "checking for valid samplerate...");
    if (ioctl(ipipe->fd_in, SNDCTL_DSP_SPEED, &sample_rate) < 0) {
        sample_rate = 44100;
        if (ioctl(ipipe->fd_in, SNDCTL_DSP_SPEED, &sample_rate) < 0) {
            sample_rate = 32000;
            if (ioctl(ipipe->fd_in, SNDCTL_DSP_SPEED, &sample_rate) < 0) {
                sample_rate = 22050;
                if (ioctl(ipipe->fd_in, SNDCTL_DSP_SPEED, &sample_rate) < 0) {
                    sample_rate = 24000;
                    if (ioctl(ipipe->fd_in, SNDCTL_DSP_SPEED, &sample_rate) < 0) {
                        sample_rate = 16000;
                        if (ioctl(ipipe->fd_in, SNDCTL_DSP_SPEED, &sample_rate) < 0) {
                            sample_rate = 11025;
                            if (ioctl(ipipe->fd_in, SNDCTL_DSP_SPEED, &sample_rate) < 0) {
                                if (ipipe->verbose & TC_DEBUG)
                                    tc_log_msg(__FILE__, "... not found");
                                goto error;
                            }
                        }
                    }
                }
            }
        }
    }
    if (ipipe->verbose & TC_DEBUG)
        tc_log_msg(__FILE__, "... found %d", sample_rate);

    ipipe->probe_info->track[0].bits = precision;
    ipipe->probe_info->track[0].chan = channels;
    ipipe->probe_info->track[0].samplerate = sample_rate;
    ipipe->probe_info->track[0].format = 0x1;

    if (ipipe->probe_info->track[0].chan > 0)
        ipipe->probe_info->num_tracks = 1;

    ipipe->probe_info->magic = TC_MAGIC_OSS_AUDIO;
    ipipe->probe_info->codec = TC_CODEC_PCM;

    return;

error:
    ipipe->error = 1;
    ipipe->probe_info->codec = TC_CODEC_UNKNOWN;
    ipipe->probe_info->magic = TC_MAGIC_UNKNOWN;

    return;

}