Mercurial > libavformat.hg
comparison utils.c @ 6462:22cb1e82d915 libavformat
move stream info arrays into a struct to ease future dynamic allocation
author | aurel |
---|---|
date | Sun, 05 Sep 2010 22:25:45 +0000 |
parents | 515e6aad6a82 |
children | e0d8a52ce091 |
comparison
equal
deleted
inserted
replaced
6461:c12416642843 | 6462:22cb1e82d915 |
---|---|
2159 int av_find_stream_info(AVFormatContext *ic) | 2159 int av_find_stream_info(AVFormatContext *ic) |
2160 { | 2160 { |
2161 int i, count, ret, read_size, j; | 2161 int i, count, ret, read_size, j; |
2162 AVStream *st; | 2162 AVStream *st; |
2163 AVPacket pkt1, *pkt; | 2163 AVPacket pkt1, *pkt; |
2164 int64_t last_dts[MAX_STREAMS]; | |
2165 int64_t duration_gcd[MAX_STREAMS]={0}; | |
2166 int duration_count[MAX_STREAMS]={0}; | |
2167 double (*duration_error)[MAX_STD_TIMEBASES]; | |
2168 int64_t old_offset = url_ftell(ic->pb); | 2164 int64_t old_offset = url_ftell(ic->pb); |
2169 int64_t codec_info_duration[MAX_STREAMS]={0}; | 2165 struct { |
2170 | 2166 int64_t last_dts; |
2171 duration_error = av_mallocz(MAX_STREAMS * sizeof(*duration_error)); | 2167 int64_t duration_gcd; |
2172 if (!duration_error) return AVERROR(ENOMEM); | 2168 int duration_count; |
2169 double duration_error[MAX_STD_TIMEBASES]; | |
2170 int64_t codec_info_duration; | |
2171 } info[MAX_STREAMS] = {{0}}; | |
2173 | 2172 |
2174 for(i=0;i<ic->nb_streams;i++) { | 2173 for(i=0;i<ic->nb_streams;i++) { |
2175 st = ic->streams[i]; | 2174 st = ic->streams[i]; |
2176 if (st->codec->codec_id == CODEC_ID_AAC) { | 2175 if (st->codec->codec_id == CODEC_ID_AAC) { |
2177 st->codec->sample_rate = 0; | 2176 st->codec->sample_rate = 0; |
2199 avcodec_open(st->codec, codec); | 2198 avcodec_open(st->codec, codec); |
2200 } | 2199 } |
2201 } | 2200 } |
2202 | 2201 |
2203 for(i=0;i<MAX_STREAMS;i++){ | 2202 for(i=0;i<MAX_STREAMS;i++){ |
2204 last_dts[i]= AV_NOPTS_VALUE; | 2203 info[i].last_dts= AV_NOPTS_VALUE; |
2205 } | 2204 } |
2206 | 2205 |
2207 count = 0; | 2206 count = 0; |
2208 read_size = 0; | 2207 read_size = 0; |
2209 for(;;) { | 2208 for(;;) { |
2218 st = ic->streams[i]; | 2217 st = ic->streams[i]; |
2219 if (!has_codec_parameters(st->codec)) | 2218 if (!has_codec_parameters(st->codec)) |
2220 break; | 2219 break; |
2221 /* variable fps and no guess at the real fps */ | 2220 /* variable fps and no guess at the real fps */ |
2222 if( tb_unreliable(st->codec) && !(st->r_frame_rate.num && st->avg_frame_rate.num) | 2221 if( tb_unreliable(st->codec) && !(st->r_frame_rate.num && st->avg_frame_rate.num) |
2223 && duration_count[i]<20 && st->codec->codec_type == AVMEDIA_TYPE_VIDEO) | 2222 && info[i].duration_count<20 && st->codec->codec_type == AVMEDIA_TYPE_VIDEO) |
2224 break; | 2223 break; |
2225 if(st->parser && st->parser->parser->split && !st->codec->extradata) | 2224 if(st->parser && st->parser->parser->split && !st->codec->extradata) |
2226 break; | 2225 break; |
2227 if(st->first_dts == AV_NOPTS_VALUE) | 2226 if(st->first_dts == AV_NOPTS_VALUE) |
2228 break; | 2227 break; |
2266 break; | 2265 break; |
2267 } | 2266 } |
2268 | 2267 |
2269 pkt= add_to_pktbuf(&ic->packet_buffer, &pkt1, &ic->packet_buffer_end); | 2268 pkt= add_to_pktbuf(&ic->packet_buffer, &pkt1, &ic->packet_buffer_end); |
2270 if(av_dup_packet(pkt) < 0) { | 2269 if(av_dup_packet(pkt) < 0) { |
2271 av_free(duration_error); | |
2272 return AVERROR(ENOMEM); | 2270 return AVERROR(ENOMEM); |
2273 } | 2271 } |
2274 | 2272 |
2275 read_size += pkt->size; | 2273 read_size += pkt->size; |
2276 | 2274 |
2277 st = ic->streams[pkt->stream_index]; | 2275 st = ic->streams[pkt->stream_index]; |
2278 if(st->codec_info_nb_frames>1) { | 2276 if(st->codec_info_nb_frames>1) { |
2279 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){ | 2277 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){ |
2280 av_log(ic, AV_LOG_WARNING, "max_analyze_duration reached\n"); | 2278 av_log(ic, AV_LOG_WARNING, "max_analyze_duration reached\n"); |
2281 break; | 2279 break; |
2282 } | 2280 } |
2283 codec_info_duration[st->index] += pkt->duration; | 2281 info[st->index].codec_info_duration += pkt->duration; |
2284 } | 2282 } |
2285 { | 2283 { |
2286 int index= pkt->stream_index; | 2284 int index= pkt->stream_index; |
2287 int64_t last= last_dts[index]; | 2285 int64_t last= info[index].last_dts; |
2288 int64_t duration= pkt->dts - last; | 2286 int64_t duration= pkt->dts - last; |
2289 | 2287 |
2290 if(pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && duration>0){ | 2288 if(pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && duration>0){ |
2291 double dur= duration * av_q2d(st->time_base); | 2289 double dur= duration * av_q2d(st->time_base); |
2292 | 2290 |
2293 // if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO) | 2291 // if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO) |
2294 // av_log(NULL, AV_LOG_ERROR, "%f\n", dur); | 2292 // av_log(NULL, AV_LOG_ERROR, "%f\n", dur); |
2295 if(duration_count[index] < 2) | 2293 if(info[index].duration_count < 2) |
2296 memset(duration_error[index], 0, sizeof(*duration_error)); | 2294 memset(info[index].duration_error, 0, sizeof(info[index].duration_error)); |
2297 for(i=1; i<MAX_STD_TIMEBASES; i++){ | 2295 for(i=1; i<MAX_STD_TIMEBASES; i++){ |
2298 int framerate= get_std_framerate(i); | 2296 int framerate= get_std_framerate(i); |
2299 int ticks= lrintf(dur*framerate/(1001*12)); | 2297 int ticks= lrintf(dur*framerate/(1001*12)); |
2300 double error= dur - ticks*1001*12/(double)framerate; | 2298 double error= dur - ticks*1001*12/(double)framerate; |
2301 duration_error[index][i] += error*error; | 2299 info[index].duration_error[i] += error*error; |
2302 } | 2300 } |
2303 duration_count[index]++; | 2301 info[index].duration_count++; |
2304 // ignore the first 4 values, they might have some random jitter | 2302 // ignore the first 4 values, they might have some random jitter |
2305 if (duration_count[index] > 3) | 2303 if (info[index].duration_count > 3) |
2306 duration_gcd[index] = av_gcd(duration_gcd[index], duration); | 2304 info[index].duration_gcd = av_gcd(info[index].duration_gcd, duration); |
2307 } | 2305 } |
2308 if(last == AV_NOPTS_VALUE || duration_count[index]<=1) | 2306 if(last == AV_NOPTS_VALUE || info[index].duration_count <= 1) |
2309 last_dts[pkt->stream_index]= pkt->dts; | 2307 info[pkt->stream_index].last_dts = pkt->dts; |
2310 } | 2308 } |
2311 if(st->parser && st->parser->parser->split && !st->codec->extradata){ | 2309 if(st->parser && st->parser->parser->split && !st->codec->extradata){ |
2312 int i= st->parser->parser->split(st->codec, pkt->data, pkt->size); | 2310 int i= st->parser->parser->split(st->codec, pkt->data, pkt->size); |
2313 if(i){ | 2311 if(i){ |
2314 st->codec->extradata_size= i; | 2312 st->codec->extradata_size= i; |
2335 if(st->codec->codec) | 2333 if(st->codec->codec) |
2336 avcodec_close(st->codec); | 2334 avcodec_close(st->codec); |
2337 } | 2335 } |
2338 for(i=0;i<ic->nb_streams;i++) { | 2336 for(i=0;i<ic->nb_streams;i++) { |
2339 st = ic->streams[i]; | 2337 st = ic->streams[i]; |
2340 if(st->codec_info_nb_frames>2 && !st->avg_frame_rate.num && codec_info_duration[i]) | 2338 if(st->codec_info_nb_frames>2 && !st->avg_frame_rate.num && info[i].codec_info_duration) |
2341 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, | 2339 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, |
2342 (st->codec_info_nb_frames-2)*(int64_t)st->time_base.den, | 2340 (st->codec_info_nb_frames-2)*(int64_t)st->time_base.den, |
2343 codec_info_duration[i] *(int64_t)st->time_base.num, 60000); | 2341 info[i].codec_info_duration*(int64_t)st->time_base.num, 60000); |
2344 if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { | 2342 if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { |
2345 if(st->codec->codec_id == CODEC_ID_RAWVIDEO && !st->codec->codec_tag && !st->codec->bits_per_coded_sample) | 2343 if(st->codec->codec_id == CODEC_ID_RAWVIDEO && !st->codec->codec_tag && !st->codec->bits_per_coded_sample) |
2346 st->codec->codec_tag= avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt); | 2344 st->codec->codec_tag= avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt); |
2347 | 2345 |
2348 // the check for tb_unreliable() is not completely correct, since this is not about handling | 2346 // the check for tb_unreliable() is not completely correct, since this is not about handling |
2349 // a unreliable/inexact time base, but a time base that is finer than necessary, as e.g. | 2347 // a unreliable/inexact time base, but a time base that is finer than necessary, as e.g. |
2350 // ipmovie.c produces. | 2348 // ipmovie.c produces. |
2351 if (tb_unreliable(st->codec) && duration_count[i] > 15 && duration_gcd[i] > 1 && !st->r_frame_rate.num) | 2349 if (tb_unreliable(st->codec) && info[i].duration_count > 15 && info[i].duration_gcd > 1 && !st->r_frame_rate.num) |
2352 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); | 2350 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); |
2353 if(duration_count[i] && !st->r_frame_rate.num | 2351 if(info[i].duration_count && !st->r_frame_rate.num |
2354 && tb_unreliable(st->codec) /*&& | 2352 && tb_unreliable(st->codec) /*&& |
2355 //FIXME we should not special-case MPEG-2, but this needs testing with non-MPEG-2 ... | 2353 //FIXME we should not special-case MPEG-2, but this needs testing with non-MPEG-2 ... |
2356 st->time_base.num*duration_sum[i]/duration_count[i]*101LL > st->time_base.den*/){ | 2354 st->time_base.num*duration_sum[i]/info[i].duration_count*101LL > st->time_base.den*/){ |
2357 int num = 0; | 2355 int num = 0; |
2358 double best_error= 2*av_q2d(st->time_base); | 2356 double best_error= 2*av_q2d(st->time_base); |
2359 best_error= best_error*best_error*duration_count[i]*1000*12*30; | 2357 best_error= best_error*best_error*info[i].duration_count*1000*12*30; |
2360 | 2358 |
2361 for(j=1; j<MAX_STD_TIMEBASES; j++){ | 2359 for(j=1; j<MAX_STD_TIMEBASES; j++){ |
2362 double error= duration_error[i][j] * get_std_framerate(j); | 2360 double error= info[i].duration_error[j] * get_std_framerate(j); |
2363 // if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO) | 2361 // if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO) |
2364 // av_log(NULL, AV_LOG_ERROR, "%f %f\n", get_std_framerate(j) / 12.0/1001, error); | 2362 // av_log(NULL, AV_LOG_ERROR, "%f %f\n", get_std_framerate(j) / 12.0/1001, error); |
2365 if(error < best_error){ | 2363 if(error < best_error){ |
2366 best_error= error; | 2364 best_error= error; |
2367 num = get_std_framerate(j); | 2365 num = get_std_framerate(j); |
2414 st->cur_dts -= delta; | 2412 st->cur_dts -= delta; |
2415 } | 2413 } |
2416 } | 2414 } |
2417 } | 2415 } |
2418 #endif | 2416 #endif |
2419 | |
2420 av_free(duration_error); | |
2421 | 2417 |
2422 return ret; | 2418 return ret; |
2423 } | 2419 } |
2424 | 2420 |
2425 /*******************************************************/ | 2421 /*******************************************************/ |