Example #1
0
static int write_stream_data(AVFormatContext *s, AVStream *st, int flag)
{
    AVIOContext *pb = s->pb;
    int ret;

    if (!flag) {
        write_chunk_header2(s, &ff_stream_guid, 0x80000000 | (st->index + INDEX_BASE));
        avio_wl32(pb, 0x00000001);
        avio_wl32(pb, st->index + INDEX_BASE); //stream_id
        avio_wl32(pb, 0x00000001);
        write_pad(pb, 8);
    } else {
        write_chunk_header2(s, &ff_stream2_guid, 0x80000000 | (st->index + INDEX_BASE));
        write_pad(pb, 4);
    }

    ret = write_stream_codec_info(s, st);
    if (ret < 0) {
        av_log(s, AV_LOG_ERROR, "write stream codec info failed codec_type(0x%x)\n", st->codec->codec_type);
        return -1;
    }
    finish_chunk(s);

    avpriv_set_pts_info(st, 64, 1, 10000000);

    return 0;
}
Example #2
0
static void write_DSATTRIB_TRANSPORT_PROPERTIES_init(AVFormatContext *s, int stream_index)
{
    AVIOContext *pb = s->pb;
    write_chunk_header2(s, &ff_DSATTRIB_TRANSPORT_PROPERTIES, 0x80000000 | stream_index);
    avio_wl64(pb, stream_index);
    avio_wl64(pb, -1);
    avio_wl64(pb, 0);
    finish_chunk(s);
}
Example #3
0
/*
 * Iterative chunk inflation. Handles cases where we cross into a new
 * sequence, doing flush finish of previous chunk if needed.
 */
static size_t inflate_chunk(struct iolog_compress *ic, int gz_hdr, FILE *f,
			    z_stream *stream, struct inflate_chunk_iter *iter)
{
	size_t ret;

	dprint(FD_COMPRESS, "inflate chunk size=%lu, seq=%u",
				(unsigned long) ic->len, ic->seq);

	if (ic->seq != iter->seq) {
		if (iter->seq)
			finish_chunk(stream, f, iter);

		z_stream_init(stream, gz_hdr);
		iter->seq = ic->seq;
	}

	stream->avail_in = ic->len;
	stream->next_in = ic->buf;

	if (!iter->buf_size) {
		iter->buf_size = iter->chunk_sz;
		iter->buf = malloc(iter->buf_size);
	}

	while (stream->avail_in) {
		size_t this_out = iter->buf_size - iter->buf_used;
		int err;

		stream->avail_out = this_out;
		stream->next_out = iter->buf + iter->buf_used;

		err = inflate(stream, Z_NO_FLUSH);
		if (err < 0) {
			log_err("fio: failed inflating log: %d\n", err);
			iter->err = err;
			break;
		}

		iter->buf_used += this_out - stream->avail_out;

		if (!stream->avail_out) {
			iter->buf_size += iter->chunk_sz;
			iter->buf = realloc(iter->buf, iter->buf_size);
			continue;
		}

		if (err == Z_STREAM_END)
			break;
	}

	ret = (void *) stream->next_in - ic->buf;

	dprint(FD_COMPRESS, "inflated to size=%lu\n", (unsigned long) ret);

	return ret;
}
Example #4
0
static void write_sync(AVFormatContext *s)
{
    AVIOContext *pb = s->pb;
    WtvContext *wctx = s->priv_data;
    int64_t last_chunk_pos = wctx->last_chunk_pos;
    wctx->sync_pos = avio_tell(pb) - wctx->timeline_start_pos;

    write_chunk_header(s, &sync_guid, 0x18, 0);
    write_pad(pb, 24);

    finish_chunk(s);

    wctx->last_chunk_pos = last_chunk_pos;
}
Example #5
0
static void write_sync(AVFormatContext *s)
{
    AVIOContext *pb = s->pb;
    WtvContext *wctx = s->priv_data;
    int64_t last_chunk_pos = wctx->last_chunk_pos;

    write_chunk_header(s, &ff_sync_guid, 0x18, 0);
    avio_wl64(pb, wctx->first_index_pos);
    avio_wl64(pb, wctx->last_timestamp_pos);
    avio_wl64(pb, 0);

    finish_chunk(s);
    add_serial_pair(&wctx->sp_pairs, &wctx->nb_sp_pairs, wctx->serial, wctx->last_chunk_pos);

    wctx->last_chunk_pos = last_chunk_pos;
}
Example #6
0
static int write_stream_codec(AVFormatContext *s, AVStream * st)
{
    AVIOContext *pb = s->pb;
    int ret;
    write_chunk_header2(s, &ff_stream1_guid, 0x80000000 | 0x01);

    avio_wl32(pb,  0x01);
    write_pad(pb, 4);
    write_pad(pb, 4);

    ret = write_stream_codec_info(s, st);
    if (ret < 0) {
        av_log(s, AV_LOG_ERROR, "write stream codec info failed codec_type(0x%x)\n", st->codec->codec_type);
        return -1;
    }

    finish_chunk(s);
    return 0;
}
Example #7
0
/*
 * Inflate stored compressed chunks, or write them directly to the log
 * file if so instructed.
 */
