Commit af70aa45 authored by Anton Khirnov's avatar Anton Khirnov

avconv: add a wrapper for output AVFormatContexts and merge output_opts into it

parent 09af7fb3
...@@ -102,10 +102,6 @@ static const OptionDef options[]; ...@@ -102,10 +102,6 @@ static const OptionDef options[];
static const char *last_asked_format = NULL; static const char *last_asked_format = NULL;
static AVDictionary *ts_scale; static AVDictionary *ts_scale;
static AVFormatContext *output_files[MAX_FILES];
static AVDictionary *output_opts[MAX_FILES];
static int nb_output_files = 0;
static StreamMap *stream_maps = NULL; static StreamMap *stream_maps = NULL;
static int nb_stream_maps; static int nb_stream_maps;
...@@ -310,11 +306,19 @@ typedef struct InputFile { ...@@ -310,11 +306,19 @@ typedef struct InputFile {
int64_t ts_offset; int64_t ts_offset;
} InputFile; } InputFile;
typedef struct OutputFile {
AVFormatContext *ctx;
AVDictionary *opts;
} OutputFile;
static InputStream *input_streams = NULL; static InputStream *input_streams = NULL;
static int nb_input_streams = 0; static int nb_input_streams = 0;
static InputFile *input_files = NULL; static InputFile *input_files = NULL;
static int nb_input_files = 0; static int nb_input_files = 0;
static OutputFile *output_files = NULL;
static int nb_output_files = 0;
#if CONFIG_AVFILTER #if CONFIG_AVFILTER
static int configure_video_filters(InputStream *ist, OutputStream *ost) static int configure_video_filters(InputStream *ist, OutputStream *ost)
...@@ -437,12 +441,12 @@ static int exit_program(int ret) ...@@ -437,12 +441,12 @@ static int exit_program(int ret)
/* close files */ /* close files */
for(i=0;i<nb_output_files;i++) { for(i=0;i<nb_output_files;i++) {
AVFormatContext *s = output_files[i]; AVFormatContext *s = output_files[i].ctx;
if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb) if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
avio_close(s->pb); avio_close(s->pb);
avformat_free_context(s); avformat_free_context(s);
av_free(output_streams_for_file[i]); av_free(output_streams_for_file[i]);
av_dict_free(&output_opts[i]); av_dict_free(&output_files[i].opts);
} }
for(i=0;i<nb_input_files;i++) { for(i=0;i<nb_input_files;i++) {
av_close_input_file(input_files[i].ctx); av_close_input_file(input_files[i].ctx);
...@@ -462,6 +466,7 @@ static int exit_program(int ret) ...@@ -462,6 +466,7 @@ static int exit_program(int ret)
av_freep(&input_streams); av_freep(&input_streams);
av_freep(&input_files); av_freep(&input_files);
av_freep(&output_files);
uninit_opts(); uninit_opts();
av_free(audio_buf); av_free(audio_buf);
...@@ -1270,7 +1275,7 @@ static void do_video_stats(AVFormatContext *os, OutputStream *ost, ...@@ -1270,7 +1275,7 @@ static void do_video_stats(AVFormatContext *os, OutputStream *ost,
} }
} }
static void print_report(AVFormatContext **output_files, static void print_report(OutputFile *output_files,
OutputStream **ost_table, int nb_ostreams, OutputStream **ost_table, int nb_ostreams,
int is_last_report) int is_last_report)
{ {
...@@ -1298,7 +1303,7 @@ static void print_report(AVFormatContext **output_files, ...@@ -1298,7 +1303,7 @@ static void print_report(AVFormatContext **output_files,
} }
oc = output_files[0]; oc = output_files[0].ctx;
total_size = avio_size(oc->pb); total_size = avio_size(oc->pb);
if(total_size<0) // FIXME improve avio_size() so it works with non seekable output too if(total_size<0) // FIXME improve avio_size() so it works with non seekable output too
...@@ -1607,7 +1612,7 @@ static int output_packet(InputStream *ist, int ist_index, ...@@ -1607,7 +1612,7 @@ static int output_packet(InputStream *ist, int ist_index,
if (ost->picref) if (ost->picref)
ist->pts = av_rescale_q(ost->picref->pts, ist_pts_tb, AV_TIME_BASE_Q); ist->pts = av_rescale_q(ost->picref->pts, ist_pts_tb, AV_TIME_BASE_Q);
#endif #endif
os = output_files[ost->file_index]; os = output_files[ost->file_index].ctx;
/* set the input output pts pairs */ /* set the input output pts pairs */
//ost->sync_ipts = (double)(ist->pts + input_files[ist->file_index].ts_offset - start_time)/ AV_TIME_BASE; //ost->sync_ipts = (double)(ist->pts + input_files[ist->file_index].ts_offset - start_time)/ AV_TIME_BASE;
...@@ -1721,7 +1726,7 @@ static int output_packet(InputStream *ist, int ist_index, ...@@ -1721,7 +1726,7 @@ static int output_packet(InputStream *ist, int ist_index,
ost = ost_table[i]; ost = ost_table[i];
if (ost->source_index == ist_index) { if (ost->source_index == ist_index) {
AVCodecContext *enc= ost->st->codec; AVCodecContext *enc= ost->st->codec;
os = output_files[ost->file_index]; os = output_files[ost->file_index].ctx;
if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <=1) if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <=1)
continue; continue;
...@@ -1802,19 +1807,27 @@ static int output_packet(InputStream *ist, int ist_index, ...@@ -1802,19 +1807,27 @@ static int output_packet(InputStream *ist, int ist_index,
return 0; return 0;
} }
static void print_sdp(AVFormatContext **avc, int n) static void print_sdp(OutputFile *output_files, int n)
{ {
char sdp[2048]; char sdp[2048];
int i;
AVFormatContext **avc = av_malloc(sizeof(*avc)*n);
if (!avc)
exit_program(1);
for (i = 0; i < n; i++)
avc[i] = output_files[i].ctx;
av_sdp_create(avc, n, sdp, sizeof(sdp)); av_sdp_create(avc, n, sdp, sizeof(sdp));
printf("SDP:\n%s\n", sdp); printf("SDP:\n%s\n", sdp);
fflush(stdout); fflush(stdout);
av_freep(&avc);
} }
/* /*
* The following code is the main loop of the file converter * The following code is the main loop of the file converter
*/ */
static int transcode(AVFormatContext **output_files, static int transcode(OutputFile *output_files,
int nb_output_files, int nb_output_files,
InputFile *input_files, InputFile *input_files,
int nb_input_files) int nb_input_files)
...@@ -1836,9 +1849,9 @@ static int transcode(AVFormatContext **output_files, ...@@ -1836,9 +1849,9 @@ static int transcode(AVFormatContext **output_files,
/* output stream init */ /* output stream init */
nb_ostreams = 0; nb_ostreams = 0;
for(i=0;i<nb_output_files;i++) { for(i=0;i<nb_output_files;i++) {
os = output_files[i]; os = output_files[i].ctx;
if (!os->nb_streams && !(os->oformat->flags & AVFMT_NOSTREAMS)) { if (!os->nb_streams && !(os->oformat->flags & AVFMT_NOSTREAMS)) {
av_dump_format(output_files[i], i, output_files[i]->filename, 1); av_dump_format(os, i, os->filename, 1);
fprintf(stderr, "Output file #%d does not contain any stream\n", i); fprintf(stderr, "Output file #%d does not contain any stream\n", i);
ret = AVERROR(EINVAL); ret = AVERROR(EINVAL);
goto fail; goto fail;
...@@ -1851,7 +1864,7 @@ static int transcode(AVFormatContext **output_files, ...@@ -1851,7 +1864,7 @@ static int transcode(AVFormatContext **output_files,
goto fail; goto fail;
n = 0; n = 0;
for(k=0;k<nb_output_files;k++) { for(k=0;k<nb_output_files;k++) {
os = output_files[k]; os = output_files[k].ctx;
for (i = 0; i < os->nb_streams; i++, n++) for (i = 0; i < os->nb_streams; i++, n++)
ost_table[n] = output_streams_for_file[k][i]; ost_table[n] = output_streams_for_file[k][i];
} }
...@@ -1859,7 +1872,7 @@ static int transcode(AVFormatContext **output_files, ...@@ -1859,7 +1872,7 @@ static int transcode(AVFormatContext **output_files,
/* for each output stream, we compute the right encoding parameters */ /* for each output stream, we compute the right encoding parameters */
for(i=0;i<nb_ostreams;i++) { for(i=0;i<nb_ostreams;i++) {
ost = ost_table[i]; ost = ost_table[i];
os = output_files[ost->file_index]; os = output_files[ost->file_index].ctx;
ist = &input_streams[ost->source_index]; ist = &input_streams[ost->source_index];
codec = ost->st->codec; codec = ost->st->codec;
...@@ -2168,15 +2181,15 @@ static int transcode(AVFormatContext **output_files, ...@@ -2168,15 +2181,15 @@ static int transcode(AVFormatContext **output_files,
} }
/* open files and write file headers */ /* open files and write file headers */
for(i=0;i<nb_output_files;i++) { for (i = 0; i < nb_output_files; i++) {
os = output_files[i]; os = output_files[i].ctx;
if (avformat_write_header(os, &output_opts[i]) < 0) { if (avformat_write_header(os, &output_files[i].opts) < 0) {
snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?)", i); snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?)", i);
ret = AVERROR(EINVAL); ret = AVERROR(EINVAL);
goto dump_format; goto dump_format;
} }
assert_avoptions(output_opts[i]); assert_avoptions(output_files[i].opts);
if (strcmp(output_files[i]->oformat->name, "rtp")) { if (strcmp(os->oformat->name, "rtp")) {
want_sdp = 0; want_sdp = 0;
} }
} }
...@@ -2185,7 +2198,7 @@ static int transcode(AVFormatContext **output_files, ...@@ -2185,7 +2198,7 @@ static int transcode(AVFormatContext **output_files,
/* dump the file output parameters - cannot be done before in case /* dump the file output parameters - cannot be done before in case
of stream copy */ of stream copy */
for(i=0;i<nb_output_files;i++) { for(i=0;i<nb_output_files;i++) {
av_dump_format(output_files[i], i, output_files[i]->filename, 1); av_dump_format(output_files[i].ctx, i, output_files[i].ctx->filename, 1);
} }
/* dump the stream mapping */ /* dump the stream mapping */
...@@ -2240,7 +2253,7 @@ static int transcode(AVFormatContext **output_files, ...@@ -2240,7 +2253,7 @@ static int transcode(AVFormatContext **output_files,
int64_t ipts; int64_t ipts;
double opts; double opts;
ost = ost_table[i]; ost = ost_table[i];
os = output_files[ost->file_index]; os = output_files[ost->file_index].ctx;
ist = &input_streams[ost->source_index]; ist = &input_streams[ost->source_index];
if(ist->is_past_recording_time || no_packet[ist->file_index]) if(ist->is_past_recording_time || no_packet[ist->file_index])
continue; continue;
...@@ -2273,7 +2286,7 @@ static int transcode(AVFormatContext **output_files, ...@@ -2273,7 +2286,7 @@ static int transcode(AVFormatContext **output_files,
} }
/* finish if limit size exhausted */ /* finish if limit size exhausted */
if (limit_filesize != 0 && limit_filesize <= avio_tell(output_files[0]->pb)) if (limit_filesize != 0 && limit_filesize <= avio_tell(output_files[0].ctx->pb))
break; break;
/* read a frame from it and output it in the fifo */ /* read a frame from it and output it in the fifo */
...@@ -2374,7 +2387,7 @@ static int transcode(AVFormatContext **output_files, ...@@ -2374,7 +2387,7 @@ static int transcode(AVFormatContext **output_files,
/* 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]; os = output_files[i].ctx;
av_write_trailer(os); av_write_trailer(os);
} }
...@@ -3380,7 +3393,7 @@ static int opt_streamid(const char *opt, const char *arg) ...@@ -3380,7 +3393,7 @@ static int opt_streamid(const char *opt, const char *arg)
static int copy_chapters(int infile, int outfile) static int copy_chapters(int infile, int outfile)
{ {
AVFormatContext *is = input_files[infile].ctx; AVFormatContext *is = input_files[infile].ctx;
AVFormatContext *os = output_files[outfile]; AVFormatContext *os = output_files[outfile].ctx;
int i; int i;
for (i = 0; i < is->nb_chapters; i++) { for (i = 0; i < is->nb_chapters; i++) {
...@@ -3571,8 +3584,12 @@ static void opt_output_file(const char *filename) ...@@ -3571,8 +3584,12 @@ static void opt_output_file(const char *filename)
av_dict_copy(&oc->metadata, metadata, 0); av_dict_copy(&oc->metadata, metadata, 0);
av_dict_free(&metadata); av_dict_free(&metadata);
av_dict_copy(&output_opts[nb_output_files], format_opts, 0);
output_files[nb_output_files++] = oc; if (nb_output_files == MAX_FILES)
exit_program(1); /* a temporary hack until all the other MAX_FILES-sized arrays are removed */
output_files = grow_array(output_files, sizeof(*output_files), &nb_output_files, nb_output_files + 1);
output_files[nb_output_files - 1].ctx = oc;
av_dict_copy(&output_files[nb_output_files - 1].opts, format_opts, 0);
/* check filename in case of an image number is expected */ /* check filename in case of an image number is expected */
if (oc->oformat->flags & AVFMT_NEEDNUMBER) { if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
......
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