mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
* Fix nasty problem with unitialized memory in the file_table
* Add default entries to switch statements to catch programming errors * Fix problem with high CPU usage when capturing live (the audio grabber is non-blocking for some reason). This is the stream_no_data stuff. * Handle the video grabber getting behind in its work -- PKT_FLAG_DROPPED_FRAME Originally committed as revision 453 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
c6a8f2ce07
commit
51bd4565f7
49
ffmpeg.c
49
ffmpeg.c
@ -138,6 +138,7 @@ typedef struct AVInputStream {
|
|||||||
int discard; /* true if stream data should be discarded */
|
int discard; /* true if stream data should be discarded */
|
||||||
int decoding_needed; /* true if the packets must be decoded in 'raw_fifo' */
|
int decoding_needed; /* true if the packets must be decoded in 'raw_fifo' */
|
||||||
INT64 pts; /* current pts */
|
INT64 pts; /* current pts */
|
||||||
|
int pts_increment; /* expected pts increment for next packet */
|
||||||
int frame_number; /* current frame */
|
int frame_number; /* current frame */
|
||||||
INT64 sample_index; /* current sample */
|
INT64 sample_index; /* current sample */
|
||||||
} AVInputStream;
|
} AVInputStream;
|
||||||
@ -599,13 +600,12 @@ static int av_encode(AVFormatContext **output_files,
|
|||||||
AVInputStream *ist, **ist_table = NULL;
|
AVInputStream *ist, **ist_table = NULL;
|
||||||
INT64 min_pts, start_time;
|
INT64 min_pts, start_time;
|
||||||
AVInputFile *file_table;
|
AVInputFile *file_table;
|
||||||
|
AVFormatContext *stream_no_data;
|
||||||
|
|
||||||
file_table= (AVInputFile*) malloc(nb_input_files * sizeof(AVInputFile));
|
file_table= (AVInputFile*) av_mallocz(nb_input_files * sizeof(AVInputFile));
|
||||||
if (!file_table)
|
if (!file_table)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
memset(file_table, 0, sizeof(file_table));
|
|
||||||
|
|
||||||
/* input stream init */
|
/* input stream init */
|
||||||
j = 0;
|
j = 0;
|
||||||
for(i=0;i<nb_input_files;i++) {
|
for(i=0;i<nb_input_files;i++) {
|
||||||
@ -797,6 +797,8 @@ static int av_encode(AVFormatContext **output_files,
|
|||||||
ist->decoding_needed = 1;
|
ist->decoding_needed = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -871,6 +873,8 @@ static int av_encode(AVFormatContext **output_files,
|
|||||||
|
|
||||||
start_time = gettime();
|
start_time = gettime();
|
||||||
min_pts = 0;
|
min_pts = 0;
|
||||||
|
stream_no_data = 0;
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
int file_index, ist_index;
|
int file_index, ist_index;
|
||||||
AVPacket pkt;
|
AVPacket pkt;
|
||||||
@ -891,14 +895,26 @@ static int av_encode(AVFormatContext **output_files,
|
|||||||
min_pts = MAXINT64;
|
min_pts = MAXINT64;
|
||||||
for(i=0;i<nb_istreams;i++) {
|
for(i=0;i<nb_istreams;i++) {
|
||||||
ist = ist_table[i];
|
ist = ist_table[i];
|
||||||
if (!ist->discard && !file_table[ist->file_index].eof_reached && ist->pts < min_pts) {
|
/* For some reason, the pts_increment code breaks q estimation?!? */
|
||||||
min_pts = ist->pts;
|
if (!ist->discard && !file_table[ist->file_index].eof_reached &&
|
||||||
|
ist->pts /* + ist->pts_increment */ < min_pts && input_files[ist->file_index] != stream_no_data) {
|
||||||
|
min_pts = ist->pts /* + ist->pts_increment */;
|
||||||
file_index = ist->file_index;
|
file_index = ist->file_index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* if none, if is finished */
|
/* if none, if is finished */
|
||||||
if (file_index < 0)
|
if (file_index < 0) {
|
||||||
|
if (stream_no_data) {
|
||||||
|
struct timespec ts;
|
||||||
|
|
||||||
|
ts.tv_sec = 0;
|
||||||
|
ts.tv_nsec = 1000 * 1000 * 10;
|
||||||
|
nanosleep(&ts, 0);
|
||||||
|
stream_no_data = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
/* finish if recording time exhausted */
|
/* finish if recording time exhausted */
|
||||||
if (recording_time > 0 && min_pts >= recording_time)
|
if (recording_time > 0 && min_pts >= recording_time)
|
||||||
break;
|
break;
|
||||||
@ -908,12 +924,20 @@ static int av_encode(AVFormatContext **output_files,
|
|||||||
file_table[file_index].eof_reached = 1;
|
file_table[file_index].eof_reached = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!pkt.size) {
|
||||||
|
stream_no_data = is;
|
||||||
|
} else {
|
||||||
|
stream_no_data = 0;
|
||||||
|
}
|
||||||
ist_index = file_table[file_index].ist_index + pkt.stream_index;
|
ist_index = file_table[file_index].ist_index + pkt.stream_index;
|
||||||
ist = ist_table[ist_index];
|
ist = ist_table[ist_index];
|
||||||
if (ist->discard) {
|
if (ist->discard) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pkt.flags & PKT_FLAG_DROPPED_FRAME)
|
||||||
|
ist->frame_number++;
|
||||||
|
|
||||||
if (do_hex_dump) {
|
if (do_hex_dump) {
|
||||||
printf("stream #%d, size=%d:\n", pkt.stream_index, pkt.size);
|
printf("stream #%d, size=%d:\n", pkt.stream_index, pkt.size);
|
||||||
hex_dump(pkt.data, pkt.size);
|
hex_dump(pkt.data, pkt.size);
|
||||||
@ -986,12 +1010,17 @@ static int av_encode(AVFormatContext **output_files,
|
|||||||
case CODEC_TYPE_AUDIO:
|
case CODEC_TYPE_AUDIO:
|
||||||
ist->pts = (INT64)1000000 * ist->sample_index / ist->st->codec.sample_rate;
|
ist->pts = (INT64)1000000 * ist->sample_index / ist->st->codec.sample_rate;
|
||||||
ist->sample_index += data_size / (2 * ist->st->codec.channels);
|
ist->sample_index += data_size / (2 * ist->st->codec.channels);
|
||||||
|
ist->pts_increment = (INT64) (data_size / (2 * ist->st->codec.channels)) * 1000000 / ist->st->codec.sample_rate;
|
||||||
break;
|
break;
|
||||||
case CODEC_TYPE_VIDEO:
|
case CODEC_TYPE_VIDEO:
|
||||||
ist->frame_number++;
|
ist->frame_number++;
|
||||||
ist->pts = ((INT64)ist->frame_number * 1000000 * FRAME_RATE_BASE) /
|
ist->pts = ((INT64)ist->frame_number * 1000000 * FRAME_RATE_BASE) /
|
||||||
ist->st->codec.frame_rate;
|
ist->st->codec.frame_rate;
|
||||||
|
ist->pts_increment = ((INT64) 1000000 * FRAME_RATE_BASE) /
|
||||||
|
ist->st->codec.frame_rate;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
ptr += ret;
|
ptr += ret;
|
||||||
len -= ret;
|
len -= ret;
|
||||||
@ -1014,6 +1043,8 @@ static int av_encode(AVFormatContext **output_files,
|
|||||||
if (do_vstats)
|
if (do_vstats)
|
||||||
do_video_stats(ost, ist, frame_size);
|
do_video_stats(ost, ist, frame_size);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* no reencoding needed : output the packet directly */
|
/* no reencoding needed : output the packet directly */
|
||||||
@ -1662,6 +1693,8 @@ void opt_input_file(const char *filename)
|
|||||||
frame_width = enc->width;
|
frame_width = enc->width;
|
||||||
frame_rate = enc->frame_rate;
|
frame_rate = enc->frame_rate;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1690,6 +1723,8 @@ void check_audio_video_inputs(int *has_video_ptr, int *has_audio_ptr)
|
|||||||
case CODEC_TYPE_VIDEO:
|
case CODEC_TYPE_VIDEO:
|
||||||
has_video = 1;
|
has_video = 1;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1947,6 +1982,8 @@ void prepare_grab(void)
|
|||||||
ap->frame_rate = enc->frame_rate;
|
ap->frame_rate = enc->frame_rate;
|
||||||
has_video = 1;
|
has_video = 1;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user