static int inflate_gz_chunks(struct io_log *log, FILE *f)
{
	struct inflate_chunk_iter iter = { .chunk_sz = log->log_gz, };
	z_stream stream;

	while (!flist_empty(&log->chunk_list)) {
		struct iolog_compress *ic;

		ic = flist_first_entry(&log->chunk_list, struct iolog_compress, list);
		flist_del(&ic->list);

		if (log->log_gz_store) {
			size_t ret;

			dprint(FD_COMPRESS, "log write chunk size=%lu, "
				"seq=%u\n", (unsigned long) ic->len, ic->seq);

			ret = fwrite(ic->buf, ic->len, 1, f);
			if (ret != 1 || ferror(f)) {
				iter.err = errno;
				log_err("fio: error writing compressed log\n");
			}
		} else
			inflate_chunk(ic, log->log_gz_store, f, &stream, &iter);

		free_chunk(ic);
	}

	if (iter.seq) {
		finish_chunk(&stream, f, &iter);
		free(iter.buf);
	}

	return iter.err;
}

/*
 * Open compressed log file and decompress the stored chunks and
 * write them to stdout. The chunks are stored sequentially in the
 * file, so we iterate over them and do them one-by-one.
 */
int iolog_file_inflate(const char *file)
{
	struct inflate_chunk_iter iter = { .chunk_sz = 64 * 1024 * 1024, };
	struct iolog_compress ic;
	z_stream stream;
	struct stat sb;
	ssize_t ret;
	size_t total;
	void *buf;
	FILE *f;

	f = fopen(file, "r");
	if (!f) {
		perror("fopen");
		return 1;
	}

	if (stat(file, &sb) < 0) {
		fclose(f);
		perror("stat");
		return 1;
	}

	ic.buf = buf = malloc(sb.st_size);
	ic.len = sb.st_size;
	ic.seq = 1;

	ret = fread(ic.buf, ic.len, 1, f);
	if (ret < 0) {
		perror("fread");
		fclose(f);
		return 1;
	} else if (ret != 1) {
		log_err("fio: short read on reading log\n");
		fclose(f);
		return 1;
	}

	fclose(f);

	/*
	 * Each chunk will return Z_STREAM_END. We don't know how many
	 * chunks are in the file, so we just keep looping and incrementing
	 * the sequence number until we have consumed the whole compressed
	 * file.
	 */
	total = ic.len;
	do {
		size_t ret;

		ret = inflate_chunk(&ic,  1, stdout, &stream, &iter);
		total -= ret;
		if (!total)
			break;
		if (iter.err)
			break;

		ic.seq++;
		ic.len -= ret;
		ic.buf += ret;
	} while (1);

	if (iter.seq) {
		finish_chunk(&stream, stdout, &iter);
		free(iter.buf);
	}

	free(buf);
	return iter.err;
}

#else

static int inflate_gz_chunks(struct io_log *log, FILE *f)
{
	return 0;
}

int iolog_file_inflate(const char *file)
{
	log_err("fio: log inflation not possible without zlib\n");
	return 1;
}

#endif

void flush_log(struct io_log *log)
{
	void *buf;
	FILE *f;

	f = fopen(log->filename, "w");
	if (!f) {
		perror("fopen log");
		return;
	}

	buf = set_file_buffer(f);

	inflate_gz_chunks(log, f);

	flush_samples(f, log->log, log->nr_samples * log_entry_sz(log));

	fclose(f);
	clear_file_buffer(buf);
}
Example #8
0
 void TIDELog::start_chunk() {
     finish_chunk();
     current_chunk = new Chunk(++num_chunks, ftell(logfile));
     writeCHUNK();
 }
Example #9
0
 TIDELog::~TIDELog() {
     finish_chunk();
     writeTIDE(); // update header
     fclose(logfile);
 }