Skip to content

Commit 719fb78

Browse files
committed
v1.4.0(44)
fix converter: support no audio or no video
1 parent d8cc8bc commit 719fb78

File tree

7 files changed

+191
-66
lines changed

7 files changed

+191
-66
lines changed

RemoteCloud/RemoteCloud/Storages/DropBoxStorage.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1055,7 +1055,7 @@ public class DropBoxStorage: NetworkStorage, URLSessionTaskDelegate, URLSessionD
10551055

10561056
#if !targetEnvironment(macCatalyst)
10571057
let config = URLSessionConfiguration.background(withIdentifier: "\(Bundle.main.bundleIdentifier!).\(self.storageName ?? "").\(Int.random(in: 0..<0xffffffff))")
1058-
config.isDiscretionary = true
1058+
//config.isDiscretionary = true
10591059
config.sessionSendsLaunchEvents = true
10601060
#else
10611061
let config = URLSessionConfiguration.default

RemoteCloud/RemoteCloud/Storages/GoogleDriveStorage.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1676,7 +1676,7 @@ public class GoogleDriveStorage: NetworkStorage, URLSessionTaskDelegate, URLSess
16761676

16771677
#if !targetEnvironment(macCatalyst)
16781678
let config = URLSessionConfiguration.background(withIdentifier: "\(Bundle.main.bundleIdentifier!).\(self.storageName ?? "").\(Int.random(in: 0..<0xffffffff))")
1679-
config.isDiscretionary = true
1679+
//config.isDiscretionary = true
16801680
config.sessionSendsLaunchEvents = true
16811681
#else
16821682
let config = URLSessionConfiguration.default

RemoteCloud/RemoteCloud/Storages/OneDriveStorage.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1065,7 +1065,7 @@ public class OneDriveStorage: NetworkStorage, URLSessionTaskDelegate, URLSession
10651065

10661066
#if !targetEnvironment(macCatalyst)
10671067
let config = URLSessionConfiguration.background(withIdentifier: "\(Bundle.main.bundleIdentifier!).\(self.storageName ?? "").\(Int.random(in: 0..<0xffffffff))")
1068-
config.isDiscretionary = true
1068+
//config.isDiscretionary = true
10691069
config.sessionSendsLaunchEvents = true
10701070
#else
10711071
let config = URLSessionConfiguration.default

RemoteCloud/RemoteCloud/Storages/pCloudStorage.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1219,7 +1219,7 @@ public class pCloudStorage: NetworkStorage, URLSessionTaskDelegate, URLSessionDa
12191219

12201220
#if !targetEnvironment(macCatalyst)
12211221
let config = URLSessionConfiguration.background(withIdentifier: "\(Bundle.main.bundleIdentifier!).\(self.storageName ?? "").\(Int.random(in: 0..<0xffffffff))")
1222-
config.isDiscretionary = true
1222+
//config.isDiscretionary = true
12231223
config.sessionSendsLaunchEvents = true
12241224
#else
12251225
let config = URLSessionConfiguration.default

ccViewer/ccViewer.xcodeproj/project.pbxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,7 @@
809809
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
810810
CODE_SIGN_ENTITLEMENTS = ccViewer/ccViewer.entitlements;
811811
CODE_SIGN_STYLE = Automatic;
812-
CURRENT_PROJECT_VERSION = 43;
812+
CURRENT_PROJECT_VERSION = 44;
813813
DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = YES;
814814
DEVELOPMENT_TEAM = 7A9X38B4YU;
815815
FRAMEWORK_SEARCH_PATHS = (
@@ -842,7 +842,7 @@
842842
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
843843
CODE_SIGN_ENTITLEMENTS = ccViewer/ccViewer.entitlements;
844844
CODE_SIGN_STYLE = Automatic;
845-
CURRENT_PROJECT_VERSION = 43;
845+
CURRENT_PROJECT_VERSION = 44;
846846
DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = YES;
847847
DEVELOPMENT_TEAM = 7A9X38B4YU;
848848
FRAMEWORK_SEARCH_PATHS = (

ffconverter/ffconverter/converter.cpp

Lines changed: 183 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
520592
void 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+
11591283
bool 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 };

ffconverter/ffconverter/converter.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ class Converter {
8686
audio_eof_enum audio_eof = playing;
8787
AudioParams audio_filter_src = {};
8888
std::shared_ptr<AVCodecContext> audio_ctx;
89-
int64_t audio_last_pts = AV_NOPTS_VALUE;
89+
int64_t audio_last_pts_t = AV_NOPTS_VALUE;
90+
double audio_last_pts = NAN;
9091
double audio_clock_start = NAN;
9192
int64_t audio_start_pts = AV_NOPTS_VALUE;
9293
uint64_t frame_count = 0;

0 commit comments

Comments
 (0)