/* This is a version of avi_writer_pop_chunk() that adds the finished chunk * to this AVI file's index, using the provided flags. */ static void avi_writer_pop_chunk_with_index (AviWriter *self, int index_flags) { IndexQueueEntry *new_entry = g_new(IndexQueueEntry, 1); ChunkStackEntry *current_chunk = self->chunk_stack->data; long current_offset = ftell(self->file); memcpy(new_entry->fourcc, current_chunk->fourcc, 5); new_entry->flags = index_flags; new_entry->offset = current_chunk->data_start - self->index_origin_offset - 4; new_entry->size = current_offset - current_chunk->data_start; g_queue_push_tail(self->index_queue, new_entry); avi_writer_pop_chunk(self); }
static void avi_writer_write_stream_header(AviWriter *self) { avi_writer_push_chunk(self, "strh"); /* data type: video stream */ write_fourcc(self->file, "vids"); /* data handler (video codec) */ write_fourcc(self->file, "DIB "); /* flags */ write_int32(self->file, 0); /* priority */ write_int16(self->file, 1); /* language */ write_int16(self->file, 0); /* initial frames */ write_int32(self->file, 0); /* scale followed by rate. For video streams, (rate/scale) is the frame rate. */ write_int32(self->file, RATE_SCALE); write_int32(self->file, self->frame_rate * RATE_SCALE); /* start */ write_int32(self->file, 0); /* length (we fill this in later) */ self->length_offset = ftell(self->file); write_int32(self->file, 0); /* suggested buffer size */ write_int32(self->file, self->width * self->height * 3 + 1024); /* quality */ write_int32(self->file, 10000); /* sample size */ write_int32(self->file, 0); /* frame position and size (left, top, right, bottom) */ write_int16(self->file, 0); write_int16(self->file, 0); write_int16(self->file, self->width - 1); write_int16(self->file, self->height - 1); avi_writer_pop_chunk(self); }
/* Write the "idx1" list, using the queued chunk positions from our index FIFO */ static void avi_writer_write_index(AviWriter *self) { IndexQueueEntry *current_entry; avi_writer_push_chunk(self, "idx1"); /* Write all IndexQueueEntry nodes, freeing them as we go */ while ((current_entry = g_queue_pop_head(self->index_queue))) { write_fourcc(self->file, current_entry->fourcc); write_int32(self->file, current_entry->flags); write_int32(self->file, current_entry->offset); write_int32(self->file, current_entry->size); g_free(current_entry); } avi_writer_pop_chunk(self); }
static void avi_writer_write_main_header(AviWriter *self) { avi_writer_push_chunk(self, "avih"); /* microseconds per frame */ write_int32(self->file, 1000000 / self->frame_rate); /* max bytes per second */ write_int32(self->file, 0); /* padding granularity */ write_int32(self->file, 0); /* flags (AVIF_* constants) */ write_int32(self->file, AVIF_HASINDEX); /* total frames (we fill this in later) */ self->frame_count_offset = ftell(self->file); write_int32(self->file, 0); /* inital frames */ write_int32(self->file, 0); /* number of streams */ write_int32(self->file, 1); /* suggested buffer size */ write_int32(self->file, self->width * self->height * 3 + 1024); /* width and height */ write_int32(self->file, self->width); write_int32(self->file, self->height); /* reserved (4) */ write_int32(self->file, 0); write_int32(self->file, 0); write_int32(self->file, 0); write_int32(self->file, 0); avi_writer_pop_chunk(self); }