From 1099cec06b35a5b401a30fed9a13a5b448834b7e Mon Sep 17 00:00:00 2001 From: Comment Date: Mon, 20 May 2013 22:42:45 +0100 Subject: ffmpeg-fas --- ffmpeg-fas/seek_indices.c | 319 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 319 insertions(+) create mode 100644 ffmpeg-fas/seek_indices.c (limited to 'ffmpeg-fas/seek_indices.c') diff --git a/ffmpeg-fas/seek_indices.c b/ffmpeg-fas/seek_indices.c new file mode 100644 index 0000000..63d2b23 --- /dev/null +++ b/ffmpeg-fas/seek_indices.c @@ -0,0 +1,319 @@ +/***************************************************************************** + * Copyright 2008. Pittsburgh Pattern Recognition, Inc. + * + * This file is part of the Frame Accurate Seeking extension library to + * ffmpeg (ffmpeg-fas). + * + * ffmpeg-fas is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * The ffmpeg-fas library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ffmpeg-fas library. If not, see . + * + ******************************************************************************/ + +#include +#include +#include +#include + +#include "seek_indices.h" +#include "private_errors.h" + +/**** Defines *****************************************************************/ + +#define DEFAULT_INITIAL_SIZE 100 + +static seek_error_type private_show_error (const char *message, seek_error_type error); +static seek_error_type private_resize_table (seek_table_type *table, int new_size); + + +/* + * seek_init_table + */ + +int compare_seek_tables(seek_table_type t1, seek_table_type t2) +{ + int i; + + // printf("n_entries=(%d %d)\n", t1.num_entries, t2.num_entries); + + if (t1.num_entries != t2.num_entries) + return 0; + + if (t1.completed != t2.completed) + return 0; + + if (t1.num_frames != t2.num_frames) + return 0; + + for (i=0;inum_entries = 0; + table->num_frames = -1; + table->completed = seek_false; + + if (NULL == table || NULL == table->array) + return; + + free (table->array); + return; +} + +/* + * seek_copy_table + */ + +seek_table_type seek_copy_table (seek_table_type source) +{ + seek_table_type dest; + dest.num_entries = source.num_entries; + dest.num_frames = source.num_frames; + dest.completed = source.completed; + + if (NULL == source.array) + { + dest.array = NULL; + dest.allocated_size = 0; + return dest; + } + + dest.array = (seek_entry_type *)malloc (source.num_entries * sizeof(seek_entry_type)); + + if (NULL == dest.array) + { + dest.array = NULL; + dest.allocated_size = 0; + return dest; + } + + dest.allocated_size = source.num_entries; + + int i; + for (i=0;iarray) + return private_show_error("null or invalid seek table", seek_bad_argument); + + if (table->num_entries != 0) + if (table->array[table->num_entries - 1].display_index >= entry.display_index) + return seek_no_error; + + if (table->num_entries == table->allocated_size) + { + seek_error_type error = private_resize_table (table, table->num_entries * 2); + if (error != seek_no_error) + return private_show_error ("unable to resize seek table", error); + } + + table->array[table->num_entries] = entry; + table->num_entries++; + + return seek_no_error; +} + +/* + * seek_get_nearest_entry + */ + +seek_error_type seek_get_nearest_entry (seek_table_type *table, seek_entry_type *entry, int display_index, int offset) +{ + /* using offset>0 returns a modified seek_entry that sets the 'time-to-seek' to be $offset keyframes in the past. + */ + + if (NULL == table || NULL == table->array || table->num_entries <= 0) { + return private_show_error ("NULL or invalid seek table", seek_bad_argument); + } + + if (NULL == entry) { + return private_show_error ("NULL entry buffer (for return)", seek_bad_argument); + } + + if (display_index < table->array[0].display_index) + return private_show_error ("tried to seek to frame index before first frame", seek_bad_argument); + + int i; + for (i=0; i < table->num_entries; i++) + if (table->array[i].display_index > display_index) + break; + + i = i-1; + + if (iarray[i]; + (*entry).first_packet_dts = table->array[i-offset].first_packet_dts; + + return seek_no_error; +} + + +/* read raw file */ +seek_table_type read_table_file(char *name) +{ + seek_table_type ans = { NULL, 0, 0 }; + + FILE *table_file = fopen(name, "r"); + if (table_file == NULL) + return ans; + + int completed_flag; + fscanf(table_file, "%d %d %d\n", &ans.num_frames, &ans.num_entries, &completed_flag); + + if (completed_flag == 1) + ans.completed = seek_true; + else + ans.completed = seek_false; + + ans.allocated_size = ans.num_entries; + ans.array = malloc (ans.allocated_size * sizeof(seek_entry_type)); + + int i; + for (i=0;idisplay_index, entry->first_packet_dts, entry->last_packet_dts); + } + return seek_no_error; +} + +seek_error_type seek_show_table (seek_table_type table) +{ + seek_entry_type *entry; + int index; + + if (NULL == table.array || table.num_entries <= 0) { + return private_show_error ("NULL or invalid seek table", seek_bad_argument); + } + + int completed_flag = 0; + if (table.completed == seek_true) + completed_flag = 1; + + fprintf (stderr, "--- Seek Table Dump ---\n"); + fprintf (stderr, "n_frames: %d n_entries: %d completed: %d\n",table.num_frames, table.num_entries, completed_flag); + for (index = 0; index < table.num_entries; index++) + { + entry = &(table.array[index]); + + fprintf (stderr, " %04d --> %08lld (%08lld)\n", entry->display_index, entry->first_packet_dts, entry->last_packet_dts); + } + + fprintf (stderr, "-----------------------\n"); + + return seek_no_error; +} + +/* + * private_show_error + */ + +static seek_error_type private_show_error (const char *message, seek_error_type error) +{ + if (SHOW_ERROR_MESSAGES) + fprintf (stderr, " ===> seek_indices: %s\n", message); + + return error; +} + +/* + * private_resize_table + */ + +static seek_error_type private_resize_table (seek_table_type *table, int new_size) +{ + seek_entry_type *new_array = NULL; + + if (table == NULL || new_size < 0) { + return private_show_error ("invalid argument for private_resize_table()", seek_malloc_failed); + } + + new_array = (seek_entry_type *)malloc (sizeof (seek_entry_type) * new_size); + if (NULL == new_array) { + return private_show_error ("unable to allocate more space for table", seek_malloc_failed); + } + + memcpy (new_array, table->array, table->allocated_size * sizeof (seek_entry_type)); + free (table->array); + + table->allocated_size = new_size; + table->array = new_array; + + return seek_no_error; +} -- cgit v1.2.3