| Index: patched-ffmpeg-mt/ffmpeg.c
|
| ===================================================================
|
| --- patched-ffmpeg-mt/ffmpeg.c (revision 41250)
|
| +++ patched-ffmpeg-mt/ffmpeg.c (working copy)
|
| @@ -44,10 +44,15 @@
|
|
|
| #if HAVE_SYS_RESOURCE_H
|
| #include <sys/types.h>
|
| +#include <sys/time.h>
|
| #include <sys/resource.h>
|
| #elif HAVE_GETPROCESSTIMES
|
| #include <windows.h>
|
| #endif
|
| +#if HAVE_GETPROCESSMEMORYINFO
|
| +#include <windows.h>
|
| +#include <psapi.h>
|
| +#endif
|
|
|
| #if HAVE_SYS_SELECT_H
|
| #include <sys/select.h>
|
| @@ -61,7 +66,6 @@
|
| #elif HAVE_CONIO_H
|
| #include <conio.h>
|
| #endif
|
| -#undef time //needed because HAVE_AV_CONFIG_H is defined on top
|
| #include <time.h>
|
|
|
| #include "cmdutils.h"
|
| @@ -69,8 +73,6 @@
|
| #undef NDEBUG
|
| #include <assert.h>
|
|
|
| -#undef exit
|
| -
|
| const char program_name[] = "FFmpeg";
|
| const int program_birth_year = 2000;
|
|
|
| @@ -301,6 +303,7 @@
|
| int64_t pts; /* current pts */
|
| int is_start; /* is 1 at the start and after a discontinuity */
|
| int showed_multi_packet_warning;
|
| + int is_past_recording_time;
|
| } AVInputStream;
|
|
|
| typedef struct AVInputFile {
|
| @@ -1309,7 +1312,7 @@
|
| ist->pts= ist->next_pts;
|
|
|
| if(avpkt.size && avpkt.size != pkt->size &&
|
| - (!ist->showed_multi_packet_warning && verbose>0 || verbose>1)){
|
| + ((!ist->showed_multi_packet_warning && verbose>0) || verbose>1)){
|
| fprintf(stderr, "Multiple frames in a packet from stream %d\n", pkt->stream_index);
|
| ist->showed_multi_packet_warning=1;
|
| }
|
| @@ -1502,7 +1505,10 @@
|
| opkt.flags= pkt->flags;
|
|
|
| //FIXME remove the following 2 lines they shall be replaced by the bitstream filters
|
| - if(ost->st->codec->codec_id != CODEC_ID_H264) {
|
| + if( ost->st->codec->codec_id != CODEC_ID_H264
|
| + && ost->st->codec->codec_id != CODEC_ID_MPEG1VIDEO
|
| + && ost->st->codec->codec_id != CODEC_ID_MPEG2VIDEO
|
| + ) {
|
| if(av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, data_buf, data_size, pkt->flags & PKT_FLAG_KEY))
|
| opkt.destruct= av_destruct_packet;
|
| } else {
|
| @@ -1632,32 +1638,6 @@
|
| fflush(stdout);
|
| }
|
|
|
| -static int stream_index_from_inputs(AVFormatContext **input_files,
|
| - int nb_input_files,
|
| - AVInputFile *file_table,
|
| - AVInputStream **ist_table,
|
| - enum CodecType type,
|
| - int programid)
|
| -{
|
| - int p, q, z;
|
| - for(z=0; z<nb_input_files; z++) {
|
| - AVFormatContext *ic = input_files[z];
|
| - for(p=0; p<ic->nb_programs; p++) {
|
| - AVProgram *program = ic->programs[p];
|
| - if(program->id != programid)
|
| - continue;
|
| - for(q=0; q<program->nb_stream_indexes; q++) {
|
| - int sidx = program->stream_index[q];
|
| - int ris = file_table[z].ist_index + sidx;
|
| - if(ist_table[ris]->discard && ic->streams[sidx]->codec->codec_type == type)
|
| - return ris;
|
| - }
|
| - }
|
| - }
|
| -
|
| - return -1;
|
| -}
|
| -
|
| /*
|
| * The following code is the main loop of the file converter
|
| */
|
| @@ -1789,33 +1769,42 @@
|
| }
|
|
|
| } else {
|
| - if(opt_programid) {
|
| - found = 0;
|
| - j = stream_index_from_inputs(input_files, nb_input_files, file_table, ist_table, ost->st->codec->codec_type, opt_programid);
|
| - if(j != -1) {
|
| - ost->source_index = j;
|
| - found = 1;
|
| - }
|
| - } else {
|
| + int best_nb_frames=-1;
|
| /* get corresponding input stream index : we select the first one with the right type */
|
| found = 0;
|
| for(j=0;j<nb_istreams;j++) {
|
| + int skip=0;
|
| ist = ist_table[j];
|
| - if (ist->discard &&
|
| + if(opt_programid){
|
| + int pi,si;
|
| + AVFormatContext *f= input_files[ ist->file_index ];
|
| + skip=1;
|
| + for(pi=0; pi<f->nb_programs; pi++){
|
| + AVProgram *p= f->programs[pi];
|
| + if(p->id == opt_programid)
|
| + for(si=0; si<p->nb_stream_indexes; si++){
|
| + if(f->streams[ p->stream_index[si] ] == ist->st)
|
| + skip=0;
|
| + }
|
| + }
|
| + }
|
| + if (ist->discard && ist->st->discard != AVDISCARD_ALL && !skip &&
|
| ist->st->codec->codec_type == ost->st->codec->codec_type) {
|
| - ost->source_index = j;
|
| - found = 1;
|
| - break;
|
| + if(best_nb_frames < ist->st->codec_info_nb_frames){
|
| + best_nb_frames= ist->st->codec_info_nb_frames;
|
| + ost->source_index = j;
|
| + found = 1;
|
| + }
|
| }
|
| }
|
| - }
|
|
|
| if (!found) {
|
| if(! opt_programid) {
|
| /* try again and reuse existing stream */
|
| for(j=0;j<nb_istreams;j++) {
|
| ist = ist_table[j];
|
| - if (ist->st->codec->codec_type == ost->st->codec->codec_type) {
|
| + if ( ist->st->codec->codec_type == ost->st->codec->codec_type
|
| + && ist->st->discard != AVDISCARD_ALL) {
|
| ost->source_index = j;
|
| found = 1;
|
| }
|
| @@ -1840,7 +1829,7 @@
|
|
|
| /* for each output stream, we compute the right encoding parameters */
|
| for(i=0;i<nb_ostreams;i++) {
|
| - AVMetadataTag *lang;
|
| + AVMetadataTag *t = NULL, *lang = NULL;
|
| ost = ost_table[i];
|
| os = output_files[ost->file_index];
|
| ist = ist_table[ost->source_index];
|
| @@ -1848,9 +1837,13 @@
|
| codec = ost->st->codec;
|
| icodec = ist->st->codec;
|
|
|
| - if ((lang=av_metadata_get(ist->st->metadata, "language", NULL, 0))
|
| - && !av_metadata_get(ost->st->metadata, "language", NULL, 0))
|
| - av_metadata_set(&ost->st->metadata, "language", lang->value);
|
| + if (av_metadata_get(ist->st->metadata, "language", NULL, 0))
|
| + lang = av_metadata_get(ost->st->metadata, "language", NULL, 0);
|
| + while ((t = av_metadata_get(ist->st->metadata, "", t, AV_METADATA_IGNORE_SUFFIX))) {
|
| + if (lang && !strcmp(t->key, "language"))
|
| + continue;
|
| + av_metadata_set2(&ost->st->metadata, t->key, t->value, 0);
|
| + }
|
|
|
| ost->st->disposition = ist->st->disposition;
|
| codec->bits_per_raw_sample= icodec->bits_per_raw_sample;
|
| @@ -2093,25 +2086,14 @@
|
|
|
| /* init pts */
|
| for(i=0;i<nb_istreams;i++) {
|
| + AVStream *st;
|
| ist = ist_table[i];
|
| - ist->pts = 0;
|
| + st= ist->st;
|
| + ist->pts = st->avg_frame_rate.num ? - st->codec->has_b_frames*AV_TIME_BASE / av_q2d(st->avg_frame_rate) : 0;
|
| ist->next_pts = AV_NOPTS_VALUE;
|
| ist->is_start = 1;
|
| }
|
|
|
| - /* set the duration of the output to the duration of the input
|
| - * if the output ends up being different, it'll be corrected later */
|
| - for (i=0;i<nb_output_files;i++) {
|
| - AVFormatContext *out_file = output_files[i];
|
| - AVFormatContext *in_file = input_files[i];
|
| -
|
| - if (recording_time != INT64_MAX) {
|
| - out_file->duration = recording_time / 1000000 * AV_TIME_BASE;
|
| - } else {
|
| - out_file->duration = in_file->duration;
|
| - }
|
| - }
|
| -
|
| /* set meta data information from input file if required */
|
| for (i=0;i<nb_meta_data_maps;i++) {
|
| AVFormatContext *out_file;
|
| @@ -2226,11 +2208,8 @@
|
| ost = ost_table[i];
|
| os = output_files[ost->file_index];
|
| ist = ist_table[ost->source_index];
|
| - if(no_packet[ist->file_index])
|
| + if(ist->is_past_recording_time || no_packet[ist->file_index])
|
| continue;
|
| - if(ost->st->codec->codec_type == CODEC_TYPE_VIDEO)
|
| - opts = ost->sync_opts * av_q2d(ost->st->codec->time_base);
|
| - else
|
| opts = ost->st->pts.val * av_q2d(ost->st->time_base);
|
| ipts = (double)ist->pts;
|
| if (!file_table[ist->file_index].eof_reached){
|
| @@ -2259,10 +2238,6 @@
|
| break;
|
| }
|
|
|
| - /* finish if recording time exhausted */
|
| - if (opts_min >= (recording_time / 1000000.0))
|
| - break;
|
| -
|
| /* finish if limit size exhausted */
|
| if (limit_filesize != 0 && limit_filesize < url_ftell(output_files[0]->pb))
|
| break;
|
| @@ -2326,8 +2301,11 @@
|
| }
|
|
|
| /* finish if recording time exhausted */
|
| - if (pkt.pts * av_q2d(ist->st->time_base) >= (recording_time / 1000000.0))
|
| + if (recording_time != INT64_MAX &&
|
| + av_compare_ts(pkt.pts, ist->st->time_base, recording_time + start_time, (AVRational){1, 1000000}) >= 0) {
|
| + ist->is_past_recording_time = 1;
|
| goto discard_packet;
|
| + }
|
|
|
| //fprintf(stderr,"read #%d.%d size=%d\n", ist->file_index, ist->index, pkt.size);
|
| if (output_packet(ist, ist_index, ost_table, nb_ostreams, &pkt) < 0) {
|
| @@ -2600,7 +2578,7 @@
|
| av_exit(1);
|
| }
|
| } else {
|
| - list_fmts(avcodec_pix_fmt_string, PIX_FMT_NB);
|
| + show_pix_fmts();
|
| av_exit(0);
|
| }
|
| }
|
| @@ -2866,7 +2844,10 @@
|
| int64_t timestamp;
|
|
|
| if (last_asked_format) {
|
| - file_iformat = av_find_input_format(last_asked_format);
|
| + if (!(file_iformat = av_find_input_format(last_asked_format))) {
|
| + fprintf(stderr, "Unknown input format: '%s'\n", last_asked_format);
|
| + av_exit(1);
|
| + }
|
| last_asked_format = NULL;
|
| }
|
|
|
| @@ -2913,10 +2894,27 @@
|
| av_exit(1);
|
| }
|
| if(opt_programid) {
|
| - int i;
|
| - for(i=0; i<ic->nb_programs; i++)
|
| - if(ic->programs[i]->id != opt_programid)
|
| - ic->programs[i]->discard = AVDISCARD_ALL;
|
| + int i, j;
|
| + int found=0;
|
| + for(i=0; i<ic->nb_streams; i++){
|
| + ic->streams[i]->discard= AVDISCARD_ALL;
|
| + }
|
| + for(i=0; i<ic->nb_programs; i++){
|
| + AVProgram *p= ic->programs[i];
|
| + if(p->id != opt_programid){
|
| + p->discard = AVDISCARD_ALL;
|
| + }else{
|
| + found=1;
|
| + for(j=0; j<p->nb_stream_indexes; j++){
|
| + ic->streams[p->stream_index[j]]->discard= 0;
|
| + }
|
| + }
|
| + }
|
| + if(!found){
|
| + fprintf(stderr, "Specified program id not found\n");
|
| + av_exit(1);
|
| + }
|
| + opt_programid=0;
|
| }
|
|
|
| ic->loop_input = loop_input;
|
| @@ -3210,6 +3208,7 @@
|
| video_disable = 0;
|
| av_freep(&video_codec_name);
|
| video_stream_copy = 0;
|
| + frame_pix_fmt = PIX_FMT_NONE;
|
| }
|
|
|
| static void new_audio_stream(AVFormatContext *oc)
|
| @@ -3544,6 +3543,24 @@
|
| #endif
|
| }
|
|
|
| +static int64_t getmaxrss(void)
|
| +{
|
| +#if HAVE_GETRUSAGE && HAVE_STRUCT_RUSAGE_RU_MAXRSS
|
| + struct rusage rusage;
|
| + getrusage(RUSAGE_SELF, &rusage);
|
| + return (int64_t)rusage.ru_maxrss * 1024;
|
| +#elif HAVE_GETPROCESSMEMORYINFO
|
| + HANDLE proc;
|
| + PROCESS_MEMORY_COUNTERS memcounters;
|
| + proc = GetCurrentProcess();
|
| + memcounters.cb = sizeof(memcounters);
|
| + GetProcessMemoryInfo(proc, &memcounters, sizeof(memcounters));
|
| + return memcounters.PeakPagefileUsage;
|
| +#else
|
| + return 0;
|
| +#endif
|
| +}
|
| +
|
| static void parse_matrix_coeffs(uint16_t *dest, const char *str)
|
| {
|
| int i;
|
| @@ -4038,7 +4055,8 @@
|
| av_exit(1);
|
| ti = getutime() - ti;
|
| if (do_benchmark) {
|
| - printf("bench: utime=%0.3fs\n", ti / 1000000.0);
|
| + int maxrss = getmaxrss() / 1024;
|
| + printf("bench: utime=%0.3fs maxrss=%ikB\n", ti / 1000000.0, maxrss);
|
| }
|
|
|
| return av_exit(0);
|
|
|