| Index: source/patched-ffmpeg-mt/libavformat/utils.c
|
| ===================================================================
|
| --- source/patched-ffmpeg-mt/libavformat/utils.c (revision 59334)
|
| +++ source/patched-ffmpeg-mt/libavformat/utils.c (working copy)
|
| @@ -457,7 +457,7 @@
|
| if (pb && !ic->data_offset)
|
| ic->data_offset = url_ftell(ic->pb);
|
|
|
| -#if LIBAVFORMAT_VERSION_MAJOR < 53
|
| +#if FF_API_OLD_METADATA
|
| ff_metadata_demux_compat(ic);
|
| #endif
|
|
|
| @@ -474,6 +474,7 @@
|
| if (st) {
|
| av_free(st->priv_data);
|
| av_free(st->codec->extradata);
|
| + av_free(st->codec);
|
| }
|
| av_free(st);
|
| }
|
| @@ -2165,16 +2166,15 @@
|
| int i, count, ret, read_size, j;
|
| AVStream *st;
|
| 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 codec_info_duration[MAX_STREAMS]={0};
|
| + struct {
|
| + int64_t last_dts;
|
| + int64_t duration_gcd;
|
| + int duration_count;
|
| + double duration_error[MAX_STD_TIMEBASES];
|
| + int64_t codec_info_duration;
|
| + } info[MAX_STREAMS] = {{0}};
|
|
|
| - duration_error = av_mallocz(MAX_STREAMS * sizeof(*duration_error));
|
| - if (!duration_error) return AVERROR(ENOMEM);
|
| -
|
| for(i=0;i<ic->nb_streams;i++) {
|
| st = ic->streams[i];
|
| if (st->codec->codec_id == CODEC_ID_AAC) {
|
| @@ -2205,7 +2205,7 @@
|
| }
|
|
|
| for(i=0;i<MAX_STREAMS;i++){
|
| - last_dts[i]= AV_NOPTS_VALUE;
|
| + info[i].last_dts= AV_NOPTS_VALUE;
|
| }
|
|
|
| count = 0;
|
| @@ -2224,7 +2224,7 @@
|
| break;
|
| /* variable fps and no guess at the real fps */
|
| 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;
|
| if(st->parser && st->parser->parser->split && !st->codec->extradata)
|
| break;
|
| @@ -2272,7 +2272,6 @@
|
|
|
| pkt= add_to_pktbuf(&ic->packet_buffer, &pkt1, &ic->packet_buffer_end);
|
| if(av_dup_packet(pkt) < 0) {
|
| - av_free(duration_error);
|
| return AVERROR(ENOMEM);
|
| }
|
|
|
| @@ -2280,15 +2279,15 @@
|
|
|
| st = ic->streams[pkt->stream_index];
|
| 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");
|
| break;
|
| }
|
| - codec_info_duration[st->index] += pkt->duration;
|
| + info[st->index].codec_info_duration += pkt->duration;
|
| }
|
| {
|
| int index= pkt->stream_index;
|
| - int64_t last= last_dts[index];
|
| + int64_t last= info[index].last_dts;
|
| int64_t duration= pkt->dts - last;
|
|
|
| if(pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && duration>0){
|
| @@ -2296,21 +2295,21 @@
|
|
|
| // if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
|
| // av_log(NULL, AV_LOG_ERROR, "%f\n", dur);
|
| - if(duration_count[index] < 2)
|
| - memset(duration_error[index], 0, sizeof(*duration_error));
|
| + if(info[index].duration_count < 2)
|
| + memset(info[index].duration_error, 0, sizeof(info[index].duration_error));
|
| for(i=1; i<MAX_STD_TIMEBASES; i++){
|
| int framerate= get_std_framerate(i);
|
| int ticks= lrintf(dur*framerate/(1001*12));
|
| 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
|
| - if (duration_count[index] > 3)
|
| - duration_gcd[index] = av_gcd(duration_gcd[index], duration);
|
| + if (info[index].duration_count > 3)
|
| + info[index].duration_gcd = av_gcd(info[index].duration_gcd, duration);
|
| }
|
| - if(last == AV_NOPTS_VALUE || duration_count[index]<=1)
|
| - last_dts[pkt->stream_index]= pkt->dts;
|
| + if(last == AV_NOPTS_VALUE || info[index].duration_count <= 1)
|
| + info[pkt->stream_index].last_dts = pkt->dts;
|
| }
|
| if(st->parser && st->parser->parser->split && !st->codec->extradata){
|
| int i= st->parser->parser->split(st->codec, pkt->data, pkt->size);
|
| @@ -2341,10 +2340,10 @@
|
| }
|
| for(i=0;i<ic->nb_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,
|
| (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_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);
|
| @@ -2352,18 +2351,18 @@
|
| // 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.
|
| // ipmovie.c produces.
|
| - if (tb_unreliable(st->codec) && duration_count[i] > 15 && duration_gcd[i] > 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);
|
| - if(duration_count[i] && !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 * info[i].duration_gcd, INT_MAX);
|
| + if(info[i].duration_count && !st->r_frame_rate.num
|
| && tb_unreliable(st->codec) /*&&
|
| //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;
|
| 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++){
|
| - 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)
|
| // av_log(NULL, AV_LOG_ERROR, "%f %f\n", get_std_framerate(j) / 12.0/1001, error);
|
| if(error < best_error){
|
| @@ -2421,8 +2420,6 @@
|
| }
|
| #endif
|
|
|
| - av_free(duration_error);
|
| -
|
| return ret;
|
| }
|
|
|
| @@ -2464,14 +2461,14 @@
|
| av_free(st->index_entries);
|
| av_free(st->codec->extradata);
|
| av_free(st->codec);
|
| -#if LIBAVFORMAT_VERSION_INT < (53<<16)
|
| +#if FF_API_OLD_METADATA
|
| av_free(st->filename);
|
| #endif
|
| av_free(st->priv_data);
|
| av_free(st);
|
| }
|
| for(i=s->nb_programs-1; i>=0; i--) {
|
| -#if LIBAVFORMAT_VERSION_INT < (53<<16)
|
| +#if FF_API_OLD_METADATA
|
| av_freep(&s->programs[i]->provider_name);
|
| av_freep(&s->programs[i]->name);
|
| #endif
|
| @@ -2483,7 +2480,7 @@
|
| flush_packet_queue(s);
|
| av_freep(&s->priv_data);
|
| while(s->nb_chapters--) {
|
| -#if LIBAVFORMAT_VERSION_INT < (53<<16)
|
| +#if FF_API_OLD_METADATA
|
| av_free(s->chapters[s->nb_chapters]->title);
|
| #endif
|
| av_metadata_free(&s->chapters[s->nb_chapters]->metadata);
|
| @@ -2491,6 +2488,7 @@
|
| }
|
| av_freep(&s->chapters);
|
| av_metadata_free(&s->metadata);
|
| + av_freep(&s->key);
|
| av_free(s);
|
| }
|
|
|
| @@ -2586,7 +2584,7 @@
|
| return NULL;
|
| dynarray_add(&s->chapters, &s->nb_chapters, chapter);
|
| }
|
| -#if LIBAVFORMAT_VERSION_INT < (53<<16)
|
| +#if FF_API_OLD_METADATA
|
| av_free(chapter->title);
|
| #endif
|
| av_metadata_set2(&chapter->metadata, "title", title, 0);
|
| @@ -2703,8 +2701,8 @@
|
| char tagbuf[32];
|
| av_get_codec_tag_string(tagbuf, sizeof(tagbuf), st->codec->codec_tag);
|
| av_log(s, AV_LOG_ERROR,
|
| - "Tag %s/0x%08x incompatible with output codec '%s'\n",
|
| - tagbuf, st->codec->codec_tag, st->codec->codec->name);
|
| + "Tag %s/0x%08x incompatible with output codec id '%d'\n",
|
| + tagbuf, st->codec->codec_tag, st->codec->codec_id);
|
| return AVERROR_INVALIDDATA;
|
| }
|
| }else
|
| @@ -2722,7 +2720,7 @@
|
| return AVERROR(ENOMEM);
|
| }
|
|
|
| -#if LIBAVFORMAT_VERSION_MAJOR < 53
|
| +#if FF_API_OLD_METADATA
|
| ff_metadata_mux_compat(s);
|
| #endif
|
|
|
| @@ -3142,7 +3140,7 @@
|
| int secs, us;
|
| av_log(NULL, AV_LOG_INFO, ", start: ");
|
| secs = ic->start_time / AV_TIME_BASE;
|
| - us = ic->start_time % AV_TIME_BASE;
|
| + us = abs(ic->start_time % AV_TIME_BASE);
|
| av_log(NULL, AV_LOG_INFO, "%d.%06d",
|
| secs, (int)av_rescale(us, 1000000, AV_TIME_BASE));
|
| }
|
| @@ -3605,6 +3603,34 @@
|
| return buff;
|
| }
|
|
|
| +int ff_hex_to_data(uint8_t *data, const char *p)
|
| +{
|
| + int c, len, v;
|
| +
|
| + len = 0;
|
| + v = 1;
|
| + for (;;) {
|
| + p += strspn(p, SPACE_CHARS);
|
| + if (*p == '\0')
|
| + break;
|
| + c = toupper((unsigned char) *p++);
|
| + if (c >= '0' && c <= '9')
|
| + c = c - '0';
|
| + else if (c >= 'A' && c <= 'F')
|
| + c = c - 'A' + 10;
|
| + else
|
| + break;
|
| + v = (v << 4) | c;
|
| + if (v & 0x100) {
|
| + if (data)
|
| + data[len] = v;
|
| + len++;
|
| + v = 1;
|
| + }
|
| + }
|
| + return len;
|
| +}
|
| +
|
| void av_set_pts_info(AVStream *s, int pts_wrap_bits,
|
| unsigned int pts_num, unsigned int pts_den)
|
| {
|
| @@ -3683,3 +3709,57 @@
|
| return av_write_frame(dst, &local_pkt);
|
| }
|
|
|
| +void ff_parse_key_value(const char *str, ff_parse_key_val_cb callback_get_buf,
|
| + void *context)
|
| +{
|
| + const char *ptr = str;
|
| +
|
| + /* Parse key=value pairs. */
|
| + for (;;) {
|
| + const char *key;
|
| + char *dest = NULL, *dest_end;
|
| + int key_len, dest_len = 0;
|
| +
|
| + /* Skip whitespace and potential commas. */
|
| + while (*ptr && (isspace(*ptr) || *ptr == ','))
|
| + ptr++;
|
| + if (!*ptr)
|
| + break;
|
| +
|
| + key = ptr;
|
| +
|
| + if (!(ptr = strchr(key, '=')))
|
| + break;
|
| + ptr++;
|
| + key_len = ptr - key;
|
| +
|
| + callback_get_buf(context, key, key_len, &dest, &dest_len);
|
| + dest_end = dest + dest_len - 1;
|
| +
|
| + if (*ptr == '\"') {
|
| + ptr++;
|
| + while (*ptr && *ptr != '\"') {
|
| + if (*ptr == '\\') {
|
| + if (!ptr[1])
|
| + break;
|
| + if (dest && dest < dest_end)
|
| + *dest++ = ptr[1];
|
| + ptr += 2;
|
| + } else {
|
| + if (dest && dest < dest_end)
|
| + *dest++ = *ptr;
|
| + ptr++;
|
| + }
|
| + }
|
| + if (*ptr == '\"')
|
| + ptr++;
|
| + } else {
|
| + for (; *ptr && !(isspace(*ptr) || *ptr == ','); ptr++)
|
| + if (dest && dest < dest_end)
|
| + *dest++ = *ptr;
|
| + }
|
| + if (dest)
|
| + *dest = 0;
|
| + }
|
| +}
|
| +
|
|
|