Advertisement
vliaskov

audiosink/RenderAudioSamples: sync w/ pipe clock, drop late

Dec 18th, 2014
245
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. diff --git a/docs/plugins/scanobj-build.stamp b/docs/plugins/scanobj-build.stamp
  2. deleted file mode 100644
  3. index e69de29..0000000
  4. diff --git a/sys/decklink/gstdecklinksink.cpp b/sys/decklink/gstdecklinksink.cpp
  5. index 257277d..657cf4e 100644
  6. --- a/sys/decklink/gstdecklinksink.cpp
  7. +++ b/sys/decklink/gstdecklinksink.cpp
  8. @@ -696,24 +696,76 @@ gst_decklink_sink_audiosink_chain (GstPad * pad, GstObject * parent,
  9. {
  10. GstDecklinkSink *decklinksink;
  11. GstFlowReturn ret;
  12. -
  13. + GstClockTime timestamp, duration;
  14. + GstClockTime running_time;
  15. + GstClockTime running_time_duration;
  16. + GstClock *clock;
  17. + GstClockID clock_id;
  18. + GstClockTime base_time;
  19. decklinksink = GST_DECKLINK_SINK (parent);
  20.  
  21. if (decklinksink->stop)
  22. return GST_FLOW_FLUSHING;
  23.  
  24. - g_mutex_lock (&decklinksink->audio_mutex);
  25. + timestamp = GST_BUFFER_TIMESTAMP (buffer);
  26. + duration = GST_BUFFER_DURATION (buffer);
  27. + if (duration == GST_CLOCK_TIME_NONE) {
  28. + duration = gst_util_uint64_scale_int (GST_SECOND, gst_buffer_get_size (buffer), 2 * 2 *48000);
  29. + GST_WARNING_OBJECT (decklinksink, "no audio duration, setting it to %lu",
  30. + duration);
  31. + }
  32. +
  33. + running_time =
  34. + gst_segment_to_running_time (&decklinksink->audio_segment,
  35. + GST_FORMAT_TIME, timestamp);
  36. + running_time_duration =
  37. + gst_segment_to_running_time (&decklinksink->audio_segment,
  38. + GST_FORMAT_TIME, timestamp + duration) - running_time;
  39. +
  40. + clock = gst_element_get_clock (GST_ELEMENT (decklinksink));
  41. + base_time = gst_element_get_base_time (GST_ELEMENT (decklinksink));
  42. + if (clock) {
  43. + if (base_time != GST_CLOCK_TIME_NONE) {
  44. + GstClockTime clock_time = gst_clock_get_time (clock);
  45. +
  46. + if (base_time + running_time + running_time_duration <
  47. + gst_clock_get_time (clock)) {
  48. + GST_WARNING_OBJECT (decklinksink,
  49. + "Dropping too late frame: %" GST_TIME_FORMAT " < %" GST_TIME_FORMAT,
  50. + GST_TIME_ARGS (running_time + running_time_duration),
  51. + GST_TIME_ARGS (clock_time - base_time));
  52. + gst_object_unref (clock);
  53. + //flow_ret = GST_FLOW_OK;
  54. + goto out;
  55. + }
  56. +
  57. + if (base_time + running_time > gst_clock_get_time(clock) ) {
  58. + clock_id = gst_clock_new_single_shot_id (clock, base_time + running_time);
  59. + GST_WARNING_OBJECT (decklinksink,
  60. + "waiting for clock: %" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT,
  61. + GST_TIME_ARGS (clock_time), GST_TIME_ARGS (base_time + running_time));
  62. + gst_clock_id_wait (clock_id, NULL);
  63. + //GST_LOG_OBJECT (decklinksink, "finished waiting for clock");
  64. + gst_clock_id_unref (clock_id);
  65. + }
  66. + }
  67. +
  68. + gst_object_unref (clock);
  69. + }
  70. +
  71. /* FIXME: This is not correct as it assumes that the decklink clock
  72. * has the exact same value as the pipeline clock at any time. Not
  73. * only the same rate!
  74. */
  75. - while (!decklinksink->stop &&
  76. - gst_adapter_available (decklinksink->audio_adapter) > 1600 * 4 * 2) {
  77. - g_cond_wait (&decklinksink->audio_cond, &decklinksink->audio_mutex);
  78. - }
  79. + //while (!decklinksink->stop &&
  80. + // gst_adapter_available (decklinksink->audio_adapter) > 1600 * 4 * 2) {
  81. + //g_cond_wait (&decklinksink->audio_cond, &decklinksink->audio_mutex);
  82. + //}
  83. + g_mutex_lock (&decklinksink->audio_mutex);
  84. gst_adapter_push (decklinksink->audio_adapter, buffer);
  85. g_mutex_unlock (&decklinksink->audio_mutex);
  86.  
  87. +out:
  88. ret = GST_FLOW_OK;
  89. return ret;
  90. }
  91. @@ -795,6 +847,13 @@ Output::RenderAudioSamples (bool preroll)
  92. {
  93. uint32_t samplesWritten;
  94. HRESULT ret;
  95. + GstClockTime timestamp, duration;
  96. + GstClockTime running_time;
  97. + GstClockTime running_time_duration;
  98. + GstClock *clock;
  99. + GstClockID clock_id;
  100. + GstClockTime base_time;
  101. + guint64 dist;
  102.  
  103. // guint64 samplesToWrite;
  104.  
  105. @@ -806,18 +865,67 @@ Output::RenderAudioSamples (bool preroll)
  106. gconstpointer data;
  107. int n;
  108.  
  109. +
  110. g_mutex_lock (&decklinksink->audio_mutex);
  111.  
  112. n = gst_adapter_available (decklinksink->audio_adapter);
  113. if (n > 0) {
  114. data = gst_adapter_map (decklinksink->audio_adapter, n);
  115.  
  116. + clock = gst_element_get_clock (GST_ELEMENT (decklinksink));
  117. + base_time = gst_element_get_base_time (GST_ELEMENT (decklinksink));
  118. + timestamp = gst_adapter_prev_pts (decklinksink->audio_adapter, &dist);
  119. +
  120. + if (timestamp == GST_CLOCK_TIME_NONE) {
  121. + GST_WARNING_OBJECT (decklinksink,
  122. + "No timestamp for audio adapter");
  123. + }
  124. +
  125. + running_time =
  126. + gst_segment_to_running_time (&decklinksink->audio_segment,
  127. + GST_FORMAT_TIME, timestamp);
  128. + duration = gst_util_uint64_scale_int (GST_SECOND, 48000, 1);
  129. +
  130. + running_time_duration =
  131. + gst_segment_to_running_time (&decklinksink->audio_segment,
  132. + GST_FORMAT_TIME, timestamp + duration) - running_time;
  133. +
  134. + if (clock) {
  135. + if (base_time != GST_CLOCK_TIME_NONE) {
  136. + GstClockTime clock_time = gst_clock_get_time (clock);
  137. +
  138. + if (base_time + running_time + running_time_duration <
  139. + gst_clock_get_time (clock)) {
  140. + GST_WARNING_OBJECT (decklinksink,
  141. + "Dropping too late frame (avail=%d, dist=%lu dropping=%ld) : %" GST_TIME_FORMAT " < %" GST_TIME_FORMAT,
  142. + n, dist, (gint64)n - (gint64)dist,
  143. + GST_TIME_ARGS (running_time + running_time_duration),
  144. + GST_TIME_ARGS (clock_time - base_time));
  145. + gst_object_unref (clock);
  146. + gst_adapter_flush (decklinksink->audio_adapter, n - dist);
  147. + return S_OK;
  148. + }
  149. +
  150. + if (base_time + running_time > gst_clock_get_time(clock) ) {
  151. + clock_id = gst_clock_new_single_shot_id (clock, base_time + running_time);
  152. + GST_LOG_OBJECT (decklinksink,
  153. + "waiting for clock: %" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT,
  154. + GST_TIME_ARGS (clock_time), GST_TIME_ARGS (base_time + running_time));
  155. + gst_clock_id_wait (clock_id, NULL);
  156. + GST_LOG_OBJECT (decklinksink, "finished waiting for clock");
  157. + gst_clock_id_unref (clock_id);
  158. + }
  159. + }
  160. +
  161. + gst_object_unref (clock);
  162. + }
  163. +
  164. /* FIXME: This is not correct. We assume here that the decklink
  165. * clock runs at the same rate as the pipeline clock and that
  166. * the input stream has no discontinuities at all
  167. */
  168. ret = decklinksink->output->ScheduleAudioSamples ((void *) data, n / 4,
  169. - 0, 0, &samplesWritten);
  170. + running_time, GST_SECOND, &samplesWritten);
  171.  
  172. gst_adapter_unmap (decklinksink->audio_adapter);
  173. gst_adapter_flush (decklinksink->audio_adapter, samplesWritten * 4);
Advertisement
Advertisement
Advertisement
RAW Paste Data Copied
Advertisement