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
13 #include "samplerate.h"
16 #undef INT64_MIN /* Because it isn't defined correctly in Zeta */
18 #define INT64_MIN (-9223372036854775807LL-1)
20 #define ABS(a) ((a) < 0 ? -(a) : (a))
24 /* Audio/Video sync thread synchronization */
26 hb_cond_t
* next_frame
;
27 int64_t volatile * last_pts
;
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
;
37 /* point-to-point support */
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 */
54 uint8_t * silence_buf
;
56 int drop_video_to_sync
;
65 hb_buffer_t
* list_current
;
67 } subtitle_sanitizer_t
;
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 */
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
;
87 uint64_t st_counts
[4];
92 struct hb_work_private_s
95 hb_sync_common_t
* common
;
98 hb_sync_video_t video
;
99 hb_sync_audio_t audio
;
103 /***********************************************************************
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 /***********************************************************************
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
;
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
) );
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;
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
;
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
;
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
;
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
);
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
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 /***********************************************************************
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
;
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);
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
);
308 hb_unlock( pv
->common
->mutex
);
312 w
->private_data
= NULL
;
315 static hb_buffer_t
* merge_ssa(hb_buffer_t
*a
, hb_buffer_t
*b
)
319 hb_buffer_t
*buf
= hb_buffer_init(a
->size
+ b
->size
);
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
, ',');
333 len
= sprintf((char*)buf
->data
, "%s\n%s", a
->data
, text
);
339 memcpy(buf
->data
, a
->data
, a
->size
);
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
;
356 if (a
!= NULL
&& b
== NULL
&& end
)
358 sanitizer
->list_current
= a
->next
;
359 if (sanitizer
->list_current
== NULL
)
360 sanitizer
->last
= NULL
;
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
;
374 else if (b
!= NULL
&& a
->s
.stop
> b
->s
.start
)
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
;
386 if (sanitizer
->last
== b
)
392 sanitizer
->list_current
= a
;
396 b
->s
.start
= a
->s
.stop
;
398 buf
= merge_ssa(a
, b
);
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
410 if (sanitizer
->last
== b
)
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
;
441 if (buf
->s
.stop
!= AV_NOPTS_VALUE
)
442 buf
->s
.duration
= buf
->s
.stop
- buf
->s
.start
;
444 buf
->s
.duration
= AV_NOPTS_VALUE
;
455 } while (buf
!= NULL
);
460 static hb_buffer_t
* sanitizeSubtitle(
461 hb_work_private_t
* pv
,
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
)
475 if (sub
->s
.stop
!= AV_NOPTS_VALUE
)
476 sub
->s
.duration
= sub
->s
.stop
- sub
->s
.start
;
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
;
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
);
512 if (sanitizer
->last
== NULL
)
514 sanitizer
->list_current
= sanitizer
->last
= sub
;
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
)
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
);
549 // Keeps sync tasks "in sync". I.e. the lowest pts will always be
551 static int waitForSync(hb_work_object_t
* w
, int64_t pts
, int index
,
554 hb_work_private_t
* pv
= w
->private_data
;
556 setSyncPTS(pv
, pts
, index
);
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);
570 (pts
> pv
->common
->last_pts
[ii
] && hb_fifo_is_full(fifo
)))
572 hb_unlock(pv
->common
->mutex
);
578 hb_unlock(pv
->common
->mutex
);
583 static void flushSubtitles(hb_work_private_t
*pv
)
585 hb_job_t
* job
= pv
->job
;
586 hb_subtitle_t
* subtitle
;
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
);
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 /***********************************************************************
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
;
627 if (next
->s
.flags
& HB_BUF_FLAG_EOF
)
629 if (sync
->cur
!= NULL
)
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 */
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
;
654 pv
->common
->start_found
= 1;
655 // Unblock anybody waiting on this threads last PTS
656 setSyncPTS(pv
, INT64_MAX
, 0);
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
;
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
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
)
690 sub
= hb_fifo_get( subtitle
->fifo_raw
);
691 hb_buffer_close( &sub
);
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
);
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
);
717 hb_buffer_close( &next
);
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
);
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();
743 // Unblock anybody waiting on this threads last PTS
744 setSyncPTS(pv
, INT64_MAX
, 0);
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",
755 hb_buffer_close(&sync
->cur
);
756 hb_buffer_close( &next
);
757 *buf_out
= hb_buffer_eof_init();
759 // Unblock anybody waiting on this threads last PTS
760 setSyncPTS(pv
, INT64_MAX
, 0);
764 if (sync
->cur
== NULL
)
770 // At this point, we have 2 video frames wich allows us to set the
771 // duration of the first and output it.
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
786 hb_log( "sync: first pts is %"PRId64
, cur
->s
.start
);
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
;
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
;
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
);
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
);
840 hb_buffer_close( &next
);
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
++)
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
);
881 hb_fifo_push( subtitle
->fifo_out
, out
);
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.
905 int64_t duration
= next_start
- cur
->s
.start
;
906 sync
->cur
= cur
= next
;
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
;
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
;
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
)
944 hb_work_object_t hb_sync_video
=
947 "Video Synchronization",
953 /***********************************************************************
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
);
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
);
986 hb_unlock( pv
->common
->mutex
);
990 w
->private_data
= NULL
;
993 int syncAudioInit( hb_work_object_t
* w
, hb_job_t
* job
)
998 /***********************************************************************
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
;
1015 /* if the next buffer is an eof send it downstream */
1016 if (buf
->s
.flags
& HB_BUF_FLAG_EOF
)
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
;
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
);
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
);
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
;
1093 hb_buffer_close( &buf
);
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
);
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
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
);
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
);
1155 hb_work_object_t hb_sync_audio
=
1158 "AudioSynchronization",
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
;
1174 pv
->common
= common
;
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
;
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
;
1205 switch ( w
->audio
->config
.out
.codec
)
1207 case HB_ACODEC_AC3_PASS
:
1209 codec
= avcodec_find_encoder( AV_CODEC_ID_AC3
);
1211 case HB_ACODEC_EAC3_PASS
:
1213 codec
= avcodec_find_encoder( AV_CODEC_ID_EAC3
);
1215 case HB_ACODEC_AAC_PASS
:
1217 codec
= avcodec_find_encoder_by_name("aac");
1219 case HB_ACODEC_FLAC_PASS
:
1221 codec
= avcodec_find_encoder( AV_CODEC_ID_FLAC
);
1226 codec
= NULL
; // Silence compiler warning
1230 c
= avcodec_alloc_context3(codec
);
1231 c
->bit_rate
= w
->audio
->config
.in
.bitrate
;
1232 c
->sample_rate
= w
->audio
->config
.in
.samplerate
;
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
);
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
;
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);
1286 case AV_MATRIX_ENCODING_DPLIIX
:
1287 case AV_MATRIX_ENCODING_DOLBYEX
:
1288 av_dict_set(&av_opts
, "dsurex_mode", "on", 0);
1290 case AV_MATRIX_ENCODING_DPLIIZ
:
1291 av_dict_set(&av_opts
, "dsurex_mode", "dpliiz", 0);
1293 case AV_MATRIX_ENCODING_DOLBYHEADPHONE
:
1294 av_dict_set(&av_opts
, "dheadphone_mode", "on", 0);
1301 if (w
->audio
->config
.in
.channel_layout
== AV_CH_LAYOUT_STEREO_DOWNMIX
)
1303 c
->channel_layout
= AV_CH_LAYOUT_STEREO
;
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;
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
,
1323 uint8_t *zeros
= calloc(1, input_size
);
1324 avcodec_fill_audio_frame(&frame
, c
->channels
, c
->sample_fmt
, zeros
,
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.
1334 for ( ii
= 0; ii
< 10; ii
++ )
1336 // Prepare output 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
);
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;
1354 sync
->silence_size
= pkt
.size
;
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;
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
);
1377 if( w
->audio
->config
.out
.codec
& HB_ACODEC_PASS_FLAG
)
1379 sync
->drop_video_to_sync
= 1;
1383 /* Not passthru, initialize libsamplerate */
1385 sync
->state
= src_new( SRC_SINC_MEDIUM_QUALITY
,
1386 hb_mixdown_get_discrete_channel_count( w
->audio
->config
.out
.mixdown
),
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)
1406 if ( buf
->s
.duration
> 0 )
1407 duration
= buf
->s
.duration
;
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
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
) *
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
);
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 )
1465 count
= buf
->size
/ sizeof(float);
1466 for ( ii
= 0; ii
< count
; ii
++ )
1470 sample
= (double)*(((float*)buf
->data
)+ii
);
1471 sample
*= sync
->gain_factor
;
1473 sample
= MIN(sample
, 1.0);
1475 sample
= MAX(sample
, -1.0);
1476 *(((float*)buf
->data
)+ii
) = sample
;
1479 else if( audio
->config
.out
.gain
< 0.0 )
1483 count
= buf
->size
/ sizeof(float);
1484 for ( ii
= 0; ii
< count
; ii
++ )
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
;
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
;
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
;
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
;
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
*
1544 if (frame_dur
> duration
)
1546 int samples
= duration
* w
->audio
->config
.in
.samplerate
/ 90000;
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
;
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.
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 )
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 )
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] ) /
1617 p
.hours
= eta
/ 3600;
1618 p
.minutes
= ( eta
% 3600 ) / 60;
1619 p
.seconds
= eta
% 60;
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
;
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.
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
;
1669 if( p
.progress
> 1.0 )
1673 if (now
> sync
->st_first
)
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;
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
)
1708 int64_t first_pts
= INT64_MAX
;
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
;