@@ -17,6 +17,8 @@ extern "C" {
1717#endif /* __cplusplus */
1818
1919 void decode_thread (struct convert_param *stream);
20+ void audio_dummy_thread (Converter *is);
21+ void video_dummy_thread (Converter *is);
2022
2123 void setParam (struct convert_param * param)
2224 {
@@ -237,78 +239,97 @@ void decode_thread(struct convert_param *stream)
237239 }
238240 }
239241
240-
241- stream->stream_count (stream->stream , (int )converter->audio_info .size (), main_audio, s_langp.data (), (int )txt_subtitleStream.size (), main_subtitle, sub_langp.data ());
242-
243-
244- v_langs.clear ();
245- sub_langp.clear ();
246- for (const auto &video: converter->video_info ) {
247- v_langs.resize (v_langs.size () + video->language .size () + 1 );
242+ if (converter->audio_info .size () == 0 ) {
243+ char und[] = " und" ;
244+ char *buf[] = {und};
245+ stream->stream_count (stream->stream , 1 , 0 , buf, (int )txt_subtitleStream.size (), main_subtitle, sub_langp.data ());
248246 }
249- for (int i = 0 ; i < img_subtitleStream.size (); i++) {
250- for (int j = 0 ; j < converter->subtitle_info .size (); j++){
251- if (img_subtitleStream[i] == converter->subtitleStream [j]) {
252- v_langs.resize (v_langs.size () + converter->subtitle_info [j]->language .size () + 1 );
253- break ;
247+ else {
248+ stream->stream_count (stream->stream , (int )converter->audio_info .size (), main_audio, s_langp.data (), (int )txt_subtitleStream.size (), main_subtitle, sub_langp.data ());
249+ }
250+
251+ if (converter->video_info .size () > 0 ) {
252+ v_langs.clear ();
253+ sub_langp.clear ();
254+ for (const auto &video: converter->video_info ) {
255+ v_langs.resize (v_langs.size () + video->language .size () + 1 );
256+ }
257+ for (int i = 0 ; i < img_subtitleStream.size (); i++) {
258+ for (int j = 0 ; j < converter->subtitle_info .size (); j++){
259+ if (img_subtitleStream[i] == converter->subtitleStream [j]) {
260+ v_langs.resize (v_langs.size () + converter->subtitle_info [j]->language .size () + 1 );
261+ break ;
262+ }
254263 }
255264 }
256- }
257- cp = &v_langs[ 0 ];
258- for ( const auto &video: converter-> video_info ) {
259- v_langp. push_back (cp);
260- strcpy (cp, video->language .c_str ()) ;
261- cp += video-> language . size () + 1 ;
262- }
263- for (int i = 0 ; i < img_subtitleStream .size (); i ++) {
264- for ( int j = 0 ; j < converter->subtitle_info . size (); j++) {
265- if (img_subtitleStream[i] == converter-> subtitleStream [j]) {
266- sub_langp. push_back (cp);
267- strcpy (cp, converter->subtitle_info [j]->language .c_str ()) ;
268- cp += converter-> subtitle_info [j]-> language . size () + 1 ;
269- break ;
265+ cp = &v_langs[ 0 ];
266+ for ( const auto &video: converter-> video_info ) {
267+ v_langp. push_back (cp);
268+ strcpy (cp, video-> language . c_str () );
269+ cp += video->language .size () + 1 ;
270+ }
271+ for ( int i = 0 ; i < img_subtitleStream. size (); i++) {
272+ for (int j = 0 ; j < converter-> subtitle_info .size (); j ++){
273+ if (img_subtitleStream[i] == converter->subtitleStream [j]) {
274+ sub_langp. push_back (cp);
275+ strcpy (cp, converter-> subtitle_info [j]-> language . c_str () );
276+ cp += converter->subtitle_info [j]->language .size () + 1 ;
277+ break ;
278+ }
270279 }
271280 }
272- }
273- select_idx[0 ] = converter->bestVideoStream ;
274- select_idx[1 ] = converter->bestSubtileStream ;
275-
276- if (converter->video_info .size () > 1 || img_subtitleStream.size () > 0 ) {
277- stream->stream_select (stream->stream , select_idx, (int )converter->video_info .size (), converter->videoStream .data (), v_langp.data (), (int )img_subtitleStream.size (), img_subtitleStream.data (), sub_langp.data ());
278- }
279-
280- if (select_idx[0 ] < 0 ) {
281- goto failed_run;
282- }
281+ select_idx[0 ] = converter->bestVideoStream ;
282+ select_idx[1 ] = converter->bestSubtileStream ;
283+
284+ if (converter->video_info .size () > 1 || img_subtitleStream.size () > 0 ) {
285+ stream->stream_select (stream->stream , select_idx, (int )converter->video_info .size (), converter->videoStream .data (), v_langp.data (), (int )img_subtitleStream.size (), img_subtitleStream.data (), sub_langp.data ());
286+ }
287+
288+ if (select_idx[0 ] < 0 ) {
289+ goto failed_run;
290+ }
283291
284- for (int i = 0 ; i < converter->subtitleStream .size (); i++) {
285- if (converter->subtitleStream [i] == select_idx[1 ]) {
286- converter->main_subtitle = i;
287- break ;
292+ for (int i = 0 ; i < converter->subtitleStream .size (); i++) {
293+ if (converter->subtitleStream [i] == select_idx[1 ]) {
294+ converter->main_subtitle = i;
295+ break ;
296+ }
288297 }
289- }
290- for ( int i = 0 ; i < converter->videoStream . size (); i++ ) {
291- if ( converter->videoStream [i] == select_idx[ 0 ]) {
292- converter-> main_video = i ;
293- break ;
298+ for ( int i = 0 ; i < converter-> videoStream . size (); i++) {
299+ if ( converter->videoStream [i] == select_idx[ 0 ] ) {
300+ converter->main_video = i;
301+ break ;
302+ }
294303 }
295304 }
296- if (converter->main_video < 0 ) {
297- goto failed_run;
305+ else {
306+ std::shared_ptr<Converter::VideoStreamInfo> info (new Converter::VideoStreamInfo (converter));
307+ info->video_clock_start = 0 ;
308+ info->video_start_pts = 0 ;
309+ info->video_eof = true ;
310+ converter->video_info .push_back (info);
311+ converter->main_video = 0 ;
298312 }
299313
300- if (converter->IsQuit ()) {
301- goto failed_run;
302- }
303-
304314 if (converter->videoStream .size () == 0 || converter->audioStream .size () == 0 ) {
305315 if (converter->videoStream .size () == 0 ) {
306316 av_log (NULL , AV_LOG_VERBOSE, " video missing\n " );
317+ converter->video_thread .push_back (std::thread (video_dummy_thread, converter));
307318 }
308319 else {
309320 av_log (NULL , AV_LOG_VERBOSE, " audio missing\n " );
321+ converter->audio_thread .push_back (std::thread (audio_dummy_thread, converter));
310322 }
311323 }
324+ else {
325+ if (converter->main_video < 0 ) {
326+ goto failed_run;
327+ }
328+ }
329+
330+ if (converter->IsQuit ()) {
331+ goto failed_run;
332+ }
312333
313334 // main decode loop
314335 av_log (NULL , AV_LOG_INFO, " decode_thread read loop\n " );
@@ -517,6 +538,57 @@ void decode_thread(struct convert_param *stream)
517538 av_log (NULL , AV_LOG_INFO, " decode_thread end\n " );
518539}
519540
541+ void video_dummy_thread (Converter *is)
542+ {
543+ int index = 0 ;
544+ av_log (NULL , AV_LOG_INFO, " video_thread %d start\n " , index);
545+ auto encode = ((struct convert_param *)is->param )->encode ;
546+ auto finish = ((struct convert_param *)is->param )->finish ;
547+ auto stream = ((struct convert_param *)is->param )->stream ;
548+ int out_width = 1920 ;
549+ int out_height = 1080 ;
550+ AVFrame outputFrame = { 0 };
551+ // outputFrame.format = AVPixelFormat::AV_PIX_FMT_YUYV422;
552+ outputFrame.format = AVPixelFormat::AV_PIX_FMT_BGRA;
553+ outputFrame.width = out_width;
554+ outputFrame.height = out_height;
555+ av_frame_get_buffer (&outputFrame, 32 );
556+ double pts = 0 ;
557+ int64_t count = 0 ;
558+
559+ while (is->main_video < 0 ) {
560+ if (is->IsQuit ()) goto finish;
561+ av_usleep (10 *1000 );
562+ }
563+ while (is->main_audio < 0 ) {
564+ if (is->IsQuit ()) goto finish;
565+ av_usleep (10 *1000 );
566+ }
567+
568+ av_log (NULL , AV_LOG_INFO, " video_thread %d read loop\n " , index);
569+ while (true ) {
570+ if (is->IsQuit ()) break ;
571+
572+ int key = 1 ;
573+ while (pts > is->audio_info [is->main_audio ]->audio_last_pts ) {
574+ if (is->IsQuit ()) goto finish;
575+ av_usleep (10 *1000 );
576+ }
577+ pts = (double )(count++) / 30.0 ;
578+ encode (stream, pts, key, outputFrame.data [0 ], outputFrame.linesize [0 ], outputFrame.height );
579+ }
580+ loopend:
581+ av_log (NULL , AV_LOG_INFO, " video_thread loop end %d\n " , index);
582+ is->video_info [index]->videoq .clear ();
583+ finish (stream);
584+ finish:
585+ av_frame_unref (&outputFrame);
586+ is->video_info [index]->video_eof = true ;
587+ av_log (NULL , AV_LOG_INFO, " video_thread end %d\n " , index);
588+ return ;
589+ }
590+
591+
520592void video_thread (Converter *is, int index)
521593{
522594 av_log (NULL , AV_LOG_INFO, " video_thread %d start\n " , index);
@@ -1007,8 +1079,8 @@ void audio_thread(Converter *is, int index)
10071079 is->audio_info [index]->audio_clock_start = pts;
10081080 is->audio_info [index]->audio_start_pts = pts_t ;
10091081 }
1010- if (is->audio_info [index]->audio_last_pts != AV_NOPTS_VALUE) {
1011- delta_pts_t = pts_t - is->audio_info [index]->audio_last_pts ;
1082+ if (is->audio_info [index]->audio_last_pts_t != AV_NOPTS_VALUE) {
1083+ delta_pts_t = pts_t - is->audio_info [index]->audio_last_pts_t ;
10121084 delta_pts = av_q2d (is->audio_info [index]->audio_st ->time_base )*delta_pts_t ;
10131085 }
10141086 else if (pts > 0 ) {
@@ -1048,7 +1120,8 @@ void audio_thread(Converter *is, int index)
10481120 is->audio_info [index]->frame_count += out_samples;
10491121
10501122 pts_t = av_rescale_q (is->audio_info [index]->frame_count , av_make_q (1 , audio_out_sample_rate), is->audio_info [index]->audio_st ->time_base );
1051- is->audio_info [index]->audio_last_pts = pts_t ;
1123+ is->audio_info [index]->audio_last_pts_t = pts_t ;
1124+ is->audio_info [index]->audio_last_pts = pts;
10521125
10531126 av_log (NULL , AV_LOG_INFO, " audio %d last pts %lld\n " , index, pts_t );
10541127
@@ -1064,7 +1137,8 @@ void audio_thread(Converter *is, int index)
10641137 is->audio_info [index]->frame_count += out_samples+delta_sample;
10651138
10661139 pts_t = av_rescale_q (is->audio_info [index]->frame_count , av_make_q (1 , audio_out_sample_rate), is->audio_info [index]->audio_st ->time_base );
1067- is->audio_info [index]->audio_last_pts = pts_t ;
1140+ is->audio_info [index]->audio_last_pts_t = pts_t ;
1141+ is->audio_info [index]->audio_last_pts = pts;
10681142 av_log (NULL , AV_LOG_INFO, " audio %d last pts %lld\n " , index, pts_t );
10691143
10701144 encode (stream, (double )is->audio_info [index]->frame_count / audio_out_sample_rate, (uint8_t *)&audio_buf[offset*audio_out_channels], fix_out_size, index);
@@ -1090,7 +1164,8 @@ void audio_thread(Converter *is, int index)
10901164 is->audio_info [index]->frame_count += out_samples;
10911165
10921166 pts_t = av_rescale_q (is->audio_info [index]->frame_count , av_make_q (1 , audio_out_sample_rate), is->audio_info [index]->audio_st ->time_base );
1093- is->audio_info [index]->audio_last_pts = pts_t ;
1167+ is->audio_info [index]->audio_last_pts_t = pts_t ;
1168+ is->audio_info [index]->audio_last_pts = pts;
10941169
10951170 av_log (NULL , AV_LOG_INFO, " audio %d last pts %lld\n " , index, pts_t );
10961171
@@ -1108,7 +1183,7 @@ void audio_thread(Converter *is, int index)
11081183
11091184 if (is->audio_info [i]->absent ) {
11101185 // sync main audio and output same content
1111- is->audio_info [i]->audio_last_pts = is->audio_info [index]->audio_last_pts ;
1186+ is->audio_info [i]->audio_last_pts_t = is->audio_info [index]->audio_last_pts_t ;
11121187 is->audio_info [i]->audio_clock_start = is->audio_info [index]->audio_clock_start ;
11131188 is->audio_info [i]->audio_start_pts = is->audio_info [index]->audio_start_pts ;
11141189
@@ -1156,6 +1231,55 @@ void audio_thread(Converter *is, int index)
11561231 return ;
11571232}
11581233
1234+ void audio_dummy_thread (Converter *is)
1235+ {
1236+ int index = 0 ;
1237+ av_log (NULL , AV_LOG_INFO, " audio_thread %d start\n " , index);
1238+ auto encode = ((struct convert_param *)is->param )->encode_sound ;
1239+ auto stream = ((struct convert_param *)is->param )->stream ;
1240+ uint8_t *silence_buf = NULL ;
1241+ int silence_buflen = 0 ;
1242+
1243+ int audio_out_channels = 2 ;
1244+ int audio_out_sample_rate = 48000 ;
1245+ double pts = 0 ;
1246+ uint64_t frame_count = 0 ;
1247+
1248+ while (is->main_video < 0 ) {
1249+ if (is->IsQuit ()) goto quit_audio;
1250+ av_usleep (10 *1000 );
1251+ }
1252+ // wait video
1253+ while (isnan (is->video_info [is->main_video ]->video_clock_start )) {
1254+ if (is->IsQuit ()) goto quit_audio;
1255+ av_usleep (10 *1000 );
1256+ }
1257+
1258+ while (true ) {
1259+ if (is->IsQuit ()) break ;
1260+
1261+ int sample_count = 4096 ;
1262+ int pad_size = sizeof (float ) * sample_count * audio_out_channels;
1263+ if (silence_buflen < pad_size) {
1264+ delete [] silence_buf;
1265+ silence_buf = new uint8_t [pad_size];
1266+ silence_buflen = pad_size;
1267+ memset (silence_buf, 0 , pad_size);
1268+ }
1269+
1270+ pts += (double )(sample_count) / audio_out_sample_rate;
1271+ frame_count += sample_count;
1272+ encode (stream, (double )frame_count / audio_out_sample_rate, silence_buf, pad_size, index);
1273+
1274+ av_log (NULL , AV_LOG_INFO, " audio %d silence %d\n " , index, sample_count);
1275+ }// while(true)
1276+ quit_audio:
1277+ av_log (NULL , AV_LOG_INFO, " audio_thread loop %d end\n " , index);
1278+ delete [] silence_buf;
1279+ av_log (NULL , AV_LOG_INFO, " audio_thread %d end\n " , index);
1280+ return ;
1281+ }
1282+
11591283bool Converter::configure_audio_filters (AVFilterContext **filt_in, AVFilterContext **filt_out, AVFilterGraph *graph, const AudioParams &audio_filter_src, int audio_out_sample_rate, int audio_out_channels)
11601284{
11611285 char asrc_args[256 ] = { 0 };
0 commit comments