/* Set up the sync handle. Disables output_sync on error. */ static int sync_init () { int combined_output = 0; #ifdef WINDOWS32 if ((!STREAM_OK (stdout) && !STREAM_OK (stderr)) || (sync_handle = create_mutex ()) == -1) { perror_with_name ("output-sync suppressed: ", "stderr"); output_sync = 0; } else { combined_output = same_stream (stdout, stderr); prepare_mutex_handle_string (sync_handle); } #else if (STREAM_OK (stdout)) { struct stat stbuf_o, stbuf_e; sync_handle = fileno (stdout); combined_output = (fstat (fileno (stdout), &stbuf_o) == 0 && fstat (fileno (stderr), &stbuf_e) == 0 && stbuf_o.st_dev == stbuf_e.st_dev && stbuf_o.st_ino == stbuf_e.st_ino); } else if (STREAM_OK (stderr)) sync_handle = fileno (stderr); else { perror_with_name ("output-sync suppressed: ", "stderr"); output_sync = 0; } #endif return combined_output; }
static GstFlowReturn process_audio_packet(MpegTSDemuxer *demuxer, AVPacket *packet) { GstFlowReturn result = GST_FLOW_OK; Stream *stream = &demuxer->audio; if (!same_stream(demuxer, stream, packet)) return result; GstBuffer *buffer = NULL; GstEvent *newsegment_event = NULL; void *buffer_data = av_mallocz(packet->size); if (buffer_data != NULL) { memcpy(buffer_data, packet->data, packet->size); buffer = gst_buffer_new_wrapped_full(0, buffer_data, packet->size, 0, packet->size, buffer_data, &av_free); if (packet->pts != AV_NOPTS_VALUE) { if (demuxer->base_pts == GST_CLOCK_TIME_NONE) { demuxer->base_pts = PTS_TO_GSTTIME(packet->pts) + stream->offset_time; } gint64 time = PTS_TO_GSTTIME(packet->pts) + stream->offset_time - demuxer->base_pts; if (time < 0) time = 0; if (stream->last_time > 0 && time < (gint64) (stream->last_time - PTS_TO_GSTTIME(G_MAXUINT32))) { stream->offset_time += PTS_TO_GSTTIME(MAX_PTS + 1); // Wraparound occured time = PTS_TO_GSTTIME(packet->pts) + stream->offset_time; #ifdef VERBOSE_DEBUG_AUDIO g_print("[Audio wraparound] updating offset_time to %lld\n", stream->offset_time); #endif } #ifdef VERBOSE_DEBUG_AUDIO g_print("[Audio]: pts=%lld(%.4f) time=%lld (%.4f) offset_time=%lld last_time=%lld\n", PTS_TO_GSTTIME(packet->pts), (double) PTS_TO_GSTTIME(packet->pts) / GST_SECOND, time, (double) time / GST_SECOND, stream->offset_time, stream->last_time); #endif stream->last_time = time; GST_BUFFER_TIMESTAMP(buffer) = time; } if (packet->duration != 0) GST_BUFFER_DURATION(buffer) = PTS_TO_GSTTIME(packet->duration); g_mutex_lock(&demuxer->lock); stream->segment.position = GST_BUFFER_TIMESTAMP(buffer); if (stream->discont) { GstSegment newsegment; gst_segment_init(&newsegment, GST_FORMAT_TIME); newsegment.flags = stream->segment.flags; newsegment.rate = stream->segment.rate; newsegment.start = stream->segment.time; newsegment.stop = stream->segment.stop; newsegment.time = stream->segment.time; newsegment.position = stream->segment.position; newsegment_event = gst_event_new_segment(&newsegment); GST_BUFFER_FLAG_SET(buffer, GST_BUFFER_FLAG_DISCONT); stream->discont = FALSE; #ifdef DEBUG_OUTPUT g_print("MpegTS: [Audio] NEWSEGMENT: last_stop = %.4f\n", (double) stream->segment.last_stop / GST_SECOND); #endif } g_mutex_unlock(&demuxer->lock); } else result = GST_FLOW_ERROR; if (newsegment_event) result = gst_pad_push_event(stream->sourcepad, newsegment_event) ? GST_FLOW_OK : GST_FLOW_FLUSHING; if (result == GST_FLOW_OK) result = gst_pad_push(stream->sourcepad, buffer); else gst_buffer_unref(buffer); #ifdef VERBOSE_DEBUG_AUDIO if (result != GST_FLOW_OK) g_print("MpegTS: Audio push failed: %s\n", gst_flow_get_name(result)); #endif return result; }