summaryrefslogtreecommitdiff
path: root/ffmpeg-fas/test
diff options
context:
space:
mode:
authorTim Redfern <tim@eclectronics.org>2013-09-05 17:57:22 +0100
committerTim Redfern <tim@eclectronics.org>2013-09-05 17:57:22 +0100
commit8992cb1d0d07edc33d274f6d7924ecdf6f83d994 (patch)
tree3a2c86846b7eec8137c1507e623fc7018f13d453 /ffmpeg-fas/test
parent741fb4b9e135cfb161a749db88713229038577bb (diff)
making act segmenter
Diffstat (limited to 'ffmpeg-fas/test')
-rwxr-xr-xffmpeg-fas/test/build.sh7
-rw-r--r--ffmpeg-fas/test/dump_frames.c67
-rw-r--r--ffmpeg-fas/test/dump_keyframes.c76
-rw-r--r--ffmpeg-fas/test/external_seek_test.c172
-rw-r--r--ffmpeg-fas/test/generate_seek_table.c209
-rw-r--r--ffmpeg-fas/test/movie_info.c81
-rwxr-xr-xffmpeg-fas/test/run_test.py56
-rw-r--r--ffmpeg-fas/test/seek_test.c162
-rw-r--r--ffmpeg-fas/test/show_seek_table.c59
-rw-r--r--ffmpeg-fas/test/test_support.h67
10 files changed, 956 insertions, 0 deletions
diff --git a/ffmpeg-fas/test/build.sh b/ffmpeg-fas/test/build.sh
new file mode 100755
index 0000000..d00dd63
--- /dev/null
+++ b/ffmpeg-fas/test/build.sh
@@ -0,0 +1,7 @@
+LINK="../lib/libffmpeg_fas.so -lm -lz "
+gcc dump_frames.c -I.. $LINK -o dump_frames
+gcc dump_keyframes.c -I.. $LINK -o dump_keyframes
+gcc show_seek_table.c -I.. $LINK -o show_seek_table
+gcc seek_test.c -I.. $LINK -o seek_test
+gcc external_seek_test.c -I.. $LINK -o external_seek_test
+gcc generate_seek_table.c -I.. -I../ffmpeg/ ../ffmpeg/libavformat/libavformat.a ../ffmpeg/libavutil/libavutil.a ../ffmpeg/libavcodec/libavcodec.a -lm -lz ../lib/libffmpeg_fas.so -o generate_seek_table \ No newline at end of file
diff --git a/ffmpeg-fas/test/dump_frames.c b/ffmpeg-fas/test/dump_frames.c
new file mode 100644
index 0000000..ee9406b
--- /dev/null
+++ b/ffmpeg-fas/test/dump_frames.c
@@ -0,0 +1,67 @@
+/*****************************************************************************
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ ******************************************************************************/
+
+#include "ffmpeg_fas.h"
+#include "test_support.h"
+#include <stdio.h>
+
+int main (int argc, char **argv)
+{
+ char filename_buffer [255];
+
+ fas_error_type video_error;
+ fas_context_ref_type context;
+ fas_raw_image_type image_buffer;
+
+ if (argc < 2) {
+ fprintf (stderr, "usage: %s <video_file>\n", argv[0]);
+ return -1;
+ }
+
+ fas_initialize (FAS_FALSE, FAS_RGB24);
+
+ fprintf(stderr, "%s : ",argv[1]);
+ video_error = fas_open_video (&context, argv[1]);
+ if (video_error != FAS_SUCCESS)
+ fail("failed to open\n");
+
+ int counter = 0;
+ while (fas_frame_available (context))
+ {
+
+ if (FAS_SUCCESS != fas_get_frame (context, &image_buffer))
+ fail("failed on rgb image\n");
+
+ char filename[50];
+ sprintf(filename, "frame_%04d.ppm", counter);
+
+ fprintf(stderr, "Writing %s (counter=%d frame_index=%d)\n", filename, counter, fas_get_frame_index(context));
+ ppm_save(&image_buffer, filename);
+
+ fas_free_frame (image_buffer);
+
+ video_error = fas_step_forward (context);
+ counter++;
+ }
+
+ success();
+
+}
diff --git a/ffmpeg-fas/test/dump_keyframes.c b/ffmpeg-fas/test/dump_keyframes.c
new file mode 100644
index 0000000..61eba5c
--- /dev/null
+++ b/ffmpeg-fas/test/dump_keyframes.c
@@ -0,0 +1,76 @@
+/*****************************************************************************
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ ******************************************************************************/
+
+#include "ffmpeg_fas.h"
+#include "seek_indices.h"
+#include "test_support.h"
+#include <stdio.h>
+
+int main (int argc, char **argv)
+{
+ fas_error_type video_error;
+ fas_context_ref_type context, seek_context;
+
+ if (argc < 3) {
+ fprintf (stderr, "usage: %s <video_file> <seek_table>\n", argv[0]);
+ fail("arguments\n");
+ }
+
+ seek_table_type table = read_table_file(argv[2]);
+ if (table.num_entries == 0)
+ fail("bad table\n");
+
+ fas_initialize (FAS_TRUE, FAS_RGB24);
+
+ video_error = fas_open_video (&context, argv[1]);
+ if (video_error != FAS_SUCCESS) fail("fail on open\n");
+
+ video_error = fas_put_seek_table(context, table);
+ if (video_error != FAS_SUCCESS) fail("fail on put_seek_table\n");
+
+ video_error = fas_open_video (&seek_context, argv[1]);
+ if (video_error != FAS_SUCCESS) fail("fail on open\n");
+
+ int i;
+ for(i=0;i<table.num_entries;i++)
+ {
+ // int frame_index = table.array[table.num_entries - i - 1].display_index;
+ int frame_index = table.array[i].display_index;
+ if (FAS_SUCCESS != fas_seek_to_frame(context, frame_index))
+ fail("failed on seek");
+
+ fas_raw_image_type image_buffer;
+
+ if (FAS_SUCCESS != fas_get_frame (context, &image_buffer))
+ fail("failed on rgb image\n");
+
+ char filename[50];
+ sprintf(filename, "frame_%04d.ppm", frame_index);
+
+ fprintf(stderr, "Writing %s (seek_table_value=%d frame_index=%d)\n", filename, frame_index, fas_get_frame_index(context));
+ ppm_save(&image_buffer, filename);
+
+ fas_free_frame (image_buffer);
+ }
+
+ success();
+}
+
diff --git a/ffmpeg-fas/test/external_seek_test.c b/ffmpeg-fas/test/external_seek_test.c
new file mode 100644
index 0000000..ee903ba
--- /dev/null
+++ b/ffmpeg-fas/test/external_seek_test.c
@@ -0,0 +1,172 @@
+/*****************************************************************************
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ ******************************************************************************/
+
+/* test seek using external table */
+
+#include "ffmpeg_fas.h"
+#include "seek_indices.h"
+#include "test_support.h"
+#include <stdio.h>
+
+#define TEST_SET_SIZE 1000
+#define N_ITERATIONS 500
+
+int compare_frames(fas_raw_image_type img1, fas_raw_image_type img2)
+{
+ // printf("(%d %d) (%d %d) (%d %d) (%d %d)\n", img1.width, img2.width,
+ // img1.height, img2.height,
+ // img1.bytes_per_line, img2.bytes_per_line,
+ // img1.color_space, img2.color_space);
+
+ if ((img1.width != img2.width) ||
+ (img1.height != img2.height) ||
+ (img1.bytes_per_line != img2.bytes_per_line) ||
+ (img1.color_space != img2.color_space))
+ return 0;
+
+ int i,j;
+ int mask = 0;
+
+ for (i=0;i<img1.height;i++)
+ for(j=0;j<img1.bytes_per_line;j++)
+ {
+ //printf("%d ", (img1.data[i*img1.bytes_per_line+j] - img2.data[i*img1.bytes_per_line+j+j]));
+ mask |= (img1.data[i*img1.bytes_per_line+j] - img2.data[i*img1.bytes_per_line+j]);
+ }
+
+ if (mask == 0)
+ return 1;
+ else
+ return 0;
+}
+
+void do_random_test(fas_context_ref_type context, int start, int stop, int count)
+{
+ // printf ("start: %d stop: %d\n", start, stop );
+
+ while (fas_get_frame_index(context) < start)
+ if (FAS_SUCCESS != fas_step_forward(context))
+ fail("failed on advancement\n");
+
+ fas_raw_image_type *ref_frames = malloc( (stop - start + 1)* sizeof(fas_raw_image_type));
+
+ int i;
+ fas_error_type video_error;
+
+ while (fas_get_frame_index(context) <= stop)
+ {
+ i = fas_get_frame_index(context) - start;
+
+ video_error = fas_get_frame(context, &(ref_frames[i]));
+ if (video_error != FAS_SUCCESS) fail("fail on test(1)\n");
+
+ video_error = fas_step_forward(context);
+ if (video_error != FAS_SUCCESS) fail("fail on test(2)\n");
+
+ }
+
+ int index = -1;
+ int prev_index;
+
+ for (i=0;i<count;i++)
+ {
+ int offset = random() % (stop - start + 1);
+ prev_index = index;
+ index = start + offset;
+
+ video_error = fas_seek_to_frame(context, index);
+ if (video_error != FAS_SUCCESS) fail("fail on test(seek)\n");
+
+
+ fas_raw_image_type test_frame;
+ video_error = fas_get_frame(context, &test_frame);
+ if (video_error != FAS_SUCCESS) fail("fail on test(seek2)\n");
+
+ // printf("offset: %d / %d\n", offset, stop - start + 1);
+
+ if (!compare_frames(test_frame, ref_frames[offset]))
+ {
+ char buffer[70];
+
+ sprintf(buffer, "fail-%d-test.ppm", index);
+ ppm_save(&test_frame, buffer);
+ sprintf(buffer, "fail-%d-ref.ppm", index);
+ ppm_save(&ref_frames[offset], buffer);
+ sprintf(buffer, "failed on compare after seeking (%d->%d)\n", prev_index, index);
+
+ fail(buffer);
+ }
+
+ fas_free_frame(test_frame);
+ }
+
+ for (i=0;i<stop - start + 1;i++)
+ free(ref_frames[i].data);
+
+ free(ref_frames);
+}
+
+int main (int argc, char **argv)
+{
+ fas_error_type video_error;
+ fas_context_ref_type context;
+
+ if (argc < 3) {
+ fprintf (stderr, "usage: %s <video_file> <seek_table>\n", argv[0]);
+ fail("arguments\n");
+ }
+
+ fprintf(stderr, "%s : ", argv[1]);
+
+ seek_table_type table = read_table_file(argv[2]);
+ if (table.num_entries == 0)
+ fail("bad table\n");
+
+ fas_initialize (FAS_FALSE, FAS_RGB24);
+
+ video_error = fas_open_video (&context, argv[1]);
+ if (video_error != FAS_SUCCESS) fail("fail on open\n");
+
+ video_error = fas_put_seek_table(context, table);
+ if (video_error != FAS_SUCCESS) fail("fail on put_seek_table\n");
+
+ if (fas_get_frame_count(context) < 0)
+ fail("n_frames = -1\n");
+
+ if (fas_get_frame_count(context) < TEST_SET_SIZE)
+ do_random_test(context, 0, fas_get_frame_count(context) - 1, N_ITERATIONS);
+ else if (fas_get_frame_count(context) < TEST_SET_SIZE * 2)
+ {
+ do_random_test(context, 0, fas_get_frame_count(context) / 2 - 1, N_ITERATIONS / 2);
+ do_random_test(context, fas_get_frame_count(context) / 2 + 1, fas_get_frame_count(context) - 1 , N_ITERATIONS / 2);
+ }
+ else
+ {
+ do_random_test(context, 0, TEST_SET_SIZE, N_ITERATIONS / 2);
+ do_random_test(context, fas_get_frame_count(context) - TEST_SET_SIZE, fas_get_frame_count(context) - 1 , N_ITERATIONS / 2);
+ }
+
+ seek_release_table(&table);
+ fas_close_video(context);
+
+ success();
+}
+
diff --git a/ffmpeg-fas/test/generate_seek_table.c b/ffmpeg-fas/test/generate_seek_table.c
new file mode 100644
index 0000000..5549f57
--- /dev/null
+++ b/ffmpeg-fas/test/generate_seek_table.c
@@ -0,0 +1,209 @@
+/*****************************************************************************
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ ******************************************************************************/
+
+#include "libavcodec/avcodec.h"
+#include "libavformat/avformat.h"
+#include <stdio.h>
+#include <string.h>
+#include "seek_indices.h"
+
+/* This executable is used for creating experimental seek tables.
+ The show_seek_table executable will show the seek-table as ffmpeg_fas
+ currently creates them.
+ */
+
+int main (int argc, char **argv)
+{
+ av_log_level = AV_LOG_QUIET;
+
+ if (argc < 2) {
+ fprintf (stderr, "usage: %s <video_file>\n", argv[0]);
+ return -1;
+ }
+
+ av_register_all();
+
+ AVFormatContext *pFormatCtx;
+ if (av_open_input_file(&pFormatCtx, argv[1], NULL, 0, NULL) !=0)
+ return -1;
+
+ if (av_find_stream_info(pFormatCtx)<0)
+ return -1;
+
+ unsigned int stream_id = -1;
+ unsigned int i;
+
+ for (i = 0; i < pFormatCtx->nb_streams; i++)
+ if (pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO)
+ {
+ stream_id = i;
+ break;
+ }
+
+ if (stream_id == -1)
+ return -1;
+
+ AVCodecContext *pCodecCtx = pFormatCtx->streams[stream_id]->codec;
+ AVCodec *pCodec;
+ pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
+ if (pCodec==NULL)
+ return -1;
+
+ if (avcodec_open(pCodecCtx, pCodec)<0)
+ return -1;
+
+
+ // printf("\n%s \n",argv[1]);
+
+ AVPacket Packet;
+ int count = 0;
+ int key_packets = 0;
+ int non_key_packets = 0;
+
+ int frame_count = 0;
+ int key_frames = 0;
+ int non_key_frames = 0;
+
+ AVFrame *pFrame;
+ pFrame=avcodec_alloc_frame();
+ int frameFinished;
+
+ seek_table_type table;
+ table = seek_init_table (16);
+ seek_entry_type entry;
+
+ int64_t key_packet_dts;
+ int64_t prev_packet_dts = AV_NOPTS_VALUE;
+ int64_t first_packet_dts; /* ensure first keyframe gets first packet */
+
+ int is_first_packet = 1;
+ int frames_have_label = 1;
+
+ // const char *format_name = pFormatCtx->iformat->name;
+ // const char *codec_name = pFormatCtx->streams[stream_id]->codec->codec->name;
+
+
+ /* these avi formats do not have labeled keyframes (the packets are labeled only and the packets and keyframe align 1-to-1 */
+ /* DISABLING THIS TYPE OF GENERATION (these videos will be unseekable) */
+ // fprintf(stderr, "format: (%s) codec: (%s)\n", format_name, codec_name);
+/*
+ * if (!strcmp(format_name, "avi"))
+ * if (!strcmp(codec_name, "aasc") ||
+ * !strcmp(codec_name, "camtasia") ||
+ * !strcmp(codec_name, "cinepak") ||
+ * !strcmp(codec_name, "cyuv") ||
+ * !strcmp(codec_name, "huffyuv") ||
+ * !strcmp(codec_name, "indeo2") ||
+ * !strcmp(codec_name, "indeo3") ||
+ * !strcmp(codec_name, "msrle") ||
+ * !strcmp(codec_name, "msvideo1") ||
+ * !strcmp(codec_name, "mszh") ||
+ * !strcmp(codec_name, "qpeg") ||
+ * !strcmp(codec_name, "truemotion1") ||
+ * !strcmp(codec_name, "ultimotion") ||
+ * !strcmp(codec_name, "vp3") ||
+ * !strcmp(codec_name, "zlib"))
+ * frames_have_label = 0;
+ */
+
+ while (av_read_frame(pFormatCtx, &Packet) >= 0)
+ {
+ if (Packet.stream_index == stream_id)
+ {
+ // fprintf(stderr, "Packet: (P%d: %lld %lld %d)\n", count, Packet.pts, Packet.dts, Packet.flags);
+ if ((Packet.flags & PKT_FLAG_KEY) || is_first_packet )
+ {
+ /* when keyframes overlap in the stream, that means multiple packets labeled 'keyframe' will arrive before
+ the keyframe itself. this results in wrong assignments all around, but only the first one needs to be right.
+ for all the rest, the seek-code will rewind to the previous keyframe to get them right.
+ */
+ if (is_first_packet)
+ {
+ first_packet_dts = Packet.dts;
+ is_first_packet = 0;
+ }
+
+ // fprintf(stderr, "Packet: (P%d: %lld %lld)\n", count, Packet.pts, Packet.dts);
+
+ /* first keyframe gets own dts, others get previous packet's dts.. this is workaround for some mpegs */
+ /* sometimes you need the previous packet from the supposed keyframe packet to get a frame back that is */
+ /* actually a keyframe */
+
+ if (prev_packet_dts == AV_NOPTS_VALUE)
+ key_packet_dts = Packet.dts;
+ else
+ key_packet_dts = prev_packet_dts;
+
+ if (Packet.flags & PKT_FLAG_KEY)
+ key_packets++;
+ else
+ non_key_packets++;
+ }
+ else
+ non_key_packets++;
+
+
+ avcodec_decode_video(pCodecCtx, pFrame, &frameFinished, Packet.data, Packet.size);
+
+ if (frameFinished)
+ {
+
+ // fprintf(stderr, "Frame : (P%d F%d: %lld %lld L:%d)\n", count, frame_count, Packet.pts, Packet.dts, pFrame->key_frame);
+ if ((pFrame->key_frame && frames_have_label) || ((Packet.flags & PKT_FLAG_KEY) && !frames_have_label))
+ {
+ key_frames++;
+
+ entry.display_index = frame_count;
+ entry.first_packet_dts = key_packet_dts;
+ entry.last_packet_dts = Packet.dts;
+
+ /* ensure first keyframe gets first packet dts */
+ if (frame_count == 0)
+ entry.first_packet_dts = first_packet_dts;
+
+ seek_append_table_entry(&table, entry);
+
+ // fprintf(stderr, "Frame : (P%d F%d: %lld %lld)\n", count, frame_count, Packet.pts, Packet.dts);
+ }
+ else
+ non_key_frames++;
+ frame_count++;
+ }
+
+ count++;
+ prev_packet_dts = Packet.dts;
+ }
+
+ av_free_packet(&Packet);
+ }
+
+ // printf("\n");
+
+ fprintf (stderr, "Packets: key: %d nonkey: %d total: %d\n", key_packets, non_key_packets, count);
+ fprintf (stderr, "Frames : key: %d nonkey: %d total: %d\n", key_frames, non_key_frames, frame_count);
+
+ table.completed = seek_true;
+ table.num_frames = frame_count;
+
+ seek_show_raw_table(stdout, table);
+
+ return 1;
+}
diff --git a/ffmpeg-fas/test/movie_info.c b/ffmpeg-fas/test/movie_info.c
new file mode 100644
index 0000000..f7bf40e
--- /dev/null
+++ b/ffmpeg-fas/test/movie_info.c
@@ -0,0 +1,81 @@
+/*****************************************************************************
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ ******************************************************************************/
+
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+
+#include <stdio.h>
+
+int main(int argc, char *argv[]) {
+ AVFormatContext *pFormatCtx;
+ int i, videoStream;
+ AVCodecContext *pCodecCtx;
+ AVCodec *pCodec;
+ AVFrame *pFrame;
+ AVFrame *pFrameRGB;
+ AVPacket packet;
+ int frameFinished;
+ int numBytes;
+ uint8_t *buffer;
+
+ if(argc < 2) {
+ printf("Please provide a movie file\n");
+ return -1;
+ }
+ // Register all formats and codecs
+ av_register_all();
+
+ // Open video file
+ if(av_open_input_file(&pFormatCtx, argv[1], NULL, 0, NULL)!=0)
+ return -1; // Couldn't open file
+
+ // Retrieve stream information
+ if(av_find_stream_info(pFormatCtx)<0)
+ return -1; // Couldn't find stream information
+
+ // Dump information about file onto standard error
+ dump_format(pFormatCtx, 0, argv[1], 0);
+
+ // Find the first video stream
+ videoStream=-1;
+ for(i=0; i<pFormatCtx->nb_streams; i++)
+ if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) {
+ videoStream=i;
+ break;
+ }
+ if(videoStream==-1)
+ return -1; // Didn't find a video stream
+
+ // Get a pointer to the codec context for the video stream
+ pCodecCtx=pFormatCtx->streams[videoStream]->codec;
+
+ // Find the decoder for the video stream
+ pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
+ if(pCodec==NULL) {
+ fprintf(stderr, "Unsupported codec!\n");
+ return -1; // Codec not found
+ }
+ // Open codec
+ if(avcodec_open(pCodecCtx, pCodec)<0)
+ return -1; // Could not open codec
+
+ return 0;
+}
diff --git a/ffmpeg-fas/test/run_test.py b/ffmpeg-fas/test/run_test.py
new file mode 100755
index 0000000..38dbb21
--- /dev/null
+++ b/ffmpeg-fas/test/run_test.py
@@ -0,0 +1,56 @@
+#!/usr/bin/python
+
+import sys
+import os
+
+def readFilelist(filename):
+ try:
+ f = open(filename, 'r')
+ except:
+ return []
+ return [ele[:-1] for ele in f.readlines()]
+
+def create_filter_func(cmd, log_file):
+ if log_file == "":
+ return lambda filename : 0 == os.system(cmd + " " + filename)
+ else:
+ return lambda filename : 0 == os.system(cmd + " " + filename + " 2>> " + log_file)
+
+def write_filelist(files, filename):
+ f = open(filename, 'w')
+ for arg in files:
+ f.write(arg + '\n')
+ f.close()
+
+if __name__ == "__main__":
+ if len(sys.argv) < 3 or len(sys.argv) > 4:
+ print "Usage: " + sys.argv[0] + " <test_executable> <file_list>"
+ raise SystemExit
+
+
+ if not os.path.isfile(sys.argv[1]):
+ print sys.argv[1] + " not found"
+ raise SystemExit
+
+ cmd = sys.argv[1]
+ base_name = cmd.split('/')[-1]
+
+ success_file = base_name + ".pass"
+ fail_file = base_name + ".fail"
+
+ if len(sys.argv) == 4:
+ log_file = sys.argv[3]
+ if os.path.isfile(log_file):
+ os.system("rm " + log_file)
+ else:
+ log_file = ""
+
+ files = readFilelist(sys.argv[2])
+
+ filterfunc = create_filter_func(cmd, log_file)
+ successful = filter(filterfunc, files)
+ failed = list(set(files) - set(successful))
+
+ write_filelist(failed, fail_file)
+ write_filelist(successful, success_file)
+
diff --git a/ffmpeg-fas/test/seek_test.c b/ffmpeg-fas/test/seek_test.c
new file mode 100644
index 0000000..b145447
--- /dev/null
+++ b/ffmpeg-fas/test/seek_test.c
@@ -0,0 +1,162 @@
+/*****************************************************************************
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ ******************************************************************************/
+
+#include "ffmpeg_fas.h"
+#include "seek_indices.h"
+#include "test_support.h"
+#include <stdio.h>
+
+#define TEST_SET_SIZE 1000
+#define N_ITERATIONS 500
+
+int compare_frames(fas_raw_image_type img1, fas_raw_image_type img2)
+{
+ // printf("(%d %d) (%d %d) (%d %d) (%d %d)\n", img1.width, img2.width,
+ // img1.height, img2.height,
+ // img1.bytes_per_line, img2.bytes_per_line,
+ // img1.color_space, img2.color_space);
+
+ if ((img1.width != img2.width) ||
+ (img1.height != img2.height) ||
+ (img1.bytes_per_line != img2.bytes_per_line) ||
+ (img1.color_space != img2.color_space))
+ return 0;
+
+ int i,j;
+ int mask = 0;
+
+ for (i=0;i<img1.height;i++)
+ for(j=0;j<img1.bytes_per_line;j++)
+ {
+ //printf("%d ", (img1.data[i*img1.bytes_per_line+j] - img2.data[i*img1.bytes_per_line+j+j]));
+ mask |= (img1.data[i*img1.bytes_per_line+j] - img2.data[i*img1.bytes_per_line+j]);
+ }
+
+ if (mask == 0)
+ return 1;
+ else
+ return 0;
+}
+
+void do_random_test(fas_context_ref_type context, int start, int stop, int count)
+{
+ // printf ("start: %d stop: %d\n", start, stop );
+
+ while (fas_get_frame_index(context) < start)
+ if (FAS_SUCCESS != fas_step_forward(context))
+ fail("failed on advancement\n");
+
+ fas_raw_image_type *ref_frames = malloc( (stop - start + 1)* sizeof(fas_raw_image_type));
+
+ int i;
+ fas_error_type video_error;
+
+ while (fas_get_frame_index(context) <= stop)
+ {
+ i = fas_get_frame_index(context) - start;
+
+ video_error = fas_get_frame(context, &(ref_frames[i]));
+ if (video_error != FAS_SUCCESS) fail("fail on test(1)\n");
+
+ video_error = fas_step_forward(context);
+ if (video_error != FAS_SUCCESS) fail("fail on test(2)\n");
+
+ }
+
+ int index = -1;
+ int prev_index;
+
+ for (i=0;i<count;i++)
+ {
+ int offset = random() % (stop - start + 1);
+ prev_index = index;
+ index = start + offset;
+
+ video_error = fas_seek_to_frame(context, index);
+ if (video_error != FAS_SUCCESS) fail("fail on test(seek)\n");
+
+
+ fas_raw_image_type test_frame;
+ video_error = fas_get_frame(context, &test_frame);
+ if (video_error != FAS_SUCCESS) fail("fail on test(seek2)\n");
+
+ // printf("offset: %d / %d\n", offset, stop - start + 1);
+
+ if (!compare_frames(test_frame, ref_frames[offset]))
+ {
+ char buffer[70];
+
+ sprintf(buffer, "fail-%d-test.ppm", index);
+ ppm_save(&test_frame, buffer);
+ sprintf(buffer, "fail-%d-ref.ppm", index);
+ ppm_save(&ref_frames[offset], buffer);
+ sprintf(buffer, "failed on compare after seeking (%d->%d)\n", prev_index, index);
+
+ fail(buffer);
+ }
+
+ fas_free_frame(test_frame);
+ }
+
+ for (i=0;i<stop - start + 1;i++)
+ free(ref_frames[i].data);
+
+ free(ref_frames);
+}
+
+int main (int argc, char **argv)
+{
+ fas_error_type video_error;
+ fas_context_ref_type context;
+
+ if (argc < 2) {
+ fprintf (stderr, "usage: %s <video_file>\n", argv[0]);
+ fail("arguments\n");
+ }
+
+ fprintf(stderr, "%s : ", argv[1]);
+
+ fas_initialize (FAS_FALSE, FAS_RGB24);
+
+ video_error = fas_open_video (&context, argv[1]);
+ if (video_error != FAS_SUCCESS) fail("fail on open\n");
+
+ if (fas_get_frame_count(context) < 0)
+ fail("failed on counting frames (completing seek table... bad table?)\n");
+
+ if (fas_get_frame_count(context) < TEST_SET_SIZE)
+ do_random_test(context, 0, fas_get_frame_count(context) - 1, N_ITERATIONS);
+ else if (fas_get_frame_count(context) < TEST_SET_SIZE * 2)
+ {
+ do_random_test(context, 0, fas_get_frame_count(context) / 2 - 1, N_ITERATIONS / 2);
+ do_random_test(context, fas_get_frame_count(context) / 2 + 1, fas_get_frame_count(context) - 1 , N_ITERATIONS / 2);
+ }
+ else
+ {
+ do_random_test(context, 0, TEST_SET_SIZE, N_ITERATIONS / 2);
+ do_random_test(context, fas_get_frame_count(context) - TEST_SET_SIZE, fas_get_frame_count(context) - 1 , N_ITERATIONS / 2);
+ }
+
+ fas_close_video(context);
+
+ success();
+}
+
diff --git a/ffmpeg-fas/test/show_seek_table.c b/ffmpeg-fas/test/show_seek_table.c
new file mode 100644
index 0000000..f5dfd39
--- /dev/null
+++ b/ffmpeg-fas/test/show_seek_table.c
@@ -0,0 +1,59 @@
+/*****************************************************************************
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ ******************************************************************************/
+
+#include "seek_indices.h"
+#include "ffmpeg_fas.h"
+#include <stdio.h>
+
+int main (int argc, char **argv)
+{
+ fas_error_type video_error;
+ fas_context_ref_type context;
+ fas_raw_image_type image_buffer;
+
+ if (argc < 2) {
+ fprintf (stderr, "usage: %s <video_file>\n", argv[0]);
+ return -1;
+ }
+
+ fas_initialize (FAS_FALSE, FAS_RGB24);
+
+ video_error = fas_open_video (&context, argv[1]);
+ if (video_error != FAS_SUCCESS)
+ return -1;
+
+ while (fas_frame_available (context))
+ {
+ if (FAS_SUCCESS != fas_get_frame (context, &image_buffer))
+ return -1;
+ fas_free_frame (image_buffer);
+
+ video_error = fas_step_forward (context);
+ }
+
+ seek_table_type table;
+ table = fas_get_seek_table(context);
+
+ seek_show_raw_table(stdout, table);
+
+ return 1;
+}
+
diff --git a/ffmpeg-fas/test/test_support.h b/ffmpeg-fas/test/test_support.h
new file mode 100644
index 0000000..5b91a1a
--- /dev/null
+++ b/ffmpeg-fas/test/test_support.h
@@ -0,0 +1,67 @@
+/*****************************************************************************
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ ******************************************************************************/
+
+#ifndef FAS_TEST_SUPPORT
+#define FAS_TEST_SUPPORT
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define fail(x) { fprintf(stderr, "fail : "); fprintf(stderr, x); exit(EXIT_FAILURE); }
+#define success() { fprintf(stderr, "success\n"); exit(EXIT_SUCCESS); }
+
+/*
+ * static void pgm_save(ppt_raw_image_type *image, char *filename)
+ * {
+ * FILE *f;
+ * int i;
+ *
+ * f=fopen(filename,"w");
+ * fprintf(f,"P5\n%d\n%d\n%d\n", image->width, image->height, 255);
+ *
+ * for(i=0; i<image->height; i++) {
+ * fwrite(image->data + i * image->bytes_per_line, 1, image->width, f);
+ * }
+ *
+ * fclose(f);
+ * }
+ */
+
+static void ppm_save(fas_raw_image_type *image, char *filename)
+{
+ FILE *f;
+ int i;
+
+ if (image->color_space != FAS_RGB24) {
+ return;
+ }
+
+ f=fopen(filename,"wb");
+ fprintf(f,"P6\n%d %d\n%d\n", image->width, image->height, 255);
+
+ for(i=0; i<image->height; i++) {
+ fwrite(image->data + i * image->bytes_per_line, 1, image->width * 3, f);
+ }
+
+ fclose(f);
+}
+
+#endif