mirror of https://git.ffmpeg.org/ffmpeg.git
move stream info arrays into a struct to ease future dynamic allocation
Originally committed as revision 25045 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
4a194c8f47
commit
b004207df4
|
@ -2161,15 +2161,14 @@ int av_find_stream_info(AVFormatContext *ic)
|
||||||
int i, count, ret, read_size, j;
|
int i, count, ret, read_size, j;
|
||||||
AVStream *st;
|
AVStream *st;
|
||||||
AVPacket pkt1, *pkt;
|
AVPacket pkt1, *pkt;
|
||||||
int64_t last_dts[MAX_STREAMS];
|
|
||||||
int64_t duration_gcd[MAX_STREAMS]={0};
|
|
||||||
int duration_count[MAX_STREAMS]={0};
|
|
||||||
double (*duration_error)[MAX_STD_TIMEBASES];
|
|
||||||
int64_t old_offset = url_ftell(ic->pb);
|
int64_t old_offset = url_ftell(ic->pb);
|
||||||
int64_t codec_info_duration[MAX_STREAMS]={0};
|
struct {
|
||||||
|
int64_t last_dts;
|
||||||
duration_error = av_mallocz(MAX_STREAMS * sizeof(*duration_error));
|
int64_t duration_gcd;
|
||||||
if (!duration_error) return AVERROR(ENOMEM);
|
int duration_count;
|
||||||
|
double duration_error[MAX_STD_TIMEBASES];
|
||||||
|
int64_t codec_info_duration;
|
||||||
|
} info[MAX_STREAMS] = {{0}};
|
||||||
|
|
||||||
for(i=0;i<ic->nb_streams;i++) {
|
for(i=0;i<ic->nb_streams;i++) {
|
||||||
st = ic->streams[i];
|
st = ic->streams[i];
|
||||||
|
@ -2201,7 +2200,7 @@ int av_find_stream_info(AVFormatContext *ic)
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i=0;i<MAX_STREAMS;i++){
|
for(i=0;i<MAX_STREAMS;i++){
|
||||||
last_dts[i]= AV_NOPTS_VALUE;
|
info[i].last_dts= AV_NOPTS_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
|
@ -2220,7 +2219,7 @@ int av_find_stream_info(AVFormatContext *ic)
|
||||||
break;
|
break;
|
||||||
/* variable fps and no guess at the real fps */
|
/* variable fps and no guess at the real fps */
|
||||||
if( tb_unreliable(st->codec) && !(st->r_frame_rate.num && st->avg_frame_rate.num)
|
if( tb_unreliable(st->codec) && !(st->r_frame_rate.num && st->avg_frame_rate.num)
|
||||||
&& duration_count[i]<20 && st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
|
&& info[i].duration_count<20 && st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
|
||||||
break;
|
break;
|
||||||
if(st->parser && st->parser->parser->split && !st->codec->extradata)
|
if(st->parser && st->parser->parser->split && !st->codec->extradata)
|
||||||
break;
|
break;
|
||||||
|
@ -2268,7 +2267,6 @@ int av_find_stream_info(AVFormatContext *ic)
|
||||||
|
|
||||||
pkt= add_to_pktbuf(&ic->packet_buffer, &pkt1, &ic->packet_buffer_end);
|
pkt= add_to_pktbuf(&ic->packet_buffer, &pkt1, &ic->packet_buffer_end);
|
||||||
if(av_dup_packet(pkt) < 0) {
|
if(av_dup_packet(pkt) < 0) {
|
||||||
av_free(duration_error);
|
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2276,15 +2274,15 @@ int av_find_stream_info(AVFormatContext *ic)
|
||||||
|
|
||||||
st = ic->streams[pkt->stream_index];
|
st = ic->streams[pkt->stream_index];
|
||||||
if(st->codec_info_nb_frames>1) {
|
if(st->codec_info_nb_frames>1) {
|
||||||
if (st->time_base.den > 0 && av_rescale_q(codec_info_duration[st->index], st->time_base, AV_TIME_BASE_Q) >= ic->max_analyze_duration){
|
if (st->time_base.den > 0 && av_rescale_q(info[st->index].codec_info_duration, st->time_base, AV_TIME_BASE_Q) >= ic->max_analyze_duration){
|
||||||
av_log(ic, AV_LOG_WARNING, "max_analyze_duration reached\n");
|
av_log(ic, AV_LOG_WARNING, "max_analyze_duration reached\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
codec_info_duration[st->index] += pkt->duration;
|
info[st->index].codec_info_duration += pkt->duration;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
int index= pkt->stream_index;
|
int index= pkt->stream_index;
|
||||||
int64_t last= last_dts[index];
|
int64_t last= info[index].last_dts;
|
||||||
int64_t duration= pkt->dts - last;
|
int64_t duration= pkt->dts - last;
|
||||||
|
|
||||||
if(pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && duration>0){
|
if(pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && duration>0){
|
||||||
|
@ -2292,21 +2290,21 @@ int av_find_stream_info(AVFormatContext *ic)
|
||||||
|
|
||||||
// if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
|
// if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
|
||||||
// av_log(NULL, AV_LOG_ERROR, "%f\n", dur);
|
// av_log(NULL, AV_LOG_ERROR, "%f\n", dur);
|
||||||
if(duration_count[index] < 2)
|
if(info[index].duration_count < 2)
|
||||||
memset(duration_error[index], 0, sizeof(*duration_error));
|
memset(info[index].duration_error, 0, sizeof(info[index].duration_error));
|
||||||
for(i=1; i<MAX_STD_TIMEBASES; i++){
|
for(i=1; i<MAX_STD_TIMEBASES; i++){
|
||||||
int framerate= get_std_framerate(i);
|
int framerate= get_std_framerate(i);
|
||||||
int ticks= lrintf(dur*framerate/(1001*12));
|
int ticks= lrintf(dur*framerate/(1001*12));
|
||||||
double error= dur - ticks*1001*12/(double)framerate;
|
double error= dur - ticks*1001*12/(double)framerate;
|
||||||
duration_error[index][i] += error*error;
|
info[index].duration_error[i] += error*error;
|
||||||
}
|
}
|
||||||
duration_count[index]++;
|
info[index].duration_count++;
|
||||||
// ignore the first 4 values, they might have some random jitter
|
// ignore the first 4 values, they might have some random jitter
|
||||||
if (duration_count[index] > 3)
|
if (info[index].duration_count > 3)
|
||||||
duration_gcd[index] = av_gcd(duration_gcd[index], duration);
|
info[index].duration_gcd = av_gcd(info[index].duration_gcd, duration);
|
||||||
}
|
}
|
||||||
if(last == AV_NOPTS_VALUE || duration_count[index]<=1)
|
if(last == AV_NOPTS_VALUE || info[index].duration_count <= 1)
|
||||||
last_dts[pkt->stream_index]= pkt->dts;
|
info[pkt->stream_index].last_dts = pkt->dts;
|
||||||
}
|
}
|
||||||
if(st->parser && st->parser->parser->split && !st->codec->extradata){
|
if(st->parser && st->parser->parser->split && !st->codec->extradata){
|
||||||
int i= st->parser->parser->split(st->codec, pkt->data, pkt->size);
|
int i= st->parser->parser->split(st->codec, pkt->data, pkt->size);
|
||||||
|
@ -2337,10 +2335,10 @@ int av_find_stream_info(AVFormatContext *ic)
|
||||||
}
|
}
|
||||||
for(i=0;i<ic->nb_streams;i++) {
|
for(i=0;i<ic->nb_streams;i++) {
|
||||||
st = ic->streams[i];
|
st = ic->streams[i];
|
||||||
if(st->codec_info_nb_frames>2 && !st->avg_frame_rate.num && codec_info_duration[i])
|
if(st->codec_info_nb_frames>2 && !st->avg_frame_rate.num && info[i].codec_info_duration)
|
||||||
av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
|
av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
|
||||||
(st->codec_info_nb_frames-2)*(int64_t)st->time_base.den,
|
(st->codec_info_nb_frames-2)*(int64_t)st->time_base.den,
|
||||||
codec_info_duration[i] *(int64_t)st->time_base.num, 60000);
|
info[i].codec_info_duration*(int64_t)st->time_base.num, 60000);
|
||||||
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
|
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||||
if(st->codec->codec_id == CODEC_ID_RAWVIDEO && !st->codec->codec_tag && !st->codec->bits_per_coded_sample)
|
if(st->codec->codec_id == CODEC_ID_RAWVIDEO && !st->codec->codec_tag && !st->codec->bits_per_coded_sample)
|
||||||
st->codec->codec_tag= avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
|
st->codec->codec_tag= avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
|
||||||
|
@ -2348,18 +2346,18 @@ int av_find_stream_info(AVFormatContext *ic)
|
||||||
// the check for tb_unreliable() is not completely correct, since this is not about handling
|
// the check for tb_unreliable() is not completely correct, since this is not about handling
|
||||||
// a unreliable/inexact time base, but a time base that is finer than necessary, as e.g.
|
// a unreliable/inexact time base, but a time base that is finer than necessary, as e.g.
|
||||||
// ipmovie.c produces.
|
// ipmovie.c produces.
|
||||||
if (tb_unreliable(st->codec) && duration_count[i] > 15 && duration_gcd[i] > 1 && !st->r_frame_rate.num)
|
if (tb_unreliable(st->codec) && info[i].duration_count > 15 && info[i].duration_gcd > 1 && !st->r_frame_rate.num)
|
||||||
av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->time_base.den, st->time_base.num * duration_gcd[i], INT_MAX);
|
av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->time_base.den, st->time_base.num * info[i].duration_gcd, INT_MAX);
|
||||||
if(duration_count[i] && !st->r_frame_rate.num
|
if(info[i].duration_count && !st->r_frame_rate.num
|
||||||
&& tb_unreliable(st->codec) /*&&
|
&& tb_unreliable(st->codec) /*&&
|
||||||
//FIXME we should not special-case MPEG-2, but this needs testing with non-MPEG-2 ...
|
//FIXME we should not special-case MPEG-2, but this needs testing with non-MPEG-2 ...
|
||||||
st->time_base.num*duration_sum[i]/duration_count[i]*101LL > st->time_base.den*/){
|
st->time_base.num*duration_sum[i]/info[i].duration_count*101LL > st->time_base.den*/){
|
||||||
int num = 0;
|
int num = 0;
|
||||||
double best_error= 2*av_q2d(st->time_base);
|
double best_error= 2*av_q2d(st->time_base);
|
||||||
best_error= best_error*best_error*duration_count[i]*1000*12*30;
|
best_error= best_error*best_error*info[i].duration_count*1000*12*30;
|
||||||
|
|
||||||
for(j=1; j<MAX_STD_TIMEBASES; j++){
|
for(j=1; j<MAX_STD_TIMEBASES; j++){
|
||||||
double error= duration_error[i][j] * get_std_framerate(j);
|
double error= info[i].duration_error[j] * get_std_framerate(j);
|
||||||
// if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
|
// if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
|
||||||
// av_log(NULL, AV_LOG_ERROR, "%f %f\n", get_std_framerate(j) / 12.0/1001, error);
|
// av_log(NULL, AV_LOG_ERROR, "%f %f\n", get_std_framerate(j) / 12.0/1001, error);
|
||||||
if(error < best_error){
|
if(error < best_error){
|
||||||
|
@ -2417,8 +2415,6 @@ int av_find_stream_info(AVFormatContext *ic)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
av_free(duration_error);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue