Пример #1
0
ssize_t DevPty::handle_read(struct anvil_read_msg *msg, anvil_msginfo_t *msg_info, size_t nbyte, off_t offset)
{
    //anvil_syslog(0, "Ptm::handle_read() n=%d a=%d\n", nbyte, get_pts()->chars_avail());

    size_t avail = get_pts()->chars_avail();
    if (avail)
    {
        size_t amount_to_read = std::min(nbyte, avail);
        msg_poke(msg_info->pid, msg_info->tid, get_pts()->get_chars_ptr(), amount_to_read, 0);
        get_pts()->erase_chars(amount_to_read);
        msg_reply(msg_info->pid, msg_info->tid, amount_to_read, NULL, 0);
        //anvil_syslog(0, "Ptm::handle_read() got %d chars\n", amount_to_read);
        msg_send(m_master_pid, ANVIL_POLL_READY, (void *)(uintptr_t)12345, 4);
    }
    else
    {
        // Reply with no chars
        msg_reply(msg_info->pid, msg_info->tid, 0, NULL, 0);
        // Queue the process until there are chars
//        m_output_waiter = *msg_info;
//        m_output_waiter_size = msg->nbyte;
//        anvil_syslog(0, "Ptm::handle_read() got no chars\n");
    }
    return 0;
}
Пример #2
0
ssize_t DevPty::handle_write(struct anvil_write_msg *msg, anvil_msginfo_t *msg_info, size_t nbyte, off_t offset)
{
    //anvil_syslog(0, "Ptm::handle_write()\n");
    // Put the bytes in the ring buffer

    uint8_t buf[WRITE_BUF_SIZE+1];
    size_t still_to_write = nbyte;
    size_t total_written = 0;

    while (still_to_write)
    {
        size_t peek_amount = std::min(still_to_write, (size_t)WRITE_BUF_SIZE);
        if (peek_amount <= 0)
        {
            break;
        }
        msg_peek(msg_info->pid, msg_info->tid, buf, peek_amount, total_written + sizeof(struct anvil_write_msg));
        still_to_write -= peek_amount;
        total_written += peek_amount;
        for (int i=0; i<peek_amount; ++i)
        {
            //anvil_syslog(0, "Ptm %c (%02x)\n", isprint(buf[i])?buf[i]:'-', buf[i]);
            get_pts()->push_char(buf[i]);
        }
    }

    msg_reply(msg_info->pid, msg_info->tid, total_written, NULL, 0);
    return total_written;
}
Пример #3
0
static int srt_read_header(AVFormatContext *s)
{
    SRTContext *srt = s->priv_data;
    AVBPrint buf;
    AVStream *st = avformat_new_stream(s, NULL);
    int res = 0;
    FFTextReader tr;
    ff_text_init_avio(s, &tr, s->pb);

    if (!st)
        return AVERROR(ENOMEM);
    avpriv_set_pts_info(st, 64, 1, 1000);
    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
    st->codec->codec_id   = AV_CODEC_ID_SUBRIP;

    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);

    while (!ff_text_eof(&tr)) {
        ff_subtitles_read_text_chunk(&tr, &buf);

        if (buf.len) {
            int64_t pos = ff_text_pos(&tr);
            int64_t pts;
            int duration;
            const char *ptr = buf.str;
            int32_t x1 = -1, y1 = -1, x2 = -1, y2 = -1;
            AVPacket *sub;

            pts = get_pts(&ptr, &duration, &x1, &y1, &x2, &y2);
            if (pts != AV_NOPTS_VALUE) {
                int len = buf.len - (ptr - buf.str);
                if (len <= 0)
                    continue;
                sub = ff_subtitles_queue_insert(&srt->q, ptr, len, 0);
                if (!sub) {
                    res = AVERROR(ENOMEM);
                    goto end;
                }
                sub->pos = pos;
                sub->pts = pts;
                sub->duration = duration;
                if (x1 != -1) {
                    uint8_t *p = av_packet_new_side_data(sub, AV_PKT_DATA_SUBTITLE_POSITION, 16);
                    if (p) {
                        AV_WL32(p,      x1);
                        AV_WL32(p +  4, y1);
                        AV_WL32(p +  8, x2);
                        AV_WL32(p + 12, y2);
                    }
                }
            }
        }
    }

    ff_subtitles_queue_finalize(&srt->q);

