1 /* Copyright 2009 Yorba Foundation
3 * This software is licensed under the GNU Lesser General Public License
4 * (version 2.1 or later). See the COPYING file in this distribution.
9 public class VideoTrack : Track {
11 public VideoTrack(Model.Project project) {
12 base(project, "Video Track");
15 protected override string name() { return "video"; }
17 public override MediaType media_type() {
18 return MediaType.VIDEO;
21 protected override bool check(Clip clip) {
25 if (!clip.clipfile.is_online())
31 if (!get_framerate(out rate2)) {
32 error_occurred("Cannot get initial frame rate!", null);
36 if (!clip.clipfile.get_frame_rate(out rate1)) {
37 error_occurred("can't get frame rate", null);
41 if (!rate1.equal(rate2)) {
42 error_occurred("can't insert clip with different frame rate", null);
48 /* It would be nice if we could query or seek in frames using GST_FORMAT_DEFAULT, or ask
49 * GStreamer to convert frame->time and time->frame for us using gst_element_query_convert().
50 * Unfortunately there are several reasons we can't.
51 * 1) It appears that position queries using GST_FORMAT_DEFAULT are broken since GstBaseSink
52 * won't pass them upstream.
53 * 2) Some codecs (e.g. theoradec) will convert between time and frames, but
54 * others (e.g. ffmpegdec, dvdec) haven't implemented this conversion.
55 * 3) Even when a codec will perform conversions, its frame->time and time->frame functions may
56 * not be perfect inverses; see the comments in time_to_frame(), below.
58 * So instead we must convert manually using the frame rate.
60 * TODO: We should file GStreamer bugs for all of these.
63 int64 frame_to_time(int frame) {
65 if (!get_framerate(out rate))
68 return (int64) Gst.util_uint64_scale(frame, Gst.SECOND * rate.denominator, rate.numerator);
71 int time_to_frame(int64 time) {
73 if (!get_framerate(out rate))
75 return time_to_frame_with_rate(time, rate);
78 public int get_current_frame(int64 time) {
79 return time_to_frame(time);
82 public int64 previous_frame(int64 position) {
83 int frame = time_to_frame(position);
84 return frame_to_time(frame - 1);
87 public int64 next_frame(int64 position) {
88 int frame = time_to_frame(position);
89 return frame_to_time(frame + 1);
92 public bool get_framerate(out Fraction rate) {
96 foreach (Clip c in clips) {
97 if (c.clipfile.is_online()) {
98 bool can = c.clipfile.get_frame_rate(out rate);
105 if (project.default_framerate.equal(Project.INVALID_FRAME_RATE))
108 rate = project.default_framerate;