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; }
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); }
/* * 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; }
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; }
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; }
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; }
/* * 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); }
void TIDELog::start_chunk() { finish_chunk(); current_chunk = new Chunk(++num_chunks, ftell(logfile)); writeCHUNK(); }
TIDELog::~TIDELog() { finish_chunk(); writeTIDE(); // update header fclose(logfile); }