00001
00002 #include "oxp_vob_frame_index.h"
00003 #include <vcl_cassert.h>
00004 #include <vcl_cstdio.h>
00005 #include <vcl_fstream.h>
00006 #include <vul/vul_awk.h>
00007
00008 bool oxp_vob_frame_index::load(char const* filename)
00009 {
00010 vcl_vector<oxp_vob_frame_index_entry> tmp;
00011
00012 vcl_ifstream f(filename, vcl_ios_binary);
00013 if (!f.good())
00014 {
00015 vcl_cerr << "oxp_vob_frame_index: Cannot read IDX file ["<< filename <<"]\n";
00016 return false;
00017 }
00018 vul_awk awk(f);
00019 vcl_string tag(awk[0]);
00020 const int MPEG_IDX = 1;
00021 const int LBA = 2;
00022 int idx_type = 0;
00023 if (tag == "MPEG_IDX")
00024 idx_type = MPEG_IDX;
00025 else if (tag == "LBA")
00026 idx_type = LBA;
00027 else
00028 vcl_cerr << "oxp_vob_frame_index: WARNING: unknown type [" << awk[0] << "]\n";
00029
00030 for (int frame=0; awk; ++awk, ++frame)
00031 {
00032
00033 oxp_vob_frame_index_entry e;
00034 if (idx_type == LBA && vcl_sscanf(awk.line(), " %x | %d", &e.lba, &e.frame) == 2)
00035 tmp.push_back(e);
00036 int dummy;
00037 if (idx_type == MPEG_IDX && vcl_sscanf(awk.line(), " %x %x", &e.lba, &dummy) == 2)
00038 {
00039 e.frame = frame;
00040 tmp.push_back(e);
00041 }
00042 }
00043 l = tmp;
00044
00045
00046 for (unsigned int i = 0; i+1 < l.size(); ++i)
00047 assert(l[i+1].frame > l[i].frame);
00048 vcl_cerr << "Loaded " << l.size() << " entries from [" << filename << "]\n";
00049 if (l.size() == 0)
00050 vcl_cerr << "WARNING: No index entries -- all seeks from start\n";
00051 return true;
00052 }
00053
00054 int oxp_vob_frame_index::frame_to_lba_of_prev_I_frame(int f, int* f_actual)
00055 {
00056 int lo = 0;
00057 int hi = l.size()-1;
00058 if (hi < 0 || f < l[lo].frame || f > l[hi].frame) {
00059 vcl_cerr << "urk: frame " << f << " out of IDX range\n";
00060 return -1;
00061 }
00062 while (lo < hi-1)
00063 {
00064 int half = (lo + hi) / 2;
00065 int f_half = l[half].frame;
00066 if (f < f_half)
00067 hi = half;
00068 else if (f > f_half)
00069 lo = half;
00070 else {
00071 lo = half;
00072 break;
00073 }
00074 }
00075
00076 if (f_actual)
00077 *f_actual = l[lo].frame;
00078 return l[lo].lba;
00079 }