mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-24 11:54:01 +00:00
Modified getting the FPS from MP4 files. More cases (CTTS present or not, durmap table with more than one entry) are handled now.
This commit is contained in:
parent
6f662a61ba
commit
f4365020f0
@ -1,5 +1,8 @@
|
|||||||
2005-03-06 Moritz Bunkus <moritz@bunkus.org>
|
2005-03-06 Moritz Bunkus <moritz@bunkus.org>
|
||||||
|
|
||||||
|
* mkvmerge: bug fix: Extracting the FPS from some AVC MP4 files
|
||||||
|
did not work.
|
||||||
|
|
||||||
* mkvmerge: bug fix: Appending + splitting was segfaulting if used
|
* mkvmerge: bug fix: Appending + splitting was segfaulting if used
|
||||||
together and at least one split occured after a track has been
|
together and at least one split occured after a track has been
|
||||||
appended.
|
appended.
|
||||||
|
@ -892,6 +892,9 @@ qtmp4_reader_c::handle_stss_atom(qtmp4_demuxer_ptr &new_dmx,
|
|||||||
new_dmx->keyframe_table.push_back(io->read_uint32_be());
|
new_dmx->keyframe_table.push_back(io->read_uint32_be());
|
||||||
|
|
||||||
mxverb(2, PFX "%*sSync/keyframe table: %u entries\n", level * 2, "", count);
|
mxverb(2, PFX "%*sSync/keyframe table: %u entries\n", level * 2, "", count);
|
||||||
|
for (i = 0; i < count; ++i)
|
||||||
|
mxverb(4, PFX "%*skeyframe at %u\n", (level + 1) * 2, "",
|
||||||
|
new_dmx->keyframe_table[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1417,46 +1420,7 @@ qtmp4_reader_c::create_packetizer(int64_t tid) {
|
|||||||
"that it looks like you expected it to.\n",
|
"that it looks like you expected it to.\n",
|
||||||
ti.fname.c_str(), (int64_t)dmx->id);
|
ti.fname.c_str(), (int64_t)dmx->id);
|
||||||
|
|
||||||
fps = 0.0;
|
fps = dmx->calculate_fps();
|
||||||
if ((dmx->durmap_table.size() == 1) &&
|
|
||||||
(dmx->durmap_table[0].duration != 0)) {
|
|
||||||
if ((dmx->sample_size != 0) ||
|
|
||||||
(dmx->frame_offset_table.size() == 0)) {
|
|
||||||
// Constant FPS. Let's set the default duration.
|
|
||||||
fps = (double)dmx->timescale /
|
|
||||||
(double)dmx->durmap_table[0].duration;
|
|
||||||
mxverb(3, PFX "fps1: %f\n", fps);
|
|
||||||
|
|
||||||
} else if ((dmx->sample_table.size() > 0) &&
|
|
||||||
(dmx->sample_table.size() ==
|
|
||||||
dmx->frame_offset_table.size())) {
|
|
||||||
// Constant FPS but the frame offsets are used. This one is
|
|
||||||
// a bit trickier. I have to find the maximum timecode including
|
|
||||||
// the frame offsets (for PTS/DTS conversion) and divide that
|
|
||||||
// by the number of frames.
|
|
||||||
int64_t max_tc;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
max_tc = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < dmx->sample_table.size(); i++) {
|
|
||||||
int64_t timecode;
|
|
||||||
|
|
||||||
timecode = ((int64_t)dmx->sample_table[i].pts +
|
|
||||||
(int64_t)dmx->frame_offset_table[dmx->pos]) *
|
|
||||||
1000000000 / dmx->timescale;
|
|
||||||
if (timecode > max_tc)
|
|
||||||
max_tc = timecode;
|
|
||||||
}
|
|
||||||
if (max_tc > 0)
|
|
||||||
fps = (double)dmx->sample_table.size() * 1000000000.0 /
|
|
||||||
(double)max_tc;
|
|
||||||
|
|
||||||
mxverb(3, PFX "fps2: max_tc %lld s_t.s %u fps %f\n", max_tc,
|
|
||||||
dmx->sample_table.size(), fps);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ti.private_size = dmx->priv_size;
|
ti.private_size = dmx->priv_size;
|
||||||
ti.private_data = dmx->priv;
|
ti.private_data = dmx->priv;
|
||||||
dmx->ptzr =
|
dmx->ptzr =
|
||||||
@ -1618,3 +1582,65 @@ qtmp4_reader_c::add_available_track_ids() {
|
|||||||
for (i =0 ; i < demuxers.size(); i++)
|
for (i =0 ; i < demuxers.size(); i++)
|
||||||
available_track_ids.push_back(demuxers[i]->id);
|
available_track_ids.push_back(demuxers[i]->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
qtmp4_demuxer_t::calculate_fps() {
|
||||||
|
double fps;
|
||||||
|
|
||||||
|
fps = 0.0;
|
||||||
|
|
||||||
|
if ((1 == durmap_table.size()) && (0 != durmap_table[0].duration) &&
|
||||||
|
((0 != sample_size) || (0 == frame_offset_table.size()))) {
|
||||||
|
// Constant FPS. Let's set the default duration.
|
||||||
|
fps = (double)timescale / (double)durmap_table[0].duration;
|
||||||
|
mxverb(3, PFX "calculate_fps: case 1: %f\n", fps);
|
||||||
|
return fps;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((0 < sample_table.size()) &&
|
||||||
|
(sample_table.size() == frame_offset_table.size())) {
|
||||||
|
// Constant FPS but the frame offsets are used. This one is
|
||||||
|
// a bit trickier. I have to find the maximum timecode including
|
||||||
|
// the frame offsets (for PTS/DTS conversion) and divide that
|
||||||
|
// by the number of frames.
|
||||||
|
int64_t max_tc;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
max_tc = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < sample_table.size(); ++i) {
|
||||||
|
int64_t timecode;
|
||||||
|
|
||||||
|
timecode = ((int64_t)sample_table[i].pts +
|
||||||
|
(int64_t)frame_offset_table[pos]) * 1000000000 / timescale;
|
||||||
|
if (timecode > max_tc)
|
||||||
|
max_tc = timecode;
|
||||||
|
}
|
||||||
|
if (0 < max_tc)
|
||||||
|
fps = (double)sample_table.size() * 1000000000.0 / (double)max_tc;
|
||||||
|
|
||||||
|
mxverb(3, PFX "calculate_fps: case 2: max_tc %lld s_t.s %u fps %f\n",
|
||||||
|
max_tc, sample_table.size(), fps);
|
||||||
|
return fps;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 < sample_table.size()) {
|
||||||
|
int64_t max_tc;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
max_tc = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < sample_table.size(); ++i)
|
||||||
|
if ((int64_t)sample_table[i].pts > max_tc)
|
||||||
|
max_tc = (int64_t)sample_table[i].pts;
|
||||||
|
if (0 < max_tc)
|
||||||
|
fps = (double)sample_table.size() * 1000000000.0 / (double)max_tc;
|
||||||
|
|
||||||
|
mxverb(3, PFX "calculate_fps: case 3: max_tc %lld s_t.s %u fps %f\n",
|
||||||
|
max_tc, sample_table.size(), fps);
|
||||||
|
return fps;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -156,6 +156,8 @@ struct qtmp4_demuxer_t {
|
|||||||
safefree(esds.decoder_config);
|
safefree(esds.decoder_config);
|
||||||
safefree(esds.sl_config);
|
safefree(esds.sl_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double calculate_fps();
|
||||||
};
|
};
|
||||||
typedef counted_ptr<qtmp4_demuxer_t> qtmp4_demuxer_ptr;
|
typedef counted_ptr<qtmp4_demuxer_t> qtmp4_demuxer_ptr;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user