end:
    av_bprint_finalize(&buf, NULL);
    return res;
}
Пример #4
0
char* parsePTStoString(uint8_t *ptsin){
	//uint64_t ptsticks = (((ptsin[0] & 0x0E) >> 1) <<32)| ((ptsin[1]) << 24) | ((ptsin[2] & 0xFE) << 16) | ((ptsin[3]) << 8) | ((ptsin[4]) & 0xFE);
	uint64_t ptsticks = get_pts(ptsin);
	uint64_t ptstotalseconds = ptsticks / 90;
	uint32_t pts_ms = ptstotalseconds % 1000;
	uint32_t pts_s = ((ptstotalseconds - pts_ms) / 1000) % 60;
	uint32_t pts_m = ((ptstotalseconds - pts_ms - (pts_s*1000)) / 1000 / 60) % 60;
	uint32_t pts_h = ((ptstotalseconds - pts_ms - (pts_s*1000) - (pts_m*60*1000)) / 1000 / 60 / 60);
	if ((pts_ms % 10) > 4){
		pts_ms = pts_ms + (10-pts_ms%10);
	} else {
		pts_ms = pts_ms - (pts_ms%10);
	}
	pts_ms=pts_ms/10;
	if (pts_ms == 100){
		pts_s++;
		pts_ms = 0;
		if (pts_s >= 60){
			pts_m++;
			pts_s=0;
			if (pts_m >= 60){
				pts_h++;
				pts_m=0;
			}
		}
	}
	
	char* outstr = malloc(100 * sizeof(char));
	snprintf(outstr,100,"%02d:%02d:%02d.%02d",pts_h,pts_m,pts_s,pts_ms);
	#ifdef DEBUG_PTS
		printf("debug: %X %X %X %X %X : %u : %d %d %d %d\n",ptsin[0],ptsin[1],ptsin[2],ptsin[3],ptsin[4],ptstotalseconds,pts_ms,pts_s,pts_m,pts_h);	
		printf("outstr: %s\n",outstr);
	#endif
	return outstr;	
}
Пример #5
0
static int microdvd_read_header(AVFormatContext *s)
{
    AVRational pts_info = (AVRational){ 2997, 125 };  /* default: 23.976 fps */
    MicroDVDContext *microdvd = s->priv_data;
    AVStream *st = avformat_new_stream(s, NULL);
    int i = 0;
    char line[MAX_LINESIZE];

    if (!st)
        return AVERROR(ENOMEM);

    while (!url_feof(s->pb)) {
        AVPacket *sub;
        int64_t pos = avio_tell(s->pb);
        int len = ff_get_line(s->pb, line, sizeof(line));

        if (!len)
            break;
        if (i < 3) {
            int frame;
            double fps;
            char c;

            i++;
            if ((sscanf(line, "{%d}{}%6lf",    &frame, &fps) == 2 ||
                 sscanf(line, "{%d}{%*d}%6lf", &frame, &fps) == 2)
                && frame <= 1 && fps > 3 && fps < 100)
                pts_info = av_d2q(fps, 100000);
            if (!st->codec->extradata && sscanf(line, "{DEFAULT}{}%c", &c) == 1) {
                st->codec->extradata = av_strdup(line + 11);
                if (!st->codec->extradata)
                    return AVERROR(ENOMEM);
                st->codec->extradata_size = strlen(st->codec->extradata) + 1;
                continue;
            }
        }
        sub = ff_subtitles_queue_insert(&microdvd->q, line, len, 0);
        if (!sub)
            return AVERROR(ENOMEM);
        sub->pos = pos;
        sub->pts = get_pts(sub->data);
        sub->duration = get_duration(sub->data);
    }
    ff_subtitles_queue_finalize(&microdvd->q);
    avpriv_set_pts_info(st, 64, pts_info.den, pts_info.num);
    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
    st->codec->codec_id   = AV_CODEC_ID_MICRODVD;
    return 0;
}
Пример #6
0
static int text_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    char buffer[2048], *ptr = buffer, *ptr2, *prt3;
    char data[1024] = {0};
    int64_t pos = avio_tell(s->pb);
    int res = AVERROR_EOF;

    do {
        ptr2 = ptr;
        ptr += ff_get_line(s->pb, ptr, sizeof(buffer)+buffer-ptr);
    } while(is_eol(*ptr2) && !url_feof(s->pb) && ptr-buffer<sizeof(buffer)-1);

    do {
        prt3 = ptr;
        ptr += ff_get_line(s->pb, ptr, sizeof(buffer)+buffer-ptr);
    } while(is_eol(*prt3) && !url_feof(s->pb) && ptr-buffer<sizeof(buffer)-1);

    


    if (buffer[0]) {
        int64_t pts;
        int duration;
        const char *end = ptr;


        ptr = buffer;

        pts = get_pts(&ptr, &duration, data);
        
        if (pts != AV_NOPTS_VALUE &&
            !(res = av_new_packet(pkt, strlen(data)))) {
            memcpy(pkt->data, data, strlen(data));
            memset(data, 0, 1024);
            pkt->flags |= AV_PKT_FLAG_KEY;
            pkt->pos = pos;
            pkt->pts = pkt->dts = pts;
            pkt->duration = duration;
        }

    }
    
    return res;
}
Пример #7
0
static int srt_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    char buffer[2048], *ptr = buffer, *ptr2;
    int64_t pos = avio_tell(s->pb);
    int res = AVERROR_EOF;

    do {
        ptr2 = ptr;
        ptr += ff_get_line(s->pb, ptr, sizeof(buffer)+buffer-ptr);
    } while (!is_eol(*ptr2) && !url_feof(s->pb) && ptr-buffer<sizeof(buffer)-1);

    if (buffer[0] && !(res = av_new_packet(pkt, ptr-buffer))) {
        memcpy(pkt->data, buffer, pkt->size);
        pkt->flags |= AV_PKT_FLAG_KEY;
        pkt->pos = pos;
        pkt->pts = pkt->dts = get_pts(pkt->data);
    }
    return res;
}
Пример #8
0
static int read_packet(AVFormatContext *s, AVPacket *pkt)
{
    ASSContext *ass = s->priv_data;
    uint8_t *p, *end;

    if(ass->event_index >= ass->event_count)
        return AVERROR(EIO);

    p= ass->event[ ass->event_index ];

    end= strchr(p, '\n');
    av_new_packet(pkt, end ? end-p+1 : strlen(p));
    pkt->flags |= AV_PKT_FLAG_KEY;
    pkt->pos= p - ass->event_buffer + s->streams[0]->codec->extradata_size;
    pkt->pts= pkt->dts= get_pts(p);
    memcpy(pkt->data, p, pkt->size);

    ass->event_index++;

    return 0;
}
Пример #9
0
static int read_seek2(AVFormatContext *s, int stream_index,
                      int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
{
    ASSContext *ass = s->priv_data;

    if (flags & AVSEEK_FLAG_BYTE) {
        return AVERROR(ENOSYS);
    } else if (flags & AVSEEK_FLAG_FRAME) {
        if (ts < 0 || ts >= ass->event_count)
            return AVERROR(ERANGE);
        ass->event_index = ts;
    } else {
        int i, idx = -1;
        int64_t min_ts_diff = INT64_MAX;
        if (stream_index == -1) {
            AVRational time_base = s->streams[0]->time_base;
            ts = av_rescale_q(ts, AV_TIME_BASE_Q, time_base);
            min_ts = av_rescale_rnd(min_ts, time_base.den,
                                    time_base.num * (int64_t)AV_TIME_BASE,
                                    AV_ROUND_UP);
            max_ts = av_rescale_rnd(max_ts, time_base.den,
                                    time_base.num * (int64_t)AV_TIME_BASE,
                                    AV_ROUND_DOWN);
        }
        /* TODO: ass->event[] is sorted by pts so we could do a binary search */
        for (i=0; i<ass->event_count; i++) {
            int64_t pts = get_pts(ass->event[i]);
            int64_t ts_diff = FFABS(pts - ts);
            if (pts >= min_ts && pts <= max_ts && ts_diff < min_ts_diff) {
                min_ts_diff = ts_diff;
                idx = i;
            }
        }
        if (idx < 0)
            return AVERROR(ERANGE);
        ass->event_index = idx;
    }
    return 0;
}
Пример #10
0
static int srt_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    char buffer[2048], *ptr = buffer, *ptr2;
    int64_t pos = avio_tell(s->pb);
    int res = AVERROR_EOF;

    do {
        ptr2 = ptr;
        ptr += ff_get_line(s->pb, ptr, sizeof(buffer)+buffer-ptr);
    } while (!is_eol(*ptr2) && !url_feof(s->pb) && ptr-buffer<sizeof(buffer)-1);

    if (buffer[0]) {
        int64_t pts;
        int duration;
        const char *end = ptr;
        int32_t x1 = -1, y1 = -1, x2 = -1, y2 = -1;

        ptr = buffer;
        pts = get_pts(&ptr, &duration, &x1, &y1, &x2, &y2);
        if (pts != AV_NOPTS_VALUE &&
            !(res = av_new_packet(pkt, end - ptr))) {
            memcpy(pkt->data, ptr, pkt->size);
            pkt->flags |= AV_PKT_FLAG_KEY;
            pkt->pos = pos;
            pkt->pts = pkt->dts = pts;
            pkt->duration = duration;
            if (x1 != -1) {
                uint8_t *p = av_packet_new_side_data(pkt, AV_PKT_DATA_SUBTITLE_POSITION, 16);
                if (p) {
                    AV_WL32(p,      x1);
                    AV_WL32(p +  4, y1);
                    AV_WL32(p +  8, x2);
                    AV_WL32(p + 12, y2);
                }
            }
        }
    }
    return res;
}
Пример #11
0
static int stl_read_header(AVFormatContext *s)
{
    STLContext *stl = s->priv_data;
    AVStream *st = avformat_new_stream(s, NULL);

    if (!st)
        return AVERROR(ENOMEM);
    avpriv_set_pts_info(st, 64, 1, 100);
    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
    st->codec->codec_id   = AV_CODEC_ID_STL;

    while (!avio_feof(s->pb)) {
        char line[4096];
        char *p = line;
        const int64_t pos = avio_tell(s->pb);
        int len = ff_get_line(s->pb, line, sizeof(line));
        int64_t pts_start;
        int duration;

        if (!len)
            break;

        line[strcspn(line, "\r\n")] = 0;
        pts_start = get_pts(&p , &duration);

        if (pts_start != AV_NOPTS_VALUE) {
            AVPacket *sub;
            sub = ff_subtitles_queue_insert(&stl->q, p, strlen(p), 0);
            if (!sub)
                return AVERROR(ENOMEM);
            sub->pos = pos;
            sub->pts = pts_start;
            sub->duration = duration;
        }
    }
    ff_subtitles_queue_finalize(&stl->q);
    return 0;
}
Пример #12
0
int vid_event_wait_next(eventq_type_t * type, void **info)
{
    event_queue_t *ret = NULL;
    pthread_mutex_lock(&videvents_mutex);
    /* NB pts are clocked at 90kHz */
    while(ret == NULL)
    {
	unsigned int pts = get_pts();
	/*Anything less than 1 (NTSC) frame should count as now */
	unsigned int max_pts = pts + (PTS_HZ/30) -1;
	/*Assume anything less than 30 seconds behind us counts as now*/
	unsigned int seek_pts = pts - PTS_HZ*30;
	/*And anything more than 40 seconds ahead we don't really need to worry about*/
	unsigned int max_seek_pts = pts + PTS_HZ*40;
	event_queue_t *pCurrent = pNextEvent;
	event_queue_t *pStart;

	PRINTF("VEQ: Looking for a worthwhile elem: %p\n",pCurrent);
	if(pCurrent != NULL)
	{
	    /*Find first event after seek_pts and before max_seek_pts */
	    pStart = pCurrent;
	    /*First move to an element before seek_pts, if it exists */
	    while(pCurrent->pts >= seek_pts)
	    {
		pCurrent = pCurrent->pPrev;
		/*The smallest element is the best we can get. Even if it
		 * is greater than seek_pts, there's not going to be another
		 * one that is less.
		 */
		if(pCurrent->pPrev->pts > pCurrent->pts)
		    break;
		/*We went all the way around, probably only one item */
		if(pCurrent == pStart)
		    break;
	    }
	    pStart = pCurrent;
	    /* Now move forward to the first element after this that is
	     * >= seek_pts
	     */
	    while(pCurrent->pts < seek_pts)
	    {
		pCurrent = pCurrent->pNext;
		/*Numbers can't get any bigger if we're about to wrap
		 * around
		 */
		if(pCurrent->pNext->pts < pCurrent->pts)
		    break;
		/*We went all the way around, probably only one item */
		if(pCurrent == pStart)
		    break;
	    }

	    /*Check if the element we've found is between seek_pts and
	     * max_seek_pts
	     */
	    if(seek_pts > max_seek_pts)
	    {
		/* PTS is about to/has wrapped around, maths is a bit different */
		if(pCurrent->pts < seek_pts && pCurrent->pts > max_seek_pts)
		    pCurrent = NULL;
	    }
	    else
	    {
		if(pCurrent->pts < seek_pts || pCurrent->pts > max_seek_pts)
		    pCurrent = NULL;
	    }
	}
	/*Check if the element is before 1 frame from now, if that's the
	 * case then dispatch the event
	 */
	PRINTF("VEQ: Found elem: %p\n",pCurrent);
	if(pCurrent != NULL && (pCurrent->pts <= max_pts ||(seek_pts > max_pts && pCurrent->pts >= seek_pts)))
	{
	    ret = pCurrent;
	    PRINTF("VEQ: returning %p\n",ret);
	}
	else
	{
	    int to_wait;
	    struct timespec abstime;
	    /*Never wait any more than 10 seconds*/
	    int max_wait;
	    if(pts_discontinuity_count > 0)
	    {
		pts_discontinuity_count--;
		max_wait = VID_EVENT_DISCON_MAX_WAIT;
	    }
	    else
		max_wait = VID_EVENT_MAX_WAIT;
	    if(pCurrent != NULL)
	    {
		if(pCurrent->pts > pts)
		    to_wait = pCurrent->pts - pts;
		else
		    /* Bitwise not of pts is the same as 0xFFFFFFFF - pts */
		    to_wait = (~pts) + pCurrent->pts;

		/* Exponentially approach the pts we're after*/
		to_wait = (to_wait*8)/10;

		if(to_wait > max_wait)
		    to_wait = max_wait;
	    }
	    else
		to_wait = max_wait;


	    clock_gettime(CLOCK_REALTIME,&abstime);
	    abstime.tv_nsec += ((to_wait%PTS_HZ) *(1000000000/PTS_HZ));
	    while(abstime.tv_nsec >= 1000000000)
	    {
		abstime.tv_sec++;
		abstime.tv_nsec -= 1000000000;
	    }
	    abstime.tv_sec += to_wait/PTS_HZ;
	    PRINTF("VEQ: Waiting for %d pts clocks, until sec %lu\n",to_wait,(unsigned long)abstime.tv_sec);
	    pthread_cond_timedwait(&videvents_cond,&videvents_mutex,&abstime);
	    PRINTF("VEQ: I'm awake now...\n");
	}
	if(ret != NULL)
	{
	    PRINTF("Dispatching event for pts %x at pts %x (seek %x, seek_max %x)\n",ret->pts,pts,seek_pts,max_seek_pts);
	}
    }
    int retval;
    if(ret == NULL)
    {
	/* Shouldn't happen... */
	retval = -1;
    }
    else
    {
	*type = ret->type;
	*info = ret->info;
	if(ret->pNext == ret)
	{
	    /*1 item in the queue*/
	    pNextEvent = NULL;
	}
	else
	{
	    if(pNextEvent == ret)
		pNextEvent = ret->pNext;
	    ret->pPrev->pNext = ret->pNext;
	    ret->pNext->pPrev = ret->pPrev;
	}
	free(ret);
	retval = 0;
    }
    pthread_mutex_unlock(&videvents_mutex);
    return retval;
}
Пример #13
0
static void* reader_thread(void * /*arg*/)
{
	int fds[2];
	pipe(fds);
	fcntl(fds[0], F_SETFD, FD_CLOEXEC);
	fcntl(fds[0], F_SETFL, O_NONBLOCK);
	fcntl(fds[1], F_SETFD, FD_CLOEXEC);
	fcntl(fds[1], F_SETFL, O_NONBLOCK);
	flagFd = fds[1];
	uint8_t tmp[16];  /* actually 6 should be enough */
	int count;
	int len;
	uint16_t packlen;
	uint8_t* buf;
	bool bad_startcode = false;
	set_threadname("dvbsub:reader");

	dmx = new cDemux(0);
#if HAVE_TRIPLEDRAGON
	dmx->Open(DMX_PES_CHANNEL, NULL, 16*1024);
#else
	dmx->Open(DMX_PES_CHANNEL, NULL, 64*1024);
#endif

	while (reader_running) {
		if(dvbsub_stopped /*dvbsub_paused*/) {
			sub_debug.print(Debug::VERBOSE, "%s stopped\n", __FUNCTION__);
			dmx->Stop();

			pthread_mutex_lock(&packetMutex);
			pthread_cond_broadcast(&packetCond);
			pthread_mutex_unlock(&packetMutex);

			pthread_mutex_lock(&readerMutex );
			int ret = pthread_cond_wait(&readerCond, &readerMutex);
			pthread_mutex_unlock(&readerMutex);
			if (ret) {
				sub_debug.print(Debug::VERBOSE, "pthread_cond_timedwait fails with %d\n", ret);
			}
			if(!reader_running)
				break;
			dvbsub_stopped = 0;
			sub_debug.print(Debug::VERBOSE, "%s (re)started with pid 0x%x\n", __FUNCTION__, dvbsub_pid);
		}
		if(pid_change_req) {
			pid_change_req = 0;
			clear_queue();
			dmx->Stop();
			dmx->pesFilter(dvbsub_pid);
			dmx->Start();
			sub_debug.print(Debug::VERBOSE, "%s changed to pid 0x%x\n", __FUNCTION__, dvbsub_pid);
		}

		struct pollfd pfds[2];
		pfds[0].fd = fds[1];
		pfds[0].events = POLLIN;
		char _tmp[64];

#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE
		if (isEplayer) {
			poll(pfds, 1, -1);
			while (0 > read(pfds[0].fd, _tmp, sizeof(tmp)));
			continue;
		}
#endif

		pfds[1].fd = dmx->getFD();
		pfds[1].events = POLLIN;
		switch (poll(pfds, 2, -1)) {
			case 0:
			case -1:
				if (pfds[0].revents & POLLIN)
					while (0 > read(pfds[0].fd, _tmp, sizeof(tmp)));
				continue;
			default:
				if (pfds[0].revents & POLLIN)
					while (0 > read(pfds[0].fd, _tmp, sizeof(tmp)));
				if (!(pfds[1].revents & POLLIN))
					continue;
		}

		len = dmx->Read(tmp, 6, 0);
		if(len <= 0)
			continue;

		if(!memcmp(tmp, "\x00\x00\x01\xbe", 4)) { // padding stream
			packlen =  getbits(tmp, 4*8, 16) + 6;
			count = 6;
			buf = (uint8_t*) malloc(packlen);

			// actually, we're doing slightly too much here ...
			memmove(buf, tmp, 6);
			/* read rest of the packet */
			while((count < packlen) && !dvbsub_stopped) {
				len = dmx->Read(buf+count, packlen-count, 1000);
				if (len < 0) {
					break;
				} else {
					count += len;
				}
			}
			free(buf);
			buf = NULL;
			continue;
		}

		if(memcmp(tmp, "\x00\x00\x01\xbd", 4)) {
			if (!bad_startcode) {
				sub_debug.print(Debug::VERBOSE, "[subtitles] bad start code: %02x%02x%02x%02x\n", tmp[0], tmp[1], tmp[2], tmp[3]);
				bad_startcode = true;
			}
			continue;
		}
		bad_startcode = false;
		count = 6;

		packlen =  getbits(tmp, 4*8, 16) + 6;

		buf = (uint8_t*) malloc(packlen);

		memmove(buf, tmp, 6);
		/* read rest of the packet */
		while((count < packlen) && !dvbsub_stopped) {
			len = dmx->Read(buf+count, packlen-count, 1000);
			if (len < 0) {
				break;
			} else {
				count += len;
			}
		}
#if 0
		for(int i = 6; i < packlen - 4; i++) {
			if(!memcmp(&buf[i], "\x00\x00\x01\xbd", 4)) {
				int plen =  getbits(&buf[i], 4*8, 16) + 6;
				sub_debug.print(Debug::VERBOSE, "[subtitles] ******************* PES header at %d ?! *******************\n", i);
				sub_debug.print(Debug::VERBOSE, "[subtitles] start code: %02x%02x%02x%02x len %d\n", buf[i+0], buf[i+1], buf[i+2], buf[i+3], plen);
				free(buf);
				continue;
			}
		}
#endif

		if(!dvbsub_stopped /*!dvbsub_paused*/) {
			sub_debug.print(Debug::VERBOSE, "[subtitles] *** new packet, len %d buf 0x%x pts-stc diff %lld ***\n", count, buf, get_pts_stc_delta(get_pts(buf)));
			/* Packet now in memory */
			pthread_mutex_lock(&packetMutex);
			packet_queue.push(buf);
			/* TODO: allocation exception */
			// wake up dvb thread
			pthread_cond_broadcast(&packetCond);
			pthread_mutex_unlock(&packetMutex);
		} else {
			free(buf);
			buf=NULL;
		}
	}

	dmx->Stop();
	delete dmx;
	dmx = NULL;

	close(fds[0]);
	close(fds[1]);
	flagFd = -1;

	sub_debug.print(Debug::VERBOSE, "%s shutdown\n", __FUNCTION__);
	pthread_exit(NULL);
}
Пример #14
0
static int microdvd_read_header(AVFormatContext *s)
{
    AVRational pts_info = (AVRational){ 2997, 125 };  /* default: 23.976 fps */
    MicroDVDContext *microdvd = s->priv_data;
    AVStream *st = avformat_new_stream(s, NULL);
    int i = 0;
    char line[MAX_LINESIZE];

    if (!st)
        return AVERROR(ENOMEM);

    while (!url_feof(s->pb)) {
        char *p = line;
        AVPacket *sub;
        int64_t pos = avio_tell(s->pb);
        int len = ff_get_line(s->pb, line, sizeof(line));

        if (!len)
            break;
        line[strcspn(line, "\r\n")] = 0;
        if (i++ < 3) {
            int frame;
            double fps;
            char c;

            if ((sscanf(line, "{%d}{}%6lf",    &frame, &fps) == 2 ||
                 sscanf(line, "{%d}{%*d}%6lf", &frame, &fps) == 2)
                && frame <= 1 && fps > 3 && fps < 100)
                pts_info = av_d2q(fps, 100000);
            if (!st->codec->extradata && sscanf(line, "{DEFAULT}{}%c", &c) == 1) {
                st->codec->extradata = av_strdup(line + 11);
                if (!st->codec->extradata)
                    return AVERROR(ENOMEM);
                st->codec->extradata_size = strlen(st->codec->extradata) + 1;
                continue;
            }
        }
#define SKIP_FRAME_ID                                       \
    p = strchr(p, '}');                                     \
    if (!p) {                                               \
        av_log(s, AV_LOG_WARNING, "Invalid event \"%s\""    \
               " at line %d\n", line, i);                   \
        continue;                                           \
    }                                                       \
    p++
        SKIP_FRAME_ID;
        SKIP_FRAME_ID;
        if (!*p)
            continue;
        sub = ff_subtitles_queue_insert(&microdvd->q, p, strlen(p), 0);
        if (!sub)
            return AVERROR(ENOMEM);
        sub->pos = pos;
        sub->pts = get_pts(line);
        sub->duration = get_duration(line);
    }
    ff_subtitles_queue_finalize(&microdvd->q);
    avpriv_set_pts_info(st, 64, pts_info.den, pts_info.num);
    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
    st->codec->codec_id   = AV_CODEC_ID_MICRODVD;
    return 0;
}
Пример #15
0
void 
remove_nodes(Bface_list& flist, ARRAY<Wvec>& blist, double min_dist, ARRAY<OctreeNode*>& t)
{
//    if (flist.num() != blist.num()) {
//       return;
//    }
   assert(flist.num() == blist.num());
   Wpt_list pts = get_pts(flist, blist);
   ARRAY< ARRAY<int> > N;
   ARRAY<bool> to_remove;
   for (int i = 0; i < pts.num(); i++) {
      N += ARRAY<int>();
      to_remove += false;
   }

   for (int i = 0; i < pts.num(); i++) {
      for (int j = 0; j < t[i]->neibors().num(); j++) {
         int index = t[i]->neibors()[j]->get_term_index();
         
         if (index < pts.num())
         {
            if (pts[i].dist(pts[index]) < min_dist) {
               N[i] += index;
               N[index] += i;
            }
         }
         else
         {
            //cerr << "Sps Warning, index > pts.num()" << endl;
         }

      }
   }

   priority_queue< Priority, vector<Priority> > queue;
   ARRAY<int> versions;
   for (int i = 0; i < pts.num(); i++) {
      if (!to_remove[i] && !N[i].empty()) {
         Priority p;
         p._priority = center(pts, N[i]).dist(pts[i]);
         p._index = i;
         p._version = 0;
         queue.push(p);
      }
      versions += 0;
   }

   while (!queue.empty()) {
      Priority p = queue.top();
      queue.pop();
      int r = p._index;
      if (p._version == versions[r]) {
         to_remove[r] = true;
         for (int i = 0; i < N[r].num(); i++) {
            N[N[r][i]] -= r;
            versions[N[r][i]]++;
            if (!N[N[r][i]].empty()) {
               Priority q;
               q._priority = center(pts, N[N[r][i]]).dist(pts[N[r][i]]);
               q._index = N[r][i];
               q._version = versions[N[r][i]];
               queue.push(q);
            }
         }
      }
   }
   versions.clear();

   Bface_list ftemp(flist);
   ARRAY<Wvec> btemp(blist);
   flist.clear();
   blist.clear();
   for (int i = 0; i < ftemp.num(); i++)
      if (!to_remove[i]) {
         flist += ftemp[i];
         blist += btemp[i];
      }
}
Пример #16
0
static int read_header(AVFormatContext *s)
{
    int i, len, header_remaining;
    ASSContext *ass = s->priv_data;
    AVIOContext *pb = s->pb;
    AVStream *st;
    int allocated[2]= {0};
    uint8_t *p, **dst[2]= {0};
    int pos[2]= {0};

    st = avformat_new_stream(s, NULL);
    if (!st)
        return -1;
    avpriv_set_pts_info(st, 64, 1, 100);
    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
    st->codec->codec_id= AV_CODEC_ID_SSA;

    header_remaining= INT_MAX;
    dst[0] = &st->codec->extradata;
    dst[1] = &ass->event_buffer;
    while(!pb->eof_reached) {
        uint8_t line[MAX_LINESIZE];

        len = ff_get_line(pb, line, sizeof(line));

        if(!memcmp(line, "[Events]", 8))
            header_remaining= 2;
        else if(line[0]=='[')
            header_remaining= INT_MAX;

        i= header_remaining==0;

        if(i && get_pts(line) == AV_NOPTS_VALUE)
            continue;

        p = av_fast_realloc(*(dst[i]), &allocated[i], pos[i]+MAX_LINESIZE);
        if(!p)
            goto fail;
        *(dst[i])= p;
        memcpy(p + pos[i], line, len+1);
        pos[i] += len;
        if(i) ass->event_count++;
        else  header_remaining--;
    }
    st->codec->extradata_size= pos[0];

    if(ass->event_count >= UINT_MAX / sizeof(*ass->event))
        goto fail;

    ass->event= av_malloc(ass->event_count * sizeof(*ass->event));
    p= ass->event_buffer;
    for(i=0; i<ass->event_count; i++) {
        ass->event[i]= p;
        while(*p && *p != '\n')
            p++;
        p++;
    }

    qsort(ass->event, ass->event_count, sizeof(*ass->event), (void*)event_cmp);

    return 0;

fail:
    read_close(s);

    return -1;
}
Пример #17
0
static int event_cmp(uint8_t **a, uint8_t **b)
{
    return get_pts(*a) - get_pts(*b);
}
Пример #18
0
static int dhav_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    DHAVContext *dhav = s->priv_data;
    int64_t start;
    int ret;

    start = avio_tell(s->pb);

    while ((ret = read_chunk(s)) == 0)
        ;

    if (ret < 0)
        return ret;

    if (dhav->type == 0xfd && dhav->video_stream_index == -1) {
        AVStream *st = avformat_new_stream(s, NULL);
        DHAVStream *dst;

        if (!st)
            return AVERROR(ENOMEM);

        st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
        switch (dhav->video_codec) {
        case 0x1: st->codecpar->codec_id = AV_CODEC_ID_MPEG4; break;
        case 0x3: st->codecpar->codec_id = AV_CODEC_ID_MJPEG; break;
        case 0x2:
        case 0x4:
        case 0x8: st->codecpar->codec_id = AV_CODEC_ID_H264;  break;
        case 0xc: st->codecpar->codec_id = AV_CODEC_ID_HEVC;  break;
        default: avpriv_request_sample(s, "Unknown video codec %X\n", dhav->video_codec);
        }
        st->codecpar->width      = dhav->width;
        st->codecpar->height     = dhav->height;
        st->avg_frame_rate.num   = dhav->frame_rate;
        st->avg_frame_rate.den   = 1;
        st->priv_data = dst = av_mallocz(sizeof(DHAVStream));
        if (!st->priv_data)
            return AVERROR(ENOMEM);
        dst->last_timestamp = AV_NOPTS_VALUE;
        dhav->video_stream_index = st->index;

        avpriv_set_pts_info(st, 64, 1, 1000);
    } else if (dhav->type == 0xf0 && dhav->audio_stream_index == -1) {
        AVStream *st = avformat_new_stream(s, NULL);
        DHAVStream *dst;

        if (!st)
            return AVERROR(ENOMEM);

        st->codecpar->codec_type  = AVMEDIA_TYPE_AUDIO;
        switch (dhav->audio_codec) {
        case 0x07: st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;    break;
        case 0x0c: st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE; break;
        case 0x10: st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE; break;
        case 0x0a: st->codecpar->codec_id = AV_CODEC_ID_PCM_MULAW; break;
        case 0x16: st->codecpar->codec_id = AV_CODEC_ID_PCM_MULAW; break;
        case 0x0e: st->codecpar->codec_id = AV_CODEC_ID_PCM_ALAW;  break;
        case 0x1a: st->codecpar->codec_id = AV_CODEC_ID_AAC;       break;
        case 0x1f: st->codecpar->codec_id = AV_CODEC_ID_MP2;       break;
        case 0x21: st->codecpar->codec_id = AV_CODEC_ID_MP3;       break;
        case 0x0d: st->codecpar->codec_id = AV_CODEC_ID_ADPCM_MS;  break;
        default: avpriv_request_sample(s, "Unknown audio codec %X\n", dhav->audio_codec);
        }
        st->codecpar->channels    = dhav->audio_channels;
        st->codecpar->sample_rate = dhav->sample_rate;
        st->priv_data = dst = av_mallocz(sizeof(DHAVStream));
        if (!st->priv_data)
            return AVERROR(ENOMEM);
        dst->last_timestamp = AV_NOPTS_VALUE;
        dhav->audio_stream_index  = st->index;

        avpriv_set_pts_info(st, 64, 1, 1000);
    }

    ret = av_get_packet(s->pb, pkt, ret);
    if (ret < 0)
        return ret;
    pkt->stream_index = dhav->type == 0xf0 ? dhav->audio_stream_index : dhav->video_stream_index;
    if (dhav->type != 0xfc)
        pkt->flags   |= AV_PKT_FLAG_KEY;
    if (pkt->stream_index >= 0)
        pkt->pts = get_pts(s, s->streams[pkt->stream_index]->priv_data);
    pkt->duration = 1;
    pkt->pos = start;
    if (avio_rl32(s->pb) != MKTAG('d','h','a','v'))
        return AVERROR_INVALIDDATA;
    avio_skip(s->pb, 4);

    return ret;
}
Пример #19
0
static void* dvbsub_thread(void* /*arg*/)
{
	struct timespec restartWait;
	struct timeval now;

	sub_debug.print(Debug::VERBOSE, "%s started\n", __FUNCTION__);
	if (!dvbSubtitleConverter)
		dvbSubtitleConverter = new cDvbSubtitleConverter;

	int timeout = 1000000;
	while(dvbsub_running) 
	{
		uint8_t* packet;
		int64_t pts;
		int dataoffset;
		int packlen;

		gettimeofday(&now, NULL);

		int ret = 0;
		now.tv_usec += (timeout == 0) ? 1000000 : timeout;   // add the timeout
		while (now.tv_usec >= 1000000) 
		{   
			// take care of an overflow
			now.tv_sec++;
			now.tv_usec -= 1000000;
		}
		restartWait.tv_sec = now.tv_sec;          // seconds
		restartWait.tv_nsec = now.tv_usec * 1000; // nano seconds

		pthread_mutex_lock( &packetMutex );
		ret = pthread_cond_timedwait( &packetCond, &packetMutex, &restartWait );
		pthread_mutex_unlock( &packetMutex );

		timeout = dvbSubtitleConverter->Action();

		if(packet_queue.size() == 0) {
			continue;
		}
#if 1
		sub_debug.print(Debug::VERBOSE, "PES: Wakeup, queue size %d\n\n", packet_queue.size());
#endif
		if(dvbsub_stopped /*dvbsub_paused*/) 
		{
			clear_queue();
			continue;
		}

		pthread_mutex_lock(&packetMutex);
		packet = packet_queue.pop();
		pthread_mutex_unlock(&packetMutex);

		if (!packet) {
			sub_debug.print(Debug::VERBOSE, "Error no packet found\n");
			continue;
		}
		packlen = (packet[4] << 8 | packet[5]) + 6;

		pts = get_pts(packet);

		dataoffset = packet[8] + 8 + 1;
		if (packet[dataoffset] != 0x20) 
		{
#if 1
			sub_debug.print(Debug::VERBOSE, "Not a dvb subtitle packet, discard it (len %d)\n", packlen);

			for(int i = 0; i < packlen; i++)
				printf("%02X ", packet[i]);
			printf("\n");
#endif
			goto next_round;
		}

#if 1
		sub_debug.print(Debug::VERBOSE, "PES packet: len %d data len %d PTS=%Ld (%02d:%02d:%02d.%d) diff %lld\n", packlen, packlen - (dataoffset + 2), pts, (int)(pts/324000000), (int)((pts/5400000)%60), (int)((pts/90000)%60), (int)(pts%90000), get_pts_stc_delta(pts));
#endif

		if (packlen <= dataoffset + 3) 
		{
			sub_debug.print(Debug::INFO, "Packet too short, discard\n");
			
			goto next_round;
		}

		if (packet[dataoffset + 2] == 0x0f) 
		{
			dvbSubtitleConverter->Convert(&packet[dataoffset + 2], packlen - (dataoffset + 2), pts);
		} 
		else 
		{
			sub_debug.print(Debug::INFO, "End_of_PES is missing\n");
		}
		timeout = dvbSubtitleConverter->Action();

next_round:
		free(packet);
	}

	delete dvbSubtitleConverter;

	sub_debug.print(Debug::VERBOSE, "%s shutdown\n", __FUNCTION__);
	pthread_exit(NULL);
}
static int microdvd_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    MicroDVDContext *microdvd = s->priv_data;
    char buffer[MAX_LINESIZE];
    int64_t pos = avio_tell(s->pb);
    int i, len = 0, res = AVERROR_EOF;

    // last packet has its duration set but couldn't be raised earlier
    if (microdvd->last_pkt_ready) {
        *pkt = microdvd->last_pkt;
        microdvd->last_pkt_ready = 0;
        return 0;
    }

    for (i=0; i<FF_ARRAY_ELEMS(microdvd->lines); i++) {
        if (microdvd->lines[i][0]) {
            strcpy(buffer, microdvd->lines[i]);
            pos = microdvd->pos[i];
            len = strlen(buffer);
            microdvd->lines[i][0] = 0;
            break;
        }
    }
    if (!len)
        len = ff_get_line(s->pb, buffer, sizeof(buffer));

    if (microdvd->last_pkt.duration == -1 && !buffer[0]) {
        // if the previous subtitle line had no duration, last until the end of
        // the presentation
        microdvd->last_pkt.duration = 0;
        *pkt = microdvd->last_pkt;
        pkt->duration = -1;
        res = 0;
    } else if (buffer[0] && !(res = av_new_packet(pkt, len))) {
        memcpy(pkt->data, buffer, len);
        pkt->flags |= AV_PKT_FLAG_KEY;
        pkt->pos = pos;
        pkt->pts = pkt->dts = get_pts(buffer);

        if (pkt->pts != AV_NOPTS_VALUE) {
            pkt->duration = get_duration(buffer);
            if (microdvd->last_pkt.duration == -1) {
                // previous packet wasn't raised because it was lacking the
                // duration info, so set its duration with the new packet pts
                // and raise it
                AVPacket tmp_pkt;

                tmp_pkt = microdvd->last_pkt;
                tmp_pkt.duration = pkt->pts - tmp_pkt.pts;
                microdvd->last_pkt = *pkt;
                microdvd->last_pkt_ready = pkt->duration != -1;
                *pkt = tmp_pkt;
            } else if (pkt->duration == -1) {
                // no packet without duration queued, and current one is
                // lacking the duration info, we need to parse another subtitle
                // event.
                microdvd->last_pkt = *pkt;
                res = AVERROR(EAGAIN);
            }
        }
    }
    return res;
}
Пример #21
0
static int read_header(AVFormatContext *s, AVFormatParameters *ap)
{
    int i, header_remaining;
    ASSContext *ass = s->priv_data;
    ByteIOContext *pb = s->pb;
    AVStream *st;
    int allocated[2]={0};
    uint8_t *p, **dst[2]={0};
    int pos[2]={0};

    st = av_new_stream(s, 0);
    if (!st)
        return -1;
    av_set_pts_info(st, 64, 1, 100);
    st->codec->codec_type = CODEC_TYPE_SUBTITLE;
    st->codec->codec_id= CODEC_ID_SSA;

    header_remaining= INT_MAX;
    dst[0] = &st->codec->extradata;
    dst[1] = &ass->event_buffer;
    while(!url_feof(pb)){
        uint8_t line[MAX_LINESIZE];

        get_line(pb, line, sizeof(line));

        if(!memcmp(line, "[Events]", 8))
            header_remaining= 2;
        else if(line[0]=='[')
            header_remaining= INT_MAX;

        i= header_remaining==0;

        if(i && get_pts(line, NULL) == AV_NOPTS_VALUE)
            continue;

        p = av_fast_realloc(*(dst[i]), &allocated[i], pos[i]+MAX_LINESIZE);
        if(!p)
            goto fail;
        *(dst[i])= p;
        memcpy(p + pos[i], line, strlen(line)+1);
        pos[i] += strlen(line);
        if(i) ass->event_count++;
        else {
            header_remaining--;
#if 0
            if (!header_remaining) {
                /* write the header into extrada section */
                int len = url_ftell(pb);
                st->codec->extradata = av_mallocz(len + 1);
                st->codec->extradata_size = len;
                url_fseek(pb, 0, SEEK_SET);
                get_buffer(pb, st->codec->extradata, len);
            }
#endif
        }
    }
    st->codec->extradata_size= pos[0];

    if(ass->event_count >= UINT_MAX / sizeof(*ass->event))
        goto fail;

    ass->event= av_malloc(ass->event_count * sizeof(*ass->event));
    p= ass->event_buffer;
    for(i=0; i<ass->event_count; i++){
        ass->event[i].text= p;
        ass->event[i].start_time= get_pts(p, &ass->event[i].end_time);
        while(*p && *p != '\n')
            p++;
        p++;
    }

    qsort(ass->event, ass->event_count, sizeof(*ass->event), event_cmp);

    return 0;

fail:
    read_close(s);

    return -1;
}
Пример #22
0
static int event_cmp(const void *_a, const void *_b)
{
    const uint8_t *const *a = _a, *const *b = _b;
    return get_pts(*a) - get_pts(*b);
}