mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
Merge remote-tracking branch 'origin/master' into 0.11
Conflicts: ext/vorbis/gstvorbisenc.c gst/playback/gstdecodebin2.c gst/playback/gstplaysinkconvertbin.c gst/videorate/gstvideorate.c
This commit is contained in:
commit
32b14c6ed3
14 changed files with 350 additions and 112 deletions
|
@ -461,6 +461,9 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet,
|
||||||
|
|
||||||
cret = GST_FLOW_OK;
|
cret = GST_FLOW_OK;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (pad, "Chaining %d %d %" GST_TIME_FORMAT " %d %p",
|
||||||
|
ogg->pullmode, ogg->push_state, GST_TIME_ARGS (ogg->push_time_length),
|
||||||
|
ogg->push_disable_seeking, ogg->building_chain);
|
||||||
GST_PUSH_LOCK (ogg);
|
GST_PUSH_LOCK (ogg);
|
||||||
if (!ogg->pullmode && ogg->push_state == PUSH_PLAYING
|
if (!ogg->pullmode && ogg->push_state == PUSH_PLAYING
|
||||||
&& ogg->push_time_length == GST_CLOCK_TIME_NONE
|
&& ogg->push_time_length == GST_CLOCK_TIME_NONE
|
||||||
|
@ -1056,6 +1059,8 @@ gst_ogg_pad_stream_out (GstOggPad * pad, gint npackets)
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
GST_LOG_OBJECT (ogg, "packetout gave packet of size %ld", packet.bytes);
|
GST_LOG_OBJECT (ogg, "packetout gave packet of size %ld", packet.bytes);
|
||||||
|
if (packet.bytes > ogg->max_packet_size)
|
||||||
|
ogg->max_packet_size = packet.bytes;
|
||||||
result = gst_ogg_pad_submit_packet (pad, &packet);
|
result = gst_ogg_pad_submit_packet (pad, &packet);
|
||||||
/* not linked is not a problem, it's possible that we are still
|
/* not linked is not a problem, it's possible that we are still
|
||||||
* collecting headers and that we don't have exposed the pads yet */
|
* collecting headers and that we don't have exposed the pads yet */
|
||||||
|
@ -1097,19 +1102,22 @@ gst_ogg_demux_setup_bisection_bounds (GstOggDemux * ogg)
|
||||||
GST_TIME_ARGS (ogg->push_last_seek_time - ogg->push_seek_time_target));
|
GST_TIME_ARGS (ogg->push_last_seek_time - ogg->push_seek_time_target));
|
||||||
ogg->push_offset1 = ogg->push_last_seek_offset;
|
ogg->push_offset1 = ogg->push_last_seek_offset;
|
||||||
ogg->push_time1 = ogg->push_last_seek_time;
|
ogg->push_time1 = ogg->push_last_seek_time;
|
||||||
|
ogg->seek_undershot = FALSE;
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG_OBJECT (ogg, "We undershot by %" GST_TIME_FORMAT,
|
GST_DEBUG_OBJECT (ogg, "We undershot by %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (ogg->push_seek_time_target - ogg->push_last_seek_time));
|
GST_TIME_ARGS (ogg->push_seek_time_target - ogg->push_last_seek_time));
|
||||||
ogg->push_offset0 = ogg->push_last_seek_offset;
|
ogg->push_offset0 = ogg->push_last_seek_offset;
|
||||||
ogg->push_time0 = ogg->push_last_seek_time;
|
ogg->push_time0 = ogg->push_last_seek_time;
|
||||||
|
ogg->seek_undershot = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint64
|
static gint64
|
||||||
gst_ogg_demux_estimate_bisection_target (GstOggDemux * ogg)
|
gst_ogg_demux_estimate_bisection_target (GstOggDemux * ogg, float seek_quality)
|
||||||
{
|
{
|
||||||
gint64 best;
|
gint64 best;
|
||||||
gint64 segment_bitrate;
|
gint64 segment_bitrate;
|
||||||
|
gint64 skew;
|
||||||
|
|
||||||
/* we might not know the length of the stream in time,
|
/* we might not know the length of the stream in time,
|
||||||
so push_time1 might not be set */
|
so push_time1 might not be set */
|
||||||
|
@ -1136,6 +1144,7 @@ gst_ogg_demux_estimate_bisection_target (GstOggDemux * ogg)
|
||||||
ogg->push_offset0 +
|
ogg->push_offset0 +
|
||||||
gst_util_uint64_scale (ogg->push_seek_time_target - ogg->push_time0,
|
gst_util_uint64_scale (ogg->push_seek_time_target - ogg->push_time0,
|
||||||
segment_bitrate, 8 * GST_SECOND);
|
segment_bitrate, 8 * GST_SECOND);
|
||||||
|
ogg->seek_secant = TRUE;
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG_OBJECT (ogg,
|
GST_DEBUG_OBJECT (ogg,
|
||||||
"New segment to consider: bytes %" G_GINT64_FORMAT " %" G_GINT64_FORMAT
|
"New segment to consider: bytes %" G_GINT64_FORMAT " %" G_GINT64_FORMAT
|
||||||
|
@ -1152,20 +1161,63 @@ gst_ogg_demux_estimate_bisection_target (GstOggDemux * ogg)
|
||||||
"Local bitrate on the %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT
|
"Local bitrate on the %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT
|
||||||
" segment: %" G_GINT64_FORMAT, GST_TIME_ARGS (ogg->push_time0),
|
" segment: %" G_GINT64_FORMAT, GST_TIME_ARGS (ogg->push_time0),
|
||||||
GST_TIME_ARGS (ogg->push_time1), segment_bitrate);
|
GST_TIME_ARGS (ogg->push_time1), segment_bitrate);
|
||||||
|
|
||||||
best =
|
best =
|
||||||
ogg->push_offset0 +
|
ogg->push_offset0 +
|
||||||
gst_util_uint64_scale (ogg->push_seek_time_target - ogg->push_time0,
|
gst_util_uint64_scale (ogg->push_seek_time_target - ogg->push_time0,
|
||||||
segment_bitrate, 8 * GST_SECOND);
|
segment_bitrate, 8 * GST_SECOND);
|
||||||
|
if (seek_quality < 0.5f && ogg->seek_secant) {
|
||||||
|
gint64 new_best, best2 = (ogg->push_offset0 + ogg->push_offset1) / 2;
|
||||||
|
/* if dire result, give as much as 25% weight to a dumb bisection guess */
|
||||||
|
float secant_weight = 1.0f - ((0.5 - seek_quality) / 0.5f) * 0.25;
|
||||||
|
new_best = (best * secant_weight + best2 * (1.0f - secant_weight));
|
||||||
|
GST_DEBUG_OBJECT (ogg,
|
||||||
|
"Secant says %" G_GINT64_FORMAT ", straight is %" G_GINT64_FORMAT
|
||||||
|
", new best %" G_GINT64_FORMAT " with secant_weight %f", best,
|
||||||
|
best2, new_best, secant_weight);
|
||||||
|
best = new_best;
|
||||||
|
ogg->seek_secant = FALSE;
|
||||||
|
} else {
|
||||||
|
ogg->seek_secant = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* offset by typical page size */
|
GST_DEBUG_OBJECT (ogg, "Raw best guess: %" G_GINT64_FORMAT, best);
|
||||||
best -= CHUNKSIZE;
|
|
||||||
|
/* offset the guess down as we need to capture the start of the
|
||||||
|
page we are targetting - but only do so if we did not undershoot
|
||||||
|
last time, as we're likely to still do this time */
|
||||||
|
if (!ogg->seek_undershot) {
|
||||||
|
/* very small packets are packed on pages, so offset by at least
|
||||||
|
a value which is likely to get us at least one page where the
|
||||||
|
packet starts */
|
||||||
|
skew =
|
||||||
|
ogg->max_packet_size >
|
||||||
|
ogg->max_page_size ? ogg->max_packet_size : ogg->max_page_size;
|
||||||
|
GST_DEBUG_OBJECT (ogg, "Offsetting by %" G_GINT64_FORMAT, skew);
|
||||||
|
best -= skew;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do not seek too close to the bounds, as we stop seeking
|
||||||
|
when we get to within max_packet_size before the target */
|
||||||
|
if (best > ogg->push_offset1 - ogg->max_packet_size) {
|
||||||
|
best = ogg->push_offset1 - ogg->max_packet_size;
|
||||||
|
GST_DEBUG_OBJECT (ogg,
|
||||||
|
"Too close to high bound, pushing back to %" G_GINT64_FORMAT, best);
|
||||||
|
} else if (best < ogg->push_offset0 + ogg->max_packet_size) {
|
||||||
|
best = ogg->push_offset0 + ogg->max_packet_size;
|
||||||
|
GST_DEBUG_OBJECT (ogg,
|
||||||
|
"Too close to low bound, pushing forth to %" G_GINT64_FORMAT, best);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* keep within bounds */
|
||||||
|
if (best > ogg->push_offset1)
|
||||||
|
best = ogg->push_offset1;
|
||||||
if (best < ogg->push_offset0)
|
if (best < ogg->push_offset0)
|
||||||
best = ogg->push_offset0;
|
best = ogg->push_offset0;
|
||||||
if (best < 0)
|
|
||||||
best = 0;
|
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (ogg, "Choosing target %" G_GINT64_FORMAT, best);
|
||||||
return best;
|
return best;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1242,6 +1294,60 @@ gst_ogg_demux_seek_back_after_push_duration_check_unlock (GstOggDemux * ogg)
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float
|
||||||
|
gst_ogg_demux_estimate_seek_quality (GstOggDemux * ogg)
|
||||||
|
{
|
||||||
|
gint64 diff; /* how far from the goal we ended up */
|
||||||
|
gint64 dist; /* how far we moved this iteration */
|
||||||
|
float seek_quality;
|
||||||
|
|
||||||
|
if (ogg->push_prev_seek_time == GST_CLOCK_TIME_NONE) {
|
||||||
|
/* for the first seek, we pretend we got a good seek,
|
||||||
|
as we don't have a previous seek yet */
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We take a guess at how good the last seek was at guessing
|
||||||
|
the byte target by comparing the amplitude of the last
|
||||||
|
seek to the error */
|
||||||
|
diff = ogg->push_seek_time_target - ogg->push_last_seek_time;
|
||||||
|
if (diff < 0)
|
||||||
|
diff = -diff;
|
||||||
|
dist = ogg->push_last_seek_time - ogg->push_prev_seek_time;
|
||||||
|
if (dist < 0)
|
||||||
|
dist = -dist;
|
||||||
|
|
||||||
|
seek_quality = (dist == 0) ? 0.0f : 1.0f / (1.0f + diff / (float) dist);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (ogg,
|
||||||
|
"We moved %" GST_TIME_FORMAT ", we're off by %" GST_TIME_FORMAT
|
||||||
|
", seek quality %f", GST_TIME_ARGS (dist), GST_TIME_ARGS (diff),
|
||||||
|
seek_quality);
|
||||||
|
return seek_quality;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_ogg_demux_update_bisection_stats (GstOggDemux * ogg)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
GST_INFO_OBJECT (ogg, "Bisection needed %d + %d steps",
|
||||||
|
ogg->push_bisection_steps[0], ogg->push_bisection_steps[1]);
|
||||||
|
|
||||||
|
for (n = 0; n < 2; ++n) {
|
||||||
|
ogg->stats_bisection_steps[n] += ogg->push_bisection_steps[n];
|
||||||
|
if (ogg->stats_bisection_max_steps[n] < ogg->push_bisection_steps[n])
|
||||||
|
ogg->stats_bisection_max_steps[n] = ogg->push_bisection_steps[n];
|
||||||
|
}
|
||||||
|
ogg->stats_nbisections++;
|
||||||
|
|
||||||
|
GST_INFO_OBJECT (ogg,
|
||||||
|
"So far, %.2f + %.2f bisections needed per seek (max %d + %d)",
|
||||||
|
ogg->stats_bisection_steps[0] / (float) ogg->stats_nbisections,
|
||||||
|
ogg->stats_bisection_steps[1] / (float) ogg->stats_nbisections,
|
||||||
|
ogg->stats_bisection_max_steps[0], ogg->stats_bisection_max_steps[1]);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_ogg_pad_handle_push_mode_state (GstOggPad * pad, ogg_page * page)
|
gst_ogg_pad_handle_push_mode_state (GstOggPad * pad, ogg_page * page)
|
||||||
{
|
{
|
||||||
|
@ -1317,6 +1423,7 @@ gst_ogg_pad_handle_push_mode_state (GstOggPad * pad, ogg_page * page)
|
||||||
GstEvent *sevent;
|
GstEvent *sevent;
|
||||||
int res;
|
int res;
|
||||||
gboolean close_enough;
|
gboolean close_enough;
|
||||||
|
float seek_quality;
|
||||||
|
|
||||||
/* ignore -1 granpos when seeking, we want to sync on a real granpos */
|
/* ignore -1 granpos when seeking, we want to sync on a real granpos */
|
||||||
if (granpos < 0) {
|
if (granpos < 0) {
|
||||||
|
@ -1354,14 +1461,18 @@ gst_ogg_pad_handle_push_mode_state (GstOggPad * pad, ogg_page * page)
|
||||||
GST_TIME_ARGS (ogg->push_seek_time_target));
|
GST_TIME_ARGS (ogg->push_seek_time_target));
|
||||||
|
|
||||||
if (ogg->push_time1 != GST_CLOCK_TIME_NONE) {
|
if (ogg->push_time1 != GST_CLOCK_TIME_NONE) {
|
||||||
|
seek_quality = gst_ogg_demux_estimate_seek_quality (ogg);
|
||||||
GST_DEBUG_OBJECT (ogg,
|
GST_DEBUG_OBJECT (ogg,
|
||||||
"Interval was %" G_GINT64_FORMAT " - %" G_GINT64_FORMAT " (%"
|
"Interval was %" G_GINT64_FORMAT " - %" G_GINT64_FORMAT " (%"
|
||||||
G_GINT64_FORMAT "), time %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT
|
G_GINT64_FORMAT "), time %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT
|
||||||
" (%" GST_TIME_FORMAT ")", ogg->push_offset0, ogg->push_offset1,
|
" (%" GST_TIME_FORMAT "), seek quality %f", ogg->push_offset0,
|
||||||
ogg->push_offset1 - ogg->push_offset0,
|
ogg->push_offset1, ogg->push_offset1 - ogg->push_offset0,
|
||||||
GST_TIME_ARGS (ogg->push_time0), GST_TIME_ARGS (ogg->push_time1),
|
GST_TIME_ARGS (ogg->push_time0), GST_TIME_ARGS (ogg->push_time1),
|
||||||
GST_TIME_ARGS (ogg->push_time1 - ogg->push_time0));
|
GST_TIME_ARGS (ogg->push_time1 - ogg->push_time0), seek_quality);
|
||||||
} else {
|
} else {
|
||||||
|
/* in a open ended seek, we can't do bisection, so we pretend
|
||||||
|
we like our result so far */
|
||||||
|
seek_quality = 1.0f;
|
||||||
GST_DEBUG_OBJECT (ogg,
|
GST_DEBUG_OBJECT (ogg,
|
||||||
"Interval was %" G_GINT64_FORMAT " - %" G_GINT64_FORMAT " (%"
|
"Interval was %" G_GINT64_FORMAT " - %" G_GINT64_FORMAT " (%"
|
||||||
G_GINT64_FORMAT "), time %" GST_TIME_FORMAT " - unknown",
|
G_GINT64_FORMAT "), time %" GST_TIME_FORMAT " - unknown",
|
||||||
|
@ -1369,30 +1480,39 @@ gst_ogg_pad_handle_push_mode_state (GstOggPad * pad, ogg_page * page)
|
||||||
ogg->push_offset1 - ogg->push_offset0,
|
ogg->push_offset1 - ogg->push_offset0,
|
||||||
GST_TIME_ARGS (ogg->push_time0));
|
GST_TIME_ARGS (ogg->push_time0));
|
||||||
}
|
}
|
||||||
|
ogg->push_prev_seek_time = ogg->push_last_seek_time;
|
||||||
|
|
||||||
gst_ogg_demux_setup_bisection_bounds (ogg);
|
gst_ogg_demux_setup_bisection_bounds (ogg);
|
||||||
|
|
||||||
best = gst_ogg_demux_estimate_bisection_target (ogg);
|
best = gst_ogg_demux_estimate_bisection_target (ogg, seek_quality);
|
||||||
|
|
||||||
if (ogg->push_seek_time_target == 0) {
|
if (ogg->push_seek_time_target == 0) {
|
||||||
GST_DEBUG_OBJECT (ogg, "Seeking to 0, deemed close enough");
|
GST_DEBUG_OBJECT (ogg, "Seeking to 0, deemed close enough");
|
||||||
close_enough = (ogg->push_last_seek_time == 0);
|
close_enough = (ogg->push_last_seek_time == 0);
|
||||||
} else {
|
} else {
|
||||||
/* TODO: make this dependent on framerate ? */
|
/* TODO: make this dependent on framerate ? */
|
||||||
GstClockTime threshold = GST_SECOND / 2;
|
GstClockTime time_threshold = GST_SECOND / 2;
|
||||||
|
guint64 byte_threshold =
|
||||||
|
(ogg->max_packet_size >
|
||||||
|
64 * 1024 ? ogg->max_packet_size : 64 * 1024);
|
||||||
|
|
||||||
/* We want to be within half a second before the target */
|
/* We want to be within half a second before the target,
|
||||||
if (threshold > ogg->push_seek_time_target)
|
or before the target and half less or equal to the max
|
||||||
threshold = ogg->push_seek_time_target;
|
packet size left to search in */
|
||||||
|
if (time_threshold > ogg->push_seek_time_target)
|
||||||
|
time_threshold = ogg->push_seek_time_target;
|
||||||
close_enough = ogg->push_last_seek_time < ogg->push_seek_time_target
|
close_enough = ogg->push_last_seek_time < ogg->push_seek_time_target
|
||||||
&& ogg->push_last_seek_time >=
|
&& (ogg->push_last_seek_time >=
|
||||||
ogg->push_seek_time_target - threshold;
|
ogg->push_seek_time_target - time_threshold
|
||||||
|
|| ogg->push_offset1 <= ogg->push_offset0 + byte_threshold);
|
||||||
GST_DEBUG_OBJECT (ogg,
|
GST_DEBUG_OBJECT (ogg,
|
||||||
"testing if we're close enough: %" GST_TIME_FORMAT " <= %"
|
"testing if we're close enough: %" GST_TIME_FORMAT " <= %"
|
||||||
GST_TIME_FORMAT " < %" GST_TIME_FORMAT " ? %s",
|
GST_TIME_FORMAT " < %" GST_TIME_FORMAT ", or %" G_GUINT64_FORMAT
|
||||||
GST_TIME_ARGS (ogg->push_seek_time_target - threshold),
|
" <= %" G_GUINT64_FORMAT " ? %s",
|
||||||
|
GST_TIME_ARGS (ogg->push_seek_time_target - time_threshold),
|
||||||
GST_TIME_ARGS (ogg->push_last_seek_time),
|
GST_TIME_ARGS (ogg->push_last_seek_time),
|
||||||
GST_TIME_ARGS (ogg->push_seek_time_target),
|
GST_TIME_ARGS (ogg->push_seek_time_target),
|
||||||
|
ogg->push_offset1 - ogg->push_offset0, byte_threshold,
|
||||||
close_enough ? "Yes" : "No");
|
close_enough ? "Yes" : "No");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1422,14 +1542,13 @@ gst_ogg_pad_handle_push_mode_state (GstOggPad * pad, ogg_page * page)
|
||||||
GST_TIME_ARGS (ogg->push_seek_time_original_target));
|
GST_TIME_ARGS (ogg->push_seek_time_original_target));
|
||||||
ogg->push_state = PUSH_LINEAR2;
|
ogg->push_state = PUSH_LINEAR2;
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG_OBJECT (ogg, "Seek to keyframe done, playing");
|
GST_INFO_OBJECT (ogg, "Seek to keyframe done, playing");
|
||||||
|
|
||||||
/* we're synced to the seek target, so flush stream and stuff
|
/* we're synced to the seek target, so flush stream and stuff
|
||||||
any queued pages into the stream so we start decoding there */
|
any queued pages into the stream so we start decoding there */
|
||||||
ogg->push_state = PUSH_PLAYING;
|
ogg->push_state = PUSH_PLAYING;
|
||||||
}
|
}
|
||||||
GST_INFO_OBJECT (ogg, "Bisection needed %d + %d steps",
|
gst_ogg_demux_update_bisection_stats (ogg);
|
||||||
ogg->push_bisection_steps[0], ogg->push_bisection_steps[1]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (ogg->push_state == PUSH_LINEAR1) {
|
} else if (ogg->push_state == PUSH_LINEAR1) {
|
||||||
|
@ -1443,14 +1562,30 @@ gst_ogg_pad_handle_push_mode_state (GstOggPad * pad, ogg_page * page)
|
||||||
GST_TIME_ARGS (pad->push_kf_time));
|
GST_TIME_ARGS (pad->push_kf_time));
|
||||||
earliest_keyframe_time = gst_ogg_demux_get_earliest_keyframe_time (ogg);
|
earliest_keyframe_time = gst_ogg_demux_get_earliest_keyframe_time (ogg);
|
||||||
if (earliest_keyframe_time != GST_CLOCK_TIME_NONE) {
|
if (earliest_keyframe_time != GST_CLOCK_TIME_NONE) {
|
||||||
GST_DEBUG_OBJECT (ogg,
|
if (earliest_keyframe_time > ogg->push_last_seek_time) {
|
||||||
"All non sparse streams now have a previous keyframe time,"
|
GST_INFO_OBJECT (ogg,
|
||||||
"bisecting again to %" GST_TIME_FORMAT,
|
"All non sparse streams now have a previous keyframe time, "
|
||||||
GST_TIME_ARGS (earliest_keyframe_time));
|
"and we already decoded it, switching to playing");
|
||||||
ogg->push_seek_time_target = earliest_keyframe_time;
|
ogg->push_state = PUSH_PLAYING;
|
||||||
|
gst_ogg_demux_update_bisection_stats (ogg);
|
||||||
|
} else {
|
||||||
|
GST_INFO_OBJECT (ogg,
|
||||||
|
"All non sparse streams now have a previous keyframe time, "
|
||||||
|
"bisecting again to %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (earliest_keyframe_time));
|
||||||
|
|
||||||
ogg->push_state = PUSH_BISECT2;
|
ogg->push_seek_time_target = earliest_keyframe_time;
|
||||||
best = gst_ogg_demux_estimate_bisection_target (ogg);
|
ogg->push_offset0 = 0;
|
||||||
|
ogg->push_time0 = ogg->push_start_time;
|
||||||
|
ogg->push_offset1 = ogg->push_last_seek_offset;
|
||||||
|
ogg->push_time1 = ogg->push_last_seek_time;
|
||||||
|
ogg->push_prev_seek_time = GST_CLOCK_TIME_NONE;
|
||||||
|
ogg->seek_secant = FALSE;
|
||||||
|
ogg->seek_undershot = FALSE;
|
||||||
|
|
||||||
|
ogg->push_state = PUSH_BISECT2;
|
||||||
|
best = gst_ogg_demux_estimate_bisection_target (ogg, 1.0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1555,6 +1690,9 @@ gst_ogg_pad_submit_page (GstOggPad * pad, ogg_page * page)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (page->header_len + page->body_len > ogg->max_page_size)
|
||||||
|
ogg->max_page_size = page->header_len + page->body_len;
|
||||||
|
|
||||||
if (ogg_stream_pagein (&pad->map.stream, page) != 0)
|
if (ogg_stream_pagein (&pad->map.stream, page) != 0)
|
||||||
goto choked;
|
goto choked;
|
||||||
|
|
||||||
|
@ -1837,6 +1975,12 @@ gst_ogg_demux_init (GstOggDemux * ogg)
|
||||||
ogg->push_lock = g_mutex_new ();
|
ogg->push_lock = g_mutex_new ();
|
||||||
ogg->chains = g_array_new (FALSE, TRUE, sizeof (GstOggChain *));
|
ogg->chains = g_array_new (FALSE, TRUE, sizeof (GstOggChain *));
|
||||||
|
|
||||||
|
ogg->stats_nbisections = 0;
|
||||||
|
ogg->stats_bisection_steps[0] = 0;
|
||||||
|
ogg->stats_bisection_steps[1] = 0;
|
||||||
|
ogg->stats_bisection_max_steps[0] = 0;
|
||||||
|
ogg->stats_bisection_max_steps[1] = 0;
|
||||||
|
|
||||||
ogg->newsegment = NULL;
|
ogg->newsegment = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3233,8 +3377,11 @@ gst_ogg_demux_perform_seek_push (GstOggDemux * ogg, GstEvent * event)
|
||||||
ogg->push_time0 = ogg->push_start_time;
|
ogg->push_time0 = ogg->push_start_time;
|
||||||
ogg->push_time1 = ogg->push_time_length;
|
ogg->push_time1 = ogg->push_time_length;
|
||||||
ogg->push_seek_time_target = start;
|
ogg->push_seek_time_target = start;
|
||||||
|
ogg->push_prev_seek_time = GST_CLOCK_TIME_NONE;
|
||||||
ogg->push_seek_time_original_target = start;
|
ogg->push_seek_time_original_target = start;
|
||||||
ogg->push_state = PUSH_BISECT1;
|
ogg->push_state = PUSH_BISECT1;
|
||||||
|
ogg->seek_secant = FALSE;
|
||||||
|
ogg->seek_undershot = FALSE;
|
||||||
|
|
||||||
/* reset pad push mode seeking state */
|
/* reset pad push mode seeking state */
|
||||||
for (i = 0; i < chain->streams->len; i++) {
|
for (i = 0; i < chain->streams->len; i++) {
|
||||||
|
|
|
@ -145,6 +145,10 @@ struct _GstOggDemux
|
||||||
gboolean need_chains;
|
gboolean need_chains;
|
||||||
gboolean resync;
|
gboolean resync;
|
||||||
|
|
||||||
|
/* keep track of how large pages and packets are,
|
||||||
|
useful for skewing when seeking */
|
||||||
|
guint64 max_packet_size, max_page_size;
|
||||||
|
|
||||||
/* state */
|
/* state */
|
||||||
GMutex *chain_lock; /* we need the lock to protect the chains */
|
GMutex *chain_lock; /* we need the lock to protect the chains */
|
||||||
GArray *chains; /* list of chains we know */
|
GArray *chains; /* list of chains we know */
|
||||||
|
@ -185,8 +189,14 @@ struct _GstOggDemux
|
||||||
GstSeekFlags push_seek_flags;
|
GstSeekFlags push_seek_flags;
|
||||||
GstEvent *push_mode_seek_delayed_event;
|
GstEvent *push_mode_seek_delayed_event;
|
||||||
gboolean push_disable_seeking;
|
gboolean push_disable_seeking;
|
||||||
|
gboolean seek_secant;
|
||||||
|
gboolean seek_undershot;
|
||||||
|
GstClockTime push_prev_seek_time;
|
||||||
|
|
||||||
gint push_bisection_steps[2];
|
gint push_bisection_steps[2];
|
||||||
|
gint stats_bisection_steps[2];
|
||||||
|
gint stats_bisection_max_steps[2];
|
||||||
|
gint stats_nbisections;
|
||||||
|
|
||||||
/* ogg stuff */
|
/* ogg stuff */
|
||||||
ogg_sync_state sync;
|
ogg_sync_state sync;
|
||||||
|
|
|
@ -448,7 +448,7 @@ gst_ogg_mux_request_new_pad (GstElement * element,
|
||||||
|
|
||||||
oggpad = (GstOggPadData *)
|
oggpad = (GstOggPadData *)
|
||||||
gst_collect_pads2_add_pad_full (ogg_mux->collect, newpad,
|
gst_collect_pads2_add_pad_full (ogg_mux->collect, newpad,
|
||||||
sizeof (GstOggPadData), gst_ogg_mux_ogg_pad_destroy_notify, TRUE);
|
sizeof (GstOggPadData), gst_ogg_mux_ogg_pad_destroy_notify, FALSE);
|
||||||
ogg_mux->active_pads++;
|
ogg_mux->active_pads++;
|
||||||
|
|
||||||
oggpad->map.serialno = serial;
|
oggpad->map.serialno = serial;
|
||||||
|
@ -968,6 +968,12 @@ gst_ogg_mux_queue_pads (GstOggMux * ogg_mux, gboolean * popped)
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG_OBJECT (pad, "caps detected: %" GST_PTR_FORMAT,
|
GST_DEBUG_OBJECT (pad, "caps detected: %" GST_PTR_FORMAT,
|
||||||
pad->map.caps);
|
pad->map.caps);
|
||||||
|
|
||||||
|
if (pad->map.is_sparse) {
|
||||||
|
GST_DEBUG_OBJECT (pad, "Pad is sparse, marking as such");
|
||||||
|
gst_collect_pads2_set_waiting (ogg_mux->collect,
|
||||||
|
(GstCollectData2 *) pad, FALSE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (caps)
|
if (caps)
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
|
@ -1325,8 +1331,8 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
|
||||||
|
|
||||||
GST_LOG_OBJECT (mux, "looking at pad %s:%s", GST_DEBUG_PAD_NAME (thepad));
|
GST_LOG_OBJECT (mux, "looking at pad %s:%s", GST_DEBUG_PAD_NAME (thepad));
|
||||||
|
|
||||||
/* if the pad has no buffer, we don't care */
|
/* if the pad has no buffer and is not sparse, we don't care */
|
||||||
if (pad->buffer == NULL)
|
if (pad->buffer == NULL && !pad->map.is_sparse)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* now figure out the headers */
|
/* now figure out the headers */
|
||||||
|
|
|
@ -11,7 +11,7 @@ libgstvorbis_la_SOURCES = gstvorbis.c \
|
||||||
gstvorbistag.c \
|
gstvorbistag.c \
|
||||||
gstvorbiscommon.c
|
gstvorbiscommon.c
|
||||||
|
|
||||||
libgstvorbis_la_CFLAGS = -DGST_USE_UNSTABLE_API \
|
libgstvorbis_la_CFLAGS = \
|
||||||
$(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(VORBIS_CFLAGS)
|
$(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(VORBIS_CFLAGS)
|
||||||
## AM_PATH_VORBIS also sets VORBISENC_LIBS
|
## AM_PATH_VORBIS also sets VORBISENC_LIBS
|
||||||
libgstvorbis_la_LIBADD = \
|
libgstvorbis_la_LIBADD = \
|
||||||
|
@ -28,7 +28,7 @@ plugin_LTLIBRARIES += libgstivorbisdec.la
|
||||||
|
|
||||||
libgstivorbisdec_la_SOURCES = gstivorbisdec.c \
|
libgstivorbisdec_la_SOURCES = gstivorbisdec.c \
|
||||||
gstvorbisdec.c gstvorbisdeclib.c gstvorbiscommon.c
|
gstvorbisdec.c gstvorbisdeclib.c gstvorbiscommon.c
|
||||||
libgstivorbisdec_la_CFLAGS = -DGST_USE_UNSTABLE_API \
|
libgstivorbisdec_la_CFLAGS = \
|
||||||
$(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
|
$(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
|
||||||
-DTREMOR $(IVORBIS_CFLAGS)
|
-DTREMOR $(IVORBIS_CFLAGS)
|
||||||
libgstivorbisdec_la_LIBADD = \
|
libgstivorbisdec_la_LIBADD = \
|
||||||
|
|
|
@ -65,7 +65,7 @@ GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS ("audio/x-raw, "
|
GST_STATIC_CAPS ("audio/x-raw, "
|
||||||
"format = (string) " GST_AUDIO_NE (F32) ", "
|
"format = (string) " GST_AUDIO_NE (F32) ", "
|
||||||
"rate = (int) [ 1, 200000 ], " "channels = (int) [ 1, 256 ]")
|
"rate = (int) [ 1, 200000 ], " "channels = (int) [ 1, 255 ]")
|
||||||
);
|
);
|
||||||
|
|
||||||
static GstStaticPadTemplate vorbis_enc_src_factory =
|
static GstStaticPadTemplate vorbis_enc_src_factory =
|
||||||
|
@ -295,7 +295,7 @@ gst_vorbis_enc_generate_sink_caps (void)
|
||||||
gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw",
|
gst_caps_append_structure (caps, gst_structure_new ("audio/x-raw",
|
||||||
"format", G_TYPE_STRING, GST_AUDIO_NE (F32),
|
"format", G_TYPE_STRING, GST_AUDIO_NE (F32),
|
||||||
"rate", GST_TYPE_INT_RANGE, 1, 200000,
|
"rate", GST_TYPE_INT_RANGE, 1, 200000,
|
||||||
"channels", GST_TYPE_INT_RANGE, 9, 256, NULL));
|
"channels", GST_TYPE_INT_RANGE, 9, 255, NULL));
|
||||||
|
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,6 @@ GstAudio-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgstaudio-@GST_MAJORMI
|
||||||
--nsversion=@GST_MAJORMINOR@ \
|
--nsversion=@GST_MAJORMINOR@ \
|
||||||
--warn-all \
|
--warn-all \
|
||||||
--strip-prefix=Gst \
|
--strip-prefix=Gst \
|
||||||
-DGST_USE_UNSTABLE_API \
|
|
||||||
-I$(top_srcdir)/gst-libs \
|
-I$(top_srcdir)/gst-libs \
|
||||||
-I$(top_builddir)/gst-libs \
|
-I$(top_builddir)/gst-libs \
|
||||||
$(gir_cincludes) \
|
$(gir_cincludes) \
|
||||||
|
|
|
@ -23,11 +23,6 @@
|
||||||
#ifndef _GST_AUDIO_DECODER_H_
|
#ifndef _GST_AUDIO_DECODER_H_
|
||||||
#define _GST_AUDIO_DECODER_H_
|
#define _GST_AUDIO_DECODER_H_
|
||||||
|
|
||||||
#ifndef GST_USE_UNSTABLE_API
|
|
||||||
#warning "GstAudioDecoder is unstable API and may change in future."
|
|
||||||
#warning "You can define GST_USE_UNSTABLE_API to avoid this warning."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/audio/audio.h>
|
#include <gst/audio/audio.h>
|
||||||
#include <gst/base/gstadapter.h>
|
#include <gst/base/gstadapter.h>
|
||||||
|
|
|
@ -22,11 +22,6 @@
|
||||||
#ifndef __GST_AUDIO_ENCODER_H__
|
#ifndef __GST_AUDIO_ENCODER_H__
|
||||||
#define __GST_AUDIO_ENCODER_H__
|
#define __GST_AUDIO_ENCODER_H__
|
||||||
|
|
||||||
#ifndef GST_USE_UNSTABLE_API
|
|
||||||
#warning "GstAudioEncoder is unstable API and may change in future."
|
|
||||||
#warning "You can define GST_USE_UNSTABLE_API to avoid this warning."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/audio/audio.h>
|
#include <gst/audio/audio.h>
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,8 @@ G_BEGIN_DECLS
|
||||||
#define GST_RIFF_TAG_JUNQ GST_MAKE_FOURCC ('J','U','N','Q')
|
#define GST_RIFF_TAG_JUNQ GST_MAKE_FOURCC ('J','U','N','Q')
|
||||||
#define GST_RIFF_TAG_idx1 GST_MAKE_FOURCC ('i','d','x','1')
|
#define GST_RIFF_TAG_idx1 GST_MAKE_FOURCC ('i','d','x','1')
|
||||||
#define GST_RIFF_TAG_dmlh GST_MAKE_FOURCC ('d','m','l','h')
|
#define GST_RIFF_TAG_dmlh GST_MAKE_FOURCC ('d','m','l','h')
|
||||||
|
#define GST_RIFF_TAG_ID32 GST_MAKE_FOURCC ('I','D','3','2')
|
||||||
|
#define GST_RIFF_TAG_IDVX GST_MAKE_FOURCC ('I','D','V','X')
|
||||||
/* WAV stuff */
|
/* WAV stuff */
|
||||||
#define GST_RIFF_TAG_fmt GST_MAKE_FOURCC ('f','m','t',' ')
|
#define GST_RIFF_TAG_fmt GST_MAKE_FOURCC ('f','m','t',' ')
|
||||||
#define GST_RIFF_TAG_data GST_MAKE_FOURCC ('d','a','t','a')
|
#define GST_RIFF_TAG_data GST_MAKE_FOURCC ('d','a','t','a')
|
||||||
|
|
|
@ -173,8 +173,6 @@ struct _GstDecodeBin
|
||||||
|
|
||||||
gboolean expose_allstreams; /* Whether to expose unknow type streams or not */
|
gboolean expose_allstreams; /* Whether to expose unknow type streams or not */
|
||||||
|
|
||||||
gboolean upstream_seekable; /* if upstream is seekable */
|
|
||||||
|
|
||||||
GList *filtered; /* elements for which error messages are filtered */
|
GList *filtered; /* elements for which error messages are filtered */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -268,7 +266,7 @@ static void type_found (GstElement * typefind, guint probability,
|
||||||
GstCaps * caps, GstDecodeBin * decode_bin);
|
GstCaps * caps, GstDecodeBin * decode_bin);
|
||||||
|
|
||||||
static void decodebin_set_queue_size (GstDecodeBin * dbin,
|
static void decodebin_set_queue_size (GstDecodeBin * dbin,
|
||||||
GstElement * multiqueue, gboolean preroll);
|
GstElement * multiqueue, gboolean preroll, gboolean seekable);
|
||||||
|
|
||||||
static gboolean gst_decode_bin_autoplug_continue (GstElement * element,
|
static gboolean gst_decode_bin_autoplug_continue (GstElement * element,
|
||||||
GstPad * pad, GstCaps * caps);
|
GstPad * pad, GstCaps * caps);
|
||||||
|
@ -293,6 +291,8 @@ static GstStateChangeReturn gst_decode_bin_change_state (GstElement * element,
|
||||||
GstStateChange transition);
|
GstStateChange transition);
|
||||||
static void gst_decode_bin_handle_message (GstBin * bin, GstMessage * message);
|
static void gst_decode_bin_handle_message (GstBin * bin, GstMessage * message);
|
||||||
|
|
||||||
|
static gboolean check_upstream_seekable (GstDecodeBin * dbin, GstPad * pad);
|
||||||
|
|
||||||
#define EXPOSE_LOCK(dbin) G_STMT_START { \
|
#define EXPOSE_LOCK(dbin) G_STMT_START { \
|
||||||
GST_LOG_OBJECT (dbin, \
|
GST_LOG_OBJECT (dbin, \
|
||||||
"expose locking from thread %p", \
|
"expose locking from thread %p", \
|
||||||
|
@ -393,6 +393,7 @@ struct _GstDecodeChain
|
||||||
GstPad *pad; /* srcpad that caused creation of this chain */
|
GstPad *pad; /* srcpad that caused creation of this chain */
|
||||||
|
|
||||||
gboolean demuxer; /* TRUE if elements->data is a demuxer */
|
gboolean demuxer; /* TRUE if elements->data is a demuxer */
|
||||||
|
gboolean seekable; /* TRUE if this chain ends on a demuxer and is seekable */
|
||||||
GList *elements; /* All elements in this group, first
|
GList *elements; /* All elements in this group, first
|
||||||
is the latest and most downstream element */
|
is the latest and most downstream element */
|
||||||
|
|
||||||
|
@ -2203,40 +2204,39 @@ beach:
|
||||||
*
|
*
|
||||||
* Check if upstream is seekable.
|
* Check if upstream is seekable.
|
||||||
*/
|
*/
|
||||||
static void
|
static gboolean
|
||||||
check_upstream_seekable (GstDecodeBin * dbin, GstPad * pad)
|
check_upstream_seekable (GstDecodeBin * dbin, GstPad * pad)
|
||||||
{
|
{
|
||||||
GstQuery *query;
|
GstQuery *query;
|
||||||
gint64 start = -1, stop = -1;
|
gint64 start = -1, stop = -1;
|
||||||
|
gboolean seekable = FALSE;
|
||||||
dbin->upstream_seekable = FALSE;
|
|
||||||
|
|
||||||
query = gst_query_new_seeking (GST_FORMAT_BYTES);
|
query = gst_query_new_seeking (GST_FORMAT_BYTES);
|
||||||
if (!gst_pad_peer_query (pad, query)) {
|
if (!gst_pad_peer_query (pad, query)) {
|
||||||
GST_DEBUG_OBJECT (dbin, "seeking query failed");
|
GST_DEBUG_OBJECT (dbin, "seeking query failed");
|
||||||
gst_query_unref (query);
|
gst_query_unref (query);
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_query_parse_seeking (query, NULL, &dbin->upstream_seekable,
|
gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
|
||||||
&start, &stop);
|
|
||||||
|
|
||||||
gst_query_unref (query);
|
gst_query_unref (query);
|
||||||
|
|
||||||
/* try harder to query upstream size if we didn't get it the first time */
|
/* try harder to query upstream size if we didn't get it the first time */
|
||||||
if (dbin->upstream_seekable && stop == -1) {
|
if (seekable && stop == -1) {
|
||||||
GST_DEBUG_OBJECT (dbin, "doing duration query to fix up unset stop");
|
GST_DEBUG_OBJECT (dbin, "doing duration query to fix up unset stop");
|
||||||
gst_pad_peer_query_duration (pad, GST_FORMAT_BYTES, &stop);
|
gst_pad_peer_query_duration (pad, GST_FORMAT_BYTES, &stop);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if upstream doesn't know the size, it's likely that it's not seekable in
|
/* if upstream doesn't know the size, it's likely that it's not seekable in
|
||||||
* practice even if it technically may be seekable */
|
* practice even if it technically may be seekable */
|
||||||
if (dbin->upstream_seekable && (start != 0 || stop <= start)) {
|
if (seekable && (start != 0 || stop <= start)) {
|
||||||
GST_DEBUG_OBJECT (dbin, "seekable but unknown start/stop -> disable");
|
GST_DEBUG_OBJECT (dbin, "seekable but unknown start/stop -> disable");
|
||||||
dbin->upstream_seekable = FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (dbin, "upstream seekable: %d", dbin->upstream_seekable);
|
GST_DEBUG_OBJECT (dbin, "upstream seekable: %d", seekable);
|
||||||
|
return seekable;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2267,10 +2267,6 @@ type_found (GstElement * typefind, guint probability,
|
||||||
pad = gst_element_get_static_pad (typefind, "src");
|
pad = gst_element_get_static_pad (typefind, "src");
|
||||||
sink_pad = gst_element_get_static_pad (typefind, "sink");
|
sink_pad = gst_element_get_static_pad (typefind, "sink");
|
||||||
|
|
||||||
/* if upstream is seekable we can safely set a limit in time to the queues so
|
|
||||||
* that streams at low bitrates can preroll */
|
|
||||||
check_upstream_seekable (decode_bin, sink_pad);
|
|
||||||
|
|
||||||
/* need some lock here to prevent race with shutdown state change
|
/* need some lock here to prevent race with shutdown state change
|
||||||
* which might yank away e.g. decode_chain while building stuff here.
|
* which might yank away e.g. decode_chain while building stuff here.
|
||||||
* In typical cases, STREAM_LOCK is held and handles that, it need not
|
* In typical cases, STREAM_LOCK is held and handles that, it need not
|
||||||
|
@ -2404,7 +2400,8 @@ no_more_pads_cb (GstElement * element, GstDecodeChain * chain)
|
||||||
* we can probably set its buffering state to playing now */
|
* we can probably set its buffering state to playing now */
|
||||||
GST_DEBUG_OBJECT (group->dbin, "Setting group %p multiqueue to "
|
GST_DEBUG_OBJECT (group->dbin, "Setting group %p multiqueue to "
|
||||||
"'playing' buffering mode", group);
|
"'playing' buffering mode", group);
|
||||||
decodebin_set_queue_size (group->dbin, group->multiqueue, FALSE);
|
decodebin_set_queue_size (group->dbin, group->multiqueue, FALSE,
|
||||||
|
(group->parent ? group->parent->seekable : TRUE));
|
||||||
CHAIN_MUTEX_UNLOCK (chain);
|
CHAIN_MUTEX_UNLOCK (chain);
|
||||||
|
|
||||||
EXPOSE_LOCK (chain->dbin);
|
EXPOSE_LOCK (chain->dbin);
|
||||||
|
@ -2753,6 +2750,12 @@ multi_queue_overrun_cb (GstElement * queue, GstDecodeGroup * group)
|
||||||
queue);
|
queue);
|
||||||
|
|
||||||
group->overrun = TRUE;
|
group->overrun = TRUE;
|
||||||
|
/* this group has prerolled enough to not need more pads,
|
||||||
|
* we can probably set its buffering state to playing now */
|
||||||
|
GST_DEBUG_OBJECT (group->dbin, "Setting group %p multiqueue to "
|
||||||
|
"'playing' buffering mode", group);
|
||||||
|
decodebin_set_queue_size (group->dbin, group->multiqueue, FALSE,
|
||||||
|
(group->parent ? group->parent->seekable : TRUE));
|
||||||
|
|
||||||
/* FIXME: We should make sure that everything gets exposed now
|
/* FIXME: We should make sure that everything gets exposed now
|
||||||
* even if child chains are not complete because the will never
|
* even if child chains are not complete because the will never
|
||||||
|
@ -2858,7 +2861,7 @@ gst_decode_group_hide (GstDecodeGroup * group)
|
||||||
* playing or prerolling. */
|
* playing or prerolling. */
|
||||||
static void
|
static void
|
||||||
decodebin_set_queue_size (GstDecodeBin * dbin, GstElement * multiqueue,
|
decodebin_set_queue_size (GstDecodeBin * dbin, GstElement * multiqueue,
|
||||||
gboolean preroll)
|
gboolean preroll, gboolean seekable)
|
||||||
{
|
{
|
||||||
guint max_bytes, max_buffers;
|
guint max_bytes, max_buffers;
|
||||||
guint64 max_time;
|
guint64 max_time;
|
||||||
|
@ -2871,7 +2874,7 @@ decodebin_set_queue_size (GstDecodeBin * dbin, GstElement * multiqueue,
|
||||||
if ((max_buffers = dbin->max_size_buffers) == 0)
|
if ((max_buffers = dbin->max_size_buffers) == 0)
|
||||||
max_buffers = AUTO_PREROLL_SIZE_BUFFERS;
|
max_buffers = AUTO_PREROLL_SIZE_BUFFERS;
|
||||||
if ((max_time = dbin->max_size_time) == 0)
|
if ((max_time = dbin->max_size_time) == 0)
|
||||||
max_time = dbin->upstream_seekable ? AUTO_PREROLL_SEEKABLE_SIZE_TIME :
|
max_time = seekable ? AUTO_PREROLL_SEEKABLE_SIZE_TIME :
|
||||||
AUTO_PREROLL_NOT_SEEKABLE_SIZE_TIME;
|
AUTO_PREROLL_NOT_SEEKABLE_SIZE_TIME;
|
||||||
} else {
|
} else {
|
||||||
/* update runtime limits. At runtime, we try to keep the amount of buffers
|
/* update runtime limits. At runtime, we try to keep the amount of buffers
|
||||||
|
@ -2901,6 +2904,7 @@ gst_decode_group_new (GstDecodeBin * dbin, GstDecodeChain * parent)
|
||||||
{
|
{
|
||||||
GstDecodeGroup *group = g_slice_new0 (GstDecodeGroup);
|
GstDecodeGroup *group = g_slice_new0 (GstDecodeGroup);
|
||||||
GstElement *mq;
|
GstElement *mq;
|
||||||
|
gboolean seekable;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (dbin, "Creating new group %p with parent chain %p", group,
|
GST_DEBUG_OBJECT (dbin, "Creating new group %p with parent chain %p", group,
|
||||||
parent);
|
parent);
|
||||||
|
@ -2921,7 +2925,17 @@ gst_decode_group_new (GstDecodeBin * dbin, GstDecodeChain * parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* configure queue sizes for preroll */
|
/* configure queue sizes for preroll */
|
||||||
decodebin_set_queue_size (dbin, mq, TRUE);
|
seekable = FALSE;
|
||||||
|
if (parent && parent->demuxer) {
|
||||||
|
GstElement *element =
|
||||||
|
((GstDecodeElement *) parent->elements->data)->element;
|
||||||
|
GstPad *pad = gst_element_get_static_pad (element, "sink");
|
||||||
|
if (pad) {
|
||||||
|
seekable = parent->seekable = check_upstream_seekable (dbin, pad);
|
||||||
|
gst_object_unref (pad);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
decodebin_set_queue_size (dbin, mq, TRUE, seekable);
|
||||||
|
|
||||||
group->overrunsig = g_signal_connect (G_OBJECT (mq), "overrun",
|
group->overrunsig = g_signal_connect (G_OBJECT (mq), "overrun",
|
||||||
G_CALLBACK (multi_queue_overrun_cb), group);
|
G_CALLBACK (multi_queue_overrun_cb), group);
|
||||||
|
@ -3682,7 +3696,7 @@ gst_decode_chain_expose (GstDecodeChain * chain, GList ** endpads,
|
||||||
dbin = group->dbin;
|
dbin = group->dbin;
|
||||||
|
|
||||||
/* configure queues for playback */
|
/* configure queues for playback */
|
||||||
decodebin_set_queue_size (dbin, group->multiqueue, FALSE);
|
decodebin_set_queue_size (dbin, group->multiqueue, FALSE, TRUE);
|
||||||
|
|
||||||
/* we can now disconnect any overrun signal, which is used to expose the
|
/* we can now disconnect any overrun signal, which is used to expose the
|
||||||
* group. */
|
* group. */
|
||||||
|
|
|
@ -825,6 +825,8 @@ gst_play_bin_class_init (GstPlayBinClass * klass)
|
||||||
*
|
*
|
||||||
* This signal is emitted when the current uri is about to finish. You can
|
* This signal is emitted when the current uri is about to finish. You can
|
||||||
* set the uri and suburi to make sure that playback continues.
|
* set the uri and suburi to make sure that playback continues.
|
||||||
|
*
|
||||||
|
* This signal is emitted from the context of a GStreamer streaming thread.
|
||||||
*/
|
*/
|
||||||
gst_play_bin_signals[SIGNAL_ABOUT_TO_FINISH] =
|
gst_play_bin_signals[SIGNAL_ABOUT_TO_FINISH] =
|
||||||
g_signal_new ("about-to-finish", G_TYPE_FROM_CLASS (klass),
|
g_signal_new ("about-to-finish", G_TYPE_FROM_CLASS (klass),
|
||||||
|
@ -839,7 +841,12 @@ gst_play_bin_class_init (GstPlayBinClass * klass)
|
||||||
* This signal is emitted whenever the number or order of the video
|
* This signal is emitted whenever the number or order of the video
|
||||||
* streams has changed. The application will most likely want to select
|
* streams has changed. The application will most likely want to select
|
||||||
* a new video stream.
|
* a new video stream.
|
||||||
|
*
|
||||||
|
* This signal is usually emitted from the context of a GStreamer streaming
|
||||||
|
* thread. You can use gst_message_new_application() and
|
||||||
|
* gst_element_post_message() to notify your application's main thread.
|
||||||
*/
|
*/
|
||||||
|
/* FIXME 0.11: turn video-changed signal into message? */
|
||||||
gst_play_bin_signals[SIGNAL_VIDEO_CHANGED] =
|
gst_play_bin_signals[SIGNAL_VIDEO_CHANGED] =
|
||||||
g_signal_new ("video-changed", G_TYPE_FROM_CLASS (klass),
|
g_signal_new ("video-changed", G_TYPE_FROM_CLASS (klass),
|
||||||
G_SIGNAL_RUN_LAST,
|
G_SIGNAL_RUN_LAST,
|
||||||
|
@ -852,7 +859,12 @@ gst_play_bin_class_init (GstPlayBinClass * klass)
|
||||||
* This signal is emitted whenever the number or order of the audio
|
* This signal is emitted whenever the number or order of the audio
|
||||||
* streams has changed. The application will most likely want to select
|
* streams has changed. The application will most likely want to select
|
||||||
* a new audio stream.
|
* a new audio stream.
|
||||||
|
*
|
||||||
|
* This signal may be emitted from the context of a GStreamer streaming thread.
|
||||||
|
* You can use gst_message_new_application() and gst_element_post_message()
|
||||||
|
* to notify your application's main thread.
|
||||||
*/
|
*/
|
||||||
|
/* FIXME 0.11: turn audio-changed signal into message? */
|
||||||
gst_play_bin_signals[SIGNAL_AUDIO_CHANGED] =
|
gst_play_bin_signals[SIGNAL_AUDIO_CHANGED] =
|
||||||
g_signal_new ("audio-changed", G_TYPE_FROM_CLASS (klass),
|
g_signal_new ("audio-changed", G_TYPE_FROM_CLASS (klass),
|
||||||
G_SIGNAL_RUN_LAST,
|
G_SIGNAL_RUN_LAST,
|
||||||
|
@ -865,7 +877,12 @@ gst_play_bin_class_init (GstPlayBinClass * klass)
|
||||||
* This signal is emitted whenever the number or order of the text
|
* This signal is emitted whenever the number or order of the text
|
||||||
* streams has changed. The application will most likely want to select
|
* streams has changed. The application will most likely want to select
|
||||||
* a new text stream.
|
* a new text stream.
|
||||||
|
*
|
||||||
|
* This signal may be emitted from the context of a GStreamer streaming thread.
|
||||||
|
* You can use gst_message_new_application() and gst_element_post_message()
|
||||||
|
* to notify your application's main thread.
|
||||||
*/
|
*/
|
||||||
|
/* FIXME 0.11: turn text-changed signal into message? */
|
||||||
gst_play_bin_signals[SIGNAL_TEXT_CHANGED] =
|
gst_play_bin_signals[SIGNAL_TEXT_CHANGED] =
|
||||||
g_signal_new ("text-changed", G_TYPE_FROM_CLASS (klass),
|
g_signal_new ("text-changed", G_TYPE_FROM_CLASS (klass),
|
||||||
G_SIGNAL_RUN_LAST,
|
G_SIGNAL_RUN_LAST,
|
||||||
|
@ -880,6 +897,10 @@ gst_play_bin_class_init (GstPlayBinClass * klass)
|
||||||
* This signal is emitted whenever the tags of a video stream have changed.
|
* This signal is emitted whenever the tags of a video stream have changed.
|
||||||
* The application will most likely want to get the new tags.
|
* The application will most likely want to get the new tags.
|
||||||
*
|
*
|
||||||
|
* This signal may be emitted from the context of a GStreamer streaming thread.
|
||||||
|
* You can use gst_message_new_application() and gst_element_post_message()
|
||||||
|
* to notify your application's main thread.
|
||||||
|
*
|
||||||
* Since: 0.10.24
|
* Since: 0.10.24
|
||||||
*/
|
*/
|
||||||
gst_play_bin_signals[SIGNAL_VIDEO_TAGS_CHANGED] =
|
gst_play_bin_signals[SIGNAL_VIDEO_TAGS_CHANGED] =
|
||||||
|
@ -896,6 +917,10 @@ gst_play_bin_class_init (GstPlayBinClass * klass)
|
||||||
* This signal is emitted whenever the tags of an audio stream have changed.
|
* This signal is emitted whenever the tags of an audio stream have changed.
|
||||||
* The application will most likely want to get the new tags.
|
* The application will most likely want to get the new tags.
|
||||||
*
|
*
|
||||||
|
* This signal may be emitted from the context of a GStreamer streaming thread.
|
||||||
|
* You can use gst_message_new_application() and gst_element_post_message()
|
||||||
|
* to notify your application's main thread.
|
||||||
|
*
|
||||||
* Since: 0.10.24
|
* Since: 0.10.24
|
||||||
*/
|
*/
|
||||||
gst_play_bin_signals[SIGNAL_AUDIO_TAGS_CHANGED] =
|
gst_play_bin_signals[SIGNAL_AUDIO_TAGS_CHANGED] =
|
||||||
|
@ -912,6 +937,10 @@ gst_play_bin_class_init (GstPlayBinClass * klass)
|
||||||
* This signal is emitted whenever the tags of a text stream have changed.
|
* This signal is emitted whenever the tags of a text stream have changed.
|
||||||
* The application will most likely want to get the new tags.
|
* The application will most likely want to get the new tags.
|
||||||
*
|
*
|
||||||
|
* This signal may be emitted from the context of a GStreamer streaming thread.
|
||||||
|
* You can use gst_message_new_application() and gst_element_post_message()
|
||||||
|
* to notify your application's main thread.
|
||||||
|
*
|
||||||
* Since: 0.10.24
|
* Since: 0.10.24
|
||||||
*/
|
*/
|
||||||
gst_play_bin_signals[SIGNAL_TEXT_TAGS_CHANGED] =
|
gst_play_bin_signals[SIGNAL_TEXT_TAGS_CHANGED] =
|
||||||
|
@ -931,6 +960,9 @@ gst_play_bin_class_init (GstPlayBinClass * klass)
|
||||||
* an audio cd source). This is functionally equivalent to connecting to
|
* an audio cd source). This is functionally equivalent to connecting to
|
||||||
* the notify::source signal, but more convenient.
|
* the notify::source signal, but more convenient.
|
||||||
*
|
*
|
||||||
|
* This signal is usually emitted from the context of a GStreamer streaming
|
||||||
|
* thread.
|
||||||
|
*
|
||||||
* Since: 0.10.33
|
* Since: 0.10.33
|
||||||
*/
|
*/
|
||||||
gst_play_bin_signals[SIGNAL_SOURCE_SETUP] =
|
gst_play_bin_signals[SIGNAL_SOURCE_SETUP] =
|
||||||
|
|
|
@ -179,12 +179,12 @@ gst_play_sink_audio_convert_class_init (GstPlaySinkAudioConvertClass * klass)
|
||||||
g_object_class_install_property (gobject_class, PROP_USE_CONVERTERS,
|
g_object_class_install_property (gobject_class, PROP_USE_CONVERTERS,
|
||||||
g_param_spec_boolean ("use-converters", "Use converters",
|
g_param_spec_boolean ("use-converters", "Use converters",
|
||||||
"Whether to use conversion elements", FALSE,
|
"Whether to use conversion elements", FALSE,
|
||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class, PROP_USE_VOLUME,
|
g_object_class_install_property (gobject_class, PROP_USE_VOLUME,
|
||||||
g_param_spec_boolean ("use-volume", "Use volume",
|
g_param_spec_boolean ("use-volume", "Use volume",
|
||||||
"Whether to use a volume element", FALSE,
|
"Whether to use a volume element", FALSE,
|
||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
gst_element_class_set_details_simple (gstelement_class,
|
gst_element_class_set_details_simple (gstelement_class,
|
||||||
"Player Sink Audio Converter", "Audio/Bin/Converter",
|
"Player Sink Audio Converter", "Audio/Bin/Converter",
|
||||||
|
|
|
@ -137,7 +137,8 @@ gst_play_sink_convert_bin_add_identity (GstPlaySinkConvertBin * self)
|
||||||
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
g_object_set (self->identity, "silent", TRUE, NULL);
|
g_object_set (self->identity, "silent", TRUE, "signal-handoffs", FALSE,
|
||||||
|
NULL);
|
||||||
gst_bin_add (GST_BIN_CAST (self), self->identity);
|
gst_bin_add (GST_BIN_CAST (self), self->identity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -335,11 +336,23 @@ gst_play_sink_convert_bin_sink_setcaps (GstPlaySinkConvertBin * self,
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "raw %d, self->raw %d, blocked %d",
|
GST_DEBUG_OBJECT (self, "raw %d, self->raw %d, blocked %d",
|
||||||
raw, self->raw, gst_pad_is_blocked (self->sink_proxypad));
|
raw, self->raw, gst_pad_is_blocked (self->sink_proxypad));
|
||||||
|
|
||||||
if (raw) {
|
if (raw) {
|
||||||
if (!self->raw && !gst_pad_is_blocked (self->sink_proxypad)) {
|
if (!gst_pad_is_blocked (self->sink_proxypad)) {
|
||||||
GST_DEBUG_OBJECT (self, "Changing caps from non-raw to raw");
|
GstPad *target = gst_ghost_pad_get_target (GST_GHOST_PAD (self->sinkpad));
|
||||||
reconfigure = TRUE;
|
|
||||||
block_proxypad (self);
|
if (!self->raw || (target && !gst_pad_query_accept_caps (target, caps))) {
|
||||||
|
if (!self->raw)
|
||||||
|
GST_DEBUG_OBJECT (self, "Changing caps from non-raw to raw");
|
||||||
|
else
|
||||||
|
GST_DEBUG_OBJECT (self, "Changing caps in an incompatible way");
|
||||||
|
|
||||||
|
reconfigure = TRUE;
|
||||||
|
block_proxypad (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target)
|
||||||
|
gst_object_unref (target);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (self->raw && !gst_pad_is_blocked (self->sink_proxypad)) {
|
if (self->raw && !gst_pad_is_blocked (self->sink_proxypad)) {
|
||||||
|
@ -402,6 +415,22 @@ gst_play_sink_convert_bin_getcaps (GstPad * pad, GstCaps * filter)
|
||||||
|
|
||||||
gst_object_unref (self);
|
gst_object_unref (self);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (pad, "Returning caps %" GST_PTR_FORMAT, ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_play_sink_convert_bin_acceptcaps (GstPad * pad, GstCaps * caps)
|
||||||
|
{
|
||||||
|
GstCaps *allowed_caps;
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
allowed_caps = gst_pad_query_caps (pad, NULL);
|
||||||
|
/* FIXME 0.11: Should be a subset check now */
|
||||||
|
ret = gst_caps_can_intersect (caps, allowed_caps);
|
||||||
|
gst_caps_unref (allowed_caps);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,6 +441,16 @@ gst_play_sink_convert_bin_query (GstPad * pad, GstObject * parent,
|
||||||
gboolean res = FALSE;
|
gboolean res = FALSE;
|
||||||
|
|
||||||
switch (GST_QUERY_TYPE (query)) {
|
switch (GST_QUERY_TYPE (query)) {
|
||||||
|
case GST_QUERY_ACCEPT_CAPS:
|
||||||
|
{
|
||||||
|
GstCaps *caps;
|
||||||
|
|
||||||
|
gst_query_parse_accept_caps (query, &caps);
|
||||||
|
gst_query_set_accept_caps_result (query,
|
||||||
|
gst_play_sink_convert_bin_acceptcaps (pad, caps));
|
||||||
|
res = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case GST_QUERY_CAPS:
|
case GST_QUERY_CAPS:
|
||||||
{
|
{
|
||||||
GstCaps *filter, *caps;
|
GstCaps *filter, *caps;
|
||||||
|
|
|
@ -92,18 +92,17 @@ enum
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
ARG_0,
|
PROP_0,
|
||||||
ARG_IN,
|
PROP_IN,
|
||||||
ARG_OUT,
|
PROP_OUT,
|
||||||
ARG_DUP,
|
PROP_DUP,
|
||||||
ARG_DROP,
|
PROP_DROP,
|
||||||
ARG_SILENT,
|
PROP_SILENT,
|
||||||
ARG_NEW_PREF,
|
PROP_NEW_PREF,
|
||||||
ARG_SKIP_TO_FIRST,
|
PROP_SKIP_TO_FIRST,
|
||||||
ARG_DROP_ONLY,
|
PROP_DROP_ONLY,
|
||||||
ARG_AVERAGE_PERIOD,
|
PROP_AVERAGE_PERIOD,
|
||||||
ARG_MAX_RATE
|
PROP_MAX_RATE
|
||||||
/* FILL ME */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static GstStaticPadTemplate gst_video_rate_src_template =
|
static GstStaticPadTemplate gst_video_rate_src_template =
|
||||||
|
@ -172,25 +171,25 @@ gst_video_rate_class_init (GstVideoRateClass * klass)
|
||||||
base_class->fixate_caps = GST_DEBUG_FUNCPTR (gst_video_rate_fixate_caps);
|
base_class->fixate_caps = GST_DEBUG_FUNCPTR (gst_video_rate_fixate_caps);
|
||||||
base_class->query = GST_DEBUG_FUNCPTR (gst_video_rate_query);
|
base_class->query = GST_DEBUG_FUNCPTR (gst_video_rate_query);
|
||||||
|
|
||||||
g_object_class_install_property (object_class, ARG_IN,
|
g_object_class_install_property (object_class, PROP_IN,
|
||||||
g_param_spec_uint64 ("in", "In",
|
g_param_spec_uint64 ("in", "In",
|
||||||
"Number of input frames", 0, G_MAXUINT64, 0,
|
"Number of input frames", 0, G_MAXUINT64, 0,
|
||||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||||
g_object_class_install_property (object_class, ARG_OUT,
|
g_object_class_install_property (object_class, PROP_OUT,
|
||||||
g_param_spec_uint64 ("out", "Out", "Number of output frames", 0,
|
g_param_spec_uint64 ("out", "Out", "Number of output frames", 0,
|
||||||
G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||||
pspec_duplicate = g_param_spec_uint64 ("duplicate", "Duplicate",
|
pspec_duplicate = g_param_spec_uint64 ("duplicate", "Duplicate",
|
||||||
"Number of duplicated frames", 0, G_MAXUINT64, 0,
|
"Number of duplicated frames", 0, G_MAXUINT64, 0,
|
||||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||||
g_object_class_install_property (object_class, ARG_DUP, pspec_duplicate);
|
g_object_class_install_property (object_class, PROP_DUP, pspec_duplicate);
|
||||||
pspec_drop = g_param_spec_uint64 ("drop", "Drop", "Number of dropped frames",
|
pspec_drop = g_param_spec_uint64 ("drop", "Drop", "Number of dropped frames",
|
||||||
0, G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
0, G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||||
g_object_class_install_property (object_class, ARG_DROP, pspec_drop);
|
g_object_class_install_property (object_class, PROP_DROP, pspec_drop);
|
||||||
g_object_class_install_property (object_class, ARG_SILENT,
|
g_object_class_install_property (object_class, PROP_SILENT,
|
||||||
g_param_spec_boolean ("silent", "silent",
|
g_param_spec_boolean ("silent", "silent",
|
||||||
"Don't emit notify for dropped and duplicated frames", DEFAULT_SILENT,
|
"Don't emit notify for dropped and duplicated frames", DEFAULT_SILENT,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
g_object_class_install_property (object_class, ARG_NEW_PREF,
|
g_object_class_install_property (object_class, PROP_NEW_PREF,
|
||||||
g_param_spec_double ("new-pref", "New Pref",
|
g_param_spec_double ("new-pref", "New Pref",
|
||||||
"Value indicating how much to prefer new frames (unused)", 0.0, 1.0,
|
"Value indicating how much to prefer new frames (unused)", 0.0, 1.0,
|
||||||
DEFAULT_NEW_PREF, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
DEFAULT_NEW_PREF, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
@ -202,7 +201,7 @@ gst_video_rate_class_init (GstVideoRateClass * klass)
|
||||||
*
|
*
|
||||||
* Since: 0.10.25
|
* Since: 0.10.25
|
||||||
*/
|
*/
|
||||||
g_object_class_install_property (object_class, ARG_SKIP_TO_FIRST,
|
g_object_class_install_property (object_class, PROP_SKIP_TO_FIRST,
|
||||||
g_param_spec_boolean ("skip-to-first", "Skip to first buffer",
|
g_param_spec_boolean ("skip-to-first", "Skip to first buffer",
|
||||||
"Don't produce buffers before the first one we receive",
|
"Don't produce buffers before the first one we receive",
|
||||||
DEFAULT_SKIP_TO_FIRST, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
DEFAULT_SKIP_TO_FIRST, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
@ -214,7 +213,7 @@ gst_video_rate_class_init (GstVideoRateClass * klass)
|
||||||
*
|
*
|
||||||
* Since: 0.10.36
|
* Since: 0.10.36
|
||||||
*/
|
*/
|
||||||
g_object_class_install_property (object_class, ARG_DROP_ONLY,
|
g_object_class_install_property (object_class, PROP_DROP_ONLY,
|
||||||
g_param_spec_boolean ("drop-only", "Only Drop",
|
g_param_spec_boolean ("drop-only", "Only Drop",
|
||||||
"Only drop frames, no duplicates are produced",
|
"Only drop frames, no duplicates are produced",
|
||||||
DEFAULT_DROP_ONLY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
DEFAULT_DROP_ONLY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
@ -228,7 +227,7 @@ gst_video_rate_class_init (GstVideoRateClass * klass)
|
||||||
*
|
*
|
||||||
* Since: 0.10.36
|
* Since: 0.10.36
|
||||||
*/
|
*/
|
||||||
g_object_class_install_property (object_class, ARG_AVERAGE_PERIOD,
|
g_object_class_install_property (object_class, PROP_AVERAGE_PERIOD,
|
||||||
g_param_spec_uint64 ("average-period", "Period over which to average",
|
g_param_spec_uint64 ("average-period", "Period over which to average",
|
||||||
"Period over which to average the framerate (in ns) (0 = disabled)",
|
"Period over which to average the framerate (in ns) (0 = disabled)",
|
||||||
0, G_MAXINT64, DEFAULT_AVERAGE_PERIOD,
|
0, G_MAXINT64, DEFAULT_AVERAGE_PERIOD,
|
||||||
|
@ -241,7 +240,7 @@ gst_video_rate_class_init (GstVideoRateClass * klass)
|
||||||
*
|
*
|
||||||
* Since: 0.10.36
|
* Since: 0.10.36
|
||||||
*/
|
*/
|
||||||
g_object_class_install_property (object_class, ARG_MAX_RATE,
|
g_object_class_install_property (object_class, PROP_MAX_RATE,
|
||||||
g_param_spec_int ("max-rate", "maximum framerate",
|
g_param_spec_int ("max-rate", "maximum framerate",
|
||||||
"Maximum framerate allowed to pass through "
|
"Maximum framerate allowed to pass through "
|
||||||
"(in frames per second, implies drop-only)",
|
"(in frames per second, implies drop-only)",
|
||||||
|
@ -1123,23 +1122,23 @@ gst_video_rate_set_property (GObject * object,
|
||||||
|
|
||||||
GST_OBJECT_LOCK (videorate);
|
GST_OBJECT_LOCK (videorate);
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case ARG_SILENT:
|
case PROP_SILENT:
|
||||||
videorate->silent = g_value_get_boolean (value);
|
videorate->silent = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
case ARG_NEW_PREF:
|
case PROP_NEW_PREF:
|
||||||
videorate->new_pref = g_value_get_double (value);
|
videorate->new_pref = g_value_get_double (value);
|
||||||
break;
|
break;
|
||||||
case ARG_SKIP_TO_FIRST:
|
case PROP_SKIP_TO_FIRST:
|
||||||
videorate->skip_to_first = g_value_get_boolean (value);
|
videorate->skip_to_first = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
case ARG_DROP_ONLY:
|
case PROP_DROP_ONLY:
|
||||||
videorate->drop_only = g_value_get_boolean (value);
|
videorate->drop_only = g_value_get_boolean (value);
|
||||||
goto reconfigure;
|
goto reconfigure;
|
||||||
break;
|
break;
|
||||||
case ARG_AVERAGE_PERIOD:
|
case PROP_AVERAGE_PERIOD:
|
||||||
videorate->average_period_set = g_value_get_uint64 (value);
|
videorate->average_period_set = g_value_get_uint64 (value);
|
||||||
break;
|
break;
|
||||||
case ARG_MAX_RATE:
|
case PROP_MAX_RATE:
|
||||||
g_atomic_int_set (&videorate->max_rate, g_value_get_int (value));
|
g_atomic_int_set (&videorate->max_rate, g_value_get_int (value));
|
||||||
goto reconfigure;
|
goto reconfigure;
|
||||||
break;
|
break;
|
||||||
|
@ -1163,34 +1162,34 @@ gst_video_rate_get_property (GObject * object,
|
||||||
|
|
||||||
GST_OBJECT_LOCK (videorate);
|
GST_OBJECT_LOCK (videorate);
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case ARG_IN:
|
case PROP_IN:
|
||||||
g_value_set_uint64 (value, videorate->in);
|
g_value_set_uint64 (value, videorate->in);
|
||||||
break;
|
break;
|
||||||
case ARG_OUT:
|
case PROP_OUT:
|
||||||
g_value_set_uint64 (value, videorate->out);
|
g_value_set_uint64 (value, videorate->out);
|
||||||
break;
|
break;
|
||||||
case ARG_DUP:
|
case PROP_DUP:
|
||||||
g_value_set_uint64 (value, videorate->dup);
|
g_value_set_uint64 (value, videorate->dup);
|
||||||
break;
|
break;
|
||||||
case ARG_DROP:
|
case PROP_DROP:
|
||||||
g_value_set_uint64 (value, videorate->drop);
|
g_value_set_uint64 (value, videorate->drop);
|
||||||
break;
|
break;
|
||||||
case ARG_SILENT:
|
case PROP_SILENT:
|
||||||
g_value_set_boolean (value, videorate->silent);
|
g_value_set_boolean (value, videorate->silent);
|
||||||
break;
|
break;
|
||||||
case ARG_NEW_PREF:
|
case PROP_NEW_PREF:
|
||||||
g_value_set_double (value, videorate->new_pref);
|
g_value_set_double (value, videorate->new_pref);
|
||||||
break;
|
break;
|
||||||
case ARG_SKIP_TO_FIRST:
|
case PROP_SKIP_TO_FIRST:
|
||||||
g_value_set_boolean (value, videorate->skip_to_first);
|
g_value_set_boolean (value, videorate->skip_to_first);
|
||||||
break;
|
break;
|
||||||
case ARG_DROP_ONLY:
|
case PROP_DROP_ONLY:
|
||||||
g_value_set_boolean (value, videorate->drop_only);
|
g_value_set_boolean (value, videorate->drop_only);
|
||||||
break;
|
break;
|
||||||
case ARG_AVERAGE_PERIOD:
|
case PROP_AVERAGE_PERIOD:
|
||||||
g_value_set_uint64 (value, videorate->average_period_set);
|
g_value_set_uint64 (value, videorate->average_period_set);
|
||||||
break;
|
break;
|
||||||
case ARG_MAX_RATE:
|
case PROP_MAX_RATE:
|
||||||
g_value_set_int (value, g_atomic_int_get (&videorate->max_rate));
|
g_value_set_int (value, g_atomic_int_get (&videorate->max_rate));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in a new issue