WinGui: Fix another instance of the Caliburn vs Json.net sillyness where objects...
[HandBrake.git] / libhb / sync.c
blob3c2a7ffbd590fd7eeb4a6ddeae4bd03476c39679
1 /* sync.c
3 Copyright (c) 2003-2015 HandBrake Team
4 This file is part of the HandBrake source code
5 Homepage: <http://handbrake.fr/>.
6 It may be used under the terms of the GNU General Public License v2.
7 For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
8 */
10 #include "hb.h"
11 #include "hbffmpeg.h"
12 #include <stdio.h>
13 #include "samplerate.h"
15 #ifdef INT64_MIN
16 #undef INT64_MIN /* Because it isn't defined correctly in Zeta */
17 #endif
18 #define INT64_MIN (-9223372036854775807LL-1)
20 #define ABS(a) ((a) < 0 ? -(a) : (a))
22 typedef struct
24 /* Audio/Video sync thread synchronization */
25 hb_lock_t * mutex;
26 hb_cond_t * next_frame;
27 int64_t volatile * last_pts;
28 int pts_count;
30 int ref; /* Reference count to tell us when it's unused */
32 /* PTS synchronization */
33 int64_t audio_pts_slip;
34 int64_t video_pts_slip;
35 int64_t pts_offset;
37 /* point-to-point support */
38 int start_found;
39 int count_frames;
40 } hb_sync_common_t;
42 typedef struct
44 int index;
45 double next_start; /* start time of next output frame */
46 int64_t first_drop; /* PTS of first 'went backwards' frame dropped */
47 int drop_count; /* count of 'time went backwards' drops */
49 /* Raw */
50 SRC_STATE * state;
51 SRC_DATA data;
53 int silence_size;
54 uint8_t * silence_buf;
56 int drop_video_to_sync;
58 double gain_factor;
59 } hb_sync_audio_t;
61 typedef struct
63 int link;
64 int merge;
65 hb_buffer_t * list_current;
66 hb_buffer_t * last;
67 } subtitle_sanitizer_t;
69 typedef struct
71 /* Video */
72 int first_frame;
73 int64_t pts_skip;
74 int64_t next_start; /* start time of next output frame */
75 int64_t first_drop; /* PTS of first 'went backwards' frame dropped */
76 int drop_count; /* count of 'time went backwards' drops */
77 int drops; /* frames dropped to make a cbr video stream */
78 int dups; /* frames duplicated to make a cbr video stream */
79 int video_sequence;
80 int count_frames_max;
81 int chap_mark; /* to propagate chapter mark across a drop */
82 hb_buffer_t * cur; /* The next picture to process */
84 subtitle_sanitizer_t *subtitle_sanitizer;
86 /* Statistics */
87 uint64_t st_counts[4];
88 uint64_t st_dates[4];
89 uint64_t st_first;
90 } hb_sync_video_t;
92 struct hb_work_private_s
94 hb_job_t * job;
95 hb_sync_common_t * common;
96 union
98 hb_sync_video_t video;
99 hb_sync_audio_t audio;
100 } type;
103 /***********************************************************************
104 * Local prototypes
105 **********************************************************************/
106 static void setSyncPTS(hb_work_private_t * pv, int64_t pts, int index);
107 static void getPtsOffset( hb_work_private_t * pv );
108 static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i );
109 static void InitSubtitle( hb_job_t * job, hb_sync_video_t * sync, int i );
110 static void InsertSilence( hb_work_object_t * w, int64_t d );
111 static void UpdateState( hb_work_object_t * w );
112 static void UpdateSearchState( hb_work_object_t * w, int64_t start );
113 static hb_buffer_t * OutputAudioFrame( hb_audio_t *audio, hb_buffer_t *buf,
114 hb_sync_audio_t *sync );
116 /***********************************************************************
117 * hb_work_sync_init
118 ***********************************************************************
119 * Initialize the work object
120 **********************************************************************/
121 hb_work_object_t * hb_sync_init( hb_job_t * job )
123 hb_title_t * title = job->title;
124 hb_chapter_t * chapter;
125 int i;
126 uint64_t duration;
127 hb_work_private_t * pv;
128 hb_sync_video_t * sync;
129 hb_work_object_t * w;
130 hb_work_object_t * ret = NULL;
132 pv = calloc( 1, sizeof( hb_work_private_t ) );
133 sync = &pv->type.video;
134 pv->common = calloc( 1, sizeof( hb_sync_common_t ) );
135 pv->common->ref++;
136 pv->common->mutex = hb_lock_init();
137 pv->common->next_frame = hb_cond_init();
138 pv->common->pts_count = 1;
139 if (job->frame_to_start || job->pts_to_start)
141 pv->common->start_found = 0;
143 else
145 pv->common->start_found = 1;
148 ret = w = hb_get_work( job->h, WORK_SYNC_VIDEO );
149 w->private_data = pv;
150 w->fifo_in = job->fifo_raw;
151 // Register condition with fifo to wake us up immediately if
152 // the fifo becomes full
153 hb_fifo_register_full_cond(w->fifo_in, pv->common->next_frame);
155 // When doing subtitle indepth scan, the pipeline ends at sync
156 if ( !job->indepth_scan )
157 w->fifo_out = job->fifo_sync;
158 else
159 w->fifo_out = NULL;
161 pv->job = job;
162 pv->common->pts_offset = INT64_MIN;
163 sync->first_frame = 1;
165 if( job->pass_id == HB_PASS_ENCODE_2ND )
167 /* We already have an accurate frame count from pass 1 */
168 hb_interjob_t * interjob = hb_interjob_get( job->h );
169 sync->count_frames_max = interjob->frame_count;
171 else
173 /* Calculate how many video frames we are expecting */
174 if ( job->pts_to_stop )
176 duration = job->pts_to_stop + 90000;
178 else if( job->frame_to_stop )
180 /* Set the duration to a rough estimate */
181 duration = (int64_t)(job->frame_to_stop + 1) *
182 title->vrate.den * 90000 / title->vrate.num;
184 else
186 duration = 0;
187 for( i = job->chapter_start; i <= job->chapter_end; i++ )
189 chapter = hb_list_item( job->list_chapter, i - 1 );
190 duration += chapter->duration;
193 sync->count_frames_max = duration * title->vrate.num / title->vrate.den / 90000;
196 hb_log( "sync: expecting %d video frames", sync->count_frames_max );
198 /* Initialize libsamplerate for every audio track we have */
199 if ( ! job->indepth_scan )
201 for( i = 0; i < hb_list_count( job->list_audio ); i++ )
203 InitAudio( job, pv->common, i );
206 pv->common->last_pts = malloc( sizeof(int64_t) * pv->common->pts_count );
207 for ( i = 0; i < pv->common->pts_count; i++ )
209 pv->common->last_pts[i] = AV_NOPTS_VALUE;
212 int count = hb_list_count(job->list_subtitle);
213 sync->subtitle_sanitizer = calloc(count, sizeof(subtitle_sanitizer_t));
214 for( i = 0; i < count; i++ )
216 InitSubtitle(job, sync, i);
218 return ret;
221 static void InitSubtitle( hb_job_t * job, hb_sync_video_t * sync, int i )
223 hb_subtitle_t * subtitle;
225 subtitle = hb_list_item( job->list_subtitle, i );
226 if (subtitle->format == TEXTSUB &&
227 subtitle->config.dest == PASSTHRUSUB &&
228 (job->mux & HB_MUX_MASK_MP4))
230 // Merge overlapping subtitles since mpv tx3g does not support them
231 sync->subtitle_sanitizer[i].merge = 1;
233 // PGS subtitles don't need to be linked because there are explicit
234 // "clear" subtitle packets that indicate the end time of the
235 // previous subtitle
236 if (subtitle->config.dest == PASSTHRUSUB &&
237 subtitle->source != PGSSUB)
239 // Fill in stop time when it is missing
240 sync->subtitle_sanitizer[i].link = 1;
244 static void CloseSubtitle(hb_sync_video_t * sync, int ii)
246 hb_buffer_close(&sync->subtitle_sanitizer[ii].list_current);
249 /***********************************************************************
250 * Close Video
251 ***********************************************************************
253 **********************************************************************/
254 void syncVideoClose( hb_work_object_t * w )
256 hb_work_private_t * pv = w->private_data;
257 hb_job_t * job = pv->job;
258 hb_sync_video_t * sync = &pv->type.video;
259 int ii;
261 // Wake up audio sync if it's still waiting on condition.
262 pv->common->pts_offset = 0;
263 pv->common->start_found = 1;
264 // Unblock anybody waiting on this threads last PTS
265 setSyncPTS(pv, INT64_MAX, 0);
267 if( sync->cur )
269 hb_buffer_close( &sync->cur );
272 hb_log( "sync: got %d frames, %d expected",
273 pv->common->count_frames, sync->count_frames_max );
275 /* save data for second pass */
276 if( job->pass_id == HB_PASS_ENCODE_1ST )
278 /* Preserve frame count for better accuracy in pass 2 */
279 hb_interjob_t * interjob = hb_interjob_get( job->h );
280 interjob->frame_count = pv->common->count_frames;
281 interjob->last_job = job->sequence_id;
284 if (sync->drops || sync->dups )
286 hb_log( "sync: %d frames dropped, %d duplicated",
287 sync->drops, sync->dups );
290 int count = hb_list_count(job->list_subtitle);
291 for( ii = 0; ii < count; ii++ )
293 CloseSubtitle(sync, ii);
295 free(sync->subtitle_sanitizer);
297 hb_lock( pv->common->mutex );
298 if ( --pv->common->ref == 0 )
300 hb_unlock( pv->common->mutex );
301 hb_cond_close( &pv->common->next_frame );
302 hb_lock_close( &pv->common->mutex );
303 free((void*)pv->common->last_pts);
304 free(pv->common);
306 else
308 hb_unlock( pv->common->mutex );
311 free( pv );
312 w->private_data = NULL;
315 static hb_buffer_t * merge_ssa(hb_buffer_t *a, hb_buffer_t *b)
317 int len, ii;
318 char *text;
319 hb_buffer_t *buf = hb_buffer_init(a->size + b->size);
320 buf->s = a->s;
322 // Find the text in the second SSA sub
323 text = (char*)b->data;
324 for (ii = 0; ii < 8; ii++)
326 text = strchr(text, ',');
327 if (text == NULL)
328 break;
329 text++;
331 if (text != NULL)
333 len = sprintf((char*)buf->data, "%s\n%s", a->data, text);
334 if (len >= 0)
335 buf->size = len + 1;
337 else
339 memcpy(buf->data, a->data, a->size);
340 buf->size = a->size;
343 return buf;
346 static hb_buffer_t * mergeSubtitles(subtitle_sanitizer_t *sanitizer, int end)
348 hb_buffer_t *a, *b, *buf, *out = NULL, *last = NULL;
352 a = sanitizer->list_current;
353 b = a != NULL ? a->next : NULL;
355 buf = NULL;
356 if (a != NULL && b == NULL && end)
358 sanitizer->list_current = a->next;
359 if (sanitizer->list_current == NULL)
360 sanitizer->last = NULL;
361 a->next = NULL;
362 buf = a;
364 else if (a != NULL && a->s.stop != AV_NOPTS_VALUE)
366 if (!sanitizer->merge)
368 sanitizer->list_current = a->next;
369 if (sanitizer->list_current == NULL)
370 sanitizer->last = NULL;
371 a->next = NULL;
372 buf = a;
374 else if (b != NULL && a->s.stop > b->s.start)
376 // Overlap
377 if (ABS(a->s.start - b->s.start) <= 18000)
379 // subtitles start within 1/5 second of eachother, merge
380 if (a->s.stop > b->s.stop)
382 // a continues after b, reorder the list and swap
383 hb_buffer_t *tmp = a;
384 a->next = b->next;
385 b->next = a;
386 if (sanitizer->last == b)
388 sanitizer->last = a;
390 a = b;
391 b = tmp;
392 sanitizer->list_current = a;
395 a->next = NULL;
396 b->s.start = a->s.stop;
398 buf = merge_ssa(a, b);
399 hb_buffer_close(&a);
400 a = buf;
401 buf = NULL;
402 sanitizer->list_current = a;
404 if (b->s.stop != AV_NOPTS_VALUE &&
405 ABS(b->s.stop - b->s.start) <= 18000)
407 // b and a completely overlap, remove b
408 a->next = b->next;
409 b->next = NULL;
410 if (sanitizer->last == b)
412 sanitizer->last = a;
414 hb_buffer_close(&b);
416 else
418 a->next = b;
421 else
423 // a starts before b, output copy of a and
424 buf = hb_buffer_dup(a);
425 buf->s.stop = b->s.start;
426 a->s.start = b->s.start;
429 else if (b != NULL && a->s.stop <= b->s.start)
431 sanitizer->list_current = a->next;
432 if (sanitizer->list_current == NULL)
433 sanitizer->last = NULL;
434 a->next = NULL;
435 buf = a;
439 if (buf != NULL)
441 if (buf->s.stop != AV_NOPTS_VALUE)
442 buf->s.duration = buf->s.stop - buf->s.start;
443 else
444 buf->s.duration = AV_NOPTS_VALUE;
445 if (last == NULL)
447 out = last = buf;
449 else
451 last->next = buf;
452 last = buf;
455 } while (buf != NULL);
457 return out;
460 static hb_buffer_t * sanitizeSubtitle(
461 hb_work_private_t * pv,
462 int i,
463 hb_buffer_t * sub)
465 hb_sync_video_t * sync;
466 subtitle_sanitizer_t * sanitizer;
468 sync = &pv->type.video;
469 sanitizer = &sync->subtitle_sanitizer[i];
471 if (!sanitizer->link && !sanitizer->merge)
473 if (sub != NULL)
475 if (sub->s.stop != AV_NOPTS_VALUE)
476 sub->s.duration = sub->s.stop - sub->s.start;
477 else
478 sub->s.duration = 0;
479 sub->s.start -= pv->common->video_pts_slip;
480 if (sub->s.stop != AV_NOPTS_VALUE)
481 sub->s.stop -= pv->common->video_pts_slip;
482 if (sub->s.renderOffset != AV_NOPTS_VALUE)
483 sub->s.renderOffset -= pv->common->video_pts_slip;
485 return sub;
488 if (sub == NULL)
490 return mergeSubtitles(sanitizer, 1);
493 sub->s.start -= pv->common->video_pts_slip;
494 if (sub->s.stop != AV_NOPTS_VALUE)
495 sub->s.stop -= pv->common->video_pts_slip;
496 if (sub->s.renderOffset != AV_NOPTS_VALUE)
497 sub->s.renderOffset -= pv->common->video_pts_slip;
499 if (sanitizer->last != NULL && sanitizer->last->s.stop == AV_NOPTS_VALUE)
501 sanitizer->last->s.stop = sub->s.start;
504 if (sub->s.start == sub->s.stop)
506 // Used to indicate "clear" subtitles when the duration
507 // of subtitles is not encoded in the stream
508 hb_buffer_close(&sub);
510 if (sub != NULL)
512 if (sanitizer->last == NULL)
514 sanitizer->list_current = sanitizer->last = sub;
516 else
518 sanitizer->last->next = sub;
519 sanitizer->last = sub;
523 return mergeSubtitles(sanitizer, 0);
526 static void setSyncPTS(hb_work_private_t * pv, int64_t pts, int index)
528 hb_lock(pv->common->mutex);
529 pv->common->last_pts[index] = pts;
530 hb_unlock(pv->common->mutex);
531 hb_cond_broadcast(pv->common->next_frame);
534 static void resetSync(hb_work_private_t * pv)
536 int ii;
538 hb_lock(pv->common->mutex);
539 for (ii = 0; ii < pv->common->pts_count; ii++)
541 // Unblock any sync thread that are waiting for a PTS
542 pv->common->last_pts[ii] = INT64_MAX;
544 hb_unlock(pv->common->mutex);
545 hb_cond_broadcast(pv->common->next_frame);
546 hb_yield();
549 // Keeps sync tasks "in sync". I.e. the lowest pts will always be
550 // output first.
551 static int waitForSync(hb_work_object_t * w, int64_t pts, int index,
552 hb_fifo_t *fifo)
554 hb_work_private_t * pv = w->private_data;
556 setSyncPTS(pv, pts, index);
558 int ii;
559 hb_lock(pv->common->mutex);
560 for (ii = 0; ii < pv->common->pts_count; ii++)
562 while (pts > pv->common->last_pts[ii])
564 // wait for other streams to catch up
565 // since fifos can become full and clog up the works,
566 // check if our fifo is full when waking.
567 // Also check if encoding was canceled.
568 hb_cond_timedwait(pv->common->next_frame, pv->common->mutex, 200);
569 if (*w->done ||
570 (pts > pv->common->last_pts[ii] && hb_fifo_is_full(fifo)))
572 hb_unlock(pv->common->mutex);
573 getPtsOffset(pv);
574 return 0;
578 hb_unlock(pv->common->mutex);
579 getPtsOffset(pv);
580 return 1;
583 static void flushSubtitles(hb_work_private_t *pv)
585 hb_job_t * job = pv->job;
586 hb_subtitle_t * subtitle;
587 int ii;
590 * Push through any subtitle EOFs in case they were not synced through.
592 for (ii = 0; ii < hb_list_count(job->list_subtitle); ii++)
594 subtitle = hb_list_item(job->list_subtitle, ii);
595 // flush out any pending subtitle buffers in the sanitizer
596 hb_buffer_t *out = sanitizeSubtitle(pv, ii, NULL);
597 if (out != NULL)
599 hb_fifo_push(subtitle->fifo_out, out);
601 if (subtitle->config.dest == PASSTHRUSUB)
603 hb_fifo_push(subtitle->fifo_out, hb_buffer_eof_init());
608 /***********************************************************************
609 * syncVideoWork
610 ***********************************************************************
612 **********************************************************************/
613 int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
614 hb_buffer_t ** buf_out )
616 hb_buffer_t * cur, * next, * sub = NULL;
617 hb_work_private_t * pv = w->private_data;
618 hb_job_t * job = pv->job;
619 hb_subtitle_t * subtitle;
620 hb_sync_video_t * sync = &pv->type.video;
621 int i;
622 int64_t next_start;
624 next = *buf_in;
625 *buf_in = NULL;
627 if (next->s.flags & HB_BUF_FLAG_EOF)
629 if (sync->cur != NULL)
631 cur = sync->cur;
632 cur->s.start = sync->next_start;
633 cur->s.stop = cur->s.start + 90000L *
634 job->vrate.den / job->vrate.num;
636 /* Make sure last frame is reflected in frame count */
637 pv->common->count_frames++;
639 /* Push the frame to the renderer */
640 *buf_out = cur;
641 sync->cur = NULL;
643 /* we got an end-of-stream. Feed it downstream & signal that
644 * we're done. Note that this means we drop the final frame of
645 * video (we don't know its duration). On DVDs the final frame
646 * is often strange and dropping it seems to be a good idea. */
647 (*buf_out)->next = next;
649 else
651 *buf_out = next;
653 flushSubtitles(pv);
654 pv->common->start_found = 1;
655 // Unblock anybody waiting on this threads last PTS
656 setSyncPTS(pv, INT64_MAX, 0);
657 return HB_WORK_DONE;
660 next_start = next->s.start - pv->common->video_pts_slip;
661 if (pv->common->pts_offset == INT64_MIN || !pv->common->start_found ||
662 job->frame_to_stop > 0)
664 waitForSync(w, next_start, 0, w->fifo_in);
665 // video_pts_slip may change in during waitForSync
666 next_start = next->s.start - pv->common->video_pts_slip;
668 else
670 setSyncPTS(pv, next_start, 0);
673 /* Wait for start of point-to-point encoding */
674 if (!pv->common->start_found)
676 if (pv->common->count_frames < job->frame_to_start ||
677 next->s.start < job->pts_to_start)
679 UpdateSearchState( w, next_start );
681 // Flush any subtitles that have pts prior to the
682 // current frame
683 for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
685 subtitle = hb_list_item( job->list_subtitle, i );
686 while( ( sub = hb_fifo_see( subtitle->fifo_raw ) ) )
688 if ( sub->s.start > next->s.start )
689 break;
690 sub = hb_fifo_get( subtitle->fifo_raw );
691 hb_buffer_close( &sub );
694 #ifdef USE_QSV
695 // reclaim QSV resources before dropping the buffer
696 // when decoding without QSV, the QSV atom will be NULL
697 if (job != NULL && job->qsv.ctx != NULL &&
698 next->qsv_details.qsv_atom != NULL)
700 av_qsv_stage *stage = av_qsv_get_last_stage(next->qsv_details.qsv_atom);
701 if (stage != NULL)
703 av_qsv_wait_on_sync(job->qsv.ctx, stage);
704 if (stage->out.sync->in_use > 0)
706 ff_qsv_atomic_dec(&stage->out.sync->in_use);
708 if (stage->out.p_surface->Data.Locked > 0)
710 ff_qsv_atomic_dec(&stage->out.p_surface->Data.Locked);
713 av_qsv_flush_stages(job->qsv.ctx->pipes,
714 &next->qsv_details.qsv_atom);
716 #endif
717 hb_buffer_close( &next );
719 return HB_WORK_OK;
721 hb_lock( pv->common->mutex );
722 pv->common->audio_pts_slip += next_start;
723 pv->common->video_pts_slip += next_start;
724 pv->common->start_found = 1;
725 pv->common->count_frames = 0;
726 hb_unlock( pv->common->mutex );
727 next_start = 0;
728 sync->st_first = 0;
729 resetSync(pv);
732 /* Check for end of point-to-point frame encoding */
733 if (job->frame_to_stop && pv->common->count_frames > job->frame_to_stop)
735 // Drop an empty buffer into our output to ensure that things
736 // get flushed all the way out.
737 hb_log("sync: reached %d frames, exiting early",
738 pv->common->count_frames);
739 hb_buffer_close(&sync->cur);
740 hb_buffer_close(&next);
741 *buf_out = hb_buffer_eof_init();
742 flushSubtitles(pv);
743 // Unblock anybody waiting on this threads last PTS
744 setSyncPTS(pv, INT64_MAX, 0);
745 return HB_WORK_DONE;
748 /* Check for end of point-to-point pts encoding */
749 if( job->pts_to_stop && sync->next_start >= job->pts_to_stop )
751 // Drop an empty buffer into our output to ensure that things
752 // get flushed all the way out.
753 hb_log("sync: reached pts %"PRId64", exiting early",
754 sync->cur->s.start);
755 hb_buffer_close(&sync->cur);
756 hb_buffer_close( &next );
757 *buf_out = hb_buffer_eof_init();
758 flushSubtitles(pv);
759 // Unblock anybody waiting on this threads last PTS
760 setSyncPTS(pv, INT64_MAX, 0);
761 return HB_WORK_DONE;
764 if (sync->cur == NULL)
766 sync->cur = next;
767 return HB_WORK_OK;
770 // At this point, we have 2 video frames wich allows us to set the
771 // duration of the first and output it.
772 cur = sync->cur;
773 if (sync->first_frame)
775 /* This is our first frame */
776 if (cur->s.start > 0)
779 * The first pts from a dvd should always be zero but
780 * can be non-zero with a transport or program stream since
781 * we're not guaranteed to start on an IDR frame. If we get
782 * a non-zero initial PTS extend its duration so it behaves
783 * as if it started at zero so that our audio timing will
784 * be in sync.
786 hb_log( "sync: first pts is %"PRId64, cur->s.start );
787 cur->s.start = 0;
789 sync->first_frame = 0;
793 * since the first frame is always 0 and the upstream reader code
794 * is taking care of adjusting for pts discontinuities, we just have
795 * to deal with the next frame's start being in the past. This can
796 * happen when the PTS is adjusted after data loss but video frame
797 * reordering causes some frames with the old clock to appear after
798 * the clock change. This creates frames that overlap in time which
799 * looks to us like time going backward. The downstream muxing code
800 * can deal with overlaps of up to a frame time but anything larger
801 * we handle by dropping frames here.
803 if ( next_start - cur->s.start <= 0 )
805 if ( sync->first_drop == 0 )
807 sync->first_drop = next_start;
809 ++sync->drop_count;
810 if ( next->s.new_chap )
812 // don't drop a chapter mark when we drop the buffer
813 sync->chap_mark = next->s.new_chap;
816 #ifdef USE_QSV
817 // reclaim QSV resources before dropping the buffer
818 // when decoding without QSV, the QSV atom will be NULL
819 if (job != NULL && job->qsv.ctx != NULL &&
820 next->qsv_details.qsv_atom != NULL)
822 av_qsv_stage *stage = av_qsv_get_last_stage(next->qsv_details.qsv_atom);
823 if (stage != NULL)
825 av_qsv_wait_on_sync(job->qsv.ctx, stage);
826 if (stage->out.sync->in_use > 0)
828 ff_qsv_atomic_dec(&stage->out.sync->in_use);
830 if (stage->out.p_surface->Data.Locked > 0)
832 ff_qsv_atomic_dec(&stage->out.p_surface->Data.Locked);
835 av_qsv_flush_stages(job->qsv.ctx->pipes,
836 &next->qsv_details.qsv_atom);
838 #endif
840 hb_buffer_close( &next );
841 return HB_WORK_OK;
843 if ( sync->first_drop )
845 hb_log( "sync: video time didn't advance - dropped %d frames "
846 "(delta %d ms, current %"PRId64", next %"PRId64", dur %d)",
847 sync->drop_count, (int)( cur->s.start - sync->first_drop ) / 90,
848 cur->s.start, next_start, (int)( next_start - cur->s.start ) );
849 sync->first_drop = 0;
850 sync->drop_count = 0;
854 * Track the video sequence number locally so that we can sync the audio
855 * to it using the sequence number as well as the PTS.
857 sync->video_sequence = cur->sequence;
859 /* Process subtitles that apply to this video frame */
860 // NOTE: There is no logic in either subtitle-sync algorithm that waits
861 // for the subtitle-decoder if it is lagging behind the video-decoder.
863 // Therefore there is the implicit assumption that the subtitle-decoder
864 // is always faster than the video-decoder. This assumption is definitely
865 // incorrect in some cases where the SSA subtitle decoder is used.
867 for( i = 0; i < hb_list_count( job->list_subtitle ); i++)
869 hb_buffer_t *out;
871 subtitle = hb_list_item( job->list_subtitle, i );
873 // Sanitize subtitle start and stop times, then pass to
874 // muxer or renderer filter.
875 while ( ( sub = hb_fifo_get( subtitle->fifo_raw ) ) != NULL )
877 if (!(next->s.flags & HB_BUF_FLAG_EOF))
879 out = sanitizeSubtitle(pv, i, sub);
880 if (out != NULL)
881 hb_fifo_push( subtitle->fifo_out, out );
883 else
885 // Push the end of stream marker
886 hb_fifo_push( subtitle->fifo_out, sub );
892 * Adjust the pts of the current frame so that it's contiguous
893 * with the previous frame. The start time of the current frame
894 * has to be the end time of the previous frame and the stop
895 * time has to be the start of the next frame. We don't
896 * make any adjustments to the source timestamps other than removing
897 * the clock offsets (which also removes pts discontinuities).
898 * This means we automatically encode at the source's frame rate.
899 * MP2 uses an implicit duration (frames end when the next frame
900 * starts) but more advanced containers like MP4 use an explicit
901 * duration. Since we're looking ahead one frame we set the
902 * explicit stop time from the start time of the next frame.
904 *buf_out = cur;
905 int64_t duration = next_start - cur->s.start;
906 sync->cur = cur = next;
907 cur->sub = NULL;
908 cur->s.start -= pv->common->video_pts_slip;
909 if (cur->s.renderOffset != AV_NOPTS_VALUE)
910 cur->s.renderOffset -= pv->common->video_pts_slip;
911 cur->s.stop -= pv->common->video_pts_slip;
912 sync->pts_skip = 0;
913 if ( duration <= 0 )
915 hb_log( "sync: invalid video duration %"PRId64", start %"PRId64", next %"PRId64"",
916 duration, cur->s.start, next_start );
919 (*buf_out)->s.start = sync->next_start;
920 sync->next_start += duration;
921 (*buf_out)->s.stop = sync->next_start;
923 if ( sync->chap_mark )
925 // we have a pending chapter mark from a recent drop - put it on this
926 // buffer (this may make it one frame late but we can't do any better).
927 (*buf_out)->s.new_chap = sync->chap_mark;
928 sync->chap_mark = 0;
931 /* Update UI */
932 UpdateState( w );
934 return HB_WORK_OK;
937 // sync*Init does nothing because sync has a special initializer
938 // that takes care of initializing video and all audio tracks
939 int syncVideoInit( hb_work_object_t * w, hb_job_t * job)
941 return 0;
944 hb_work_object_t hb_sync_video =
946 WORK_SYNC_VIDEO,
947 "Video Synchronization",
948 syncVideoInit,
949 syncVideoWork,
950 syncVideoClose
953 /***********************************************************************
954 * Close Audio
955 ***********************************************************************
957 **********************************************************************/
958 void syncAudioClose( hb_work_object_t * w )
960 hb_work_private_t * pv = w->private_data;
961 hb_sync_audio_t * sync = &pv->type.audio;
963 // Unblock anybody waiting on this threads last PTS
964 setSyncPTS(pv, INT64_MAX, sync->index+1);
966 if( sync->silence_buf )
968 free( sync->silence_buf );
970 if ( sync->state )
972 src_delete( sync->state );
975 hb_lock( pv->common->mutex );
976 if ( --pv->common->ref == 0 )
978 hb_unlock( pv->common->mutex );
979 hb_cond_close( &pv->common->next_frame );
980 hb_lock_close( &pv->common->mutex );
981 free((void*)pv->common->last_pts);
982 free(pv->common);
984 else
986 hb_unlock( pv->common->mutex );
989 free( pv );
990 w->private_data = NULL;
993 int syncAudioInit( hb_work_object_t * w, hb_job_t * job)
995 return 0;
998 /***********************************************************************
999 * SyncAudio
1000 ***********************************************************************
1002 **********************************************************************/
1003 static int syncAudioWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
1004 hb_buffer_t ** buf_out )
1006 hb_work_private_t * pv = w->private_data;
1007 hb_job_t * job = pv->job;
1008 hb_sync_audio_t * sync = &pv->type.audio;
1009 hb_buffer_t * buf;
1010 int64_t start;
1012 buf = *buf_in;
1013 *buf_in = NULL;
1015 /* if the next buffer is an eof send it downstream */
1016 if (buf->s.flags & HB_BUF_FLAG_EOF)
1018 *buf_out = buf;
1019 // Unblock anybody waiting on this threads last PTS
1020 setSyncPTS(pv, INT64_MAX, sync->index+1);
1021 return HB_WORK_DONE;
1024 start = buf->s.start - pv->common->audio_pts_slip;
1025 if (pv->common->pts_offset == INT64_MIN || !pv->common->start_found ||
1026 job->frame_to_stop > 0)
1028 waitForSync(w, start, sync->index+1, w->fifo_in);
1029 // audio_pts_slip may change in waitForSync()
1030 start = buf->s.start - pv->common->audio_pts_slip;
1032 else
1034 setSyncPTS(pv, start, sync->index+1);
1037 // Wait for start frame if doing point-to-point
1039 // When doing frame p-to-p, video leads the way. The video thead will set
1040 // start_found when we have reached the start point.
1041 if (!pv->common->start_found)
1043 if (job->pts_to_start > 0 && buf->s.start >= job->pts_to_start)
1045 hb_lock( pv->common->mutex );
1046 pv->common->start_found = 1;
1047 pv->common->audio_pts_slip += start;
1048 pv->common->video_pts_slip += start;
1049 pv->common->count_frames = 0;
1050 hb_unlock( pv->common->mutex );
1051 resetSync(pv);
1052 start = 0;
1054 else
1056 // For frame-to-frame encoding, the video sync thread will
1057 // tell us when it is ok to start
1058 hb_buffer_close(&buf);
1059 return HB_WORK_OK;
1063 // Check for p-to-p end time
1064 if (job->frame_to_stop && pv->common->count_frames >= job->frame_to_stop)
1066 hb_buffer_close( &buf );
1067 *buf_out = hb_buffer_eof_init();
1068 // Unblock anybody waiting on this threads last PTS
1069 setSyncPTS(pv, INT64_MAX, sync->index+1);
1070 return HB_WORK_DONE;
1072 if (job->pts_to_stop && sync->next_start >= job->pts_to_stop)
1074 hb_buffer_close( &buf );
1075 *buf_out = hb_buffer_eof_init();
1076 // Unblock anybody waiting on this threads last PTS
1077 setSyncPTS(pv, INT64_MAX, sync->index+1);
1078 return HB_WORK_DONE;
1081 // audio time went backwards.
1082 // If our output clock is more than a half frame ahead of the
1083 // input clock drop this frame to move closer to sync.
1084 // Otherwise drop frames until the input clock matches the output clock.
1085 if ( sync->next_start - start > 90*15 )
1087 // Discard data that's in the past.
1088 if ( sync->first_drop == 0 )
1090 sync->first_drop = start;
1092 ++sync->drop_count;
1093 hb_buffer_close( &buf );
1094 return HB_WORK_OK;
1096 if ( sync->first_drop )
1098 // we were dropping old data but input buf time is now current
1099 hb_log( "sync: audio 0x%x time went backwards %d ms, dropped %d frames "
1100 "(start %"PRId64", next %"PRId64")", w->audio->id,
1101 (int)( sync->next_start - sync->first_drop ) / 90,
1102 sync->drop_count, sync->first_drop, (int64_t)sync->next_start );
1103 sync->first_drop = 0;
1104 sync->drop_count = 0;
1106 if ( start - sync->next_start >= (90 * 70) )
1108 if ( start - sync->next_start > (90000LL * 60) )
1110 // there's a gap of more than a minute between the last
1111 // frame and this. assume we got a corrupted timestamp
1112 // and just drop the next buf.
1113 hb_log( "sync: %d minute time gap in audio 0x%x - dropping buf"
1114 " start %"PRId64", next %"PRId64,
1115 (int)((start - sync->next_start) / (90000*60)),
1116 w->audio->id, start, (int64_t)sync->next_start );
1117 hb_buffer_close( &buf );
1118 return HB_WORK_OK;
1121 * there's a gap of at least 70ms between the last
1122 * frame we processed & the next. Fill it with silence.
1123 * Or in the case of DCA, skip some frames from the
1124 * other streams.
1126 if ( sync->drop_video_to_sync )
1128 hb_log( "sync: audio gap %d ms. Skipping frames. Audio 0x%x"
1129 " start %"PRId64", next %"PRId64,
1130 (int)((start - sync->next_start) / 90),
1131 w->audio->id, start, (int64_t)sync->next_start );
1132 hb_lock( pv->common->mutex );
1133 pv->common->audio_pts_slip += (start - sync->next_start);
1134 pv->common->video_pts_slip += (start - sync->next_start);
1135 hb_unlock( pv->common->mutex );
1136 *buf_out = OutputAudioFrame( w->audio, buf, sync );
1137 return HB_WORK_OK;
1139 hb_log( "sync: adding %d ms of silence to audio 0x%x"
1140 " start %"PRId64", next %"PRId64,
1141 (int)((start - sync->next_start) / 90),
1142 w->audio->id, start, (int64_t)sync->next_start );
1143 InsertSilence( w, start - sync->next_start );
1147 * When we get here we've taken care of all the dups and gaps in the
1148 * audio stream and are ready to inject the next input frame into
1149 * the output stream.
1151 *buf_out = OutputAudioFrame( w->audio, buf, sync );
1152 return HB_WORK_OK;
1155 hb_work_object_t hb_sync_audio =
1157 WORK_SYNC_AUDIO,
1158 "AudioSynchronization",
1159 syncAudioInit,
1160 syncAudioWork,
1161 syncAudioClose
1164 static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i )
1166 hb_work_object_t * w;
1167 hb_work_private_t * pv;
1168 hb_sync_audio_t * sync;
1170 pv = calloc( 1, sizeof( hb_work_private_t ) );
1171 sync = &pv->type.audio;
1172 sync->index = i;
1173 pv->job = job;
1174 pv->common = common;
1175 pv->common->ref++;
1176 pv->common->pts_count++;
1178 w = hb_get_work( job->h, WORK_SYNC_AUDIO );
1179 w->private_data = pv;
1180 w->audio = hb_list_item( job->list_audio, i );
1181 w->fifo_in = w->audio->priv.fifo_raw;
1182 // Register condition with fifo to wake us up immediately if
1183 // the fifo becomes full
1184 hb_fifo_register_full_cond(w->fifo_in, pv->common->next_frame);
1186 if ( w->audio->config.out.codec & HB_ACODEC_PASS_FLAG )
1188 w->fifo_out = w->audio->priv.fifo_out;
1190 else
1192 w->fifo_out = w->audio->priv.fifo_sync;
1195 if( w->audio->config.out.codec == HB_ACODEC_AC3_PASS ||
1196 w->audio->config.out.codec == HB_ACODEC_AAC_PASS ||
1197 w->audio->config.out.codec == HB_ACODEC_EAC3_PASS ||
1198 w->audio->config.out.codec == HB_ACODEC_FLAC_PASS )
1200 /* Have a silent frame ready in case we have to fill a gap */
1201 AVDictionary *av_opts = NULL;
1202 AVCodec *codec;
1203 AVCodecContext *c;
1205 switch ( w->audio->config.out.codec )
1207 case HB_ACODEC_AC3_PASS:
1209 codec = avcodec_find_encoder( AV_CODEC_ID_AC3 );
1210 } break;
1211 case HB_ACODEC_EAC3_PASS:
1213 codec = avcodec_find_encoder( AV_CODEC_ID_EAC3 );
1214 } break;
1215 case HB_ACODEC_AAC_PASS:
1217 codec = avcodec_find_encoder_by_name("aac");
1218 } break;
1219 case HB_ACODEC_FLAC_PASS:
1221 codec = avcodec_find_encoder( AV_CODEC_ID_FLAC );
1222 } break;
1223 default:
1225 // Never gets here
1226 codec = NULL; // Silence compiler warning
1227 } break;
1230 c = avcodec_alloc_context3(codec);
1231 c->bit_rate = w->audio->config.in.bitrate;
1232 c->sample_rate = w->audio->config.in.samplerate;
1233 c->channels =
1234 av_get_channel_layout_nb_channels(w->audio->config.in.channel_layout);
1237 * lossless codecs may encode differently depending on the bit depth, so
1238 * we need to set it correctly if we want the bitstream to be as close
1239 * as possible to what we're passing through
1241 if (w->audio->config.out.codec == HB_ACODEC_FLAC_PASS)
1243 if (w->audio->config.in.sample_bit_depth <= 16)
1245 hb_ff_set_sample_fmt(c, codec, AV_SAMPLE_FMT_S16);
1247 else
1249 hb_ff_set_sample_fmt(c, codec, AV_SAMPLE_FMT_S32);
1251 c->bits_per_raw_sample = w->audio->config.in.sample_bit_depth;
1253 else
1255 hb_ff_set_sample_fmt(c, codec, AV_SAMPLE_FMT_FLTP);
1259 * the default frame size selected by the encoder may not match
1260 * that of the input stream, but the FLAC encoder will honor whatever
1261 * frame size we set as long as it's a valid FLAC block size.
1263 * for AC-3, the frame size is the same for all streams.
1265 * for E-AC-3, using the same bitrate and sample rate as the input
1266 * should result in the frame size being the same as the source's.
1268 if (w->audio->config.out.codec == HB_ACODEC_FLAC_PASS)
1270 c->frame_size = w->audio->config.in.samples_per_frame;
1274 * we want the output to be as close as possible to what we're passing
1275 * through, and we do have access to the source's matrix encoding mode.
1277 if (w->audio->config.out.codec == HB_ACODEC_AC3_PASS ||
1278 w->audio->config.out.codec == HB_ACODEC_EAC3_PASS)
1280 switch (w->audio->config.in.matrix_encoding)
1282 case AV_MATRIX_ENCODING_DOLBY:
1283 case AV_MATRIX_ENCODING_DPLII:
1284 av_dict_set(&av_opts, "dsur_mode", "on", 0);
1285 break;
1286 case AV_MATRIX_ENCODING_DPLIIX:
1287 case AV_MATRIX_ENCODING_DOLBYEX:
1288 av_dict_set(&av_opts, "dsurex_mode", "on", 0);
1289 break;
1290 case AV_MATRIX_ENCODING_DPLIIZ:
1291 av_dict_set(&av_opts, "dsurex_mode", "dpliiz", 0);
1292 break;
1293 case AV_MATRIX_ENCODING_DOLBYHEADPHONE:
1294 av_dict_set(&av_opts, "dheadphone_mode", "on", 0);
1295 break;
1296 default:
1297 break;
1301 if (w->audio->config.in.channel_layout == AV_CH_LAYOUT_STEREO_DOWNMIX)
1303 c->channel_layout = AV_CH_LAYOUT_STEREO;
1305 else
1307 c->channel_layout = w->audio->config.in.channel_layout;
1310 if (hb_avcodec_open(c, codec, &av_opts, 0) < 0)
1312 hb_log("sync: track %d, hb_avcodec_open() failed, dropping video to sync",
1313 w->audio->config.out.track);
1314 sync->drop_video_to_sync = 1;
1316 else
1318 // Prepare input frame
1319 AVFrame frame = { .nb_samples = c->frame_size, .pts = 0, };
1320 int input_size = av_samples_get_buffer_size(NULL, c->channels,
1321 frame.nb_samples,
1322 c->sample_fmt, 1);
1323 uint8_t *zeros = calloc(1, input_size);
1324 avcodec_fill_audio_frame(&frame, c->channels, c->sample_fmt, zeros,
1325 input_size, 1);
1327 // Allocate enough space for the encoded silence
1328 // The output should be < the input
1329 sync->silence_buf = malloc( input_size );
1331 // There is some delay in getting output from some audio encoders.
1332 // So encode a few packets till we get output.
1333 int ii;
1334 for ( ii = 0; ii < 10; ii++ )
1336 // Prepare output packet
1337 AVPacket pkt;
1338 int got_packet;
1339 av_init_packet(&pkt);
1340 pkt.data = sync->silence_buf;
1341 pkt.size = input_size;
1343 int ret = avcodec_encode_audio2( c, &pkt, &frame, &got_packet);
1344 if ( ret < 0 )
1346 hb_log("sync: track %d, avcodec_encode_audio() failed, dropping video to sync",
1347 w->audio->config.out.track);
1348 sync->drop_video_to_sync = 1;
1349 break;
1352 if ( got_packet )
1354 sync->silence_size = pkt.size;
1355 break;
1357 else if (ii + 1 == 10)
1359 hb_log("sync: track %d, failed to get output packet, dropping video to sync",
1360 w->audio->config.out.track);
1361 sync->drop_video_to_sync = 1;
1364 free( zeros );
1365 hb_avcodec_close( c );
1367 AVDictionaryEntry *opt = NULL;
1368 while ((opt = av_dict_get(av_opts, "", opt, AV_DICT_IGNORE_SUFFIX)) != NULL)
1370 hb_log("InitAudio: unknown option '%s'", opt->key);
1372 av_dict_free( &av_opts );
1373 av_free( c );
1375 else
1377 if( w->audio->config.out.codec & HB_ACODEC_PASS_FLAG )
1379 sync->drop_video_to_sync = 1;
1381 else
1383 /* Not passthru, initialize libsamplerate */
1384 int error;
1385 sync->state = src_new( SRC_SINC_MEDIUM_QUALITY,
1386 hb_mixdown_get_discrete_channel_count( w->audio->config.out.mixdown ),
1387 &error );
1388 sync->data.end_of_input = 0;
1392 sync->gain_factor = pow(10, w->audio->config.out.gain / 20);
1394 hb_list_add( job->list_work, w );
1397 static hb_buffer_t * OutputAudioFrame( hb_audio_t *audio, hb_buffer_t *buf,
1398 hb_sync_audio_t *sync )
1400 int64_t start = (int64_t)sync->next_start;
1402 // Can't count of buf->s.stop - buf->s.start for accurate duration
1403 // due to integer rounding, so use buf->s.duration when it is set
1404 // (which should be always if I didn't miss anything)
1405 double duration;
1406 if ( buf->s.duration > 0 )
1407 duration = buf->s.duration;
1408 else
1409 duration = buf->s.stop - buf->s.start;
1411 if ( !( audio->config.out.codec & HB_ACODEC_PASS_FLAG ) )
1413 // Audio is not passthru. Check if we need to modify the audio
1414 // in any way.
1415 if( audio->config.in.samplerate != audio->config.out.samplerate )
1417 /* do sample rate conversion */
1418 int count_in, count_out;
1419 hb_buffer_t * buf_raw = buf;
1420 int sample_size = hb_mixdown_get_discrete_channel_count( audio->config.out.mixdown ) *
1421 sizeof( float );
1423 count_in = buf_raw->size / sample_size;
1425 * When using stupid rates like 44.1 there will always be some
1426 * truncation error. E.g., a 1536 sample AC3 frame will turn into a
1427 * 1536*44.1/48.0 = 1411.2 sample frame. If we just truncate the .2
1428 * the error will build up over time and eventually the audio will
1429 * substantially lag the video. libsamplerate will keep track of the
1430 * fractional sample & give it to us when appropriate if we give it
1431 * an extra sample of space in the output buffer.
1433 count_out = ( duration * audio->config.out.samplerate ) / 90000 + 1;
1435 sync->data.input_frames = count_in;
1436 sync->data.output_frames = count_out;
1437 sync->data.src_ratio = (double)audio->config.out.samplerate /
1438 (double)audio->config.in.samplerate;
1440 buf = hb_buffer_init( count_out * sample_size );
1441 sync->data.data_in = (float *) buf_raw->data;
1442 sync->data.data_out = (float *) buf->data;
1443 if( src_process( sync->state, &sync->data ) )
1445 /* XXX If this happens, we're screwed */
1446 hb_log( "sync: audio 0x%x src_process failed", audio->id );
1448 hb_buffer_close( &buf_raw );
1450 if (sync->data.output_frames_gen <= 0)
1452 // XXX: don't send empty buffers downstream (EOF)
1453 // possibly out-of-sync audio is better than no audio at all
1454 hb_buffer_close(&buf);
1455 return NULL;
1457 buf->size = sync->data.output_frames_gen * sample_size;
1458 duration = (double)( sync->data.output_frames_gen * 90000 ) /
1459 audio->config.out.samplerate;
1461 if( audio->config.out.gain > 0.0 )
1463 int count, ii;
1465 count = buf->size / sizeof(float);
1466 for ( ii = 0; ii < count; ii++ )
1468 double sample;
1470 sample = (double)*(((float*)buf->data)+ii);
1471 sample *= sync->gain_factor;
1472 if (sample > 0)
1473 sample = MIN(sample, 1.0);
1474 else
1475 sample = MAX(sample, -1.0);
1476 *(((float*)buf->data)+ii) = sample;
1479 else if( audio->config.out.gain < 0.0 )
1481 int count, ii;
1483 count = buf->size / sizeof(float);
1484 for ( ii = 0; ii < count; ii++ )
1486 double sample;
1488 sample = (double)*(((float*)buf->data)+ii);
1489 sample *= sync->gain_factor;
1490 *(((float*)buf->data)+ii) = sample;
1495 buf->s.type = AUDIO_BUF;
1496 buf->s.frametype = HB_FRAME_AUDIO;
1498 buf->s.start = start;
1499 sync->next_start += duration;
1500 buf->s.stop = (int64_t)sync->next_start;
1501 return buf;
1504 static void InsertSilence( hb_work_object_t * w, int64_t duration )
1506 hb_work_private_t * pv = w->private_data;
1507 hb_sync_audio_t *sync = &pv->type.audio;
1508 hb_buffer_t *buf;
1509 hb_fifo_t *fifo;
1510 int frame_dur;
1512 // to keep pass-thru and regular audio in sync we generate silence in
1513 // frame-sized units. If the silence duration isn't an integer multiple
1514 // of the frame duration we will truncate or round up depending on
1515 // which minimizes the timing error.
1516 if( w->audio->config.out.codec & HB_ACODEC_PASS_FLAG )
1518 frame_dur = ( 90000 * w->audio->config.in.samples_per_frame ) /
1519 w->audio->config.in.samplerate;
1521 else
1523 frame_dur = ( 90000 * w->audio->config.out.samples_per_frame ) /
1524 w->audio->config.in.samplerate;
1527 while (duration >= frame_dur >> 2)
1529 if( w->audio->config.out.codec & HB_ACODEC_PASS_FLAG )
1531 buf = hb_buffer_init( sync->silence_size );
1532 buf->s.start = sync->next_start;
1533 buf->s.stop = buf->s.start + frame_dur;
1534 memcpy( buf->data, sync->silence_buf, buf->size );
1535 fifo = w->audio->priv.fifo_out;
1536 duration -= frame_dur;
1538 else
1540 int channel_count = hb_mixdown_get_discrete_channel_count( w->audio->config.out.mixdown );
1541 int size = sizeof( float ) *
1542 w->audio->config.out.samples_per_frame *
1543 channel_count;
1544 if (frame_dur > duration)
1546 int samples = duration * w->audio->config.in.samplerate / 90000;
1547 if (samples == 0)
1549 break;
1551 size = sizeof(float) * samples * channel_count;
1552 frame_dur = (90000 * samples) / w->audio->config.in.samplerate;
1554 buf = hb_buffer_init(size);
1555 buf->s.start = sync->next_start;
1556 buf->s.duration = frame_dur;
1557 buf->s.stop = buf->s.start + frame_dur;
1558 memset( buf->data, 0, buf->size );
1559 fifo = w->audio->priv.fifo_sync;
1560 duration -= frame_dur;
1562 buf = OutputAudioFrame( w->audio, buf, sync );
1563 hb_fifo_push( fifo, buf );
1567 static void UpdateState( hb_work_object_t * w )
1569 hb_work_private_t * pv = w->private_data;
1570 hb_sync_video_t * sync = &pv->type.video;
1571 hb_state_t state;
1573 hb_get_state2( pv->job->h, &state );
1574 if ( !pv->common->count_frames )
1576 sync->st_first = hb_get_date();
1577 pv->job->st_pause_date = -1;
1578 pv->job->st_paused = 0;
1580 pv->common->count_frames++;
1582 if (pv->job->indepth_scan)
1584 // Progress for indept scan is handled by reader
1585 // pv->common->count_frames is used during indepth_scan
1586 // to find start & end points.
1587 return;
1590 if( hb_get_date() > sync->st_dates[3] + 1000 )
1592 memmove( &sync->st_dates[0], &sync->st_dates[1],
1593 3 * sizeof( uint64_t ) );
1594 memmove( &sync->st_counts[0], &sync->st_counts[1],
1595 3 * sizeof( uint64_t ) );
1596 sync->st_dates[3] = hb_get_date();
1597 sync->st_counts[3] = pv->common->count_frames;
1600 #define p state.param.working
1601 state.state = HB_STATE_WORKING;
1602 p.progress = (float) pv->common->count_frames / (float) sync->count_frames_max;
1603 if( p.progress > 1.0 )
1605 p.progress = 1.0;
1607 p.rate_cur = 1000.0 *
1608 (float) ( sync->st_counts[3] - sync->st_counts[0] ) /
1609 (float) ( sync->st_dates[3] - sync->st_dates[0] );
1610 if( hb_get_date() > sync->st_first + 4000 )
1612 int eta;
1613 p.rate_avg = 1000.0 * (float) sync->st_counts[3] /
1614 (float) ( sync->st_dates[3] - sync->st_first - pv->job->st_paused);
1615 eta = (float) ( sync->count_frames_max - sync->st_counts[3] ) /
1616 p.rate_avg;
1617 p.hours = eta / 3600;
1618 p.minutes = ( eta % 3600 ) / 60;
1619 p.seconds = eta % 60;
1621 else
1623 p.rate_avg = 0.0;
1624 p.hours = -1;
1625 p.minutes = -1;
1626 p.seconds = -1;
1628 #undef p
1630 hb_set_state( pv->job->h, &state );
1633 static void UpdateSearchState( hb_work_object_t * w, int64_t start )
1635 hb_work_private_t * pv = w->private_data;
1636 hb_sync_video_t * sync = &pv->type.video;
1637 hb_state_t state;
1638 uint64_t now;
1639 double avg;
1641 now = hb_get_date();
1642 if( !pv->common->count_frames )
1644 sync->st_first = now;
1645 pv->job->st_pause_date = -1;
1646 pv->job->st_paused = 0;
1648 pv->common->count_frames++;
1650 if (pv->job->indepth_scan)
1652 // Progress for indept scan is handled by reader
1653 // pv->common->count_frames is used during indepth_scan
1654 // to find start & end points.
1655 return;
1658 hb_get_state2(pv->job->h, &state);
1660 #define p state.param.working
1661 state.state = HB_STATE_SEARCHING;
1662 if ( pv->job->frame_to_start )
1663 p.progress = (float) pv->common->count_frames /
1664 (float) pv->job->frame_to_start;
1665 else if ( pv->job->pts_to_start )
1666 p.progress = (float) start / (float) pv->job->pts_to_start;
1667 else
1668 p.progress = 0;
1669 if( p.progress > 1.0 )
1671 p.progress = 1.0;
1673 if (now > sync->st_first)
1675 int eta = 0;
1677 if ( pv->job->frame_to_start )
1679 avg = 1000.0 * (double)pv->common->count_frames / (now - sync->st_first);
1680 eta = ( pv->job->frame_to_start - pv->common->count_frames ) / avg;
1682 else if ( pv->job->pts_to_start )
1684 avg = 1000.0 * (double)start / (now - sync->st_first);
1685 eta = ( pv->job->pts_to_start - start ) / avg;
1687 p.hours = eta / 3600;
1688 p.minutes = ( eta % 3600 ) / 60;
1689 p.seconds = eta % 60;
1691 else
1693 p.rate_avg = 0.0;
1694 p.hours = -1;
1695 p.minutes = -1;
1696 p.seconds = -1;
1698 #undef p
1700 hb_set_state( pv->job->h, &state );
1703 static void getPtsOffset(hb_work_private_t * pv)
1705 if (pv->common->pts_offset != INT64_MIN)
1706 return;
1708 int64_t first_pts = INT64_MAX;
1709 int ii;
1710 for (ii = 0; ii < pv->common->pts_count; ii++)
1712 if (pv->common->last_pts[ii] != AV_NOPTS_VALUE &&
1713 pv->common->last_pts[ii] < first_pts)
1715 first_pts = pv->common->last_pts[ii];
1718 pv->common->video_pts_slip = pv->common->audio_pts_slip =
1719 pv->common->pts_offset = first_pts;
1720 return;