예제 #1
0
파일: ffmdec.c 프로젝트: JackDanger/libav
static void adjust_write_index(AVFormatContext *s)
{
    FFMContext *ffm = s->priv_data;
    AVIOContext *pb = s->pb;
    int64_t pts;
    //int64_t orig_write_index = ffm->write_index;
    int64_t pos_min, pos_max;
    int64_t pts_start;
    int64_t ptr = avio_tell(pb);


    pos_min = 0;
    pos_max = ffm->file_size - 2 * FFM_PACKET_SIZE;

    pts_start = get_dts(s, pos_min);

    pts = get_dts(s, pos_max);

    if (pts - 100000 > pts_start)
        goto end;

    ffm->write_index = FFM_PACKET_SIZE;

    pts_start = get_dts(s, pos_min);

    pts = get_dts(s, pos_max);

    if (pts - 100000 <= pts_start) {
        while (1) {
            int64_t newpos;
            int64_t newpts;

            newpos = ((pos_max + pos_min) / (2 * FFM_PACKET_SIZE)) * FFM_PACKET_SIZE;

            if (newpos == pos_min)
                break;

            newpts = get_dts(s, newpos);

            if (newpts - 100000 <= pts) {
                pos_max = newpos;
                pts = newpts;
            } else {
                pos_min = newpos;
            }
        }
        ffm->write_index += pos_max;
    }

 end:
    avio_seek(pb, ptr, SEEK_SET);
}
예제 #2
0
파일: ffmdec.c 프로젝트: JackDanger/libav
/* seek to a given time in the file. The file read pointer is
   positioned at or before pts. XXX: the following code is quite
   approximative */
static int ffm_seek(AVFormatContext *s, int stream_index, int64_t wanted_pts, int flags)
{
    FFMContext *ffm = s->priv_data;
    int64_t pos_min, pos_max, pos;
    int64_t pts_min, pts_max, pts;
    double pos1;

    av_dlog(s, "wanted_pts=%0.6f\n", wanted_pts / 1000000.0);
    /* find the position using linear interpolation (better than
       dichotomy in typical cases) */
    pos_min = FFM_PACKET_SIZE;
    pos_max = ffm->file_size - FFM_PACKET_SIZE;
    while (pos_min <= pos_max) {
        pts_min = get_dts(s, pos_min);
        pts_max = get_dts(s, pos_max);
        /* linear interpolation */
        pos1 = (double)(pos_max - pos_min) * (double)(wanted_pts - pts_min) /
            (double)(pts_max - pts_min);
        pos = (((int64_t)pos1) / FFM_PACKET_SIZE) * FFM_PACKET_SIZE;
        if (pos <= pos_min)
            pos = pos_min;
        else if (pos >= pos_max)
            pos = pos_max;
        pts = get_dts(s, pos);
        /* check if we are lucky */
        if (pts == wanted_pts) {
            goto found;
        } else if (pts > wanted_pts) {
            pos_max = pos - FFM_PACKET_SIZE;
        } else {
            pos_min = pos + FFM_PACKET_SIZE;
        }
    }
    pos = (flags & AVSEEK_FLAG_BACKWARD) ? pos_min : pos_max;

 found:
    if (ffm_seek1(s, pos) < 0)
        return -1;

    /* reset read state */
    ffm->read_state = READ_HEADER;
    ffm->packet_ptr = ffm->packet;
    ffm->packet_end = ffm->packet;
    ffm->first_packet = 1;

    return 0;
}
예제 #3
0
파일: reorder.c 프로젝트: Distrotech/libnut
void nut_write_frame_reorder(nut_context_tt * nut, const nut_packet_tt * p, const uint8_t * buf) {
	stream_context_tt * s = &nut->sc[p->stream];
	if (nut->stream_count < 2) { // do nothing
		nut_write_frame(nut, p, buf);
		return;
	}

	s->num_packets++;
	s->packets = nut->alloc->realloc(s->packets, s->num_packets * sizeof(reorder_packet_tt));
	s->packets[s->num_packets - 1].p = *p;
	s->packets[s->num_packets - 1].dts = get_dts(s->sh.decode_delay, s->reorder_pts_cache, p->pts);

	s->packets[s->num_packets - 1].buf = nut->alloc->malloc(p->len); // FIXME
	memcpy(s->packets[s->num_packets - 1].buf, buf, p->len);

	flushcheck_frames(nut);
}