Commit 1c169782 authored by Anton Khirnov's avatar Anton Khirnov

avconv: explicitly postpone writing the header until all streams are initialized

This should have no practical effect for now, but will make a difference
in the following commits.
parent 5b63b156
...@@ -87,7 +87,7 @@ static FILE *vstats_file; ...@@ -87,7 +87,7 @@ static FILE *vstats_file;
static int nb_frames_drop = 0; static int nb_frames_drop = 0;
static int want_sdp = 1;
#if HAVE_PTHREADS #if HAVE_PTHREADS
/* signal to input threads that they should exit; set by the main thread */ /* signal to input threads that they should exit; set by the main thread */
...@@ -1487,8 +1487,14 @@ static void print_sdp(void) ...@@ -1487,8 +1487,14 @@ static void print_sdp(void)
{ {
char sdp[16384]; char sdp[16384];
int i; int i;
AVFormatContext **avc = av_malloc(sizeof(*avc) * nb_output_files); AVFormatContext **avc;
for (i = 0; i < nb_output_files; i++) {
if (!output_files[i]->header_written)
return;
}
avc = av_malloc(sizeof(*avc) * nb_output_files);
if (!avc) if (!avc)
exit_program(1); exit_program(1);
for (i = 0; i < nb_output_files; i++) for (i = 0; i < nb_output_files; i++)
...@@ -1618,6 +1624,42 @@ static InputStream *get_input_stream(OutputStream *ost) ...@@ -1618,6 +1624,42 @@ static InputStream *get_input_stream(OutputStream *ost)
return NULL; return NULL;
} }
/* open the muxer when all the streams are initialized */
static int check_init_output_file(OutputFile *of, int file_index)
{
int ret, i;
for (i = 0; i < of->ctx->nb_streams; i++) {
OutputStream *ost = output_streams[of->ost_index + i];
if (!ost->initialized)
return 0;
}
of->ctx->interrupt_callback = int_cb;
ret = avformat_write_header(of->ctx, &of->opts);
if (ret < 0) {
char errbuf[128];
av_strerror(ret, errbuf, sizeof(errbuf));
av_log(NULL, AV_LOG_ERROR,
"Could not write header for output file #%d "
"(incorrect codec parameters ?): %s",
file_index, errbuf);
return ret;
}
assert_avoptions(of->opts);
of->header_written = 1;
av_dump_format(of->ctx, file_index, of->ctx->filename, 1);
if (want_sdp)
print_sdp();
return 0;
}
static int init_output_bsfs(OutputStream *ost) static int init_output_bsfs(OutputStream *ost)
{ {
AVBSFContext *ctx; AVBSFContext *ctx;
...@@ -1860,6 +1902,12 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len) ...@@ -1860,6 +1902,12 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len)
if (ret < 0) if (ret < 0)
return ret; return ret;
ost->initialized = 1;
ret = check_init_output_file(output_files[ost->file_index], ost->file_index);
if (ret < 0)
return ret;
return ret; return ret;
} }
...@@ -1929,7 +1977,6 @@ static int transcode_init(void) ...@@ -1929,7 +1977,6 @@ static int transcode_init(void)
OutputStream *ost; OutputStream *ost;
InputStream *ist; InputStream *ist;
char error[1024]; char error[1024];
int want_sdp = 1;
/* init framerate emulation */ /* init framerate emulation */
for (i = 0; i < nb_input_files; i++) { for (i = 0; i < nb_input_files; i++) {
...@@ -2051,33 +2098,7 @@ static int transcode_init(void) ...@@ -2051,33 +2098,7 @@ static int transcode_init(void)
} }
} }
/* open files and write file headers */
for (i = 0; i < nb_output_files; i++) {
oc = output_files[i]->ctx;
oc->interrupt_callback = int_cb;
if ((ret = avformat_write_header(oc, &output_files[i]->opts)) < 0) {
char errbuf[128];
av_strerror(ret, errbuf, sizeof(errbuf));
snprintf(error, sizeof(error),
"Could not write header for output file #%d "
"(incorrect codec parameters ?): %s",
i, errbuf);
ret = AVERROR(EINVAL);
goto dump_format;
}
assert_avoptions(output_files[i]->opts);
if (strcmp(oc->oformat->name, "rtp")) {
want_sdp = 0;
}
}
dump_format: dump_format:
/* dump the file output parameters - cannot be done before in case
of stream copy */
for (i = 0; i < nb_output_files; i++) {
av_dump_format(output_files[i]->ctx, i, output_files[i]->ctx->filename, 1);
}
/* dump the stream mapping */ /* dump the stream mapping */
av_log(NULL, AV_LOG_INFO, "Stream mapping:\n"); av_log(NULL, AV_LOG_INFO, "Stream mapping:\n");
for (i = 0; i < nb_input_streams; i++) { for (i = 0; i < nb_input_streams; i++) {
...@@ -2166,10 +2187,6 @@ static int transcode_init(void) ...@@ -2166,10 +2187,6 @@ static int transcode_init(void)
return ret; return ret;
} }
if (want_sdp) {
print_sdp();
}
return 0; return 0;
} }
...@@ -2672,6 +2689,13 @@ static int transcode(void) ...@@ -2672,6 +2689,13 @@ static int transcode(void)
/* write the trailer if needed and close file */ /* write the trailer if needed and close file */
for (i = 0; i < nb_output_files; i++) { for (i = 0; i < nb_output_files; i++) {
os = output_files[i]->ctx; os = output_files[i]->ctx;
if (!output_files[i]->header_written) {
av_log(NULL, AV_LOG_ERROR,
"Nothing was written into output file %d (%s), because "
"at least one of its streams received no packets.\n",
i, os->filename);
continue;
}
av_write_trailer(os); av_write_trailer(os);
} }
...@@ -2761,7 +2785,7 @@ static int64_t getmaxrss(void) ...@@ -2761,7 +2785,7 @@ static int64_t getmaxrss(void)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int ret; int i, ret;
int64_t ti; int64_t ti;
register_exit(avconv_cleanup); register_exit(avconv_cleanup);
...@@ -2796,6 +2820,11 @@ int main(int argc, char **argv) ...@@ -2796,6 +2820,11 @@ int main(int argc, char **argv)
exit_program(1); exit_program(1);
} }
for (i = 0; i < nb_output_files; i++) {
if (strcmp(output_files[i]->ctx->oformat->name, "rtp"))
want_sdp = 0;
}
ti = getutime(); ti = getutime();
if (transcode() < 0) if (transcode() < 0)
exit_program(1); exit_program(1);
......
...@@ -366,6 +366,12 @@ typedef struct OutputStream { ...@@ -366,6 +366,12 @@ typedef struct OutputStream {
AVDictionary *resample_opts; AVDictionary *resample_opts;
int finished; /* no more packets should be written for this stream */ int finished; /* no more packets should be written for this stream */
int stream_copy; int stream_copy;
// init_output_stream() has been called for this stream
// The encoder and the bistream filters have been initialized and the stream
// parameters are set in the AVStream.
int initialized;
const char *attachment_filename; const char *attachment_filename;
int copy_initial_nonkeyframes; int copy_initial_nonkeyframes;
...@@ -396,6 +402,8 @@ typedef struct OutputFile { ...@@ -396,6 +402,8 @@ typedef struct OutputFile {
uint64_t limit_filesize; uint64_t limit_filesize;
int shortest; int shortest;
int header_written;
} OutputFile; } OutputFile;
extern InputStream **input_streams; extern InputStream **input_streams;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment